Mateusz Grzywacz / SDI12_device
Committer:
amateusz
Date:
Wed Aug 01 17:11:44 2018 +0000
Revision:
5:e53104570fde
Parent:
4:11438803516c
Child:
6:d9a5240a99fd
added proper string with all the addresses (called ADDRRICES).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
amateusz 0:d58ebb2bed9a 1 #include "SDI12.h"
amateusz 0:d58ebb2bed9a 2 #include <string>
amateusz 2:e2db05bc4708 3 #include "mbed.h"
amateusz 0:d58ebb2bed9a 4
amateusz 0:d58ebb2bed9a 5 class SDI12_device
amateusz 0:d58ebb2bed9a 6 {
amateusz 0:d58ebb2bed9a 7 public:
amateusz 0:d58ebb2bed9a 8 struct Identification_struct {
amateusz 0:d58ebb2bed9a 9 unsigned char sdi_version;
amateusz 0:d58ebb2bed9a 10 char company[8+1];
amateusz 0:d58ebb2bed9a 11 char model[6+1];
amateusz 0:d58ebb2bed9a 12 char version[3+1];
amateusz 0:d58ebb2bed9a 13 };
amateusz 0:d58ebb2bed9a 14
amateusz 0:d58ebb2bed9a 15 struct Measurement_struct {
amateusz 0:d58ebb2bed9a 16 unsigned long timestampMeasurementReadyAt;
amateusz 4:11438803516c 17 char readyIn;
amateusz 0:d58ebb2bed9a 18 bool _measurementAlreadyRead;
amateusz 0:d58ebb2bed9a 19 char count;
amateusz 4:11438803516c 20 float values[48]; // not float values [] !! :O
amateusz 0:d58ebb2bed9a 21 };
amateusz 0:d58ebb2bed9a 22
amateusz 0:d58ebb2bed9a 23 Identification_struct _ident_struct;
amateusz 0:d58ebb2bed9a 24
amateusz 0:d58ebb2bed9a 25 static int detect(SDI12 &sdi12, char indices[]) {
amateusz 0:d58ebb2bed9a 26 char found = 0;
amateusz 5:e53104570fde 27 for (size_t i = 0; i < ADDRRICES.size(); ++i) {
amateusz 0:d58ebb2bed9a 28 string question = "?!";
amateusz 5:e53104570fde 29 question[0] = ADDRRICES[i];
amateusz 0:d58ebb2bed9a 30 sdi12.sendCommand(question);
amateusz 0:d58ebb2bed9a 31 std::string response;
amateusz 5:e53104570fde 32 debug("detecting: %s\r\n", question);
amateusz 5:e53104570fde 33
amateusz 0:d58ebb2bed9a 34 Timer detectTimer;
amateusz 0:d58ebb2bed9a 35 detectTimer.start();
amateusz 5:e53104570fde 36 while (sdi12.RxBufferAvailable() == 0) {
amateusz 5:e53104570fde 37 if (sdi12.RxInProgress()) detectTimer.reset();
amateusz 5:e53104570fde 38 if (detectTimer.read_ms() > RESPONSE_TIMEOUT) {
amateusz 0:d58ebb2bed9a 39 ++i;
amateusz 0:d58ebb2bed9a 40 break;
amateusz 0:d58ebb2bed9a 41 }
amateusz 5:e53104570fde 42 }
amateusz 0:d58ebb2bed9a 43 unsigned char bufferSize = sdi12.RxBufferAvailable();
amateusz 0:d58ebb2bed9a 44 char buffer[bufferSize];
amateusz 0:d58ebb2bed9a 45
amateusz 0:d58ebb2bed9a 46 sdi12.getRxBuffer(buffer);
amateusz 0:d58ebb2bed9a 47 // if first char is valid address char
amateusz 5:e53104570fde 48
amateusz 5:e53104570fde 49 if (ADDRRICES.find(buffer[0])) {
amateusz 5:e53104570fde 50 // if (buffer[0] >= '0' && buffer[0] <= '9' ||
amateusz 5:e53104570fde 51 // buffer[0] >= 'a' && buffer[0] <= 'z' ||
amateusz 5:e53104570fde 52 // buffer[0] >= 'A' && buffer[0] <= 'Z') {
amateusz 0:d58ebb2bed9a 53 indices[found++] = buffer[0];
amateusz 0:d58ebb2bed9a 54 }
amateusz 0:d58ebb2bed9a 55 }
amateusz 0:d58ebb2bed9a 56 return found;
amateusz 0:d58ebb2bed9a 57 };
amateusz 0:d58ebb2bed9a 58
amateusz 2:e2db05bc4708 59 SDI12_device (SDI12 &inst, char address, EventQueue &mainDispatcher) : _sdi12(inst) {
amateusz 0:d58ebb2bed9a 60 setAddress(address);
amateusz 2:e2db05bc4708 61 sensorQueue.chain(&mainDispatcher);
amateusz 1:6b1a21925a81 62 if(getIdentification(_ident_struct));
amateusz 0:d58ebb2bed9a 63 };
amateusz 5:e53104570fde 64 ~SDI12_device () {
amateusz 5:e53104570fde 65 // unchain event queue
amateusz 5:e53104570fde 66 sensorQueue.cancel(_measurementEventId);
amateusz 5:e53104570fde 67 sensorQueue.chain(NULL);
amateusz 5:e53104570fde 68 }
amateusz 0:d58ebb2bed9a 69
amateusz 0:d58ebb2bed9a 70 // void printIdentification(){
amateusz 0:d58ebb2bed9a 71 // Serial.println(_ident_struct.company);
amateusz 0:d58ebb2bed9a 72 // Serial.println(_ident_struct.model);
amateusz 0:d58ebb2bed9a 73 // Serial.println(_ident_struct.version);
amateusz 0:d58ebb2bed9a 74 // }
amateusz 0:d58ebb2bed9a 75 //
amateusz 2:e2db05bc4708 76
amateusz 0:d58ebb2bed9a 77 // // returns after how many seconds a measurement will be ready
amateusz 2:e2db05bc4708 78 int measure(bool concurrent = true) {
amateusz 4:11438803516c 79
amateusz 2:e2db05bc4708 80 std::string question = string("?") + string(concurrent?"C":"M") + string("!");
amateusz 2:e2db05bc4708 81 question[0] = _address;
amateusz 2:e2db05bc4708 82 _sdi12.sendCommand(question);
amateusz 2:e2db05bc4708 83
amateusz 2:e2db05bc4708 84 Timer timeout;
amateusz 2:e2db05bc4708 85 timeout.start();
amateusz 2:e2db05bc4708 86 while (sdi12.RxBufferAvailable() == 0) {
amateusz 2:e2db05bc4708 87 if (sdi12.RxInProgress()) timeout.reset();
amateusz 5:e53104570fde 88 if(timeout.read_ms() > RESPONSE_TIMEOUT) {
amateusz 2:e2db05bc4708 89 return false;
amateusz 2:e2db05bc4708 90 }
amateusz 2:e2db05bc4708 91 }
amateusz 2:e2db05bc4708 92 unsigned char bufferSize = sdi12.RxBufferAvailable();
amateusz 2:e2db05bc4708 93 char buffer[bufferSize+1];
amateusz 2:e2db05bc4708 94 sdi12.getRxBuffer(buffer);
amateusz 2:e2db05bc4708 95 buffer[bufferSize] = '\0';
amateusz 2:e2db05bc4708 96 std::string response(buffer);
amateusz 2:e2db05bc4708 97
amateusz 2:e2db05bc4708 98 if (response[0] == _address) {
amateusz 2:e2db05bc4708 99 char measurementsCount = std::atoi(response.substr(1+3,(concurrent?2:1)).c_str());
amateusz 2:e2db05bc4708 100 char waitFor = std::atoi(response.substr(1,3).c_str());
amateusz 2:e2db05bc4708 101 _measurement.count = measurementsCount;
amateusz 4:11438803516c 102 _measurement.readyIn = waitFor;
amateusz 2:e2db05bc4708 103 // _measurement.timestampMeasurementReadyAt
amateusz 2:e2db05bc4708 104 debug("wait for %d measurement for %d seconds...", _measurement.count, waitFor);
amateusz 5:e53104570fde 105 _measurementEventId = sensorQueue.call_in(waitFor * 1000, callback(this, &SDI12_device::read));
amateusz 5:e53104570fde 106 debug("measurement scheduled");
amateusz 4:11438803516c 107 // if (_measurement.values != NULL) delete[] _measurement.values;
amateusz 4:11438803516c 108 // _measurement.values = new float[measurementsCount];
amateusz 2:e2db05bc4708 109 return 0;
amateusz 2:e2db05bc4708 110 }
amateusz 2:e2db05bc4708 111 return -1;
amateusz 2:e2db05bc4708 112 };
amateusz 0:d58ebb2bed9a 113 //
amateusz 0:d58ebb2bed9a 114 // bool isMeasurementReady(){
amateusz 0:d58ebb2bed9a 115 // return (((unsigned)(_measurement.timestampMeasurementReadyAt - millis())>0)?false:true);
amateusz 0:d58ebb2bed9a 116 // };
amateusz 0:d58ebb2bed9a 117 //
amateusz 0:d58ebb2bed9a 118 // short unsigned int measurementReadyIn(){ // ms
amateusz 0:d58ebb2bed9a 119 // if (isMeasurementReady())
amateusz 0:d58ebb2bed9a 120 // return 0;
amateusz 0:d58ebb2bed9a 121 // else{
amateusz 0:d58ebb2bed9a 122 // return _measurement.timestampMeasurementReadyAt - millis();
amateusz 0:d58ebb2bed9a 123 // }
amateusz 0:d58ebb2bed9a 124 // };
amateusz 0:d58ebb2bed9a 125 //
amateusz 4:11438803516c 126 char readyIn() {
amateusz 4:11438803516c 127 return _measurement.readyIn;
amateusz 4:11438803516c 128 }
amateusz 4:11438803516c 129
amateusz 2:e2db05bc4708 130 bool read() {
amateusz 3:2847f7c543d3 131 char valuesAlreadyRead = 0;
amateusz 2:e2db05bc4708 132 std::string question = string("?") + string("D0") + string("!");
amateusz 2:e2db05bc4708 133 question[0] = _address;
amateusz 2:e2db05bc4708 134 _sdi12.sendCommand(question);
amateusz 2:e2db05bc4708 135
amateusz 2:e2db05bc4708 136 Timer timeout;
amateusz 2:e2db05bc4708 137 timeout.start();
amateusz 2:e2db05bc4708 138 while (sdi12.RxBufferAvailable() == 0) {
amateusz 2:e2db05bc4708 139 if (sdi12.RxInProgress()) timeout.reset();
amateusz 5:e53104570fde 140 if(timeout.read_ms() > RESPONSE_TIMEOUT) {
amateusz 2:e2db05bc4708 141 return false;
amateusz 2:e2db05bc4708 142 }
amateusz 2:e2db05bc4708 143 }
amateusz 2:e2db05bc4708 144 unsigned char bufferSize = sdi12.RxBufferAvailable();
amateusz 2:e2db05bc4708 145 char buffer[bufferSize+1];
amateusz 2:e2db05bc4708 146 sdi12.getRxBuffer(buffer);
amateusz 2:e2db05bc4708 147 buffer[bufferSize] = '\0';
amateusz 2:e2db05bc4708 148 std::string response(buffer);
amateusz 2:e2db05bc4708 149
amateusz 4:11438803516c 150 // debug("parser. recv: %s\r\n", response);
amateusz 3:2847f7c543d3 151 if (response[0] == _address) {
amateusz 3:2847f7c543d3 152 // parser here
amateusz 3:2847f7c543d3 153 response = response.substr(1); // to limit repeting this operation later. i.e. extract only values e.g. +21.3-123+123
amateusz 3:2847f7c543d3 154 // the only two possible delimeters of a value
amateusz 3:2847f7c543d3 155 size_t next_start_index = response.find_first_of("-+", 0);
amateusz 3:2847f7c543d3 156 size_t next_end_index;
amateusz 3:2847f7c543d3 157 // ready, steady, parse!!
amateusz 3:2847f7c543d3 158 while(next_start_index != std::string::npos) {
amateusz 3:2847f7c543d3 159 // determine start index:
amateusz 3:2847f7c543d3 160 next_end_index = response.find_first_of("-+", next_start_index + 1); // std::substr is prepared to take std::npos
amateusz 3:2847f7c543d3 161 float value = std::atof(response.substr(next_start_index, next_end_index).c_str());
amateusz 4:11438803516c 162 // debug("parsed: %f\r\n", value);
amateusz 4:11438803516c 163 _measurement.values[valuesAlreadyRead++] = value;
amateusz 3:2847f7c543d3 164 next_start_index = response.find_first_of("-+", next_end_index);
amateusz 3:2847f7c543d3 165 }
amateusz 3:2847f7c543d3 166 }
amateusz 4:11438803516c 167 return true;
amateusz 2:e2db05bc4708 168 }
amateusz 4:11438803516c 169
amateusz 4:11438803516c 170
amateusz 0:d58ebb2bed9a 171 //
amateusz 4:11438803516c 172 const unsigned char getMeasurementCount() {
amateusz 2:e2db05bc4708 173 return _measurement.count;
amateusz 2:e2db05bc4708 174 }
amateusz 2:e2db05bc4708 175
amateusz 4:11438803516c 176 const float getMeasurementValue(char which) {
amateusz 2:e2db05bc4708 177 return _measurement.values[which];
amateusz 2:e2db05bc4708 178 }
amateusz 2:e2db05bc4708 179
amateusz 0:d58ebb2bed9a 180 void setAddress(char address) {
amateusz 0:d58ebb2bed9a 181 _address = address;
amateusz 0:d58ebb2bed9a 182 };
amateusz 0:d58ebb2bed9a 183 //
amateusz 0:d58ebb2bed9a 184 //
amateusz 0:d58ebb2bed9a 185 private:
amateusz 5:e53104570fde 186 static const int RESPONSE_TIMEOUT = 15+1; // ms
amateusz 5:e53104570fde 187 static const std::string ADDRRICES; // as in index -> indices,
amateusz 5:e53104570fde 188
amateusz 0:d58ebb2bed9a 189 SDI12 &_sdi12;
amateusz 0:d58ebb2bed9a 190 char _address;
amateusz 5:e53104570fde 191 int _measurementEventId;
amateusz 0:d58ebb2bed9a 192 Measurement_struct _measurement;
amateusz 0:d58ebb2bed9a 193
amateusz 2:e2db05bc4708 194 EventQueue sensorQueue;
amateusz 2:e2db05bc4708 195
amateusz 1:6b1a21925a81 196 bool getIdentification(Identification_struct &ident) {
amateusz 1:6b1a21925a81 197 // _sdi12.sendCommand(std::string(_address) + "I!");
amateusz 1:6b1a21925a81 198 std::string question = "?I!";
amateusz 1:6b1a21925a81 199 question[0] = _address;
amateusz 1:6b1a21925a81 200 _sdi12.sendCommand(question);
amateusz 0:d58ebb2bed9a 201
amateusz 1:6b1a21925a81 202 Timer timeout;
amateusz 1:6b1a21925a81 203 timeout.start();
amateusz 1:6b1a21925a81 204 while (sdi12.RxBufferAvailable() == 0) {
amateusz 1:6b1a21925a81 205 if (sdi12.RxInProgress()) timeout.reset();
amateusz 5:e53104570fde 206 if(timeout.read_ms() > RESPONSE_TIMEOUT) {
amateusz 1:6b1a21925a81 207 return false;
amateusz 1:6b1a21925a81 208 }
amateusz 1:6b1a21925a81 209 }
amateusz 1:6b1a21925a81 210 unsigned char bufferSize = sdi12.RxBufferAvailable();
amateusz 1:6b1a21925a81 211 char buffer[bufferSize+1];
amateusz 1:6b1a21925a81 212 sdi12.getRxBuffer(buffer);
amateusz 1:6b1a21925a81 213 buffer[bufferSize] = '\0';
amateusz 1:6b1a21925a81 214 std::string response(buffer);
amateusz 0:d58ebb2bed9a 215
amateusz 1:6b1a21925a81 216 if (response[0] == _address) {
amateusz 1:6b1a21925a81 217 // e.g.: 113DECAGON GS3 402
amateusz 2:e2db05bc4708 218
amateusz 1:6b1a21925a81 219 ident.sdi_version = std::atoi(response.substr(1, 2).c_str());
amateusz 1:6b1a21925a81 220 std::string tempStr = response.substr(3, 8);
amateusz 1:6b1a21925a81 221 strcpy(ident.company, tempStr.c_str());
amateusz 1:6b1a21925a81 222
amateusz 1:6b1a21925a81 223 tempStr = response.substr(3+8, 6);
amateusz 1:6b1a21925a81 224 strcpy(ident.model, tempStr.c_str());
amateusz 1:6b1a21925a81 225
amateusz 1:6b1a21925a81 226 tempStr = response.substr(3+8+6, 3);
amateusz 1:6b1a21925a81 227 strcpy(ident.version, tempStr.c_str());
amateusz 1:6b1a21925a81 228 return true;
amateusz 0:d58ebb2bed9a 229 }
amateusz 1:6b1a21925a81 230 return false;
amateusz 1:6b1a21925a81 231 }
amateusz 0:d58ebb2bed9a 232
amateusz 5:e53104570fde 233 };
amateusz 5:e53104570fde 234
amateusz 5:e53104570fde 235 const std::string SDI12_device::ADDRRICES = "0123456789abcdefgijklmnoprstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ";