-2

I am still continuing my hydroponic nutrient monitoring project. In short, I made a hydroponic nutrient monitoring system with I2C connection, and decided to do serial communication with Raspberry Pi 3B+ to save sensor reading data in CSV file. I am curious about why after uploading the sketch, the sensors always gives zero values at first reading on Serial Monitor.

This is the screenshot of my Serial Monitor.

enter image description here

From left to right: timestamp, EC, pH, Temperature.

Everytime I reset the Arduino, the Serial Monitor first will show no values. On the second line, it shows only EC value. The third line only EC and pH value, then the fourth line and so on will show all values.

How to make the Arduino show all sensor values from the start in the Serial Monitor?

Here is my code that I modified from Atlas Scientific page for my project:

#include <Ezo_i2c.h>
#include <Wire.h>                

Ezo_board ec = Ezo_board(100, "EC");
Ezo_board ph = Ezo_board(99, "PH");
Ezo_board temp = Ezo_board(102, "RTD");

bool reading_request_phase = true;        

uint32_t next_poll_time = 0;              
const unsigned int response_delay = 1000; 

void setup()                     
{
  Serial.begin(9600);            
  Wire.begin();                  
  delay(1000);

}

void loop() {                                                                     
  if (reading_request_phase)             
  {
    ec.send_read_cmd();
    ph.send_read_cmd();
    temp.send_read_cmd();

    next_poll_time = millis() + response_delay;        
    reading_request_phase = false;                      
  }
  else                                                
  {
    if (millis() >= next_poll_time)                    
    {
      receive_reading(ec);
      receive_reading(ph);                              
      receive_reading(temp);                              

      reading_request_phase = true;                     
    }
  }
}

void receive_reading(Ezo_board &Sensor) {
  Sensor.receive_read_cmd();
  Serial.println();
  Serial.print(ec.get_last_received_reading()/1000);
  Serial.print(",");
  Serial.print(ph.get_last_received_reading());
  Serial.print(",");
  Serial.print(temp.get_last_received_reading());
  Serial.print("");
  delay(1000);
}

1 Answer 1

5

Each time you call receive_reading() you pass it one sensor to read the value from. But each time you call receive_reading() you print out all three sensors.

So you:

  1. Read EC and print EC PC TEMP
  2. Read PC and print EC PC TEMP
  3. Read TEMP and print EC PC TEMP

In step one you only have EC, you haven't read PC or TEMP yet. In step two you have the old reading of EC and a new PC reading but still no TEMP reading. By step three you finally have a TEMP reading but still the old EC and PC readings from earlier.

You should instead put the receiving command (Sensor.receive_read_cmd()) once for each sensor as a separate thing to displaying the received values. More like:

#include <Ezo_i2c.h>
#include <Wire.h>                

Ezo_board ec = Ezo_board(100, "EC");
Ezo_board ph = Ezo_board(99, "PH");
Ezo_board temp = Ezo_board(102, "RTD");

bool reading_request_phase = true;        

uint32_t next_poll_time = 0;              
const unsigned int response_delay = 1000; 

void setup()                     
{
  Serial.begin(9600);            
  Wire.begin();                  
  delay(1000);

}

void loop() {                                                                     
  if (reading_request_phase)             
  {
    ec.send_read_cmd();
    ph.send_read_cmd();
    temp.send_read_cmd();

    next_poll_time = millis() + response_delay;        
    reading_request_phase = false;                      
  }
  else                                                
  {
    if (millis() >= next_poll_time)                    
    {
      ec.receive_read_cmd();
      ph.receive_read_cmd();
      temp.receive_read_cmd();
      display_reading();

      reading_request_phase = true;                     
    }
  }
}

void display_reading() {
  Serial.print(ec.get_last_received_reading()/1000);
  Serial.print(",");
  Serial.print(ph.get_last_received_reading());
  Serial.print(",");
  Serial.println(temp.get_last_received_reading());
}

Also remove the delay() after each printed line, it's just confusing everything and slowing down your reading.

2
  • I think there are too much colons on the receive_read_cmd() like. Otherwise good answer
    – chrisl
    May 25, 2022 at 10:20
  • @chrisl copy-pasta ;)
    – Majenko
    May 25, 2022 at 10:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.