Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

61 receive responses from a tcp server 2 #74

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cross/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ members = [
"dns",
"get_fw_version",
"join",
"send_data_tcp"
"send_data_tcp",
"receive_data_tcp"
]

[profile.dev]
Expand Down
42 changes: 42 additions & 0 deletions cross/receive_data_tcp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[package]
authors = [
"Jim Hodapp",
"Caleb Bourg",
"Glyn Matthews",
"Dilyn Corner"
]
edition = "2021"
name = "receive_data_tcp"
version = "0.3.0"
description = "Example RP2040 target application that demonstrates how to receive data from a remote server over TCP."

# makes `cargo check --all-targets` work
[[bin]]
name = "receive_data_tcp"
bench = false
doctest = false
test = false

[dependencies]
defmt = "0.3.0"
defmt-rtt = "0.3.1"
cortex-m = "0.7"
cortex-m-rt = "0.7"
embedded-hal = { version = "0.2", features=["unproven"] }
esp32-wroom-rp = { path = "../../esp32-wroom-rp" }
panic-probe = { version = "0.3.0", features = ["print-rtt"] }
heapless = "0.7.16"

rp2040-hal = { version = "0.6", features=["rt", "eh1_0_alpha"] }
rp2040-boot2 = { version = "0.2" }
fugit = "0.3"

[features]
default = ['defmt-default']
# these features are required by defmt
defmt-default = []
defmt-trace = []
defmt-debug = []
defmt-info = []
defmt-warn = []
defmt-error = []
266 changes: 266 additions & 0 deletions cross/receive_data_tcp/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
//! # ESP32-WROOM-RP Pico Wireless Example
//!
//! This application demonstrates how to use the ESP32-WROOM-RP crate to
//! send data to a remote server over TCP.
//!
//! See the `Cargo.toml` file for Copyright and license details.

#![no_std]
#![no_main]

extern crate esp32_wroom_rp;

include!("../../secrets/secrets.rs");

// The macro for our start-up function
use cortex_m_rt::entry;

// Needed for debug output symbols to be linked in binary image
use defmt_rtt as _;

use panic_probe as _;

// Alias for our HAL crate
use rp2040_hal as hal;

use embedded_hal::spi::MODE_0;

use core::fmt::Write;

use fugit::RateExtU32;
use hal::gpio::{FloatingInput, PushPullOutput};
use hal::{clocks::Clock, pac};

use heapless::String;

use esp32_wroom_rp::{
gpio::EspControlPins, network::IpAddress, network::Port, network::TransportMode,
tcp_client::Connect, tcp_client::TcpClient, wifi::ConnectionStatus, wifi::Wifi,
};

const MAX_HTTP_DOC_LENGTH: usize = 4096 as usize;

/// The linker will place this boot block at the start of our program image. We
/// need this to help the ROM bootloader get our code up and running.
#[link_section = ".boot2"]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;

/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
/// if your board has a different frequency
const XTAL_FREQ_HZ: u32 = 12_000_000u32;

/// Entry point to our bare-metal application.
///
/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function
/// as soon as all global variables are initialized.
#[entry]
fn main() -> ! {
// Grab our singleton objects
let mut pac = pac::Peripherals::take().unwrap();
let core = pac::CorePeripherals::take().unwrap();

// Set up the watchdog driver - needed by the clock setup code
let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);

// Configure the clocks
let clocks = hal::clocks::init_clocks_and_plls(
XTAL_FREQ_HZ,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();

let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());

// The single-cycle I/O block controls our GPIO pins
let sio = hal::Sio::new(pac.SIO);

// Set the pins to their default state
let pins = hal::gpio::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);

defmt::info!("ESP32-WROOM-RP example to send HTTP data over TCP socket and receive server response");

// These are implicitly used by the spi driver if they are in the correct mode
let _spi_miso = pins.gpio16.into_mode::<hal::gpio::FunctionSpi>();
let _spi_sclk = pins.gpio18.into_mode::<hal::gpio::FunctionSpi>();
let _spi_mosi = pins.gpio19.into_mode::<hal::gpio::FunctionSpi>();

let spi = hal::Spi::<_, _, 8>::new(pac.SPI0);

// Exchange the uninitialized SPI driver for an initialized one
let spi = spi.init(
&mut pac.RESETS,
clocks.peripheral_clock.freq(),
8.MHz(),
&MODE_0,
);

let esp_pins = EspControlPins {
// CS on pin x (GPIO7)
cs: pins.gpio7.into_mode::<PushPullOutput>(),
// GPIO0 on pin x (GPIO2)
gpio0: pins.gpio2.into_mode::<PushPullOutput>(),
// RESETn on pin x (GPIO11)
resetn: pins.gpio11.into_mode::<PushPullOutput>(),
// ACK on pin x (GPIO10)
ack: pins.gpio10.into_mode::<FloatingInput>(),
};

let mut wifi = Wifi::init(spi, esp_pins, &mut delay).unwrap();

let result = wifi.join(SSID, PASSPHRASE);
defmt::info!("Join Result: {:?}", result);

defmt::info!("Entering main loop");

