@ -9,6 +9,7 @@
use defmt ::info ;
use embassy_executor ::Spawner ;
use embassy_time ::{ Delay , Duration , Timer } ;
use embedded_graphics ::primitives ::{ Line , Polyline , PrimitiveStyle } ;
use embedded_hal_bus ::spi ::ExclusiveDevice ;
use esp_hal ::clock ::CpuClock ;
use esp_hal ::gpio ::{ Input , InputConfig , Level , Output , OutputConfig , Pull } ;
@ -22,7 +23,8 @@ use esp_hal::time::Rate;
// epd
use epd_waveshare ::color ::Color ;
use epd_waveshare ::epd1in54_v2 ::{ Display1in54 , Epd1in54 } ;
//use epd_waveshare::epd1in54_v2::{Display1in54, Epd1in54};
use epd_waveshare ::epd4in2 ::{ Display4in2 , Epd4in2 } ;
use epd_waveshare ::prelude ::WaveshareDisplay ;
// embedded graphics
@ -40,10 +42,13 @@ fn panic(_: &core::panic::PanicInfo) -> ! {
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
esp_bootloader_esp_idf ::esp_app_desc ! ( ) ;
#[ esp_rtos::main ]
async fn main ( spawner : Spawner ) -> ! {
// generator version: 1.0.0
esp_alloc ::heap_allocator ! ( size : 72 * 1024 ) ;
let config = esp_hal ::Config ::default ( ) . with_cpu_clock ( CpuClock ::max ( ) ) ;
let peripherals = esp_hal ::init ( config ) ;
@ -58,36 +63,158 @@ async fn main(spawner: Spawner) -> ! {
let spi_bus = Spi ::new (
peripherals . SPI2 ,
spi ::master ::Config ::default ( )
. with_frequency ( Rate ::from_mhz ( 4 ) )
. with_frequency ( Rate ::from_mhz ( 20 ) )
. with_mode ( spi ::Mode ::_0 ) ,
)
. unwrap ( )
//CLK
. with_sck ( peripherals . GPIO18 )
. with_sck ( peripherals . GPIO12 )
//DIN
. with_mosi ( peripherals . GPIO23 ) ;
. with_mosi ( peripherals . GPIO11 )
. with_cs ( peripherals . GPIO10 ) ;
let cs = Output ::new ( peripherals . GPIO33 , Level ::Low , OutputConfig ::default ( ) ) ;
let mut spi_dev = ExclusiveDevice ::new ( spi_bus , cs , Delay ) . unwrap ( ) ;
// Initialize Display
let busy_in = Input ::new (
peripherals . GPIO22 ,
peripherals . GPIO16 ,
InputConfig ::default ( ) . with_pull ( Pull ::None ) ,
) ;
let dc = Output ::new ( peripherals . GPIO17 , Level ::Low , OutputConfig ::default ( ) ) ;
let reset = Output ::new ( peripherals . GPIO16 , Level ::Low , OutputConfig ::default ( ) ) ;
let mut display = Display1in54 ::default ( ) ;
let mut epd = Epd1in54 ::new ( & mut spi_dev , busy_in , dc , reset , & mut Delay , None ) . unwrap ( ) ;
let dc = Output ::new ( peripherals . GPIO15 , Level ::Low , OutputConfig ::default ( ) ) ;
let reset = Output ::new ( peripherals . GPIO17 , Level ::Low , OutputConfig ::default ( ) ) ;
let mut display = Display4in2 ::default ( ) ;
let mut epd = Epd4in2 ::new ( & mut spi_dev , busy_in , dc , reset , & mut Delay , None ) . unwrap ( ) ;
// Clear any existing image
epd . clear_frame ( & mut spi_dev , & mut Delay ) . unwrap ( ) ;
display . clear ( Color ::White ) . unwrap ( ) ;
epd . update_and_display_frame ( & mut spi_dev , display . buffer ( ) , & mut Delay )
. unwrap ( ) ;
Timer ::after ( Duration ::from_secs ( 5 ) ) . await ;
draw_text ( & mut display , "impl Rust for ESP32" , 3 , 100 ) ;
let prices = [
124.51 ,
120.29 ,
117.14 ,
115.63 ,
122.15 ,
119.4 ,
119.33 ,
117.12 ,
120.92 ,
118.14 ,
115.3 ,
115.01 ,
116.5 ,
119.49 ,
117.0 ,
118.34 ,
117.67 ,
118.73 ,
120.93 ,
123.66 ,
119.8 ,
129.0 ,
143.99 ,
153.06 ,
152.2 ,
168.99 ,
179.1 ,
190.23 ,
203.74 ,
191.36 ,
170.92 ,
139.56 ,
194.19 ,
151.4 ,
136.77 ,
107.87 ,
136.41 ,
122.21 ,
109.38 ,
88.01 ,
101.21 ,
90.13 ,
86.53 ,
71.17 ,
85.31 ,
77.93 ,
68.83 ,
59.17 ,
70.74 ,
64.99 ,
61.01 ,
56.54 ,
61.21 ,
59.19 ,
57.9 ,
60.1 ,
58.27 ,
67.62 ,
82.3 ,
88.11 ,
78.83 ,
91.99 ,
95.32 ,
103.15 ,
90.64 ,
100.02 ,
100.98 ,
120.69 ,
105.61 ,
130.77 ,
146.59 ,
173.23 ,
145.81 ,
159.0 ,
163.46 ,
167.46 ,
192.98 ,
177.61 ,
158.25 ,
144.14 ,
174.9 ,
150.14 ,
127.52 ,
119.0 ,
124.13 ,
122.5 ,
119.78 ,
109.57 ,
123.1 ,
117.9 ,
117.59 ,
108.05 ,
113.65 ,
106.89 ,
105.25 ,
98.26 ,
] ;
let mut points = [ Point ::new ( 0 , 0 ) ; 96 /* TODO: same size as prices? or assume+validate / truncate first 96? */ ] ;
let mut foo = [ 0 u8 ; 2 ] ;
for ( i , pr ) in prices . iter ( ) . enumerate ( ) {
points [ i ] = Point ::new ( i as i32 * 4 , 300 - * pr as i32 ) ;
if i % 18 = = 0 {
Line ::new ( Point ::new ( i as i32 * 4 , 300 ) , Point ::new ( i as i32 * 4 , 290 ) )
. into_styled ( PrimitiveStyle ::with_stroke ( Color ::Black , 5 ) )
. draw ( & mut display )
. expect ( "draw x-axis tick" ) ;
// no proper write/format library..
foo [ 0 ] = b'0' + ( i / 10 ) as u8 ;
foo [ 1 ] = b'0' + ( i % 10 ) as u8 ;
draw_text ( & mut display , str ::from_utf8 ( & foo [ . . ] ) . unwrap ( ) , i as i32 * 4 , 280 ) ;
}
}
let line_style = PrimitiveStyle ::with_stroke ( Color ::Black , 3 ) ;
Polyline ::new ( & points )
. into_styled ( line_style )
. draw ( & mut display )
. expect ( "draw polyline" ) ;
epd . update_and_display_frame ( & mut spi_dev , display . buffer ( ) , & mut Delay )
. unwrap ( ) ;
Timer ::after ( Duration ::from_secs ( 5 ) ) . await ;
@ -100,7 +227,7 @@ async fn main(spawner: Spawner) -> ! {
}
}
fn draw_text ( display : & mut Display1in54 , text : & str , x : i32 , y : i32 ) {
fn draw_text ( display : & mut Display4in2 , text : & str , x : i32 , y : i32 ) {
let text_style = MonoTextStyleBuilder ::new ( )
. font ( & FONT_10X20 )
. text_color ( Color ::Black )
@ -110,3 +237,19 @@ fn draw_text(display: &mut Display1in54, text: &str, x: i32, y: i32) {
. draw ( display )
. unwrap ( ) ;
}
// TODO / wishlist
//
// ## more hardware support/use
//
// * rtc initialization, and/or NTP query, to print times.
// - maybe we can just convert the time steps from the returned data set, and e.g. do x axis ticks on multiples of 3hours from that
// * wifi
// * tls
// * json parser
// => fetch data from https://api.energy-charts.info/price?bzn=DE-LU
//
//
// ## drawing prettier
// * chrono: timestamp -> datetime<utc> -> .hours() % 3 == 0, then x-axis tick