DHT20 и дисплей Oled не работают вместе
Я пытаюсь заставить DHT20 и Oled (оба из комплекта датчиков Arduino) работать одновременно. Я могу заставить их работать отдельно с соответствующими тестовыми кодами, но когда я пытаюсь объединить коды, дисплей Oled больше не работает. Оба соединения являются соединениями I2C, но я проверил, каждое устройство имеет свой адрес, так что проблем быть не должно.
Вот мой тестовый код DHT20:
#include "Arduino_SensorKit.h"
//раскомментируйте строку ниже, если используете DHT20
#define Environment Environment_I2C
void setup() {
//раскомментируйте строку ниже, если используете DHT20
Wire.begin();
Serial.begin(9600);
Environment.begin();
}
void loop() {
Serial.print("Temperature = ");
Serial.print(Environment.readTemperature()); //температура печати
Serial.println(" C");
Serial.print("Humidity = ");
Serial.print(Environment.readHumidity()); //печатаем влажность
Serial.println(" %");
delay(2000);
}
Вот мой тестовый код Oled-дисплея:
#include "Arduino_SensorKit.h"
void setup() {
Oled.begin();
Oled.setFlipMode(true);
}
void loop() {
int random_value = random(0, 1023); // создаем случайное значение
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.setCursor(0, 3);
Oled.print("Value: ");
Oled.print(random_value);
delay(1000);
}
Это мой код, в котором я пытался заставить оба устройства работать одновременно:
#include "Arduino_SensorKit.h"
#define Environment Environment_I2C
void setup() {
Oled.begin();
Oled.setFlipMode(true);
Wire.begin();
Serial.begin(9600);
Environment.begin();
}
void loop() {
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.setCursor(0, 3);
Oled.print("Testing");
Serial.print("Temperature = ");
Serial.print(Environment.readTemperature()); //температура печати
Serial.println(" C");
Serial.print("Humidity = ");
Serial.print(Environment.readHumidity()); //печатаем влажность
Serial.println(" %");
delay(2000);
}
Когда я использую приведенный выше код, значения температуры и влажности печатаются на последовательном мониторе, но Oled ничего не отображает.
Любая помощь приветствуется!
@Darren D'Arcy, 👍1
Обсуждение2 ответа
Основная проблема
У меня нет этого комплекта датчиков. Но я могу наблюдать то, что вы описываете, с заменами и дублерами. Кажется, вы можете сделать две вещи.
Основная проблема заключается в том, что библиотека Arduino_SensorKit написана для использования программного обеспечения/битового I2C для отображения. Вернее, он приказывает U8G2LIB это сделать, по какой причине я не знаю. Когда периферийное устройство ATmega328P I2C включено, оборудование GPIO больше не управляет выводами. Таким образом, в тот момент, когда вы включаете аппаратный I2C (через код DHT20), код битов GPIO в U8G2LIB не может работать правильно.
Итак, есть как минимум два способа заставить это работать.
Изменение вашего кода, чтобы он соответствовал тому, как написана библиотека Arduino_SensorKit.
Другой — модификация библиотеки Arduino_SensorKit для использования аппаратного I2C, и в этом случае исходный код работает дословно.
Изменение скетча
Вы можете изменить свой скетч следующим образом:
#include "Arduino_SensorKit.h"
#define Environment Environment_I2C
void setup() {
Oled.begin();
Oled.setFlipMode(true);
Serial.begin(9600);
Wire.begin(); // только здесь, чтобы соответствовать последующему .end()
}
void loop() {
Wire.end(); // возвращаем управление выпуском I2C обратно в GPIO
{
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.setCursor(0, 3);
Oled.print(millis()); //Oled.print("Тестирование");
}
Wire.begin(); // повторно включаем I2C для использования DHT20 («Среда»);
Serial.print("Temperature = ");
Serial.print(Environment.readTemperature()); //температура печати
Serial.println(" C");
Serial.print("Humidity = ");
Serial.print(Environment.readHumidity()); //печатаем влажность
Serial.println(" %");
delay(2000);
}
По большей части библиотеке AVR Wire не важно, используете ли вы повторяющиеся вызовы begin()
или повторяющиеся вызовы end()
. Однако это может повлиять на настройку скорости. Фигурные скобки вокруг использования Oled
предназначены только для визуального эффекта.
В любом случае, это работает, если вы уверены, что Oled
может использовать GPIO.
Изменение Arduino_SensorKit
Благодаря следующим изменениям в библиотеке Arduino_SensorKit версии 1.2.1 (действующей на момент написания) я могу использовать ваш код скетча дословно. Я также изменил его, чтобы печатать millis()
, а не "Тестирование"
, чтобы быть уверенным, что продолжается обновление дисплея.
Arduino_SensorKit.h
В строке 24 файла библиотеки Arduino_SensorKit.h, изменить:
extern U8X8_SSD1306_128X64_NONAME_SW_I2C Oled;
в
extern U8X8_SSD1306_128X64_NONAME_HW_I2C Oled;
Обратите внимание на HW
(аппаратное обеспечение), а не на SW
(программное обеспечение).
Arduino_SensorKit.cpp
Аналогичным образом измените аналог на определение Oled
соответствует приведенному выше изменению в объявлении extern
Oled
, из:
U8X8_SSD1306_128X64_NONAME_SW_I2C Oled(/* clock=*/ _PIN_SCL, /* data=*/ _PIN_SDA, /* reset=*/ U8X8_PIN_NONE);
кому:
U8X8_SSD1306_128X64_NONAME_HW_I2C Oled(/* clock=*/ _PIN_SCL, /* data=*/ _PIN_SDA, /* reset=*/ U8X8_PIN_NONE);
Вероятно, здесь можно удалить аргументы из вызова конструктора; ATMega328P не имеет возможностей настройки TWI/I2C для более чем одного набора контактов.
Также ничто не мешает вам оставить его как U8X8_SSD1306_128X64_NONAME_SW_I2C
, но изменить контакты так, чтобы программный I2C использовал контакты, отличные от A4/A5, чтобы не конфликтовать с использованием аппаратного I2C библиотеками DHT20. .
Для справки: версия U8G2LIB, которую я тестировал, была 2.33.15. ардуино-кли версии 0.32.2. ардуино: avr ядро 1.8.7. Я не думаю, что они вам нужны. Я просто уточняю на случай, если кто-нибудь найдет это через 5 лет или где-то еще.
Большое спасибо! Я изменил скетч, и теперь он работает отлично!, @Darren D'Arcy
Я использую переменную для хранения показаний.
#include "Arduino_SensorKit.h"
#define Environment Environment_I2C
void setup() {
Oled.begin();
Oled.setFlipMode(true); // Устанавливает поворот экрана
// раскомментируйте строку ниже, если используете DHT20 (черный датчик)
Wire.begin();
// раскомментируйте строку ниже, если вы подключаете DHT20 к контакту, отличному от 3
Serial.begin(9600);
Environment.begin();
}
void loop() {
Wire.begin();
// Вам нужна переменная для сохранения показаний, потому что среда не будет работать, когда светодиод работает
float temp= Environment.readTemperature();
float hum= Environment.readHumidity();
Serial.print("Temperature = ");
Serial.print(temp); //температура печати
Serial.println(" C");
Serial.print("Humidity = ");
Serial.print(hum); //печатаем влажность
Serial.println(" %");
delay(2000);
// int random_value = AnalogRead(A0);
Wire.end();
{
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.setCursor(0, 0); // Устанавливаем координаты
Oled.print("temp: ");
Oled.print(temp); // Распечатываем значения
Oled.setCursor(0, 3); // Устанавливаем координаты
Oled.print("Humidity: ");
Oled.print(hum); // Распечатываем значения
Oled.refreshDisplay(); // Обновляем отображение
}
}
- Что выбрать между датчиками температуры и влажности: AM230x или DHT22?
- Проблемы с подключением I2C на ESP8266 — 12F, какие контакты использовать?
- BMP280 возвращает 0
- Подключение двух Arduino через I2C, когда контакты I2C A4/A5 уже используются.
- Нужен усилитель сигнала датчика качества воздуха MQ135? Датчик более высокого качества?
- Чтение данных из eagle tree airspeed v3
- Датчик DHT11: режим ожидания или выключение?
- Датчик качества воздуха Sparkfun CCS811 не работает
что произойдет, если вы измените порядок инициализации двух модулей в
setup()
?, @jsotolaК сожалению, изменение порядка инициализации в setup() ничего не меняет., @Darren D'Arcy