- This topic has 13 replies, 2 voices, and was last updated 8 years, 7 months ago by RC Tractor Guy.
- AuthorPosts
- September 9, 2015 at 2:42 pm #1134TomekParticipant
As there is a new forum, I decided to move my topic here.
for some time I cannot figure out why, but I have such a problem. There is a strange delay between controller and tractor.When I move joystick from centre to max forward, the weels are speeding up in two – three steps and those steps are related to the packets received by the microcontroller (the time is same to green led blnking)
The controller code is:
#include <SendOnlySoftwareSerial.h>
int ValueX = 0;
int ValueY = 0;
int ValueXsend = 0;
int ValueYsend = 0;
int DiffX;
int DiffY;
int i;
int sensorValueX = 0;
int sensorValueY = 0;
const int histereza_joystick = 1; //bylo 20
const int OffsetX = 0;
const int OffsetY = 0;
boolean SendDataX; //*****************88 skończyć wysyłanie jak będzie komunikacja
boolean SendDataY;
byte wlaczniki = 0;
byte wlacznikiLast = 0;
byte wlaczniki2 = 0;
byte wlaczniki2Last = 0;
byte ID1 = 0x39; //9
byte commandOut;
byte valueOut;
byte dataOut[6];SendOnlySoftwareSerial ExternalSerial(1);
void setup() {
// initialize serial communication at 9600 bits per second:
ExternalSerial.begin(38400);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, INPUT_PULLUP); // kierunek lewy, prawy
pinMode(11, INPUT_PULLUP); // pozycyjne, krótkie
pinMode(12, INPUT_PULLUP); // kabina przód, tył
pinMode(13, INPUT_PULLUP); // awaryjne, kogut
}void loop() {
i = i+1;
if (i>=4000) i=0;//if (i==25) {
// odczyt joystick
sensorValueX = analogRead(A1) + OffsetX;
sensorValueY = analogRead(A0) + OffsetY;
// }
//uwzglednienie histerezy
if (sensorValueX >= ValueX) {
DiffX = sensorValueX – ValueX;
if (DiffX > histereza_joystick){
ValueX = sensorValueX;
}
}
else {
DiffX = ValueX – sensorValueX;
if (DiffX > histereza_joystick){
ValueX = sensorValueX;
}
}if (sensorValueY >= ValueY) {
DiffY = sensorValueY – ValueY;
ValueY = sensorValueY;}
else {
DiffY = ValueY – sensorValueY;
ValueY = sensorValueY;
}/****************************** obsluga włączników ******************************/
//check prog before 09 2015/******************************* obsługa komunikacji ********************************/
dataOut[0] = ID1;
dataOut[1] = 0x42;
dataOut[2] = map(ValueY, 0, 670, 0x00, 0xFF);
if (i==99){
ExternalSerial.write(dataOut,3); //do xbee
// Serial.write(dataOut,6); //do monitoraSerial.write(dataOut,3);
Serial.println(ValueY);
}
}And tractor code is:
String inputString = “”; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
boolean odebrano = false;
byte dat1 = 0x00; // Stores received byte
byte dat2 = 0x00; // Stores received byte
byte dat3 = 0x00; // Stores received byte
byte ID1 = 0x39; //9560
byte drive_max = 255; // but you can change these values if you need to
byte drive_min = 0;
byte drive_center = 128;
int move2 = 100;
byte command_val = 0x00; // Stores the command value
byte data_val = 0x7F; // Stores the data value
int servo_val = 128; // Variable used to ensure data_val is between servo limits
int servo_val2 = 128;
int data = 0; // Variable to indicate serial data is available
int i;
int j = 0;
const int leftana=11;
const int connled=13;
const int motorcon1=2;
const int motorcon2=3;void setup() {
// initialize serial:
Serial.begin(38400);
inputString.reserve(3);
pinMode(13, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
pinMode(15, OUTPUT);
}void loop() {
i = i+1;
if (i>=10) i=0;
// j = i / 10;
if (dat1 == ID1){ // Confirm that the correct vehicle ID has been recieved
command_val = dat2; // Store the new command value
data_val = dat3;
}if (odebrano==true && i==1){
odebrano = false;
digitalWrite(connled,LOW);
}
servo_val = map(data_val, 0x00, 0xFF, drive_min, drive_max); // scale the data value for use with the motorif (servo_val2 > servo_val && i==1) servo_val2=servo_val2-1;
if (servo_val2 < servo_val && i==1) servo_val2=servo_val2+1;if (servo_val2 < (drive_center-10)){ // These if functions leave a buffer zone of 15 bits above and below the drive center value
move2=map(servo_val2,0,128,255,100);
digitalWrite(motorcon2, HIGH); // Set the direction with pins 7 and 8
digitalWrite(motorcon1, LOW);
}
else if (servo_val2 > (drive_center+10)){
move2=map(servo_val2,128,255,100,255);
digitalWrite(motorcon2, LOW); // Set the direction with pins 7 and 8
digitalWrite(motorcon1, HIGH);
}
else { // If within the buffer turn off the motor
move2=100;
digitalWrite(motorcon2, LOW); // Set the direction with pins 7 and 8
digitalWrite(motorcon1, LOW);
}
analogWrite(leftana,move2);if (Serial.available()) {
inputString=Serial.readString();
dat1=inputString[0];
dat2=inputString[1];
dat3=inputString[2];
odebrano = true;
digitalWrite(connled,HIGH);
}
}Some time ago I was told by RC Tractor Guy to add if loop for analog reading, but with that modification it is not working at all.
I have changed all analog write and digital write commands, no now there is a constant integer instead of numerical port number. I have also tried to disable buffer in the xbee and send all the data immediately, but nothing has changed.Any ideas?
September 9, 2015 at 2:43 pm #1135TomekParticipantSeptember 11, 2015 at 10:27 am #1161RC Tractor GuyKeymasterThat is a tricky one. Does it make sense to you that it didn’t work at all with the analogRead in the if loop? I mean you take a reading at i=25 and send at i=99 then why did you not see a change? You are clearly a better programmer than me, I’ve no clue of actual c or c++ so I don’t 100% follow your code unfortunately.
Have you tried hooking the receive XBee to your computer and seeing how fast the data is arriving and whether it is what you would expect? Just to be sure the delay is in the controller code.
Your 4WD is just awesome, every video I think it is so cool. I can’t wait to see it in action.
September 12, 2015 at 7:30 am #1199TomekParticipantAfter connecting xbee to the computer I was able to speed up sending up to one time per 50 cycles and serial data monitor was displaying correct packets. Probably it is possible to do that faster, but no need to. Transmitter is working correctly,
I have replaced XBees with wires and it was working in the same way. This is not a XBee issue
I have modified code a lot to make it simpler:void setup() { // initialize serial: Serial.begin(115200); inputString.reserve(3); pinMode(13, OUTPUT); pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(11, OUTPUT); pinMode(15, OUTPUT); } void loop() { servo_val = map(data_val, 0x00, 0xFF, drive_min, drive_max); // scale the data value for use with the motor servo_val2=servo_val; if (servo_val2 > idle_high){ move2=map(servo_val2,128,255,100,255); digitalWrite(motorcon2, LOW); // Set the direction with pins 7 and 8 digitalWrite(motorcon1, HIGH); } else { // If within the buffer turn off the motor move2=100; digitalWrite(motorcon2, LOW); // Set the direction with pins 7 and 8 digitalWrite(motorcon1, LOW); } while (Serial.available()) { inputString=Serial.readString(); dat1=inputString[0]; dat2=inputString[1]; data_val=inputString[2]; } }
There was no change after that either.
I think the issue is related to serial buffer overflow, difference between speed of Leonardo and ProMini 3,3V or I need to change the way I read serial data to look for beginning of the packet.
September 12, 2015 at 9:24 am #1200TomekParticipantI have finally found the problem. Instead of this:
while (Serial.available()) { inputString=Serial.readString(); dat1=inputString[0]; dat2=inputString[1]; data_val=inputString[2]; }
I have now this:
while(Serial.available() > 0) { char inChar = Serial.read(); if(inChar == SOP) { index = 0; inData[index] = '\0'; started = true; ended = false; } else if(index == 3) { ended = true; break; } else { if(index < 79) { inData[index] = inChar; index++; inData[index] = '\0'; } } } // We are here either because all pending serial // data has been read OR because an end of // packet marker arrived. Which is it? if(started && ended) { // The end of packet marker arrived. Process the packet // Reset for the next packet started = false; ended = false; index = 0; inData[index] = '\0'; } data_val=inData[1];
So I look for begining of the packet starting with char 9 length 3 chars and it is working well and fast. Also baudrate 9600 is enough.
September 14, 2015 at 9:23 am #1201RC Tractor GuyKeymasterThat’s great news, I never would have caught that problem 🙂
Have you much left to add to the model or just squeezing the components into the model now?
September 14, 2015 at 10:14 am #1202TomekParticipantMy happiness came too early. There is no delay now, but one digital output to motor driver is blinking, and I have no idea why.
I want to add all the lights and servo for rear attacher. Most likely it will take next half a year.September 15, 2015 at 10:29 am #1203RC Tractor GuyKeymasterThat is very strange alright, I can’t think of anything to help. I had taught maybe a library interfering or an interrupt but it doesn’t look like you’re using any of those. It can’t be a power problem because your video clearly shows the tractor working fine previously with the delay issue so I really don’t know. Maybe check if servo_val2 is changing for some reason but I don’t see why it should be.
Sounds like you’ve a low to do alright, hopefully that all goes smoothly.
September 15, 2015 at 11:41 am #1204TomekParticipantSeptember 15, 2015 at 12:23 pm #1206RC Tractor GuyKeymasterThat looks great, it moves at a really nice speed and it is a lot quieter than my model with the Tamiya gearbox. It’s a really nice job.
September 15, 2015 at 2:54 pm #1209TomekParticipantI think it is a little bit too low. It is ok for a fieldwork, but for a transport it is slow. Also servo has not enough power when it is connected to 3,3 or even 5V power supply. I need to buy 6V power supply and check how the servo will work with that and control signal from arduino 3,3V. If it will be ok, I will change motors to 6V 100RPM.
September 15, 2015 at 3:20 pm #1210RC Tractor GuyKeymasterThat’s a pity about the servo, it would take a strong servo to slide all those wheels around. I have my rear wheels free wheeling so it is pretty easy to turn but I don’t have anywhere near your pulling power.
What voltage and rpm are you currently using?
September 15, 2015 at 3:26 pm #1211TomekParticipantI am thinking about Hitec HS-5085MG but it is quite expensive, so maybe I will look for something else. I am using 3v 50RPM motors.
September 15, 2015 at 3:37 pm #1212RC Tractor GuyKeymasterYou don’t have individual control of each motor do you? Maybe you could slow one side down as you steer or something.
Also I’d say you could up the voltage of the motor you have to 5V and see if that was fast enough. I checked the serial number on an N20 motor I had before and the voltage was rated for 1.5 – 6V but was sold as 30rpm at 3volts or something like that.
- AuthorPosts
You must be logged in to reply to this topic.