Skyward boardcore
Loading...
Searching...
No Matches
MBLoadCell.cpp
Go to the documentation of this file.
1/* Copyright (c) 2021 Skyward Experimental Rocketry
2 * Author: Emilio Corigliano
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include "MBLoadCell.h"
24
25#include <cmath>
26#include <iostream>
27
28#include "stdlib.h"
29
30using ctrlPin1 = miosix::Gpio<GPIOC_BASE, 1>;
31using ctrlPin2 = miosix::Gpio<GPIOC_BASE, 2>;
32
33namespace Boardcore
34{
35
37 : serial(serial)
38{
39 this->settings.mode = mode;
40 maxPrint = maxSetted = minPrint = minSetted = 0;
41}
42
44{
45 {
46 // Disabling interrupts in order to set with no problems the ctrl pins
47 miosix::FastInterruptDisableLock dLock;
48 ctrlPin1::mode(miosix::Mode::OUTPUT);
49 ctrlPin2::mode(miosix::Mode::OUTPUT);
50 }
51
52 return true;
53}
54
56{
57 DataAsciiRequest request;
58
59 // Generating the request
60 generateRequest(request, reqType, value);
61
62 // Transmitting request
63 transmitASCII(request.to_string());
64
65 // Waiting for the response
66 std::string response = receiveASCII();
67
68 if (response.find('!') != std::string::npos)
70
71 if (response.find('#') != std::string::npos)
73
74 // Memorizing the requested data
75 switch (reqType)
76 {
79 break;
82 break;
85 break;
92 {
93 // Taking the value returned
94 float val = stof(response.substr(3, 6)) / 10.0;
95
96 // Updating the last value struct
97 settings.updateValue(reqType, val);
98 break;
99 }
101 TRACE("TARE RESETTED\n");
102 break;
104 settings.grossMode = true;
105 TRACE("COMMUTED TO GROSS WEIGHT\n");
106 break;
108 settings.grossMode = false;
109 TRACE("COMMUTED TO NET WEIGHT\n");
110 break;
111 }
112
114}
115
117{
118 TRACE("max and min values erased!\n");
119 maxWeight.valid = false;
120 minWeight.valid = false;
121}
122
124{
125 if (lastSample.valid)
126 {
127#ifdef PRINT_ALL_SAMPLES
128 lastSample.print(std::cout);
129#endif
130 }
131 else
132 {
134 TRACE("No valida data has been collected\n");
135 }
136
137 if (maxPrint)
138 {
139 TRACE("NEW MAX %.2f (ts: %.3f [s])\n", maxWeight.load,
140 maxWeight.loadTimestamp / 1000000.0);
141 maxPrint = false;
142 }
143
144 if (minPrint)
145 {
146 TRACE("NEW MIN %.2f (ts: %.3f [s])\n", minWeight.load,
147 minWeight.loadTimestamp / 1000000.0);
148 minPrint = false;
149 }
150}
151
153
155
156bool MBLoadCell::selfTest() { return true; }
157
159{
160 MBLoadCellData value;
161 switch (settings.mode)
162 {
164 value = sampleContModT();
165 break;
167 value = sampleContModTd();
168 break;
170 value = sampleAsciiModTd();
171 break;
172 default:
174 return lastSample;
175 }
176
177 // Memorizing also the maximum gross weight registered
178 if (!maxWeight.valid || maxWeight.load < value.load)
179 {
180 maxWeight = value;
181 maxSetted = true;
182 }
183 else if (maxSetted)
184 {
185 maxSetted = false;
186 maxPrint = true;
187 }
188
189 // Memorizing also the minimum gross weight registered
190 if (!minWeight.valid || minWeight.load > value.load)
191 {
192 minWeight = value;
193 minSetted = true;
194 }
195 else if (minSetted)
196 {
197 minSetted = false;
198 minPrint = true;
199 }
200
201 return value;
202}
203
205{
206 DataModT data;
207 receive(&data);
208
209 return MBLoadCellData(atof(data.weight) / 10.0);
210}
211
213{
214 DataModTd data;
215 receive(&data);
216
217 return MBLoadCellData(atof(data.weightT) / 10.0);
218}
219
221{
222 DataAsciiRequest request;
223
224 // Generating the request
226
227 // Transmitting request
228 transmitASCII(request.to_string());
229
230 // Waiting for the response
231 std::string response = receiveASCII();
232
233 // If response invalid returns lastSample, otherwise returns new sample
234 if (response.find('!') != std::string::npos)
235 {
236 TRACE("Gross weight reception error\n");
238 return lastSample;
239 }
240 else if (response.find('#') != std::string::npos)
241 {
242 TRACE("Gross weight execution error\n");
244 return lastSample;
245 }
246 else
247 {
248 // Taking the value returned
249 return MBLoadCellData(stof(response.substr(3, 6)) / 10.0);
250 }
251}
252
254 const LoadCellValuesEnum toRequest, int value)
255{
256 strcpy(req.req, loadCellValues[toRequest].c_str());
257
258 if (toRequest == LoadCellValuesEnum::SET_SETPOINT_1 ||
261 {
262 std::string strVal = std::to_string(abs(value));
263 strVal.insert(strVal.begin(), 6 - strVal.length(), '0');
264
265 if (value < 0)
266 strVal[0] = '-';
267
268 strcpy(req.value, strVal.c_str());
269 TRACE("value sent: %s\n", strVal.c_str());
270 }
271
272 req.setChecksum();
273}
274
275void MBLoadCell::transmitASCII(const std::string& buf)
276{
277 // Setting both the control pins to high in order to transmit
278 ctrlPin1::high();
279 ctrlPin2::high();
280 serial.writeString(buf.c_str());
281 miosix::Thread::sleep(10); // Needs some time (>5ms) idk why
282}
283
285{
286 char buf[64];
287
288 // Setting both the control pins to low in order to receive
289 ctrlPin1::low();
290 ctrlPin2::low();
291 int len = serial.readBlocking(buf, 64);
292 buf[len] = '\0';
293
294 return std::string(buf);
295}
296
297template <typename T>
299{
300 // Setting both the control pins to low in order to receive
301 ctrlPin1::low();
302 ctrlPin2::low();
303 serial.readBlocking(buf, sizeof(buf));
304}
305
306} // namespace Boardcore
#define TRACE(...)
Definition Debug.h:58
miosix::Gpio< GPIOC_BASE, 1 > ctrlPin1
Control R/W pin 1.
miosix::Gpio< GPIOC_BASE, 2 > ctrlPin2
Control R/W pin 2.
SensorErrors lastError
Definition Sensor.h:54
void receive(T *buf)
Wrapper to the serial receive method. This also sets the control pins to enable the receiver mode.
MBLoadCellData getMaxWeight()
Returns a copy of the max weight detected.
MBLoadCellData sampleContModTd(void)
Sampling in the "continuous Mod Td" mode.
MBLoadCellData sampleContModT(void)
Sampling in the "continuous Mod T" mode.
void resetMaxMinWeights()
Permits to reset the peak weight value.
MBLoadCellData sampleAsciiModTd(void)
Sampling in the "ASCII Mod Td" mode.
std::string receiveASCII()
Wrapper to the serial recvString method. This also sets the control pins to enable the receiver mode.
MBLoadCellData getMinWeight()
Returns a copy of the min weight detected.
void printData()
Prints the last sample received.
void transmitASCII(const std::string &buf)
Wrapper to the serial sendString method. This also sets the control pins to enable the transmission m...
ReturnsStates asciiRequest(LoadCellValuesEnum r, int value=0)
Generates and sends a request in ASCII mode, waits for the response and updates the lastSample struct...
bool init() override
Initializes the serial communication with the load cell.
void generateRequest(DataAsciiRequest &req, const LoadCellValuesEnum toRequest, int value=0)
Forges a request for the ascii mode.
MBLoadCellData sampleImpl() override
Requests the weight sampled from the load cell or waits for a sample depending on the mode selected (...
bool selfTest() override
Check if the sensor is working.
MBLoadCell(USARTInterface &serial, LoadCellModes mode)
constructor that initializes the serial communication with the load cell
Abstract class that implements the interface for the USART/UART serial communication.
Definition USART.h:70
virtual bool readBlocking(void *buffer, size_t nBytes, std::chrono::nanoseconds timeout=std::chrono::nanoseconds::zero())
Blocking read operation to read nBytes until the data transfer is complete or the timeout is reached.
Definition USART.h:91
virtual void writeString(const char *buffer)=0
Write a string to the serial, comprising the '\0' character.
This file includes all the types the logdecoder script will decode.
ReturnsStates
Structure of the errors in the ASCII requests.
LoadCellModes
Enumeration of all the modes supported by the driver.
LoadCellValuesEnum
Enumeration of all the requests in ASCII mode.
Structure that contains all the parameters for the request to be sent.
void setChecksum()
In base of the address and the request parameter calculates the checksum.
Structure of the output of the load cell in [continuous mode -> ModT].
Structure of the output of the load cell in [continuous mode -> ModTd].
Structure that stores a data value, with his timestamp and his validity.
void print(std::ostream &os) const
void updateValue(LoadCellValuesEnum val, float data)
Updates the correct value with the data passed. Also, memorizes the maximum and minimum value of the ...