From 4065ac8fde29a1b581a4f3f28337eeb48f0d47bf Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Tue, 8 Jul 2025 19:33:24 +0300 Subject: [PATCH 1/9] AE-577: Added basic comments to example sketches to explain their intended purpose; Implemented in "KeyboardAndMouse" sketch the same solution to print mouse data to console, as used in the "Mouse" example. --- examples/Barcode/Barcode.ino | 6 +++ examples/Keyboard/Keyboard.ino | 7 ++- .../KeyboardAndMouse/KeyboardAndMouse.ino | 43 ++++++++++++------- examples/Mouse/Mouse.ino | 2 + 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/examples/Barcode/Barcode.ino b/examples/Barcode/Barcode.ino index 711929d..571de3f 100644 --- a/examples/Barcode/Barcode.ino +++ b/examples/Barcode/Barcode.ino @@ -1,3 +1,9 @@ +/* + * By connecting a handheld barcode reader to the USB-A port on the mid-carrier board of your Arduino Portenta C33, + * you should immediately be able to read standard 13-digit bar codes on any ordinary commercial product packaging. + * Please note that barcodes longer than 13 digits will result in the "Invalid character detected, resetting..." being printed. + */ + #include #include diff --git a/examples/Keyboard/Keyboard.ino b/examples/Keyboard/Keyboard.ino index 85baf6c..b034dad 100755 --- a/examples/Keyboard/Keyboard.ino +++ b/examples/Keyboard/Keyboard.ino @@ -1,3 +1,5 @@ +/* This simple example shows how to read keyboard data by both listening for events and polling for available character data in the internal buffers of the USB HID Host */ + #include #include @@ -17,15 +19,16 @@ void setup() { while (!Serial); kb.attachConnectionCallback(onKeyboardConnected); - kb.attachKeyboardEventCallback(onKeyboardEvent); + kb.attachKeyboardEventCallback(onKeyboardEvent); // Register callback to get the keystrokes via events kb.begin(); } void loop() { kb.poll(); + // Second way of reading back the keystrokes is via polling for available characters while (kb.available() > 0) { char c = kb.read(); - Serial.print(c); + Serial.println(c); } } diff --git a/examples/KeyboardAndMouse/KeyboardAndMouse.ino b/examples/KeyboardAndMouse/KeyboardAndMouse.ino index 25d1737..cbd0f62 100755 --- a/examples/KeyboardAndMouse/KeyboardAndMouse.ino +++ b/examples/KeyboardAndMouse/KeyboardAndMouse.ino @@ -1,10 +1,24 @@ +/* This simple example demonstrates how to read mouse and keyboard data, by connecting these devices at the same time to the Portenta, via a USB hub */ + #include #include +/* + * In order to use two (or more) HID devices connected via a USB hub to your Portenta C33 board, please open "tusb_config.h" below (right click -> Go To Definition) + * and make sure that "CFG_TUH_HUB" is set to value 1, and that "CFG_TUH_HID" is set to the number of HID devices you intend to connect to your Arduino (2 in this example). + * Please also keep in mind that some keyboards and mice which include advanced illumination features might draw more power than the Arduino is able to provide on its + * USB-A port and might therefore lead to a reset or failure to be enumerated by the board. Ideally, use basic USB keyboards and mice, these should work best. + */ + +#include + // Global device instances USBHIDKeyboard kb; USBHIDMouse ms; +HIDMouseEvent mouseEvent; +bool eventReceived = false; + // Keyboard connection callback void onKeyboardConnected() { Serial.println("Keyboard connected (callback)."); @@ -23,14 +37,8 @@ void onMouseConnected() { // Mouse movement/button event callback void onMouseEvent(const HIDMouseEvent &event) { - Serial.print("Mouse event (callback) - Buttons: "); - Serial.print(event.buttons); - Serial.print(", x: "); - Serial.print(event.xMovement); - Serial.print(", y: "); - Serial.print(event.yMovement); - Serial.print(", wheel: "); - Serial.println(event.wheelMovement); + eventReceived = true; + mouseEvent = event; } void setup() { @@ -55,12 +63,15 @@ void loop() { kb.poll(); ms.poll(); - // Optional: Read keyboard characters from buffer - while (kb.available() > 0) { - char c = kb.read(); - Serial.print("Buffered keystroke: "); - Serial.println(c); - } - - // You can also process mouse state if needed + if(eventReceived){ + Serial.print("Mouse event (callback) - Buttons: "); + Serial.print(mouseEvent.buttons); + Serial.print(", x: "); + Serial.print(mouseEvent.xMovement); + Serial.print(", y: "); + Serial.print(mouseEvent.yMovement); + Serial.print(", wheel: "); + Serial.println(mouseEvent.wheelMovement); + eventReceived = false; + } } diff --git a/examples/Mouse/Mouse.ino b/examples/Mouse/Mouse.ino index 7da987f..3987aa1 100755 --- a/examples/Mouse/Mouse.ino +++ b/examples/Mouse/Mouse.ino @@ -1,3 +1,5 @@ +/* This simple example shows how to read mouse data, like cursor position and key states, by registering a callback and listening for events */ + #include #include From 8caaaef29362fd17774096f895f9f57e5cca3bc7 Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Wed, 9 Jul 2025 14:45:12 +0300 Subject: [PATCH 2/9] AE-577: Added more details in comment headers. --- examples/Barcode/Barcode.ino | 11 ++++++++++- examples/Keyboard/Keyboard.ino | 10 +++++++++- examples/KeyboardAndMouse/KeyboardAndMouse.ino | 18 ++++++++++++------ examples/Mouse/Mouse.ino | 11 ++++++++++- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/examples/Barcode/Barcode.ino b/examples/Barcode/Barcode.ino index 571de3f..e4c62df 100644 --- a/examples/Barcode/Barcode.ino +++ b/examples/Barcode/Barcode.ino @@ -1,7 +1,16 @@ -/* +/* + * This example shows how to use the Arduino Portenta C33 USBHIDHost library to read barcodes like the ones printed on common + * products packaging. + * * By connecting a handheld barcode reader to the USB-A port on the mid-carrier board of your Arduino Portenta C33, * you should immediately be able to read standard 13-digit bar codes on any ordinary commercial product packaging. * Please note that barcodes longer than 13 digits will result in the "Invalid character detected, resetting..." being printed. + * + * Instructions: + * 1. Connect your Arduino Portenta C33 to a mid-carrier board; + * 2. Upload this sketch to the Portenta; + * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; + * 4. Connect your barcode scanner to the USB-A connector on the mid-carrier board and scan away. */ #include diff --git a/examples/Keyboard/Keyboard.ino b/examples/Keyboard/Keyboard.ino index b034dad..c88ab23 100755 --- a/examples/Keyboard/Keyboard.ino +++ b/examples/Keyboard/Keyboard.ino @@ -1,4 +1,12 @@ -/* This simple example shows how to read keyboard data by both listening for events and polling for available character data in the internal buffers of the USB HID Host */ +/* + * This simple example shows how to read keyboard data by both listening for events and polling for available character data in the internal buffers of the USB HID Host + * + * Instructions: + * 1. Connect your Arduino Portenta C33 to a mid-carrier board; + * 2. Upload this sketch to the Portenta; + * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; + * 4. Connect your keyboard to the USB-A connector and any keypress should be printed to the console window. + */ #include #include diff --git a/examples/KeyboardAndMouse/KeyboardAndMouse.ino b/examples/KeyboardAndMouse/KeyboardAndMouse.ino index cbd0f62..f18ab05 100755 --- a/examples/KeyboardAndMouse/KeyboardAndMouse.ino +++ b/examples/KeyboardAndMouse/KeyboardAndMouse.ino @@ -1,15 +1,21 @@ -/* This simple example demonstrates how to read mouse and keyboard data, by connecting these devices at the same time to the Portenta, via a USB hub */ - -#include -#include - -/* +/* + * This simple example demonstrates how to read mouse and keyboard data, by connecting these devices at the same time to the Portenta, via a USB hub + * * In order to use two (or more) HID devices connected via a USB hub to your Portenta C33 board, please open "tusb_config.h" below (right click -> Go To Definition) * and make sure that "CFG_TUH_HUB" is set to value 1, and that "CFG_TUH_HID" is set to the number of HID devices you intend to connect to your Arduino (2 in this example). * Please also keep in mind that some keyboards and mice which include advanced illumination features might draw more power than the Arduino is able to provide on its * USB-A port and might therefore lead to a reset or failure to be enumerated by the board. Ideally, use basic USB keyboards and mice, these should work best. + * + * Instructions: + * 1. Connect your Arduino Portenta C33 to a mid-carrier board; + * 2. Upload this sketch to the Portenta; + * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; + * 4. Connect a USB hub to the USB-A connector on the mid-carrier board; + * 5. Now connect your keyboard and mouse to the USB hub and check the printed output on the console when pressing a key on the keyboard or moving the mouse. */ +#include +#include #include // Global device instances diff --git a/examples/Mouse/Mouse.ino b/examples/Mouse/Mouse.ino index 3987aa1..8ce1dfe 100755 --- a/examples/Mouse/Mouse.ino +++ b/examples/Mouse/Mouse.ino @@ -1,4 +1,13 @@ -/* This simple example shows how to read mouse data, like cursor position and key states, by registering a callback and listening for events */ +/* + * This simple example shows how to read mouse data, like cursor position and key states, by registering a callback and listening for events + * + * Instructions: + * 1. Connect your Arduino Portenta C33 to a mid-carrier board; + * 2. Upload this sketch to the Portenta; + * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; + * 4. Connect your mouse to the USB-A connector and any movement or keypress should be printed as data to the console. + * Please not that scroll wheel data works inconsistently and might not function correctly with your mouse. + */ #include #include From 9fdf67ceaaa492741b2b784f331a98704b9a68e9 Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Wed, 9 Jul 2025 15:38:24 +0300 Subject: [PATCH 3/9] AE-577: Added info regarding hardware used for testing the implementation. --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ce00439..cb1f004 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,9 @@ void loop() { The connection callback (via attachConnectionCallback()) notifies you when a compatible keyboard is connected. +Tested with: Oldschool classic Dell L100 and brand new “gaming” modern GamingX Trust keyboards. + + ### Mouse Reading Mouse Information The mouse class provides a callback that returns a structure containing mouse event data. The structure is defined as follows: @@ -85,6 +88,14 @@ void onMouseEvent(const HIDMouseEvent &mouseEvent) { usbMouse.attachMouseEventCallback(onMouseEvent); ``` +Tested with: basic wired mouse Genius X-Scroll GM-110020, new model GamingX Trust “gaming” mouse and Dell WM 126 wireless mouse. + + +### Keyboard and Mouse +In order to use two (or more) HID devices connected via a USB hub to your Portenta C33 board, please open "tusb_config.h" and make sure that "CFG_TUH_HUB" is set to value 1, and that "CFG_TUH_HID" is set to the number of HID devices you intend to connect to your Arduino (2 in this example). +Please also keep in mind that some keyboards and mice which include advanced illumination features might draw more power than the Arduino is able to provide on its +USB-A port and might therefore lead to a reset or failure to be enumerated by the board. Ideally, use basic USB keyboards and mice, these should work best. + ### Temp. Development instructions Before all the changes get merged into the core, you will have to do some modifications to get this library to compile. @@ -92,9 +103,4 @@ Before all the changes get merged into the core, you will have to do some modifi In the core by modify [variants/PORTENTA_C33/tusb_config.h](https://github.com/arduino/ArduinoCore-renesas/blob/main/variants/PORTENTA_C33/tusb_config.h). On line 106, add `#define CFG_TUH_HID 1`. -Check [this PR](https://github.com/arduino/ArduinoCore-renesas/compare/main...cristidragomir97:ArduinoCore-renesas:hid_host_c33) for more information. - -2. Enable weak callback for `tuh_hid_report_received_cb` -When enabling CFG_TUH_HID in tusb_config.h, the stack will expect a tuh_hid_report_received_cb callback to be defined in every sketch, preventing any sketch that doesn't have anything to do with the HID Host stack from compiling. The hid_host.h file defines weak callbacks in order to prevent this issue, but the TU_ATTR_WEAK is prefixed to most callbacks except fortuh_hid_report_received_cb. These changes add this attribute, allowing any sketch to compile. - -Check [this PR](https://github.com/arduino/tinyusb/pull/3/commits/e3e9dd066cd64d98de6bd19d2920fec3019b71c4) for more information. +Check [this PR](https://github.com/arduino/ArduinoCore-renesas/compare/main...cristidragomir97:ArduinoCore-renesas:hid_host_c33) for more information. \ No newline at end of file From 6f8bb66d1638293381aea1519356e2059a5d9f42 Mon Sep 17 00:00:00 2001 From: cristidragomir97 Date: Mon, 14 Jul 2025 18:21:52 +0300 Subject: [PATCH 4/9] Update comments for examples/Barcode/Barcode.ino Co-authored-by: Sebastian Romero --- examples/Barcode/Barcode.ino | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/Barcode/Barcode.ino b/examples/Barcode/Barcode.ino index e4c62df..19c4e12 100644 --- a/examples/Barcode/Barcode.ino +++ b/examples/Barcode/Barcode.ino @@ -2,9 +2,10 @@ * This example shows how to use the Arduino Portenta C33 USBHIDHost library to read barcodes like the ones printed on common * products packaging. * - * By connecting a handheld barcode reader to the USB-A port on the mid-carrier board of your Arduino Portenta C33, - * you should immediately be able to read standard 13-digit bar codes on any ordinary commercial product packaging. - * Please note that barcodes longer than 13 digits will result in the "Invalid character detected, resetting..." being printed. + * By connecting a handheld barcode reader to the USB-A port on the mid-carrier board of your + * Arduino Portenta C33, you should immediately be able to read standard 13-digit bar codes on + * any ordinary commercial product packaging. + * Please note that barcodes longer than 13 digits will result in "Invalid character detected, resetting..." messages being printed. * * Instructions: * 1. Connect your Arduino Portenta C33 to a mid-carrier board; From abda6d2c12ec3bd753c03730b6cf6a6d2fc19d01 Mon Sep 17 00:00:00 2001 From: cristidragomir97 Date: Mon, 14 Jul 2025 18:22:05 +0300 Subject: [PATCH 5/9] Update examples/Barcode/Barcode.ino Co-authored-by: Sebastian Romero --- examples/Barcode/Barcode.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Barcode/Barcode.ino b/examples/Barcode/Barcode.ino index 19c4e12..0a7dc85 100644 --- a/examples/Barcode/Barcode.ino +++ b/examples/Barcode/Barcode.ino @@ -9,7 +9,7 @@ * * Instructions: * 1. Connect your Arduino Portenta C33 to a mid-carrier board; - * 2. Upload this sketch to the Portenta; + * 2. Upload this sketch to the board; * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; * 4. Connect your barcode scanner to the USB-A connector on the mid-carrier board and scan away. */ From de539e7e94420ff09ba982a516899a61f03ef4ca Mon Sep 17 00:00:00 2001 From: cristidragomir97 Date: Mon, 14 Jul 2025 18:28:53 +0300 Subject: [PATCH 6/9] Update examples/Keyboard/Keyboard.ino Co-authored-by: Sebastian Romero --- examples/Keyboard/Keyboard.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/Keyboard/Keyboard.ino b/examples/Keyboard/Keyboard.ino index c88ab23..a3ab9da 100755 --- a/examples/Keyboard/Keyboard.ino +++ b/examples/Keyboard/Keyboard.ino @@ -4,7 +4,8 @@ * Instructions: * 1. Connect your Arduino Portenta C33 to a mid-carrier board; * 2. Upload this sketch to the Portenta; - * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; + * 3. Open the Serial Monitor and chose 115200 as baud rate; + * 4. Connect your keyboard to the USB-A connector and any keypress should be printed to the console window. */ From 3c21cd3126ac8aa79875ec0d852d47a68c15dfed Mon Sep 17 00:00:00 2001 From: cristidragomir97 Date: Mon, 14 Jul 2025 18:30:02 +0300 Subject: [PATCH 7/9] Update examples/Mouse/Mouse.ino Co-authored-by: Sebastian Romero --- examples/Mouse/Mouse.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/Mouse/Mouse.ino b/examples/Mouse/Mouse.ino index 8ce1dfe..330e735 100755 --- a/examples/Mouse/Mouse.ino +++ b/examples/Mouse/Mouse.ino @@ -3,7 +3,8 @@ * * Instructions: * 1. Connect your Arduino Portenta C33 to a mid-carrier board; - * 2. Upload this sketch to the Portenta; + * 2. Upload this sketch to the board; + * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; * 4. Connect your mouse to the USB-A connector and any movement or keypress should be printed as data to the console. * Please not that scroll wheel data works inconsistently and might not function correctly with your mouse. From a99579d06834aa6551c427ec64fe90d5abbe1a6e Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Wed, 17 Sep 2025 21:12:36 +0300 Subject: [PATCH 8/9] AE-577: Addressed code review findings. --- examples/Keyboard/Keyboard.ino | 13 +++++++++---- examples/KeyboardAndMouse/KeyboardAndMouse.ino | 5 ++++- examples/Mouse/Mouse.ino | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/Keyboard/Keyboard.ino b/examples/Keyboard/Keyboard.ino index a3ab9da..fa77638 100755 --- a/examples/Keyboard/Keyboard.ino +++ b/examples/Keyboard/Keyboard.ino @@ -1,5 +1,8 @@ /* - * This simple example shows how to read keyboard data by both listening for events and polling for available character data in the internal buffers of the USB HID Host + * This simple example shows how to read keyboard data by both listening for events and polling for available character data in the internal buffers of the USB HID Host. + * There are two general ways user input can be detected, either by constantly checking for the state of a buffer (or pin, for example), which we refer to as the "polling" method, or + * by having some event fire as soon as the user input (key press in this case) is detected, which, in turn, calls a function we registered previously with the lower layers. + * The below example demonstrates both these methods of capturing user input. * * Instructions: * 1. Connect your Arduino Portenta C33 to a mid-carrier board; @@ -18,8 +21,9 @@ void onKeyboardConnected() { Serial.println("Keyboard connected (callback)."); } +// This function will now be called every time a key is pressed by the user, as a single event void onKeyboardEvent(uint8_t key) { - Serial.print("Keyboard event (callback): "); + Serial.print("Key pressed (event callback): "); Serial.println((char) key); } @@ -33,11 +37,12 @@ void setup() { } void loop() { - kb.poll(); + kb.poll(); // This function will continuosly check if a key has been pressed, this is generally refered to as "polling" - // Second way of reading back the keystrokes is via polling for available characters + // If keystrokes were registered, we enter a second loop and print out the entire buffer while (kb.available() > 0) { char c = kb.read(); + Serial.print("Key pressed (polling detection): "); Serial.println(c); } } diff --git a/examples/KeyboardAndMouse/KeyboardAndMouse.ino b/examples/KeyboardAndMouse/KeyboardAndMouse.ino index f18ab05..da4ce47 100755 --- a/examples/KeyboardAndMouse/KeyboardAndMouse.ino +++ b/examples/KeyboardAndMouse/KeyboardAndMouse.ino @@ -42,9 +42,12 @@ void onMouseConnected() { } // Mouse movement/button event callback +// Note here the use of the "eventReceived" global variable. Since this function is called in an interrupt context, +// we cannot do the processing and printin of data using Serial.print inside the interrupt, because it takes too much time. +// Therefore, we set a global flag to "true", which is then checked in the "loop", outside of the ISR (interrupt service routine), then set back to "false". +// An even better and more robut, but also more complex, way of handling this is by using a buffer queue for the mouse data and a state machine to process it. void onMouseEvent(const HIDMouseEvent &event) { eventReceived = true; - mouseEvent = event; } void setup() { diff --git a/examples/Mouse/Mouse.ino b/examples/Mouse/Mouse.ino index 330e735..ded4038 100755 --- a/examples/Mouse/Mouse.ino +++ b/examples/Mouse/Mouse.ino @@ -5,9 +5,9 @@ * 1. Connect your Arduino Portenta C33 to a mid-carrier board; * 2. Upload this sketch to the board; - * 3. Open the Serial Monitor and chose the same baud rate as used in the sketch; + * 3. Open the Serial Monitor and chose the same baud rate (115200 in this case) as used in the sketch; * 4. Connect your mouse to the USB-A connector and any movement or keypress should be printed as data to the console. - * Please not that scroll wheel data works inconsistently and might not function correctly with your mouse. + * Please note that the scroll wheel data works inconsistently and might not function correctly with your mouse. */ #include From 65d32e54c5d1bbc8e02589eca35d4caaa6ed9f07 Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Mon, 22 Sep 2025 14:04:09 +0300 Subject: [PATCH 9/9] AE-577: Fixed spelling mistakes. --- examples/Keyboard/Keyboard.ino | 2 +- examples/KeyboardAndMouse/KeyboardAndMouse.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Keyboard/Keyboard.ino b/examples/Keyboard/Keyboard.ino index fa77638..8d61338 100755 --- a/examples/Keyboard/Keyboard.ino +++ b/examples/Keyboard/Keyboard.ino @@ -37,7 +37,7 @@ void setup() { } void loop() { - kb.poll(); // This function will continuosly check if a key has been pressed, this is generally refered to as "polling" + kb.poll(); // This function will continuously check if a key has been pressed, this is generally referred to as "polling" // If keystrokes were registered, we enter a second loop and print out the entire buffer while (kb.available() > 0) { diff --git a/examples/KeyboardAndMouse/KeyboardAndMouse.ino b/examples/KeyboardAndMouse/KeyboardAndMouse.ino index da4ce47..f406cad 100755 --- a/examples/KeyboardAndMouse/KeyboardAndMouse.ino +++ b/examples/KeyboardAndMouse/KeyboardAndMouse.ino @@ -43,7 +43,7 @@ void onMouseConnected() { // Mouse movement/button event callback // Note here the use of the "eventReceived" global variable. Since this function is called in an interrupt context, -// we cannot do the processing and printin of data using Serial.print inside the interrupt, because it takes too much time. +// we cannot do the processing and printing out of data using Serial.print, inside the interrupt, because it takes too much time. // Therefore, we set a global flag to "true", which is then checked in the "loop", outside of the ISR (interrupt service routine), then set back to "false". // An even better and more robut, but also more complex, way of handling this is by using a buffer queue for the mouse data and a state machine to process it. void onMouseEvent(const HIDMouseEvent &event) {