Temperature App: Difference between revisions
(3 intermediate revisions by the same user not shown) | |||
Line 143: | Line 143: | ||
[[File:Dht22 rust.png]] | [[File:Dht22 rust.png]] | ||
=SSD1306= | =SSD1306= | ||
Right now to screen | Right now to screen. This was a little tricky due to using the ssd1306-i2c package. This turned out to be the wrong one and the ssd1306 did the trick. I also needed format_no_std for the string interpolation. | ||
<syntaxhighlight lang="rs"> | |||
#[main] | |||
fn main() -> ! { | |||
#[allow(unused)] | |||
let peripherals = esp_hal::init(esp_hal::Config::default()); | |||
let od_for_dht22 = OutputOpenDrain::new(peripherals.GPIO4, Level::High, Pull::None); | |||
let i2c_dev = I2c::new( | |||
peripherals.I2C0, | |||
Config::default().with_frequency(400.kHz()), | |||
) | |||
.unwrap() | |||
.with_scl(peripherals.GPIO22) | |||
.with_sda(peripherals.GPIO21); | |||
esp_println::logger::init_logger_from_env(); | |||
log::info!("Got here 1"); | |||
let interface = I2CDisplayInterface::new(i2c_dev); | |||
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) | |||
.into_buffered_graphics_mode(); | |||
display.init().unwrap(); | |||
log::info!("Got here 2"); | |||
let delay = Delay::new(); | |||
log::info!("calling display.delay()"); | |||
delay.delay_millis(400); | |||
log::info!("calling display.init()"); | |||
display.init().unwrap(); | |||
log::info!("calling display.flush()"); | |||
let mut dht22 = Dht22::new(od_for_dht22, delay); | |||
let text_style = MonoTextStyleBuilder::new() | |||
.font(&FONT_6X10) | |||
.text_color(BinaryColor::On) | |||
.build(); | |||
let text_style_bold = MonoTextStyleBuilder::new() | |||
.font(&FONT_6X13_BOLD) | |||
.text_color(BinaryColor::On) | |||
.build(); | |||
let point1 = Point::new(0, 0); | |||
let point2 = Point::new(0, 19); | |||
let mut buf1 = [0u8; 64]; | |||
let mut buf2 = [0u8; 64]; | |||
loop { | |||
log::info!("Hello world!"); | |||
delay.delay_millis(2000); | |||
match dht22.read() { | |||
Ok(sensor_reading) => { | |||
// Temperature | |||
let str1 = format_no_std::show( | |||
&mut buf1, | |||
format_args!("Temperature: {} °C", sensor_reading.temperature), | |||
).unwrap(); | |||
Text::with_baseline( | |||
&str1, | |||
point1, | |||
text_style_bold, | |||
Baseline::Top, | |||
) | |||
.draw(&mut display) | |||
.unwrap(); | |||
// Humidity | |||
let str2 = format_no_std::show( | |||
&mut buf2, | |||
format_args!("Humidity: {} %", sensor_reading.humidity), | |||
).unwrap(); | |||
Text::with_baseline(&str2, | |||
point2, | |||
text_style, Baseline::Top) | |||
.draw(&mut display) | |||
.unwrap(); | |||
display.flush().unwrap(); | |||
log::info!( | |||
"DHT 22 Sensor - Temperature: {} °C, humidity: {} %", | |||
sensor_reading.temperature, | |||
sensor_reading.humidity | |||
) | |||
} | |||
Err(error) => log::error!("An error occurred while trying to read sensor: {:?}", error), | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
=Embassy= | |||
Time to use embassy as we are going to output this to an html file and serve it. Embassy allow the creation of tasks. First let's set the wifi up. | |||
<syntaxhighlight lang="rs"> | <syntaxhighlight lang="rs"> | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 02:40, 2 May 2025
Introduction
Blink
As always show blink to work before starting on something bigger
#define LED 2
void setup() {
// Set pin mode
pinMode(LED,OUTPUT);
}
void loop() {
delay(500);
digitalWrite(LED,HIGH);
delay(500);
digitalWrite(LED,LOW);
}
DHT22 (Arduino)
Pretty easy with arduino.
#include "DHT.h"
#define DHTPIN 4 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
Serial.println(F("DHTxx test!"));
dht.begin();
}
void loop() {
// Wait a few seconds between measurements.
delay(2000);
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Compute heat index in Fahrenheit (the default)
float hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius (isFahreheit = false)
float hic = dht.computeHeatIndex(t, h, false);
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F("°C "));
Serial.print(f);
Serial.print(F("°F Heat index: "));
Serial.print(hic);
Serial.print(F("°C "));
Serial.print(hif);
Serial.println(F("°F"));
}
SSD1306 (Arduino)
Lets connect our display and stick with Arduino for now. It is an I2C interface. To do this I google an example and tested. On my expansion board the GPIO21 is mislabeled as 20.
Rust
Now know the wiring is correct and lets move over to rust. The main issues with rust for me is that the hardware abstraction layer changes day-to-day. Always getting better but does mean my software breaks.
Blinky
To create project run
cargo generate esp-rs/esp-template
This old and way out of date. In vscode I download dependi to update the cargo file. And here is the latest blink code
#![no_std]
#![no_main]
use esp_backtrace as _;
use esp_hal::{delay::Delay,main};
#[main]
fn main() -> ! {
#[allow(unused)]
let peripherals = esp_hal::init(esp_hal::Config::default());
let delay = Delay::new();
esp_println::logger::init_logger_from_env();
loop {
log::info!("Hello world!");
delay.delay_millis(500);
}
}
DHT22
So lets get this going. This is the quickest I have done this. Maybe getting better.
#![no_std]
#![no_main]
use embedded_dht_rs::dht22::Dht22;
use esp_backtrace as _;
use esp_hal::{delay::Delay, gpio::{Level, OutputOpenDrain, Pull}, main};
#[main]
fn main() -> ! {
#[allow(unused)]
let peripherals = esp_hal::init(esp_hal::Config::default());
let od_for_dht22 = OutputOpenDrain::new(peripherals.GPIO4, Level::High, Pull::None);
let delay = Delay::new();
esp_println::logger::init_logger_from_env();
let mut dht22 = Dht22::new(od_for_dht22, delay);
loop {
log::info!("Hello world!");
delay.delay_millis(500);
match dht22.read() {
Ok(sensor_reading) => log::info!(
"DHT 22 Sensor - Temperature: {} °C, humidity: {} %",
sensor_reading.temperature,
sensor_reading.humidity
),
Err(error) => log::error!("An error occurred while trying to read sensor: {:?}", error),
}
}
}
Here we go. I is freezing here.
SSD1306
Right now to screen. This was a little tricky due to using the ssd1306-i2c package. This turned out to be the wrong one and the ssd1306 did the trick. I also needed format_no_std for the string interpolation.
#[main]
fn main() -> ! {
#[allow(unused)]
let peripherals = esp_hal::init(esp_hal::Config::default());
let od_for_dht22 = OutputOpenDrain::new(peripherals.GPIO4, Level::High, Pull::None);
let i2c_dev = I2c::new(
peripherals.I2C0,
Config::default().with_frequency(400.kHz()),
)
.unwrap()
.with_scl(peripherals.GPIO22)
.with_sda(peripherals.GPIO21);
esp_println::logger::init_logger_from_env();
log::info!("Got here 1");
let interface = I2CDisplayInterface::new(i2c_dev);
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
.into_buffered_graphics_mode();
display.init().unwrap();
log::info!("Got here 2");
let delay = Delay::new();
log::info!("calling display.delay()");
delay.delay_millis(400);
log::info!("calling display.init()");
display.init().unwrap();
log::info!("calling display.flush()");
let mut dht22 = Dht22::new(od_for_dht22, delay);
let text_style = MonoTextStyleBuilder::new()
.font(&FONT_6X10)
.text_color(BinaryColor::On)
.build();
let text_style_bold = MonoTextStyleBuilder::new()
.font(&FONT_6X13_BOLD)
.text_color(BinaryColor::On)
.build();
let point1 = Point::new(0, 0);
let point2 = Point::new(0, 19);
let mut buf1 = [0u8; 64];
let mut buf2 = [0u8; 64];
loop {
log::info!("Hello world!");
delay.delay_millis(2000);
match dht22.read() {
Ok(sensor_reading) => {
// Temperature
let str1 = format_no_std::show(
&mut buf1,
format_args!("Temperature: {} °C", sensor_reading.temperature),
).unwrap();
Text::with_baseline(
&str1,
point1,
text_style_bold,
Baseline::Top,
)
.draw(&mut display)
.unwrap();
// Humidity
let str2 = format_no_std::show(
&mut buf2,
format_args!("Humidity: {} %", sensor_reading.humidity),
).unwrap();
Text::with_baseline(&str2,
point2,
text_style, Baseline::Top)
.draw(&mut display)
.unwrap();
display.flush().unwrap();
log::info!(
"DHT 22 Sensor - Temperature: {} °C, humidity: {} %",
sensor_reading.temperature,
sensor_reading.humidity
)
}
Err(error) => log::error!("An error occurred while trying to read sensor: {:?}", error),
}
}
}
Embassy
Time to use embassy as we are going to output this to an html file and serve it. Embassy allow the creation of tasks. First let's set the wifi up.