Датчики 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 Ком.
Сначала я протестировал код, подключив свой 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;
}
}
2 ответа
Лучший ответ:
Добро пожаловать в Stack Exchange!
Я могу заметить несколько проблем с цепью. Как сказал @hcheung, подтягивающие резисторы I2C должны подключаться только между SDA> 3,3 В и SCL> 3,3 В (параллельно), а не последовательно с датчиками.
Кроме того, еще одно предупреждение: вы питаете свои датчики напряжением 3,3В, но выходы Arduino Uno составляют 5 В! Многим платам это не понравится, и они могут сами сгореть или, по крайней мере, работать неправильно. Их сигналы также будут иметь напряжение 3,3 В вместо 5 В, что потенциально может привести к более странному поведению.
Если все ваши компоненты совместимы с питанием 5 вольт (проверьте их спецификации / руководства), я бы рекомендовал запитать их все напряжением 5 вольт.
В противном случае вам понадобятся переключатели уровня для преобразования между сигналами Arduino 5 В и сигналами платы 3,3 В.
Спасибо вам за всю вашу помощь. Теперь я понимаю, что я сделал неправильные схемы I2C. Затем я изменил их, и теперь программа и датчики работают безукоризненно.
Вот моя схема сейчас.
- Проблема стабильности кода прерываний, связанного с датчиком расхода
- ЖК-дисплей I2C отображает странные символы
- Экран LCD 16*02 I2C показывает только первый напечатанный символ
- 16/2 arduino I2C ЖК-дисплей не загорается?
- Подключение двух Arduino через I2C, когда контакты I2C A4/A5 уже используются.
- Чтение данных из eagle tree airspeed v3
- Датчик качества воздуха Sparkfun CCS811 не работает
- Альтернатива LCD-дисплеям UART/I2C?
Если все ваши устройства являются устройствами i2c, подтягивающие резисторы должны быть подключены не так. Пожалуйста, прочтите [i2c](https://en.wikipedia.org/wiki/I2C ), @hcheung