Started implementing the UDP protocol
This commit is contained in:
parent
ded8a7c21f
commit
7631bfb669
|
@ -10,3 +10,6 @@ pub const NUM_STRIPS: usize = 8;
|
|||
pub const NUM_LEDS_PER_STRIP: usize = 16;
|
||||
|
||||
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";
|
||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -8,9 +8,11 @@ use byteorder::{NativeEndian, ReadBytesExt};
|
|||
mod signal_processing;
|
||||
mod config;
|
||||
mod userscript;
|
||||
mod udpproto;
|
||||
|
||||
use crate::signal_processing::SignalProcessing;
|
||||
use crate::userscript::UserScript;
|
||||
use crate::udpproto::UdpProto;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
@ -19,6 +21,15 @@ fn main()
|
|||
{
|
||||
let mut stdin = std::io::stdin();
|
||||
|
||||
// set up the UDP protocol
|
||||
let mut udpproto = match UdpProto::new(config::UDP_SERVER_ADDR) {
|
||||
Ok(u) => u,
|
||||
Err(e) => {
|
||||
println!("Error during UDP client setup:\n{}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// set up signal processing
|
||||
|
||||
println!("Initializing signal processing...");
|
||||
|
@ -30,7 +41,7 @@ fn main()
|
|||
|
||||
println!("Loading user script...");
|
||||
|
||||
let script = match UserScript::new(sigproc.clone(), "test.lua") {
|
||||
let mut script = match UserScript::new(sigproc.clone(), "test.lua") {
|
||||
Ok(script) => script,
|
||||
Err(e) => {
|
||||
println!("=== Lua Error ===\n{}\n====> Terminating.", e);
|
||||
|
@ -98,6 +109,18 @@ fn main()
|
|||
}
|
||||
};
|
||||
|
||||
// FIXME: only send with 60 FPS!
|
||||
|
||||
for i in 0..script.colorlists[0].len() {
|
||||
udpproto.set_color((i / config::NUM_LEDS_PER_STRIP) as u8,
|
||||
(i % config::NUM_LEDS_PER_STRIP) as u8,
|
||||
(script.colorlists[0][i] * 255.0) as u8,
|
||||
(script.colorlists[1][i] * 255.0) as u8,
|
||||
(script.colorlists[2][i] * 255.0) as u8,
|
||||
(script.colorlists[3][i] * 255.0) as u8).unwrap();
|
||||
}
|
||||
|
||||
udpproto.commit().unwrap();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
119
src/udpproto.rs
Normal file
119
src/udpproto.rs
Normal file
|
@ -0,0 +1,119 @@
|
|||
// vim: noet
|
||||
|
||||
use std::net::UdpSocket;
|
||||
use std::net::SocketAddrV4;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
const MAX_PACKET_LEN: usize = 1470;
|
||||
|
||||
struct Command
|
||||
{
|
||||
cmd: u8,
|
||||
strip: u8,
|
||||
led: u8,
|
||||
data: [u8; 4],
|
||||
}
|
||||
|
||||
pub struct UdpProto
|
||||
{
|
||||
socket: UdpSocket,
|
||||
packet: [u8; MAX_PACKET_LEN],
|
||||
packet_offset: usize,
|
||||
}
|
||||
|
||||
impl UdpProto
|
||||
{
|
||||
pub fn new(target_address: &str) -> std::io::Result<UdpProto>
|
||||
{
|
||||
let u = UdpProto {
|
||||
socket: UdpSocket::bind(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0))?,
|
||||
packet: [0u8; MAX_PACKET_LEN],
|
||||
packet_offset: 0,
|
||||
};
|
||||
|
||||
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.packet_offset = 0;
|
||||
|
||||
self.socket.send(&self.packet[0..self.packet_offset])?;
|
||||
|
||||
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] = data[i];
|
||||
}
|
||||
|
||||
self.packet_offset += 7;
|
||||
|
||||
if self.packet_offset >= MAX_PACKET_LEN {
|
||||
self.send_packet()?;
|
||||
}
|
||||
|
||||
Ok( () )
|
||||
}
|
||||
|
||||
pub fn set_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(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( () )
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
|
@ -33,6 +33,8 @@ use std::cell::RefCell;
|
|||
pub struct UserScript
|
||||
{
|
||||
lua_state: Lua,
|
||||
|
||||
pub colorlists: [ [f32; config::NUM_LEDS_TOTAL]; 4],
|
||||
}
|
||||
|
||||
impl UserScript
|
||||
|
@ -41,6 +43,7 @@ impl UserScript
|
|||
{
|
||||
let s = UserScript {
|
||||
lua_state: Lua::new(),
|
||||
colorlists: [ [0f32; config::NUM_LEDS_TOTAL]; 4],
|
||||
};
|
||||
|
||||
// provide some configuration constants to Lua via a table
|
||||
|
@ -74,7 +77,7 @@ impl UserScript
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn periodic(&self) -> std::result::Result<(), mlua::Error>
|
||||
pub fn periodic(&mut self) -> std::result::Result<(), mlua::Error>
|
||||
{
|
||||
// find the init functions
|
||||
let lua_periodic_func: mlua::Function = self.lua_state.globals().get("periodic")?;
|
||||
|
@ -89,8 +92,7 @@ impl UserScript
|
|||
}
|
||||
|
||||
// convert the Lua Tables to normal vectors
|
||||
let mut colorlists = Vec::<Vec<f32>>::new();
|
||||
|
||||
let mut i = 0;
|
||||
for rval in rvals {
|
||||
let table = mlua::Table::from_lua(rval, &self.lua_state)?;
|
||||
|
||||
|
@ -103,10 +105,12 @@ impl UserScript
|
|||
return Err(Error::RuntimeError("Number of color values returned from 'periodic' must match number of LEDs given in 'init'.".to_string()));
|
||||
}
|
||||
|
||||
colorlists.push(v);
|
||||
}
|
||||
for j in 0 .. self.colorlists[i].len() {
|
||||
self.colorlists[i][j] = v[j];
|
||||
}
|
||||
|
||||
println!("{:?}", colorlists[0][0]);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue