How a generic keyboard is made has been already explained in the Atmega 32u4 Based Generic USB Keyboard Project. In this project a wireless keyboard will be designed. For making a wireless keyboard, there will be two circuits involved in the project – a transmitter circuit which will have a keypad included for getting the user input and a receiver circuit that will connect with the PC through USB port. The two circuits will connect wirelessly using NRF24lO1 module. The NRF module is a Wireless Transceiver that works on 2.4 GHz ISM (Industrial Scientific Medical) band. It is manufactured by Nordic Semiconductors.
The transmitter section will have Arduino Mega as the controller. The Arduino Mega is selected due to large number of GPIO pins available with board. So, if the project has to be expanded large number of keys can be interfaced to an Arduino Mega Board. At the transmitter section, the computation will be handled by two controller boards – Arduino UNO and Arduino Pro Micro, each having their own computational roles. At the end Arduino Pro Micro will connect with the USB port of the PC where the 8-bit USB AVR – Atmega 32u4 will work as the USB device controller chip. The Arduino Pro Micro will use AVR based Lightweight USB Framework (LUFA) as the firmware for implementing the USB protocol in the end phase of the project execution.
Usually the Windows keyboard has 104 keys which is the de facto standard and the windows based laptops have 86-key keyboards. An Apple keyboard has 109 keys as the standard and Apple laptops have 78-key keyboard. In this project a 4-key keyboard is built to demonstrate the making of wireless keyboard. The Arduino Pro Micro will use HID device driver class of LUFA framework for keyboard which will be modified to implement the project. With the use of LUFA firmware on Arduino Pro Micro, the device driver code to implement USB protocol is not needed to be written explicitly. The project works similar to any USB keyboard having wireless connectivity and has buttons for the following Inputs – :
• Input H Alphabet to the computer
• Input I Alphabet to the computer
• Turn Caps lock ON or OFF
• Left Shift Key
The transmitter circuit of the project uses tactile switches as the keyboard buttons, Arduino Mega for generating keycodes and NRF24LO1 for wireless connectivity. The receiver circuit of the project will use NRF24LO1 for receiving keycodes wirelessly, Arduino UNO to fetch and pass keycodes, Arduino Pro Micro to analyze keycodes and prepare HID keyboard specific data reports and USB cable to connect with the personal computer.
Fig. 1: Prototype of Arduino Based Wireless USB Keyboard
PREREQUISITES
This project is based on Arduino Pro Micro, Arduino Mega and Arduino UNO which have AVR microcontrollers on board. In order to understand this project, one must have basic knowledge of the AVR microcontrollers and the embedded C programming for AVRs. WinAVR Studio is used to write, edit and compile the project code, so closely following the project shall require familiarizing with the above stated IDE as well. Though LUFA framework takes care of implementing the USB protocol on Arduino Pro Micro and has APIs to abstract the lower level codes, understanding USB protocol is recommended to understand how actually the project is working. In fact, if anyone has already worked on some other microcontroller and have some experience of working on electronic circuits, it will not be much pain to understand and follow this project. The project is based on getting input from the GPIO pins of AVR MCU, transmitting data through SPI, interfacing wireless module with Arduino(s) and modifying the LUFA device driver for keyboard functionality.
COMPONENTS REQUIRED
1. Arduino Pro Micro
2. Arduino Mega
3. Arduino UNO
4. Breadboard
5. Connecting wires
6. Push buttons
7. Micro USB cable
8. 10K resistors
9. NRF24LO1 Transmitter and Receiver
SOFTWARE TOOLS REQUIRED
1. WinAVR Studio
2. AVR Dude
BLOCK DIAGRAM
Fig. 2: Block Diagram of Arduino Based Wireless USB Keyboard
CIRCUIT CONNECTIONS
The project will have two circuits – Transmitter Circuit and the Receiver Circuit. The Transmitter will have following hardware blocks – :
• Keys – The push buttons will be used as keyboard keys. There will be four keys: h alphabet key, I alphabet key, Caps Lock key and Left Shift key. The Push buttons will be attached to Arduino Mega via Digital Input/Output pins. The switches will be interfaced to the pins of the Arduino Mega in the following manner -:
Fig. 3: Table listing Arduino pins and respective keyboard functions
The tactile switches are connected between the pins and the ground. The pins by default are connected to VCC and receive a HIGH logic. Pressing a tactile switch changes the status at the respective pin to LOW by short circuiting to the ground.
• Arduino Mega – The Arduino Mega will be the controller board at the transmitter end. The NRF will be interfaced with Arduino to add the wireless functionality. Push buttons that will work as keys will be attached to the GPIO pins of the Arduino. The Arduino Mega has more input pins than other boards, which makes it suitable for connecting large number of keys. Therefore, on Arduino Mega, the project can be expanded from four keys to a significant number of additional keys.
• NRF – The NRF24LO1 will be interfaced with the Arduino Mega via SPI (Serial Peripheral Interface). It will be used to transmit data wirelessly to receiver. The NRF module will be interfaced to the Arduino Mega by connecting the pins in the following manner -:
Fig. 4: Table listing circuit connections between Arduino Mega and NRF Module on Transmitter Side of Wireless USB Keyboard
The Receiver circuit of the project will have the following hardware blocks.
• NRF – The NRF24LO1 will receive the Data Packet from the Transmitter via wireless communication. It will then feed the packet to the Arduino Uno via SPI protocol. The receiver side NRF module will be interfaced with the Arduino UNO by connecting their pins in the following manner -:
Fig. 5: Table listing circuit connections between Arduino Mega and NRF Module on Receiver Side of Wireless USB Keyboard
• Arduino Uno – The Arduino UNO will collect Data Packet from NRF and will provide it to Atmega32u4 microcontroller on Arduino Pro Micro via UART serial communication. The Arduino UNO will act as intermediate device that will convert wireless protocol into serial protocol. The Arduino UNO and Arduino Pro Micro will be connected via UART pins in the following manner -:
Fig. 6: Table listing circuit connections between Arduino Pro Micro and Arduino Uno
• Arduino Pro Micro – The Arduino Pro Micro has the Atmega 32u4 as the sitting MCU. The microcontroller will take Data Packet from the Arduino UNO and transmit relevant Keyboard specific HID reports according to the USB protocol to the PC. It will connect to the USB port of a PC by a USB cable.
The Program code for the project will be burnt to the Arduino Pro Micro, Arduino UNO and Arduino Mega using AVR Dude.
HOW THE PROJECT WORKS
The functioning of the project involves three stages – :
1) Detection of key press and wireless transmission of data containing keycodes – This stage is handled by the Arduino Mega on the transmitter circuit of the project. The Arduino Mega has the program code to detect key press by detecting LOW logic at the pins to which tactile switches have been interfaced and pass a 2-byte code to the NRF module for wireless transmission. The Arduino Mega pass the 2-byte data to NRF module using SPI interface. Check out the program code of Arduino Mega to learn how key press is detected and accordingly 2-byte custom data is passed through SPI.
Fig. 7: Image showing push buttons connected at transmitter end
2) Wireless reception of data containing keycodes and passing it to Arduino Pro Micro – In the next stage, the 2-byte data received from the wireless module is read by the Arduino UNO and passed to the Arduino Pro Micro through UART interface. The Arduino UNO connects with the NRF module by SPI interface. Check out the program code to learn how Arduino UNO receives 2-byte data through SPI interface and passes it to Arduino Pro Micro by the UART interface.
3) Analysis of 2-byte data to fetch keycodes and transmit HID data report specific to Keyboard to the PC – The 2-byte data is received by the Arduino Pro Micro by the UART interface. The program code on Arduino Pro Micro is built on LUFA framework and has the demo project of keyboard modified to detect keycodes from data received by UART and transmit keyboard specific HID reports to the PC. For configuring the controller chip on Arduino Pro Micro to work as USB Keyboard, the HID Class Driver of the LUFA framework is used. The Human Interface Device (HID) class takes care of the transfers between the host device and the human controlled USB peripherals like USB Keyboard, Mouse or Joystick. Being a USB device on connecting with the PC, the Arduino Pro Micro has to get enumerated as HID Keyboard.
According to the USB protocol, keys pressed on a keyboard are identified by the key codes. The keycodes in this project are fetched from the transmitter section wirelessly. The keycodes for different keys on an USB keyboard are dictated by the HID Usage Table provided by the USB Implementers Forum.
A keyboard is HID class USB device and LUFA framework has HID class related module in the LUFA-Source-Folder /LUFA/Drivers/USB/Class/Device folder. Other device class related module are also in the same folder. The LUFA framework has demo projects for different USB device classes in the LUFA-Source-FolderDemosDeviceClassDriver folder. For implementing the project, demo project for keyboard provided in the LUFA framework will be modified and complied. The demo project for keyboard is in the LUFA-Source-FolderDemosDeviceClassDriverKeyboard folder. The folder contains keyboard.c file which will be modified to make this keyboard device.
How Keyboard.c identifies HID device being Keyboard
The keyboard.c uses Keyboard_HID_Interface interface in HID_Device_USBTask() function which is being imported from the HIDDeviceClass.c (from LUFA-Source-Folder LUFADriversUSBClassDevice) to configure the device as keyboard. The interface abstracts the low-level descriptor codes and identifies the device as keyboard through an InterfaceNumber variable.
Keyboard Specific Report Descriptors
Any HID device has to exchange data with the host which should be structured in the form of reports. The report descriptor defines the report structure. A report descriptor contains the information needed by host to determine the data format and how the data should be processed by the host. Therefore, a report descriptor basically structure the data that needs to be exchanged with the host according to the USB protocol.
For working like a keyboard, the device needs to send usage report and data input report descriptors specific to keyboard HID Class to the host while it itself needs to interpret data output report specific to keyboard HID Class received from the host device. The Usage Report informs the Host about the features or functionality of the USB device whereas the Data Input Report is used to transmit the data to the Host. The Data Output Report is used to receive data from the host.
From Where Keyboard.C gets the USAGE and Data Reports Descriptors
In the LUFA framework’s demo project for Keyboard, descriptor.c file is imported in keyboard.c to send the relevant usage and data reports descriptors to the host device. The descriptor.c defines a KeyboardReport[] structure which is used in the CALLBACK_HID_Device_CreateHIDReport() function of the keyboard.c to generate keyboard specific usage and data reports descriptors. Inside descriptor.c the KeyboardReport[] structure has the values returned by HID_DESCRIPTOR_KEYBOARD () function. The HID_DESCRIPTOR_KEYBOARD() is defined in HIDClassCommon.h (located in LUFA-Source-FolderLUFADriversUSBClassCommon folder). The keyboard.c imports keyboard.h which imports usb.h. USB.h imports HIDCLass.h. In HIDClass.h is imported HIDClassDevice.h if the USB_CAN_BE_DEVICE is true for the controller chip to being a USB device not the host. The HIDClassDevice.h imports HIDClassCommon.h where the HID device specific descriptor fields have been defined.
Usage and Data Reports
To learn about the usage and data reports specific to keyboard device refer to the Atmega 32u4 Based Generic USB Keyboard Project. For understanding this project it is important to understand data input report of the keyboard. The Data Input Report contains the data that needs to be transmitted to the Host. It contains data related to the features selected via the Usage Report. The data input report for keyboard consist of 8 bytes of which 6 bytes are used to represent keycodes of maximum six keys pressed together, one byte is reserved for OEM and is always set to 0 and one byte is for the modifier key. The field values specific to data report for keyboard are organised in the following manner – :
Fig. 8: Table listing Usage and Data Reports
For the project implementation, maximum 2-byte data report needs to be send to the PC as either a single keycode (in case H or I has to be passed to the PC) or a combination of two keycodes (in case Capital H or I has to be passed to the PC) need to be sent in data input report. The required 2-byte data for deciding keycodes is received wirelessly from the transmitter circuit of the project.
The main() function and the CALLBACK_HID_Device_CreateHIDReport() function of the keyboard.c are modified to detect 2-byte data and send relevant data input reports.
PROGRAMMING GUIDE
1) Program Code of Arduino Mega – The Arduino Mega detects the key press by detecting LOW logic at its pins and transmits keycodes for the keys by passing 2-byte data to the NRF module on SPI interface.
First the libraries for SPI and NRF modules are imported.
Then, two arrays are declared to hold the addresses of the SPI transmitter and receiver pipes. A two bytes long integer variable is declared to hold the value of keycodes that should be passed to the NRF transmitter.
The Arduino Mega pins are assigned constant names.
A setup function is called in which the Arduino pins where the tactile switches are connected are configured as digital input. The SPI interface is initialized using standard radio.begin() function and the pipe address is set to LOW. The transmitter address is assigned to the pipe address by using radio.openWritingPipe() function.
A loop() function is called in which, first the 2-byte data that has to be transmitted is set to 0 and by detecting respective key press is assigned specific keycode values either to first byte or the second byte (for modifier key) of the data.
If there is data available for transmission it is passed to NRF module on SPI interface using radio.write() function. The function accepts first parameter as pointer to the data and second parameter as the size of the data that has to be passed.
This completes the program code on Arduino Mega.
2) Program Code of Arduino UNO – The Arduino UNO reads the 2-byte data coming from the NRF module on SPI interface and pass it to the Arduino Pro Micro on UART interface.
First the libraries for SPI and NRF modules are imported.
Then, two arrays are declared to hold the addresses of the SPI transmitter and receiver pipes. A two bytes long integer variable is declared to hold the value of 2-byte data received from the NRF module. Also, two single byte integer variables are declared to hold the values of modifier key and alphabetical keycode seperately.
A setup function is called in which the baud rate for serial communication on UART is set using Serial.begin() function. The SPI interface is initialized using standard radio.begin() function and the pipe address is set to LOW. The receiver address (SPI) is assigned to the pipe address by using radio.openReadingPipe() function. The data from the receiver pin of SPI is read using radio.startListening() function.
A loop() function is called in which the data availability is checked and if 2-byte data is successfully received, modifier and alphabetic keycodes are separated in the variables declared for the respective purposes. The values of the variables holding modifier and alphabetic keycode are passed serially on UART to the Arduino Pro Micro.
This completes the program code on Arduino UNO.
3) Program Code of Arduino Pro Micro – For programming the Arduino Pro Micro, download the LUFA framework from the github.com. The demo project provided with the LUFA framework is modified to make implement the Keyboard specific HID class driver. In the extracted LUFA zip file, open Demos/Device/ClassDriver/Keyboard folder. The folder has the following files and folders.
Fig. 9: Screenshot of LUFA Library Folder on Windows
Of these, Keyboard.h, Keyboard.c and Makefile needs to be modified for this project. The modified files (provided at the bottom of the article in zip format) can also be downloaded from the engineersgarage and replaced with the original files. Either open the files in WinAVR Studio or Notepad++ and modify original files or replace files with the already modified one. The modified or replaced Keyboard.c needs to be compiled from within the LUFA’s Source folder to get the object code of Arduino Pro Micro.
Modifying Keyboard.h
The Keyboard.h library file is imported in the Keyboard.c file and includes a set of additional libraries and defines the constants and functions for the keyboard device. These include the additional libraries for the joystick, button and LEDs which should be commented out as the project is not using these HID features. So open Keyboard.h and make the following changes – :
• Comment the #include library statements for Joystick.h, LEDS.h, and Buttons.h ( We are commenting these libraries as we are not using any joystick, buttons board and LED board)
• Comment the #define statements for LEDMASK_USB_NOTREADY, LEDMASK_USB_ENUMERATING, LEDMASK_USB_READY, LEDMASK_USB_ERROR
Save the file with changes.
Modifying Keyboard.C file
Again in the Keyboard.c, the code sections for Joystick, button board and LEDs need to be commented out. So open Keyboard.c and make the following changes – :
• In the main loop, comment the LEDs_SetAllLEDs()
• In SetupHardware() function, comment the Joystick_Init(), LEDs_Init(), Buttons_Init()
• In EVENT_USB_Device_Connect() function, comment the LEDs_SetAllLEDs()
• In EVENT_USB_Device_Disconnect() function, comment LEDs_SetAllLEDs()
• In EVENT_USB_Device_ConfigurationChanged() function, comment the LEDs_SetAllLEDs()
In Keyboard.c, first uart.h has to be included. So add the following line below include statement of keyboard.h.
In the main() function, UART also needs to be initialized by using uart_init() function so add the following lines to the main() function of the Keyboard.c.
Inside the infinite for loop the HID_Device_USBTask() function is called where Keyboard_HID_Interface interface is passed as parameter. The interface identifies the device as keyboard and abstracts the low level program code specific to keyboard HID class. The function is coming from the HIDClassDevice.c module (located in LUFA/Drivers/USB/Class/Device/HIDClassDevice.c) and is used for general management task for a given HID class interface, required for the correct operation of the interface. It should be called in the main program loop, before the master USB management task USB_USBTask(). The USB_USBTask() is the main USB management task. The USB driver requires this task to be executed continuously when the USB system is active (device attached in host mode, or attached to a host in device mode) in order to manage USB communications. The function is defined in USBTask.c (Located in LUFA-Source-FolderLUFADriversUSBCore folder).
Fig. 10: Image showing h typed from Arduino based Wireless USB Keyboard
For holding the keycodes extracted from received 2-byte data, two global variables need to be declared along with a counter to trace position of byte in the received data. The ISR (Interrupt Service Routine) will be executed when any serial data is received.
The ISR that needs to be added in the source code is – :
For creating Keyboard Data Input report CALLBACK_HID_Device_CreateHIDReport() needs to be modified. The default file has the function body to detect joystick movement as well.
Fig. 11: Screenshot of CALLBACK_HID_Device_CreateHIDReport Function in LUFA Library
If there is any keycode extracted in the keycode_received and modifier_keys_received variables, it has to be passed into the data input report. So replace the body of the function with the following code.
The Data Output Report is not utilized in the project execution therefore the CALLBACK_HID_Device_ProcessHIDReport() function which process Data Output report has been kept unchanged.
Save the file and create Make file for the project.
Modifying Make File
In the Keyboard folder there is a make file that needs to be edited. The file can be edited using Notepad++. The following information needs to be edited – :
• MCU = atmega32u4
• ARCH = AVR8
• BOARD = LEONARDO
• F_CPU = 16000000
Save the file and exit. Now all the files are edited completely for the wireless Keyboard project.
Compiling Keyboard.c
For compiling the source code, WinAVR Programmers Notepad or Arduino IDE can be used. Open the modified Keyboard.c file and compile the code.
BURNING HEX CODE
The hex file is generated on compiling the keyboard.c file. For burning the object code to microcontroller open the Command Prompt, change the current directory to the directory containing the Hex file. This can be done using command: CD <address of the directory>. Now reset the Arduino and instantly run the command: : avrdude -v -p atmega32u4 -c avr109 -P COM20 -b 57600 -D -Uflash:w:Keyboard.hex:i after replacing the COM Port with the recognized one.
If the uploading process is successful, on connecting the Arduino Pro Micro with PC, it will be shown as HID Keyboard in the Device Manager. There is no need of installing any driver in the computer as Generic HID Keyboard driver is used for the project implementation. Use the buttons on transmitter circuit to test the project working as wireless keyboard.
In the next project – Atmega 32u4 Based Wireless Mouse, learn how to make a wireless mouse after making this wireless keyboard.
Project Source Code
###
/* LUFA Library Copyright (C) Dean Camera, 2015. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaims all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. */ /** file * * Main source file for the Keyboard demo. This file contains the main tasks of * the demo and is responsible for the initial application hardware configuration. */ #include "Keyboard.h" #include "uart.h" /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */ static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)]; /** LUFA HID Class driver interface configuration and state information. This structure is * passed to all HID Class driver functions, so that multiple instances of the same class * within a device can be differentiated from one another. */ USB_ClassInfo_HID_Device_t Keyboard_HID_Interface = { .Config = { .InterfaceNumber = INTERFACE_ID_Keyboard, .ReportINEndpoint = { .Address = KEYBOARD_EPADDR, .Size = KEYBOARD_EPSIZE, .Banks = 1, }, .PrevReportINBuffer = PrevKeyboardHIDReportBuffer, .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer), }, }; //variable to hold received keycode volatile uint8_t keycode_received = 0; //variable to hold received modifier keys data volatile uint8_t modifier_keys_received = 0; // counter variable to indicate the position of byte volatile bool counter = 0; /** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { SetupHardware(); /* enable the uart communication * with 57600 bps */ uart_init(16); //LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); GlobalInterruptEnable(); for (;;) { HID_Device_USBTask(&Keyboard_HID_Interface); USB_USBTask(); } } /** Configures the board hardware and chip peripherals for the demo's functionality. */ void SetupHardware() { #if (ARCH == ARCH_AVR8) /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); /* Disable clock division */ clock_prescale_set(clock_div_1); #elif (ARCH == ARCH_XMEGA) /* Start the PLL to multiply the 2MHz RC oscillator to 32MHz and switch the CPU core to run from it */ XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU); XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL); /* Start the 32MHz internal RC oscillator and start the DFLL to increase it to 48MHz using the USB SOF as a reference */ XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ); XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB); PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; #endif /* Hardware Initialization */ //Joystick_Init(); //LEDs_Init(); //Buttons_Init(); USB_Init(); } /** Event handler for the library USB Connection event. */ void EVENT_USB_Device_Connect(void) { //LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); } /** Event handler for the library USB Disconnection event. */ void EVENT_USB_Device_Disconnect(void) { //LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); } /** Event handler for the library USB Configuration Changed event. */ void EVENT_USB_Device_ConfigurationChanged(void) { bool ConfigSuccess = true; ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface); USB_Device_EnableSOFEvents(); //LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); } /** Event handler for the library USB Control Request reception event. */ void EVENT_USB_Device_ControlRequest(void) { HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); } /** Event handler for the USB device Start Of Frame event. */ void EVENT_USB_Device_StartOfFrame(void) { HID_Device_MillisecondElapsed(&Keyboard_HID_Interface); } /** HID class driver callback function for the creation of HID reports to the host. * * param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature * param[out] ReportData Pointer to a buffer where the created report should be stored * param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) * * return Boolean c true to force the sending of the report, c false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize) { USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; /* if Keycode is received * add the received keycode in data report */ if(keycode_received) { KeyboardReport->KeyCode[0] = keycode_received; keycode_received = 0; } /* if modifier keys is received * add the received modifier keys in data report */ if(modifier_keys_received) { KeyboardReport->Modifier = modifier_keys_received; modifier_keys_received = 0; } *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; } /** HID class driver callback function for the processing of HID reports from the host. * * param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * param[in] ReportID Report ID of the received report from the host * param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature * param[in] ReportData Pointer to a buffer where the received report has been stored * param[in] ReportSize Size in bytes of the received HID report */ void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, const uint8_t ReportType, const void* ReportData, const uint16_t ReportSize) { } /* Interrupt Service Routine to capture the Serially received data * Store the received daa into corresponding variables */ ISR(USART1_RX_vect) { /* if this is the zeroth byte of the data packet * store the keycode and update the counter * else, it is the first byte * store the modifier keys */ if(counter == 0) { keycode_received = UDR1; // get data from rx counter = 1; // update counter } else { modifier_keys_received = UDR1; // get data from rx counter = 0; // update counter } }###
Circuit Diagrams
Circuit-Diagram-Receiver-Arduino-Based-Wireless-USB-Keyboard | |
Circuit-Diagram-Arduino-Based-Wireless-USB-Keyboard |
Project Datasheet
Project Video
Filed Under: Electronic Projects
Filed Under: Electronic Projects
Questions related to this article?
👉Ask and discuss on Electro-Tech-Online.com and EDAboard.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.