network
This commit is contained in:
1348
Cargo.lock
generated
1348
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
30
Cargo.toml
30
Cargo.toml
@@ -7,15 +7,23 @@ authors = [ "Marvin Drescher <m@sparv.in>" ]
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-executor = { version = "0.2.0", features = ["nightly", "integrated-timers", "arch-riscv32", "executor-thread"] }
|
embassy-executor = { version = "0.5.0", features = ["nightly", "integrated-timers", "arch-riscv32", "executor-thread"] }
|
||||||
embassy-time = { version = "0.1.0", features = ["nightly"] }
|
embassy-net = { version = "0.4.0", features = ["dhcpv4", "dhcpv4-hostname", "dns", "medium-ip", "proto-ipv4", "proto-ipv6", "tcp"] }
|
||||||
embedded-hal = "0.2.7"
|
embassy-sync = "0.5.0"
|
||||||
|
embassy-time = { version = "0.3.0" }
|
||||||
|
embedded-io-async = "0.6.1"
|
||||||
|
embedded-tls = { version = "0.17.0", default-features = false, features = ["embedded-io-adapters"] }
|
||||||
esp-alloc = "0.3.0"
|
esp-alloc = "0.3.0"
|
||||||
esp-backtrace = { version = "0.4.0", features = ["esp32c3", "exception-handler", "panic-handler"] }
|
esp-backtrace = { version = "0.11.0", features = ["esp32c3", "exception-handler", "panic-handler", "println"] }
|
||||||
esp-hal-common = { version = "0.11.0", features = ["esp32c3"] }
|
esp-hal = { version = "0.16.1", features = ["embassy", "embassy-time-timg0", "esp32c3"] }
|
||||||
esp-hal-smartled = { version = "0.4.0", features = ["esp32c3"] }
|
esp-hal-smartled = { version = "0.9.0", features = ["esp32c3"] }
|
||||||
esp-println = { version = "0.3.1", features = ["esp32c3"] }
|
esp-println = { version = "0.9.1", features = ["esp32c3", "uart"] }
|
||||||
esp32c3-hal = { version = "0.11.0", features = ["embassy", "embassy-time", "embassy-time-systick", "embedded-hal-async", "async", "direct-boot"] }
|
esp-wifi = { version = "0.4.0", features = ["embassy-net", "esp32c3", "wifi"] }
|
||||||
smart-leds = "0.3.0"
|
heapless = { version = "0.8.0", features = ["portable-atomic", "portable-atomic-unsafe-assume-single-core"] }
|
||||||
smart-leds-trait = "0.2.1"
|
mqttrust = "0.6.0"
|
||||||
static_cell = "1.0.0"
|
rust-mqtt = { version = "0.3.0", default-features = false }
|
||||||
|
smart-leds = "0.4.0"
|
||||||
|
static_cell = { version = "2.0.0", features = ["nightly"] }
|
||||||
|
|
||||||
|
[profile.dev.package.esp-wifi]
|
||||||
|
opt-level = 2
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
combine [
|
combine [
|
||||||
minimal.rustc
|
minimal.rustc
|
||||||
minimal.cargo
|
minimal.cargo
|
||||||
|
stable.rust-src
|
||||||
|
stable.rustfmt
|
||||||
targets.riscv32imc-unknown-none-elf.latest.rust-std # ESP32-C3 RISC-V
|
targets.riscv32imc-unknown-none-elf.latest.rust-std # ESP32-C3 RISC-V
|
||||||
targets.riscv32imac-unknown-none-elf.latest.rust-std # ESP32-C3 RISC-V \w atomic emulation
|
targets.riscv32imac-unknown-none-elf.latest.rust-std # ESP32-C3 RISC-V \w atomic emulation
|
||||||
];
|
];
|
||||||
@@ -39,7 +41,6 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
doCheck = true;
|
doCheck = true;
|
||||||
RUSTFLAGS="-C link-arg=-Tlinkall.x -C force-frame-pointers";
|
|
||||||
# CARGO_UNSTABLE_BUILD_STD = "true";
|
# CARGO_UNSTABLE_BUILD_STD = "true";
|
||||||
"CARGO_TARGET_${pkgs.lib.toUpper CARGO_BUILD_TARGET}_LINKER" = "riscv32-none-elf-gcc";
|
"CARGO_TARGET_${pkgs.lib.toUpper CARGO_BUILD_TARGET}_LINKER" = "riscv32-none-elf-gcc";
|
||||||
"CARGO_TARGET_${pkgs.lib.toUpper CARGO_BUILD_TARGET}_RUNNER" = "espflash --monitor";
|
"CARGO_TARGET_${pkgs.lib.toUpper CARGO_BUILD_TARGET}_RUNNER" = "espflash --monitor";
|
||||||
|
306
src/main.rs
306
src/main.rs
@@ -7,32 +7,61 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
|
#![feature(generic_arg_infer)]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
use core::mem::{self, MaybeUninit};
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use embassy_executor::Executor;
|
use embassy_executor::Executor;
|
||||||
|
use embassy_net::{Config, DhcpConfig, Ipv4Address, Stack, StackResources};
|
||||||
|
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
||||||
|
use embassy_sync::blocking_mutex::NoopMutex;
|
||||||
|
use embassy_sync::mutex::Mutex;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp32c3_hal::{
|
|
||||||
clock::ClockControl, embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup, Rtc, IO,
|
|
||||||
};
|
|
||||||
use esp_alloc::EspHeap;
|
use esp_alloc::EspHeap;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal_common::Rmt;
|
use esp_hal::adc::{AdcPin, Attenuation, ADC};
|
||||||
use esp_hal_common::{dma::TxChannel, gdma::Channel0};
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal_smartled::smartLedAdapter;
|
use esp_hal::gpio::{
|
||||||
|
Analog, AnalogPin, AnyPin, GpioPin, OpenDrain, Output, OutputSignal, PushPull,
|
||||||
|
};
|
||||||
|
use esp_hal::peripherals::{Peripherals, ADC1, ADC2, TIMG0};
|
||||||
|
use esp_hal::systimer::SystemTimer;
|
||||||
|
use esp_hal::{adc::AdcConfig, clock::ClockControl};
|
||||||
|
use esp_hal::{embassy, prelude::*, rmt, Rmt, Rng, Rtc, IO};
|
||||||
|
use esp_hal_smartled::SmartLedsAdapter;
|
||||||
use esp_hal_smartled::*;
|
use esp_hal_smartled::*;
|
||||||
use smart_leds::SmartLedsWrite;
|
use esp_println::println;
|
||||||
use smart_leds_trait::{RGB, RGBW, RGB8, White, RGBA};
|
use esp_wifi::wifi::{get_random, ClientConfiguration, Configuration};
|
||||||
use static_cell::StaticCell;
|
use esp_wifi::wifi::{WifiController, WifiDevice, WifiEvent, WifiStaDevice, WifiState};
|
||||||
|
use esp_wifi::{initialize as initialize_wifi, EspWifiInitFor};
|
||||||
|
use smart_leds::{SmartLedsWrite, RGB8};
|
||||||
|
use static_cell::{make_static, StaticCell};
|
||||||
|
|
||||||
|
mod mqtt;
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOCATOR: EspHeap = EspHeap::empty();
|
static ALLOCATOR: EspHeap = EspHeap::empty();
|
||||||
|
|
||||||
|
const SSID: Option<&str> = option_env!("WIFI_SSID");
|
||||||
|
const PASSWORD: Option<&str> = option_env!("WIFI_PASSWORD");
|
||||||
|
|
||||||
|
pub type NetworkStack = &'static Stack<WifiDevice<'static, WifiStaDevice>>;
|
||||||
|
|
||||||
|
fn init_heap() {
|
||||||
|
const HEAP_SIZE: usize = 32 * 1024;
|
||||||
|
static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
trait MySmartLed {
|
trait MySmartLed {
|
||||||
fn set_color(&mut self, color: RGB8);
|
fn set_color(&mut self, color: RGB8);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TX: esp_hal_common::rmt::TxChannel<CH>, const CH: u8, const BUFFER_SIZE: usize> MySmartLed
|
impl<TX: rmt::TxChannel, const BUFFER_SIZE: usize> MySmartLed
|
||||||
for SmartLedsAdapter<TX, CH, BUFFER_SIZE>
|
for SmartLedsAdapter<TX, BUFFER_SIZE>
|
||||||
{
|
{
|
||||||
fn set_color(&mut self, color: RGB8) {
|
fn set_color(&mut self, color: RGB8) {
|
||||||
if let Err(err) = self.write([color].into_iter()) {
|
if let Err(err) = self.write([color].into_iter()) {
|
||||||
@@ -45,47 +74,115 @@ impl<TX: esp_hal_common::rmt::TxChannel<CH>, const CH: u8, const BUFFER_SIZE: us
|
|||||||
async fn blink(mut led: Box<dyn MySmartLed>) {
|
async fn blink(mut led: Box<dyn MySmartLed>) {
|
||||||
loop {
|
loop {
|
||||||
esp_println::println!("Bing!");
|
esp_println::println!("Bing!");
|
||||||
for r in 0u8..255 {
|
let scale = 4;
|
||||||
Timer::after(Duration::from_millis(500)).await;
|
for r in 0..(255 / scale) {
|
||||||
esp_println::println!("Bing! {r}");
|
Timer::after(Duration::from_millis(1)).await;
|
||||||
let color = RGB8::new(r, r, r);
|
for g in 0..(255 / scale) {
|
||||||
|
Timer::after(Duration::from_millis(1)).await;
|
||||||
|
for b in 0..(255 / scale) {
|
||||||
|
Timer::after(Duration::from_millis(1)).await;
|
||||||
|
let color = RGB8::new(
|
||||||
|
(r * scale % 255) as _,
|
||||||
|
(g * scale % 255) as _,
|
||||||
|
(b * scale % 255) as _,
|
||||||
|
);
|
||||||
led.set_color(color);
|
led.set_color(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn async_read<T, E>(
|
||||||
|
mut fun: impl FnMut() -> nb::Result<T, E>,
|
||||||
|
interval: Duration,
|
||||||
|
) -> Result<T, E> {
|
||||||
|
loop {
|
||||||
|
match (fun()) {
|
||||||
|
Err(nb::Error::WouldBlock) => Timer::after(interval).await,
|
||||||
|
Err(nb::Error::Other(e)) => return Err(e),
|
||||||
|
Ok(val) => return Ok(val),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32c3/api-reference/peripherals/adc.html
|
||||||
|
fn adc_voltage(d_out: u16, att: Attenuation) -> u16 {
|
||||||
|
let scale = match att {
|
||||||
|
Attenuation::Attenuation0dB => 800,
|
||||||
|
Attenuation::Attenuation6dB => 1350,
|
||||||
|
Attenuation::Attenuation2p5dB => 1100,
|
||||||
|
Attenuation::Attenuation11dB => 2600,
|
||||||
|
};
|
||||||
|
(d_out as u32 * scale / 4095) as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn moisture(
|
||||||
|
mut pin: AdcPin<GpioPin<Analog, 4>, ADC1>,
|
||||||
|
adc: &'static Mutex<NoopRawMutex, ADC<'static, ADC1>>,
|
||||||
|
mut supply: AnyPin<Output<PushPull>>,
|
||||||
|
) {
|
||||||
|
let warmup = Duration::from_millis(100);
|
||||||
|
let submerged_in_water = 1500;
|
||||||
|
let dry = 2600;
|
||||||
|
loop {
|
||||||
|
supply.set_high().unwrap();
|
||||||
|
Timer::after(warmup).await;
|
||||||
|
let pin_value: u16 = {
|
||||||
|
let mut adc1 = adc.lock().await;
|
||||||
|
async_read(|| adc1.read(&mut pin), Duration::from_millis(10)).await
|
||||||
|
}
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
supply.set_low();
|
||||||
|
// Vout = Dout * Vmax / Dmax
|
||||||
|
let milli_volt = adc_voltage(pin_value, Attenuation::Attenuation11dB) as u32;
|
||||||
|
let moisture = ((milli_volt.checked_sub(submerged_in_water).unwrap_or(0))
|
||||||
|
<< 8 / (dry - submerged_in_water))
|
||||||
|
>> 8;
|
||||||
|
esp_println::println!("moisture: {moisture}%, v_s: {milli_volt}");
|
||||||
|
Timer::after(Duration::from_secs(10) - warmup).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn battery_monitor(
|
||||||
|
mut vbat_in: AdcPin<GpioPin<Analog, 3>, ADC1>,
|
||||||
|
adc: &'static Mutex<NoopRawMutex, ADC<'static, ADC1>>,
|
||||||
|
) {
|
||||||
|
loop {
|
||||||
|
let v_out = adc_voltage(
|
||||||
|
{
|
||||||
|
let mut adc1 = adc.lock().await;
|
||||||
|
async_read(|| adc1.read(&mut vbat_in), Duration::from_millis(10)).await
|
||||||
|
}
|
||||||
|
.unwrap(),
|
||||||
|
Attenuation::Attenuation11dB,
|
||||||
|
);
|
||||||
|
// account for 50:50 voltage divider
|
||||||
|
let v_bat = v_out * 2;
|
||||||
|
println!("V_bat: {}", v_bat);
|
||||||
|
|
||||||
|
Timer::after(Duration::from_secs(15)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
|
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
esp_println::println!("Init!");
|
esp_println::println!("Init!");
|
||||||
const HEAP_SIZE: usize = 2 * 1024;
|
init_heap();
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
static _sheap: u8;
|
|
||||||
static _heap_size: u8;
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
let heap_bottom = &_sheap as *const u8 as usize;
|
|
||||||
let heap_size = &_heap_size as *const u8 as usize;
|
|
||||||
ALLOCATOR.init(heap_bottom as *mut u8, 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let mut system = peripherals.SYSTEM.split();
|
let mut system = peripherals.SYSTEM.split();
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze();
|
||||||
|
|
||||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
let mut rtc = Rtc::new(peripherals.LPWR);
|
||||||
let timer_group0 = TimerGroup::new(
|
let mut timer_group0 = esp_hal::timer::TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||||
peripherals.TIMG0,
|
let timer_group1 = esp_hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks);
|
||||||
&clocks,
|
{
|
||||||
&mut system.peripheral_clock_control,
|
let mut wdt0 = &mut timer_group0.wdt;
|
||||||
);
|
|
||||||
let mut wdt0 = timer_group0.wdt;
|
|
||||||
let timer_group1 = TimerGroup::new(
|
|
||||||
peripherals.TIMG1,
|
|
||||||
&clocks,
|
|
||||||
&mut system.peripheral_clock_control,
|
|
||||||
);
|
|
||||||
let mut wdt1 = timer_group1.wdt;
|
let mut wdt1 = timer_group1.wdt;
|
||||||
|
|
||||||
// Disable watchdog timers
|
// Disable watchdog timers
|
||||||
@@ -93,29 +190,138 @@ fn main() -> ! {
|
|||||||
rtc.rwdt.disable();
|
rtc.rwdt.disable();
|
||||||
wdt0.disable();
|
wdt0.disable();
|
||||||
wdt1.disable();
|
wdt1.disable();
|
||||||
|
}
|
||||||
|
let timer = SystemTimer::new(peripherals.SYSTIMER).alarm0;
|
||||||
|
|
||||||
embassy::init(
|
let mut rng = Rng::new(peripherals.RNG);
|
||||||
&clocks,
|
|
||||||
esp32c3_hal::systimer::SystemTimer::new(peripherals.SYSTIMER),
|
|
||||||
);
|
|
||||||
|
|
||||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
let mut seed = [0u8; 8]; // very random, very secure seed
|
||||||
let rmt = Rmt::new(
|
rng.read(&mut seed).expect("random seed");
|
||||||
peripherals.RMT,
|
|
||||||
80u32.MHz(),
|
let wifi_init = initialize_wifi(
|
||||||
&mut system.peripheral_clock_control,
|
EspWifiInitFor::Wifi,
|
||||||
|
timer,
|
||||||
|
rng,
|
||||||
|
system.radio_clock_control,
|
||||||
&clocks,
|
&clocks,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let wifi = peripherals.WIFI;
|
||||||
|
let (wifi_interface, controller) =
|
||||||
|
esp_wifi::wifi::new_with_mode(&wifi_init, wifi, WifiStaDevice).unwrap();
|
||||||
|
|
||||||
let mut led = <smartLedAdapter!(0, 1)>::new(rmt.channel0, io.pins.gpio7);
|
let mut hostname = heapless::String::<_>::new();
|
||||||
|
hostname.push_str("esp32c3");
|
||||||
|
let config = Config::dhcpv4({
|
||||||
|
let mut dhcp = DhcpConfig::default();
|
||||||
|
dhcp.hostname = Some(hostname);
|
||||||
|
dhcp
|
||||||
|
});
|
||||||
|
// Init network stack
|
||||||
|
let stack = &*make_static!(Stack::new(
|
||||||
|
wifi_interface,
|
||||||
|
config,
|
||||||
|
make_static!(StackResources::<3>::new()),
|
||||||
|
u64::from_le_bytes(seed)
|
||||||
|
));
|
||||||
|
|
||||||
|
embassy::init(&clocks, timer_group0);
|
||||||
|
|
||||||
|
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
let rmt = Rmt::new(peripherals.RMT, 80u32.MHz(), &clocks).unwrap();
|
||||||
|
|
||||||
|
let rmt_buffer = smartLedBuffer!(1);
|
||||||
|
let mut led = SmartLedsAdapter::new(rmt.channel0, io.pins.gpio7, rmt_buffer, &clocks);
|
||||||
|
|
||||||
led.set_color(RGB8::new(0, 255, 255));
|
led.set_color(RGB8::new(0, 255, 255));
|
||||||
|
|
||||||
let led: Box<dyn MySmartLed> = Box::new(led);
|
let led: Box<dyn MySmartLed> = Box::new(led);
|
||||||
|
|
||||||
|
let mut adc1_config = AdcConfig::new();
|
||||||
|
let pin = adc1_config.enable_pin(io.pins.gpio4.into_analog(), Attenuation::Attenuation11dB);
|
||||||
|
let mut vbat_in =
|
||||||
|
adc1_config.enable_pin(io.pins.gpio3.into_analog(), Attenuation::Attenuation11dB);
|
||||||
|
let moisture_sensor_suppy_pin = io.pins.gpio5.into_push_pull_output().degrade();
|
||||||
|
|
||||||
|
let adc1: &'static Mutex<NoopRawMutex, ADC<'static, ADC1>> =
|
||||||
|
make_static!(Mutex::new(ADC::<ADC1>::new(peripherals.ADC1, adc1_config)));
|
||||||
|
|
||||||
let executor = EXECUTOR.init(Executor::new());
|
let executor = EXECUTOR.init(Executor::new());
|
||||||
executor.run(move |spawner| {
|
executor.run(move |spawner| {
|
||||||
spawner.spawn(blink(led)).ok();
|
if let (Some(ssid), Some(psk)) = (SSID.as_ref(), PASSWORD.as_ref()) {
|
||||||
|
spawner
|
||||||
|
.spawn(wifi_connection(controller, ssid, psk))
|
||||||
|
.unwrap();
|
||||||
|
spawner.spawn(net_task(&stack)).unwrap();
|
||||||
|
spawner.spawn(ip_task(&stack)).unwrap();
|
||||||
|
}
|
||||||
|
spawner.spawn(blink(led)).unwrap();
|
||||||
|
spawner
|
||||||
|
.spawn(moisture(pin, adc1, moisture_sensor_suppy_pin.into()))
|
||||||
|
.unwrap();
|
||||||
|
spawner.spawn(battery_monitor(vbat_in, adc1)).unwrap();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn wifi_connection(
|
||||||
|
mut controller: WifiController<'static>,
|
||||||
|
ssid: &'static str,
|
||||||
|
psk: &'static str,
|
||||||
|
) {
|
||||||
|
println!("start connection task");
|
||||||
|
println!("Device capabilities: {:?}", controller.get_capabilities());
|
||||||
|
loop {
|
||||||
|
match esp_wifi::wifi::get_wifi_state() {
|
||||||
|
WifiState::StaConnected => {
|
||||||
|
// wait until we're no longer connected
|
||||||
|
controller.wait_for_event(WifiEvent::StaDisconnected).await;
|
||||||
|
Timer::after(Duration::from_millis(5000)).await
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
if !matches!(controller.is_started(), Ok(true)) {
|
||||||
|
let client_config = Configuration::Client(ClientConfiguration {
|
||||||
|
ssid: ssid.try_into().unwrap(),
|
||||||
|
password: psk.try_into().unwrap(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
controller.set_configuration(&client_config).unwrap();
|
||||||
|
println!("Starting wifi");
|
||||||
|
controller.start().await.unwrap();
|
||||||
|
println!("Wifi started!");
|
||||||
|
}
|
||||||
|
println!("About to connect...");
|
||||||
|
|
||||||
|
match controller.connect().await {
|
||||||
|
Ok(_) => println!("Wifi connected!"),
|
||||||
|
Err(e) => {
|
||||||
|
println!("Failed to connect to wifi: {e:?}");
|
||||||
|
Timer::after(Duration::from_millis(5000)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn ip_task(stack: NetworkStack) {
|
||||||
|
loop {
|
||||||
|
if stack.is_link_up() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Timer::after(Duration::from_millis(500)).await;
|
||||||
|
}
|
||||||
|
println!("Waiting to get IP address...");
|
||||||
|
loop {
|
||||||
|
if let Some(config) = stack.config_v4() {
|
||||||
|
println!("Got IP: {}", config.address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Timer::after(Duration::from_millis(500)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn net_task(stack: NetworkStack) {
|
||||||
|
stack.run().await
|
||||||
|
}
|
||||||
|
11
src/mqtt.rs
Normal file
11
src/mqtt.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use embassy_net::tcp::TcpSocket;
|
||||||
|
use embassy_time::Duration;
|
||||||
|
|
||||||
|
use crate::NetworkStack;
|
||||||
|
|
||||||
|
async fn send_message(stack: NetworkStack, message: &[u8]) {
|
||||||
|
let mut rx_buffer = [0; 4096];
|
||||||
|
let mut tx_buffer = [0; 4096];
|
||||||
|
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||||
|
socket.set_timeout(Some(Duration::from_secs(10)));
|
||||||
|
}
|
Reference in New Issue
Block a user