sending interrupt information through bluetooth

Hi, am building two robots to showcase how a robot can sense movement of another robot through encoder wheel together with photo sensor that uses interrupts in Arduino Uno. The slave robot should receive the information through Bluetooth and match that speed of the master robot. However I have issues with information received on the slave robot. when i check on serial monitor i see different information from the one sent. Please help me figure out the problem.
(The master robot is controlled by a joystick.)
Thank you

slavebluetoothTRIAL6.ino (5.85 KB)

joystickandinterrupts_4.ino (5.97 KB)

Please post your as explained in the forum guidelines.

First (and maybe biggest) problem is the existence of Serial.print() statements inside an ISR. Interrupts are off in an ISR and Serial requires interrupts to be on. Just use millis() to manage the timing as illustrated in Several Things at a Time.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

And on the receiving side this is not good

 if (Serial.available() >= 1) {
   // x = Serial.read();
    //delay(10);
    rotation1 = Serial.read();
    delay(10);
    rotation2= Serial.read();

There is nothing to guarantee that the receiver won’t get the two bytes mixed up. And there should be no delay()s in a receiving program.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

Separately from all of that I’m not sure what you are trying to accomplish. There is zero possibility of data sent over a serial connection being as responsive on the receiving end as an interrupt on the transmitting end.

…R

lastchancename:
Please post your as explained in the forum guidelines.

//SLAVEBLUETOOTH
#include <AFMotor.h>
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7
int rotation1=0;
int rotation2=0;

//unsigned int  x = 0;
//unsigned int  counter = 0;
int motorspeed3 = 0;
int motorspeed4 = 0;
void setup() {
Serial.begin(38400); // Default communication rate of the Bluetooth module
//  pinMode(yAxis,INPUT);
 pinMode(enA, OUTPUT);
 pinMode(enB, OUTPUT);
 pinMode(in1, OUTPUT);
 pinMode(in2, OUTPUT);
 pinMode(in3, OUTPUT);
 pinMode(in4, OUTPUT);
 
motor3.run(RELEASE);
motor4.run(RELEASE);
}
void loop() {
 // Default value - no movement when the Joystick stays in the center
//  x = 510 / 4;
// y = 510 / 4;
 // Read the incoming data from the Joystick, or the master Bluetooth device
 if (Serial.available() >= 1) {
  // x = Serial.read();
   //delay(10);
   rotation1 = Serial.read();
   delay(10);
   rotation2= Serial.read();
   //counter1=3*counter;
 
// delay(10);
   Serial.print("rotation1-");
   Serial.print(rotation1);
   Serial.print("RPM");
   Serial.print("    rotation2-");
   Serial.print(rotation2);
   Serial.println("RPM");
 }
  
 if (rotation1>0 ||rotation1 <201){
 motorspeed3 = map(rotation1, 0, 200, 0, 255);
  motor3.setSpeed(motorspeed3);
   motor3.run(FORWARD);}
   delay(10);
 if (rotation2>0 ||rotation2 <201) {
  motorspeed4 = map(rotation2, 0, 200, 0, 255);
 motor4.setSpeed(motorspeed4);
 motor4.run(FORWARD);
 
  
 delay(10);}
else {
motor3.setSpeed(0);
motor4.setSpeed(0);
}
}

//MASTER BLUETOOTH
 //Optical sensor
#include <TimerOne.h> 
//#include "TimerOne.h"
#include <AFMotor.h>
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);
#define joystick A0
#define enA 9 //enA
#define in1 4 //in1
#define in2 5 //in2
#define enB 10 //enB
#define in3 6 //in3
#define in4 7 //in4
int rotation1=0;
int rotation2=0;
int yAxis = 1;
int xAxis = 0;
int motorspeed3=0;
int motorspeed4=0;

// Constants for Interrupt Pins
// Change values if not using Arduino Uno

const byte MOTOR3 = 2;  // Motor 1 Interrupt Pin - INT 0
const byte MOTOR4 = 3;  // Motor 2 Interrupt Pin - INT 1

// Integers for pulse counters
unsigned int counter1 = 0;
unsigned int counter2 = 0;

// Float for number of slots in encoder disk
int diskslots = 20;  // Change to match value of encoder disk

// Interrupt Service Routines

// Motor 1 pulse count ISR
void ISR_count1()  
{
 counter1++;  // increment Motor 1 counter value
} 

// Motor 2 pulse count ISR
void ISR_count2()  
{
 counter2++;  // increment Motor 2 counter value
} 

