由于我在电机反转时更换了电机控制器,因此它不会制动...
向前移动,很好,只要我按住控制台应用程序上的按钮就可以运行。 向左/向右转动,正在反转的电机将不停地运转。 向后移动,两者都会不停地运行。
// Firmware for the Android Shield Board for tank robots
// Pan/tilt servos now work: 0 pin off, 255 pin on, 1~254 8 bit granularity servo movement (5 microseconds).
#define PwmPinMotorA 11
#define PwmPinMotorB 6
#define DirectionPinMotorA 3
#define DirectionPinMotorB 5
#define ServoPin1 0
#define ServoPin2 0
#define ServoFlip1 false
#define ServoFlip2 false
#define mySerialSpeed 9600 // arduino 2009: 4800 or lower!
#define debugSerialSpeed 9600 // arduino 2009: 4800 or lower!
#define BufferLength 16
#define LineEnd1 13
#define LineEnd2 10
#define ServoTimingStep 5
#define ServoCenter 1500
#define ServoTimingFloor ServoCenter-(127*ServoTimingStep)
//#define serialout
#define debugout
#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 255); // rx only
char charin = 80;
char inputBuffer[BufferLength];
int value = 128;
int speed = 128;
int timer = 15;
int timermax = 15;
int inputLength = 0;
int servoval1 = 127;
int servoval2 = 127;
int tempval1, tempval2;
void setup()
{
// motor pins must be outputs
pinMode(PwmPinMotorA, OUTPUT);
pinMode(PwmPinMotorB, OUTPUT);
pinMode(DirectionPinMotorA, OUTPUT);
pinMode(DirectionPinMotorB, OUTPUT);
mySerial.begin(mySerialSpeed);
#ifdef debugout
Serial.begin(debugSerialSpeed);
#endif
}
// process a command string
void HandleCommand(char* input, int length)
{
#ifdef debugout
Serial.print(">");
Serial.print(input);
Serial.print("<");
Serial.print(length);
Serial.println("|");
#endif
if (length < 1) { // not a valid command
return;
}
// calculate number following command (d10~d255)
if (length > 1) {
value = atoi(&input[1]);
if (value > 255)
value = 255;
if (value < 0)
value = 0;
switch(input[0])
{
case 'd':
case 'D':
if (value > 127)
value = 127;
speed = value*2;
break;
case '/':
timermax = value;
break;
case 'c':
case 'C':
#ifdef ServoFlip1
servoval1 = 256 - value;
#else
servoval1 = value;
#endif
break;
case 'v':
case 'V':
#ifdef ServoFlip2
servoval2 = 256 - value;
#else
servoval2 = value;
#endif
break;
default:
break;
}
}
timer = timermax;
int* command = (int*)input;
// check commands
// note that the two bytes are swapped, ie 'RA' means command AR
switch(*command) {
case '2':
case '2j':
case '2J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, LOW);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, HIGH);
break;
case '8':
case '8j':
case '8J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, HIGH);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, LOW);
break;
case '6':
case '6j':
case '6J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, HIGH);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, HIGH);
break;
case '4':
case '4j':
case '4J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, LOW);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, LOW);
break;
case '9':
case '9j':
case '9J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, HIGH);
break;
case '1':
case '1j':
case '1J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, LOW);
break;
case '3':
case '3j':
case '3J':
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, HIGH);
break;
case '7':
case '7j':
case '7J':
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, LOW);
break;
default: // stop, just to be safe
analogWrite(PwmPinMotorA, 0);
digitalWrite(DirectionPinMotorA, LOW);
analogWrite(PwmPinMotorB, 0);
digitalWrite(DirectionPinMotorB, LOW);
break;
}
}
void loop()
{
// get a command string form the mySerial port
inputLength = 0;
do {
while (!mySerial.available()){
// note: arduino cannot handle fullduplex on myserial so no output here!
// do servos here
tempval1 = (servoval1*ServoTimingStep) + ServoTimingFloor;
tempval2 = (servoval2*ServoTimingStep) + ServoTimingFloor;
if (servoval1 > 0)
digitalWrite(ServoPin1,HIGH);
delayMicroseconds(tempval1);
if (servoval1 < 255)
digitalWrite(ServoPin1,LOW);
if (servoval2 > 0)
digitalWrite(ServoPin2,HIGH);
delayMicroseconds(tempval2);
if (servoval2 < 255)
digitalWrite(ServoPin2,LOW);
delayMicroseconds(5000 - tempval1 - tempval2);
delay(15); // reduce/remove if we're doing more things here
// decrease the timer
if (--timer < 0)
{
timer=0;
analogWrite(PwmPinMotorA, 0);
analogWrite(PwmPinMotorB, 0);
}
};
// wait for input
{
charin = mySerial.read(); // read it in
#ifdef debugout
Serial.print(charin);
tempval1 = charin;
Serial.println(tempval1);
#endif
if ((charin > 46 && charin < 58) || (charin=='d') || (charin=='j') || (charin=='c') || (charin=='v'))
{
inputBuffer[inputLength]=charin;
inputLength++;
#ifdef serialout
mySerial.print("$PD,11,");
mySerial.print(timer);
mySerial.print(",");
mySerial.print(value);
mySerial.println("*");
#endif
}
}
}
while (charin>46 && charin<119 && charin != LineEnd1 && charin != LineEnd2 && inputLength < BufferLength);
inputBuffer[inputLength] = 0; // add null terminator
HandleCommand(inputBuffer, inputLength);
}
答案 0 :(得分:2)
我在Arduino 1.0中编译了你的代码,并在我的Pro Mini 16MHz 328上进行了这些修改:
//#define debugout
HardwareSerial mySerial = Serial;
并在我的Mega 16MHz 2560上进行了这些修改:
#define PwmPinMotorA 7
//#define debugout
HardwareSerial mySerial = Serial;
它似乎工作正常(根据我的示波器上的代码和结果判断)。
我一直在使用SoftwareSerial与我的GPS通信,我注意到如果我以9600波特率运行它会有奇怪的错误。我必须在4800运行以获得无缝通信。
显然这并不能解释为什么你的--timer&lt; 0会被忽略。我建议重写它,以便定时器功能总是像:
unsigned long timeout = 2000; // 2 seconds
unsigned long clrtime = 0;
boolean timecheck = false;
// ... upon command set the event
clrtime = millis() + timeout;
timecheck = true;
// ... every loop check for event
if (timecheck && millis() > clrtime)
{
timecheck = false;
analogWrite(PwmPinMotorA, 0);
analogWrite(PwmPinMotorB, 0);
}
这是一种处理定时事件的更安全的方法。注意不要覆盖Timer0,Arduino用于delay(),delayMicroseconds(),micros()和millis()。我还建议交换引脚3和6以保持Timer2作为两者的来源。这是我测试的最终代码:
// Firmware for the Android Shield Board for tank robots
// Pan/tilt servos now work: 0 pin off, 255 pin on, 1~254 8 bit granularity
// servo movement (5 microseconds).
// Required Libraries //////////////////////////////////////////////////////////
// Pin Mapping /////////////////////////////////////////////////////////////////
// Arduino 3 [PD3](INT1/OC2B) OC2B (Timer/Counter2 Output Compare Match B Output)
// Arduino 4 [PD4](XCK/T0) T0 (Timer/Counter 0 External Counter Input)
// Arduino 5 [PD5](T1/OC0B) T1 (Timer/Counter 1 External Counter Input)
// OC0B (Timer/Counter0 Output Compare Match B Output)
// Arduino 6 [PD6](AIN0/OC0A) OC0A (Timer/Counter0 Output Compare Match A Output)
// Arduino 8 [PB0](ICP/CLKO) ICP1 (Timer/Counter1 Input Capture Input)
// Arduino 9 [PB1](OC1A) OC1A (Timer/Counter1 Output Compare Match A Output)
// Arduino 10 [PB2](SS/OC1B) OC1B (Timer/Counter1 Output Compare Match B Output)
// Arduino 11 [PB3](MOSI/OC2) OC2A (Timer/Counter2 Output Compare Match A Output)
#define PwmPinMotorA 11
#define PwmPinMotorB 3 // SWAPPED!
#define DirectionPinMotorA 6 // SWAPPED!
#define DirectionPinMotorB 5
#define ServoPin1 0
#define ServoPin2 0
#define ServoFlip1 false
#define ServoFlip2 false
// Global Macros ///////////////////////////////////////////////////////////////
#define mySerialSpeed 9600 // arduino 2009: 4800 or lower!
#define debugSerialSpeed 9600 // arduino 2009: 4800 or lower!
#define BufferLength 16
#define LineEnd1 13
#define LineEnd2 10
#define ServoTimingStep 5
#define ServoCenter 1500
#define ServoTimingFloor ServoCenter-(127*ServoTimingStep)
// Global Variables ////////////////////////////////////////////////////////////
HardwareSerial mySerial = Serial;
char charin = 80;
char inputBuffer[BufferLength];
int value = 128;
int speed = 128;
int inputLength = 0;
int servoval1 = 127;
int servoval2 = 127;
int tempval1, tempval2;
unsigned long timeout = 2000; // 2 seconds
unsigned long clrtime = 0;
boolean timecheck = false;
// Hardware Setup //////////////////////////////////////////////////////////////
void setup()
{
// motor pins must be outputs
pinMode(PwmPinMotorA, OUTPUT);
pinMode(PwmPinMotorB, OUTPUT);
pinMode(DirectionPinMotorA, OUTPUT);
pinMode(DirectionPinMotorB, OUTPUT);
mySerial.begin(mySerialSpeed);
}
// setup()
// Main Code ///////////////////////////////////////////////////////////////////
void loop()
{
// get a command string form the mySerial port
inputLength = 0;
do {
while (!mySerial.available()){
// note: arduino cannot handle fullduplex on myserial so no output here!
// do servos here
tempval1 = (servoval1*ServoTimingStep) + ServoTimingFloor;
tempval2 = (servoval2*ServoTimingStep) + ServoTimingFloor;
if (servoval1 > 0)
digitalWrite(ServoPin1,HIGH);
delayMicroseconds(tempval1);
if (servoval1 < 255)
digitalWrite(ServoPin1,LOW);
if (servoval2 > 0)
digitalWrite(ServoPin2,HIGH);
delayMicroseconds(tempval2);
if (servoval2 < 255)
digitalWrite(ServoPin2,LOW);
delayMicroseconds(5000 - tempval1 - tempval2);
delay(15); // reduce/remove if we're doing more things here
// handle the timeout
if (timecheck && millis() > clrtime)
{
timecheck = false;
analogWrite(PwmPinMotorA, 0);
analogWrite(PwmPinMotorB, 0);
}
};
// wait for input
{
charin = mySerial.read(); // read it in
if ((charin > 46 && charin < 58) || (charin=='d') ||
(charin=='j') || (charin=='c') || (charin=='v'))
{
inputBuffer[inputLength]=charin;
inputLength++;
}
}
}
while (charin>46 && charin<119 && charin != LineEnd1 &&
charin != LineEnd2 && inputLength < BufferLength);
inputBuffer[inputLength] = 0; // add null terminator
HandleCommand(inputBuffer, inputLength);
}
// loop()
// Local Methods ///////////////////////////////////////////////////////////////
// process a command string
void HandleCommand(char* input, int length)
{
if (length < 1) { // not a valid command
return;
}
// calculate number following command (d10~d255)
if (length > 1) {
value = atoi(&input[1]);
if (value > 255)
value = 255;
if (value < 0)
value = 0;
switch(input[0])
{
case 'd':
case 'D':
if (value > 127)
value = 127;
speed = value*2;
break;
case '/':
timeout = 100 * value;
break;
case 'c':
case 'C':
#ifdef ServoFlip1
servoval1 = 256 - value;
#else
servoval1 = value;
#endif
break;
case 'v':
case 'V':
#ifdef ServoFlip2
servoval2 = 256 - value;
#else
servoval2 = value;
#endif
break;
default:
break;
}
}
clrtime = millis() + timeout;
timecheck = true;
int* command = (int*)input;
// check commands
// note that the two bytes are swapped, ie 'RA' means command AR
switch(*command) {
case '2':
case '2j':
case '2J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, LOW);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, HIGH);
break;
case '8':
case '8j':
case '8J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, HIGH);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, LOW);
break;
case '6':
case '6j':
case '6J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, HIGH);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, HIGH);
break;
case '4':
case '4j':
case '4J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, LOW);
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, LOW);
break;
case '9':
case '9j':
case '9J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, HIGH);
break;
case '1':
case '1j':
case '1J':
analogWrite(PwmPinMotorB, speed);
digitalWrite(DirectionPinMotorB, LOW);
break;
case '3':
case '3j':
case '3J':
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, HIGH);
break;
case '7':
case '7j':
case '7J':
analogWrite(PwmPinMotorA, speed);
digitalWrite(DirectionPinMotorA, LOW);
break;
default: // stop, just to be safe
analogWrite(PwmPinMotorA, 0);
digitalWrite(DirectionPinMotorA, LOW);
analogWrite(PwmPinMotorB, 0);
digitalWrite(DirectionPinMotorB, LOW);
break;
}
}
因为我不能导致同样的错误,我无法判断这是否解决了问题。祝你好运。