HELP! Need delay in ISR.

Hello,

I am dying here. I have a simple timer ISR for what is called “Motors Under No Load”. Basically the point is to check the current sensors for a no-load condition since a load would imply high current and no load would imply low current. The issue is, when do I turn the motors back on? So if I turn the motors off because there is no load I now have to find out if a load is present. My quick fix was that I would pulse the motors to see if a load was present. Next issue: when I pulse the motors there’s in-rush current! So now the current is super-high and to the mc it thinks that a load is present. So, what I need to do is pulse the motors and wait for the current to stabilize before I read them. Should only take about 50 ms or so to do this but I can’t seem to write the motor enable pin high then delay for a moment and then read the current sensor pin.

If you have any ideas or suggestions all are welcome :slight_smile:

Don’t be too harsh on the code, it’s a work in progress. Just trying to make it work.

volatile uint8_t curr_state3 = 0;
volatile uint8_t curr_state1 = 0;
volatile uint8_t curr_state2 = 0;
volatile uint8_t curr_state4 = 0;
volatile uint8_t curr_state5 = 0;
volatile uint8_t curr_state6 = 0;
volatile boolean LED_state = LOW;
const uint8_t currentThreshold = 50;
volatile uint16_t currentReading1_1 = 0;
volatile uint16_t currentReading1_2 = 0;
volatile uint16_t currentReading1_3 = 0;
volatile uint16_t currentReadingave1 = 0;
volatile boolean nlclk = HIGH;
volatile boolean nlclk2 = HIGH;
#define LED_pin 46
#define M3CS A4 // Motor 3 Current Sensor
#define M1CS A1 // Motor 2 Current Sensor
#define M3EN 34 // Motor 3 Enable
#define M1EN 25 // Motor 2 Enable
#define M3INA 36 // Motor 3 Input A
#define M3INB 37 // Motor 3 Input B
#define M1INA 26 // Motor 2 Input A
#define M1INB 27 // Motor 2 Input B
#define M3PWM 6 // Motor 3 PWM Signal
#define M1PWM 7 // Motor 2 PWM Signal

void setup() {
Serial.begin(9600);
pinMode(LED_pin, OUTPUT);
pinMode(M1CS, INPUT);

pinMode(M1EN, OUTPUT);

pinMode(M1INA, OUTPUT);
pinMode(M1INB, OUTPUT);

pinMode(M1PWM, OUTPUT);

cli();//stop interrupts

//set timer5 interrupt at 0.25 Hz
TCCR5A = 0;// set entire TCCR2A register to 0
TCCR5B = 0;// same for TCCR2B
TCNT5 = 0;//initialize counter value to 0
// set compare match register for 1 Hz increments
OCR5A = 62496;// = (16*10^6) / (256) - 1 (must be <65536)
// turn on CTC mode with WGM52
// Set CS52 and CS50 bit for 1024 prescaler
TCCR5B |= (1 << CS52) | (1 << WGM52) | (1 << CS50);
// enable timer compare interrupt
TIMSK5 |= (1 << OCIE5A);

sei();//allow interrupts
delay(1000);
leftmotorsforward(250);
delay(1000);
}//end setup

