added led ws 2812 and buzzer stuff

This commit is contained in:
PC_WSL 2025-05-05 12:34:41 +02:00
parent f3c4e9884e
commit e14f703a76
8 changed files with 226 additions and 40 deletions

71
Cargo.lock generated
View File

@ -273,6 +273,16 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "embedded-hal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
]
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.35" version = "0.8.35"
@ -403,7 +413,9 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"simplelog", "simplelog",
"smart-leds",
"tokio", "tokio",
"ws2812-spi",
] ]
[[package]] [[package]]
@ -753,6 +765,21 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "nb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.1.0",
]
[[package]]
name = "nb"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
[[package]] [[package]]
name = "nu-ansi-term" name = "nu-ansi-term"
version = "0.46.0" version = "0.46.0"
@ -1037,6 +1064,15 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rgb"
version = "0.8.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
dependencies = [
"bytemuck",
]
[[package]] [[package]]
name = "rocket" name = "rocket"
version = "0.5.1" version = "0.5.1"
@ -1315,6 +1351,24 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
[[package]]
name = "smart-leds"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38dd45fa275f70b4110eac5f5182611ad384f88bb22b68b9a9c3cafd7015290b"
dependencies = [
"smart-leds-trait",
]
[[package]]
name = "smart-leds-trait"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebf6d833fa93f16a1c1874e62c2aebe8567e5bdd436d59bf543ed258b6f7a8e3"
dependencies = [
"rgb",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.9" version = "0.5.9"
@ -1634,6 +1688,12 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]] [[package]]
name = "walkdir" name = "walkdir"
version = "2.5.0" version = "2.5.0"
@ -1982,6 +2042,17 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "ws2812-spi"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6c2ba0d6c0ea9c117487411e93dc5dacaafc2c17698677a03d1c67901d4c70a"
dependencies = [
"embedded-hal",
"nb 0.1.3",
"smart-leds-trait",
]
[[package]] [[package]]
name = "yansi" name = "yansi"
version = "1.0.1" version = "1.0.1"

View File

@ -7,7 +7,6 @@ edition = "2024"
chrono = { version = "0.4.40", features = ["serde"] } chrono = { version = "0.4.40", features = ["serde"] }
gpio = "0.4.1" gpio = "0.4.1"
regex = "1.11.1" regex = "1.11.1"
rppal = "0.22.1"
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
rocket = "0.5.1" rocket = "0.5.1"
@ -16,5 +15,9 @@ rust-embed = "8.7.0"
log = "0.4.27" log = "0.4.27"
simplelog = "0.12.2" simplelog = "0.12.2"
rppal = "0.22.1"
smart-leds = "0.3"
ws2812-spi = "0.3"
[target.armv7-unknown-linux-gnueabihf] [target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc" linker = "arm-linux-gnueabihf-gcc"

24
buzzer.py Normal file
View File

@ -0,0 +1,24 @@
import RPi.GPIO as GPIO
import time
BUZZER_PIN = 26
def beep(frequency, duration):
pwm = GPIO.PWM(BUZZER_PIN, frequency)
pwm.start(50) # 50 % duty cycle
time.sleep(duration)
pwm.stop()
def main():
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
try:
beep(523, 0.3) # C5
beep(659, 0.3) # E5
beep(784, 0.3) # G5
finally:
GPIO.cleanup()
if __name__ == "__main__":
main()

View File

@ -1,8 +1,10 @@
use rppal::gpio::Gpio; pub mod buzzer {
use std::{thread, time}; use rppal::gpio::Gpio;
use std::{thread, time};
/// Emits a sound on a passive buzzer.
pub fn modulated_tone(pin_num: u8, carrier_hz: u32, sound_hz: u32, duration_ms: u64) { /// Emits a sound on a passive buzzer.
pub fn modulated_tone(pin_num: u8, carrier_hz: u32, sound_hz: u32, duration_ms: u64) {
let gpio = Gpio::new().expect("GPIO konnte nicht initialisiert werden"); let gpio = Gpio::new().expect("GPIO konnte nicht initialisiert werden");
let mut pin = gpio.get(pin_num).expect("Pin konnte nicht geöffnet werden").into_output(); let mut pin = gpio.get(pin_num).expect("Pin konnte nicht geöffnet werden").into_output();
@ -24,23 +26,24 @@ pub fn modulated_tone(pin_num: u8, carrier_hz: u32, sound_hz: u32, duration_ms:
let pause = time::Duration::from_millis((mod_period / 2.0) as u64); let pause = time::Duration::from_millis((mod_period / 2.0) as u64);
thread::sleep(pause); thread::sleep(pause);
} }
} }
pub fn beep_ack() { pub fn beep_ack() {
// GPIO 17, carrier = 2300 Hz, sound = 440 Hz, Dauer = 1 sec // GPIO 17, carrier = 2300 Hz, sound = 440 Hz, Dauer = 1 sec
modulated_tone(4, 2300, 500, 500); modulated_tone(4, 2300, 500, 500);
modulated_tone(4, 2300, 700, 500); modulated_tone(4, 2300, 700, 500);
} }
pub fn beep_nak() { pub fn beep_nak() {
// GPIO 17, carrier = 2300 Hz, sound = 440 Hz, duration = 1 sec // GPIO 17, carrier = 2300 Hz, sound = 440 Hz, duration = 1 sec
modulated_tone(4, 2300, 700, 500); modulated_tone(4, 2300, 700, 500);
modulated_tone(4, 2300, 500, 500); modulated_tone(4, 2300, 500, 500);
} }
pub fn beep_unnkown(){ pub fn beep_unnkown(){
modulated_tone(4, 2300, 500, 500); modulated_tone(4, 2300, 500, 500);
modulated_tone(4, 2300, 500, 500); modulated_tone(4, 2300, 500, 500);
modulated_tone(4, 2300, 500, 500); modulated_tone(4, 2300, 500, 500);
}
} }