// TimerOne ISR
void ISR_timerone()
{
 Timer1.detachInterrupt();  // Stop the timer
 Serial.print("Motor Speed 1: "); 
 int rotation1 = (counter1 / diskslots) * 60.00;  // calculate RPM for Motor 1
 Serial.print(rotation1); 
//  Serial.write(rotation1);
 //delay(10);
 Serial.print(" RPM - "); 
 counter1 = 0;  //  reset counter to zero
 Serial.print("Motor Speed 2: "); 
 int rotation2 = (counter2 / diskslots) * 60.00;  // calculate RPM for Motor 2
// Serial.write(rotation2);
 Serial.print(rotation2);  
 Serial.println(" RPM"); 
 counter2 = 0;  //  reset counter to zero
 Timer1.attachInterrupt( ISR_timerone );  // Enable the timer
 delay(10);
 Serial.write(int(rotation1));
 Serial.write(int(rotation2));
}
//Serial.read(rotation1
void setup() 
{
 Serial.begin(38400);
// pinMode(MOTOR3,OUTPUT);
// pinMode(MOTOR4,OUTPUT);
 Timer1.initialize(1000000); // set timer for 1sec
 attachInterrupt(digitalPinToInterrupt (MOTOR3), ISR_count1, RISING);  // Increase counter 1 when speed sensor pin goes High
 //delayMicroseconds(10);
 
 delay(10);
 attachInterrupt(digitalPinToInterrupt (MOTOR4), ISR_count2, RISING);  // Increase counter 2 when speed sensor pin goes High
 
 Timer1.attachInterrupt( ISR_timerone ); // Enable the timer

// Serial.begin(38400);
 pinMode(yAxis, INPUT);
 pinMode(yAxis, INPUT);
 pinMode (enA,OUTPUT);
 pinMode (in1,OUTPUT);
 pinMode (in2,OUTPUT);
 pinMode (enB,OUTPUT);
 pinMode (in3,OUTPUT);
 pinMode (in4,OUTPUT);
 
motor3.setSpeed(255);
 motor3.run(RELEASE);

 motor4.setSpeed(255);
 motor4.run(RELEASE);
 delay(10);
} 

void loop()
{
 //Serial.write(rotation1);
// Serial.print("rotat1");
// Serial.println(rotation1);
// Serial.write(rotation2);
 //int xAxis = analogRead(A0);
 int yAxis = analogRead(A1);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

//Serial.print("xAxis");
//Serial.println(xAxis);
//Serial.print("yAxis");
//Serial.println(yAxis);
//delay(10);

 if (yAxis<470) {
   
//  digitalWrite (in1, HIGH);
//  digitalWrite (in2 , LOW);
//
//  digitalWrite (in3 , HIGH);
//  digitalWrite (in4 , LOW);

 motorspeed3 = map(yAxis, 470, 0, 0, 255);
 motorspeed4 = map(yAxis, 470, 0, 0, 255);
 
 motor3.setSpeed(motorspeed3);
 motor4.setSpeed(motorspeed4);
 motor3.run(BACKWARD);
 motor4.run(BACKWARD);
//Serial.print("          BackwardSpeed3: ");  
//Serial.println(motorspeed3);
//Serial.print("                         BackwardSpeed4: ");  
//Serial.println(motorspeed4);
delay(100);

 }
 
 if (yAxis>550) {
//  digitalWrite (in1, HIGH);
//  digitalWrite (in2, LOW);
//
//  digitalWrite (in3, HIGH);
//  digitalWrite (in4, LOW);

 motorspeed3 = map(yAxis, 550, 1023, 0, 255);
 motorspeed4 = map(yAxis, 550, 1023, 0, 255);
 motor3.setSpeed(motorspeed3);
 motor4.setSpeed(motorspeed4);
 motor3.run(FORWARD);
 motor4.run(FORWARD);
//motorspeedA = map(yAxis,1023, 550, 255, 0);
//motorspeedB = map(yAxis,1023,550, 255, 0);
//  Serial.print("                                                                                                            ForwardSpeedM3: ");  
//  Serial.println(motorspeed3);
//  Serial.print("                                                                                                                                ForwardSpeedM4: ");  
//  Serial.println(motorspeed4);
 delay(100);
 } 
 
 else  {
 motorspeed3=0;
 motorspeed4=0;
}
 
 if (yAxis>470 ||yAxis <550){
 motorspeed3=map(yAxis,470,550,0,0);
 motorspeed4=map(yAxis,470,550,0,0);
 motor3.setSpeed(motorspeed3);
 motor4.setSpeed(motorspeed4);
 motor3.run(0);
 motor4.run(0);

//  Serial.print("                                                      motorspeed3@centre: ");  
//  Serial.println(motorspeed3);
//  Serial.print(                                                                             "motorspeed4@centre: ");  
//  Serial.println(motorspeed4);
 delay(10);
 }

}

