caarlosmoura / adaencoder

Automatically exported from code.google.com/p/adaencoder
0 stars 0 forks source link

Arduino Mega 2560 always loop to CW #1

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Arduino Mega 2560 always loop to CW
2.
3.

What is the expected output? What do you see instead?

Test OK on Arduino Mini Pro (mega 328)

What version of the product are you using? On what operating system?

Current version (updated PinChangeInt)

Please provide any additional information below.

Please help...

Original issue reported on code.google.com by ad...@serveurperso.com on 11 Sep 2011 at 9:04

GoogleCodeExporter commented 8 years ago
Unfortunately, the Mega 2560 is not supported by PinChangeInt.  That said, I 
don't see why it wouldn't work.  The  Interrupt code is supposed to be the 
same.  Can you go into the code, #define DEBUG, and send me the output?

Also, post your sketch.

My email is mschwage@gmail.com

Thanks.

Original comment by m...@schwager.com on 24 Sep 2011 at 4:02

GoogleCodeExporter commented 8 years ago
Thank you for responding.

Yes indeed, I saw later PinChangeInt that does not work with Mega2560...
So I developed myself the reading of the encoder. It work like your code but 
use CHANGE PIN triggered external interrupts

Here is my code :

#include <digitalWriteFast.h>

#define encoderPinA 2
#define encoderPinB 3
#define encoderPinBtn 4
#define encoderPinSwt 5

#define spkPin 12

volatile int16_t encoderPosition = 0;
volatile int8_t encoderState = 0;
int16_t oldEncoderPosition = 0;

void setup() {
 pinMode(encoderPinA, INPUT);
 pinMode(encoderPinB, INPUT);
 pinMode(encoderPinBtn, INPUT);
 pinMode(encoderPinSwt, INPUT);

 pinMode(spkPin, OUTPUT);

 attachInterrupt(0, encoderChange, CHANGE);
 attachInterrupt(1, encoderChange, CHANGE);

 Serial.begin(115200);
}

void loop() {
 input();

 Serial.print(encoderState, DEC);
 Serial.print(" ");
 Serial.println(encoderPosition, DEC);

 delay(10);
}

void input() {
 int16_t encoderDifference = encoderPosition - oldEncoderPosition;
 bool encoderBtn = digitalReadFast(encoderPinBtn);
 static bool oldEncoderBtn = 0;
 static uint8_t encoderStateReset = 0;

 if(encoderDifference) {
  tone(spkPin, encoderPosition * 100);
  encoderStateReset = 0;
 } else {
  encoderStateReset++;
  if(encoderStateReset == 50) {
   encoderState = 0;
   encoderStateReset = 0;
  }
 }

 if(encoderBtn and !oldEncoderBtn) {
  tone(spkPin, 1000, 10);
 }

 oldEncoderPosition = encoderPosition;
 oldEncoderBtn = encoderBtn;
}

void encoderChange() {
 static uint8_t newAB = 3;
 static uint8_t oldAB;
 static const int8_t encoderStates[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};

 oldAB = newAB;
 newAB = PINE >> 4;
 //newAB = digitalReadFast(encoderPinB) * 2 + digitalReadFast(encoderPinA);
 encoderState += encoderStates[oldAB * 4 + newAB];

 if(encoderState > 3) {
  encoderPosition++;
  encoderState = 0;
 } else if(encoderState < -3) {
  encoderPosition--;
  encoderState = 0;
 }
}

Original comment by ad...@serveurperso.com on 24 Sep 2011 at 4:41

GoogleCodeExporter commented 8 years ago
Be aware of the assumptions built into the encoderChange code.  I believe it 
does not intrinsically account for switch bounce.  The program works because 
the loop has some built-in debounce features, in that it takes some miliseconds 
between tests of the encoder state.  You can certainly depend on it as long as 
you realize that it takes advantage of the relatively long duration between 
loop iterations.

Original comment by m...@schwager.com on 3 Dec 2011 at 6:43

GoogleCodeExporter commented 8 years ago
I don't have a Arduino Mega so cannot configure/test this code on it.  I 
apologize.

Original comment by m...@schwager.com on 4 Feb 2012 at 5:52