Hi everyone,
Thanks for coming in.
I use my arduino uno to read encoders' value of my motor then tried to send the counting number to raspberry pi using serial.write() in 20hz. However, it has up to 10 second's delay until I open my serial monitor. Serial monitor seems stop the buffering and make the delay disappear. I tried press the reset button on the board since opening serial monitor reset the board, but it doesn't work.
The communication is done via usb connection. Pin 0 & 1 don't involve in this program.
Encoders is very sensitive with timing. And I think it is odd to open my serial monitor whenever I try to start my car .
Do anyone have any idea about how to resolve this? The part of code I used to send message shown below.
serial.write() part:
void setup() {
Serial.begin(115200);
}
void loop() {
time1 = millis();
dt = time1 - time2;
if (dt >= 50){ // To make it run every 50ms
time2 = millis();
if (encoder1Pos>=0){
Serial.write(11); // flag: positive & encoder1
Serial.write(255); //flag
Serial.write(byte(abs(encoder1Pos))); // encoder counter
}
if (encoder1Pos<0){
Serial.write(1); // flag: negative & encoder1
Serial.write(255); //flag
Serial.write(byte(abs(encoder1Pos))); // encoder counter
}
}
}
Full version:
#include <PID_v1.h>
// motor one
int enA = 5;
int in1 = 9;
int in2 = 8;
// motor two
int enB = 11;
int in3 = 7;
int in4 = 6;
double steering, motor_speed1, motor_speed2, joy_speed;
double max_angularspeed1=0, max_angularspeed2=0;
// twelve servo objects can be created on most boards
int encoder1PinA = 2;
int encoder1PinB = 4;
int encoder2PinA = 3;
int encoder2PinB = 12;
//int powerpin = 1;
int groundpin = 13;
int endpoint = 140;
//
volatile int encoder1Pos = 0;
volatile int encoder2Pos = 0;
int time1 = 0;
int time2 = 0;
double dt;
double pi = 3.141592653589;
double angular_speed1;
double angular_speed2;
int time_gap = 50;
PID myPID1(&angular_speed1, &motor_speed1, &joy_speed,4.1,0,0.32, DIRECT);
PID myPID2(&angular_speed2, &motor_speed2, &joy_speed,4.1,0,0.32, DIRECT);
void setup() {
Serial.begin(115200);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode (encoder1PinA, INPUT);
pinMode (encoder1PinB, INPUT);
pinMode (encoder2PinA, INPUT);
pinMode (encoder2PinB, INPUT);
attachInterrupt(digitalPinToInterrupt(encoder1PinA), counter1, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoder2PinA), counter2, CHANGE);
//turn the PID on
myPID1.SetMode(AUTOMATIC);
myPID2.SetMode(AUTOMATIC);
myPID1.SetSampleTime(time_gap);
myPID2.SetSampleTime(time_gap);
}
void loop() {
char buffer[] = {' ',' ',' '};
if (Serial.available() > 0) {
//read the incoming byte:
Serial.readBytesUntil('n', buffer, 3);
// Serial.print("I received: ");
// Serial.println(buffer[0], DEC);
// Serial.println(buffer[1], DEC);
// Serial.println(buffer[2], DEC);
steering = map(abs(int(buffer[0])), 0, 100, 0, endpoint);
joy_speed = map(abs(int(buffer[1])), 0, 100, 0, endpoint);
if(buffer[1] < 0 && steering < 50){
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
}
if(buffer[1] > 0 && steering < 50){
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}
if(buffer[0] < 0 && motor_speed1 < 50){
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enA, steering); // Send PWM signal to motor A
// Serial.print (buffer[0]);
// Serial.print ("/");
// Serial.print (motor_speed1);
// Serial.print ("/");
// Serial.println (steering);
}
if(buffer[0] >= 0 && motor_speed1 < 50){
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, HIGH);
digitalWrite(in4, HIGH);
analogWrite(enB, steering); // Send PWM signal to motor B
// Serial.print (buffer[0]);
// Serial.print ("/");
// Serial.print (motor_speed1);
// Serial.print ("/");
// Serial.println (steering);
}
//debug pid control
// Serial.print(joy_speed);
// Serial.print ("---");
// Serial.println(angular_speed1/4);
// Serial.print ("/");
// Serial.println(angular_speed2/4);
// Serial.print("+++");
// Serial.print(motor_speed1);
// Serial.print ("/");
// Serial.println(motor_speed2);
// Serial.println(encoder1Pos);
}
time1 = millis();
dt = time1 - time2;
if (dt >= time_gap){
time2 = millis();
angular_speed1 = (2*pi*abs(encoder1Pos))/(2*390*(dt/1000))*4;
// Serial.print(dt/1000);
// Serial.print ("/");
// Serial.println(encoder1Pos);
// Serial.print ("/");
// Serial.println (angular_speed1*180/(pi));
if (encoder1Pos>=0){
Serial.write(byte(11)); // flag: positive & encoder1
Serial.write(byte(255));
Serial.write(byte(abs(encoder1Pos)));
}
if (encoder1Pos<0){
Serial.write(byte(1)); // flag: negative & encoder1
Serial.write(byte(255));
Serial.write(byte(abs(encoder1Pos)));
}
encoder1Pos = 0;
angular_speed2 = (2*pi*abs(encoder2Pos))/(2*390*(dt/1000))*4;
// Serial.print(dt/1000);
// Serial.print ("'+'");
// Serial.print(encoder2Pos);
// Serial.print ("'+'");
// Serial.println (angular_speed2*180/(pi));
if (encoder2Pos>=0){
Serial.write(byte(12)); // flag: positive & encoder2
Serial.write(byte(255));
Serial.write(byte(abs(encoder2Pos)));
}
if (encoder2Pos<0){
Serial.write(byte(2)); // flag: negative & encoder2
Serial.write(byte(255));
Serial.write(byte(abs(encoder2Pos)));
}
// Serial.flush();
encoder2Pos = 0;
myPID1.Compute();
myPID2.Compute();
// angular_speed1 = map(angular_speed1, 0, max_angularspeed1, 0, endpoint);
// angular_speed2 = map(angular_speed2, 0, max_angularspeed2, 0, endpoint);
if(steering < 50){
analogWrite(enA, motor_speed1); // Send PWM signal to motor A
analogWrite(enB, motor_speed2); // Send PWM signal to motor B
// Serial.print ("/");
}
}
}
//
void counter1(){
if (digitalRead(encoder1PinB) == digitalRead(encoder1PinA)) {
encoder1Pos++;
} else {
encoder1Pos--; //--
}
}
void counter2(){
if (digitalRead(encoder2PinB) == digitalRead(encoder2PinA)) {
encoder2Pos--; //--
} else {
encoder2Pos++;
}
}