4

I am making a hydroponic nutrient monitoring system using Arduino Uno, Atlas Scientific EC sensor, pH sensor, and RTD (temperature) sensor in I2C mode. I also want to use LCD 20x04 to display the sensor reading so that will display the EC, pH, and temperature values. I connect all the SDA and SCL to pin A4 (SDA) and A5 (SCL), and powered all the sensors and LCD with 3.3 V. Each sensor's SDA and SCL are added with resistor 4.7 kOhm.

The Fritzing of my circuit

I tested the code first by connecting my Arduino Uno to the RTD EZO circuit and sensors, without the LCD. The Serial Monitor successfully displays the data sensor reading of RTD, as well as 'No Data' for EC and pH as I do not connect the EC and pH sensors. But when I connect all the circuits and sensors, it can not detect the pH sensor. The most frustrating part is the LCD. The LCD at first displays the EC and RTD data, but only run for 5 minutes and freeze. The LCD sometimes only shows a "0.00" value for EC and RTD even though the Serial Monitor shows the data sensor reading.

I want to know if there is something wrong with my code or maybe the problem with my own circuit.

Here is the code:

#include <Ezo_i2c.h>
#include <Wire.h>                //enable I2C.
#include <LiquidCrystal_I2C.h>

Ezo_board ec = Ezo_board(100, "EC");
Ezo_board ph = Ezo_board(99, "PH");
Ezo_board temp = Ezo_board(102, "RTD");
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);

bool reading_request_phase = true;        //selects our phase

uint32_t next_poll_time = 0;              //holds the next time we receive a response, in milliseconds
const unsigned int response_delay = 1000; //how long we wait to receive a response, in milliseconds

void setup()                     //hardware initialization.
{
  Serial.begin(9600);            //enable serial port.
  Wire.begin();                  //enable I2C port.
  Serial.println("ATLAS EZO I2C v2");
  Serial.print("Test date: ");
  lcd.init();
  lcd.backlight();
  lcd.setCursor(1,1);
  lcd.print("ATLAS EZO I2C v2");
  lcd.setCursor(0,2);

  delay(3000);
  lcd.clear();
 }

  void loop() {                                                      //the main loop.
  lcd.setCursor(0,1);
  lcd.print("EC: ");
  lcd.setCursor(4,1);
  lcd.print(ec.get_last_received_reading());
  lcd.setCursor(10,1);
  lcd.print("ppm");
  lcd.setCursor(0,2);
  lcd.print("pH: ");
  lcd.setCursor(4,2);
  lcd.print(ph.get_last_received_reading());
  lcd.setCursor(0,3);
  lcd.print("Temp.: ");
  lcd.setCursor(7,3);
  lcd.print(temp.get_last_received_reading());
  lcd.setCursor(13,3);
  lcd.print("C");

  if (reading_request_phase)             //if were in the phase where we ask for a reading
  {
    //send a read command
    //to let the library know to parse the reading
    ec.send_read_cmd();
    ph.send_read_cmd();
    temp.send_read_cmd();

    next_poll_time = millis() + response_delay;         //set when the response will arrive
    reading_request_phase = false;                      //switch to the receiving phase
  }
  else                                                //if were in the receiving phase
  {
    if (millis() >= next_poll_time)                    //and its time to get the response
  {
    receive_reading(ec);                              //get the reading from the EC circuit
    receive_reading(ph);                              //get the reading from the PH circuit
    receive_reading(temp);                              //get the reading from the RTD circuit

    reading_request_phase = true;                     //switch back to asking for readings
  }
 }
 }

  void receive_reading(Ezo_board &Sensor) {
  Serial.println();
  Serial.print(Sensor.get_name()); //print the name of the EZO circuit
  Serial.print(": ");
  Sensor.receive_read_cmd();

  switch (Sensor.get_error())                          //switch case based on what the response code is.
     {
    case Ezo_board::SUCCESS:
    Serial.print(Sensor.get_last_received_reading());               //the command was successful, print the reading
    break;

    case Ezo_board::FAIL:
    Serial.print("Failed ");                          //means the command has failed.
    break;

    case Ezo_board::NOT_READY:
    Serial.print("Pending ");                         //the command has not yet been finished calculating.
    break;

    case Ezo_board::NO_DATA:
    Serial.print("No Data ");                         //the sensor has no data to send.
    break;
 }
}
1
  • 2
    If all your devices are i2c devices, that's not how the pull-up resistors should be wired. Please read i2c
    – hcheung
    Apr 25, 2022 at 11:51

2 Answers 2

5

Welcome to Stack Exchange!

I can spot a few problems with the circuit. As @hcheung said, the I2C pull-up resistors should only be wired between SDA>3.3V and SCL>3.3V (in parallel), not in series with the sensors.

Also, another warning: You are powering your sensors with 3.3V, but the outputs from the Arduino Uno are 5V! Many boards will not like this and might fry themselves, or at least not function correctly. Their signals will also be 3.3V instead of 5V, potentially causing more weird behavior.

If all your components are compatible with 5 volt power (check their datasheets/guides), I would recommend powering them all with 5 volts.

Otherwise, you will need level shifters to convert between the 5V Arduino signals and the 3.3V board signals.

2

Thank you for all your help. I now realize that I have made the wrong I2C circuits. Then I modified them and now the program and the sensors work perfectly.

Here is my circuit now.

enter image description here

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.