-
Notifications
You must be signed in to change notification settings - Fork 308
Open
Labels
package:esp-radioIssues related to the esp-wifi packageIssues related to the esp-wifi packageperformancePerformance seems to be not as good as it could bePerformance seems to be not as good as it could be
Description
I have a problem with slow download speed on esp32c3. I'm trying to build a simple audio sink, which connects to audio source in my local network and plays audio through I2S DAC. For now I'm testing download speed, because i wan't to stream uncompressed audio at CD quality which requires about 172 KiB/s of data throughput. On ESP datasheet i saw 20 Mbit/s download speed, so it should be possibile.
This is my test program based on examples :
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
//extern crate alloc;
use esp_backtrace as _;
use embassy_executor::_export::StaticCell;
use embassy_net::tcp::TcpSocket;
use embassy_net::{Config, Ipv4Address, Stack, StackResources};
use embassy_executor::Executor;
use embassy_time::{Duration, Timer, Instant};
use embedded_svc::wifi::{ClientConfiguration, Configuration, Wifi};
use esp_backtrace as _;
use esp_println::logger::init_logger;
use esp_println::println;
use esp_wifi::wifi::{WifiController, WifiDevice, WifiEvent, WifiMode, WifiState};
use esp_wifi::{initialize, EspWifiInitFor};
use hal::{
clock::{ClockControl, CpuClock},
Rng, embassy,
peripherals::Peripherals,
prelude::*,
timer::TimerGroup, Rtc,
systimer::SystemTimer,
i2s::{I2s0New},
};
const SSID: &str = env!("SSID");
const PASSWORD: &str = env!("PASSWORD");
macro_rules! singleton {
($val:expr) => {{
type T = impl Sized;
static STATIC_CELL: StaticCell<T> = StaticCell::new();
let (x,) = STATIC_CELL.init(($val,));
x
}};
}
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
#[entry]
fn main() -> ! {
init_logger(log::LevelFilter::Info);
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let mut peripheral_clock_control = system.peripheral_clock_control;
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze();
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
rtc.swd.disable();
rtc.rwdt.disable();
let timer = SystemTimer::new(peripherals.SYSTIMER).alarm0;
let init = initialize(
EspWifiInitFor::Wifi,
timer,
Rng::new(peripherals.RNG),
system.radio_clock_control,
&clocks,
).unwrap();
let (wifi, _) = peripherals.RADIO.split();
let (wifi_interface, controller) = esp_wifi::wifi::new_with_mode(&init, wifi, WifiMode::Sta);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut peripheral_clock_control);
embassy::init(&clocks, timer_group0.timer0);
let config = Config::dhcpv4(Default::default());
let seed = 1234; // very random, very secure seed
// Init network stack
let stack = &*singleton!(Stack::new(
wifi_interface,
config,
singleton!(StackResources::<3>::new()),
seed
));
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(connection(controller)).ok();
spawner.spawn(net_task(&stack)).ok();
spawner.spawn(get_page(&stack)).ok();
})
}
#[embassy_executor::task]
async fn connection(mut controller: WifiController<'static>) {
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.into(),
password: PASSWORD.into(),
..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 net_task(stack: &'static Stack<WifiDevice<'static>>) {
println!("start net_task task");
stack.run().await
}
#[embassy_executor::task]
async fn get_page(stack: &'static Stack<WifiDevice<'static>>) {
let mut rx_buffer = [0; 40960];
let mut tx_buffer = [0; 40960];
println!("start get_page task");
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;
}
loop {
Timer::after(Duration::from_millis(1_000)).await;
let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer);
socket.set_timeout(Some(embassy_time::Duration::from_secs(10)));
let remote_endpoint = (Ipv4Address::new(10, 1, 1, 85), 5901);
println!("connecting...");
let r = socket.connect(remote_endpoint).await;
if let Err(e) = r {
println!("connect error: {:?}", e);
continue;
}
println!("connected!");
let mut buf = [0; 20480];
loop {
use embedded_io::asynch::Write;
let r = socket
.write_all(b"GET /stream/swyh.wav HTTP/1.1\r\nHost: 10.1.1.85:5901\r\n\r\n")
.await;
if let Err(e) = r {
println!("write error: {:?}", e);
break;
}
let mut measure_start = Instant::now();
let mut bytes_downloaded_total = 0;
loop {
let bytes_downloaded = match socket.read(&mut buf).await {
Ok(0) => {
println!("read EOF");
break;
}
Ok(n) => n,
Err(e) => {
println!("read error: {:?}", e);
break;
}
};
bytes_downloaded_total += bytes_downloaded;
let now = Instant::now();
let elapsed_ms = now.duration_since(measure_start).as_millis();
if elapsed_ms >= 1000 {
let kib_per_sec = bytes_downloaded_total as f32 / elapsed_ms as f32;
println!("got {}B in {}ms {:05.2} KB/s", bytes_downloaded_total, elapsed_ms, kib_per_sec);
measure_start = now;
bytes_downloaded_total = 0;
}
}
}
Timer::after(Duration::from_millis(3000)).await;
}
}
And speeds i get :
got 15818B in 1028ms 15.39 KB/s
got 15818B in 1044ms 15.15 KB/s
got 12942B in 1075ms 12.04 KB/s
got 12942B in 1142ms 11.33 KB/s
got 12942B in 1023ms 12.65 KB/s
got 11504B in 1154ms 09.97 KB/s
got 14380B in 1078ms 13.34 KB/s
got 14380B in 1013ms 14.20 KB/s
got 11504B in 1097ms 10.49 KB/s
So I'm more than 10 times short :(
Is there anything i can do to speed this up ?
I have tried increasing buffers size but it doesn't change anything.
Ultimately i would like to use DMA transfer to push incoming audio data to I2S, is this possible on ESP and this library ?
Metadata
Metadata
Assignees
Labels
package:esp-radioIssues related to the esp-wifi packageIssues related to the esp-wifi packageperformancePerformance seems to be not as good as it could bePerformance seems to be not as good as it could be
Type
Projects
Status
Todo