init
This commit is contained in:
53
examples/brightness.rs
Normal file
53
examples/brightness.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use anyhow::Result;
|
||||
use std::time::Duration;
|
||||
|
||||
use m::vfd::VfdConfig;
|
||||
use m::worker::VfdWorker;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// args:
|
||||
// 1) port (default: /dev/cu.usbmodem101)
|
||||
// 2) width (default: 20)
|
||||
// 3) delay_ms (default: 800)
|
||||
let port_name = std::env::args()
|
||||
.nth(1)
|
||||
.unwrap_or("/dev/cu.usbmodem101".into());
|
||||
|
||||
let width: usize = std::env::args()
|
||||
.nth(2)
|
||||
.as_deref()
|
||||
.unwrap_or("20")
|
||||
.parse()
|
||||
.unwrap_or(20);
|
||||
|
||||
let delay_ms: u64 = std::env::args()
|
||||
.nth(3)
|
||||
.as_deref()
|
||||
.unwrap_or("800")
|
||||
.parse()
|
||||
.unwrap_or(800);
|
||||
|
||||
let cfg = VfdConfig::new(port_name).with_width(width);
|
||||
let worker = VfdWorker::start(cfg)?;
|
||||
let vfd = worker.handle();
|
||||
|
||||
vfd.clear();
|
||||
|
||||
// шапка один раз (не обязательно, но удобно)
|
||||
let _ = vfd.print_line_diff(1, "Яркость");
|
||||
|
||||
loop {
|
||||
for level in 1u8..=4u8 {
|
||||
vfd.set_brightness(level);
|
||||
|
||||
// обновляем строку медленно, через print_line_diff
|
||||
// можно сделать “индикатор” уровня (*****)
|
||||
let bar = "*".repeat(level as usize);
|
||||
let line2 = format!("Уровень: {} {}", level, bar);
|
||||
|
||||
let _ = vfd.print_line_diff(2, line2);
|
||||
|
||||
std::thread::sleep(Duration::from_millis(delay_ms));
|
||||
}
|
||||
}
|
||||
}
|
||||
150
examples/clock.rs
Normal file
150
examples/clock.rs
Normal file
@@ -0,0 +1,150 @@
|
||||
// examples/clock_ru.rs
|
||||
use anyhow::Result;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use m::vfd::VfdConfig;
|
||||
use m::worker::VfdWorker;
|
||||
|
||||
fn run_date(args: &[&str]) -> Option<String> {
|
||||
let out = std::process::Command::new("date")
|
||||
.args(args)
|
||||
.output()
|
||||
.ok()?;
|
||||
if !out.status.success() {
|
||||
return None;
|
||||
}
|
||||
Some(String::from_utf8_lossy(&out.stdout).trim().to_string())
|
||||
}
|
||||
|
||||
fn local_datetime_ddmmyyyy_hhmmss() -> String {
|
||||
// 28.01.2006 12:03:34
|
||||
run_date(&["+%d.%m.%Y %H:%M:%S"]).unwrap_or_else(|| "??.??.???? ??:??:??".to_string())
|
||||
}
|
||||
|
||||
fn local_weekday_num_1_7() -> u8 {
|
||||
// 1..7 (Mon..Sun)
|
||||
run_date(&["+%u"])
|
||||
.and_then(|s| s.parse::<u8>().ok())
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
||||
fn weekday_ru_full(n: u8) -> &'static str {
|
||||
match n {
|
||||
1 => "Понедельник",
|
||||
2 => "Вторник",
|
||||
3 => "Среда",
|
||||
4 => "Четверг",
|
||||
5 => "Пятница",
|
||||
6 => "Суббота",
|
||||
7 => "Воскресенье",
|
||||
_ => "Понедельник",
|
||||
}
|
||||
}
|
||||
|
||||
fn weekday_ru_short(n: u8) -> &'static str {
|
||||
match n {
|
||||
1 => "Пн",
|
||||
2 => "Вт",
|
||||
3 => "Ср",
|
||||
4 => "Чт",
|
||||
5 => "Пт",
|
||||
6 => "Сб",
|
||||
7 => "Вс",
|
||||
_ => "Пн",
|
||||
}
|
||||
}
|
||||
|
||||
fn time_of_day_ru(hour: u8) -> &'static str {
|
||||
match hour {
|
||||
5..=10 => "утро",
|
||||
11..=16 => "день",
|
||||
17..=22 => "вечер",
|
||||
_ => "ночь",
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_hour(datetime: &str) -> u8 {
|
||||
// ожидаем "DD.MM.YYYY HH:MM:SS"
|
||||
// берём HH как 2 символа после пробела
|
||||
datetime
|
||||
.split_whitespace()
|
||||
.nth(1)
|
||||
.and_then(|t| t.get(0..2))
|
||||
.and_then(|hh| hh.parse::<u8>().ok())
|
||||
.unwrap_or(12)
|
||||
}
|
||||
|
||||
fn fit_to_width(s: &str, width: usize) -> String {
|
||||
// простое “обрезать по символам”, чтобы кириллицу не порвать
|
||||
let mut out = String::new();
|
||||
for (i, ch) in s.chars().enumerate() {
|
||||
if i >= width {
|
||||
break;
|
||||
}
|
||||
out.push(ch);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// args:
|
||||
// 1) port (default: /dev/cu.usbmodem101)
|
||||
// 2) width (default: 20)
|
||||
// 3) brightness 1..4 (default: 2)
|
||||
let port_name = std::env::args()
|
||||
.nth(1)
|
||||
.unwrap_or("/dev/cu.usbmodem101".into());
|
||||
|
||||
let width: usize = std::env::args()
|
||||
.nth(2)
|
||||
.as_deref()
|
||||
.unwrap_or("20")
|
||||
.parse()
|
||||
.unwrap_or(20);
|
||||
|
||||
let brightness: u8 = std::env::args()
|
||||
.nth(3)
|
||||
.as_deref()
|
||||
.unwrap_or("2")
|
||||
.parse()
|
||||
.unwrap_or(2);
|
||||
|
||||
let cfg = VfdConfig::new(port_name).with_width(width);
|
||||
let worker = VfdWorker::start(cfg)?;
|
||||
let vfd = worker.handle();
|
||||
|
||||
vfd.clear();
|
||||
vfd.set_brightness(brightness);
|
||||
|
||||
loop {
|
||||
let dt = local_datetime_ddmmyyyy_hhmmss();
|
||||
let wd = local_weekday_num_1_7();
|
||||
let hour = extract_hour(&dt);
|
||||
let tod = time_of_day_ru(hour);
|
||||
|
||||
// 1 строка: "28.01.2006 12:03:34"
|
||||
let line1 = fit_to_width(&dt, width);
|
||||
|
||||
// 2 строка: "Понедельник сейчас день"
|
||||
// но если не влазит — "Пн сейчас день"
|
||||
let full = format!("{} сейчас {}", weekday_ru_full(wd), tod);
|
||||
let mut line2 = full;
|
||||
|
||||
if line2.chars().count() > width {
|
||||
line2 = format!("{} сейчас {}", weekday_ru_short(wd), tod);
|
||||
}
|
||||
|
||||
line2 = fit_to_width(&line2, width);
|
||||
|
||||
vfd.print_line_diff(1, line1)?;
|
||||
vfd.print_line_diff(2, line2)?;
|
||||
|
||||
// чтобы обновлялось ровно раз в секунду (плюс/минус), можно “привязать” к UNIX time
|
||||
let now = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_millis();
|
||||
let ms_to_next = 1000 - (now % 1000) as u64;
|
||||
std::thread::sleep(Duration::from_millis(ms_to_next));
|
||||
}
|
||||
}
|
||||
66
examples/marquee.rs
Normal file
66
examples/marquee.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use anyhow::Result;
|
||||
use std::time::Duration;
|
||||
|
||||
use m::vfd::VfdConfig;
|
||||
use m::worker::VfdWorker;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// args:
|
||||
// 1) port (default: /dev/cu.usbmodem101)
|
||||
// 2) width (default: 20)
|
||||
// 3) cps (chars per second, default: 8)
|
||||
// 4) end_pause_ms (default: 1500)
|
||||
// 5) brightness 1..4 (default: 2)
|
||||
let port_name = std::env::args()
|
||||
.nth(1)
|
||||
.unwrap_or("/dev/cu.usbmodem101".into());
|
||||
|
||||
let width: usize = std::env::args()
|
||||
.nth(2)
|
||||
.as_deref()
|
||||
.unwrap_or("20")
|
||||
.parse()
|
||||
.unwrap_or(20);
|
||||
|
||||
let cps: u32 = std::env::args()
|
||||
.nth(3)
|
||||
.as_deref()
|
||||
.unwrap_or("8")
|
||||
.parse()
|
||||
.unwrap_or(8);
|
||||
|
||||
let end_pause_ms: u64 = std::env::args()
|
||||
.nth(4)
|
||||
.as_deref()
|
||||
.unwrap_or("1500")
|
||||
.parse()
|
||||
.unwrap_or(1500);
|
||||
|
||||
let brightness: u8 = std::env::args()
|
||||
.nth(5)
|
||||
.as_deref()
|
||||
.unwrap_or("2")
|
||||
.parse()
|
||||
.unwrap_or(2);
|
||||
|
||||
let cfg = VfdConfig::new(port_name).with_width(width);
|
||||
let worker = VfdWorker::start(cfg)?;
|
||||
let vfd = worker.handle();
|
||||
|
||||
vfd.clear();
|
||||
vfd.set_brightness(brightness);
|
||||
|
||||
let text = String::from(
|
||||
"Однозначно, базовые сценарии поведения пользователей призывают нас к новым свершениям, которые, в свою очередь, должны быть объявлены нарушающими общечеловеческие нормы этики и морали. С другой стороны, понимание сути ресурсосберегающих технологий не даёт нам иного выбора, кроме определения экономической целесообразности принимаемых решений. Задача организации, в особенности же укрепление и развитие внутренней структуры обеспечивает актуальность соответствующих условий активизации. Предварительные выводы неутешительны: укрепление и развитие внутренней структуры однозначно фиксирует необходимость укрепления моральных ценностей. Высокий уровень вовлечения представителей целевой аудитории является четким доказательством простого факта: повышение уровня гражданского сознания представляет собой интересный эксперимент проверки поэтапного и последовательного развития общества.",
|
||||
);
|
||||
// “рыба” + бесконечный цикл
|
||||
vfd.set_marquee_text(text);
|
||||
vfd.start_marquee(2, cps, Duration::from_millis(end_pause_ms));
|
||||
|
||||
// можно подсветить вторую строку статикой
|
||||
let _ = vfd.print_line_diff(1, "Бегущая строка");
|
||||
|
||||
loop {
|
||||
std::thread::sleep(Duration::from_secs(3600));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user