Zuerst mal ein glückliches, erfolgreiches und gesundes neues Jahr!
Zu meinem Problem. Ich habe einen kleinen Roboter der über I2C Daten austauscht. Dies funktioniert alles problemlos. Sobald ich nun einen Motorcontroller über die hardware serielle TX/RX ansteuern möchte, dann friert mir alles ein, sprich der Sende Arduino Mega und dieser Empfangs Arduino Uno bleiben hängen und machen bis zu einem Neustart/Reset nichts mehr.
Ohne die serielle TX/RX Verbindung funktioniert es, sprich auch wenn diese angeschlossen ist, aber keine Befehle darüber gesendet werden funktioniert alles.
Es wird alles von einem Akku mit Strom versorgt. Die TX/RX und GND Leitungen gehen vom Uno an den Motorcontroller. Der Mega ist über SCL/SDA und GND mit dem Uno verbunden. Motorcontroller wäre ein Roboclaw 2x7A falls das benötigt wird.
Ich habe was gelesen, dass bei Interrupts solche Probleme auftreten können, wenn mehrere Libs solche verwenden. Weiss hier jemand mehr darüber oder findet hier das Problem wieso mir direkt alles einfriert sobald ich die Motoren über TX/RX ansteuere?
Hier ist der Problemcode des Empfänger Unos mit der TX/RX Nutzung:
/**SETTINGS**/
const unsigned long Baudrate = 38400; //starts serial port for Roboclaw with a baudrate by 38400 b/s
const byte ArduBody = 0x2A; //I2C address for the Arduino UNO, body
const byte address = 0x80; //address for Roboclaw from feet motors, address 128
const byte addressDD = 0x82; //address for Roboclaw from dome motor, address 130
const byte SpeedBP = 30; //set the speed for body panels 1-5 (0=full speed, 1-255 slower to faster)
const byte SpeedUAL = 30; //set the speed for arm left (0=full speed, 1-255 slower to faster)
const byte SpeedUAR = 30; //set the speed for arm right (0=full speed, 1-255 slower to faster)
const byte SpeedDD = 80; //set the speed for dome drive (127=full speed, 0-127 slower to faster)
const byte SpeedFDLR = 100; //set the maximum, normal speed for foot drive left/right (0=stop, 127=full speed, 0-127 slower to faster)
const byte SpeedFDUD = 100; //set the maximum, normal speed for foot drive forward/backward (0=stop, 127=full speed, 0-127 slower to faster)
const byte SpeedFDLRfast = 120; //set the maximum, fast speed for foot drive left/right (if joystick is pressed down) (0=stop, 127=full speed, 0-127 slower to faster)
const byte SpeedFDUDfast = 120; //set the maximum, fast speed for foot drive forward/backward (if joystick is pressed down) (0=stop, 127=full speed, 0-127 slower to faster)
const unsigned long BPservoMin = 900; //set minimum pulse length in microseconds for body panels
const unsigned long BPservoMax = 2100; //set maximum pulse length in microseconds for body panels
const unsigned long UAservoMin = 900; //set minimum pulse length in microseconds for arms
const unsigned long UAservoMax = 2100; //set maximum pulse length in microseconds for arms
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
//Definition of pinnumbers
const byte BodyPanel1 = 7; //Body panel 1 connected to pin D7
const byte BodyPanel2 = 8; //Body panel 2 connected to pin D8
const byte BodyPanel3 = 9; //Body panel 3 connected to pin D9
const byte BodyPanel4 = 10; //Body panel 4 connected to pin D10
const byte BodyPanel5 = 11; //Body panel 5 connected to pin D11
const byte ArmL = 5; //arm left connected to pin D5
const byte ArmR = 6; //arm right connected to pin D6
//Definition of designations for reading signals (signals to be received)
byte BP1 = 0; //Bodypanel 1
byte BP2 = 0; //Bodypanel 2
byte BP3 = 0; //Bodypanel 3
byte BP4 = 0; //Bodypanel 4
byte BP5 = 0; //Bodypanel 5
byte UAL = 0; //arm left
byte UAR = 0; //arm right
byte DD = 0; //Dome drive
byte FDLR = 0; //Foot drive left/right
byte FDUD = 0; //Foot drive forward/backward
byte joybut = 0; //Foot drive joystick-button
byte BUT4 = 0; //Button 4
byte BUT8 = 0; //Button 8
byte BUT12 = 0; //Button 12
byte BUT20 = 0; //Button 20
//Definition of designations for storing signals (cache)
byte data[5]; //create array for packet serial (feet and dome motors)
uint16_t crc = 0; //checksum crc
volatile byte dataReceived[2]; //byte array for received data over I2C
bool newData; //check for new data received
byte lastBP1 = 0; //last status from body panel 1
byte lastBP2 = 0; //last status from body panel 2
byte lastBP3 = 0; //last status from body panel 3
byte lastBP4 = 0; //last status from body panel 4
byte lastBP5 = 0; //last status from body panel 5
byte lastUAL = 0; //last status from arm left
byte lastUAR = 0; //last status from arm right
byte lastDD = 0; //last status from dome drive
byte lastFDLR = 0; //last status from foot drive, left/right
byte lastFDUD = 0; //last status from foot drive, forward/backward
byte mapFDLR = 0; //converted value FDLR (foot drive left/right) for the dc motor
byte mapFDUD = 0; //converted value FDUD (foot drive forward/backward)( for the dc motor
byte mapDD = 0; //converted value DD (dome drive left/right) for the dc motor
#include <VarSpeedServo.h> //adds library to control servos
#include <Wire.h> //adds library for I2C
//create servo object (maximum 8)
VarSpeedServo servoBP1; //create servo body panel 1
VarSpeedServo servoBP2; //create servo body panel 2
VarSpeedServo servoBP3; //create servo body panel 3
VarSpeedServo servoBP4; //create servo body panel 4
VarSpeedServo servoBP5; //create servo body panel 5
VarSpeedServo servoUAL; //create servo arm left
VarSpeedServo servoUAR; //create servo arm right
void setup() {
Wire.begin(ArduBody); //starts I2C bus as slave on address ArduBody
Wire.onReceive(readCommand); //function to trigger when something is received over I2C
Serial.begin(Baudrate); //starts serial port with a baudrate by "Baudrate" (b/s)
//attach the servos
servoBP1.attach(BodyPanel1,BPservoMin,BPservoMax); //servoBP1 is attached to pin BodyPanel1 with pulse length BPservoMin and BPservoMax
servoBP2.attach(BodyPanel2,BPservoMin,BPservoMax); //servoBP2 is attached to pin BodyPanel2 with pulse length BPservoMin and BPservoMax
servoBP3.attach(BodyPanel3,BPservoMin,BPservoMax); //servoBP3 is attached to pin BodyPanel3 with pulse length BPservoMin and BPservoMax
servoBP4.attach(BodyPanel4,BPservoMin,BPservoMax); //servoBP4 is attached to pin BodyPanel4 with pulse length BPservoMin and BPservoMax
servoBP5.attach(BodyPanel5,BPservoMin,BPservoMax); //servoBP5 is attached to pin BodyPanel5 with pulse length BPservoMin and BPservoMax
servoUAL.attach(ArmL,UAservoMin,UAservoMax); //servoUAL is attached to pin ArmL with pulse length UAservoMin and UAservoMax
servoUAR.attach(ArmR,UAservoMin,UAservoMax); //servoUAR is attached to pin ArmR with pulse length UAservoMin and UAservoMax
//initialization of the dome motor on startup
motor(0,0, addressDD, Serial); //command for forward, stop movement, address, serial port
//initialization of the feet motors on startup
motor(10,0, address, Serial); //command for turn right in mix mode, stop movement, address, serial port
motor(8,0, address, Serial); //command for forward in mix mode, stop movement, address, serial port
}
void loop() {
if(newData == true){ //if new data received is true, then make...
//Utility arms
if(UAL != lastUAL){ //if UAL (arm left) not equal to lastUAL, then make...
servoUAL.slowmove(UAL, SpeedUAL); //servoUAL moves with angle UAL and speed SpeedUAL (0=full speed, 1-255 slower to faster)
lastUAL = UAL; //stores UAL on lastUAL
}
if(UAR != lastUAR){ //if UAR (arm right) not equal to lastUAR, then make...
servoUAR.slowmove(UAR, SpeedUAR); //servoUAR moves with angle UAR and speed SpeedUAR (0=full speed, 1-255 slower to faster)
lastUAR = UAR; //stores UAR on lastUAR
}
//Body panels:
if(BP1 != lastBP1){ //if BP1 (body panel 1) not equal to lastBP1, then make...
servoBP1.slowmove(BP1, SpeedBP); //servoBP1 moves with angle BP1 and speed SpeedBP (0=full speed, 1-255 slower to faster)
lastBP1 = BP1; //stores BP1 on lastBP1
}
if(BP2 != lastBP2){ //if BP2 (body panel 2) not equal to lastBP2, then make...
servoBP2.slowmove(BP2, SpeedBP); //servoBP2 moves with angle BP2 and speed SpeedBP (0=full speed, 1-255 slower to faster)
lastBP2 = BP2; //stores BP2 on lastBP2
}
if(BP3 != lastBP3){ //if BP3 (body panel 3) not equal to lastBP3, then make...
servoBP3.slowmove(BP3, SpeedBP); //servoBP3 moves with angle BP3 and speed SpeedBP (0=full speed, 1-255 slower to faster)
lastBP3 = BP3; //stores BP3 on lastBP3
}
if(BP4 != lastBP4){ //if BP4 (body panel 4) not equal to lastBP4, then make...
servoBP4.slowmove(BP4, SpeedBP); //servoBP4 moves with angle BP4 and speed SpeedBP (0=full speed, 1-255 slower to faster)
lastBP4 = BP4; //stores BP4 on lastBP4
}
if(BP5 != lastBP5){ //if BP5 (body panel 5) not equal to lastBP5, then make...
servoBP5.slowmove(BP5, SpeedBP); //servoBP5 moves with angle BP5 and speed SpeedBP (0=full speed, 1-255 slower to faster)
lastBP5 = BP5; //stores BP5 on lastBP5
}
//Dome drive
if(DD != lastDD){ //if DD (dome drive) not equal to lastDD, then make...
if(DD < 87){ //if DD is between 0 and 90, then make...
mapDD = map(DD, 90, 0, 0, SpeedDD); //read value from DD, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedDD and store it to mapDD
motor(0,mapDD, addressDD, Serial); //command for forward, movement mapDD, address, serial port
}
else if(180 >= DD && DD > 93){ //if DD is between 90 and 180, then make...
mapDD = map(DD, 90, 180, 0, SpeedDD); //read value from DD, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedDD and store it to mapDD
motor(1,mapDD, addressDD, Serial); //command for backward, movement mapDD, address, serial port
}
else if(87 <= DD && DD <= 93){ //if DD is 90, then make...
motor(0,0, addressDD, Serial); //command for forward, stop movement, address, serial port
}
lastDD = DD; //stores DD on lastDD
}
//Foot drive
if(FDLR != lastFDLR && joybut == HIGH){ //if FDLR (foot drive left/right) not equal to lastFDLR and joybut is equal to HIGH (not pressed), then make...
if(FDLR < 87){ //if FDLR is between 0 and 90, then make...
mapFDLR = map(FDLR, 90, 0, 0, SpeedFDLR); //read value from FDLR, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDLR and store it to mapFDLR
motor(10,mapFDLR, address, Serial); //command for turn right in mix mode, movement mapFDLR, address, serial port
}
else if(180 >= FDLR && FDLR > 93){ //if FDLR is between 90 and 180, then make...
mapFDLR = map(FDLR, 90, 180, 0, SpeedFDLR); //read value from FDLR, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDLR and store it to mapFDLR
motor(11,mapFDLR, address, Serial); //command for turn left in mix mode, movement mapFDLR, address, serial port
}
else if(87 <= FDLR && FDLR <= 93){ //if FDLR is 90, then make...
motor(10,0, address, Serial); //command for turn right in mix mode, stop movement, address, serial port
}
lastFDLR = FDLR; //stores FDLR on lastFDLR
}
if(FDLR != lastFDLR && joybut == LOW){ //if FDLR (foot drive left/right) not equal to lastFDLR and joybut is equal to LOW (pressed), then make...
if(FDLR < 87){ //if FDLR is between 0 and 90, then make...
mapFDLR = map(FDLR, 90, 0, 0, SpeedFDLRfast); //read value from FDLR, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDLRfast and store it to mapFDLR
motor(10,mapFDLR, address, Serial); //command for turn right in mix mode, movement mapFDLR, address, serial port
}
else if(180 >= FDLR && FDLR > 93){ //if FDLR is between 90 and 180, then make...
mapFDLR = map(FDLR, 90, 180, 0, SpeedFDLRfast); //read value from FDLR, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDLRfast and store it to mapFDLR
motor(11,mapFDLR, address, Serial); //command for turn left in mix mode, movement mapFDLR, address, serial port
}
else if(87 <= FDLR && FDLR <= 93){ //if FDLR is 90, then make...
motor(10,0, address, Serial); //command for turn right in mix mode, stop movement, address, serial port
}
lastFDLR = FDLR; //stores FDLR on lastFDLR
}
if(FDUD != lastFDUD && joybut == HIGH){ //if FDUD (foot drive forward/backward) not equal to lastFDUD and joybut is equal to HIGH (not pressed), then make...
if(FDUD < 87){ //if FDUD is between 0 and 90, then make...
mapFDUD = map(FDUD, 90, 0, 0, SpeedFDUD); //read value from FDUD, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDUD and store it to mapFDUD
motor(8,mapFDUD, address, Serial); //command for forward in mix mode, movement mapFDUD, address, serial port
}
else if(180 >= FDUD && FDUD > 93){ //if FDUD is between 90 and 180, then make...
mapFDUD = map(FDUD, 90, 180, 0, SpeedFDUD); //read value from FDUD, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDUD and store it to mapFDUD
motor(9,mapFDUD, address, Serial); //command for backward in mix mode, movement mapFDUD, address, serial port
}
else if(87 <= FDUD && FDUD <= 93){ //if FDUD is 90, then make...
motor(8,0, address, Serial); //command for forward in mix mode, stop movement, address, serial port
}
lastFDUD = FDUD; //stores FDUD on lastFDUD
}
if(FDUD != lastFDUD && joybut == LOW){ //if FDUD (foot drive forward/backward) not equal to lastFDUD and joybut is equal to LOW (pressed), then make...
if(FDUD < 87){ //if FDUD is between 0 and 90, then make...
mapFDUD = map(FDUD, 90, 0, 0, SpeedFDUDfast); //read value from FDUD, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDUDfast and store it to mapFDUD
motor(8,mapFDUD, address, Serial); //command for forward in mix mode, movement mapFDUD, address, serial port
}
else if(180 >= FDUD && FDUD > 93){ //if FDUD is between 90 and 180, then make...
mapFDUD = map(FDUD, 90, 180, 0, SpeedFDUDfast); //read value from FDUD, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDUDfast and store it to mapFDUD
motor(9,mapFDUD, address, Serial); //command for backward in mix mode, movement mapFDUD, address, serial port
}
else if(87 <= FDUD && FDUD <= 93){ //if FDUD is 90, then make...
motor(8,0, address, Serial); //command for forward in mix mode, stop movement, address, serial port
}
lastFDUD = FDUD; //stores FDUD on lastFDUD
}
newData = false; //set new data received to false for receiving new data
}
}
//Function for reading a command and store it to designation
void readCommand(int bytes){ //function readCommand takes the length of received data (bytes) from onReceive and make...
if(bytes == 2){ //if bytes is equal to 2 (received bytes), then make...
dataReceived[0] = Wire.read(); //store the first byte from received data over I2C to dataReceived array
dataReceived[1] = Wire.read(); //store the second byte from received data over I2C to dataReceived array
switch(dataReceived[0]){
case 'Q' : BP1 = dataReceived[1]; //if the first byte in the array dataReceived is equal to Q, then store the second byte from the array dataReceived to BP1
break; //finish the command and return
case 'R' : BP2 = dataReceived[1];
break;
case 'S' : BP3 = dataReceived[1];
break;
case 'T' : BP4 = dataReceived[1];
break;
case 'U' : BP5 = dataReceived[1];
break;
case 'V' : UAL = dataReceived[1];
break;
case 'W' : UAR = dataReceived[1];
break;
case 'X' : DD = dataReceived[1];
break;
case 'Y' : FDLR = dataReceived[1];
break;
case 'Z' : FDUD = dataReceived[1];
break;
case 'd' : joybut = dataReceived[1];
break;
case 'h' : BUT4 = dataReceived[1];
break;
case 'l' : BUT8 = dataReceived[1];
break;
case 'p' : BUT12 = dataReceived[1];
break;
case 'x' : BUT20 = dataReceived[1];
break;
}
newData = true;
}
}
//Function for driving the feet and dome motors over serial
void motor(const byte command, const byte value, const byte address, Stream& stream){
data[0] = address; //write address in data array
data[1] = command; //write command for forward/reverse/left/right in data array
data[2] = value; //write movement speed in data array
for(byte index = 0; index < 3; index++){ //create the checksum for the array data[i] with 0 <= i <= 3
crc16(data[index]); //call the function crc16
}
data[3] = crc >> 8; //store checksum in data array
data[4] = crc;
stream.write(data, sizeof(data)); //send the data array by serial
crc = 0; //clear the checksum
}
//Calculates CRC16 of nBytes of data[index] in byte array
void crc16(uint8_t data) {
int i;
crc = crc ^ ((uint16_t)data << 8);
for (i=0; i<8; i++){
if (crc & 0x8000){
crc = (crc << 1) ^ 0x1021;
}
else{
crc <<= 1;
}
}
}
