+10
Cargo.lock
+10
Cargo.lock
···
906
"reqwless",
907
"serde",
908
"serde-json-core",
909
"smart-leds",
910
"st7789",
911
"static_cell",
···
2130
version = "0.1.0"
2131
source = "registry+https://github.com/rust-lang/crates.io-index"
2132
checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9"
2133
2134
[[package]]
2135
name = "siphasher"
···
906
"reqwless",
907
"serde",
908
"serde-json-core",
909
+
"shtcx",
910
"smart-leds",
911
"st7789",
912
"static_cell",
···
2131
version = "0.1.0"
2132
source = "registry+https://github.com/rust-lang/crates.io-index"
2133
checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9"
2134
+
2135
+
[[package]]
2136
+
name = "shtcx"
2137
+
version = "1.0.0"
2138
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2139
+
checksum = "2c25d66e6c78c6e19160a5b528cebe6f54d5737f091a2b90b08dbd7e63a9269f"
2140
+
dependencies = [
2141
+
"embedded-hal 1.0.0",
2142
+
]
2143
2144
[[package]]
2145
name = "siphasher"
+1
Cargo.toml
+1
Cargo.toml
+12
-16
src/badge_display/mod.rs
+12
-16
src/badge_display/mod.rs
···
4
cell::RefCell,
5
sync::atomic::{AtomicBool, AtomicU32, AtomicU8},
6
};
7
-
use cortex_m::interrupt::CriticalSection;
8
use defmt::*;
9
use display_image::get_current_image;
10
use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
···
42
pub static CURRENT_IMAGE: AtomicU8 = AtomicU8::new(0);
43
pub static CHANGE_IMAGE: AtomicBool = AtomicBool::new(true);
44
pub static WIFI_COUNT: AtomicU32 = AtomicU32::new(0);
45
-
46
pub static RTC_TIME_STRING: blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<String<8>>> =
47
blocking_mutex::Mutex::new(RefCell::new(String::<8>::new()));
48
-
49
pub static HOUR: AtomicU8 = AtomicU8::new(10);
50
pub static MINUTE: AtomicU8 = AtomicU8::new(57);
51
pub static SECOND: AtomicU8 = AtomicU8::new(0);
···
122
//Runs every 30 cycles/15 seconds and first run
123
if cycles_since_last_clear % 30 == 0 || first_run {
124
let count = WIFI_COUNT.load(core::sync::atomic::Ordering::Relaxed);
125
-
let count_text: String<16> = easy_format::<16>(format_args!("Count: {}", count));
126
-
let count_bounds = Rectangle::new(Point::new(0, 0), Size::new(WIDTH, 24));
127
-
count_bounds
128
.into_styled(
129
PrimitiveStyleBuilder::default()
130
.stroke_color(BinaryColor::Off)
···
135
.draw(&mut display)
136
.unwrap();
137
138
-
Text::new(count_text.as_str(), Point::new(8, 16), character_style)
139
.draw(&mut display)
140
.unwrap();
141
142
-
// // Draw the text box.
143
-
let result = display
144
-
.partial_update(count_bounds.try_into().unwrap())
145
-
.await;
146
match result {
147
Ok(_) => {}
148
Err(_) => {
149
info!("Error updating display");
150
}
151
}
152
-
// let _ = display.clear(Rgb565::WHITE.into());
153
-
// let _ = display.update().await;
154
WIFI_COUNT.store(count + 1, core::sync::atomic::Ordering::Relaxed);
155
}
156
···
207
let tga: Bmp<BinaryColor> = Bmp::from_slice(¤t_image.image()).unwrap();
208
let image = Image::new(&tga, current_image.image_location());
209
//clear image location by writing a white rectangle over previous image location
210
-
let image_bounds = Size::new(160, 140);
211
let clear_rectangle = Rectangle::new(
212
current_image.previous().image_location(),
213
Size::new(157, 101),
···
219
220
let _ = image.draw(&mut display);
221
//TODO need to look up the reginal area display
222
-
// let update_region = UpdateRegion::new(192, 32, 160, 144).unwrap();
223
-
// let result = display.partial_update(update_region).await;
224
let _ = display.update().await;
225
CHANGE_IMAGE.store(false, core::sync::atomic::Ordering::Relaxed);
226
}
···
4
cell::RefCell,
5
sync::atomic::{AtomicBool, AtomicU32, AtomicU8},
6
};
7
use defmt::*;
8
use display_image::get_current_image;
9
use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
···
41
pub static CURRENT_IMAGE: AtomicU8 = AtomicU8::new(0);
42
pub static CHANGE_IMAGE: AtomicBool = AtomicBool::new(true);
43
pub static WIFI_COUNT: AtomicU32 = AtomicU32::new(0);
44
pub static RTC_TIME_STRING: blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<String<8>>> =
45
blocking_mutex::Mutex::new(RefCell::new(String::<8>::new()));
46
+
pub static TEMP: AtomicU8 = AtomicU8::new(0);
47
+
pub static HUMIDITY: AtomicU8 = AtomicU8::new(0);
48
pub static HOUR: AtomicU8 = AtomicU8::new(10);
49
pub static MINUTE: AtomicU8 = AtomicU8::new(57);
50
pub static SECOND: AtomicU8 = AtomicU8::new(0);
···
121
//Runs every 30 cycles/15 seconds and first run
122
if cycles_since_last_clear % 30 == 0 || first_run {
123
let count = WIFI_COUNT.load(core::sync::atomic::Ordering::Relaxed);
124
+
let temp = TEMP.load(core::sync::atomic::Ordering::Relaxed);
125
+
let humidity = HUMIDITY.load(core::sync::atomic::Ordering::Relaxed);
126
+
let top_text: String<64> =
127
+
easy_format::<64>(format_args!("{}F {}% Count: {}", temp, humidity, count));
128
+
let top_bounds = Rectangle::new(Point::new(0, 0), Size::new(WIDTH, 24));
129
+
top_bounds
130
.into_styled(
131
PrimitiveStyleBuilder::default()
132
.stroke_color(BinaryColor::Off)
···
137
.draw(&mut display)
138
.unwrap();
139
140
+
Text::new(top_text.as_str(), Point::new(8, 16), character_style)
141
.draw(&mut display)
142
.unwrap();
143
144
+
// Draw the text box.
145
+
let result = display.partial_update(top_bounds.try_into().unwrap()).await;
146
match result {
147
Ok(_) => {}
148
Err(_) => {
149
info!("Error updating display");
150
}
151
}
152
+
153
WIFI_COUNT.store(count + 1, core::sync::atomic::Ordering::Relaxed);
154
}
155
···
206
let tga: Bmp<BinaryColor> = Bmp::from_slice(¤t_image.image()).unwrap();
207
let image = Image::new(&tga, current_image.image_location());
208
//clear image location by writing a white rectangle over previous image location
209
let clear_rectangle = Rectangle::new(
210
current_image.previous().image_location(),
211
Size::new(157, 101),
···
217
218
let _ = image.draw(&mut display);
219
//TODO need to look up the reginal area display
220
let _ = display.update().await;
221
CHANGE_IMAGE.store(false, core::sync::atomic::Ordering::Relaxed);
222
}
+8
-18
src/main.rs
+8
-18
src/main.rs
···
16
use embassy_rp::spi::{self};
17
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
18
use embassy_sync::mutex::Mutex;
19
-
use embassy_time::{Delay, Duration, Timer};
20
-
use embedded_graphics::{
21
-
image::Image,
22
-
mono_font::{ascii::*, MonoTextStyle},
23
-
pixelcolor::BinaryColor,
24
-
prelude::*,
25
-
primitives::{PrimitiveStyle, Rectangle},
26
-
};
27
-
use embedded_text::{
28
-
alignment::HorizontalAlignment,
29
-
style::{HeightMode, TextBoxStyleBuilder},
30
-
TextBox,
31
-
};
32
use gpio::{Level, Output, Pull};
33
use helpers::easy_format;
34
use static_cell::StaticCell;
35
use {defmt_rtt as _, panic_probe as _};
36
37
mod badge_display;
38
mod cyw43_driver;
39
mod env;
40
mod helpers;
41
42
type Spi0Bus = Mutex<NoopRawMutex, Spi<'static, SPI0, spi::Async>>;
43
···
73
let _btn_b = Input::new(p.PIN_13, Pull::Down);
74
let btn_c = Input::new(p.PIN_14, Pull::Down);
75
76
-
// let mut btn_c: Debouncer<'_> = Debouncer::new(Input::new(btn_c, Pull::Up), Duration::from_millis(20));
77
-
78
let spi = Spi::new(
79
p.SPI0,
80
clk,
···
84
p.DMA_CH2,
85
spi::Config::default(),
86
);
87
-
// let spi_bus: Mutex<NoopRawMutex, _> = Mutex::new(spi);
88
static SPI_BUS: StaticCell<Spi0Bus> = StaticCell::new();
89
let spi_bus = SPI_BUS.init(Mutex::new(spi));
90
91
info!("led on!");
92
// control.gpio_set(0, true).await;
93
spawner.must_spawn(run_the_display(spi_bus, cs, dc, busy, reset));
94
95
//rtc setup
···
101
month: 1,
102
day: 1,
103
day_of_week: DayOfWeek::Saturday,
104
-
hour: 0,
105
-
minute: 0,
106
second: 0,
107
};
108
rtc.set_datetime(now).unwrap();
···
16
use embassy_rp::spi::{self};
17
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
18
use embassy_sync::mutex::Mutex;
19
+
use embassy_time::{Duration, Timer};
20
use gpio::{Level, Output, Pull};
21
use helpers::easy_format;
22
use static_cell::StaticCell;
23
+
use temp_sensor::run_the_temp_sensor;
24
use {defmt_rtt as _, panic_probe as _};
25
26
mod badge_display;
27
mod cyw43_driver;
28
mod env;
29
mod helpers;
30
+
mod temp_sensor;
31
32
type Spi0Bus = Mutex<NoopRawMutex, Spi<'static, SPI0, spi::Async>>;
33
···
63
let _btn_b = Input::new(p.PIN_13, Pull::Down);
64
let btn_c = Input::new(p.PIN_14, Pull::Down);
65
66
let spi = Spi::new(
67
p.SPI0,
68
clk,
···
72
p.DMA_CH2,
73
spi::Config::default(),
74
);
75
+
76
+
//SPI Bus setup to run the e-ink display
77
static SPI_BUS: StaticCell<Spi0Bus> = StaticCell::new();
78
let spi_bus = SPI_BUS.init(Mutex::new(spi));
79
80
info!("led on!");
81
// control.gpio_set(0, true).await;
82
+
spawner.must_spawn(run_the_temp_sensor(p.I2C0, p.PIN_5, p.PIN_4));
83
spawner.must_spawn(run_the_display(spi_bus, cs, dc, busy, reset));
84
85
//rtc setup
···
91
month: 1,
92
day: 1,
93
day_of_week: DayOfWeek::Saturday,
94
+
hour: 18,
95
+
minute: 31,
96
second: 0,
97
};
98
rtc.set_datetime(now).unwrap();
+38
src/temp_sensor.rs
+38
src/temp_sensor.rs
···
···
1
+
use bt_hci::cmd::info;
2
+
use defmt::*;
3
+
use embassy_rp::i2c::{I2c, SclPin, SdaPin};
4
+
use embassy_rp::peripherals::I2C0;
5
+
use embassy_rp::{i2c, Peripheral};
6
+
use embassy_time::Timer;
7
+
use shtcx::{self, PowerMode};
8
+
9
+
use crate::badge_display::{HUMIDITY, TEMP}; // Import the necessary items from shtcx
10
+
11
+
#[embassy_executor::task]
12
+
pub async fn run_the_temp_sensor(
13
+
i2c0: I2C0,
14
+
scl: impl Peripheral<P = impl SclPin<I2C0>> + 'static,
15
+
sda: impl Peripheral<P = impl SdaPin<I2C0>> + 'static,
16
+
) {
17
+
let i2c = I2c::new_blocking(i2c0, scl, sda, i2c::Config::default());
18
+
19
+
let mut sht = shtcx::shtc3(i2c);
20
+
let mut sht_delay = embassy_time::Delay; // Create a delay instance
21
+
22
+
loop {
23
+
let combined = sht.measure(PowerMode::NormalMode, &mut sht_delay).unwrap();
24
+
let celsius = combined.temperature.as_degrees_celsius();
25
+
let fahrenheit = (celsius * 9.0 / 5.0) + 32.0;
26
+
info!(
27
+
"Temperature: {}°F, Humidity: {}%",
28
+
fahrenheit,
29
+
combined.humidity.as_percent()
30
+
);
31
+
TEMP.store(fahrenheit as u8, core::sync::atomic::Ordering::Relaxed);
32
+
HUMIDITY.store(
33
+
combined.humidity.as_percent() as u8,
34
+
core::sync::atomic::Ordering::Relaxed,
35
+
);
36
+
Timer::after_secs(120).await;
37
+
}
38
+
}