mirror of
https://github.com/esp-rs/esp-idf-hal.git
synced 2025-09-29 21:31:17 +00:00

* commit test 1 test commit 2 next device asd * try example, haven't built yet * Add feature flags for legacy RMT examples Remove references to the ds18b20 specific device. Add a feature flag `rmt-legacy` that, when enabled, will build the original rmt modules from v4 of the esp-idf. When disabled, the v5 rmt interface can be used for one wire applications. Implement the Iterator trait for a device search and use the Iterator in the example. * Add more feature guards to examples compile * Add alternative main functions for examples * Use std threading * Add std to thread sleep * use std duration * correct use for legacy rmt component * Remove local bindings and use the esp-idf-sys master * fix a typo * Remove esp-idf component inclusion * Update gitignore * Fix examples * mut-ex out the example compilation * add implementation for temperature readings * Conditional compile * esp4.4 compile * Changes to cargo and config * Remove OWDevice and simplify API * Remove phantomdata that is not required * adjust lifetimes for single search at a time * Keep RMT peripheral and add channel to onewire Moves the RMT driver into a private `driver` module, which will only be compiled in rmt-legacy mode. Also reduce the number of cfg feature flags in examples by wrapping the implementation in a module. * modularise examples * Fix for CI * update example name to make it pop --------- Co-authored-by: Dane Slattery <dane@polarmonitoring.com> Co-authored-by: DaneSlattery <dane_s@umantec.net>
188 lines
6.0 KiB
Rust
188 lines
6.0 KiB
Rust
//! RMT Transmit Example -- Morse Code
|
|
//!
|
|
//! To try this out, connect a piezo buzzer via a resistor into pin 17. It should repeat "HELLO"
|
|
//! in morse code.
|
|
//!
|
|
//! Set pin 16 to low to stop the signal and make the buzzer sound "GOODBYE" in morse code.
|
|
//!
|
|
//! Example loosely based off which has a circuit you can follow.
|
|
//! https://github.com/espressif/esp-idf/tree/master/examples/peripherals/rmt/morse_code
|
|
//!
|
|
//! This example demonstrates:
|
|
//! * A carrier signal.
|
|
//! * Looping.
|
|
//! * Background sending.
|
|
//! * Taking a [`Pin`] and [`Channel`] by ref mut, so that they can be used again later.
|
|
//!
|
|
|
|
#[cfg(any(feature = "rmt-legacy", esp_idf_version_major = "4"))]
|
|
fn main() -> anyhow::Result<()> {
|
|
example::main()
|
|
}
|
|
|
|
#[cfg(not(any(feature = "rmt-legacy", esp_idf_version_major = "4")))]
|
|
fn main() -> anyhow::Result<()> {
|
|
println!("This example requires feature `rmt-legacy` enabled or using ESP-IDF v4.4.X");
|
|
|
|
loop {
|
|
std::thread::sleep(std::time::Duration::from_millis(1000));
|
|
}
|
|
}
|
|
|
|
#[cfg(any(feature = "rmt-legacy", esp_idf_version_major = "4"))]
|
|
mod example {
|
|
use esp_idf_hal::units::FromValueType;
|
|
use esp_idf_hal::{
|
|
delay::Ets,
|
|
gpio::{OutputPin, PinDriver},
|
|
peripheral::Peripheral,
|
|
prelude::Peripherals,
|
|
rmt::{
|
|
config::{CarrierConfig, DutyPercent, Loop, TransmitConfig},
|
|
PinState, Pulse, PulseTicks, RmtChannel, TxRmtDriver, VariableLengthSignal,
|
|
},
|
|
};
|
|
|
|
pub fn main() -> anyhow::Result<()> {
|
|
esp_idf_hal::sys::link_patches();
|
|
|
|
let peripherals = Peripherals::take()?;
|
|
let mut channel = peripherals.rmt.channel0;
|
|
let mut led = peripherals.pins.gpio17;
|
|
let stop = peripherals.pins.gpio16;
|
|
|
|
let carrier = CarrierConfig::new()
|
|
.duty_percent(DutyPercent::new(50)?)
|
|
.frequency(611.Hz());
|
|
let mut config = TransmitConfig::new()
|
|
.carrier(Some(carrier))
|
|
.looping(Loop::Endless)
|
|
.clock_divider(255);
|
|
|
|
let tx = send_morse_code(&mut channel, &mut led, &config, "HELLO ")?;
|
|
|
|
let stop = PinDriver::input(stop)?;
|
|
|
|
println!("Keep sending until pin {} is set low.", stop.pin());
|
|
|
|
while stop.is_high() {
|
|
Ets::delay_ms(100);
|
|
}
|
|
|
|
println!("Pin {} set to low. Stopped.", stop.pin());
|
|
|
|
// Release pin and channel so we can use them again.
|
|
drop(tx);
|
|
|
|
// Wait so the messages don't get garbled.
|
|
Ets::delay_ms(3000);
|
|
|
|
// Now send a single message and stop.
|
|
println!("Saying GOODBYE!");
|
|
config.looping = Loop::None;
|
|
send_morse_code(channel, led, &config, "GOODBYE")?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn send_morse_code<'d>(
|
|
channel: impl Peripheral<P = impl RmtChannel> + 'd,
|
|
led: impl Peripheral<P = impl OutputPin> + 'd,
|
|
config: &TransmitConfig,
|
|
message: &str,
|
|
) -> anyhow::Result<TxRmtDriver<'d>> {
|
|
println!("Sending morse message '{message}'.");
|
|
|
|
let mut signal = VariableLengthSignal::new();
|
|
let pulses = str_pulses(message);
|
|
// We've been collecting `Pulse` but `VariableLengthSignal` needs `&Pulse`:
|
|
let pulses: Vec<&Pulse> = pulses.iter().collect();
|
|
signal.push(pulses)?;
|
|
|
|
let mut tx = TxRmtDriver::new(channel, led, config)?;
|
|
tx.start(signal)?;
|
|
|
|
// Return `tx` so we can release the pin and channel later.
|
|
Ok(tx)
|
|
}
|
|
|
|
enum Code {
|
|
Dot,
|
|
Dash,
|
|
WordGap,
|
|
}
|
|
|
|
impl Code {
|
|
pub fn push_pulse(&self, pulses: &mut Vec<Pulse>) {
|
|
match &self {
|
|
Code::Dot => pulses.extend_from_slice(&[high(), low()]),
|
|
Code::Dash => pulses.extend_from_slice(&[high(), high(), high(), low()]),
|
|
Code::WordGap => {
|
|
pulses.extend_from_slice(&[low(), low(), low(), low(), low(), low()])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn high() -> Pulse {
|
|
Pulse::new(PinState::High, PulseTicks::max())
|
|
}
|
|
|
|
fn low() -> Pulse {
|
|
Pulse::new(PinState::Low, PulseTicks::max())
|
|
}
|
|
|
|
fn find_codes(c: &char) -> &'static [Code] {
|
|
for (found, codes) in CODES.iter() {
|
|
if found == c {
|
|
return codes;
|
|
}
|
|
}
|
|
&[]
|
|
}
|
|
|
|
fn str_pulses(s: &str) -> Vec<Pulse> {
|
|
let mut pulses = vec![];
|
|
for c in s.chars() {
|
|
for code in find_codes(&c) {
|
|
code.push_pulse(&mut pulses);
|
|
}
|
|
|
|
// Create a gap after each symbol.
|
|
pulses.push(low());
|
|
pulses.push(low());
|
|
}
|
|
pulses
|
|
}
|
|
|
|
const CODES: &[(char, &[Code])] = &[
|
|
(' ', &[Code::WordGap]),
|
|
('A', &[Code::Dot, Code::Dash]),
|
|
('B', &[Code::Dash, Code::Dot, Code::Dot, Code::Dot]),
|
|
('C', &[Code::Dash, Code::Dot, Code::Dash, Code::Dot]),
|
|
('D', &[Code::Dash, Code::Dot, Code::Dot]),
|
|
('E', &[Code::Dot]),
|
|
('F', &[Code::Dot, Code::Dot, Code::Dash, Code::Dot]),
|
|
('G', &[Code::Dash, Code::Dash, Code::Dot]),
|
|
('H', &[Code::Dot, Code::Dot, Code::Dot, Code::Dot]),
|
|
('I', &[Code::Dot, Code::Dot]),
|
|
('J', &[Code::Dot, Code::Dash, Code::Dash, Code::Dash]),
|
|
('K', &[Code::Dash, Code::Dot, Code::Dash]),
|
|
('L', &[Code::Dot, Code::Dash, Code::Dot, Code::Dot]),
|
|
('M', &[Code::Dash, Code::Dash]),
|
|
('N', &[Code::Dash, Code::Dot]),
|
|
('O', &[Code::Dash, Code::Dash, Code::Dash]),
|
|
('P', &[Code::Dot, Code::Dash, Code::Dash, Code::Dot]),
|
|
('Q', &[Code::Dash, Code::Dash, Code::Dot, Code::Dash]),
|
|
('R', &[Code::Dot, Code::Dash, Code::Dot]),
|
|
('S', &[Code::Dot, Code::Dot, Code::Dot]),
|
|
('T', &[Code::Dash]),
|
|
('U', &[Code::Dot, Code::Dot, Code::Dash]),
|
|
('V', &[Code::Dot, Code::Dot, Code::Dot, Code::Dash]),
|
|
('W', &[Code::Dot, Code::Dash, Code::Dash]),
|
|
('X', &[Code::Dash, Code::Dot, Code::Dot, Code::Dash]),
|
|
('Y', &[Code::Dash, Code::Dot, Code::Dash, Code::Dash]),
|
|
('Z', &[Code::Dash, Code::Dash, Code::Dot, Code::Dot]),
|
|
];
|
|
}
|