[SOLVED]Program freezes when using an encoder

Hi everybody! I am using a rotary encoder to add or subtract from a value when rotating back and forth. I noticed that when a make a rapid spin the program becomes frozen. I tried a software delay so the program wont bug when I spin fast but I don't think that the delay even works on encoder because of the interrupt thing. Has anyone encountered this problem?

And how are we supposed to have a clue what your problem is without seeing any of your (obviously buggy) code? We're not psychic....

Regards,
Ray L.

It's difficult for us to help when we can't see the code. Please read Nick Gammon's two posts at the top of this Forum, especially about using code tags when posting, then format the code in the IDE using Ctrl-T before posting. This will help us help you. BTW, using delay() may not be a good idea, as most encoder routines use interrupts and delay() is a blocking function call.

interrupt

Are all the variables updated by the ISR declared as volatile ?

Who knows because you did not post your code.

Sorry for that, here is the code:

  /*
  * CS(pin?) - to digital pin 10  (SS pin)
  * SI(pin?) - to digital pin 11 (MOSI pin)
  * SCK(pin?) - to digital pin 13 (SCK pin)
  */

#include <SPI.h> // inslude the SPI library
#define encoder0PinA  2 //pin A on the encoder
#define encoder0PinB  3 //pin B on the encoder
word outputValue = 0; // a word is a 16-bit number
byte data = 0; // and a byte is an 8-bit number
volatile unsigned int encoder0Pos = 0; //variable to store the encoder position
word ButtonDAC = 0;
boolean State = 0;    //0 = button 1 = encoder

const int slaveSelectPin = 10;// set pin 10 as the slave select 

//buttons
const byte  ButtonPin1 = 4;    // the pin that the pushbutton is attached to (up cycle ++)
const byte  ButtonPin2 = 5;    // the pin that the pushbutton is attached to (down cycle --)
const byte  ButtonPin3 = 6;    // the pin that the pushbutton is attached to (xx.xx or x.xxx two separate high signals)

// Variables will change:
byte ButtonPushCounter1 = 0;   // counter for the number of button presses
byte ButtonState1 = 0;         // current state of the button
byte lastButtonState1 = 0;     // previous state of the button

byte ButtonPushCounter2 = 0;   // counter for the number of button presses
byte ButtonState2 = 0;         // current state of the button
byte lastButtonState2 = 0;     // previous state of the button

byte ButtonPushCounter3 = 0;   // counter for the number of button presses
byte ButtonState3 = 0;         // current state of the button
byte lastButtonState3 = 0;     // previous state of the button
//buttons
int decim2 = 8;          //deseti4na zapetaq
int decim3 = 9;        // deseti4na zapetaq 2

void setup() {
  pinMode(decim2, OUTPUT);
  pinMode(decim3, OUTPUT);
  //Button intiliazation
  // initialize the button pin as a input:
  pinMode(ButtonPin1, INPUT);
  // initialize the button pin as a input:
  pinMode(ButtonPin2, INPUT);
  // initialize the button pin as a input:
  pinMode(ButtonPin3, INPUT);
 
  //SPI initilization
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin(); 
  
  //Encoder 
  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor

  attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
 
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println(ButtonPushCounter1);
}


void loop() 

//Button coding
{
  ButtonState1 = digitalRead(ButtonPin1);
  ButtonState2 = digitalRead(ButtonPin2);
  ButtonState3 = digitalRead(ButtonPin3);
  //Button1 up cycle
   if(ButtonState1 && ButtonState1 != lastButtonState1)  // button latch, no debounce needed.
   {
     State = 0;
    if(ButtonPushCounter1 < 4) // This will check to see if the count is within a range of 0 - 3, and anything over that, it will reset count back to 0.
     ButtonPushCounter1 ++ ; // increase with one
     else{
     ButtonPushCounter1 = 0;
     } 
     delay(185);
   Serial.print("Button1 position: "); 
   Serial.println(ButtonPushCounter1); //print the number of times the button is pushed
   ButtonDAC=ButtonPushCounter1*0.25*4095;
   Serial.println(ButtonDAC);
  }
  //Button2 down cycle
  if(ButtonState2 && ButtonState2 != lastButtonState2)  // button latch, no debounce needed.
   {
     State = 0;
    if(ButtonPushCounter1 <= 4 && ButtonPushCounter1 > 0) // This will check to see if the count is within a range of 0 - 3, and anything over that, it will reset count back to 0.
     ButtonPushCounter1 -- ; // increase with one
     else{
     ButtonPushCounter1 = 4;
     } 
      delay(185);
   Serial.print("Button2 position: ");  
   Serial.println(ButtonPushCounter1); //print the number of times the button is pushed
   ButtonDAC=ButtonPushCounter1*0.25*4095;
   Serial.println(ButtonDAC);
  }
  //Button3 xx.xx or x.xxx
  if(ButtonState3 && ButtonState3 != lastButtonState3)  // button latch, no debounce needed.
   {
    if(ButtonPushCounter3 < 1) // This will check to see if the count is within a range of 0 - 3, and anything over that, it will reset count back to 0.
     ButtonPushCounter3 ++ ; // increase with one
     else{
     ButtonPushCounter3 = 0;
     } 
     delay(185);
   Serial.print("Button3 position: ");  
   Serial.println(ButtonPushCounter3); //print the number of times the button is pushed
  }
  
  if (ButtonPushCounter3 == 0){
    digitalWrite(decim3, LOW);
    digitalWrite(decim2, HIGH);
  }
    else
    {
      digitalWrite(decim2, LOW);
      digitalWrite(decim3, HIGH);
    }
  //Saving the last position of the button
  lastButtonState1 = ButtonState1;
  lastButtonState2 = ButtonState2;
  lastButtonState3 = ButtonState3;

 //Encoder SPI coding 


  int level=0;
  {
    if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
    { 
     digitalDACWrite(encoder0Pos); //Sets the level of the potentiometer to the level of the encoder in this case 1 up
    }
    else 
    {
     digitalDACWrite(encoder0Pos); //Sets the level of the potentiometer to the level of the encoder in this case 1 down
    }
  }


}



  void doEncoder() {
  /* If pinA and pinB are both high or both low, it is spinning
   * forward. If they're different, it's going backward.
   *
   * For more information on speeding up this process, see
   * [Reference/PortManipulation], specifically the PIND register.
   */

  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    if (encoder0Pos <= (4095 - 5)) 
    {
      encoder0Pos+=5;
      State = 1;
    }
  } else {
    if (encoder0Pos >= (0 + 5)) 
    {
      encoder0Pos-=5;
      State = 1;
    }
  }

  Serial.println (encoder0Pos, DEC);
}

  void digitalDACWrite(int value) {
    if (State == 0) outputValue = ButtonDAC;
    else outputValue = value;
    digitalWrite(10, LOW);
    data = highByte(outputValue);
    data = 0b00001111 & data;
    data = 0b00110000 | data;
    SPI.transfer(data);
    data = lowByte(outputValue);
    SPI.transfer(data);
    digitalWrite(10, HIGH); 

}

There are several things I don't understand. In several places you have statements like:

    if (encoder0Pos <= (4095 - 5)) 
    // ...other code...
    if (encoder0Pos >= (0 + 5))

Because the second expressions do not use variables, why not use 4090 and 5 for the expressions?

Also, I's not sure you want to put a Serial.print() call in your encoder routine, as I think that is a blocking function call.

@econjack - Its about the step size and it is to remind me its there( I know it sounds stupid)
@Delta_G Thanks man, after I removed the Serial.println (encoder0Pos, DEC) the freezing stopped. You're awesome :slight_smile: