Interrupts

Hello,

I'm currently working on a sumo bot that has some line sensors on the front end of it to detect the color of the outer ring so it will know it needs to turn around. I'm using the interrupt function to ideally read the LOW state of the sensor so it identifies the color has changed. I currently have no errors when I upload, but when I set the robot to drive over a white line the Interrupt function is not triggering. Any help would be greatly appreciated.

int signalPin = 3; //pin 3
int signalPin2 = 2; //pin 2

#include "Grove_I2C_Motor_Driver.h" //motor controller

// default I2C address is 0x0f
#define I2C_ADDRESS 0x0f

void setup()
{
Motor.begin(I2C_ADDRESS);
Serial.begin(9600);
pinMode(signalPin2, INPUT);
pinMode(signalPin, INPUT);

attachInterrupt(signalPin, turnRight, LOW);
attachInterrupt(signalPin2, turnLeft, LOW);
delay(3000);

}

void loop()
{
{
Motor.speed(MOTOR1, -100);
Motor.speed(MOTOR2, -100);

}

}
void turnRight()
{
delay(1);
Motor.stop(MOTOR2);
Motor.speed(MOTOR1, 50);

}

void turnLeft()
{
delay(1);
Motor.stop(MOTOR1);
Motor.speed(MOTOR2, 50);

}

1.) you have an extra "{" in your loop()

2.) get those "delay(1)" function calls out of your ISRs

3.) I would venture to guess that your ISRs ARE being called and ARE working, but any input via the ISRs are negligible since after being called, you immediately reset your motors via the main loop(). In other words, you aren't allowing enough time for the bot to actually turn. You need to use the ISRs to set a flag and then do the turning in the loop() via a switch-case statement.

Could you elaborate on how I should set up the flag that will run in my main loop please?

@MRInfected101

In addition to guide lines mentioned in #1, #2, and #3, you may be liking to revise your program at the appropriate labels as per following extra guide lines:

1. Use recommended function:
attachInterrupt(digitalPinToInterrupt(2), isrName, triggerLevel);

2. attachInterrupt() function does/does not do the following:
(a) It enables EIMSK0 signal (External Interrupt Request 0 Enable, INT0)

(b) (Global Interrupt Enable Bit has already been activated by the System Program during reset initialization.)

(c) Does not connect the internal pull-up resistor with Pin-4 of the ATmega328. To make Pin-4 (PD2 Port Line) to work as an external interrupt line (INT0-pin), we must connect the internal pull-up or external pull-up. So, add the instruction:

pinMode(2, INPUT_PULLUP);

No luck, can someone explain what they mean by making the Interrupt a flag and making that connect to my main loop.

I guess you might want that to be volatile.

volatile boolean doMyThang = false;

still getting the same result, the interrupt is not firing

int signalPin = 3; //pin 3
int signalPin2 = 2; //pin 2

#include "Grove_I2C_Motor_Driver.h" //motor controller

// default I2C address is 0x0f
#define I2C_ADDRESS 0x0f
volatile boolean sensorRight = false;

void setup()
{
Motor.begin(I2C_ADDRESS);
Serial.begin(9600);
pinMode(signalPin2, INPUT);
pinMode(signalPin, INPUT);

attachInterrupt(signalPin, turnRight, FALLING);
attachInterrupt(signalPin2, turnLeft, FALLING);
delay(3000);

}

void loop()
{
{
Motor.speed(MOTOR1, -100);
Motor.speed(MOTOR2, -100);
}
if (sensorRight)
{
Motor.stop(MOTOR2);
Motor.speed(MOTOR1, 50);

}

}
void turnRight()
{
sensorRight = true;
}

void turnLeft()
{

Motor.stop(MOTOR1);
Motor.speed(MOTOR2, 50);

}

How do you know what your code is doing?
I don't see any debug prints

