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_PER_STRIP: usize = 16;
|
||||||
|
|
||||||
pub const NUM_LEDS_TOTAL: usize = NUM_STRIPS * NUM_LEDS_PER_STRIP;
|
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 signal_processing;
|
||||||
mod config;
|
mod config;
|
||||||
mod userscript;
|
mod userscript;
|
||||||
|
mod udpproto;
|
||||||
|
|
||||||
use crate::signal_processing::SignalProcessing;
|
use crate::signal_processing::SignalProcessing;
|
||||||
use crate::userscript::UserScript;
|
use crate::userscript::UserScript;
|
||||||
|
use crate::udpproto::UdpProto;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -19,6 +21,15 @@ fn main()
|
||||||
{
|
{
|
||||||
let mut stdin = std::io::stdin();
|
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
|
// set up signal processing
|
||||||
|
|
||||||
println!("Initializing signal processing...");
|
println!("Initializing signal processing...");
|
||||||
|
@ -30,7 +41,7 @@ fn main()
|
||||||
|
|
||||||
println!("Loading user script...");
|
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,
|
Ok(script) => script,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("=== Lua Error ===\n{}\n====> Terminating.", 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
|
pub struct UserScript
|
||||||
{
|
{
|
||||||
lua_state: Lua,
|
lua_state: Lua,
|
||||||
|
|
||||||
|
pub colorlists: [ [f32; config::NUM_LEDS_TOTAL]; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserScript
|
impl UserScript
|
||||||
|
@ -41,6 +43,7 @@ impl UserScript
|
||||||
{
|
{
|
||||||
let s = UserScript {
|
let s = UserScript {
|
||||||
lua_state: Lua::new(),
|
lua_state: Lua::new(),
|
||||||
|
colorlists: [ [0f32; config::NUM_LEDS_TOTAL]; 4],
|
||||||
};
|
};
|
||||||
|
|
||||||
// provide some configuration constants to Lua via a table
|
// provide some configuration constants to Lua via a table
|
||||||
|
@ -74,7 +77,7 @@ impl UserScript
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn periodic(&self) -> std::result::Result<(), mlua::Error>
|
pub fn periodic(&mut self) -> std::result::Result<(), mlua::Error>
|
||||||
{
|
{
|
||||||
// find the init functions
|
// find the init functions
|
||||||
let lua_periodic_func: mlua::Function = self.lua_state.globals().get("periodic")?;
|
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
|
// convert the Lua Tables to normal vectors
|
||||||
let mut colorlists = Vec::<Vec<f32>>::new();
|
let mut i = 0;
|
||||||
|
|
||||||
for rval in rvals {
|
for rval in rvals {
|
||||||
let table = mlua::Table::from_lua(rval, &self.lua_state)?;
|
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()));
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue