eyeiii/src/main.rs

188 lines
7.5 KiB
Rust

use std::{error::Error, thread::sleep, time::Duration};
use embedded_graphics::{image::Image, pixelcolor::Rgb565, prelude::*};
use esp_idf_hal::{
gpio::{Gpio12, Gpio14, Gpio16, Gpio17, Gpio18, Gpio23, Gpio5, Input, Output},
prelude::{Hertz, Peripherals},
spi::{self, Master, Pins, SPI3},
};
// If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use esp_idf_sys as _;
use rand::Rng;
use ssd1331::Ssd1331;
use tinybmp::Bmp;
fn secondary() -> Result<(), Box<dyn Error>> {
// Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once,
// or else some patches to the runtime implemented by esp-idf-sys might not link properly.
esp_idf_sys::link_patches();
// Bind the log crate to the ESP Logging facilities
esp_idf_svc::log::EspLogger::initialize_default();
let peripherals = Peripherals::take().unwrap();
let spi3 = peripherals.spi3;
let pins = peripherals.pins;
let cs: Gpio17<Output> = pins.gpio17.into_output()?;
let dc: Gpio16<Output> = pins.gpio16.into_output()?;
let mosi: Gpio23<Output> = pins.gpio23.into_output()?;
let sclk: Gpio18<Output> = pins.gpio18.into_output()?;
let reset: Gpio5<Output> = pins.gpio5.into_output()?;
let read: Gpio12<Input> = pins.gpio12.into_input()?;
let write: Gpio14<Output> = pins.gpio14.into_output()?;
let spiman =
spi::Master::<SPI3, Gpio18<Output>, Gpio23<Output>, Gpio5<Output>, Gpio17<Output>>::new(
spi3,
Pins {
sclk: sclk,
sdo: mosi,
sdi: Some(reset),
cs: Some(cs),
},
spi::config::Config {
baudrate: Hertz(24000000),
data_mode: embedded_hal::spi::MODE_0,
write_only: false,
dma: spi::Dma::Disabled,
},
)?;
let mut display = Ssd1331::new(spiman, dc, ssd1331::DisplayRotation::Rotate180);
display.init().unwrap();
display.flush().unwrap();
let (w, h) = display.dimensions();
println!("got resolution {} x {}", w.clone(), h.clone());
let mut rng = rand::thread_rng();
let eye = Bmp::from_slice(include_bytes!("./eye.bmp")).expect("Failed to load BMP image");
let eye_closed =
Bmp::from_slice(include_bytes!("./eye_closed.bmp")).expect("Failed to load BMP image");
let emilis = Bmp::from_slice(include_bytes!("./emilis.bmp")).expect("Failed to load BMP image");
print_image(emilis, &mut display, h as u32, w as u32);
sleep(Duration::from_secs(3));
display.clear();
puff_idle(&mut display, h as u32, w as u32);
loop {
print_image(eye, &mut display, h as u32, w as u32);
sleep(Duration::from_secs(rng.gen_range(2..8)));
print_image(eye_closed, &mut display, h as u32, w as u32);
sleep(Duration::from_millis(190))
}
}
fn print_image(
img: Bmp<Rgb565>,
display: &mut Ssd1331<
Master<SPI3, Gpio18<Output>, Gpio23<Output>, Gpio5<Output>, Gpio17<Output>>,
Gpio16<Output>,
>,
h: u32,
w: u32,
) {
let im: Image<Bmp<Rgb565>> = Image::new(&img, Point::zero());
// Position image in the center of the display
let moved = im.translate(Point::new(
(w - img.size().width) as i32 / 2,
(h - img.size().height) as i32 / 2,
));
moved.draw(display).unwrap();
display.flush().unwrap();
}
fn puff_idle(
display: &mut Ssd1331<
Master<SPI3, Gpio18<Output>, Gpio23<Output>, Gpio5<Output>, Gpio17<Output>>,
Gpio16<Output>,
>,
h: u32,
w: u32,
) -> ! {
let raw = get_puff_raw();
let mut frames = Vec::<Bmp<Rgb565>>::new();
for raw_image in raw {
let frame_bmp = Bmp::from_slice(raw_image).unwrap();
frames.push(frame_bmp);
}
loop {
for frame in &frames {
print_image(*frame, display, h, w);
sleep(Duration::from_millis(1));
}
}
}
// Manually unrolled because im gay
fn get_puff_raw() -> Vec<&'static [u8]> {
let mut raw = Vec::<&[u8]>::new();
raw.push(include_bytes!("../puff/puffidle-0.bmp"));
raw.push(include_bytes!("../puff/puffidle-1.bmp"));
raw.push(include_bytes!("../puff/puffidle-2.bmp"));
raw.push(include_bytes!("../puff/puffidle-3.bmp"));
raw.push(include_bytes!("../puff/puffidle-4.bmp"));
raw.push(include_bytes!("../puff/puffidle-5.bmp"));
raw.push(include_bytes!("../puff/puffidle-6.bmp"));
raw.push(include_bytes!("../puff/puffidle-7.bmp"));
raw.push(include_bytes!("../puff/puffidle-8.bmp"));
raw.push(include_bytes!("../puff/puffidle-9.bmp"));
raw.push(include_bytes!("../puff/puffidle-10.bmp"));
raw.push(include_bytes!("../puff/puffidle-11.bmp"));
raw.push(include_bytes!("../puff/puffidle-12.bmp"));
raw.push(include_bytes!("../puff/puffidle-13.bmp"));
raw.push(include_bytes!("../puff/puffidle-14.bmp"));
raw.push(include_bytes!("../puff/puffidle-15.bmp"));
raw.push(include_bytes!("../puff/puffidle-16.bmp"));
raw.push(include_bytes!("../puff/puffidle-17.bmp"));
raw.push(include_bytes!("../puff/puffidle-18.bmp"));
raw.push(include_bytes!("../puff/puffidle-19.bmp"));
raw.push(include_bytes!("../puff/puffidle-20.bmp"));
raw.push(include_bytes!("../puff/puffidle-21.bmp"));
raw.push(include_bytes!("../puff/puffidle-22.bmp"));
raw.push(include_bytes!("../puff/puffidle-23.bmp"));
raw.push(include_bytes!("../puff/puffidle-24.bmp"));
raw.push(include_bytes!("../puff/puffidle-25.bmp"));
raw.push(include_bytes!("../puff/puffidle-26.bmp"));
raw.push(include_bytes!("../puff/puffidle-27.bmp"));
raw.push(include_bytes!("../puff/puffidle-28.bmp"));
raw.push(include_bytes!("../puff/puffidle-29.bmp"));
raw.push(include_bytes!("../puff/puffidle-30.bmp"));
raw.push(include_bytes!("../puff/puffidle-31.bmp"));
raw.push(include_bytes!("../puff/puffidle-32.bmp"));
raw.push(include_bytes!("../puff/puffidle-33.bmp"));
raw.push(include_bytes!("../puff/puffidle-34.bmp"));
raw.push(include_bytes!("../puff/puffidle-35.bmp"));
raw.push(include_bytes!("../puff/puffidle-36.bmp"));
raw.push(include_bytes!("../puff/puffidle-37.bmp"));
raw.push(include_bytes!("../puff/puffidle-38.bmp"));
raw.push(include_bytes!("../puff/puffidle-39.bmp"));
raw.push(include_bytes!("../puff/puffidle-40.bmp"));
raw.push(include_bytes!("../puff/puffidle-41.bmp"));
raw.push(include_bytes!("../puff/puffidle-42.bmp"));
raw.push(include_bytes!("../puff/puffidle-43.bmp"));
raw.push(include_bytes!("../puff/puffidle-44.bmp"));
raw.push(include_bytes!("../puff/puffidle-45.bmp"));
raw.push(include_bytes!("../puff/puffidle-46.bmp"));
raw.push(include_bytes!("../puff/puffidle-47.bmp"));
raw.push(include_bytes!("../puff/puffidle-48.bmp"));
raw.push(include_bytes!("../puff/puffidle-49.bmp"));
raw.push(include_bytes!("../puff/puffidle-50.bmp"));
raw.push(include_bytes!("../puff/puffidle-51.bmp"));
raw.push(include_bytes!("../puff/puffidle-52.bmp"));
raw.push(include_bytes!("../puff/puffidle-53.bmp"));
raw.push(include_bytes!("../puff/puffidle-54.bmp"));
raw.push(include_bytes!("../puff/puffidle-55.bmp"));
raw.push(include_bytes!("../puff/puffidle-56.bmp"));
raw.push(include_bytes!("../puff/puffidle-57.bmp"));
raw.push(include_bytes!("../puff/puffidle-58.bmp"));
raw.push(include_bytes!("../puff/puffidle-59.bmp"));
raw
}
fn main() -> Result<(), Box<dyn Error>> {
sleep(Duration::from_secs(1));
Ok(secondary().unwrap())
}