ISR(TIMER5_COMPA_vect) { // Interrupts every second
// This routine takes about 600 uS and might upset the value from
// 6 wheel differential. Due to this, this ISR is only performed every second.
// Need to average values of currentReading to get a better estimate of current
// passing through motors.

// No-Load FSM for Motor 1
// State 0.1
nlclk = !nlclk;
if (nlclk == HIGH) {
nlclk2 = !nlclk2;
if (nlclk2 = HIGH) {
uint8_t next_state1;
if (curr_state1 == 0) {
// Check motors to see if they are under no load
currentReading1_1 = analogRead(M1CS);
currentReading1_2 = analogRead(M1CS);
currentReading1_3 = analogRead(M1CS);
currentReadingave1 = (currentReading1_1 + currentReading1_2 + currentReading1_3) / 3;
if (currentReadingave1 < currentThreshold) { // Go to state 1
digitalWrite(M1EN, LOW);
next_state1 = 1;
}
else {
next_state1 = 0; // Remain in state 0
}
}
// State 1.1
else {
// Apply power to motors and check if they are under load
digitalWrite(M1EN, HIGH);
uint16_t curr_time = millis();
uint16_t lapsedtime = 0;
while (lapsedtime < 200) {
uint16_t pres_time = millis();
lapsedtime = pres_time - curr_time;
}
currentReading1_1 = analogRead(M1CS);
currentReading1_2 = analogRead(M1CS);
currentReading1_3 = analogRead(M1CS);
currentReadingave1 = (currentReading1_1 + currentReading1_2 + currentReading1_3) / 3;
digitalWrite(M1EN, LOW);
if (currentReadingave1 < currentThreshold) { // Remain in State 1
next_state1 = 1;
}
else {
next_state1 = 0; // Otherwise go to state 0
digitalWrite(M1EN, HIGH);
}
}
curr_state1 = next_state1;
}
}
/*
// No-Load FSM for Motor 2
// State 0.2
if(curr_state2 == 0){
// Check motors to see if they are under no load
int currentReading2 = analogRead(currentPin2);
if (currentReading2 < currentThreshold){ // Go to state 1
motor_enable2 = 0;
next_state2 = 1;
}
else{next_state2 = 0;} // Remain in state 0
}
// State 1.1
else{
// Apply power to motors and check if they are under load
motor_enable2 = 1;
delayMicroseconds(10);
currentReading2 = analogRead(currentPin2);
if (currentReading2 < currentThreshold){ // Remain in State 1
motor_enable2 = 0;
next_state2 = 1;
}
else{next_state2 = 0;} // Otherwise go to state 0
}
curr_state2 = next_state2;

// No-Load FSM for Motor 3
// State 0.3
if(curr_state3 == 0){
// Check motors to see if they are under no load
int currentReading3 = analogRead(currentPin3);
if (currentReading3 < currentThreshold){ // Go to state 1
motor_enable3 = 0;
next_state3 = 1;
}
else{next_state3 = 0;} // Remain in state 0
}
// State 1.3
else{
// Apply power to motors and check if they are under load
motor_enable3 = 1;
delayMicroseconds(10);
currentReading3 = analogRead(currentPin3);
if (currentReading3 < currentThreshold){ // Remain in State 1
motor_enable3 = 0;
next_state3 = 1;
}
else{next_state3 = 0;} // Otherwise go to state 0
}
curr_state3 = next_state3;

// No-Load FSM for Motor 4
// State 0.4
if(curr_state4 == 0){
// Check motors to see if they are under no load
int currentReading4 = analogRead(currentPin4);
if (currentReading4 < currentThreshold){ // Go to state 1
motor_enable4 = 0;
next_state4 = 1;
}
else{next_state4 = 0;} // Remain in state 0
}
// State 1.4
else{
// Apply power to motors and check if they are under load
motor_enable4 = 1;
delayMicroseconds(10);
currentReading4 = analogRead(currentPin4);
if (currentReading4 < currentThreshold){ // Remain in State 1
motor_enable4 = 0;
next_state4 = 1;
}
else{next_state4 = 0;} // Otherwise go to state 0
}
curr_state4 = next_state4;

// No-Load FSM for Motor 5
// State 0.5
if(curr_state5 == 0){
// Check motors to see if they are under no load
int currentReading5 = analogRead(currentPin5);
if (currentReading5 < currentThreshold){ // Go to state 1
motor_enable5 = 0;
next_state5 = 1;
}
else{next_state5 = 0;} // Remain in state 0
}
// State 1.5
else{
// Apply power to motors and check if they are under load
motor_enable5 = 1;
delayMicroseconds(10);
currentReading5 = analogRead(currentPin5);
if (currentReading5 < currentThreshold){ // Remain in State 1
motor_enable5 = 0;
next_state5 = 1;
}
else{next_state5 = 0;} // Otherwise go to state 0
}
curr_state5 = next_state5;

// No-Load FSM for Motor 6
// State 0.6
if(curr_state6 == 0){
// Check motors to see if they are under no load
int currentReading6 = analogRead(currentPin6);
if (currentReading6 < currentThreshold){ // Go to state 1
motor_enable6 = 0;
next_state6 = 1;
}
else{next_state6 = 0;} // Remain in state 0
}
// State 1.6
else{
// Apply power to motors and check if they are under load
motor_enable6 = 1;
delayMicroseconds(10);
currentReading6 = analogRead(currentPin6);
if (currentReading6 < currentThreshold){ // Remain in State 1
motor_enable6 = 0;
next_state6 = 1;
}
else{next_state6 = 0;} // Otherwise go to state 0
}
curr_state6 = next_state6;
*/
}

void loop() {
Serial.println(currentReadingave1);
}

No_LoadISRPC.ino (6.96 KB)

You’re supposed to post your code like this:

