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-07-27
- Revision:
- 2:e2db05bc4708
- Parent:
- 1:6b1a21925a81
- Child:
- 3:2847f7c543d3
File content as of revision 2:e2db05bc4708:
#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;
bool _measurementAlreadyRead;
char count;
float values[];
};
Identification_struct _ident_struct;
static int detect(SDI12 &sdi12, char indices[]) {
char found = 0;
for (char i = '1'; i < '9'; ++i) {
string question = "?!";
question[0] = i;
sdi12.sendCommand(question);
std::string response;
Timer detectTimer;
detectTimer.start();
while (sdi12.RxBufferAvailable() == 0)
if(detectTimer.read_ms() > 800) {
++i;
break;
}
unsigned char bufferSize = sdi12.RxBufferAvailable();
char buffer[bufferSize];
sdi12.getRxBuffer(buffer);
// if first char is valid address char
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));
};
// 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() > 100) {
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.timestampMeasurementReadyAt
debug("wait for %d measurement for %d seconds...", _measurement.count, waitFor);
sensorQueue.call_in(waitFor * 1000, callback(this, &SDI12_device::read));
if (_measurement.values == NULL) delete[] _measurement.values;
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();
// }
// };
//
bool read() {
char alreadyRead = 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() > 100) {
return false;
}
}
unsigned char bufferSize = sdi12.RxBufferAvailable();
char buffer[bufferSize+1];
sdi12.getRxBuffer(buffer);
buffer[bufferSize] = '\0';
std::string response(buffer);
debug("parser");
// if (response[0] == _address) {
// debug("parser");
// // parser here
// response = response.substr(1); // to limit repeting this operation later
// // the only two possible delimeters of a value
// uint8_t start_index = 0;
//
// int8_t index_pos = response.indexOf('+', start_index);
// int8_t index_neg = response.indexOf('-', start_index);
//
// Serial.println(index_pos);
// Serial.println(index_pos);
//
// do {
// // determine start index:
// if (index_pos != -1 && index_neg != -1) start_index = min(index_pos,index_neg);
// else if (index_pos == -1) start_index = index_neg;
// else if (index_neg == -1) start_index = index_pos;
//
// int8_t index_pos_next = response.indexOf('+', start_index +1);
// int8_t index_neg_next = response.indexOf('-', start_index +1);
//
// uint8_t end_index;
// if (index_pos_next != -1 && index_neg_next != -1) end_index = min(index_pos_next,index_neg_next);
// else if (index_pos_next == -1) end_index = index_neg_next;
// else if (index_neg_next == -1) end_index = index_pos_next;
//
// _measurement.values[alreadyRead++] = response.substr(start_index, end_index).toFloat();
//
// index_pos = response.indexOf('+', start_index);
// index_neg = response.indexOf('-', start_index);
// } while(index_pos != -1 || index_neg != -1);
// }
}
//
unsigned char getMeasurementCount() {
return _measurement.count;
}
float getMeasurementValue(char which) {
return _measurement.values[which];
}
void setAddress(char address) {
_address = address;
};
//
//
private:
SDI12 &_sdi12;
char _address;
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() > 20) {
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());
debug("|%d| /%s/\r\n",ident.sdi_version ,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;
}
};