From b30acab82339584331fdb9ebae424499ac2c28dd Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Wed, 8 Feb 2023 01:24:54 +0100 Subject: [PATCH] clear Rx buffer before TCP connect and ofc some other things too :) --- Cargo.toml | 2 +- src/gps.rs | 2 +- src/main.rs | 3 +-- src/modem.rs | 47 ++++++++++++++++++++++++++++++++++------------- src/serial.rs | 23 ++++++++++++++++++++++- 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5e56188..4ff3999 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ esp-idf-hal = "0.37.4" esp-idf-sys = { version = "0.31.5", features = ["binstart", "native"] } mqtt-protocol = "0.11.2" nb = "1.0.0" -ublox = { git = "https://github.com/lkolbly/ublox.git", branch = "master" } +ublox = "0.4.2" [build-dependencies] embuild = "0.29" diff --git a/src/gps.rs b/src/gps.rs index 025cad7..2b0b943 100644 --- a/src/gps.rs +++ b/src/gps.rs @@ -126,7 +126,7 @@ pub fn main( mode: UartMode::new(DataBits::Eight, Parity::None, StopBits::One), baud_rate: 9600, in_proto_mask: InProtoMask::all(), - out_proto_mask: OutProtoMask::UBLOX, + out_proto_mask: OutProtoMask::UBOX, flags: 0, reserved5: 0, } diff --git a/src/main.rs b/src/main.rs index 3138387..e4449fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,6 @@ mod accel; mod config; #[allow(dead_code)] mod command; -mod gps; mod modem; mod serial; mod types; @@ -43,7 +42,7 @@ fn main() -> anyhow::Result<()> { // let _ = gps::main(gps_tx, gps_rx, gps_uart, gps_sender)?; // threads.push(thread::spawn(move || gps::main(gps_rx, gps_tx, gps_uart, gps_sender))); - //thread::sleep(Duration::from_millis(1000)); + thread::sleep(Duration::from_millis(1000)); threads.push(thread::spawn(move || accel::main(accel_sender))); let _ = modem::main(modem_rx, modem_tx, modem_uart, modem_pwrkey, modem_rst, modem_power, receiver)?; diff --git a/src/modem.rs b/src/modem.rs index 9381baf..cc313c6 100644 --- a/src/modem.rs +++ b/src/modem.rs @@ -67,10 +67,10 @@ impl Modem { pub fn init(&mut self, mut pwrkey: impl OutputPin, mut rst: impl OutputPin, mut power: impl OutputPin) -> Result<()> { println!("Turning SIM800L on ..."); power.set_high().map_err(|_| ModemError::SetupError("Error setting POWER to high.".to_string()))?; - rst.set_high().map_err(|_| ModemError::SetupError("Error setting RST to high.".to_string()))?; + //rst.set_high().map_err(|_| ModemError::SetupError("Error setting RST to high.".to_string()))?; // Pull down PWRKEY for more than 1 second according to manual requirements pwrkey.set_high().map_err(|_| ModemError::SetupError("Error setting PWRKEY to high.".to_string()))?; - thread::sleep(Duration::from_millis(100)); + thread::sleep(Duration::from_millis(1500)); pwrkey.set_low().map_err(|_| ModemError::SetupError("Error setting PWRKEY to low.".to_string()))?; thread::sleep(Duration::from_millis(1000)); pwrkey.set_high().map_err(|_| ModemError::SetupError("Error setting PWRKEY to high.".to_string()))?; @@ -122,14 +122,24 @@ impl Modem { } fn send_command(&mut self, cmd: Command) -> Result { + if let Some(contains) = cmd.contains { + self.send(&cmd.text, &contains) + } else { + self.send(&cmd.text, "") + } + } + + fn send(&mut self, at_command: &str, contains: &str) -> Result { println!("-----------------------------------------------------------"); - println!("Sending {} ...", cmd.text); + println!("Sending {} ...", at_command); let _ = nb::block!(self.serial - .write_bytes(&[cmd.text.as_bytes(), &['\r' as u8]].concat())) - .map_err(|_| ModemError::SendDataError(format!("Error in send_command({})", cmd.text)))?; + .write_bytes(&[at_command.as_bytes(), &['\r' as u8]].concat())) + .map_err(|_| ModemError::SendDataError(format!("Error in send_command({})", at_command)))?; - self.command_read_response(cmd.contains) + let contains_opt = if contains == "" { None } else { Some(contains.to_string()) }; + + self.command_read_response(contains_opt) } fn handle_prompt(&mut self) -> Result<()> { @@ -247,7 +257,8 @@ impl Modem { } pub fn tcp_connect(&mut self, addr: &str, port: u16) -> Result<()> { - let _ = self.send_command(Command::tcp_connect(addr, port))?; + let at_command = format!("AT+CIPSTART=\"TCP\",\"{}\",\"{}\"", addr, port); + let _ = self.send(&at_command, "CONNECT OK"); for _ in 0..3 { if let Ok(reply) = self.command_read_response(Some("CONNECT OK".to_string())) { println!("TCP connect replied with {}", reply); @@ -515,6 +526,9 @@ pub fn main( //let _ = mdm.ssl_set_client_cert(client_cert_path, "t")?; //let _ = mdm.fs_list("C:\\USER\\")?; + // Retry 5 times to open a TCP connection, otherwise fail and wait for reboot. + let mut retries = 0; + loop { if !mdm.is_gprs_attached()? { let _ = mdm.gprs_attach_ap( @@ -526,13 +540,21 @@ pub fn main( if let Ok(()) = mdm.try_connect_gprs() { let device_id = "c36a72df-5bd6-4f9b-995d-059433bc3267"; - let _ = mdm.tcp_set_quick_mode(false); - let _ = mdm.tcp_set_manual_receive(true); + // When command AT+CIPQSEND=0, it is in normal sending mode. In this mode, after user + // sends data by AT+CIPSEND, if the server receives TCP data, it will give ACK message + // to module, and the module will respond SEND OK. + let _ = mdm.send("AT+CIPQSEND=0", "OK"); + // Enables getting data from network manually. + let _ = mdm.send("AT+CIPRXGET=1", "OK"); if let Err(_) = mdm.tcp_connect("51.158.66.64", 7887) { - continue; + if retries < 5 { + retries += 1; + continue; + } } - thread::sleep(Duration::from_secs(1)); + thread::sleep(Duration::from_millis(500)); + mdm.serial.clear(); let _ = mdm.mqtt_connect(device_id)?; @@ -551,7 +573,7 @@ pub fn main( err_count = 0; } Err(e) => { - if err_count < 10 { + if err_count < 5 { err_count += 1; println!("received error {} | NOT sending to mqtt ...", e); } @@ -561,7 +583,6 @@ pub fn main( } } }; - let _ = mdm.tcp_close_connection()?; } } diff --git a/src/serial.rs b/src/serial.rs index a3240c2..cccf36d 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -54,7 +54,7 @@ impl SerialIO { } } - fn read_bytes(&mut self, buf: &mut [u8]) -> Result { + pub fn read_bytes(&mut self, buf: &mut [u8]) -> Result { let mut started_reading = false; let mut count = 0; let mut retries = 0; @@ -85,6 +85,27 @@ impl SerialIO { Err(nb::Error::Other(SerialError::ReadError("Rx buffer empty.".to_string()))) } } + + pub fn clear(&mut self) { + let mut started_reading = false; + let mut retries = 0; + + loop { + match self.rx.read() { + Ok(_) => { + started_reading = true; + }, + Err(nb::Error::WouldBlock) => { + if started_reading || retries > READ_MAX_RETRIES { break; } + else { + thread::sleep(Duration::from_millis(READ_WAIT_TIME)); + retries += 1; + } + }, + Err(nb::Error::Other(err)) => println!("Serial read error :: {:?}", err), + } + } + } } impl io::Read for SerialIO {