volatile uint8_t curr_state3 = 0;
volatile uint8_t curr_state1 = 0;
volatile uint8_t curr_state2 = 0;
volatile uint8_t curr_state4 = 0;
volatile uint8_t curr_state5 = 0;
volatile uint8_t curr_state6 = 0;
volatile boolean  LED_state = LOW;
const uint8_t currentThreshold = 50;
volatile uint16_t currentReading1_1 = 0;
volatile uint16_t currentReading1_2 = 0;
volatile uint16_t currentReading1_3 = 0;
volatile uint16_t currentReadingave1 = 0;
volatile boolean nlclk = HIGH;
volatile boolean nlclk2 = HIGH;
#define LED_pin 46
#define M3CS A4 // Motor 3 Current Sensor
#define M1CS A1 // Motor 2 Current Sensor
#define M3EN 34 // Motor 3 Enable
#define M1EN 25 // Motor 2 Enable
#define M3INA 36 // Motor 3 Input A
#define M3INB 37 // Motor 3 Input B
#define M1INA 26 // Motor 2 Input A
#define M1INB 27 // Motor 2 Input B
#define M3PWM 6 // Motor 3 PWM Signal
#define M1PWM 7 // Motor 2 PWM Signal


void setup() {
  Serial.begin(9600);
  pinMode(LED_pin, OUTPUT);
  pinMode(M1CS, INPUT);


  pinMode(M1EN, OUTPUT);


  pinMode(M1INA, OUTPUT);
  pinMode(M1INB, OUTPUT);


  pinMode(M1PWM, OUTPUT);




  cli();//stop interrupts




  //set timer5 interrupt at 0.25 Hz
  TCCR5A = 0;// set entire TCCR2A register to 0
  TCCR5B = 0;// same for TCCR2B
  TCNT5  = 0;//initialize counter value to 0
  // set compare match register for 1 Hz increments
  OCR5A = 62496;// = (16*10^6) / (256) - 1 (must be <65536)
  // turn on CTC mode with WGM52
  // Set CS52 and CS50 bit for 1024 prescaler
  TCCR5B |= (1 << CS52) | (1 << WGM52) | (1 << CS50);
  // enable timer compare interrupt
  TIMSK5 |= (1 << OCIE5A);




  sei();//allow interrupts
  delay(1000);
  leftmotorsforward(250);
  delay(1000);
}//end setup