let mut sleep: u32 = 1500;
loop {
match wifi.get_connection_status() {
Ok(status) => {
defmt::info!("Connection status: {:?}", status);
delay.delay_ms(sleep);

if status == ConnectionStatus::Connected {
defmt::info!("Connected to network: {:?}", SSID);

// The IPAddresses of two DNS servers to resolve hostnames with.
// Note that failover from ip1 to ip2 is fully functional.
let ip1: IpAddress = [9, 9, 9, 9];
let ip2: IpAddress = [8, 8, 8, 8];
let dns_result = wifi.set_dns(ip1, Some(ip2));

defmt::info!("set_dns result: {:?}", dns_result);

//let hostname = "ambi.matrix.net:4000";
//let ip_address: IpAddress = [10, 0, 1, 3]; // github.com
let ip_address: IpAddress = [52, 20, 27, 92]; // httpbin.org

//let port: Port = 4000;
let port: Port = 80;
let mode: TransportMode = TransportMode::Tcp;

let mut http_document: String<MAX_HTTP_DOC_LENGTH> = String::from("");
write!(http_document, "GET / HTTP/1.1\r\nHost: {}.{}.{}.{}:{}\r\nAccept: */*\r\n\r\n",
ip_address[0],
ip_address[1],
ip_address[2],
ip_address[3],
port
).ok().unwrap();

// write!(
// http_document,
// "GET / HTTP/1.1\r\nHost: {}:{}\r\nAccept: */*\r\n\r\n",
// hostname, port
// )
// .ok()
// .unwrap();


// let temperature = 22.0;
// let humidity = 33.1;
// let pressure = 997.0;

// let mut http_document: String<MAX_HTTP_DOC_LENGTH> = String::from("POST /api/readings/add");
// http_document
// .push_str(" HTTP/1.1\r\nHost: ")
// .ok()
// .unwrap();
// let mut host_address_str: String<MAX_HTTP_DOC_LENGTH> = String::new();
// write!(
// host_address_str,
// "{}.{}.{}.{}:{:?}\r\n",
// ip_address[0],
// ip_address[1],
// ip_address[2],
// ip_address[3],
// port
// )
// .unwrap();
// http_document.push_str(&host_address_str).ok().unwrap();
// http_document
// .push_str("User-Agent: edge/0.0.1\r\n")
// .ok()
// .unwrap();
// http_document.push_str("Accept: */*\r\n").ok().unwrap();
// http_document
// .push_str("Content-Type: application/json\r\n")
// .ok()
// .unwrap();
// let mut json_str: String<MAX_HTTP_DOC_LENGTH> = String::new();
// write!(json_str,
// "{{\"temperature\":\"{:.1?}\",\"humidity\":\"{:.1?}\",\"pressure\":\"{:.0?}\",\"dust_concentration\":\"200\",\"air_purity\":\"Low Pollution\"}}\r\n",
// temperature, humidity, pressure / 100.0
// ).ok().unwrap();
// let mut content_len_str: String<MAX_HTTP_DOC_LENGTH> = String::new();
// write!(content_len_str, "{:?}\r\n", json_str.len())
// .ok()
// .unwrap();
// http_document.push_str("Content-Length: ").ok().unwrap();
// http_document.push_str(&content_len_str).ok().unwrap();
// http_document.push_str("\r\n").ok().unwrap();
// http_document.push_str(&json_str).ok().unwrap();
// http_document.push_str("\r\n").ok().unwrap();

if let Err(e) = TcpClient::build(&mut wifi, &mut delay).connect(
ip_address,
port,
mode,
&mut |tcp_client| {
//defmt::info!("TCP connection to {:?}:{:?} successful", hostname, port);
defmt::info!("Hostname: {:?}", tcp_client.server_hostname());
defmt::info!("Sending HTTP Document: {:?}", http_document.as_str());
match tcp_client.send_data(&http_document) {
Ok(result) => {
defmt::info!("Data sent successfully: {:?}", result);
defmt::info!("Receiving response...");

match tcp_client.receive_data() {
Ok(response) => {
defmt::info!("{=[u8]:#X}", response);
defmt::info!("{=[u8]:a}", response);
}
Err(e) => {
defmt::info!("Error receiving data: {:?}", e);
}
}
}
Err(e) => {
defmt::error!("Response error: {:?}", e)
}
}
},
) {
defmt::error!(
"TCP connection to {:?}:{:?} failed: {:?}",
ip_address,
port,
e
);
}

delay.delay_ms(100);

defmt::info!("Leaving network: {:?}", SSID);
wifi.leave().ok();
} else if status == ConnectionStatus::Disconnected {
sleep = 20000; // No need to loop as often after disconnecting
}
}
Err(e) => {
defmt::error!("Failed to get connection result: {:?}", e);
}
}
}
}
3 changes: 1 addition & 2 deletions cross/send_data_tcp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,10 @@ fn main() -> ! {
.ok()
.unwrap();

if let Err(e) = TcpClient::build(&mut wifi).connect(
if let Err(e) = TcpClient::build(&mut wifi, &mut delay).connect(
hostname,
port,
mode,
&mut delay,
&mut |tcp_client| {
defmt::info!("TCP connection to {:?}:{:?} successful", hostname, port);
defmt::info!("Hostname: {:?}", tcp_client.server_hostname());
Expand Down
Loading