Hello, I am using an Arduino Mega 2560 and photoreflective sensors to measure the speed of 3 wheels of a small robot for a school project. (Due to budget constraints for the project, we are using photoreflective sensors and a small wheel with 8 slots in it instead of a premade optical/rotary encoder). I am using a Roboclaw 2x15A motor controller in Packet Serial mode. I have two 12V batteries connected in series powering two 24V Banebots RS775 motors through the roboclaw. My photoreflectors are powered at 5V, and their output signal is connected to 5V via a pull-up (I believe this is the proper term) resistor and then connected to the interrupt pin of the Arduino.
Below I have included the code that I am using to test this setup. So far, I have only connected one of the 3 photoreflective sensors. I wanted to test that the setup worked on at least one wheel before complicating it with 3 wheels. I have a single sensor aimed at Motor 1 and connected to pin 18, to which I have connected "Interrupt1". When driving motor 1 at a relatively low speed, say 20%, this code and setup works fine, and I can see the time interval between interrupts on my serial monitor.
My initial fear was that the arduino wouldn't be able to process interrupts quickly enough when the motors were driven at high speeds. However, I'm getting a different problem altogether. When I increase the speed of Motor 1, I can see on the serial monitor that Interrupt 2 is periodically triggered--maybe once or twice per second. This is extremely confusing to me, because there is no signal at all connected to Interrupt 2/Pin 19. The only sensor I have connected is from the sensor aimed at Motor 1, which goes to Arduino Pin 18 and is associated with Interrupt 1. How is it possible that Interrupt 2 would be triggered when there is nothing connected to its pin?
Can anyone help me diagnose what the issue might be? Thank you very much for your help!
// SingleDrivenWheelSpeedTest_Mega.ino
// Author: Will Cunningham
// Date: 11/19/19
// Serial Output pins:
// Arduino pin 11 to roboclaw s1
// Arduino pin 10 to roboclaw s2
//See BareMinimum example for a list of library functions
//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"
//See limitations of Arduino SoftwareSerial
SoftwareSerial serial(10,11);
RoboClaw roboclaw(&serial,10000);
#define address 0x80 // serial address used for the roboclaw packet serial mode 7
# define M_PI 3.14159265358979323846 /* pi */
// set up first interrupt pin
const byte interrupt1Pin = 18; // pin 18 on Arduino mega
volatile unsigned long ti1, tf1, dt1; // initial time 1, final time 1, and delta time 1
volatile byte interrupt1Flag = 0; // this is either 1 or 0, allows for entrance into if structure
// set up second interrupt pin
const byte interrupt2Pin = 19;
volatile unsigned long ti2, tf2, dt2;
volatile byte interrupt2Flag = 0;
// set up third interrupt pin
const byte interrupt3Pin = 20;
volatile unsigned long ti3, tf3, dt3, int3Counts;
volatile byte interrupt3Flag = 0;
// set up distance-counting variables
float distTraveled; // [inches]
int finalDistance = 240; // [inches]
int decelDistance = 15*12; // [inches]
void setup()
{
// initialize serial monitor
Serial.begin(38400);
// setup interrupt pins on arduino
// attach first interrupt pin
pinMode(interrupt1Pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interrupt1Pin), Interrupt_1, RISING);
// attach second interrupt pin
pinMode(interrupt2Pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interrupt2Pin), Interrupt_2, RISING);
// attach second interrupt pin
pinMode(interrupt3Pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interrupt3Pin), Interrupt_3, RISING);
// initialize serial communication with RoboClaw---serial mode option 4 for baud rate = 38400
roboclaw.begin(38400);
Serial.print("INITIAL TEST");
}
void loop()
{
// Measure wheel speed
if (interrupt1Flag){
interrupt1Flag = 0;
dt1 = tf1 - ti1;
// Serial.println("Interrupt 1 Occurred");
// Serial.print("Time1 Initial: ");
// Serial.println(ti1,DEC);
// Serial.print("Time1 Final: ");
// Serial.println(tf1,DEC);
Serial.print("dt1: ");
Serial.println(dt1,DEC);
// noInterrupts();
// tf1 = ti1 = 0;
// interrupts();
}
else{
// do nothing
}
if (interrupt2Flag){
interrupt2Flag = 0;
dt2 = tf2 - ti2;
Serial.println("Interrupt 2 Occurred");
Serial.print("Time2 Initial: ");
Serial.println(ti2,DEC);
Serial.print("Time2 Final: ");
Serial.println(tf2,DEC);
Serial.print("dt2: ");
Serial.println(dt2,DEC);
// noInterrupts();
// tf2 = ti2 = 0;
// interrupts();
}
else{
// do nothing
}
if (interrupt3Flag){
interrupt3Flag = 0;
dt3 = tf3 - ti3;
Serial.println("Interrupt 3 Occurred");
Serial.print("Time3 Initial: ");
Serial.println(ti3,DEC);
Serial.print("Time3 Final: ");
Serial.println(tf3,DEC);
Serial.print("dt3: ");
Serial.println(dt3,DEC);
// noInterrupts();
// tf2 = ti2 = 0;
// interrupts();
// update the distance
distTraveled = (float)int3Counts*M_PI/2; // [inches]
}
else{
// do nothing
}
// Control the speed (input range: 0 = full stop, 127 = full forward
roboclaw.ForwardM1(address,20); //start Motor1 forward at 0 speed
// roboclaw.ForwardM1(address,50); //start Motor1 forward at half speed
// to readers of the arduino forum: When experiencing the problem I have described, I am not driving motor 2 at all, and there is no sensor at all hooked up to pin 19.
roboclaw.ForwardM2(address,0); //start Motor2 forward at 0 speed
// roboclaw.ForwardM2(address,50); //start Motor2 forward at half speed
// Check if you have traveled far enough to start slowing down or stopping
if(distTraveled > finalDistance){
// stop
}
else if(distTraveled > decelDistance){
// slow down
}
// print speed on either serial monitor or lcd
}
void Interrupt_1(void)
{
ti1 = tf1;
tf1 = micros();
interrupt1Flag = 1;
}
void Interrupt_2(void)
{
ti2 = tf2;
tf2 = micros();
interrupt2Flag = 1;
}
void Interrupt_3(void)
{
ti3 = tf3;
tf3 = micros();
interrupt3Flag = 1;
int3Counts++;
}
RoboClaw.cpp (25.3 KB)
RoboClaw.h (10.4 KB)