Code Monkey home page Code Monkey logo

envirodiy / arduino-sdi-12 Goto Github PK

View Code? Open in Web Editor NEW
154.0 154.0 99.0 7.24 MB

An Arduino library for SDI-12 communication with a wide variety of environmental sensors. This library provides a general software solution, without requiring any additional hardware.

Home Page: https://github.com/EnviroDIY/Arduino-SDI-12/wiki

License: BSD 3-Clause "New" or "Revised" License

C++ 94.70% Shell 5.30%
arduino-library environmental-monitoring environmental-sensors

arduino-sdi-12's People

Contributors

aufdenkampe avatar bleckers avatar dependabot[bot] avatar diegogmx avatar dwasielewski avatar eddyrodrigues avatar foundouck avatar gabbas1 avatar kevin-m-smith avatar majenkotech avatar manhere avatar per1234 avatar peterj43 avatar s-hicks2 avatar scottensign avatar srgdamia1 avatar stephencatsamas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduino-sdi-12's Issues

inconsistent results

Hello,

I have used this library to communicate and get results from an SDI-12 based sensor(Decagon 5TM). after collecting Ea and VWC data for about 4 days i decided to check the data and noticed the results are not consistent. as shown bellow in the plot. has any one had such results? please help.
image

Compatibility with ESP8266

Hello,
I would like to know if it already exists, there are plans to develop it with an estimated date of publication, the compatibility of this library with the ESP8266 chip

Thank you
regards
Matias Alvarez Sabate

Data read error

Hello, I am trying to read the data from a LUFFT 600 weather station or a Hydrolab DS5x probe but I have been able, even if I connect the SDI-12 data pin to any of the pins of the arduino it does not recognize it. How much I achieved was what is sampled in the image and nothing else. Using an OTT datalogger if it was possible to observe the data.
image

CRC Validation for SDI12 v1.4

Hi,

Currently, I'm using Metergroup SDI-12 soil sensors (Teros 11 - Teros 12)

Using examples to get measurements from the sensor, I sometimes have some “bad” values returning -68 for soil moisture and 0 for temperature. Is it usual to have some “errors” during measurement with the Sensor like Teros 11-12? Is it a bad initialization? I could repeat measurement until a value is different from -68 in my code, but this is a trick, and it will just mask the real problem.

Adding a Direction Control Pin

