Raspbian环境下实现ttyUSB0连接时自动执行指定命令
Got it, let's work through this problem properly. The most reliable way to handle automatic actions when a USB device is plugged/unplugged on Raspbian is using udev rules—it's Linux's native tool for responding to device events, perfect for your use case.
Step 1: Identify Your Arduino's Unique Device Attributes
First, we need to target your specific Arduino (not just any /dev/ttyUSB0, which can shift if you plug in other serial devices). Here's how to get its unique IDs:
Plug in your Arduino, then run this command in the terminal:
lsusbLook for a line like this (yours might have a different ID, depending on your Arduino model):
Bus 001 Device 005: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
The two hex numbers here (2341and0043) are your Arduino's Vendor ID (VID) and Product ID (PID)—we'll use these to create a precise udev rule.To confirm, you can also run this command to get more detailed udev attributes:
udevadm info -a -n /dev/ttyUSB0 | grep -E "(SUBSYSTEM|ATTRS{idVendor}|ATTRS{idProduct})"This will show you the exact attributes udev uses to recognize your device, so we can match them perfectly.
Step 2: Create a Udev Rule File
Udev rules live in /etc/udev/rules.d/. Let's create a custom rule for your Arduino:
Open a text editor with root privileges (e.g., nano):
sudo nano /etc/udev/rules.d/99-arduino-auto-config.rulesPaste in the following rule (replace
2341and0043with your Arduino's VID/PID from Step 1):SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0043", \ SYMLINK+="arduino", \ RUN+="/usr/local/bin/arduino_post_connect.sh"SYMLINK+="arduino"creates a fixed/dev/arduinolink that points to your Arduino's serial port (even if/dev/ttyUSB0changes tottyUSB1later—super useful for your program to reference a stable path).RUN+="/usr/local/bin/arduino_post_connect.sh"tells udev to run our custom script whenever the device connects.
Save and exit nano (Ctrl+O, Enter, Ctrl+X).
Step 3: Write the Post-Connect Script
Now we need to create the script that resets the baud rate and restarts your program. Let's put it in /usr/local/bin/ (a standard spot for custom scripts):
Create the script file:
sudo nano /usr/local/bin/arduino_post_connect.shPaste in this template (adjust the values to match your setup):
#!/bin/bash # Wait a second to make sure the device is fully initialized sleep 1 # Set the desired baud rate (replace 115200 with your needed rate) stty -F /dev/arduino 115200 cs8 -cstopb -parenb # Restart your dependent program—choose one of the options below: # Option 1: If your program runs as a systemd service (recommended for persistent programs) # systemctl restart my_arduino_program.service # Option 2: If your program runs as a regular user process (replace "pi" with your username, and the path/command) # su - pi -c "pkill -f 'my_program_executable' && /home/pi/path/to/my_program_executable &" # Option 3: If you just need to start it (no need to kill first) # su - pi -c "/home/pi/path/to/my_program_executable &"- The
sleep 1is important—sometimes the device isn't fully ready immediately after plugging in, so adding a short delay prevents errors. - The
sttycommand sets the serial port parameters: adjust115200to your required baud rate, and tweak other flags if needed (cs8 = 8 data bits, -cstopb = 1 stop bit, -parenb = no parity). - Choose the right restart method for your program: systemd is the most robust way to manage persistent programs on Raspbian.
- The
Save and exit, then make the script executable:
sudo chmod +x /usr/local/bin/arduino_post_connect.sh
Step 4: Test the Setup
Now let's activate the udev rule and test it:
- Reload the udev rules to apply changes:
sudo udevadm control --reload-rules && sudo udevadm trigger - Unplug your Arduino, then plug it back in. Check:
- Does
/dev/arduinoexist? Runls -l /dev/arduinoto confirm it links to your ttyUSB device. - Is your program restarted? Check its process status (e.g.,
systemctl status my_arduino_program.serviceif using systemd). - Did the baud rate get set correctly? Run
stty -F /dev/arduinoto verify.
- Does
Troubleshooting Tips
- If the script doesn't run, check udev logs with
dmesg | grep udevto see error messages. - Make sure all paths in the script are absolute (e.g.,
/home/pi/programinstead ofprogram)—udev runs with a minimal environment, so relative paths might not work. - If your program runs as a non-root user, use
su - [username] -c "command"to avoid permission issues.
内容的提问来源于stack exchange,提问作者tofgau

