mirror of
				https://github.com/Djeeberjr/fw-anwesenheit.git
				synced 2025-11-03 23:24:10 +00:00 
			
		
		
		
	added led ws 2812 and buzzer stuff
This commit is contained in:
		
							parent
							
								
									f3c4e9884e
								
							
						
					
					
						commit
						e14f703a76
					
				
							
								
								
									
										71
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										71
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -273,6 +273,16 @@ version = "1.15.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "encoding_rs"
 | 
			
		||||
version = "0.8.35"
 | 
			
		||||
@ -403,7 +413,9 @@ dependencies = [
 | 
			
		||||
 "serde",
 | 
			
		||||
 "serde_json",
 | 
			
		||||
 "simplelog",
 | 
			
		||||
 "smart-leds",
 | 
			
		||||
 "tokio",
 | 
			
		||||
 "ws2812-spi",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -753,6 +765,21 @@ dependencies = [
 | 
			
		||||
 "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]]
 | 
			
		||||
name = "nu-ansi-term"
 | 
			
		||||
version = "0.46.0"
 | 
			
		||||
@ -1037,6 +1064,15 @@ version = "0.8.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rgb"
 | 
			
		||||
version = "0.8.50"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "bytemuck",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rocket"
 | 
			
		||||
version = "0.5.1"
 | 
			
		||||
@ -1315,6 +1351,24 @@ version = "1.15.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "socket2"
 | 
			
		||||
version = "0.5.9"
 | 
			
		||||
@ -1634,6 +1688,12 @@ version = "0.9.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "void"
 | 
			
		||||
version = "1.0.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "walkdir"
 | 
			
		||||
version = "2.5.0"
 | 
			
		||||
@ -1982,6 +2042,17 @@ dependencies = [
 | 
			
		||||
 "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]]
 | 
			
		||||
name = "yansi"
 | 
			
		||||
version = "1.0.1"
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,6 @@ edition = "2024"
 | 
			
		||||
chrono = { version = "0.4.40", features = ["serde"] }
 | 
			
		||||
gpio = "0.4.1"
 | 
			
		||||
regex = "1.11.1"
 | 
			
		||||
rppal = "0.22.1"
 | 
			
		||||
serde = { version = "1.0.219", features = ["derive"] }
 | 
			
		||||
serde_json = "1.0.140"
 | 
			
		||||
rocket = "0.5.1"
 | 
			
		||||
@ -16,5 +15,9 @@ rust-embed = "8.7.0"
 | 
			
		||||
log = "0.4.27"
 | 
			
		||||
simplelog = "0.12.2"
 | 
			
		||||
 | 
			
		||||
rppal = "0.22.1"
 | 
			
		||||
smart-leds = "0.3"
 | 
			
		||||
ws2812-spi = "0.3"
 | 
			
		||||
 | 
			
		||||
[target.armv7-unknown-linux-gnueabihf]
 | 
			
		||||
linker = "arm-linux-gnueabihf-gcc"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								buzzer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								buzzer.py
									
									
									
									
									
										Normal 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()
 | 
			
		||||
@ -1,46 +1,49 @@
 | 
			
		||||
use rppal::gpio::Gpio;
 | 
			
		||||
use std::{thread, time};
 | 
			
		||||
pub mod buzzer {
 | 
			
		||||
    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) {
 | 
			
		||||
    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 carrier_period = time::Duration::from_micros((1_000_000.0 / carrier_hz as f64 / 2.0) as u64);
 | 
			
		||||
    let mod_period = 1_000.0 / sound_hz as f64; // in ms
 | 
			
		||||
    let total_cycles = duration_ms as f64 / mod_period;
 | 
			
		||||
    /// 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 mut pin = gpio.get(pin_num).expect("Pin konnte nicht geöffnet werden").into_output();
 | 
			
		||||
 | 
			
		||||
    for _ in 0..total_cycles as u64 {
 | 
			
		||||
        // Modulation on: Carrier on for mod_period / 2
 | 
			
		||||
        let cycles_on = (carrier_hz as f64 * (mod_period / 2.0) / 1000.0) as u64;
 | 
			
		||||
        for _ in 0..cycles_on {
 | 
			
		||||
            pin.set_high();
 | 
			
		||||
            thread::sleep(carrier_period);
 | 
			
		||||
            pin.set_low();
 | 
			
		||||
            thread::sleep(carrier_period);
 | 
			
		||||
        let carrier_period = time::Duration::from_micros((1_000_000.0 / carrier_hz as f64 / 2.0) as u64);
 | 
			
		||||
        let mod_period = 1_000.0 / sound_hz as f64; // in ms
 | 
			
		||||
        let total_cycles = duration_ms as f64 / mod_period;
 | 
			
		||||
 | 
			
		||||
        for _ in 0..total_cycles as u64 {
 | 
			
		||||
            // Modulation on: Carrier on for mod_period / 2
 | 
			
		||||
            let cycles_on = (carrier_hz as f64 * (mod_period / 2.0) / 1000.0) as u64;
 | 
			
		||||
            for _ in 0..cycles_on {
 | 
			
		||||
                pin.set_high();
 | 
			
		||||
                thread::sleep(carrier_period);
 | 
			
		||||
                pin.set_low();
 | 
			
		||||
                thread::sleep(carrier_period);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Modulation off: Carrier on for mod_period / 2
 | 
			
		||||
            let pause = time::Duration::from_millis((mod_period / 2.0) as u64);
 | 
			
		||||
            thread::sleep(pause);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        // Modulation off: Carrier on for mod_period / 2
 | 
			
		||||
        let pause = time::Duration::from_millis((mod_period / 2.0) as u64);
 | 
			
		||||
        thread::sleep(pause);
 | 
			
		||||
    pub fn beep_ack() {
 | 
			
		||||
        // GPIO 17, carrier  = 2300 Hz, sound = 440 Hz, Dauer = 1 sec
 | 
			
		||||
        modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
        modulated_tone(4, 2300, 700, 500);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn beep_nak() {
 | 
			
		||||
        // GPIO 17, carrier  = 2300 Hz, sound = 440 Hz, duration = 1 sec
 | 
			
		||||
        modulated_tone(4, 2300, 700, 500);
 | 
			
		||||
        modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn beep_unnkown(){
 | 
			
		||||
        modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
        modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
        modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn beep_ack() {
 | 
			
		||||
    // GPIO 17, carrier  = 2300 Hz, sound = 440 Hz, Dauer = 1 sec
 | 
			
		||||
    modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
    modulated_tone(4, 2300, 700, 500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn beep_nak() {
 | 
			
		||||
    // GPIO 17, carrier  = 2300 Hz, sound = 440 Hz, duration = 1 sec
 | 
			
		||||
    modulated_tone(4, 2300, 700, 500);
 | 
			
		||||
    modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn beep_unnkown(){
 | 
			
		||||
    modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
    modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
    modulated_tone(4, 2300, 500, 500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								src/color.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/color.rs
									
									
									
									
									
										Normal 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 },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -4,6 +4,11 @@ use std::{
 | 
			
		||||
    error::Error,
 | 
			
		||||
    fmt::Display,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::led::Led;
 | 
			
		||||
use tokio::fs;
 | 
			
		||||
 | 
			
		||||
use crate::led::Led;
 | 
			
		||||
use tokio::fs;
 | 
			
		||||
 | 
			
		||||
/// Represents the ID that is stored on the Tally
 | 
			
		||||
@ -130,7 +135,12 @@ impl AttendanceDay {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        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
									
								
							
							
						
						
									
										28
									
								
								src/led.rs
									
									
									
									
									
										Normal 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(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -13,6 +13,10 @@ mod id_store;
 | 
			
		||||
mod parser;
 | 
			
		||||
mod pm3;
 | 
			
		||||
mod webserver;
 | 
			
		||||
mod color;
 | 
			
		||||
mod led;
 | 
			
		||||
mod buzzer;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
        Ok(()) => {}
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user