Start backend
This commit is contained in:
parent
44c2604855
commit
2dedc08636
1
backend/.gitignore
vendored
Normal file
1
backend/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
target
|
1203
backend/Cargo.lock
generated
Normal file
1203
backend/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
backend/Cargo.toml
Normal file
12
backend/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "backend"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.43"
|
||||||
|
palette = "0.6.0"
|
||||||
|
rodio = "0.14.0"
|
||||||
|
serialport = "4.0.1"
|
129
backend/src/main.rs
Normal file
129
backend/src/main.rs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
use std::{
|
||||||
|
io, thread,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use palette::{FromColor, Hsl, Pixel, Srgb};
|
||||||
|
use serialport::SerialPort;
|
||||||
|
|
||||||
|
const TEST_VALUE: [u8; 9] = [0, 0, 134, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
|
const FPS: u32 = 50;
|
||||||
|
|
||||||
|
enum MCUResponse {
|
||||||
|
Sync,
|
||||||
|
Ack,
|
||||||
|
Info { num_pkts: u32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_response(ser: &mut dyn SerialPort) -> Result<MCUResponse> {
|
||||||
|
let mut read_buffer = vec![0u8; 32];
|
||||||
|
let bytes_read;
|
||||||
|
loop {
|
||||||
|
match ser.read(read_buffer.as_mut_slice()) {
|
||||||
|
Ok(t) => {
|
||||||
|
bytes_read = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => continue,
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}?
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = std::str::from_utf8(&read_buffer[..bytes_read])?;
|
||||||
|
|
||||||
|
match response.trim() {
|
||||||
|
"Sync." => Ok(MCUResponse::Sync),
|
||||||
|
"Ack." => Ok(MCUResponse::Ack),
|
||||||
|
s if s.starts_with("Info") => Ok(MCUResponse::Info { num_pkts: 69 }),
|
||||||
|
s => Err(anyhow!("Unknown response: \"{}\"", s)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
let frame_time = Duration::from_secs_f64(1.0 / FPS as f64);
|
||||||
|
|
||||||
|
let mut dmx_buffer = [0u8; 512];
|
||||||
|
let start_addr = 10;
|
||||||
|
|
||||||
|
dmx_buffer[(start_addr - 1)..(start_addr - 1 + TEST_VALUE.len())].copy_from_slice(&TEST_VALUE);
|
||||||
|
|
||||||
|
let mut ser = serialport::new("/dev/ttyUSB0", 500_000)
|
||||||
|
.timeout(Duration::from_millis(10))
|
||||||
|
.open()?;
|
||||||
|
|
||||||
|
println!("open");
|
||||||
|
|
||||||
|
// wait for initial sync
|
||||||
|
loop {
|
||||||
|
match poll_response(&mut *ser) {
|
||||||
|
Ok(MCUResponse::Sync) => break,
|
||||||
|
_ => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("sync");
|
||||||
|
|
||||||
|
let mut t = 0;
|
||||||
|
|
||||||
|
'main: loop {
|
||||||
|
let loop_start = Instant::now();
|
||||||
|
|
||||||
|
// calculate color
|
||||||
|
let hsl_color = Hsl::new(360.0 * (t as f64 / FPS as f64), 1.0, 0.5);
|
||||||
|
let rgb_color = Srgb::from_color(hsl_color);
|
||||||
|
let rgb: [u8; 3] = rgb_color.into_format().into_raw();
|
||||||
|
|
||||||
|
let offset = start_addr + 2;
|
||||||
|
dmx_buffer[offset..offset + 3].copy_from_slice(&rgb);
|
||||||
|
|
||||||
|
// write DMX data
|
||||||
|
let write_result = ser.write(&dmx_buffer);
|
||||||
|
|
||||||
|
if write_result.is_err() {
|
||||||
|
loop {
|
||||||
|
match poll_response(&mut *ser) {
|
||||||
|
Ok(MCUResponse::Sync) => {
|
||||||
|
continue 'main;
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get response
|
||||||
|
loop {
|
||||||
|
match poll_response(&mut *ser) {
|
||||||
|
Ok(MCUResponse::Ack) => break,
|
||||||
|
Ok(MCUResponse::Info { num_pkts }) => {
|
||||||
|
println!("Info: {}", num_pkts);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Error! {:?}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Ok(MCUResponse::Sync) => {
|
||||||
|
continue 'main;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t = (t + 1) % FPS;
|
||||||
|
|
||||||
|
let loop_time = loop_start.elapsed();
|
||||||
|
|
||||||
|
if loop_time < frame_time {
|
||||||
|
thread::sleep(frame_time - loop_time);
|
||||||
|
} else {
|
||||||
|
println!("loop took too long!");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"loop time: {}ms busy, {}ms total",
|
||||||
|
loop_time.as_millis(),
|
||||||
|
loop_start.elapsed().as_millis()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user