mirror of
https://github.com/FliegendeWurst/raspi-oled.git
synced 2024-11-22 18:34:58 +00:00
Compare commits
No commits in common. "a5cf0bf0b1842fd1704d058ef51f4e2b5d5d31d3" and "5cac88580dd2a4d2c4aada8f7f3103e3dcff3415" have entirely different histories.
a5cf0bf0b1
...
5cac88580d
@ -22,4 +22,4 @@ https://www.waveshare.com/wiki/1.5inch_RGB_OLED_Module
|
|||||||
|
|
||||||
![events](./images/events.png)
|
![events](./images/events.png)
|
||||||
|
|
||||||
(the blue text seen in the second image is bright enough on the real OLED display)
|
(the second blue text is brighter on the OLED)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![feature(round_char_boundary)]
|
#![feature(round_char_boundary)]
|
||||||
|
|
||||||
use std::{fmt::Debug, fs, ops::Sub, time::Duration};
|
use std::{fs, ops::Sub, time::Duration, fmt::Debug};
|
||||||
|
|
||||||
use display_interface_spi::SPIInterfaceNoCS;
|
use display_interface_spi::SPIInterfaceNoCS;
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
@ -9,10 +9,10 @@ use embedded_graphics::{
|
|||||||
ascii::{FONT_10X20, FONT_4X6, FONT_5X8, FONT_6X9, FONT_9X15},
|
ascii::{FONT_10X20, FONT_4X6, FONT_5X8, FONT_6X9, FONT_9X15},
|
||||||
MonoTextStyleBuilder,
|
MonoTextStyleBuilder,
|
||||||
},
|
},
|
||||||
pixelcolor::Rgb565,
|
pixelcolor::{Rgb565},
|
||||||
prelude::{Point, Primitive},
|
prelude::{Point, Primitive},
|
||||||
primitives::{PrimitiveStyleBuilder, Rectangle},
|
primitives::{PrimitiveStyleBuilder, Rectangle},
|
||||||
text::{renderer::CharacterStyle, Text},
|
text::{Text, renderer::CharacterStyle},
|
||||||
Drawable,
|
Drawable,
|
||||||
};
|
};
|
||||||
use raspi_oled::FrameOutput;
|
use raspi_oled::FrameOutput;
|
||||||
@ -23,7 +23,7 @@ use rppal::{
|
|||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
//use ssd1306::{I2CDisplayInterface, Ssd1306, size::DisplaySize128x64, rotation::DisplayRotation, mode::DisplayConfig};
|
//use ssd1306::{I2CDisplayInterface, Ssd1306, size::DisplaySize128x64, rotation::DisplayRotation, mode::DisplayConfig};
|
||||||
use time::{format_description, Date, OffsetDateTime, PrimitiveDateTime};
|
use time::{format_description, OffsetDateTime, PrimitiveDateTime, Date};
|
||||||
use time_tz::{timezones::db::europe::BERLIN, OffsetDateTimeExt, PrimitiveDateTimeExt};
|
use time_tz::{timezones::db::europe::BERLIN, OffsetDateTimeExt, PrimitiveDateTimeExt};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -37,7 +37,7 @@ struct Events {
|
|||||||
struct Event {
|
struct Event {
|
||||||
name: String,
|
name: String,
|
||||||
start_time: String,
|
start_time: String,
|
||||||
end_time: Option<String>,
|
end_time: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -54,7 +54,7 @@ enum Status {
|
|||||||
Unknown,
|
Unknown,
|
||||||
Down,
|
Down,
|
||||||
Bad,
|
Bad,
|
||||||
Good,
|
Good
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Status {
|
impl Status {
|
||||||
@ -124,20 +124,8 @@ fn main() {
|
|||||||
let all: Vec<bool> = x.split(' ').map(|x| x.parse().unwrap()).collect();
|
let all: Vec<bool> = x.split(' ').map(|x| x.parse().unwrap()).collect();
|
||||||
[
|
[
|
||||||
if all[0] { Status::Good } else { Status::Bad },
|
if all[0] { Status::Good } else { Status::Bad },
|
||||||
if all[1] && all[2] {
|
if all[1] && all[2] { Status::Good } else if all[1] { Status::Down } else { Status::Bad },
|
||||||
Status::Good
|
if all[3] && all[4] { Status::Good } else if all[3] { Status::Down } else { Status::Bad }
|
||||||
} else if all[1] {
|
|
||||||
Status::Down
|
|
||||||
} else {
|
|
||||||
Status::Bad
|
|
||||||
},
|
|
||||||
if all[3] && all[4] {
|
|
||||||
Status::Good
|
|
||||||
} else if all[3] {
|
|
||||||
Status::Down
|
|
||||||
} else {
|
|
||||||
Status::Bad
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
[Status::Unknown, Status::Unknown, Status::Unknown]
|
[Status::Unknown, Status::Unknown, Status::Unknown]
|
||||||
@ -150,28 +138,12 @@ fn main() {
|
|||||||
let disp = ssd1351::display::display::Ssd1351::new(spii);
|
let disp = ssd1351::display::display::Ssd1351::new(spii);
|
||||||
//let mut disp = FrameOutput::new(128, 128);
|
//let mut disp = FrameOutput::new(128, 128);
|
||||||
|
|
||||||
let mut disp = draw(
|
let mut disp = draw(disp, time, rh, temp, events, &args, global_min, global_max, vals, status);
|
||||||
disp, time, rh, temp, events, &args, global_min, global_max, vals, status,
|
|
||||||
);
|
|
||||||
let _ = disp.flush();
|
let _ = disp.flush();
|
||||||
//disp.buffer.save("/tmp/x.png");
|
//disp.buffer.save("/tmp/x.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<D: DrawTarget<Color = Rgb565>>(
|
fn draw<D: DrawTarget<Color = Rgb565>>(mut disp: D, time: OffsetDateTime, rh: i64, temp: i64, events: Events, args: &[String], global_min: i32, global_max: i32, mut vals: Vec<(i32, i32)>, status: [Status; 3]) -> D where <D as DrawTarget>::Error: Debug {
|
||||||
mut disp: D,
|
|
||||||
time: OffsetDateTime,
|
|
||||||
rh: i64,
|
|
||||||
temp: i64,
|
|
||||||
events: Events,
|
|
||||||
args: &[String],
|
|
||||||
global_min: i32,
|
|
||||||
global_max: i32,
|
|
||||||
mut vals: Vec<(i32, i32)>,
|
|
||||||
status: [Status; 3],
|
|
||||||
) -> D
|
|
||||||
where
|
|
||||||
<D as DrawTarget>::Error: Debug,
|
|
||||||
{
|
|
||||||
let hour = time.hour();
|
let hour = time.hour();
|
||||||
let minute = time.minute();
|
let minute = time.minute();
|
||||||
|
|
||||||
@ -303,14 +275,7 @@ where
|
|||||||
while event_time.weekday().number_days_from_monday() as i32 != event.day {
|
while event_time.weekday().number_days_from_monday() as i32 != event.day {
|
||||||
event_time += Duration::from_secs(24 * 60 * 60);
|
event_time += Duration::from_secs(24 * 60 * 60);
|
||||||
}
|
}
|
||||||
all_events.push((
|
all_events.push((event.day, event.hour, event.minute, event.duration, event.name, event_time.to_julian_day()));
|
||||||
event.day,
|
|
||||||
event.hour,
|
|
||||||
event.minute,
|
|
||||||
event.duration,
|
|
||||||
event.name,
|
|
||||||
event_time.to_julian_day(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
let format = format_description::parse("[year]-[month]-[day]T[hour]:[minute]:[second]").unwrap();
|
let format = format_description::parse("[year]-[month]-[day]T[hour]:[minute]:[second]").unwrap();
|
||||||
for event in events.events {
|
for event in events.events {
|
||||||
@ -377,11 +342,7 @@ where
|
|||||||
if now2 > event_start && now < event_end {
|
if now2 > event_start && now < event_end {
|
||||||
bits.push((i, hour, minute / 6, colors.get(event_idx).copied()));
|
bits.push((i, hour, minute / 6, colors.get(event_idx).copied()));
|
||||||
}
|
}
|
||||||
if time_until_first.is_none()
|
if time_until_first.is_none() && (i > 0 || event.1 > time.hour() as i32 || (event.1 == time.hour() as i32 && event.2 >= time.minute() as i32)) {
|
||||||
&& (i > 0
|
|
||||||
|| event.1 > time.hour() as i32
|
|
||||||
|| (event.1 == time.hour() as i32 && event.2 >= time.minute() as i32))
|
|
||||||
{
|
|
||||||
time_until_first = Some(
|
time_until_first = Some(
|
||||||
((i * 24 + event.1) * 60 + event.2) * 60
|
((i * 24 + event.1) * 60 + event.2) * 60
|
||||||
- (time.hour() as i32 * 60 + time.minute() as i32) * 60,
|
- (time.hour() as i32 * 60 + time.minute() as i32) * 60,
|
||||||
@ -395,29 +356,18 @@ where
|
|||||||
// calculate position
|
// calculate position
|
||||||
let x = x + 4 + d * 12 + m;
|
let x = x + 4 + d * 12 + m;
|
||||||
let y = y + 8 + h;
|
let y = y + 8 + h;
|
||||||
disp.fill_solid(
|
disp.fill_solid(&Rectangle::new((x, y).into(), (1, 1).into()), color.unwrap_or(Rgb565::new(0xff, 0xff, 0x10)))
|
||||||
&Rectangle::new((x, y).into(), (1, 1).into()),
|
|
||||||
color.unwrap_or(Rgb565::new(0xff, 0xff, 0x10)),
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
//Rectangle::new((x, y).into(), (1, 1).into()).into_styled(rect_style).draw(&mut disp).unwrap();
|
//Rectangle::new((x, y).into(), (1, 1).into()).into_styled(rect_style).draw(&mut disp).unwrap();
|
||||||
}
|
}
|
||||||
if args[3] == "events" {
|
if args[3] == "events" {
|
||||||
for (i, event) in all_events.iter().take(7).enumerate() {
|
for (i, event) in all_events.iter().take(7).enumerate() {
|
||||||
let text = if event.4.len() > 19 {
|
let text = if event.4.len() > 19 { &event.4[0..event.4.floor_char_boundary(19)] } else { &event.4 };
|
||||||
&event.4[0..event.4.floor_char_boundary(19)]
|
|
||||||
} else {
|
|
||||||
&event.4
|
|
||||||
};
|
|
||||||
let day = event.0 as usize;
|
let day = event.0 as usize;
|
||||||
let y = y + 64 + 9 * i as i32 + 5;
|
let y = y + 64 + 9 * i as i32 + 5;
|
||||||
if event.5 > today && event.5 - today > 7 {
|
if event.5 > today && event.5 - today > 7 {
|
||||||
let dt = Date::from_julian_day(event.5).unwrap();
|
let dt = Date::from_julian_day(event.5).unwrap();
|
||||||
Text::new(
|
Text::new(&format!("{}.{}.", dt.day(), dt.month() as u8), (0, y).into(), text_style_4x6)
|
||||||
&format!("{}.{}.", dt.day(), dt.month() as u8),
|
|
||||||
(0, y).into(),
|
|
||||||
text_style_4x6,
|
|
||||||
)
|
|
||||||
.draw(&mut disp)
|
.draw(&mut disp)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,20 +3,8 @@ use std::process::Command;
|
|||||||
fn main() {
|
fn main() {
|
||||||
// adjust as needed
|
// adjust as needed
|
||||||
|
|
||||||
let github_up = Command::new("ping")
|
let github_up = Command::new("ping").args(["-c1", "github.com"]).spawn().unwrap().wait().unwrap().success();
|
||||||
.args(["-c1", "github.com"])
|
let gitlab_up = Command::new("ping").args(["-c1", "gitlab.com"]).spawn().unwrap().wait().unwrap().success();
|
||||||
.spawn()
|
|
||||||
.unwrap()
|
|
||||||
.wait()
|
|
||||||
.unwrap()
|
|
||||||
.success();
|
|
||||||
let gitlab_up = Command::new("ping")
|
|
||||||
.args(["-c1", "gitlab.com"])
|
|
||||||
.spawn()
|
|
||||||
.unwrap()
|
|
||||||
.wait()
|
|
||||||
.unwrap()
|
|
||||||
.success();
|
|
||||||
|
|
||||||
let status = format!("{} {} {} {} {}", true, github_up, true, gitlab_up, true);
|
let status = format!("{} {} {} {} {}", true, github_up, true, gitlab_up, true);
|
||||||
std::fs::write("/run/user/1000/status.json", status).unwrap();
|
std::fs::write("/run/user/1000/status.json", status).unwrap();
|
||||||
|
20
src/lib.rs
20
src/lib.rs
@ -3,11 +3,7 @@ use std::{
|
|||||||
time::{self, Duration},
|
time::{self, Duration},
|
||||||
};
|
};
|
||||||
|
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{pixelcolor::Rgb565, draw_target::DrawTarget, prelude::{OriginDimensions, Size, RgbColor}};
|
||||||
draw_target::DrawTarget,
|
|
||||||
pixelcolor::Rgb565,
|
|
||||||
prelude::{OriginDimensions, RgbColor, Size},
|
|
||||||
};
|
|
||||||
use gpio_cdev::{EventType, Line, LineRequestFlags};
|
use gpio_cdev::{EventType, Line, LineRequestFlags};
|
||||||
use image::{ImageBuffer, Rgb};
|
use image::{ImageBuffer, Rgb};
|
||||||
|
|
||||||
@ -18,7 +14,7 @@ pub struct FrameOutput {
|
|||||||
impl FrameOutput {
|
impl FrameOutput {
|
||||||
pub fn new(width: u32, height: u32) -> Self {
|
pub fn new(width: u32, height: u32) -> Self {
|
||||||
FrameOutput {
|
FrameOutput {
|
||||||
buffer: ImageBuffer::new(width, height),
|
buffer: ImageBuffer::new(width, height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -33,17 +29,10 @@ impl DrawTarget for FrameOutput {
|
|||||||
I: IntoIterator<Item = embedded_graphics::Pixel<Self::Color>>,
|
I: IntoIterator<Item = embedded_graphics::Pixel<Self::Color>>,
|
||||||
{
|
{
|
||||||
for pos in pixels {
|
for pos in pixels {
|
||||||
if pos.0.x < 0
|
if pos.0.x < 0 || pos.0.y < 0 || pos.0.x as u32 >= self.buffer.width() || pos.0.y as u32 >= self.buffer.height() {
|
||||||
|| pos.0.y < 0 || pos.0.x as u32 >= self.buffer.width()
|
|
||||||
|| pos.0.y as u32 >= self.buffer.height()
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
self.buffer.put_pixel(
|
self.buffer.put_pixel(pos.0.x as u32, pos.0.y as u32, Rgb([pos.1.r() << 3, pos.1.g() << 2, pos.1.b() << 3]));
|
||||||
pos.0.x as u32,
|
|
||||||
pos.0.y as u32,
|
|
||||||
Rgb([pos.1.r() << 3, pos.1.g() << 2, pos.1.b() << 3]),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -55,6 +44,7 @@ impl OriginDimensions for FrameOutput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn read_events(line: &gpio_cdev::Line, timeout: std::time::Duration) -> Result<Vec<(u64, EventType)>, SensorError> {
|
fn read_events(line: &gpio_cdev::Line, timeout: std::time::Duration) -> Result<Vec<(u64, EventType)>, SensorError> {
|
||||||
let input = line.request(LineRequestFlags::INPUT, 0, "read-data")?;
|
let input = line.request(LineRequestFlags::INPUT, 0, "read-data")?;
|
||||||
|
|
||||||
|
212
src/main.rs
212
src/main.rs
@ -96,10 +96,7 @@ fn main() {
|
|||||||
println!("app valid = {:?}", ccs.app_valid());
|
println!("app valid = {:?}", ccs.app_valid());
|
||||||
println!("baseline = {:x}", ccs.get_baseline());
|
println!("baseline = {:x}", ccs.get_baseline());
|
||||||
println!("reading {:?}", ccs.get_reading());
|
println!("reading {:?}", ccs.get_reading());
|
||||||
println!(
|
println!("setting drive mode to 1: {:?}", ccs.set_drive_mode(CCS811DriveMode::EverySecond));
|
||||||
"setting drive mode to 1: {:?}",
|
|
||||||
ccs.set_drive_mode(CCS811DriveMode::EverySecond)
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let args = std::env::args().collect::<Vec<_>>();
|
let args = std::env::args().collect::<Vec<_>>();
|
||||||
@ -165,3 +162,210 @@ fn main() {
|
|||||||
disp.buffer.save("/tmp/frame.png").unwrap();
|
disp.buffer.save("/tmp/frame.png").unwrap();
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
use dht_hal::{Dht22, Reading};
|
||||||
|
use embedded_graphics::image::{Image, ImageRaw};
|
||||||
|
use embedded_graphics::mono_font::iso_8859_7::FONT_9X18;
|
||||||
|
use embedded_graphics::pixelcolor::BinaryColor;
|
||||||
|
use embedded_graphics::prelude::*;
|
||||||
|
use embedded_graphics::primitives::{Circle, Line, PrimitiveStyle, Rectangle};
|
||||||
|
|
||||||
|
use embedded_graphics::{
|
||||||
|
mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
|
||||||
|
text::Text,
|
||||||
|
};
|
||||||
|
use embedded_hal::digital::v2::{InputPin, OutputPin};
|
||||||
|
use embedded_hal::prelude::_embedded_hal_blocking_i2c_Write;
|
||||||
|
use gpio_cdev::{Chip, EventRequestFlags, EventType, LineRequestFlags};
|
||||||
|
use linux_embedded_hal::i2cdev::core::I2CDevice;
|
||||||
|
use linux_embedded_hal::i2cdev::linux::LinuxI2CError;
|
||||||
|
use linux_embedded_hal::{Delay, I2cdev};
|
||||||
|
use machine_ip;
|
||||||
|
use rusqlite::{params, Connection};
|
||||||
|
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
||||||
|
use std::intrinsics::transmute;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::{Duration, SystemTime};
|
||||||
|
use std::{env, mem, time};
|
||||||
|
|
||||||
|
static IMG_DATA: &[u8; 512] = include_bytes!("../rust.raw");
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = env::args().collect::<Vec<_>>();
|
||||||
|
if args.len() < 2 {
|
||||||
|
panic!("missing argument: database path");
|
||||||
|
}
|
||||||
|
let database = Connection::open(&args[1]).expect("failed to open database");
|
||||||
|
database
|
||||||
|
.execute(
|
||||||
|
"
|
||||||
|
CREATE TABLE IF NOT EXISTS sensor_readings(
|
||||||
|
time INTEGER PRIMARY KEY,
|
||||||
|
humidity INTEGER NOT NULL,
|
||||||
|
celsius INTEGER NOT NULL
|
||||||
|
)",
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
/*
|
||||||
|
let mut ccs = CCS811::new(i2c, CCS811_ADDR);
|
||||||
|
println!("HW ID, should be 0x81 {:x}", ccs.hardware_id());
|
||||||
|
println!("Error code, should be None: {:?}", ccs.check_for_error());
|
||||||
|
println!("app valid = {:?}", ccs.app_valid());
|
||||||
|
println!("baseline = {:x}", ccs.get_baseline());
|
||||||
|
println!("reading {:?}", ccs.get_reading());
|
||||||
|
println!("setting drive mode to 1: {:?}", ccs.set_drive_mode(CCS811DriveMode::EverySecond));
|
||||||
|
*/
|
||||||
|
let mut chip = Chip::new("/dev/gpiochip0").unwrap();
|
||||||
|
let line = chip.get_line(26).unwrap();
|
||||||
|
for _attempt in 0..5 {
|
||||||
|
let time = std::time::SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap();
|
||||||
|
if let Ok((rh, temp)) = raspi_oled::am2302_reading(&line) {
|
||||||
|
if rh > 0 && temp < 500 {
|
||||||
|
database
|
||||||
|
.execute(
|
||||||
|
"INSERT INTO sensor_readings (time, humidity, celsius) VALUES (?1, ?2, ?3)",
|
||||||
|
params![time.as_secs(), rh, temp],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
display_on_ssd1306(rh, temp, time);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_on_ssd1306(rh: u16, temp: u16, time: Duration) {
|
||||||
|
let i2c = I2cdev::new("/dev/i2c-1").unwrap();
|
||||||
|
let interface = I2CDisplayInterface::new(i2c);
|
||||||
|
let mut disp = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0).into_buffered_graphics_mode();
|
||||||
|
|
||||||
|
disp.init().unwrap();
|
||||||
|
|
||||||
|
let text_style = MonoTextStyleBuilder::new()
|
||||||
|
.font(&FONT_9X18)
|
||||||
|
.text_color(BinaryColor::On)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let text = format!("{}.{}% {}.{}°C", rh / 10, rh % 10, temp / 10, temp % 10);
|
||||||
|
Text::new(&text, Point::new(0, 10), text_style).draw(&mut disp).unwrap();
|
||||||
|
let secs = time.as_secs();
|
||||||
|
let time = format!("{:02}:{:02} Uhr", (secs / 3600 + 2) % 24, secs / 60 % 60);
|
||||||
|
Text::new(&time, Point::new(0, 32), text_style).draw(&mut disp).unwrap();
|
||||||
|
disp.flush().unwrap();
|
||||||
|
/*
|
||||||
|
sleep(Duration::from_secs(2));
|
||||||
|
disp.clear();
|
||||||
|
|
||||||
|
let base_y = 0.0;
|
||||||
|
let max_dy = 32.0;
|
||||||
|
let mut tick = 0;
|
||||||
|
loop {
|
||||||
|
let y = if tick % 32 < 16 {
|
||||||
|
base_y + (tick % 16) as f32 / 16.0 * max_dy
|
||||||
|
} else {
|
||||||
|
base_y + max_dy - (tick % 16) as f32 / 16.0 * max_dy
|
||||||
|
} as i32;
|
||||||
|
tick += 1;
|
||||||
|
Line::new(Point::new(8, y + 16), Point::new(8 + 16, y + 16))
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
|
||||||
|
.draw(&mut disp).unwrap();
|
||||||
|
Line::new(Point::new(8, y + 16), Point::new(8 + 8, y))
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
|
||||||
|
.draw(&mut disp).unwrap();
|
||||||
|
|
||||||
|
Line::new(Point::new(8 + 16, y + 16), Point::new(8 + 8, y))
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
|
||||||
|
.draw(&mut disp).unwrap();
|
||||||
|
|
||||||
|
Rectangle::new(Point::new(48, y), Size::new(16, 16))
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
|
||||||
|
.draw(&mut disp).unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
Circle::new(Point::new(88, y), 16)
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
|
||||||
|
.draw(&mut disp).unwrap();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Text::new(&format!("Hello from frame {}", tick), Point::new(0, 56), text_style)
|
||||||
|
.draw(&mut disp)
|
||||||
|
.unwrap();
|
||||||
|
*/
|
||||||
|
disp.flush().unwrap();
|
||||||
|
|
||||||
|
sleep(Duration::from_millis(10));
|
||||||
|
|
||||||
|
disp.clear();
|
||||||
|
|
||||||
|
/*
|
||||||
|
let im: ImageRaw<BinaryColor> = ImageRaw::new(IMG_DATA, 64);
|
||||||
|
let img = Image::new(&im, Point::new(32, 0));
|
||||||
|
img.draw(&mut disp).unwrap();
|
||||||
|
disp.flush().unwrap();
|
||||||
|
|
||||||
|
sleep(Duration::from_secs(2));
|
||||||
|
disp.clear();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LineWrapper(gpio_cdev::Line);
|
||||||
|
|
||||||
|
impl InputPin for LineWrapper {
|
||||||
|
type Error = gpio_cdev::Error;
|
||||||
|
|
||||||
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
let handle = self.0.request(LineRequestFlags::INPUT, 0, "rust-line-wrapper")?;
|
||||||
|
Ok(handle.get_value()? == 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
let handle = self.0.request(LineRequestFlags::INPUT, 0, "rust-line-wrapper")?;
|
||||||
|
Ok(handle.get_value()? == 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputPin for LineWrapper {
|
||||||
|
<<<<<<< HEAD
|
||||||
|
type Error = gpio_cdev::Error;
|
||||||
|
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
||||||| parent of 683458d (Reformat code)
|
||||||
|
type Error = gpio_cdev::Error;
|
||||||
|
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
=======
|
||||||
|
type Error = gpio_cdev::Error;
|
||||||
|
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0
|
||||||
|
.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?
|
||||||
|
.set_value(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0
|
||||||
|
.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?
|
||||||
|
.set_value(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user