(I don't see any code tags either. Hint)

GET RID of those extra curly braces in your loop(). Your code is all sorts of messed up in terms of curly brace placement.

pinMode(signalPin2, INPUT);
pinMode(signalPin, INPUT);

Will PD2 and PD3 port lines work as interrupt lines without internal/external pull-up?

GolamMostafa:
Will PD2 and PD3 port lines work as interrupt lines without internal/external pull-up?

Why shouldn't they?
Depending on what they're connected to, the interrupts could be unpredictable​, but they'll generate interrupts.

Still only moving forward the pull up didn't do anything, the only time it has done something but move forward was when I had,

if(sensorRight = true)

but then it continued turning, probably because it wasn't being reset.

if(sensorRight = true)

That needs ==, otherwise you are assigning sensorRight the value of true.

Yeah I saw that but it just then continues moving forward

@AWOL

As I am not sure about the nature of the external interrupting device of the third party (it could be a push switch or an opto-coupler), I would always define my interrupt pin to known logic. How good is this idea?

I'm trying to use liner sensors so I do not drive off the edge of the ring.

#include <Wire.h>

#include "Ultrasonic.h"

Ultrasonic ultrasonic(7); //ultrasonic

int signalPin2 = 2;
int signalPin = 3;

#include "Grove_I2C_Motor_Driver.h" //motor controller

// default I2C address is 0x0f
#define I2C_ADDRESS 0x0f

void setup()
{
Motor.begin(I2C_ADDRESS);

pinMode(signalPin2, INPUT);
pinMode(signalPin, INPUT);

delay(3000);

}

void loop()
{
long RangeInCentimeters;
Serial.println(RangeInCentimeters = ultrasonic.MeasureInCentimeters());
if (RangeInCentimeters <= 15) // checking to see how close an object is
{

// Motor.stop(MOTOR1);
// Motor.stop(MOTOR2);
Motor.speed(MOTOR1, -100);
Motor.speed(MOTOR2, -100);
delay(500);
}

else (RangeInCentimeters > 15);
{
// Motor.stop(MOTOR1);
// Motor.stop(MOTOR2);
Motor.speed(MOTOR1, -25);
Motor.speed(MOTOR2, 25); //motor2 rightside motor 1 left side
delay(250);
}

//line sensor commands

{
if(HIGH == digitalRead(signalPin)) //sensor RIGHT
{
Serial.println("black");
}
else
{
Serial.println("white"); // display the color
//delay(1000); // wait for a second
// Motor.stop(MOTOR1);
// Motor.stop(MOTOR2);
Motor.speed(MOTOR1, 100);
delay(250);
}
}
{
if(HIGH == digitalRead(signalPin2)) //sensor LEFT
{
Serial.println("black2");
}
else {
Serial.println("white2");
// Motor.stop(MOTOR1);
// Motor.stop(MOTOR2);
Motor.speed(MOTOR2, 100);
delay(250);
}

}
}

this is the code that I want to use but the problem is the timing because even though I might get an input value for the sensor detecting the white line it has to finish the other task first creating in accuracy for being able to react to the line.

  else (RangeInCentimeters > 15);oops.

Please start using code tags.

int signalPin = 3; //pin 3
int signalPin2 = 2; //pin 2

#include "Grove_I2C_Motor_Driver.h"         //motor controller

// default I2C address is 0x0f
#define I2C_ADDRESS 0x0f
volatile boolean sensorRight = false;

void setup()
{
  Motor.begin(I2C_ADDRESS);
  Serial.begin(9600);
  pinMode(signalPin2, INPUT);  //setting the sensors to have their values read
  pinMode(signalPin, INPUT);

  attachInterrupt(signalPin, turnRight, FALLING);  //having the function turnRight activate if the sensor gets a low value
  attachInterrupt(signalPin2, turnLeft, FALLING);  //having the function turnLeft activate if the sensor gets a low value
  delay(3000);  //waiting three secounds so I can input power to the arduino


}

void loop()

{
  Motor.speed(MOTOR1, -100);  //having the motors constantly move forward to observe if the Interrupt fires
  Motor.speed(MOTOR2, -100);

  if (sensorRight == true)  //If the interrupt fires the robot should turn here
  {
    Motor.stop(MOTOR2);
    Motor.speed(MOTOR1, 50);
  }

}


void turnRight()     //When the interrupt triggers it changes the value of sensorRight
{
  sensorRight = true;
}

void turnLeft() //this is in place for later when a solution is found
{

  Motor.stop(MOTOR1);
  Motor.speed(MOTOR2, 50);

}