esp32-usb-host-demos
esp32-usb-host-demos copied to clipboard
Printer demo needs a little further help
With the printer demo, it seems if you try to print just a fixed string like "hello world" instead of a line read from Serial, the program crashes, because PrinterOut is a null pointer.
I guess some extra logic is needed to check for PrinterOut being null, and it would be most instructive and helpful if you could add this.
Or perhaps a better approach would use some callback to tell when the printer is ready to accept data?
With the printer demo, it seems if you try to print just a fixed string like "hello world" instead of a line read from Serial, the program crashes, because PrinterOut is a null pointer.
PrintOut is initialized as follows so is not NULL.
err = usb_host_transfer_alloc(endpoint->wMaxPacketSize*PRINTER_OUT_BUFFERS, 0, &PrinterOut);
if (err != ESP_OK) {
PrinterOut = NULL;
Dbg_printf("usb_host_transfer_alloc Out fail: %x", err);
return;
}
The following is a an older version of the program that prints "Hello" instead of reading from terminal.
"The following" seems to be missing...
Maybe there is a race condition? I was trying this on an ESP32S3 and v 3.0.2 of the Arduino ESP32 package.
If I use this modification of the loop, printing basically works, but if I leave out the test for PrinterOut being Null, the program just crashes with an illegal memory access exception and restarts, over and over again.
int times = 0;
void loop()
{
usbh_task();
if ( (PrinterOut != NULL) && (times < 5) ) {
String aLine = String(times)+"\n"; // Read line ending with newline
Serial.printf("%d\n",times);
// readStringUntil removes the newline so add it back
PrinterOut->num_bytes = aLine.length();
memcpy(PrinterOut->data_buffer, aLine.c_str(), PrinterOut->num_bytes);
esp_err_t err = usb_host_transfer_submit(PrinterOut);
if (err != ESP_OK) {
ESP_LOGI("", "usb_host_transfer_submit Out fail: %x", err);
}
times++;
}
}
This is the older version that just prints hello.
https://github.com/touchgadget/esp32-usb-host-demos/blob/ce8088f4dd3fbf12a8e81b16ee273ae8c30cbc27/examples/usbhprinter/usbhprinter.ino
I note that older version also has a test (PrinterOut != NULL) in it. My example is pretty much the same, except that it prints several lines using a counter, rather than a Boolean flag. If you remove the test for PrinterOut being Null, your old program also crashes.
It seems that, from start up, it takes a time for PrinterOut to become non-Null, and essentially, we must wait for this before trying to print.
Of course, there must be a check for NULL. The printer may be unplugged on power up. The Arduino sketch runs as a freeRTOS task. The USB host stack is interfaced with another task. If you like, you can create semaphores to sync the tasks.
Prerequisite: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/usb_host.html
The ESP-IDF has USB host examples using one more task for the client/class driver and semaphores to sync main, usb host lib task, and usb client/class tasks.