ISR(TIMER5_COMPA_vect) { // Interrupts every second
  // This routine takes about 600 uS and might upset the value from
  // 6 wheel differential. Due to this, this ISR is only performed every second.
  // Need to average values of currentReading to get a better estimate of current
  // passing through motors.


  // No-Load FSM for Motor 1
  // State 0.1
  nlclk = !nlclk;
  if (nlclk == HIGH) {
    nlclk2 = !nlclk2;
    if (nlclk2 = HIGH) {
      uint8_t next_state1;
      if (curr_state1 == 0) {
        // Check motors to see if they are under no load
        currentReading1_1 = analogRead(M1CS);
        currentReading1_2 = analogRead(M1CS);
        currentReading1_3 = analogRead(M1CS);
        currentReadingave1 = (currentReading1_1 + currentReading1_2 + currentReading1_3) / 3;
        if (currentReadingave1 < currentThreshold) { // Go to state 1
          digitalWrite(M1EN, LOW);
          next_state1 = 1;
        }
        else {
          next_state1 = 0; // Remain in state 0
        }
      }
      // State 1.1
      else {
        // Apply power to motors and check if they are under load
        digitalWrite(M1EN, HIGH);
        uint16_t curr_time = millis();
        uint16_t lapsedtime = 0;
        while (lapsedtime < 200) {
          uint16_t pres_time = millis();
          lapsedtime = pres_time - curr_time;
        }
        currentReading1_1 = analogRead(M1CS);
        currentReading1_2 = analogRead(M1CS);
        currentReading1_3 = analogRead(M1CS);
        currentReadingave1 = (currentReading1_1 + currentReading1_2 + currentReading1_3) / 3;
        digitalWrite(M1EN, LOW);
        if (currentReadingave1 < currentThreshold) { // Remain in State 1
          next_state1 = 1;
        }
        else {
          next_state1 = 0;  // Otherwise go to state 0
          digitalWrite(M1EN, HIGH);
        }
      }
      curr_state1 = next_state1;
    }
  }
  /*
      // No-Load FSM for Motor 2
      // State 0.2
    if(curr_state2 == 0){
      // Check motors to see if they are under no load
      int currentReading2 = analogRead(currentPin2);
      if (currentReading2 < currentThreshold){ // Go to state 1
        motor_enable2 = 0;
        next_state2 = 1;
      }
      else{next_state2 = 0;} // Remain in state 0
      }
    // State 1.1
    else{
      // Apply power to motors and check if they are under load
      motor_enable2 = 1;
      delayMicroseconds(10);
      currentReading2 = analogRead(currentPin2);
          if (currentReading2 < currentThreshold){ // Remain in State 1
        motor_enable2 = 0;
        next_state2 = 1;
      }
      else{next_state2 = 0;} // Otherwise go to state 0
      }
    curr_state2 = next_state2;


      // No-Load FSM for Motor 3
      // State 0.3
    if(curr_state3 == 0){
      // Check motors to see if they are under no load
      int currentReading3 = analogRead(currentPin3);
      if (currentReading3 < currentThreshold){ // Go to state 1
        motor_enable3 = 0;
        next_state3 = 1;
      }
      else{next_state3 = 0;} // Remain in state 0
      }
    // State 1.3
    else{
      // Apply power to motors and check if they are under load
      motor_enable3 = 1;
      delayMicroseconds(10);
      currentReading3 = analogRead(currentPin3);
          if (currentReading3 < currentThreshold){ // Remain in State 1
        motor_enable3 = 0;
        next_state3 = 1;
      }
      else{next_state3 = 0;} // Otherwise go to state 0
      }
    curr_state3 = next_state3;


      // No-Load FSM for Motor 4
      // State 0.4
    if(curr_state4 == 0){
      // Check motors to see if they are under no load
      int currentReading4 = analogRead(currentPin4);
      if (currentReading4 < currentThreshold){ // Go to state 1
        motor_enable4 = 0;
        next_state4 = 1;
      }
      else{next_state4 = 0;} // Remain in state 0
      }
    // State 1.4
    else{
      // Apply power to motors and check if they are under load
      motor_enable4 = 1;
      delayMicroseconds(10);
      currentReading4 = analogRead(currentPin4);
          if (currentReading4 < currentThreshold){ // Remain in State 1
        motor_enable4 = 0;
        next_state4 = 1;
      }
      else{next_state4 = 0;} // Otherwise go to state 0
      }
    curr_state4 = next_state4;


      // No-Load FSM for Motor 5
      // State 0.5
    if(curr_state5 == 0){
      // Check motors to see if they are under no load
      int currentReading5 = analogRead(currentPin5);
      if (currentReading5 < currentThreshold){ // Go to state 1
        motor_enable5 = 0;
        next_state5 = 1;
      }
      else{next_state5 = 0;} // Remain in state 0
      }
    // State 1.5
    else{
      // Apply power to motors and check if they are under load
      motor_enable5 = 1;
      delayMicroseconds(10);
      currentReading5 = analogRead(currentPin5);
          if (currentReading5 < currentThreshold){ // Remain in State 1
        motor_enable5 = 0;
        next_state5 = 1;
      }
      else{next_state5 = 0;} // Otherwise go to state 0
      }
    curr_state5 = next_state5;


      // No-Load FSM for Motor 6
      // State 0.6
    if(curr_state6 == 0){
      // Check motors to see if they are under no load
      int currentReading6 = analogRead(currentPin6);
      if (currentReading6 < currentThreshold){ // Go to state 1
        motor_enable6 = 0;
        next_state6 = 1;
      }
      else{next_state6 = 0;} // Remain in state 0
      }
    // State 1.6
    else{
      // Apply power to motors and check if they are under load
      motor_enable6 = 1;
      delayMicroseconds(10);
      currentReading6 = analogRead(currentPin6);
          if (currentReading6 < currentThreshold){ // Remain in State 1
        motor_enable6 = 0;
        next_state6 = 1;
      }
      else{next_state6 = 0;} // Otherwise go to state 0
      }
    curr_state6 = next_state6;
  */
}




void loop() {
  Serial.println(currentReadingave1);
}

You have set up a Timer5 compare match interrupt to fire at .25Hz ( every four seconds).

With this sort of period, I see no reason why your code should not use a millis() based timer calling a function instead of an ISR, the then you would have all sorts of freedom to handle your measurements.

An ISR should be simple and should NOT contain any form of delays.

Instead, use millis() and learn about Finite State Machines.

nadroj_55:
Should only take about 50 ms or so to do this but I can't seem to write the motor enable pin high then delay for a moment and then read the current sensor pin.

What about something like this pseudo code

void loop() {
   if (motorStarted == false) {
      digitalWrite(motorPin, HIGH);
      startMicros = micros();
      motorStarted = true;
   }
   if (motorStarted == true) {
     if (micros() - startMicros >= settlingPeriod) {
        // read the current
        motorStarted = false;
        digitalWrite(motorPin, LOW);
      }
   }
   // other code
}

...R

This 'if" statement is unnecessary:

   if (motorStarted == true) {

The variable motorStarted will always be true at this point... or did I not read something correctly?

vaj4088:
The variable motorStarted will always be true at this point... or did I not read something correctly?

You are probably correct. Maybe it needs to be a 3-state variable - waiting, started, done.

Let's wait to hear from the OP about what he plans to to.

...R