Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
325b118a20 |
13 changed files with 830 additions and 32 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -62,6 +62,7 @@ dependencies = [
|
||||||
"esp-hal",
|
"esp-hal",
|
||||||
"esp-hal-embassy",
|
"esp-hal-embassy",
|
||||||
"esp-println",
|
"esp-println",
|
||||||
|
"heapless",
|
||||||
"log",
|
"log",
|
||||||
"static_cell",
|
"static_cell",
|
||||||
]
|
]
|
||||||
|
|
|
@ -25,8 +25,10 @@ hal = { package = "esp-hal", version = "0.18.0", features = [
|
||||||
esp-hal-embassy = {version= "0.1.0", features = ["esp32", "time-timg0"]}
|
esp-hal-embassy = {version= "0.1.0", features = ["esp32", "time-timg0"]}
|
||||||
embassy-time = "0.3.1"
|
embassy-time = "0.3.1"
|
||||||
embassy-sync = "0.6.0"
|
embassy-sync = "0.6.0"
|
||||||
|
# esp-hal-common = "0.15.0"
|
||||||
esp-println = { version = "0.9.1", features = ["esp32", "log"] }
|
esp-println = { version = "0.9.1", features = ["esp32", "log"] }
|
||||||
log = { version = "0.4.21" }
|
log = { version = "0.4.21" }
|
||||||
|
heapless = "0.8.0"
|
||||||
esp-alloc = { version = "0.4.0" }
|
esp-alloc = { version = "0.4.0" }
|
||||||
static_cell = { version = "2.1.0", features = ["nightly"] }
|
static_cell = { version = "2.1.0", features = ["nightly"] }
|
||||||
embassy-executor = { version = "0.5.0", features = [
|
embassy-executor = { version = "0.5.0", features = [
|
||||||
|
|
10
README.md
10
README.md
|
@ -11,3 +11,13 @@ git push -u origin main
|
||||||
# Pushing an existing repository from the command line
|
# Pushing an existing repository from the command line
|
||||||
git remote add origin https://gitdab.com/andodeki/relay_button.git
|
git remote add origin https://gitdab.com/andodeki/relay_button.git
|
||||||
git push -u origin main
|
git push -u origin main
|
||||||
|
|
||||||
|
git add *
|
||||||
|
git commit -m "working button to trigger relay and blinking led code"
|
||||||
|
git push -u origin main
|
||||||
|
|
||||||
|
|
||||||
|
https://wokwi.com/projects/400243028096410625
|
||||||
|
|
||||||
|
easyeda2kicad --full --lcsc_id=C99666
|
||||||
|
easyeda2kicad --full --lcsc_id=C99666 --output ~/libs/my_lib
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
// #![feature(async_fn_in_trait)]
|
// #![feature(async_fn_in_trait)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
pub mod confg;
|
pub mod confg;
|
||||||
|
|
66
src/main.rs
66
src/main.rs
|
@ -2,19 +2,26 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
use button_relay::run::blinky::blink_green;
|
// use button_relay::run::blinky::blink_green;
|
||||||
use button_relay::run::button::button_task;
|
// use button_relay::run::button::button_task;
|
||||||
use button_relay::run::relay::relay_task;
|
// use button_relay::run::relay::relay_task;
|
||||||
use button_relay::run::shared::{Command, QUEUE_SIZE};
|
// use button_relay::run::shared::{Command, PerPins, QUEUE_SIZE};
|
||||||
|
|
||||||
|
use button_relay::run::validate::serial_number_validation_task;
|
||||||
|
use button_relay::singleton;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
// use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
||||||
use embassy_sync::pubsub::{PubSubChannel, Publisher, Subscriber};
|
// use embassy_sync::pubsub::{PubSubChannel, Publisher, Subscriber};
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
use hal::gpio::{Input, Io, Level, Output, Pull};
|
// use hal::gpio::{Input, Io, Level, Output, Pull};
|
||||||
|
// use hal::uart::TxRxPins;
|
||||||
use hal::{
|
use hal::{
|
||||||
clock::ClockControl, delay::Delay, peripherals::Peripherals, prelude::*, system::SystemControl,
|
clock::{ClockControl, Clocks},
|
||||||
|
delay::Delay,
|
||||||
|
peripherals::Peripherals,
|
||||||
|
prelude::*,
|
||||||
|
system::SystemControl,
|
||||||
};
|
};
|
||||||
use static_cell::make_static;
|
use static_cell::make_static;
|
||||||
|
|
||||||
|
@ -36,33 +43,19 @@ fn init_heap() {
|
||||||
#[main]
|
#[main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
|
// let peripherals = singleton!(Peripherals::take(), Peripherals);
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
|
|
||||||
let clocks = ClockControl::max(system.clock_control).freeze();
|
// let clocks = ClockControl::max(system.clock_control).freeze();
|
||||||
let _delay = Delay::new(&clocks);
|
let clocks = singleton!(ClockControl::max(system.clock_control).freeze(), Clocks<'_>);
|
||||||
|
|
||||||
|
let delay = Delay::new(&clocks);
|
||||||
init_heap();
|
init_heap();
|
||||||
|
|
||||||
esp_println::logger::init_logger_from_env();
|
esp_println::logger::init_logger_from_env();
|
||||||
log::info!("Logger is setup");
|
log::info!("Logger is setup");
|
||||||
println!("Hello world!");
|
println!("Hello world!");
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let button_pin = Input::new(io.pins.gpio12, Pull::Down);
|
|
||||||
let led_pin = Output::new(io.pins.gpio2, Level::Low);
|
|
||||||
let relay_pin = Output::new(io.pins.gpio16, Level::Low);
|
|
||||||
|
|
||||||
let channel: &'static mut PubSubChannel<
|
|
||||||
NoopRawMutex,
|
|
||||||
Command,
|
|
||||||
QUEUE_SIZE,
|
|
||||||
QUEUE_SIZE,
|
|
||||||
QUEUE_SIZE,
|
|
||||||
> = make_static!(PubSubChannel::new());
|
|
||||||
|
|
||||||
let publisher = channel.publisher().unwrap();
|
|
||||||
let led_subscriber = channel.subscriber().unwrap();
|
|
||||||
let relay_subscriber = channel.subscriber().unwrap();
|
|
||||||
|
|
||||||
hal::interrupt::enable(
|
hal::interrupt::enable(
|
||||||
hal::peripherals::Interrupt::GPIO,
|
hal::peripherals::Interrupt::GPIO,
|
||||||
hal::interrupt::Priority::Priority1,
|
hal::interrupt::Priority::Priority1,
|
||||||
|
@ -82,13 +75,24 @@ async fn main(spawner: Spawner) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("Starting embassy executor ...");
|
println!("Starting embassy executor ...");
|
||||||
|
// Validate serial number before proceeding with other tasks
|
||||||
spawner.spawn(button_task(button_pin, publisher)).unwrap();
|
|
||||||
spawner.spawn(blink_green(led_pin, led_subscriber)).unwrap();
|
|
||||||
spawner
|
spawner
|
||||||
.spawn(relay_task(relay_pin, relay_subscriber))
|
.spawn(serial_number_validation_task(
|
||||||
|
delay,
|
||||||
|
spawner,
|
||||||
|
peripherals.GPIO,
|
||||||
|
peripherals.IO_MUX,
|
||||||
|
peripherals.UART0,
|
||||||
|
peripherals.UART1,
|
||||||
|
clocks,
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// spawner.spawn(button_task(button_pin, publisher)).unwrap();
|
||||||
|
// spawner.spawn(blink_green(led_pin, led_subscriber)).unwrap();
|
||||||
|
// spawner.spawn(relay_task(relay_pin, relay_subscriber)).unwrap();
|
||||||
|
// spawner.spawn(thermal_printer_task(printer_subscriber)).unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
esp_println::println!("Bing!");
|
esp_println::println!("Bing!");
|
||||||
embassy_time::Timer::after(embassy_time::Duration::from_millis(5_000)).await;
|
embassy_time::Timer::after(embassy_time::Duration::from_millis(5_000)).await;
|
||||||
|
|
370
src/main.rs.txt
Normal file
370
src/main.rs.txt
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
//! Blinks an LED
|
||||||
|
//!
|
||||||
|
//! This assumes that a LED is connected to the pin assigned to `led`. (GPIO4)
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
extern crate embassy_executor;
|
||||||
|
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
||||||
|
use embassy_sync::pubsub::{PubSubChannel, Publisher, Subscriber, WaitResult};
|
||||||
|
use embassy_time::{Duration, Timer};
|
||||||
|
use esp_backtrace as _;
|
||||||
|
use esp_println::println;
|
||||||
|
use hal::gpio::{Gpio12, Gpio2, Gpio4, Input, Io, Level, Output, Pull};
|
||||||
|
use hal::{
|
||||||
|
clock::{ClockControl, Clocks},
|
||||||
|
delay::Delay,
|
||||||
|
peripherals::Peripherals,
|
||||||
|
peripherals::{GPIO, IO_MUX, UART0, UART1},
|
||||||
|
prelude::*,
|
||||||
|
system::SystemControl,
|
||||||
|
uart::{TxRxPins, Uart},
|
||||||
|
Async,
|
||||||
|
};
|
||||||
|
use heapless::String;
|
||||||
|
use static_cell::make_static;
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
use core::cell::RefCell;
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macro_rules! singleton {
|
||||||
|
($val:expr, $T:ty) => {{
|
||||||
|
static STATIC_CELL: ::static_cell::StaticCell<$T> = ::static_cell::StaticCell::new();
|
||||||
|
STATIC_CELL.init($val)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const QUEUE_SIZE: usize = 10;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Command {
|
||||||
|
pub is_on: bool,
|
||||||
|
pub led_state: bool,
|
||||||
|
pub relay_state: bool,
|
||||||
|
pub is_printer_command: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
const SAFE_MODE: bool = false;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Sens<T>(pub T);
|
||||||
|
|
||||||
|
impl<T: core::fmt::Display> core::fmt::Display for Sens<T> {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
let Self(inner) = self;
|
||||||
|
if SAFE_MODE {
|
||||||
|
"[REDACTED]".fmt(f)
|
||||||
|
} else {
|
||||||
|
inner.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[main]
|
||||||
|
async fn main(spawner: Spawner) {
|
||||||
|
let peripherals = Peripherals::take();
|
||||||
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
|
let clocks = singleton!(ClockControl::max(system.clock_control).freeze(), Clocks<'_>);
|
||||||
|
|
||||||
|
let delay = Delay::new(&clocks);
|
||||||
|
init_heap();
|
||||||
|
|
||||||
|
esp_println::logger::init_logger_from_env();
|
||||||
|
log::info!("Logger is setup");
|
||||||
|
println!("Hello world!");
|
||||||
|
|
||||||
|
hal::interrupt::enable(
|
||||||
|
hal::peripherals::Interrupt::GPIO,
|
||||||
|
hal::interrupt::Priority::Priority1,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("We are connected!");
|
||||||
|
println!("Start busy loop on main");
|
||||||
|
|
||||||
|
let timer_group0 = hal::timer::timg::TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||||
|
esp_hal_embassy::init(&clocks, timer_group0);
|
||||||
|
|
||||||
|
hal::interrupt::enable(
|
||||||
|
hal::peripherals::Interrupt::UART1,
|
||||||
|
hal::interrupt::Priority::Priority1,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("Starting embassy executor ...");
|
||||||
|
// Validate serial number before proceeding with other tasks
|
||||||
|
spawner
|
||||||
|
.spawn(validation_task(
|
||||||
|
delay,
|
||||||
|
spawner,
|
||||||
|
peripherals.GPIO,
|
||||||
|
peripherals.IO_MUX,
|
||||||
|
peripherals.UART0,
|
||||||
|
peripherals.UART1,
|
||||||
|
clocks,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
esp_println::println!("Bing!");
|
||||||
|
embassy_time::Timer::after(embassy_time::Duration::from_millis(5_000)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
pub async fn button_task(
|
||||||
|
button_pin: Input<'static, Gpio12>,
|
||||||
|
publisher: Publisher<'static, NoopRawMutex, Command, QUEUE_SIZE, QUEUE_SIZE, QUEUE_SIZE>,
|
||||||
|
) {
|
||||||
|
let mut previous_button_state = false;
|
||||||
|
let mut led_state = false;
|
||||||
|
let mut relay_state = false;
|
||||||
|
let mut press_count = 0;
|
||||||
|
let mut last_press_time = embassy_time::Instant::now();
|
||||||
|
loop {
|
||||||
|
let current_button_state = button_pin.is_high();
|
||||||
|
|
||||||
|
if current_button_state && !previous_button_state {
|
||||||
|
// Button was pressed
|
||||||
|
let now = embassy_time::Instant::now();
|
||||||
|
let elapsed = now.duration_since(last_press_time);
|
||||||
|
last_press_time = now;
|
||||||
|
|
||||||
|
if elapsed < Duration::from_millis(500) {
|
||||||
|
press_count += 1;
|
||||||
|
} else {
|
||||||
|
press_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if press_count == 1 {
|
||||||
|
led_state = !led_state;
|
||||||
|
relay_state = !relay_state;
|
||||||
|
let payload = Command {
|
||||||
|
is_on: true,
|
||||||
|
led_state,
|
||||||
|
relay_state,
|
||||||
|
is_printer_command: false,
|
||||||
|
};
|
||||||
|
publisher.publish(payload).await;
|
||||||
|
esp_println::println!(
|
||||||
|
"Single press: LED State: {}, Relay State: {}",
|
||||||
|
led_state,
|
||||||
|
relay_state
|
||||||
|
);
|
||||||
|
} else if press_count == 2 {
|
||||||
|
let payload = Command {
|
||||||
|
is_on: true,
|
||||||
|
led_state: false,
|
||||||
|
relay_state: false,
|
||||||
|
is_printer_command: true,
|
||||||
|
};
|
||||||
|
publisher.publish(payload).await;
|
||||||
|
esp_println::println!("Double press: Printing from thermal printer...");
|
||||||
|
|
||||||
|
// Insert thermal printer logic here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if current_button_state {
|
||||||
|
let now = embassy_time::Instant::now();
|
||||||
|
let elapsed = now.duration_since(last_press_time);
|
||||||
|
if elapsed >= Duration::from_secs(2) {
|
||||||
|
esp_println::println!("Long press: Rebooting device...");
|
||||||
|
// Insert reboot logic here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previous_button_state = current_button_state;
|
||||||
|
Timer::after(Duration::from_millis(50)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
pub async fn blink_green(
|
||||||
|
mut pin: Output<'static, Gpio2>,
|
||||||
|
mut subscriber: Subscriber<'static, NoopRawMutex, Command, QUEUE_SIZE, QUEUE_SIZE, QUEUE_SIZE>,
|
||||||
|
) {
|
||||||
|
let mut led_state = false;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match subscriber.try_next_message() {
|
||||||
|
Some(WaitResult::Message(command)) => {
|
||||||
|
led_state = command.led_state;
|
||||||
|
}
|
||||||
|
Some(WaitResult::Lagged(_)) | None => {
|
||||||
|
// No new message, continue with the current state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if led_state {
|
||||||
|
pin.toggle();
|
||||||
|
Timer::after(Duration::from_millis(200)).await;
|
||||||
|
} else {
|
||||||
|
pin.set_low();
|
||||||
|
Timer::after(Duration::from_millis(50)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type AbrPub = Publisher<'static, NoopRawMutex, Command, QUEUE_SIZE, QUEUE_SIZE, QUEUE_SIZE>;
|
||||||
|
type AbrSub = Subscriber<'static, NoopRawMutex, Command, QUEUE_SIZE, QUEUE_SIZE, QUEUE_SIZE>;
|
||||||
|
|
||||||
|
pub struct ButtonLedPins {
|
||||||
|
pub button_pin: Input<'static, Gpio12>,
|
||||||
|
pub led_pin: Output<'static, Gpio2>,
|
||||||
|
pub button_publisher: AbrPub,
|
||||||
|
pub led_subscriber: AbrSub,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ButtonLedPins {
|
||||||
|
fn new(
|
||||||
|
button_pin: Input<'static, Gpio12>,
|
||||||
|
led_pin: Output<'static, Gpio2>,
|
||||||
|
button_publisher: AbrPub,
|
||||||
|
led_subscriber: AbrSub,
|
||||||
|
) -> Self {
|
||||||
|
ButtonLedPins {
|
||||||
|
button_pin,
|
||||||
|
led_pin,
|
||||||
|
button_publisher,
|
||||||
|
led_subscriber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn uart_device_setup(
|
||||||
|
&self,
|
||||||
|
delay: Delay,
|
||||||
|
uart0_per: UART0,
|
||||||
|
uart1_per: UART1,
|
||||||
|
clocks: &Clocks<'static>,
|
||||||
|
) -> (Uart<'static, UART0, Async>, Uart<'static, UART1, Async>) {
|
||||||
|
let mut uart0 = Uart::new_async(uart0_per, &clocks);
|
||||||
|
let mut uart1 = Uart::new_async(uart1_per, &clocks);
|
||||||
|
|
||||||
|
(uart0, uart1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
|
use core::sync::atomic::AtomicBool;
|
||||||
|
pub static SERIAL_NUMBER_VALID: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
pub async fn validation_task(
|
||||||
|
delay: Delay,
|
||||||
|
spawner: Spawner,
|
||||||
|
peripherals_GPIO: GPIO,
|
||||||
|
peripherals_IO_MUX: IO_MUX,
|
||||||
|
uart0_per: UART0,
|
||||||
|
uart1_per: UART1,
|
||||||
|
clocks: &'static Clocks<'static>,
|
||||||
|
) {
|
||||||
|
let io = Io::new(peripherals_GPIO, peripherals_IO_MUX);
|
||||||
|
let button_pin = Input::new(io.pins.gpio12, Pull::Down);
|
||||||
|
let led_pin = Output::new(io.pins.gpio2, Level::Low);
|
||||||
|
|
||||||
|
let channel: &'static mut PubSubChannel<
|
||||||
|
NoopRawMutex,
|
||||||
|
Command,
|
||||||
|
QUEUE_SIZE,
|
||||||
|
QUEUE_SIZE,
|
||||||
|
QUEUE_SIZE,
|
||||||
|
> = make_static!(PubSubChannel::new());
|
||||||
|
|
||||||
|
let button_publisher = channel.publisher().unwrap();
|
||||||
|
let led_subscriber = channel.subscriber().unwrap();
|
||||||
|
|
||||||
|
// let btnsleds = Rc::new(RefCell::new(ButtonLedPins {
|
||||||
|
// button_pin,
|
||||||
|
// led_pin,
|
||||||
|
// button_publisher,
|
||||||
|
// led_subscriber,
|
||||||
|
// }));
|
||||||
|
let btnsleds = ButtonLedPins {
|
||||||
|
button_pin,
|
||||||
|
led_pin,
|
||||||
|
button_publisher,
|
||||||
|
led_subscriber,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (mut uart0, mut uart1) = btnsleds.uart_device_setup(delay, uart0_per, uart1_per, &clocks);
|
||||||
|
let mut buffer = [0u8; 16];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if uart0.read_async(&mut buffer).await.is_ok() {
|
||||||
|
match core::str::from_utf8(&buffer) {
|
||||||
|
Ok(serial_number) => {
|
||||||
|
esp_println::println!("Serial number received: {}", serial_number);
|
||||||
|
|
||||||
|
// Validate the serial number with the server
|
||||||
|
if validate_serial_number_with_server(&mut uart1, &buffer).await {
|
||||||
|
esp_println::println!("Serial number is valid!");
|
||||||
|
SERIAL_NUMBER_VALID.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
|
// Spawn other tasks after successful validation
|
||||||
|
spawner
|
||||||
|
.spawn(button_task(btnsleds.button_pin, btnsleds.button_publisher))
|
||||||
|
.unwrap();
|
||||||
|
spawner
|
||||||
|
.spawn(blink_green(btnsleds.led_pin, btnsleds.led_subscriber))
|
||||||
|
.unwrap();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
esp_println::println!("Serial number is invalid. Please try again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
esp_println::println!(
|
||||||
|
"Received invalid UTF-8 serial number. Please try again."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
embassy_time::Timer::after(embassy_time::Duration::from_secs(1)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn validate_serial_number_with_server(
|
||||||
|
uart: &mut Uart<'static, UART1, Async>,
|
||||||
|
serial_number: &[u8],
|
||||||
|
) -> bool {
|
||||||
|
// Initialize GPRS module
|
||||||
|
send_at_command(uart, b"AT\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Receive validation response from the server
|
||||||
|
let mut response = [0u8; 128];
|
||||||
|
if uart.read_async(&mut response).await.is_ok() {
|
||||||
|
esp_println::println!("Received response from server.");
|
||||||
|
return parse_server_response(&response);
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn parse_server_response(response: &[u8]) -> bool {
|
||||||
|
// Parse the HTTP response to check if the serial number is valid
|
||||||
|
// This is a simplified example, you should implement a proper HTTP response parser
|
||||||
|
if let Ok(response_str) = core::str::from_utf8(response) {
|
||||||
|
return response_str.contains("200 OK") && response_str.contains("valid");
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
async fn send_at_command(uart: &mut Uart<'static, UART1, Async>, command: &[u8]) {
|
||||||
|
uart.write_async(command).await.unwrap();
|
||||||
|
Timer::after(Duration::from_secs(1)).await;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
extern crate embassy_executor;
|
extern crate embassy_executor;
|
||||||
|
|
||||||
use crate::confg::Sens;
|
// use crate::confg::Sens;
|
||||||
use embassy_sync::{
|
use embassy_sync::{
|
||||||
blocking_mutex::raw::NoopRawMutex,
|
blocking_mutex::raw::NoopRawMutex,
|
||||||
pubsub::{Subscriber, WaitResult},
|
pubsub::{Subscriber, WaitResult},
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub async fn button_task(
|
||||||
is_on: true,
|
is_on: true,
|
||||||
led_state,
|
led_state,
|
||||||
relay_state,
|
relay_state,
|
||||||
|
is_printer_command: false,
|
||||||
};
|
};
|
||||||
publisher.publish(payload).await;
|
publisher.publish(payload).await;
|
||||||
esp_println::println!(
|
esp_println::println!(
|
||||||
|
@ -48,7 +49,15 @@ pub async fn button_task(
|
||||||
relay_state
|
relay_state
|
||||||
);
|
);
|
||||||
} else if press_count == 2 {
|
} else if press_count == 2 {
|
||||||
|
let payload = Command {
|
||||||
|
is_on: true,
|
||||||
|
led_state: false,
|
||||||
|
relay_state: false,
|
||||||
|
is_printer_command: true,
|
||||||
|
};
|
||||||
|
publisher.publish(payload).await;
|
||||||
esp_println::println!("Double press: Printing from thermal printer...");
|
esp_println::println!("Double press: Printing from thermal printer...");
|
||||||
|
|
||||||
// Insert thermal printer logic here
|
// Insert thermal printer logic here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
src/run/isdevicedisconnected.rs
Normal file
36
src/run/isdevicedisconnected.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//! Connect a potentiometer to PIN25 and see the read values change when
|
||||||
|
//! rotating the shaft. Alternatively you could also connect the PIN to GND or
|
||||||
|
//! 3V3 to see the maximum and minimum raw values read.
|
||||||
|
|
||||||
|
use esp_hal_common::{
|
||||||
|
adc::RegisterAccess,
|
||||||
|
gpio::{Analog, GpioPin},
|
||||||
|
peripheral::Peripheral,
|
||||||
|
};
|
||||||
|
use esp_println::println;
|
||||||
|
use hal::{
|
||||||
|
// adc::{AdcConfig, Attenuation, ADC},
|
||||||
|
analog::adc::{AdcConfig, Attenuation},
|
||||||
|
peripherals::ADC2,
|
||||||
|
prelude::*,
|
||||||
|
Delay,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
pub async fn checkdevice(
|
||||||
|
pin2: GpioPin<Analog, 2>,
|
||||||
|
// adc_instance: impl Peripheral<P = dyn RegisterAccess> + 'static,
|
||||||
|
mut delay: Delay,
|
||||||
|
) {
|
||||||
|
let mut adc2_config = AdcConfig::new();
|
||||||
|
let mut pin2 = adc2_config.enable_pin(pin2, Attenuation::Attenuation11dB);
|
||||||
|
let mut adc2 = ADC::<ADC2>::new(adc_instance.adc2, adc2_config).unwrap();
|
||||||
|
|
||||||
|
// let mut delay = Delay::new(&clocks);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let pin2_value: u16 = nb::block!(adc2.read(&mut pin2)).unwrap();
|
||||||
|
println!("PIN2 ADC reading = {}", pin2_value);
|
||||||
|
delay.delay_ms(1500u32);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
pub mod blinky;
|
pub mod blinky;
|
||||||
pub mod button;
|
pub mod button;
|
||||||
|
// pub mod isdevicedisconnected;
|
||||||
|
pub mod printing;
|
||||||
pub mod relay;
|
pub mod relay;
|
||||||
pub mod shared;
|
pub mod shared;
|
||||||
|
pub mod validate;
|
||||||
|
|
28
src/run/printing.rs
Normal file
28
src/run/printing.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
extern crate embassy_executor;
|
||||||
|
|
||||||
|
// use crate::confg::Sens;
|
||||||
|
use embassy_sync::{
|
||||||
|
blocking_mutex::raw::NoopRawMutex,
|
||||||
|
pubsub::{Subscriber, WaitResult},
|
||||||
|
};
|
||||||
|
use embassy_time::{Duration, Timer};
|
||||||
|
use hal::gpio::{Gpio13, Output};
|
||||||
|
|
||||||
|
use super::shared::{Command, QUEUE_SIZE};
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
pub async fn thermal_printer_task(
|
||||||
|
mut _pin: Output<'static, Gpio13>,
|
||||||
|
mut subscriber: Subscriber<'static, NoopRawMutex, Command, QUEUE_SIZE, QUEUE_SIZE, QUEUE_SIZE>,
|
||||||
|
) {
|
||||||
|
loop {
|
||||||
|
let command = subscriber.next_message_pure().await;
|
||||||
|
if command.is_printer_command {
|
||||||
|
// Mock printing logic
|
||||||
|
esp_println::println!("Thermal Printer: Printing...");
|
||||||
|
// Replace with actual printer command
|
||||||
|
Timer::after(Duration::from_secs(2)).await; // Simulate printing time
|
||||||
|
esp_println::println!("Thermal Printer: Print complete.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,11 +12,127 @@
|
||||||
// relay_state: AtomicBool::new(false),
|
// relay_state: AtomicBool::new(false),
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
use core::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
|
use embassy_sync::{
|
||||||
|
blocking_mutex::raw::NoopRawMutex,
|
||||||
|
pubsub::{Publisher, Subscriber},
|
||||||
|
};
|
||||||
|
use hal::{
|
||||||
|
clock::Clocks,
|
||||||
|
delay::Delay,
|
||||||
|
gpio::{Gpio12, Gpio13, Gpio16, Gpio2, GpioPin, Input, Output},
|
||||||
|
peripherals::{UART0, UART1},
|
||||||
|
uart::{
|
||||||
|
config::{AtCmdConfig, Config, DataBits, Parity, StopBits},
|
||||||
|
ClockSource, TxRxPins, Uart, UartRx, UartTx,
|
||||||
|
},
|
||||||
|
Async,
|
||||||
|
};
|
||||||
|
|
||||||
pub const QUEUE_SIZE: usize = 10;
|
pub const QUEUE_SIZE: usize = 10;
|
||||||
|
pub static mut SERIAL_NUMBER: [u8; 16] = [0; 16];
|
||||||
|
pub static SERIAL_NUMBER_VALID: AtomicBool = AtomicBool::new(false);
|
||||||
|
// rx_fifo_full_threshold
|
||||||
|
pub const READ_BUF_SIZE: usize = 64;
|
||||||
|
// EOT (CTRL-D)
|
||||||
|
pub const AT_CMD: u8 = 0x04;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! singleton {
|
||||||
|
($val:expr, $T:ty) => {{
|
||||||
|
static STATIC_CELL: ::static_cell::StaticCell<$T> = ::static_cell::StaticCell::new();
|
||||||
|
STATIC_CELL.init($val)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Command {
|
pub struct Command {
|
||||||
pub is_on: bool,
|
pub is_on: bool,
|
||||||
pub led_state: bool,
|
pub led_state: bool,
|
||||||
pub relay_state: bool,
|
pub relay_state: bool,
|
||||||
|
pub is_printer_command: bool,
|
||||||
|
}
|
||||||
|
type AbrPubType = Publisher<'static, NoopRawMutex, Command, QUEUE_SIZE, QUEUE_SIZE, QUEUE_SIZE>;
|
||||||
|
type AbrSubType = Subscriber<'static, NoopRawMutex, Command, QUEUE_SIZE, QUEUE_SIZE, QUEUE_SIZE>;
|
||||||
|
|
||||||
|
pub struct PerPins {
|
||||||
|
pub button_pin: Input<'static, Gpio12>,
|
||||||
|
pub led_pin: Output<'static, Gpio2>,
|
||||||
|
pub relay_pin: Output<'static, Gpio16>,
|
||||||
|
pub printer_pin: Output<'static, Gpio13>,
|
||||||
|
pub uart0_pins: TxRxPins<'static, GpioPin<1>, GpioPin<3>>,
|
||||||
|
pub modem_uart_pins: TxRxPins<'static, GpioPin<15>, GpioPin<14>>,
|
||||||
|
pub publisher: AbrPubType,
|
||||||
|
pub led_subscriber: AbrSubType,
|
||||||
|
pub relay_subscriber: AbrSubType,
|
||||||
|
pub printer_subscriber: AbrSubType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PerPins {
|
||||||
|
pub fn new(
|
||||||
|
button_pin: Input<'static, Gpio12>,
|
||||||
|
led_pin: Output<'static, Gpio2>,
|
||||||
|
relay_pin: Output<'static, Gpio16>,
|
||||||
|
uart0_pins: TxRxPins<'static, GpioPin<1>, GpioPin<3>>,
|
||||||
|
modem_uart_pins: TxRxPins<'static, GpioPin<15>, GpioPin<14>>,
|
||||||
|
printer_pin: Output<'static, Gpio13>,
|
||||||
|
publisher: AbrPubType,
|
||||||
|
led_subscriber: AbrSubType,
|
||||||
|
relay_subscriber: AbrSubType,
|
||||||
|
printer_subscriber: AbrSubType,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
button_pin,
|
||||||
|
led_pin,
|
||||||
|
relay_pin,
|
||||||
|
printer_pin,
|
||||||
|
uart0_pins,
|
||||||
|
modem_uart_pins,
|
||||||
|
publisher,
|
||||||
|
led_subscriber,
|
||||||
|
relay_subscriber,
|
||||||
|
printer_subscriber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn uart_device_setup(
|
||||||
|
&self,
|
||||||
|
delay: Delay,
|
||||||
|
uart0_per: UART0,
|
||||||
|
uart1_per: UART1,
|
||||||
|
clocks: &Clocks<'static>,
|
||||||
|
) -> (
|
||||||
|
UartTx<'static, UART0, Async>,
|
||||||
|
UartRx<'static, UART0, Async>,
|
||||||
|
UartTx<'static, UART1, Async>,
|
||||||
|
UartRx<'static, UART1, Async>,
|
||||||
|
)
|
||||||
|
// (Uart<'static, UART0, Async>, Uart<'static, UART1, Async>)
|
||||||
|
{
|
||||||
|
let mut uart0 = Uart::new_async(uart0_per, &clocks);
|
||||||
|
|
||||||
|
uart0.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None));
|
||||||
|
uart0
|
||||||
|
.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16)
|
||||||
|
.unwrap();
|
||||||
|
let (tx0, rx0) = uart0.split();
|
||||||
|
|
||||||
|
let config = Config {
|
||||||
|
baudrate: 115200,
|
||||||
|
data_bits: DataBits::DataBits8,
|
||||||
|
parity: Parity::ParityNone,
|
||||||
|
stop_bits: StopBits::STOP1,
|
||||||
|
clock_source: ClockSource::Apb,
|
||||||
|
};
|
||||||
|
// UART interface for the GSM modem
|
||||||
|
let mut uart1 =
|
||||||
|
Uart::new_with_config(uart1_per, config, Some(self.modem_uart_pins), &clocks, None);
|
||||||
|
uart1.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None));
|
||||||
|
// uart.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16).unwrap();
|
||||||
|
uart1.set_rx_fifo_full_threshold(1).unwrap();
|
||||||
|
let (tx1, rx1) = uart1.split();
|
||||||
|
|
||||||
|
// (uart0, uart1, tx0, rx0)
|
||||||
|
(tx0, rx0, tx1, rx1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
218
src/run/validate.rs
Normal file
218
src/run/validate.rs
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_sync::signal::Signal;
|
||||||
|
use embassy_sync::{blocking_mutex::raw::NoopRawMutex, pubsub::PubSubChannel};
|
||||||
|
use embassy_time::{Duration, Timer};
|
||||||
|
use hal::{
|
||||||
|
clock::Clocks,
|
||||||
|
delay::Delay,
|
||||||
|
gpio::{Input, Io, Level, Output, Pull},
|
||||||
|
peripherals::{GPIO, IO_MUX, UART0, UART1},
|
||||||
|
uart::{TxRxPins, Uart},
|
||||||
|
Async,
|
||||||
|
};
|
||||||
|
|
||||||
|
use heapless::String;
|
||||||
|
use static_cell::{make_static, StaticCell};
|
||||||
|
|
||||||
|
use crate::run::{
|
||||||
|
blinky::blink_green, button::button_task, printing::thermal_printer_task, relay::relay_task,
|
||||||
|
shared::SERIAL_NUMBER_VALID,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::shared::{Command, PerPins, QUEUE_SIZE};
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
pub async fn serial_number_validation_task(
|
||||||
|
delay: Delay,
|
||||||
|
spawner: Spawner,
|
||||||
|
peripherals_gpio: GPIO,
|
||||||
|
peripherals_io_mux: IO_MUX,
|
||||||
|
uart0_per: UART0,
|
||||||
|
uart1_per: UART1,
|
||||||
|
clocks: &'static Clocks<'static>,
|
||||||
|
) {
|
||||||
|
let io = Io::new(peripherals_gpio, peripherals_io_mux);
|
||||||
|
let button_pin = Input::new(io.pins.gpio12, Pull::Down);
|
||||||
|
let led_pin = Output::new(io.pins.gpio2, Level::Low);
|
||||||
|
let relay_pin = Output::new(io.pins.gpio16, Level::Low);
|
||||||
|
let printer_pin = Output::new(io.pins.gpio13, Level::Low);
|
||||||
|
|
||||||
|
let uart0_pins = TxRxPins::new_tx_rx(io.pins.gpio1, io.pins.gpio3);
|
||||||
|
let uart1_pins = TxRxPins::new_tx_rx(io.pins.gpio15, io.pins.gpio14);
|
||||||
|
|
||||||
|
let channel: &'static mut PubSubChannel<
|
||||||
|
NoopRawMutex,
|
||||||
|
Command,
|
||||||
|
QUEUE_SIZE,
|
||||||
|
QUEUE_SIZE,
|
||||||
|
QUEUE_SIZE,
|
||||||
|
> = make_static!(PubSubChannel::new());
|
||||||
|
|
||||||
|
let publisher = channel.publisher().unwrap();
|
||||||
|
let led_subscriber = channel.subscriber().unwrap();
|
||||||
|
let relay_subscriber = channel.subscriber().unwrap();
|
||||||
|
let printer_subscriber = channel.subscriber().unwrap();
|
||||||
|
|
||||||
|
static SIGNAL: StaticCell<Signal<NoopRawMutex, usize>> = StaticCell::new();
|
||||||
|
let uart_signal = &*SIGNAL.init(Signal::new());
|
||||||
|
|
||||||
|
let per_pins = PerPins {
|
||||||
|
button_pin,
|
||||||
|
led_pin,
|
||||||
|
relay_pin,
|
||||||
|
printer_pin,
|
||||||
|
uart0_pins,
|
||||||
|
modem_uart_pins: uart1_pins,
|
||||||
|
publisher,
|
||||||
|
led_subscriber,
|
||||||
|
relay_subscriber,
|
||||||
|
printer_subscriber,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (_tx0, _rx0, _tx1, _rx1) = per_pins.uart_device_setup(delay, uart0_per, uart1_per, &clocks);
|
||||||
|
let mut buffer = [0u8; 16];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if uart0.read_async(&mut buffer).await.is_ok() {
|
||||||
|
match core::str::from_utf8(&buffer) {
|
||||||
|
Ok(serial_number) => {
|
||||||
|
esp_println::println!("Serial number received: {}", serial_number);
|
||||||
|
|
||||||
|
// Validate the serial number with the server
|
||||||
|
if validate_serial_number_with_server(&mut uart1, &buffer).await {
|
||||||
|
esp_println::println!("Serial number is valid!");
|
||||||
|
SERIAL_NUMBER_VALID.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
|
// Spawn other tasks after successful validation
|
||||||
|
spawner
|
||||||
|
.spawn(button_task(per_pins.button_pin, per_pins.publisher))
|
||||||
|
.unwrap();
|
||||||
|
spawner
|
||||||
|
.spawn(blink_green(per_pins.led_pin, per_pins.led_subscriber))
|
||||||
|
.unwrap();
|
||||||
|
spawner
|
||||||
|
.spawn(relay_task(per_pins.relay_pin, per_pins.relay_subscriber))
|
||||||
|
.unwrap();
|
||||||
|
spawner
|
||||||
|
.spawn(thermal_printer_task(
|
||||||
|
per_pins.printer_pin,
|
||||||
|
per_pins.printer_subscriber,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
esp_println::println!("Serial number is invalid. Please try again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
esp_println::println!(
|
||||||
|
"Received invalid UTF-8 serial number. Please try again."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
embassy_time::Timer::after(embassy_time::Duration::from_secs(1)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn validate_serial_number_with_server(
|
||||||
|
uart: &mut Uart<'static, UART1, Async>,
|
||||||
|
serial_number: &[u8],
|
||||||
|
) -> bool {
|
||||||
|
// Initialize GPRS module
|
||||||
|
send_at_command(uart, b"AT\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Set GPRS connection
|
||||||
|
send_at_command(uart, b"AT+CGATT=1\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Setup PDP context
|
||||||
|
send_at_command(uart, b"AT+CGDCONT=1,\"IP\",\"internet\"\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Activate PDP context
|
||||||
|
send_at_command(uart, b"AT+CGACT=1,1\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Establish TCP connection to the server
|
||||||
|
send_at_command(uart, b"AT+CIPSTART=\"TCP\",\"server_address\",\"port\"\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Prepare HTTP GET request
|
||||||
|
let mut http_request = String::<128>::new();
|
||||||
|
write!(http_request, "GET /validate?serial_number={} HTTP/1.1\r\nHost: server_address\r\nConnection: close\r\n\r\n", core::str::from_utf8(serial_number).unwrap()).unwrap();
|
||||||
|
|
||||||
|
// Send HTTP GET request
|
||||||
|
send_at_command(uart, b"AT+CIPSEND\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
uart.write_async(http_request.as_bytes()).await.unwrap();
|
||||||
|
uart.write_async(b"\x1A").await.unwrap(); // Send Ctrl+Z to indicate the end of the data
|
||||||
|
|
||||||
|
// Receive validation response from the server
|
||||||
|
let mut response = [0u8; 128];
|
||||||
|
if uart.read_async(&mut response).await.is_ok() {
|
||||||
|
esp_println::println!("Received response from server.");
|
||||||
|
return parse_server_response(&response);
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn parse_server_response(response: &[u8]) -> bool {
|
||||||
|
// Parse the HTTP response to check if the serial number is valid
|
||||||
|
// This is a simplified example, you should implement a proper HTTP response parser
|
||||||
|
if let Ok(response_str) = core::str::from_utf8(response) {
|
||||||
|
return response_str.contains("200 OK") && response_str.contains("valid");
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
async fn send_at_command(uart: &mut Uart<'static, UART1, Async>, command: &[u8]) {
|
||||||
|
uart.write_async(command).await.unwrap();
|
||||||
|
Timer::after(Duration::from_secs(1)).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn validate_serial_number_with_tcpserver(
|
||||||
|
uart: &mut Uart<'static, UART1, Async>,
|
||||||
|
serial_number: &[u8],
|
||||||
|
) -> bool {
|
||||||
|
// Initialize GPRS module
|
||||||
|
send_at_command(uart, b"AT\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Set GPRS connection
|
||||||
|
send_at_command(uart, b"AT+CGATT=1\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Setup PDP context
|
||||||
|
send_at_command(uart, b"AT+CGDCONT=1,\"IP\",\"internet\"\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Activate PDP context
|
||||||
|
send_at_command(uart, b"AT+CGACT=1,1\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Establish TCP connection to the server
|
||||||
|
send_at_command(uart, b"AT+CIPSTART=\"TCP\",\"server_address\",\"port\"\r\n").await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
// Send serial number to the server
|
||||||
|
// let cmd = format!("AT+CIPSEND={}\r\n", serial_number.len());
|
||||||
|
// Prepare the CIPSEND command
|
||||||
|
let mut cmd = String::<32>::new();
|
||||||
|
write!(cmd, "AT+CIPSEND={}\r\n", serial_number.len()).unwrap();
|
||||||
|
send_at_command(uart, cmd.as_bytes()).await;
|
||||||
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|
||||||
|
uart.write_async(serial_number).await.unwrap();
|
||||||
|
uart.write_async(b"\x1A").await.unwrap(); // Send Ctrl+Z to indicate the end of the data
|
||||||
|
|
||||||
|
// Receive validation response from the server
|
||||||
|
let mut response = [0u8; 1];
|
||||||
|
if uart.read_async(&mut response).await.is_ok() {
|
||||||
|
esp_println::println!("Received response from server.");
|
||||||
|
return response[0] == 1; // Assume server sends 1 for valid and 0 for invalid
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
Loading…
Reference in a new issue