Hello all...
I want to read the A and B pins from an encoder using interrupts together with an OLED display used as a readout, much like a lathe digital readout. Then to control a stepper motor with the Arduino Motor Shield using buttons with set amounts of steps in ether direction. Both the encoder and stepper motor will be fitted to a linear actuator. I have looked at the playground.arduino.cc/Main/RotaryEncoders and have taken bit's to use, study and to try and learn the code. It has been great fun till I stumbled on getting both the encoder and stepper motor to work together. I cant have to much delay() commands in the code or it will miss the state changes made from the encoder. How can I do this? I would guess using the "millis()"?
After reading though Coding Academy "Linux Format" there is a fantastic bit about controlling the Arduino from an Android devise this would be the next step to learn instead of using buttons.
Parts in use are..
Arduino Mega 2560
Arduino Motor Shield,
SSD1306 - Adafruit - "OLED" [u]http://www.adafruit.com/datasheets/SSD1306.pdf[/u]
ENA1J-B28-L00128L - Bourns - "Encoder" http://docs-europe.electrocomponents.com/webdocs/008d/0900766b8008d78a.pdf
RS (191-8328) - "1.8DEG Stepper motor" http://docs-europe.electrocomponents.com/webdocs/001c/0900766b8001c018.pdf
I know this code is not %100 that is why I'm here. If I have missed anything out shout.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_DC 48
#define OLED_CS 52
#define OLED_CLK 46
#define OLED_MOSI 44
#define OLED_RESET 50
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#if (SSD1306_LCDHEIGHT != 32)
#endif
enum PinAssignments {
encoderPinA = 21,
encoderPinB = 20,
clearButton = 42
};
volatile unsigned int encoderPos = 0;
unsigned int lastReportedPos = 1;
boolean A_set = false;
boolean B_set = false;
static boolean rotating=false; // debounce management
int myValue;
const int ledPin = 43; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 500; // interval at which to blink (milliseconds)
void setup() {
display.begin(SSD1306_SWITCHCAPVCC);
display.display(); // show splashscreen
delay(500);
display.clearDisplay();
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(clearButton, INPUT);
digitalWrite(encoderPinA, HIGH); // turn on pullup resistor
digitalWrite(encoderPinB, HIGH); // turn on pullup resistor
digitalWrite(clearButton, HIGH);
attachInterrupt(2, doEncoderA, CHANGE);
attachInterrupt(3, doEncoderB, CHANGE);
pinMode(ledPin, OUTPUT);
}
void loop() {
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("EncoderPos");
display.setTextSize(5);
display.setTextColor(WHITE);
display.print(myValue, DEC);
display.display();
display.clearDisplay();
rotating = true; // reset the debouncer
if (lastReportedPos != encoderPos) {
lastReportedPos = encoderPos;
}
if (digitalRead(clearButton) == LOW ) {
encoderPos = 0;
}
(myValue = (encoderPos) * 1);
}
// Interrupt on A changing state
void doEncoderA(){
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done
// Test transition, did things really change?
if( digitalRead(encoderPinA) != A_set ) { // debounce once more
A_set = !A_set;
// adjust counter + if A leads B
if ( A_set && !B_set )
encoderPos += 1;
rotating = false; // no more debouncing until loop() hits again
}
}
// Interrupt on B changing state, same as A above
void doEncoderB(){
if ( rotating ) delay (1);
if( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// adjust counter - 1 if B leads A
if( B_set && !A_set )
encoderPos -= 1;
rotating = false;
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
Many Thanks,