Welcome to EnviroDIY, a community for do-it-yourself environmental science and monitoring. EnviroDIY is part of WikiWatershed, an initiative of Stroud Water Research Center designed to help people advance knowledge and stewardship of fresh water.
New to EnviroDIY? Start here

SDI-12 Slave

Home Forums Other Data Loggers SDI-12 Slave

Viewing 2 reply threads
  • Author
    Posts
    • #17848
      dani68k
      Participant

        Hello,

        I’m trying to create an I2C PH sensor over a SDI-12 bus.

        I’m using a Arduino Leonardo to read sensor data over I2C and then send it to the datalogger over a SDI-12 bus.

        I have a DIY datalogger using same SDI-12 library, with a commercial sensor with address 0 working without problems, and my PH sensor, I just run the example there is the folder ‘example/h_SDI-12_slave_implementation’ with some lines commented, just to verify the comunication. So, I just left the part where data is available and just print the incomming char… but nothing appears, even I’m getting data from sensor 0 from datalogger. I checked with an oscilloscope and there is imcomming signal on pin 7 of my leonardo. I serialprinted the variable avail on the loop and it is always 0, menaing there is no data comming.

        I guess I’m missing something… but for the moment not clear what it can be.

        Here the code:

        #include <Arduino.h>
        #include <SDI12.h>

        #define DATA_PIN 7 /*!< The pin of the SDI-12 data bus */
        // Create object by which to communicate with the SDI-12 bus on SDIPIN
        SDI12 slaveSDI12(DATA_PIN);

        void setup() {
        Serial.begin(115200);
        slaveSDI12.begin(DATA_PIN);
        delay(500);
        slaveSDI12.forceListen(); // sets SDIPIN as input to prepare for incoming message
        pinMode(LED_BUILTIN, OUTPUT);
        }

        void loop() {
        // If a byte is available, an SDI message is queued up. Read in the entire message
        // before proceding. It may be more robust to add a single character per loop()
        // iteration to a static char buffer; however, the SDI-12 spec requires a precise
        // response time, and this method is invariant to the remaining loop() contents.
        int avail = slaveSDI12.available();
        Serial.println(avail);
        if (avail < 0) {
        slaveSDI12.clearBuffer();
        } // Buffer is full; clear
        else {
        for (int a = 0; a < avail; a++) {
        char charReceived = slaveSDI12.read();
        Serial.print(charReceived);
        }
        }
        }

        I think the code above should work as sniffer for the SDI-12 bus… so getting data is running on the bus.
        I even tried to blink the LED with data over DATA_PIN, and the leds blinks… so leonardo is reading the incomming signal.
        I also tried with arduino MINI PRO 5V 16MHz, and the same result.
        I hope you can help me about this issue.
        If you need more information and details to find the issue: just ask me.
        Thank you.
        BR,
        daniel

      • #17853
        neilh20
        Participant

          Hi @dani68k, welcome to EnviroDIY.

          I’ve not got any experience on the ATmega32u4, and as a small AVR processor I would think you would need to customize your development for it. SDI-12 bit banging is very sensitive (unrelaible) if the timing isn’t configured right. Possibly using the USART would be better for timeing, but configuring that is another story. Also needs compute the CRC in the allocated time.

           

          My approach would be to separate the development in to two parts  divide the problem into smaller testable parts – one proving the SDI-12 protocol/ response and the other reading the sensor over I2C.

          Say every time there is SDI12 request – after any response to the host, flash the led for a correctly decoded CRC and a different sequence for failed CRC  – that way you know if the basic request msg was received OK.

          Then for successful request return an incrementing number, that way you can see that all the protocol is working, and the response CRC is being correctly calculated.

          Then separately, set up program so that say every 10seconds it reads the PH sensor, computes the units correctly and displays it with print the basic format you want to send as well as human readable format.

          Of course with realtime protocols like SDI12, and reading a sensor, prints do impact the real-time nature and may cause realtime bugs just using them. Having the USB interface does allow prints to come out, but also implies you need to understand how the queue is maintained inside the 32u4

          Unfortunately, its easy for many things to go wrong, and sometimes it takes focused analysis on the data flow to see the way it might work, and then tweak the program to work that way.

          When asking for help, you may want to be explicit as to  which library’s/systems  you are using, devices you are using and do all the work for any reader with links.

           

          good luck with it

           

        • #17875
          dani68k
          Participant

            Hi Neilh20,

            After some tests and new code I succed with reading PH data from sensor with I2C, and trasmitting them to datalogger over the SDI-12.

            Actually, I must left the slave device in listening mode every time using: mySDI12.forceListen();

            For some reason I didn’t proceed that way… but finally I could find the way 😉

            This is working in AVR MCUs. I have tested in atmega328 (Arduino ProMini 5V-16MHz) and atmega32u4 (Arduino Leonardo).

            I developed the project with VSCode and PlatformIO and Arduino framework, using envirodiy/SDI-12@^2.1.4 library.

            I’m attaching a complete project. I will proceed with new features… 🙂

            I hope the code can help someone else

            Thank you,

            BR,

            daniel

            Attachments:
        Viewing 2 reply threads
        • You must be logged in to reply to this topic.