Arduino USART通信与直流电机控制故障排查求助
Let's break down your problems one by one and fix them step by step:
1. DC Motors Not Responding (But Indicator Lights Work)
The fact that your indicators toggle correctly means your serial communication is working, so the issue is likely tied to motor wiring or code oversight:
- H-Bridge Power & Wiring Checks
- Motors draw way more current than Arduino's 5V pin can supply—make sure your H-bridge is connected to an external power source (matching your motor's voltage) and that the H-bridge's GND is tied to Arduino's GND (common ground is critical for signal integrity).
- Double-check pin mappings: Ensure
in3,in4, anden2are wired to the correct control pins on your H-bridge for Motor B.
- Pin Initialization Gap
While you initialized Motor B's pins insetup(), you left out Motor A's pins. Even if you're not using it yet, it's good practice to add these lines to avoid confusion later:pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(en1, OUTPUT); - Test Motor/H-Bridge Hardware
Isolate the motor and H-bridge with a simple test sketch to rule out hardware failures:
If the motor still doesn't run, your H-bridge or motor is faulty.void setup() { pinMode(6, OUTPUT); // in3 pinMode(5, OUTPUT); // in4 pinMode(3, OUTPUT); // en2 } void loop() { digitalWrite(6, LOW); digitalWrite(5, HIGH); analogWrite(3, 127); // 50% speed delay(2000); digitalWrite(6, HIGH); digitalWrite(5, LOW); delay(2000); }
2. Slow Data Transfer After Adding Motor Code
This is a classic issue caused by blocking code—your demo1() function uses delay(5000) twice, which freezes the Arduino for 10 seconds every time it runs. During this period, the board can't process incoming serial data, leading to backed-up buffers and perceived slow transfer speeds.
Fix: Replace Blocking delay() with Non-Blocking Logic
Use millis() to track time without halting the main loop. Here's how to refactor your code:
First, add global variables to track motor state and timing:
unsigned long previousMillis = 0; const long motorInterval = 5000; int motorState = 0; // 0 = stopped, 1 = forward, 2 = reverse
Then rewrite your loop() function to handle serial data and motor control without blocking:
void loop() { // Always prioritize serial data first if (port1.available() > 0){ Serial.println("Data from other Arduino:"); data = port1.read(); Serial.println(data); if (data == '1') { // Start motor cycle: forward first motorState = 1; previousMillis = millis(); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); analogWrite(en2, 250); } else { // Stop motor immediately motorState = 0; stopMotor(); } } // Non-blocking motor state switching if (motorState != 0) { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= motorInterval) { previousMillis = currentMillis; if (motorState == 1) { // Switch to reverse digitalWrite(in3, HIGH); digitalWrite(in4, LOW); motorState = 2; } else if (motorState == 2) { // End cycle, stop motor motorState = 0; stopMotor(); } } } }
You can now delete the original demo1() function, as its logic is integrated into the non-blocking loop. This way, your Arduino will always be ready to read incoming serial data while managing motor timing in the background.
Extra Optimizations
- Improve Serial Reliability: Add a simple frame format (e.g., start/end characters like
<and>) to your data to avoid misreading partial bytes as valid commands. - Enhance Motor Stop Safety: Update your
stopMotor()function to disable PWM output too:void stopMotor() { digitalWrite(in3, LOW); digitalWrite(in4, LOW); analogWrite(en2, 0); // Cut power to motor } - SoftwareSerial Limitation: Remember that Arduino's SoftwareSerial can only listen to one port at a time. Your current send-side code uses
BT1.listen()which is correct for your use case, but keep this in mind if you expand the project later.
内容的提问来源于stack exchange,提问作者Dominik