It would be great if the SDI-12 object constructor can take in an optional pin argument to control the direction of the flow of data. This is useful if a 3.3V or lower voltage controller is used with the SDI-12 bus. This pin is used to put up conversion voltage translation IC like a SN74AHCT1G125 output pin into high impedance mode when the controller is not in transmitting mode but in receiving mode (use an IC like SN74LVC1G17 which is running at 3.3V but is a Schmitt-trigger and over voltage tolerant input to 5V but doesn't require any direction control). I believe this can be added in the SDI-12 mode control function using a compile time #ifdef?

Corrupted data on SDI-12 interface

While trying SDI-12 library with 2 Arduino nano boards, one as an SDI-12 slave and another as a Datalogger, I am getting junk values on the device serial monitor while requesting for data (D0!)

I am using the default examples:
Datalogger - f_basic_data_request
Sensor - h_SDI-12_slave_implementation

image

Any idea on what could be causing these errors? I am not sure if it's on the SDI data line or data corruption or the serial print issues.

YSI 600 communication

First off, thanks for your contribution with this library. I have recently started using Arduino based data loggers in my work for Duke University's River Center and it has been very helpful. While I have had no issues communicating with other sensors, I have not been able to successfully communicate with the YSI 600. I noticed that you mentioned testing the library with a YSI in a google group. Do you have any code you could share or general tips on communicating with the YSI 600 through Arduino?

I've also emailed you and I apologize for hassling you.

Thanks,
Joseph

not working with mkr1300

Hi, I am trying sdi12 with mkr1300 board, The probe is getting detected and when I read the sensor data only battery voltage is coming. but temperature salinity and moisture values are not coming. If the clock was the issue then why the battery voltage is coming. Can you help me how to make It work with mkr1300

ATmega328p using 8MHz internal oscillator

Hello!

I am trying to make a sensor-node based on the ATmega328p running on the internal oscillator. I have burned the relevant bootloader from here, but when I try to run the SDI-12 library, almost all the characters are wrong (and some are dropped). I have tried calibrating the oscillator and playing with the RX_WINDOW_FUDGE with little success. Everything works as expected when I use a 16MHz external oscillator.

The readings are however consistently wrong (for a given message, the same incorrect message is displayed every time), leading me to think that it is possible to make it work, with the right combination of settings. Have you tried using the library with an internal oscillator before, or do you have any advice on the best procedure for debugging this issue?

Thanks for all input!

Example with SDI-12 Sonde

I am trying to use your library to develop a datalogger that controls the 6600 V2 probe from YSI. I tried to use the example a from your library, wild card, but got no answers.
I have the following question: My probe is powered by 12 volts, and the power pin provides only 5 volts. Can I feed it externally, excluding the following section of the code that feeds the probe?

if(POWER_PIN > 0){ Serial.println("Powering up sensors..."); pinMode(POWER_PIN, OUTPUT); digitalWrite(POWER_PIN, HIGH); delay(200);

PS: If you can do that, is it necessary for the arduino to share the same external power?

Attached is a printout of the Arduino's serial response to the code.

I apologize if the doubts are simple, I have been trying to communicate my probe with the Arduino for a considerable time and I can't.

Sincerely,
Augusto Almeida
image

SDI-12 Data error

屏幕截图 2021-05-13 140909

#include <SDI12.h>

#define SERIAL_BAUD 9600 /*!< The baud rate for the output serial port */
#define DATA_PIN 7         /*!< The pin of the SDI-12 data bus */

/** Define the SDI-12 bus */
SDI12 mySDI12(DATA_PIN);

String myCommand = "?I!";

void setup() {
  Serial.begin(SERIAL_BAUD);
  while (!Serial)
    ;

  Serial.println("Opening SDI-12 bus...");
  mySDI12.begin();
  delay(500);  // allow things to settle
}

void loop() {
  mySDI12.sendCommand(myCommand);
  delay(300);                    // wait a while for a response
  while (mySDI12.available()) {  // write the response to the screen
    Serial.write(mySDI12.read());
  }
  delay(2000);
}

NodeMCU Compatibility

Hi,

first of all thank you for the great work put inside this library.

I'm trying to use the library with NodeMCU module I successfully read from a sensor using arduino uno, but while connecting the nodemcu to the sensor and flash this code :

the serial log return : console log

could someone help with this

Thank you


#define SERIAL_BAUD 9600 /*!< The baud rate for the output serial port */
#define DATA_PIN 5         /*!< The pin of the SDI-12 data bus */
#define POWER_PIN 4       /*!< The sensor power pin (or -1 if not switching power) */

/** Define the SDI-12 bus */
SDI12 mySDI12(DATA_PIN);

/**
  '?' is a wildcard character which asks any and all sensors to respond
  'I' indicates that the command wants information about the sensor
  '!' finishes the command
*/
String myCommand = "?I!";

void setup() {
  Serial.begin(SERIAL_BAUD);
  while (!Serial)
    ;

  Serial.println("Opening SDI-12 bus...");
  mySDI12.begin();
  delay(500);  // allow things to settle

  // Power the sensors;
  if (POWER_PIN > 0) {
    Serial.println("Powering up sensors...");
    pinMode(POWER_PIN, OUTPUT);
    digitalWrite(POWER_PIN, HIGH);
    delay(200);
  }
}

void loop() {
  mySDI12.sendCommand(myCommand);
  delay(300);                    // wait a while for a response
  while (mySDI12.available()) {  // write the response to the screen
    Serial.write(mySDI12.read());
  }
  delay(3000);  // print again in three seconds
}```



NRF52 Support

Hello,
I was looking to add my Adafruit NRF52 bluefruit board and am having trouble setting up the timer registers. The NRF52 has a NRF_TIMER0 type definition where there are separate registers that set the prescaler, start the timer etc. But, the issue that I am having is that when I initialize the NRF_TIMER0 it does not begin to count and hangs in the comparison while loops such as the one in write char

while((uint32_t)(NRF_TIMER0_BASE) < txBitWidth) {}

This is an example of where the timer causes the code to hang.

This is how I initialize the timer

void SDI12::init_timer(void) {
  NRF_TIMER1->TASKS_STOP = 1;
  NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
  NRF_TIMER1->BITMODE = (TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos);
  NRF_TIMER1->PRESCALER = 0b00001011;

  NRF_TIMER1->TASKS_CLEAR = 1;
  NRF_TIMER1->CC[0] = TIMEOUT * 1000;

  NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;

  NRF_TIMER1->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
  NRF_TIMER1->TASKS_START = 1;
}

Issue on compilation // Sodaq Explorer - 32 Bits - Cortex M0+

Hi,

I don't know if you're library is compatible with Cortex M0+ (SAMD21J18), it's board with LoRa modem (Low Band), and bluetooth.
In first time, when i selected this type of board, the IDE put your library in not compatible directory, when i take a sample and i try to compile, i have this errors:

Compilation du croquis...
"/Users/pascalchignon/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD -DF_CPU=48000000L -DARDUINO=10802 -DARDUINO_SODAQ_EXPLORER -DARDUINO_ARCH_SAMD -D__SAMD21J18A__ -DUSB_VID=0x2341 -DUSB_PID=0x804d -DUSBCON '-DUSB_MANUFACTURER="SODAQ"' '-DUSB_PRODUCT="SODAQ ExpLoRer"' "-I/Users/pascalchignon/Library/Arduino15/packages/arduino/tools/CMSIS/4.5.0/CMSIS/Include/" "-I/Users/pascalchignon/Library/Arduino15/packages/arduino/tools/CMSIS-Atmel/1.1.0/CMSIS/Device/ATMEL/" "-I/Users/pascalchignon/Library/Arduino15/packages/SODAQ/hardware/samd/1.6.14/cores/arduino" "-I/Users/pascalchignon/Library/Arduino15/packages/SODAQ/hardware/samd/1.6.14/variants/sodaq_explorer" "-I/Users/pascalchignon/Documents/Arduino/libraries/SDI12" "/var/folders/b_/fzlgd0l12f79w7x8vsjv411w0000gn/T/arduino_build_659337/sketch/e_simple_parsing.ino.cpp" -o "/var/folders/b_/fzlgd0l12f79w7x8vsjv411w0000gn/T/arduino_build_659337/sketch/e_simple_parsing.ino.cpp.o"
In file included from /Users/pascalchignon/Documents/Arduino/libraries/Arduino-SDI-12-develop/examples/e_simple_parsing/e_simple_parsing.ino:57:0:
/Users/pascalchignon/Documents/Arduino/libraries/SDI12/SDI12.h:63:5: error: 'KINETISK_UART_t' does not name a type
KINETISK_UART_t REG;
^
/Users/pascalchignon/Documents/Arduino/libraries/SDI12/SDI12.h: In constructor 'UART::UART()':
/Users/pascalchignon/Documents/Arduino/libraries/SDI12/SDI12.h:44:9: error: class 'UART' does not have any field named 'REG'
REG( nullptr ),
^
/Users/pascalchignon/Documents/Arduino/libraries/Arduino-SDI-12-develop/examples/e_simple_parsing/e_simple_parsing.ino: At global scope:
e_simple_parsing:60: error: invalid conversion from 'int' to 'Stream
' [-fpermissive]
SDI12 mySDI12(DATAPIN);
^
In file included from /Users/pascalchignon/Documents/Arduino/libraries/Arduino-SDI-12-develop/examples/e_simple_parsing/e_simple_parsing.ino:57:0:
/Users/pascalchignon/Documents/Arduino/libraries/SDI12/SDI12.h:90:5: error: initializing argument 1 of 'SDI12::SDI12(Stream*)' [-fpermissive]
SDI12( Stream *port ) {
^
If you hava an idea, of the problem, i need to do a POC, read a Aquacheck 4 probes ( 2 xTemp & 2 x humidity), and transfer this informations with the modem.

Regards,

Documentation missing?

It says: "Full details on the library functionality can be found on github pages: https://envirodiy.github.io/Arduino-SDI-12/ "
But that loops back to the same https://envirodiy.github.io/Arduino-SDI-12/ page, and it seems to only contain info about history and supported chips and conflicts and limitations, with no information on how to actually USE the library...

I don't see any usage documentation in the source repository either, although there might be some Doxygen scripts that are supposed to extract it.

Lockup on SAMD Based Arduino MKR 1500

I am experiencing a lockup issue with the operation of this library on the newer MKR 1500 (ATSAMD21G18 based).
This happens with the verbatim check_all_addresses example and current version of the library when you try to do any SDI-12 operations.

At first I thought it might be clock gen/TC conflicts, but running the configSDI12TimerPrescale on it's own works just fine. Then I thought it might be the USB CDC interface being problematic with the way the global interrupts are being disabled, but disabling all Serial operations (just had an LED set up to blink after each operation) doesn't stop the lockups.

These lockups happen just the standalone board (nothing is connected to any pins and just being powered from 5V) or with USB connected.

The differences between the Zero and MKR 1500 are here in the variants files (left is Zero, right is MKR1500) - variant.h - https://www.diffchecker.com/3s0SIx1t , variant.cpp - https://www.diffchecker.com/iWa7l4fq

These are the same files as the ones in here - https://github.com/arduino/ArduinoCore-samd/tree/master/variants

This is being compiled with Arduino 1.8.6 and v1.8.3 of the SAMD boards libraries.

Is there anything that I am missing?

SDI-12 and SoftwareSerial Compatibility Issues

Problem Overview

Refresher on Interrupts

  • The problem is a conflict between the SoftwareSerial library packaged with the Arduino IDE and the SDI-12 library.
  • Both libraries use pin change interrupts (PCINT) to detect when a signal is being received.
  • If something (a switch or a signal) causes the state of a pin to change, an
    "interrupt service routine" (ISR) is triggered. This quickly stops execution of the main
    program and runs the code you have written in the ISR.
  • While pin change interrupts (PCINT) are available on all pins of the Arduino Uno, there are only three different PCINT Request Vectors, which are triggered are hardwired groupings of pins called ports.
  • On the Arduino UNO, there are three such ports:
    • Digital Pins 0-7 - Port D - PCINT2
    • Digital Pins 8-13 - Port B - PCINT0
    • Analog Pins A0-A5 - Port C - PCINT1
  • Take Aways:
    • Each PCINT Request Vector can only be assigned one ISR.
    • Each PCINT Request Vector represents a hardwired grouping of pins.

Library Conflicts

If you look at the SoftwareSerial library:
https://github.com/arduino/Arduino/blob/master/libraries/SoftwareSerial/SoftwareSerial.cpp

In SoftwareSerial.cpp:

#if defined(PCINT0_vect)
ISR(PCINT0_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif

#if defined(PCINT1_vect)
ISR(PCINT1_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif

#if defined(PCINT2_vect)
ISR(PCINT2_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif

#if defined(PCINT3_vect)
ISR(PCINT3_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif

Code Interpretation

  • This essentially checks which PCINT Request Vectors (ports) the hardware has access to and assigns them all to the same ISR defined by the SoftwareSerial library. Note: The Arduino Uno only has the following three PCINT Request Vectors: PCINT0, PCINT1, PCINT2, available, but other hardware may have access to more.
  • The trouble is that for simplicity's sake, the SoftwareSerial library has claimed all of the PCINT Request Vectors. If we want to use the SDI-12 library with the SoftwareSerial library, we will have to give at least one of those PCINT Request Vectors up. Note: For simplicity's sake, the SDI-12 library also claims all of the available PCINT Request Vectors. So we will have to take a complementary action (i.e. give up at least one PCINT vector).

Stopgap Fix

As an example:

  • SoftwareSerial is set up on pins 2 and 3.
  • SDI-12 is set up on pin 9.

Pins 2 and 3 map to the PCINT Request Vector PCINT2. As a simple fix we can comment out the sections of code we are not using. (You may want to include a note as to why you changed it.)

In SoftwareSerial.cpp:

// Last edit: June 30th, 2014 by KMS
// Lines in this block are commented out
// because PCINT0, PCINT1, and PCINT3 
// are not used by SoftwareSerial for this
// project. 
//#if defined(PCINT0_vect)
//ISR(PCINT0_vect)
//{
//  SoftwareSerial::handle_interrupt();
//}
//#endif

//#if defined(PCINT1_vect)
//ISR(PCINT1_vect)
//{
//  SoftwareSerial::handle_interrupt();
//}
//#endif

#if defined(PCINT2_vect)
ISR(PCINT2_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif

//#if defined(PCINT3_vect)
//ISR(PCINT3_vect)
//{
//  SoftwareSerial::handle_interrupt();
//}
//#endif

Next, we are going to do the complementary action in the SDI-12 Library. Since we are using pin 9 for SDI-12, we only need to assign our ISR to PCINT Request Vector PCINT0.

In SDI12.cpp:

// Last edit: June 30th, 2014 by KMS
// Lines in this block are commented out
// because PCINT1, PCINT2, and PCINT3 
// are not used by SDI-12 for this
// project. 
//6.3
#if defined(PCINT0_vect)
ISR(PCINT0_vect){ SDI12::handleInterrupt(); }
#endif

//#if defined(PCINT1_vect)
//ISR(PCINT1_vect){ SDI12::handleInterrupt(); }
//#endif

//#if defined(PCINT2_vect)
//ISR(PCINT2_vect){ SDI12::handleInterrupt(); }
//#endif

//#if defined(PCINT3_vect)
//ISR(PCINT3_vect){ SDI12::handleInterrupt(); }
//#endif

Restart the Arduino IDE, and it should recognize the changes to the libraries and your code should compile without issue.

Towards A Better Fix?

Limitations

  • The PCINT structure represents a physical limitation that does not allow SoftwareSerial and SDI-12 to share some groupings of pins (as in port mapping shown above).
  • The PCINT structure (pin to port mapping) is hardware specific (e.g. Arduino Uno vs. Arduino Mega) so it is tricky to determine at compile time if SoftwareSerial or SDI-12 are claiming pins on the same port.

Desires

  • The user should not have to modify the core SoftwareSerial library since this will likely break compatibility with other projects.
  • It would also be ideal if the user did not need to edit the SDI-12 library, since different projects may require different configurations.

Potential Options?

  • Package a complimentary and compatible SoftwareSerial library with the SDI-12 library and use a clever set of #define statements to determine how to map pins to ports.
  • Others?

Looking forward to your thoughts.

Help SDI-12 Communication

Hello,

I am developing a project in which I will use SDI-12 sensors, but i will also use sensors that do not use any communication protocol and the aim is to mete them respond as if they were an SDI-12 sensor. For that, I will use an Arduino (where i will put the sensors that are not SDI-12) that receives requests from another arduino and respode as if it is an SDI-12 with measurements from sensors placed there.
I am using a library SDI-12 developed by you, but I am with difficulties in putting the Arduino to respond to commands ...
Will could help me?
Sorry for bad english, but it is not my language: s

Best regards.

Sparkfun Artemis and CS320 pyranometer

Hi All, I've come across a sensor that communicates through SDI-12 and would be great to use a microcontroller to log the data.

Has anyone got experience using the CS320 pyranometer (Campbell Scientific) with the SDI-12 library?
Also, any experience with the SDI-12 library and the Sparkfun Artemis? @jerabaul29

Any feedback much appreciated

IDE 2.0 compilation problem

Hello I have started to use Arduino IDE 2.0 Beta but I get compilation errors below, I have tried to compile with Arduino IDE 1.8.13 I get no errors for compilation. What could be the problem?

Thanks in advance,

SDI12.cpp:139:35: error: 'TICKS_PER_BIT' was not declared in this scope static const uint8_t txBitWidth = TICKS_PER_BIT;
SDI12.cpp:140:38: error: 'RX_WINDOW_FUDGE' was not declared in this scope static const uint8_t rxWindowWidth = RX_WINDOW_FUDGE; // A fudge factor to make things work
SDI12.cpp:141:40: error: 'BITS_PER_TICK_Q10' was not declared in this scope
static const uint8_t bitsPerTick_Q10 = BITS_PER_TICK_Q10;
^~~~~~~~~~~~~~~~~
SDI12.cpp: In member function 'void SDI12::begin()':
SDI12.cpp:433:3: error: 'configSDI12TimerPrescale' was not declared in this scope
configSDI12TimerPrescale();
^~~~~~~~~~~~~~~~~~~~~~~~
SDI12.cpp: In member function 'void SDI12::end()':
SDI12.cpp:446:3: error: 'resetSDI12TimerPrescale' was not declared in this scope
resetSDI12TimerPrescale();
^~~~~~~~~~~~~~~~~~~~~~~
SDI12.cpp: At global scope:
SDI12.cpp:150:17: warning: 'uint16_t mul8x8to16(uint8_t, uint8_t)' defined but not used [-Wunused-function]
static uint16_t mul8x8to16(uint8_t x, uint8_t y)

AVR 1284P @4Mhz which #define RX_WINDOW_FUDGE to be set in .h?

Hi,
I'm testing the library running on a AVR 1284P @ 4 Mhz.
I would use the following setting but I don' understand the parameter RX_WINDOW_FUDGE in the .h file
Is a value of 20 for my case fine?

Many thanks for the support,
Kind Regards,

Martino

#if F_CPU == 16000000L
    #define PRESCALE_IN_USE_STR "1024"
    #define TICKS_PER_BIT 13
        // 16MHz / 1024 prescaler = 15624 'ticks'/sec = 64 µs / 'tick'
        // (1 sec/1200 bits) * (1 tick/64 µs) = 13.0208 ticks/bit
    #define BITS_PER_TICK_Q10 79
        // 1/(13.0208 ticks/bit) * 2^10 = 78.6432
    #define RX_WINDOW_FUDGE 2

    static uint8_t preSDI12_TCCR2A;
    static uint8_t preSDI12_TCCR2B;
    void configSDI12TimerPrescale(void)
    {
        preSDI12_TCCR2A = TCCR2A;
        preSDI12_TCCR2B = TCCR2B;
        TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
        TCCR2B = 0x07;  // TCCR2B = 0x07 = 0b00000111 - Clock Select bits 22, 21, & 20 on - prescaler set to CK/1024
    }
    void resetSDI12TimerPrescale(void)
    {
        TCCR2A = preSDI12_TCCR2A;
        TCCR2B = preSDI12_TCCR2B;
    }


#elif F_CPU == 8000000L
    #define PRESCALE_IN_USE_STR "256"
    #define TICKS_PER_BIT 26
        // 8MHz / 256 prescaler = 31250 'ticks'/sec = 32 µs / 'tick'
        // (1 sec/1200 bits) * (1 tick/32 µs) = 26.04166667 ticks/bit
    #define BITS_PER_TICK_Q10 39
        // 1/(26.04166667 ticks/bit) * 2^10 = 39.3216
    #define RX_WINDOW_FUDGE 10

    static uint8_t preSDI12_TCCR2A;
    static uint8_t preSDI12_TCCR2B;
    void configSDI12TimerPrescale(void)
    {
        preSDI12_TCCR2A = TCCR2A;
        preSDI12_TCCR2B = TCCR2B;
        TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
        TCCR2B = 0x06;  // TCCR2B = 0x06 = 0b00000110 - Clock Select bits 22 & 20 on - prescaler set to CK/256
    }
    void resetSDI12TimerPrescale(void)
    {
        TCCR2A = preSDI12_TCCR2A;
        TCCR2B = preSDI12_TCCR2B;
    }

    // #define PRESCALE_IN_USE_STR "1024"
    // #define TICKS_PER_BIT 6
    //     // 8MHz / 1024 prescaler = 31250 'ticks'/sec = 128 µs / 'tick'
    //     // (1 sec/1200 bits) * (1 tick/128 µs) = 6.5104166667 ticks/bit
    // #define BITS_PER_TICK_Q10 157
    //     // 1/(6.5104166667 ticks/bit) * 2^10 = 157.2864
    // #define RX_WINDOW_FUDGE 5

    // uint8_t preSDI12_TCCR2A;
    // uint8_t preSDI12_TCCR2B;
    // void configSDI12TimerPrescale(void)
    // {
    //     preSDI12_TCCR2A = TCCR2A;
    //     preSDI12_TCCR2B = TCCR2B;
    //     TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
    //     TCCR2B = 0x07;  // TCCR2B = 0x07 = 0b00000111 - Clock Select bits 22, 21, & 20 on - prescaler set to CK/1024
    // }
    // void resetSDI12TimerPrescale(void)
    // {
    //     TCCR2A = preSDI12_TCCR2A;
    //     TCCR2B = preSDI12_TCCR2B;
    // }

// xSense AVR 1284P
#elif F_CPU == 4000000L
    #define PRESCALE_IN_USE_STR "256"
    #define TICKS_PER_BIT 13
        // 4MHz / 256 prescaler = 15625 'ticks'/sec = 64 µs / 'tick'
        // (1 sec/1200 bits) * (1 tick/64 µs) = 13.02083333 ticks/bit
    #define BITS_PER_TICK_Q10 79
        // 1/(26.04166667 ticks/bit) * 2^10 = 78.6432
    #define RX_WINDOW_FUDGE 20

    static uint8_t preSDI12_TCCR2A;
    static uint8_t preSDI12_TCCR2B;
    void configSDI12TimerPrescale(void)
    {
        preSDI12_TCCR2A = TCCR2A;
        preSDI12_TCCR2B = TCCR2B;
        TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
        TCCR2B = 0x06;  // TCCR2B = 0x06 = 0b00000110 - Clock Select bits 22 & 20 on - prescaler set to CK/256
    }
    void resetSDI12TimerPrescale(void)
    {
        TCCR2A = preSDI12_TCCR2A;
        TCCR2B = preSDI12_TCCR2B;
    }
    
 #endif

ESP32- Core panic when using in conjunction with the "preferences" library.

I found I get the following error in the SDI12 receive interrupt:-
"esp32 guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed)"
This only occurs when trying to write data to the Preferences NVM. I have solution to the issue which requires that the receive interrupt and any function call by the receive interrupt be located in the ESP32/8266 instruction RAM (IRAM)

arduino due-sdi 12 error

Hi,
I am using arduino-1.5.7 and trying to work with decagon sensors using serial event example code with some modifications to suit my project.
The library works great with arduino uno but with arduino due, it gives me the following error message:

home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp: In member function 'void SDI12::setState(uint8_t)':
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:377:32: error: 'digitalPinToPCMSK' was not declared in this scope
*digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:377:71: error: 'digitalPinToPCMSKbit' was not declared in this scope
*digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:389:29: error: 'digitalPinToPCICR' was not declared in this scope
*digitalPinToPCICR(_dataPin) |= (1<<digitalPinToPCICRbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:389:67: error: 'digitalPinToPCICRbit' was not declared in this scope
*digitalPinToPCICR(_dataPin) |= (1<<digitalPinToPCICRbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:390:32: error: 'digitalPinToPCMSK' was not declared in this scope
*digitalPinToPCMSK(_dataPin) |= (1<<digitalPinToPCMSKbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:390:70: error: 'digitalPinToPCMSKbit' was not declared in this scope
*digitalPinToPCMSK(_dataPin) |= (1<<digitalPinToPCMSKbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:394:31: error: 'digitalPinToPCMSK' was not declared in this scope
*digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:394:70: error: 'digitalPinToPCMSKbit' was not declared in this scope
*digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:396:32: error: 'digitalPinToPCICR' was not declared in this scope
*digitalPinToPCICR(_dataPin) &= ~(1<<digitalPinToPCICRbit(_dataPin));
^
/home/bmubuntu/Arduino/libraries/Arduino-SDI-12-master/SDI12.cpp:396:71: error: 'digitalPinToPCICRbit' was not declared in this scope
*digitalPinToPCICR(_dataPin) &= ~(1<<digitalPinToPCICRbit(_dataPin));
^

I am a newbie to the arduino board. Please help me in the regard.

Thanks!

Arduino Due

Hi,

If I want to use an Arduino Due to communicate with a sensor that uses the SDI12 protocol, how should I connect them instead?

Thanks.

How to use this library along with xbee-arduino library

Hello,

I am new to the Arduino platform, i have used the Arduino SDI-12 library to get data from 5TM soil sensors. I am trying to send the data via Xbee to my computer connected with another Xbee as coordinator. I cant seam to see the data at the computer. I am wondering can it have to deal with the serial interface used by both the SDI12 sensor and the Xbee for communication? am i to use an Arduino with two serial interfaces like the Leonardo or may be use the Software serial library with arduino Uno? Please if there are some specific steps needed to get the library to work with Xbee radios let me know thanks.

Fix receive ISR to correctly handle the wake and marking

For a master, this makes no difference because it's controlling the line state and not listening for interrupts during the break and marking. For a slave or a spy, the break and marking are currently read as characters, which creates junk and screws up the first real character.

SDI-12 Transparent Mode

Does this library support the "transparent mode"? I have an Enviropro Probe that I am trying to use with this library but so far no luck in getting any response back from the probe.

ESP32 support.

I have made changes to SDI-12 driver to support the ESP32. Is this a development you would like to see push back in to the repo?

Stm32 compatibility

I was wondering if there are plans to make this stm32 compatible, particularly stm32g0 as this is a great replacement for 8 bit microcontrollers.

SAMD21 issue

I'm using the library to control many SDI12 devices (one for time). For example, using a Sentek drill and drop probe I succed taking data but if I define the WDT as follow, the same SDI commands fail

void set_Low_Power_Clock()
{
// initialize the WDT watchdog timer
// Setup GCLK for the watchdog using:
// - Generic clock generator 2 as the source for the watchdog clock
// - Low power 32khz internal oscillator as the source for generic clock
// generator 2.
// - Generic clock generator 2 divisor to 32 so it ticks roughly once a
// millisecond.
// 2^(divisor register value + 1)
// A 32khz clock with a divisor of 32 will then generate a 1ms clock period.
GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(CK_DIV); // 4096 Hz with CK_DIV = 2
// Now enable clock generator 2 using the low power 32khz oscillator and the
// clock divisor set above.
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) |
GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_SRC_OSCULP32K | //32.768kHz Ultra Low-Power Internal Oscillator (OSCULP32K)
GCLK_GENCTRL_DIVSEL;
while (GCLK->STATUS.bit.SYNCBUSY); // Syncronize write to GENCTRL reg.
// Turn on the WDT clock using clock generator 2 as the source.
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_WDT |
GCLK_CLKCTRL_CLKEN | //enable it
GCLK_CLKCTRL_GEN_GCLK2;
}

The clock source and channel seems to be unrelated to the one used in the library for the SAMD board, but still I've got a fail, even changing the WDT channel

SDI12 - ESP32 NOT OPEN BUS

Hello everyone @majenkotech @diegogmx @majenkotech,@ALL I am trying to read data from a Campbell Scientific sensor by sdi12 with an ESP32, but the sensor does not recognize me or it simply does not detect that the sdi12 object is available.
I share my code in case someone could help me

I'm from Chile, that's why there are some lines in Spanish. If there was someone who spoke my language much better!!!

`//#include <SPI.h>
//#include <UIPEthernet.h>
//#include <SPI.h>
//#include <Ethernet.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include "SDI12.h"
SDI12 mySDI12(2);
String datos = "";
bool isAvailable(int pin){
// SDI12 mySDI12(pin);
// Serial.println("DATAPIN: "+this->DATAPIN);
return mySDI12.available();
}
void printBufferToScreen(int pin){
Serial.println(" en print buffer screen ");
String buffer = "";
buffer +="{"H":"";
byte cont = 0;
byte largo = 0;
byte cont_largo = 0;
mySDI12.read(); // consume address

while(mySDI12.available()){
Serial.println("dentro del while print buffer screeen");
char c = mySDI12.read();
if(c == '+'){
if(cont == 0){
}
if(cont == 1){
buffer += "","CE":"";
}
if(cont == 2){
buffer += "","T":"";
}if(cont == 3){
buffer += "","PDIEF":"";
}
if(cont == 4){
buffer +="}";
}
cont++;
if(c == '-') {
buffer += '-';
}
if(c=='\0'){
}
}
else {
buffer += c;
}

delay(100);   
}

Serial.println("despues del while en print buffer screen");
datos = buffer;
}

void takeMeasurement(char i,int pin){
Serial.println(" take measurement");
String command = "";
command += i;
command += "M3!"; // SDI-12 measurement command format [address]['M'][!]
mySDI12.sendCommand(command);
while(!mySDI12.available()>5); // wait for acknowlegement with format [address][ttt (3 char, seconds)][number of measurments available, 0-9]
delay(100);
mySDI12.read(); //consume address

// find out how long we have to wait (in seconds).
int wait = 0;
wait += 100 * mySDI12.read()-'0';
wait += 10 * mySDI12.read()-'0';
wait += 1 * mySDI12.read()-'0';

mySDI12.read(); // ignore # measurements, for this simple examlpe
mySDI12.read(); // ignore carriage return
mySDI12.read(); // ignore line feed

long timerStart = millis();
while((millis() - timerStart) > (1000 * wait)){
if(mySDI12.available()) break; //sensor can interrupt us to let us know it is done early
}

// in this example we will only take the 'DO' measurement
mySDI12.flush();
command = "";
command += i;
command += "D0!"; // SDI-12 command to get data [address][D][dataOption][!]
mySDI12.sendCommand(command);
while(!mySDI12.available()>1); // wait for acknowlegement
delay(300); // let the data transfer
//Serial.println("antes de printBufferToScreen()");

printBufferToScreen(pin);
mySDI12.flush();
}

String obtenerDatos(int pin){
float temp_c;
float humidity;
temp_c = 0;//sht1x.readTemperatureC();
humidity = 0;//sht1x.readHumidity();
takeMeasurement('0',int(pin));
// datos +="","PH":"","+""TA":"+"""+temp_c+"","+""HA":"+"}";

datos +="","PH":"",";
datos += ""TA":";
datos +=""";
datos += temp_c;
datos +="",";
datos += ""HA":";
datos +=""";
datos += humidity;
datos +=""";
datos += "}";
int largo_datos = datos.length()+1;
char datos_array[largo_datos];
//char nuevo_datos_array[largo_datos];
String datos_limpios = String("");
datos.toCharArray(datos_array,largo_datos);
for(int i=0;i<largo_datos;i++){
if(datos_array[i] != '\0' && datos_array[i] != '\n' && datos_array[i] != '\r'){
datos_limpios+=datos_array[i];
}
}
return String(datos_limpios);
}

String jsonSensor(int id){
Serial.print("id: ");
Serial.println(id);
String data = obtenerDatos(id);
String json = "{";
json += ""pin":";
json += """;
json += id;
json += "",";
json += ""available":";
json += """;
json += isAvailable(id);
json += "",";
json += ""data":";
//json += """;
json += data;
//json += """;
json += "}";
return String(json);
}

void setup() {
Serial.begin(115200);
delay(500);
mySDI12.begin();
}

void loop() {
Serial.println(jsonSensor(2));
delay(1000);
}
`

I hope you can help me

Thank you
Greetings
Matias

Help with Using library

Hello
I am new to Arduino and the SDI12 based sensors, I am currently working on a project to transfer data from SDI12 based sensors (Decagon 5TM sensors) wirelessly with help of the Arduino and Xbee. Can you please help me with a basic code to collect data from this sensor and display them on the Arduino serial monitor.

CRC Implementation

From what I can see the CRC has not been implemented. Being very new to SDI-12, is this because no one uses it or is it some thing that need implementing? My current project is developing a SDI-12 version of our sensor so could do to know if I will need to add this functionality?

Arduino Mega Compatibility

According to http://arduino.cc/en/Reference/SoftwareSerial:

"Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)."

I have confirmed that the library does work with the Arduino Mega, but only on the pins noted above.

So I pose the question: Where is the best place to publish this information so that users will notice?

I think putting a note right next to the pin declaration in each of the examples is a good place to start, since they probably get the most traffic. Thoughts?

Communicating with other sensors

Please has any one used this library to collect data from the Stevens hydraprobe? I succeeded in communicating and logging data from Decagon 5TM but tried for days now to communicate and get data from the hydraprobe but no success. Any help or idea will be much appreciated. Thanks

Watchdog Problem SAMD21

Hello,

I'm interfacing with a TEROS 12 Soil Moisture Sensor, and whenever I activate the watchdog in my SAMD21 processor (based on Feather M0), the system hangs on reading data (with 8s timer).

The same code without the watchdog activation works perfectly, so I guess it must be a conflict between the library timers and the watchdog ones?

I would like to know any suggestions for this issue.

Thank you for your time.

ASR6501 - Cubecell support

I would be great to add support for Hetec Cubecell - ASR6501 based boards. We have tried to use the board definitions for Arduino Zero (since we thought it shares the same MCU architecture), but it did not work. Timer definitions must be different.
Thanks for the support!!!

8 MHz Arduino and SDI12 LIbrary

I have been using your library for some remote soil moisture sensor stations for our strawberry nursery stock production. I'm using the Arduino Pro Mini 5V/16MHz versions and Decagon GS3 soil moisture sensors and everything is working great. I want to redesign my sensor stations to be a little bit smaller and less power hungry (i.e. smaller solar panel, less battery capacity, etc) so I started testing the Arduino Pro Mini 3.3V/8MHz versions and the SDI12 communications stopped working. I'm guessing it has something to do with the serial timing when moving from a 16 MHz device to an 8 MHz device, but I'm not familiar enough with the serial communication programming to know where to look or how to modify it to work at 8 MHz. Could your library be modified to work at 8 MHz? My initial thought was to double the SPACING constant since the speed is cut in half...am I even on the right track?

Thanks for your help in advance and thank you for making such a wonderful open-source SDI12 library in the first place.

PS - I emailed you also, but this seemed like a better place to ask my question...sorry for the double-post/email.

Make some changes for slave side use

Hi there,

I'm keen to make a few small changes to the lib to allow for slave side use.

E.g. slaves should not pull the line high for 12ms before sending command, but they should wait the min of 8.3ms before replying

Would you be able to make the changes, or shall I attempt it?

Regards, Justin

Has anybody worked on porting this to 32-bit ARM boards?

Before I jump in and try to figure out reworking this to avoid avr/interrupt.h and avr/parity.h, I would like to ask if anybody else has been working on this. It would take me a long time to accomplish this, given my total unfamiliarity with how these interrupts function. I am used to simply using attachInterrupt() on my 32 bit board.

Can not read measurements

Hi

I am trying to use this library to interface Acclima soil sensors (TDT and with TDR315H) with Arduino/ESP32. When connecting the sensors and using the d_simple_logger.ino example sketch (after changing the DATA_PIN to fit my connections) I get communication with the sensors as their addresses and information show up. It seems that they immediately respond to the M! command with the time and number of measurements, but no measurements are retrieved after D0!. I have tried a few other examples with no success. I used different boards as well - ESP32 (pin 32), Arduino nano (pin 7) and Arduino Mega 2560 (pin 11), with all I get the same behavior.

They are all powered with 12v from a bench power supply, the data wires are all connect to the same pin on the microcontroller and the grounds are all connected.

In the image below, you can see the serial print that I get (using Arduino Mega 2560):
image
Thanks
Erez

Buffer size of 64 is too small for a complete response.

I have been using the example code (h_SDI-12_slave and f_basic-data request) and find if I issue a "aC!" command followed by a "aD0" I do not receive all the character in the response. As the maximum length of the values is 75 long

+ + + I would expect the max buffer size to be at least 79 chars long. I have tested increasing the buffer and I now receive the full response. I am performing e2e test on an Arduino MKRWifi1010 and ESP32.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.