Датчики I2C не работают при подключении к LCD дисплею 20X04

Я создаю гидропонную систему мониторинга питательных веществ с использованием Arduino Uno, датчика Atlas Scientific EC, датчика pH и датчика RTD (температуры) в режиме I2C. Я также хочу использовать ЖК-дисплей 20x04 для отображения показаний датчика, чтобы на нем отображались значения EC, pH и температуры. Я подключаю все SDA и SCL к контактам A4 (SDA) и A5 (SCL) и питаю все датчики и ЖК-дисплей напряжением 3,3 В. К SDA и SCL каждого датчика добавляется резистор 4,7 Ком.

The Fritzing of my circuit

Сначала я протестировал код, подключив свой Arduino Uno к схеме RTD EZO и датчикам без ЖК-дисплея. Последовательный монитор успешно отображает показания датчика RTD, а также "Нет данных" для EC и pH, поскольку я не подключаю датчики EC и pH. Но когда я подключаю все цепи и датчики, он не может обнаружить датчик pH. Самая неприятная часть - это ЖК-дисплей. Сначала на ЖК-дисплее отображаются данные EC и RTD, но они работают только в течение 5 минут и замораживаются. ЖК-дисплей иногда показывает только значение "0.00" для EC и RTD, даже если последовательный монитор показывает показания датчика данных.

Я хочу знать, есть ли что-то не так с моим кодом или, возможно, проблема с моей собственной схемой.

Вот код:

#include <Ezo_i2c.h>
#include <Wire.h>                //включить 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;        //выбирает нашу фазу

uint32_t next_poll_time = 0;              //удерживает следующий раз, когда мы получим ответ, в миллисекундах
const unsigned int response_delay = 1000; //сколько времени мы ждем получения ответа, в миллисекундах

void setup()                     //инициализация оборудования.
{
  Serial.begin(9600);            //включить последовательный порт.
  Wire.begin();                  //включить порт I2C.
  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() {                                                      //основной цикл.
  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)             // если бы мы находились на этапе, когда мы запрашиваем чтение
  {
    //отправить команду чтения
    //чтобы сообщить библиотеке о необходимости анализа прочитанного
    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);                              //получить показания из схемы EC
    receive_reading(ph);                              //получить показания из схемы PH
    receive_reading(temp);                              //получить показания из схемы RTD

    reading_request_phase = true;                     //переключитесь обратно на запрос показаний
  }
 }
 }

  void receive_reading(Ezo_board &Sensor) {
  Serial.println();
  Serial.print(Sensor.get_name()); //вывести имя схемы EZO
  Serial.print(": ");
  Sensor.receive_read_cmd();

  switch (Sensor.get_error())                          //переключите регистр в зависимости от того, что такое код ответа.
     {
    case Ezo_board::SUCCESS:
    Serial.print(Sensor.get_last_received_reading());               //команда прошла успешно, распечатайте показания
    break;

    case Ezo_board::FAIL:
    Serial.print("Failed ");                          //означает, что команда выполнена с ошибкой.
    break;

    case Ezo_board::NOT_READY:
    Serial.print("Pending ");                         //вычисление команды еще не завершено.
    break;

    case Ezo_board::NO_DATA:
    Serial.print("No Data ");                         // у датчика нет данных для отправки.
    break;
 }
}

, 👍4

Обсуждение

Если все ваши устройства являются устройствами i2c, подтягивающие резисторы должны быть подключены не так. Пожалуйста, прочтите [i2c](https://en.wikipedia.org/wiki/I2C ), @hcheung


2 ответа


Лучший ответ:

5

Добро пожаловать в Stack Exchange!

Я могу заметить несколько проблем с цепью. Как сказал @hcheung, подтягивающие резисторы I2C должны подключаться только между SDA> 3,3 В и SCL> 3,3 В (параллельно), а не последовательно с датчиками.

Кроме того, еще одно предупреждение: вы питаете свои датчики напряжением 3,3В, но выходы Arduino Uno составляют 5 В! Многим платам это не понравится, и они могут сами сгореть или, по крайней мере, работать неправильно. Их сигналы также будут иметь напряжение 3,3 В вместо 5 В, что потенциально может привести к более странному поведению.

Если все ваши компоненты совместимы с питанием 5 вольт (проверьте их спецификации / руководства), я бы рекомендовал запитать их все напряжением 5 вольт.

В противном случае вам понадобятся переключатели уровня для преобразования между сигналами Arduino 5 В и сигналами платы 3,3 В.

,

2

Спасибо вам за всю вашу помощь. Теперь я понимаю, что я сделал неправильные схемы I2C. Затем я изменил их, и теперь программа и датчики работают безукоризненно.

Вот моя схема сейчас.

,