Home › Forums › Other Data Loggers › SDI-12 Library
- This topic has 10 replies, 3 voices, and was last updated 2020-03-20 at 10:33 AM by
Sara Damiano.
-
AuthorPosts
-
-
2020-02-22 at 2:08 PM #13844
quiqueapolo
ParticipantHi:
I am using this library SDI12. I’m trying to read SRS sensor from Decagon. The code used is the provided in the example codes call “d_simple_logger.ino”. The code works well and I can read all the sensors. However, the time to read all the sensors is too high. Due to the code takes 3-4 seconds for reading each sensors. I have 8 sensors attached. In this sense, the time required to read all sensors is around 25 seconds. Could someone tell me how to solve this problem?
-
2020-02-22 at 7:03 PM #13845
Shannon Hicks
ParticipantThat example goes through the list of available address to see if a sensor is attached that has a corresponding address, so it definitely takes awhile to go through the whole list. You could rewrite it to only go through the addresses of your sensors and not the entire list. But your sensors have a 600ms sample time (as stated in the datasheet), so you’ll need to add a little delay after that and then you’ll have the poll time, so I’d allow 1 second for each sensor, and with 8 sensors it’ll take 8 seconds total. Is that acceptable?
-
2020-02-22 at 7:10 PM #13846
quiqueapolo
ParticipantCould you tell me the lines I need to rewrite to read only my adress. I have 8 sensors with adress from 0 to 7.
-
2020-02-23 at 9:12 AM #13847
Shannon Hicks
ParticipantThat demo sketch is just a sample of how to talk to your sensors, there’s lots of stuff in there that you could trim out if you’re actually trying to collect data at a certain rate. What type of board are you using? Are you planning to store the data on a memory card or just print to the computer’s serial monitor? There’s a 10-second delay on the very last line of the sketch that isn’t needed if you’re trying to cut down on time between samples. Do you want to take one discrete reading from each sensor each time, or are you interested in taking several readings from each sensor an averaging them to limit the “noise” or variation between readings of each sensor? Are you sensors going to be powered continuously or do you want to turn them off between readings? Do you need a timestamp to go along with each data record?
-
2020-02-23 at 9:18 AM #13848
quiqueapolo
ParticipantI achieve to reduce the time to 8 seconds (see the code attached). I am storing the data in a Micro SD Card. The sensors will be powered continuously. I am using an Arduino UNO board. I am interesting in take on discrete reading from each sensor. In the code I also include a Melexis infrared thermometers.
Regards, Enrique
Attachments:
-
2020-02-28 at 11:44 AM #13868
Sara Damiano
ModeratorIs your goal to read all of your sensors and write to your SD card as fast as you possibly can? You could get faster readings by using concurrent sampling on the Decagons like this: https://github.com/EnviroDIY/Arduino-SDI-12/blob/master/examples/k_concurrent_logger/k_concurrent_logger.ino
-
2020-02-28 at 11:51 AM #13869
Sara Damiano
ModeratorRe-Wrote for you. I didn’t even test if it compiles, but this should get you going with concurrent measurements:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170/*The Sensor Orientation Index. This number is two when the sensor is upward facing, one when the sensor is downward facing, and zerowhen orientation is undetermined.*/#include <SDI12.h>#include <SD.h>#include <Wire.h>#include <DS3232RTC.h>#include <Adafruit_MLX90614.h>#define DATA_PIN 3SDI12 mySDI12(DATA_PIN);const int chipSelect = 10;unsigned long time;File logFile;Adafruit_MLX90614 sensor_52 = Adafruit_MLX90614(0x52);Adafruit_MLX90614 sensor_53 = Adafruit_MLX90614(0x53);Adafruit_MLX90614 sensor_03 = Adafruit_MLX90614(0x03);Adafruit_MLX90614 sensor_07 = Adafruit_MLX90614(0x07);// keeps track of the wait time for each active addressesuint8_t waitTime[8] = {0,};// keeps track of the time each sensor was starteduint32_t millisStarted[8] = {0,};// keeps track of the time each sensor will be readyuint32_t millisReady[8] = {0,};// How many sensors to readuint8_t numSensors = 8;void startConcurrentMeasurement(char i){String command = "";command += i;command += "C!"; // SDI-12 concurrent measurement command format [address]['C'][!]mySDI12.sendCommand(command);delay(30);// wait for acknowlegement with format [address][ttt (3 char, seconds)][number of measurments available, 0-9]String sdiResponse = "";delay(30);while (mySDI12.available()) // build response string{char c = mySDI12.read();if ((c != '\n') && (c != '\r')){sdiResponse += c;delay(5);}}mySDI12.clearBuffer();// find out how long we have to wait (in seconds).uint8_t wait = 0;wait = sdiResponse.substring(1, 4).toInt();uint8_t sensorNum = charToDec(i); // e.g. convert '0' to 0, 'a' to 10, 'Z' to 61.waitTime[sensorNum] = wait;millisStarted[sensorNum] = millis();millisReady[sensorNum] = millis() + wait * 1000;}void logSDI12Results(char i){String command = "";// in this example we will only take the 'DO' measurementcommand = "";command += i;command += "D0!"; // SDI-12 command to get data [address][D][dataOption][!]mySDI12.sendCommand(command);// wait for acknowlegementuint32_t startMillis = millis();while (!(mySDI12.available() > 7) && (millis() - startMillis < 5000L)){}mySDI12.read(); // throw away the repeated addresslogfile.print(mySDI12.readStringUntil('+')); // read and log red bandlogFile.print(";");logfile.print(mySDI12.readStringUntil('+')); // read and log nir bandlogFile.print(";");logfile.print(mySDI12.readStringUntil('\n')); // read and log orientationlogFile.print(";");printBufferToScreen();mySDI12.clearBuffer();}void setup(){Serial.begin(115200);sensor_52.begin();sensor_53.begin();sensor_03.begin();sensor_07.begin();Wire.begin();if (!SD.begin(chipSelect)){return;}while (!Serial);mySDI12.begin();delay(500);for (byte i = '0'; i <= '9'; i++)if (checkActive(i)){numSensors++;setTaken(i);}logFile = SD.open("hwheat.txt", FILE_WRITE);if (logFile){logFile.println("fecha;hora;r_red;r_nir;r_orientation;r_red;r_nir;r_orientation;r_red;r_nir;r_orientation;r_532;r_570;orientation;r_532;r_570;orientation;r_532;r_570;orientation;i_532;i_570;orientation;r_red;r_nir;r_orientation;Temp1;Temp2;Temp3;Temp4");logFile.close();}}void lectura_sensores(){logFile.print(sensor_52.readObjectTempC());logFile.print(";");logFile.print(sensor_53.readObjectTempC());logFile.print(";");logFile.print(sensor_03.readObjectTempC());logFile.print(";");logFile.println(sensor_07.readObjectTempC());}void loop(){time_t p;p = RTC.get();logFile = SD.open("hwheat.txt", FILE_WRITE);if (logFile){logFile.print(String(day(p)) + "/" + String(month(p)) + "/" + String(year(p)) + ";" + String(hour(p)) + ":" + String(minute(p)) + ":" + String(second(p)));// Start a concurrent measurement on all of the SDI-12 sensorsfor (char i = '0'; i < '8'; i++){startConcurrentMeasurement(i);}// get all readingsuint8_t numReadingsRecorded = 0;while (numReadingsRecorded < numSensors){for (char i = '0'; i < '8'; i++){if (millis() > millisReady[charToDec(i)]){logSDI12Results(i);numReadingsRecorded++;}}}logFile.print(";");lectura_sensores();logFile.close();}} -
2020-02-29 at 7:11 AM #13872
quiqueapolo
ParticipantHi Sara:
Thank you for your quickly answer. However, when I tried to compile the code several errors were shown (see images attached).
Regards, Enrique
Attachments:
-
2020-03-05 at 10:40 AM #13903
Sara Damiano
ModeratorDelete lines 112-117 of the code I posted.
-
2020-03-19 at 4:17 AM #13963
quiqueapolo
ParticipantHi again Sara:
I deleted the lines that you say in previous comment. However, the problem do not have solution.
Thanks in advance
-
2020-03-20 at 10:33 AM #13967
Sara Damiano
ModeratorMy intent was to help you by giving you an example of something you could modify to your needs, not to give you a final working program.
This version will compile. I don’t know if it will actually work for your sensors or log data as expected. You will need to test that.
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169#include <SDI12.h>#include <SD.h>#include <Wire.h>#include <DS3232RTC.h>#include <Adafruit_MLX90614.h>#define DATA_PIN 3SDI12 mySDI12(DATA_PIN);const int chipSelect = 10;unsigned long time;File logFile;Adafruit_MLX90614 sensor_52 = Adafruit_MLX90614(0x52);Adafruit_MLX90614 sensor_53 = Adafruit_MLX90614(0x53);Adafruit_MLX90614 sensor_03 = Adafruit_MLX90614(0x03);Adafruit_MLX90614 sensor_07 = Adafruit_MLX90614(0x07);// keeps track of the wait time for each active addressesuint8_t waitTime[8] = {0,};// keeps track of the time each sensor was starteduint32_t millisStarted[8] = {0,};// keeps track of the time each sensor will be readyuint32_t millisReady[8] = {0,};// How many sensors to readuint8_t numSensors = 8;// converts allowable address characters '0'-'9', 'a'-'z', 'A'-'Z',// to a decimal number between 0 and 61 (inclusive) to cover the 62 possible addressesbyte charToDec(char i){if((i >= '0') && (i <= '9')) return i - '0';if((i >= 'a') && (i <= 'z')) return i - 'a' + 10;if((i >= 'A') && (i <= 'Z')) return i - 'A' + 37;else return i;}void startConcurrentMeasurement(char i){String command = "";command += i;command += "C!"; // SDI-12 concurrent measurement command format [address]['C'][!]mySDI12.sendCommand(command);delay(30);// wait for acknowlegement with format [address][ttt (3 char, seconds)][number of measurments available, 0-9]String sdiResponse = "";delay(30);while (mySDI12.available()) // build response string{char c = mySDI12.read();if ((c != '\n') && (c != '\r')){sdiResponse += c;delay(5);}}mySDI12.clearBuffer();// find out how long we have to wait (in seconds).uint8_t wait = 0;wait = sdiResponse.substring(1, 4).toInt();uint8_t sensorNum = charToDec(i); // e.g. convert '0' to 0, 'a' to 10, 'Z' to 61.waitTime[sensorNum] = wait;millisStarted[sensorNum] = millis();millisReady[sensorNum] = millis() + wait * 1000;}void logSDI12Results(char i){String command = "";// in this example we will only take the 'DO' measurementcommand = "";command += i;command += "D0!"; // SDI-12 command to get data [address][D][dataOption][!]mySDI12.sendCommand(command);// wait for acknowlegementuint32_t startMillis = millis();while (!(mySDI12.available() > 7) && (millis() - startMillis < 5000L)){}mySDI12.read(); // throw away the repeated addresslogFile.print(mySDI12.readStringUntil('+')); // read and log red bandlogFile.print(";");logFile.print(mySDI12.readStringUntil('+')); // read and log nir bandlogFile.print(";");logFile.print(mySDI12.readStringUntil('\n')); // read and log orientationlogFile.print(";");mySDI12.clearBuffer();}void setup(){Serial.begin(115200);sensor_52.begin();sensor_53.begin();sensor_03.begin();sensor_07.begin();Wire.begin();if (!SD.begin(chipSelect)){return;}while (!Serial);mySDI12.begin();delay(500);logFile = SD.open("hwheat.txt", FILE_WRITE);if (logFile){logFile.println("fecha;hora;r_red;r_nir;r_orientation;r_red;r_nir;r_orientation;r_red;r_nir;r_orientation;r_532;r_570;orientation;r_532;r_570;orientation;r_532;r_570;orientation;i_532;i_570;orientation;r_red;r_nir;r_orientation;Temp1;Temp2;Temp3;Temp4");logFile.close();}}void lectura_sensores(){logFile.print(sensor_52.readObjectTempC());logFile.print(";");logFile.print(sensor_53.readObjectTempC());logFile.print(";");logFile.print(sensor_03.readObjectTempC());logFile.print(";");logFile.println(sensor_07.readObjectTempC());}void loop(){time_t p;p = RTC.get();logFile = SD.open("hwheat.txt", FILE_WRITE);if (logFile){logFile.print(String(day(p)) + "/" + String(month(p)) + "/" + String(year(p)) + ";" + String(hour(p)) + ":" + String(minute(p)) + ":" + String(second(p)));// Start a concurrent measurement on all of the SDI-12 sensorsfor (char i = '0'; i < '8'; i++){startConcurrentMeasurement(i);}// get all readingsuint8_t numReadingsRecorded = 0;while (numReadingsRecorded < numSensors){for (char i = '0'; i < '8'; i++){if (millis() > millisReady[charToDec(i)]){logSDI12Results(i);numReadingsRecorded++;}}}logFile.print(";");lectura_sensores();logFile.close();}}
-
-
AuthorPosts
- You must be logged in to reply to this topic.