Slow encoder response

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I am using Arduino Uno
I read the analog input and compare it to a value that I want.

I also use hysteresis and delay to run two pwm controlled motors.

When I run the program below, everything works fine if I turn the encoder slowly, any value is left in any of its output when I turn the encoder a little fast.

Is the logic in the program completely wrong?

 

<

   int val;
   int val2;
   int buttonState;
   int Mode = 0;

  enum PinAssignments
 { 
  encoderPinA = 2,   
  encoderPinB = 3,   
  clearButton = A4,  
  switchPin = A5, 
  } ;
  
  volatile unsigned int encoderPos = 320;  // degree celcius
  volatile unsigned int encoderPos_time = 5;  
  volatile unsigned int encoderPos_hyst = 6;  
  unsigned int lastReportedPos = 0;   
  static boolean rotating = false;   

  boolean A_set = false;
  boolean B_set = false;

  #define COLD 11  
  #define HOT 10 
    
  long int coldout = 0;
  long int hotout = 0;
  
  long int analog_input = 0; 
  long int analog_input_1 = 0; 

  unsigned int count_two = 0;
  unsigned int num = 0;
  
  unsigned int count_time = 0;
  unsigned int count_hyst = 0;
  
  void setup() 
  { 
  pinMode (COLD, OUTPUT);
  pinMode (HOT, OUTPUT); 
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  
  pinMode(clearButton, INPUT_PULLUP);
  pinMode(switchPin, INPUT_PULLUP);
  
  buttonState = digitalRead(switchPin);   
  attachInterrupt(0, doEncoderA, CHANGE);
  attachInterrupt(1, doEncoderB, CHANGE);
  
     } 
  void loop()
    { 
     val =  digitalRead(switchPin);
    delay (10);
    val2 =  digitalRead(switchPin);
      if (val == val2) {
        if (val != buttonState){
          if (val== LOW ) {
            if (Mode == 0) {
                  Mode = 1;               
                           } 
                    else
                          {
                  if (Mode == 1) {       
                         Mode = 2;           
                                 } 
                    else
                            {
                    if (Mode == 2) {     
                          Mode = 0;         
                                  }
                            }
                    }
              }
          buttonState = val;
             } 
       if (Mode == 0) { 
          {
            if (lastReportedPos != encoderPos) 
                 {
                  lastReportedPos = encoderPos;
                 }
              } 
          }
          if (Mode == 1){ 
            {
            if (lastReportedPos != encoderPos) 
                 {
                  lastReportedPos = encoderPos;
                 }
              } 
           }
          if (Mode == 2){ 
                 {
            if (lastReportedPos != encoderPos) 
                 {
                  lastReportedPos = encoderPos;
                 }
              } 
           }
        rotating = true;  // reset the debouncer
        
        if (digitalRead(clearButton) == LOW ){
                 {
                  encoderPos = 328;
                  }  
                  {
                  encoderPos_time = 1;
                  } 
                  {
                 encoderPos_hyst = 0;
                 }
             } 
        }      
  { 
  for (int i=0;i<500;i++)
  analog_input = analog_input + analogRead(A0);
  delay (1);
  }
   analog_input = analog_input / 501 ; // testing purpose
  
  int converted = map((analog_input*0.963), 0, 1023, 0,5000);  
       
  analog_input_1 = (analog_input/2.1258);// testing purpose
           
      //-- CHECK FROM HERE 
      
        double gap = abs((encoderPos-encoderPos_hyst) - analog_input_1); 
        double gap2 = abs((encoderPos+encoderPos_hyst) - analog_input_1);  

       if (analog_input_1 >= (encoderPos-encoderPos_hyst))
       if (analog_input_1 >= (encoderPos+encoderPos_hyst))// ** 
           {
         coldout = gap2 ;
         coldout = coldout*25; // testing purpose
         coldout = min(coldout,250); // testing purpose
         hotout == 0;
           }
          else
            {
          coldout == 0;
            }
           analogWrite(COLD,coldout);
        {
         if (analog_input_1 <= (encoderPos-encoderPos_hyst))
         if (analog_input_1 <= (encoderPos+encoderPos_hyst))// ** 
        {
         hotout = gap;
         hotout = hotout*25;  // testing purpose
         hotout = min(hotout,250); // testing purpose
         coldout == 0;
          }
          else
            {
          hotout == 0;
            }
          analogWrite(HOT,hotout); 
         }
             
    unsigned char i=0;
    unsigned int k = 0;
    while(number)
    { 
        k = ( k ) | ((number%10) << i*4);
        number = number / 10;
        i++;
    } 
    return(k);
  } 
  void doEncoderA()  // with debounce 
     { 
      if ( rotating ) delay (2); 
      
      if ( digitalRead(encoderPinA) != A_set )
        { 
        A_set = !A_set;
        
          if ( A_set && !B_set )
            if (Mode == 0) {
                            encoderPos += 1;
                            }
            else                
            if (Mode == 1) {
                            encoderPos_time += 1;
                            }
            else                
            if (Mode == 2) {
                            encoderPos_hyst += 1;
                            }     
                            
        rotating = false;  // no more debouncing until loop() hits again
             } 
      } 
    void doEncoderB() //with DEBOUNCE
      { 
      if ( rotating ) delay (2);
        if ( digitalRead(encoderPinB) != B_set )
         { 
            B_set = !B_set;
            
              if ( B_set && !A_set )
                if (Mode == 0) {
                            encoderPos -= 1;
                            }
                  else          
                if (Mode == 1) {
                            encoderPos_time -= 1;
                            }
                 else                
                if (Mode == 2) {
                            encoderPos_hyst -= 1;
                            }            
              rotating = false;
                
                  }
       } 

      >

