树莓派通过C语言读取USB键盘输入的技术咨询
Hey there! I've worked through similar setups on Raspbian before, so let's walk through how to read USB keyboard input in C and send it over serial to your computer. Here's what you need to know:
1. First, Locate Your USB Keyboard Device
On Linux (including Raspbian), USB keyboards show up as input devices under /dev/input/. To find the exact path for your keyboard:
- Run
ls /dev/input/by-id/in the terminal - Look for an entry with
event-kbdin the name (e.g.,usb-Logitech_USB_Keyboard-event-kbd) - Copy this path—you'll need it in your code later.
2. C Code to Read Keyboard Input & Send Over Serial
Linux uses input_event structures to handle input device events. We'll open the keyboard device file, read these events, map keycodes to readable characters, and send them over serial to your computer.
Here's a complete, ready-to-use code example:
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <linux/input.h> #include <unistd.h> #include <string.h> #include <termios.h> int serial_fd = -1; // Map Linux keycodes to ASCII characters (expand this as needed) char keycode_to_char(int keycode, int shift_pressed) { switch(keycode) { case KEY_A: return shift_pressed ? 'A' : 'a'; case KEY_B: return shift_pressed ? 'B' : 'b'; case KEY_C: return shift_pressed ? 'C' : 'c'; case KEY_1: return shift_pressed ? '!' : '1'; case KEY_2: return shift_pressed ? '@' : '2'; case KEY_ENTER: return '\n'; case KEY_SPACE: return ' '; case KEY_BACKSPACE: return '\b'; // Add more key mappings from /usr/include/linux/input.h default: return 0; // Ignore unhandled keys } } // Initialize serial port for communication with your computer void init_serial() { // Use /dev/ttyAMA0 or /dev/ttyS0 depending on your Pi model serial_fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); if (serial_fd == -1) { perror("Failed to open serial port"); exit(EXIT_FAILURE); } struct termios serial_options; tcgetattr(serial_fd, &serial_options); // Configure serial settings: 9600 baud, 8N1 (8 bits, no parity, 1 stop bit) cfsetispeed(&serial_options, B9600); cfsetospeed(&serial_options, B9600); serial_options.c_cflag &= ~PARENB; serial_options.c_cflag &= ~CSTOPB; serial_options.c_cflag &= ~CSIZE; serial_options.c_cflag |= CS8; serial_options.c_cflag &= ~CRTSCTS; // Disable hardware flow control serial_options.c_cflag |= CREAD | CLOCAL; // Enable receiver, ignore modem controls serial_options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Disable canonical mode serial_options.c_oflag &= ~OPOST; // Disable output processing tcsetattr(serial_fd, TCSANOW, &serial_options); } // Send a character over serial void send_over_serial(char c) { if (serial_fd == -1) { init_serial(); } write(serial_fd, &c, 1); } int main() { // Replace this path with your keyboard's path from step 1 const char* keyboard_path = "/dev/input/by-id/usb-Your_Keyboard_Model-event-kbd"; int keyboard_fd = open(keyboard_path, O_RDONLY); if (keyboard_fd == -1) { perror("Failed to open keyboard device"); exit(EXIT_FAILURE); } struct input_event event; int shift_active = 0; printf("Reading keyboard input... Press Ctrl+C to exit.\n"); while (1) { ssize_t bytes_read = read(keyboard_fd, &event, sizeof(struct input_event)); if (bytes_read == -1) { perror("Failed to read input event"); close(keyboard_fd); exit(EXIT_FAILURE); } // Only process key press/release events if (event.type == EV_KEY) { // Update shift state if (event.code == KEY_LEFTSHIFT || event.code == KEY_RIGHTSHIFT) { shift_active = (event.value == 1); // 1 = pressed, 0 = released } // Handle key press (ignore release events for simplicity) else if (event.value == 1) { char input_char = keycode_to_char(event.code, shift_active); if (input_char != 0) { printf("Sent: %c\n", input_char); send_over_serial(input_char); } } } } close(keyboard_fd); close(serial_fd); return 0; }
3. Compile and Run the Code
- Save the code as
keyboard_serial.c - Compile it with:
gcc keyboard_serial.c -o keyboard_serial - Run it with sudo (input devices and serial ports require root access):
sudo ./keyboard_serial
4. Critical Setup Tips
- Serial Port Configuration:
- Open
raspi-config-> Interface Options -> Serial - Select "No" when asked if you want a login shell over serial
- Select "Yes" to enable the serial port hardware
- Reboot your Pi for changes to take effect
- Open
- Permissions (Optional): To avoid using sudo every time, add your user to the
inputanddialoutgroups:
Log out and back in for the group changes to apply.sudo usermod -aG input pi sudo usermod -aG dialout pi - Expand Key Mappings: Check all available keycodes with
cat /usr/include/linux/input.hand add more entries to thekeycode_to_charfunction as needed.
内容的提问来源于stack exchange,提问作者Ricardo Luis
相关产品推荐
相关产品推荐

