Interrupts

I'm building something that uses an encoder strip salvaged from an inkjet printer.
The code I'm building on uses

cli();

I can't find any documentation on that, is it similar to

noInterrupts();

Yes, it's about the same.

The Arduino core is open source. You can go find the source for noInterrupts():

#define interrupts() sei()
#define noInterrupts() cli()

The cli() function is specific to Atmega controllers. The noInterrupts() is more generic and can be used on non Atmega based Arduinos.

In case of Arduino Uno, Nano, Mega, Micro, Mini cli() and noInterrupts() are same.

the cli(); is used once in the loop, interrups() or sei() is not used, does the cli() or noInterrups() expire at the end of the loop or something?

dirkelectro:
the cli(); is used once in the loop, interrups() or sei() is not used, does the cli() or noInterrups() expire at the end of the loop or something?

cli() is not "expire". But you can enable interrupts back using different methods. Post your code here.

//#include <Wire.h>

//pins for L298N
#define enA 10      //motor 1 pwm
#define in1 8      //motor 1 in1
#define in2 9      //motor 1 in2
#define enB 11      //motor 2 pwm
#define in3 12     //motor 2 in3
#define in4 13     //motor 2 in4

const int frontstop = 100;            // Right most encoder boundary
const int backstop = 9999;            // Left most encoder boundary


const int encoder1PinA = 2;        // X-AXIS  encoder 1 on pins 2 and 4
const int encoder1PinB = 4;
volatile int encoder1Pos = 0;

const int encoder2PinA = 3;        // Y-AXIS  encoder 2 on pins 3 and 5
const int encoder2PinB = 5;
volatile int encoder2Pos = 0;

boolean CarriageDir = 0;           // Carriage Direction '0' is Right to left
//byte spd = 220;                    // Carriage speed from 0-255
byte spd = 100;                    // Carriage speed from 0-255
int newpos = 0;                    // Taget position for carriage
int posrchd = 1;                   // Flag for target reached

int Pos1, Pos2;

const int closeEnough = 10;



void setup() {
  Serial.begin(115200);
  Serial.println("Linear Encoder Test  04-29-2014");

  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  // Set initial rotation direction
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);

  pinMode(encoder1PinA, INPUT_PULLUP);
  pinMode(encoder1PinB, INPUT_PULLUP);
  pinMode(encoder2PinA, INPUT_PULLUP);
  pinMode(encoder1PinB, INPUT_PULLUP);

  attachInterrupt(0, doEncoder1, CHANGE);  // encoder pin on interrupt 0 (pin 2)
  attachInterrupt(1, doEncoder2, CHANGE);  // encoder pin on interrupt 1 (pin 3)
}

void loop() {
  static int oldPos1, oldPos2;
  uint8_t oldSREG = SREG;

  uint8_t i;

  cli(); //same as noInterrupts();
  Pos1 = encoder1Pos;
  Pos2 = encoder2Pos;
  SREG = oldSREG;

  if (Pos1 != oldPos1) {
    Serial.print("Encoder 1=");
    Serial.println(Pos1, DEC);
    oldPos1 = Pos1;
  }
  if (Pos2 != oldPos2) {
    Serial.print("Encoder 2=");
    Serial.println(Pos2, DEC);
    oldPos2 = Pos2;
  }

  if (posrchd) {                          // If target has been reached clear flag, and get new target
    newpos =  random(100, 3000);
    //newpos =  3500;
    posrchd = 0;
  }
  posrchd = go_to_target(newpos); //run function to move to target
}

void doEncoder1() {                                  // ************** X-AXIS ****************
  if (PIND & 0x04) {                              // test for a low-to-high interrupt on channel A,
    if ( !(PIND & 0x10)) {                      // check channel B for which way encoder turned,
      encoder1Pos = ++encoder1Pos;               // CW rotation
      PORTD = PIND | 0x40;                     // set direction output pin to 1 = forward,
    }
    else {
      encoder1Pos = --encoder1Pos;               // CCW rotation
      PORTD = PIND & 0xBF;                     // Set direction output pin to 0 = reverse,
    }
  }
  else {                                          // it was a high-to-low interrupt on channel A
    if (PIND & 0x10) {                          // check channel B for which way encoder turned,
      encoder1Pos = ++encoder1Pos;               // CW rotation
      PORTD = PIND | 0x40;                     // Set direction output pin to 1 = forward,
    }
    else {
      encoder1Pos = --encoder1Pos;               // CCW rotation
      PORTD = PIND & 0xBF;                     // Set direction output pin to 0 = reverse,
    }
  }
  PORTD = PIND | 0x80;                            //  digitalWrite(encoderstep, HIGH);   generate step pulse high
  PORTD = PIND | 0x80;                            //  digitalWrite(encoderstep, HIGH);   add a small delay
  PORTD = PIND & 0x7F;                            //  digitalWrite(encoderstep, LOW);    reset step pulse
}                                                   // End of interrupt code for encoder #1