39
src/color.rs Normal file
View File

@ -0,0 +1,39 @@
#[derive(Clone, Copy)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Color {
pub fn to_grb(self) -> [u8; 3] {
[self.g, self.r, self.b]
}
}
#[derive(Debug, Clone, Copy)]
pub enum NamedColor {
Red,
Green,
Blue,
White,
Off,
Yellow,
Cyan,
Magenta,
}
impl From<NamedColor> for Color {
fn from(named: NamedColor) -> Self {
match named {
NamedColor::Red => Color { r: 255, g: 0, b: 0 },
NamedColor::Green => Color { r: 0, g: 255, b: 0 },
NamedColor::Blue => Color { r: 0, g: 0, b: 255 },
NamedColor::White => Color { r: 255, g: 255, b: 255 },
NamedColor::Off => Color { r: 0, g: 0, b: 0 },
NamedColor::Yellow => Color { r: 255, g: 255, b: 0 },
NamedColor::Cyan => Color { r: 0, g: 255, b: 255 },
NamedColor::Magenta => Color { r: 255, g: 0, b: 255 },
}
}
}

View File

@ -4,6 +4,11 @@ use std::{
error::Error, error::Error,
fmt::Display, fmt::Display,
}; };
use crate::led::Led;
use tokio::fs;
use crate::led::Led;
use tokio::fs; use tokio::fs;
/// Represents the ID that is stored on the Tally /// Represents the ID that is stored on the Tally
@ -130,7 +135,12 @@ impl AttendanceDay {
return false; return false;
} }
self.ids.push(id); self.ids.push(id);
true
buzzer::beep_ack();
led.set_named_color_time(NamedColor::Green, 1); //led is green for 1 sec
return true;
} }
} }

28
src/led.rs Normal file
View File

@ -0,0 +1,28 @@
use rppal::spi::{Bus, Mode, SlaveSelect, Spi};
use smart_leds::{SmartLedsWrite, RGB8};
use ws2812_spi::Ws2812;
pub struct Led {
controller: Ws2812<Spi>,
}
impl Led {
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
let spi = Spi::new(Bus::Spi0, SlaveSelect::Ss0, 3_000_000, Mode::Mode0)?;
let controller = Ws2812::new(spi);
Ok(Led { controller })
}
pub fn turn_green_on(&mut self) -> Result<(), Box<dyn std::error::Error>> {
let green = [RGB8 { r: 0, g: 255, b: 0 }];
self.controller.write(green.iter().cloned())?;
Ok(())
}
pub fn turn_off(&mut self) -> Result<(), Box<dyn std::error::Error>> {
let off = [RGB8 { r: 0, g: 0, b: 0 }];
self.controller.write(off.iter().cloned())?;
Ok(())
}
}

View File

@ -13,6 +13,10 @@ mod id_store;
mod parser; mod parser;
mod pm3; mod pm3;
mod webserver; mod webserver;
mod color;
mod led;
mod buzzer;
const STORE_PATH: &str = "./data.json"; const STORE_PATH: &str = "./data.json";
@ -85,6 +89,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
} }
}); });
tokio::spawn(async move {
})
match start_webserver(store.clone()).await { match start_webserver(store.clone()).await {
Ok(()) => {} Ok(()) => {}
Err(e) => { Err(e) => {