Last Edited: Tue. Dec 1, 2020 - 08:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is the logic in the program completely wrong?    Yes!  If the program doesn't work and it's over a page long, then, yes, no one has to read your code to determine that the logic is wrong.

  You don't tell us what you analog input source is, how your motors are connected, or what an encoder has to do with any of it.  And you expect us to analyze about 180 lines of code that just goes on and on....

 

An encoder routine has three lines of code: 

 

First line in main() enables the pin-change interrupt that is triggered when one of the encoder pins changes. 

 

The second line (in the IRQ routine) tests the other encoder pin to determine the direction of the movement. 

 

And the third line sets a boolean flag to the main code that indicates that an encoder movement has happened and its direction.

 

Name your booleans so that they make sense when assigned TRUE or FALSE values.  For example, if you have one encoder, your boolean flags to the the main() will be   isEncoderBeingTurnedLeft = TRUE; and isEncoderBeingTurnedRight = FALSE.  With no turning, both will be FALSE.  If they are both TRUE, then your main() is not processing these flags fast enough.

Last Edited: Mon. Nov 30, 2020 - 05:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn't look very deeply at your code, but delaying in your interrupts could be a problem. I don't even think delay() works within interrupts. And you probably don't want to be waiting around for 2ms in an interrupt anyhow. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's Arduino! Why are you reinventing encoder support? It's right there waiting for you to use already.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta,

Thank you very much indeed. I didn't expect such a quick response.

I will follow your suggestions.

Best regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nerull wrote:

I didn't look very deeply at your code, but delaying in your interrupts could be a problem. I don't even think delay() works within interrupts. And you probably don't want to be waiting around for 2ms in an interrupt anyhow. 

Hello Nerull,

I tested delay(2), but no change, thank you very much for your kind interest

Regards,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

It's Arduino! Why are you reinventing encoder support? It's right there waiting for you to use already.

Hello Clawson,

Believe me, Avrfreaks people more clever than Arduino.

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Glamo wrote:
Avrfreaks people more clever than Arduino.
Um no. The encoder support in Arduino is either done by Adafruit or Paul Stoffregen (PJRC) - both of whom are top rank AVR engineers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Glamo wrote:

Avrfreaks people more clever than Arduino.

 

Um no. The encoder support in Arduino is either done by Adafruit or Paul Stoffregen (PJRC) - both of whom are top rank AVR engineers.

 

Thanks for helping me find the most clever one.

Even this answer justifies me.

Thanks a lot.

Last Edited: Tue. Dec 1, 2020 - 10:09 AM