void doEncoder2() {                                 // ************** Y-AXIS ****************
  if (PIND & 0x08) {                                // test for a low-to-high interrupt on channel A,
    if (!(PIND & 0x20)) {                          // check channel B for which way encoder turned,
      encoder2Pos = ++encoder2Pos;                  // CW rotation
      PORTB = PINB | 0x01;                          // Set direction output pin to 1 = forward,
    }
    else {
      encoder2Pos = --encoder2Pos;                  // CCW rotation
      PORTD = PIND & 0xFE;                          // Set direction output pin to 0 = reverse,
    }
  }
  else {                                            // it was a high-to-low interrupt on channel A
    if (PIND & 0x20) {                             // check channel B for which way encoder turned,
      encoder2Pos = ++encoder2Pos;                  // CW rotation
      PORTB = PINB | 0x01;                          // Set direction output pin to 1 = forward,
    }
    else {
      encoder2Pos = --encoder2Pos;                  // CCW rotation
      PORTB = PINB & 0xFE;                          // Set direction output pin to 0 = reverse,
    }
  }
  PORTB = PINB | 0x02;                              // digitalWrite(encoder2step, HIGH);   generate step pulse high
  PORTB = PINB | 0x02;                              // digitalWrite(encoder2step, HIGH);   used to add a small delay
  PORTB = PINB & 0xFD;                              // digitalWrite(encoder2step, LOW);    reset step pulse
}                                                   // End of interrupt code for encoder #2

/***************************************************************************************
  go_to_target() determines the distance and direction from current position to target
  position, then maps speed to decellerate close to the target so as not to overshoot.
***************************************************************************************/

int go_to_target(int target)
{
  int temp = 0;
  //int delta = abs(Pos1 - target);                 // Distance to target
  ///spd = map(delta, 3600, 0, 255, 150);            // Decellerate as you get closer
  // spd = map(delta, 3600, 0, 100, 150);            // Decellerate as you get closer
  spd = 100;            // Decellerate as you get closer
  if (target < backstop && target > frontstop) {

    if (Pos1 > target - closeEnough && Pos1 < target + closeEnough) { //if close close enough stop motor
      //myMotor->run(OFF);
      analogWrite(enA, spd);
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
    } else

      if (Pos1 < target) {
        //myMotor->run(FORWARD);
        analogWrite(enA, spd);
        digitalWrite(in1, LOW);
        digitalWrite(in2, HIGH);
        temp = 0;
      } else if (Pos1 > target) {
        //myMotor->run(BACKWARD);
        analogWrite(enA, spd);
        digitalWrite(in1, HIGH);
        digitalWrite(in2, LOW);
        temp = 0;
      }  else temp = 1;
  }
  return temp;
}
SREG = oldSREG;

This statement re-enables interrupts. (Works only for Atmega based Arduinos)

alesam:

SREG = oldSREG;

This statement re-enables interrupts. (Works only for Atmega based Arduinos)

That works only if you set this line above the cli()/noInterrupts() call:

 uint8_t oldSRED = SREG;

pylon:
That works only if you set this line above the cli()/noInterrupts() call:

 uint8_t oldSRED = SREG;

Have you seen code posted by TS? That line is present there. So SREG = oldSREG; will restore an interrupts*.*

Have you seen code posted by TS? That line is present there. So SREG = oldSREG; will restore an interrupts.

There is no post by "TS" in this thread. I found the mentioned code in the post above yours, so you probably referred to there but you didn't explicitly told so. A user reading the thread might interpret your post as that your one line does restore interrupts and that is simply not true.

pylon:
There is no post by "TS" in this thread.

TS = thread starter