Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SDI12_device.h
- Committer:
- amateusz
- Date:
- 2018-08-01
- Revision:
- 6:d9a5240a99fd
- Parent:
- 5:e53104570fde
- Child:
- 7:1f506c65c4e8
File content as of revision 6:d9a5240a99fd:
#include "SDI12.h" #include <string> #include "mbed.h" class SDI12_device { public: struct Identification_struct { unsigned char sdi_version; char company[8+1]; char model[6+1]; char version[3+1]; }; struct Measurement_struct { unsigned long timestampMeasurementReadyAt; char readyIn; bool _measurementAlreadyRead; char count; float values[48]; // not float values [] !! :O }; Identification_struct _ident_struct; static int detect(SDI12 &sdi12, char indices[]) { char found = 0; for (size_t i = 0; i < ADDRRICES.size(); ++i) { string question = "?!"; question[0] = ADDRRICES[i]; sdi12.sendCommand(question); std::string response; Timer detectTimer; detectTimer.start(); while (sdi12.RxBufferAvailable() == 0) { if (sdi12.RxInProgress()) detectTimer.reset(); if (detectTimer.read_ms() > RESPONSE_TIMEOUT) { break; } } unsigned char bufferSize = sdi12.RxBufferAvailable(); char buffer[bufferSize]; sdi12.getRxBuffer(buffer); // if first char is valid address char if (ADDRRICES.find(buffer[0])) { // if (buffer[0] >= '0' && buffer[0] <= '9' || // buffer[0] >= 'a' && buffer[0] <= 'z' || // buffer[0] >= 'A' && buffer[0] <= 'Z') { indices[found++] = buffer[0]; } } return found; }; SDI12_device (SDI12 &inst, char address, EventQueue &mainDispatcher) : _sdi12(inst) { setAddress(address); sensorQueue.chain(&mainDispatcher); if(getIdentification(_ident_struct)); }; ~SDI12_device () { // unchain event queue sensorQueue.cancel(_measurementEventId); sensorQueue.chain(NULL); } // void printIdentification(){ // Serial.println(_ident_struct.company); // Serial.println(_ident_struct.model); // Serial.println(_ident_struct.version); // } // // // returns after how many seconds a measurement will be ready int measure(bool concurrent = true) { std::string question = string("?") + string(concurrent?"C":"M") + string("!"); question[0] = _address; _sdi12.sendCommand(question); Timer timeout; timeout.start(); while (sdi12.RxBufferAvailable() == 0) { if (sdi12.RxInProgress()) timeout.reset(); if(timeout.read_ms() > RESPONSE_TIMEOUT) { return false; } } unsigned char bufferSize = sdi12.RxBufferAvailable(); char buffer[bufferSize+1]; sdi12.getRxBuffer(buffer); buffer[bufferSize] = '\0'; std::string response(buffer); if (response[0] == _address) { char measurementsCount = std::atoi(response.substr(1+3,(concurrent?2:1)).c_str()); char waitFor = std::atoi(response.substr(1,3).c_str()); _measurement.count = measurementsCount; _measurement.readyIn = waitFor; // _measurement.timestampMeasurementReadyAt debug("wait for %d measurement for %d seconds...", _measurement.count, waitFor); _measurementEventId = sensorQueue.call_in(waitFor * 1000, callback(this, &SDI12_device::read)); debug("measurement scheduled"); // if (_measurement.values != NULL) delete[] _measurement.values; // _measurement.values = new float[measurementsCount]; return 0; } return -1; }; // // bool isMeasurementReady(){ // return (((unsigned)(_measurement.timestampMeasurementReadyAt - millis())>0)?false:true); // }; // // short unsigned int measurementReadyIn(){ // ms // if (isMeasurementReady()) // return 0; // else{ // return _measurement.timestampMeasurementReadyAt - millis(); // } // }; // char readyIn() { return _measurement.readyIn; } bool read() { char valuesAlreadyRead = 0; std::string question = string("?") + string("D0") + string("!"); question[0] = _address; _sdi12.sendCommand(question); Timer timeout; timeout.start(); while (sdi12.RxBufferAvailable() == 0) { if (sdi12.RxInProgress()) timeout.reset(); if(timeout.read_ms() > RESPONSE_TIMEOUT) { return false; } } unsigned char bufferSize = sdi12.RxBufferAvailable(); char buffer[bufferSize+1]; sdi12.getRxBuffer(buffer); buffer[bufferSize] = '\0'; std::string response(buffer); // debug("parser. recv: %s\r\n", response); if (response[0] == _address) { // parser here response = response.substr(1); // to limit repeting this operation later. i.e. extract only values e.g. +21.3-123+123 // the only two possible delimeters of a value size_t next_start_index = response.find_first_of("-+", 0); size_t next_end_index; // ready, steady, parse!! while(next_start_index != std::string::npos) { // determine start index: next_end_index = response.find_first_of("-+", next_start_index + 1); // std::substr is prepared to take std::npos float value = std::atof(response.substr(next_start_index, next_end_index).c_str()); // debug("parsed: %f\r\n", value); _measurement.values[valuesAlreadyRead++] = value; next_start_index = response.find_first_of("-+", next_end_index); } } return true; } // const unsigned char getMeasurementCount() { return _measurement.count; } const float getMeasurementValue(char which) { return _measurement.values[which]; } void setAddress(char address) { _address = address; }; // // private: static const int RESPONSE_TIMEOUT = 15+1; // ms static const std::string ADDRRICES; // as in index -> indices, SDI12 &_sdi12; char _address; int _measurementEventId; Measurement_struct _measurement; EventQueue sensorQueue; bool getIdentification(Identification_struct &ident) { // _sdi12.sendCommand(std::string(_address) + "I!"); std::string question = "?I!"; question[0] = _address; _sdi12.sendCommand(question); Timer timeout; timeout.start(); while (sdi12.RxBufferAvailable() == 0) { if (sdi12.RxInProgress()) timeout.reset(); if(timeout.read_ms() > RESPONSE_TIMEOUT) { return false; } } unsigned char bufferSize = sdi12.RxBufferAvailable(); char buffer[bufferSize+1]; sdi12.getRxBuffer(buffer); buffer[bufferSize] = '\0'; std::string response(buffer); if (response[0] == _address) { // e.g.: 113DECAGON GS3 402 ident.sdi_version = std::atoi(response.substr(1, 2).c_str()); std::string tempStr = response.substr(3, 8); strcpy(ident.company, tempStr.c_str()); tempStr = response.substr(3+8, 6); strcpy(ident.model, tempStr.c_str()); tempStr = response.substr(3+8+6, 3); strcpy(ident.version, tempStr.c_str()); return true; } return false; } }; const std::string SDI12_device::ADDRRICES = "0123456789abcdefgijklmnoprstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ";