From 641eba5faa908fc8870c55b9b71de73c4bb1dee3 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Thu, 23 Jun 2022 22:12:00 +0200 Subject: [PATCH] Modify UDP protocol to be WLED-compatible. --- src/config.rs | 8 ++-- src/main.rs | 4 +- src/udpproto.rs | 102 +++++++++++------------------------------------- 3 files changed, 29 insertions(+), 85 deletions(-) diff --git a/src/config.rs b/src/config.rs index f1e4323..40c207d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,16 +6,16 @@ pub const SAMP_RATE: f32 = 48000.0; pub const SAMPLES_PER_UPDATE: usize = BLOCK_LEN/2; // LED configuration -pub const NUM_STRIPS: usize = 8; -pub const NUM_LEDS_PER_STRIP: usize = 16; +pub const NUM_STRIPS: usize = 1; +pub const NUM_LEDS_PER_STRIP: usize = 322; pub const NUM_LEDS_TOTAL: usize = NUM_STRIPS * NUM_LEDS_PER_STRIP; // network configuration -pub const UDP_SERVER_ADDR: &str = "192.168.23.118:2703"; +pub const UDP_SERVER_ADDR: &str = "wled1:21324"; pub const FPS_ANIMATION: f32 = SAMP_RATE / SAMPLES_PER_UPDATE as f32; -pub const FPS_LEDS: f32 = 60.0; +pub const FPS_LEDS: f32 = 30.0; // “standby mode” configuration pub const STANDBY_MAX_SILENT_SAMPLES: usize = SAMP_RATE as usize; diff --git a/src/main.rs b/src/main.rs index ffd3db6..5a63e3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ fn main() let mut stdin = std::io::stdin(); // set up the UDP protocol - let mut udpproto = match UdpProto::new(config::UDP_SERVER_ADDR) { + let mut udpproto = match UdpProto::new(config::UDP_SERVER_ADDR, config::NUM_LEDS_TOTAL) { Ok(u) => u, Err(e) => { println!("Error during UDP client setup:\n{}", e); @@ -135,7 +135,7 @@ fn main() let led = i % config::NUM_LEDS_PER_STRIP; let r = udpproto.set_color(strip as u8, - led as u8, + led, (colorlists[strip][led].r * 255.0) as u8, (colorlists[strip][led].g * 255.0) as u8, (colorlists[strip][led].b * 255.0) as u8, diff --git a/src/udpproto.rs b/src/udpproto.rs index 52a2a64..8f75b76 100644 --- a/src/udpproto.rs +++ b/src/udpproto.rs @@ -5,6 +5,8 @@ use std::net::SocketAddrV4; use std::net::Ipv4Addr; const MAX_PACKET_LEN: usize = 1470; +const TIMEOUT_SEC: u8 = 3; +const WLED_MODE_DRGBW: u8 = 3; struct Command { @@ -17,103 +19,45 @@ struct Command pub struct UdpProto { socket: UdpSocket, - packet: [u8; MAX_PACKET_LEN], - packet_offset: usize, + packet: Vec, } impl UdpProto { - pub fn new(target_address: &str) -> std::io::Result + pub fn new(target_address: &str, num_leds_total: usize) -> std::io::Result { - let u = UdpProto { + let mut u = UdpProto { socket: UdpSocket::bind(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0))?, - packet: [0u8; MAX_PACKET_LEN], - packet_offset: 0, + packet: vec![0; 2 + 4*num_leds_total], }; + u.packet[0] = WLED_MODE_DRGBW; + u.packet[1] = TIMEOUT_SEC; + u.socket.connect(target_address)?; Ok(u) } - fn send_packet(&mut self) -> std::io::Result<()> - { - if self.packet_offset == 0 { - // nothing to do - return Ok( () ); - } - - self.socket.send(&self.packet[0..self.packet_offset])?; - - self.packet_offset = 0; - - Ok( () ) - } - - fn add_command(&mut self, cmd: u8, strip: u8, led: u8, data: &[u8; 4]) -> std::io::Result<()> - { - // put the command into the packet buffer - self.packet[self.packet_offset + 0] = cmd; - self.packet[self.packet_offset + 1] = strip; - self.packet[self.packet_offset + 2] = led; - - for i in 0 .. data.len() { - self.packet[self.packet_offset + i + 3] = data[i]; - } - - self.packet_offset += 7; - - if self.packet_offset >= MAX_PACKET_LEN-7 { - self.send_packet()?; - } - - Ok( () ) - } - - pub fn set_color(&mut self, strip: u8, led: u8, + pub fn set_color(&mut self, _strip: u8, led: usize, r: u8, g: u8, b: u8, w: u8) -> std::io::Result<()> { - let data = [r,g,b,w]; - - self.add_command(0x00, strip, led, &data)?; - - Ok( () ) - } - - pub fn fade_color(&mut self, strip: u8, led: u8, - r: u8, g: u8, b: u8, w: u8) -> std::io::Result<()> - { - let data = [r,g,b,w]; - - self.add_command(0x01, strip, led, &data)?; - - Ok( () ) - } - - pub fn add_color(&mut self, strip: u8, led: u8, - r: u8, g: u8, b: u8, w: u8) -> std::io::Result<()> - { - let data = [r,g,b,w]; - - self.add_command(0x02, strip, led, &data)?; - - Ok( () ) - } - - pub fn set_fadestep(&mut self, fadestep: u8) -> std::io::Result<()> - { - let data = [fadestep, 0, 0, 0]; - - self.add_command(0x03, 0, 0, &data)?; - - Ok( () ) + let offset = 2 + 4*led; + if offset > self.packet.len() { + Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "LED index out of range")) + } + else { + self.packet[offset + 0] = r; + self.packet[offset + 1] = g; + self.packet[offset + 2] = b; + self.packet[offset + 3] = w; + Ok( () ) + } } pub fn commit(&mut self) -> std::io::Result<()> { - // add the END_OF_UPDATE command - self.add_command(0xFE, 0, 0, &[0u8; 4])?; - - self.send_packet() + self.socket.send(&self.packet)?; + Ok( () ) } }