When posting code please use the code button </>
codeButton.png

so your code 
looks like this

and is easy to copy to a text editor See How to use the Forum

Also please use the AutoFormat tool to indent your code for easier reading.

Your code is too long for me to study quickly without copying to my text editor. The text editor shows line numbers, identifies matching brackets and allows me to search for things like all instances of a particular variable or function.

...R

Robin2:
First (and maybe biggest) problem is the existence of Serial.print() statements inside an ISR. Interrupts are off in an ISR and Serial requires interrupts to be on. Just use millis() to manage the timing as illustrated in Several Things at a Time.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

And on the receiving side this is not good

 if (Serial.available() >= 1) {

// x = Serial.read();
    //delay(10);
    rotation1 = Serial.read();
    delay(10);
    rotation2= Serial.read();




There is nothing to guarantee that the receiver won't get the two bytes mixed up. And there should be no delay()s in a receiving program.

Have a look at the examples in [Serial Input Basics](http://forum.arduino.cc/index.php?topic=396450.0) - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)


Serial.print(’<’); // start marker
Serial.print(value1);
Serial.print(’,’); // comma separator
Serial.print(value2);
Serial.println(’>’); // end marker






Separately from all of that I'm not sure what you are trying to accomplish. There is zero possibility of data sent over a serial connection being as responsive on the receiving end as an interrupt on the transmitting end.

...R

What am trying to achieve is to read speed of master robot which is gotten from the encoder wheel and photo sensor. Send this speed to the slave robot which should match that speed. So that when i control the master robot, the slave robot connected through Bluetooth matches my master speed.

 if (Serial.available() >= 1) {
  // x = Serial.read();
   //delay(10);
   rotation1 = Serial.read();
   delay(10);
   rotation2= Serial.read();

If there is one byte in the buffer, it is NOT OK to read two bytes.

Robin2:
When posting code please use the code button </>
codeButton.png

so your code 

looks like this



and is easy to copy to a text editor See [How to use the Forum](http://forum.arduino.cc/index.php?topic=149014.0)

Also please use the AutoFormat tool to indent your code for easier reading.


Your code is too long for me to study quickly without copying to my text editor. The text editor shows line numbers, identifies matching brackets and allows me to search for things like all instances of a particular variable or function.


...R

I have shortened the code and followed the previous instructions. Looking forward to hearing from you

MASTER BLUETOOTH

//Optical sensor
#include <TimerOne.h>
#include <AFMotor.h>
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);
#define joystick A0
#define enA 9 //enA
#define in1 4 //in1
#define in2 5 //in2
#define enB 10 //enB
#define in3 6 //in3
#define in4 7 //in4
int rotation1 = 0;
int rotation2 = 0;
int yAxis = 1;
int xAxis = 0;
int motorspeed3 = 0;
int motorspeed4 = 0;

// Constants for Interrupt Pins
// Change values if not using Arduino Uno

const byte MOTOR3 = 2;  // Motor 1 Interrupt Pin - INT 0
const byte MOTOR4 = 3;  // Motor 2 Interrupt Pin - INT 1

// Integers for pulse counters
unsigned int counter1 = 0;
unsigned int counter2 = 0;

// Float for number of slots in encoder disk
int diskslots = 20;  // Change to match value of encoder disk

// Interrupt Service Routines

// Motor 1 pulse count ISR
void ISR_count1()
{
 counter1++;  // increment Motor 1 counter value
}

// Motor 2 pulse count ISR
void ISR_count2()
{
 counter2++;  // increment Motor 2 counter value
}

// TimerOne ISR
void ISR_timerone()
{
 Timer1.detachInterrupt();  // Stop the timer
 // Serial.print("Motor Speed 1: ");
 int rotation1 = (counter1 / diskslots) * 60.00;  // calculate RPM for Motor 1
 // Serial.print(rotation1);
 //  Serial.write(rotation1);
 //delay(10);
 //Serial.print(" RPM - ");
 counter1 = 0;  //  reset counter to zero
 // Serial.print("Motor Speed 2: ");
 int rotation2 = (counter2 / diskslots) * 60.00;  // calculate RPM for Motor 2
 // Serial.write(rotation2);
 // Serial.print(rotation2);
 // Serial.println(" RPM");
 counter2 = 0;  //  reset counter to zero
 Timer1.attachInterrupt( ISR_timerone );  // Enable the timer
 delay(10);
 Serial.write(int(rotation1));
 Serial.write(int(rotation2));
}
//Serial.read(rotation1
void setup()
{
 Serial.begin(38400);

 Timer1.initialize(1000000); // set timer for 1sec
 attachInterrupt(digitalPinToInterrupt (MOTOR3), ISR_count1, RISING);  // Increase counter 1 when speed sensor pin goes High
 //delayMicroseconds(10);

 delay(10);
 attachInterrupt(digitalPinToInterrupt (MOTOR4), ISR_count2, RISING);  // Increase counter 2 when speed sensor pin goes High

 Timer1.attachInterrupt( ISR_timerone ); // Enable the timer

 // Serial.begin(38400);
 pinMode(yAxis, INPUT);
 pinMode(yAxis, INPUT);
 pinMode (enA, OUTPUT);
 pinMode (in1, OUTPUT);
 pinMode (in2, OUTPUT);
 pinMode (enB, OUTPUT);
 pinMode (in3, OUTPUT);
 pinMode (in4, OUTPUT);

 motor3.setSpeed(255);
 motor3.run(RELEASE);

 motor4.setSpeed(255);
 motor4.run(RELEASE);
 delay(10);
}

void loop()
{
 int yAxis = analogRead(A1);
 if (yAxis < 470) {
   motorspeed3 = map(yAxis, 470, 0, 0, 255);
   motorspeed4 = map(yAxis, 470, 0, 0, 255);

   motor3.setSpeed(motorspeed3);
   motor4.setSpeed(motorspeed4);
   motor3.run(BACKWARD);
   motor4.run(BACKWARD);
   //Serial.print("          BackwardSpeed3: ");
   //Serial.println(motorspeed3);
   //Serial.print("                         BackwardSpeed4: ");
   //Serial.println(motorspeed4);
   delay(100);

 }

 if (yAxis > 550) {
   motorspeed3 = map(yAxis, 550, 1023, 0, 255);
   motorspeed4 = map(yAxis, 550, 1023, 0, 255);
   motor3.setSpeed(motorspeed3);
   motor4.setSpeed(motorspeed4);
   motor3.run(FORWARD);
   motor4.run(FORWARD);

   delay(100);
 }

 else  {
   motorspeed3 = 0;
   motorspeed4 = 0;
 }

 if (yAxis > 470 || yAxis < 550) {
   motorspeed3 = map(yAxis, 470, 550, 0, 0);
   motorspeed4 = map(yAxis, 470, 550, 0, 0);
   motor3.setSpeed(motorspeed3);
   motor4.setSpeed(motorspeed4);
   motor3.run(0);
   motor4.run(0);

   //  Serial.print("                                                      motorspeed3@centre: ");
   //  Serial.println(motorspeed3);
   //  Serial.print(                                                                             "motorspeed4@centre: ");
   //  Serial.println(motorspeed4);
   delay(10);
 }

}

SLAVEBLUETOOTH

#include <AFMotor.h>
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7
int rotation1 = 0;
int rotation2 = 0;
int motorspeed3 = 0;
int motorspeed4 = 0;
void setup() {
 Serial.begin(38400); // Default communication rate of the Bluetooth module
 pinMode(yAxis, INPUT);
 pinMode(enA, OUTPUT);
 pinMode(enB, OUTPUT);
 pinMode(in1, OUTPUT);
 pinMode(in2, OUTPUT);
 pinMode(in3, OUTPUT);
 pinMode(in4, OUTPUT);

 motor3.run(RELEASE);
 motor4.run(RELEASE);
}
void loop() {

 // Read the incoming data from the Joystick, or the master Bluetooth device
 while (Serial.available() >= 1) {
   // x = Serial.read();
   //delay(10);
   rotation1 = Serial.read();
   //delay(10);
   rotation2 = Serial.read();
   //counter1=3*counter;

   // delay(10);
   Serial.print("rotation1-");
   Serial.print(rotation1);
   Serial.print("RPM");
   Serial.print("    rotation2-");
   Serial.print(rotation2);
   Serial.println("RPM");
 }

 if (rotation1 > 0 || rotation1 < 201) {
   motorspeed3 = map(rotation1, 0, 200, 0, 255);
   motor3.setSpeed(motorspeed3);
   motor3.run(FORWARD);
 }
 // delay(10);
 if (rotation2 > 0 || rotation2 < 201) {
   motorspeed4 = map(rotation2, 0, 200, 0, 255);
   motor4.setSpeed(motorspeed4);
   motor4.run(FORWARD);


   //delay(10);}
   else {
     motor3.setSpeed(0);
     motor4.setSpeed(0);
   }
 }

It may not be your only problem, but it's a critical error that you did not define 'counter1' and 'counter2' as volatile. Also, if you're running this code on an 8-bit AVR processor, accesses to these variables will not be atomic. So, everyplace they are accessed in non-ISR code must be protected by Critical Sections.

You still have Serial code in the ISR.

...R