| | #include <avr/sleep.h> |
---|
| | #include <avr/interrupt.h> |
---|
| | #include <SoftwareSerial.h> |
---|
| | |
---|
| | const int rx = -1; // -1 = dont use |
---|
| | const int tx = 5; // pin 5 for serial.print() |
---|
| | SoftwareSerial Serial(rx,tx); // rx, tx pins |
---|
| | |
---|
| | int enc1pinA = 2; // Encoder pin A |
---|
| | int enc1pinB = 3; // Encoder pin B |
---|
| | int counter = 0; // could use a byte here? |
---|
| | byte enc1oldPins = 0; // will hold state of pins last time encoder was read |
---|
| | byte enc1newPins = 0; // will hold new encoder pin reading, to be compared with last time's pin states |
---|
| | byte enc1move = 0; // when two encoders are used to control the same parameter, this will hold the combined deduced movement |
---|
| | |
---|
| | const byte RotaryDecodeTable[4][4] = { |
---|
| | {B00, B10, B01, B11}, |
---|
| | {B01, B00, B11, B10}, |
---|
| | {B10, B11, B00, B01}, |
---|
| | {B11, B01, B10, B00} |
---|
| | }; |
---|
| | |
---|
| | int bLed = 1; // rotary encoder LED pin |
---|
| | int rgLed = 4; // red/green LED pin |
---|
| | int val = 0; // rotary encoder current position |
---|
| | |
---|
| | unsigned long lastCheck = 0; // time (for sleep state) |
---|
| | bool sleepState = 0; // sleep or awake |
---|
| | |
---|
| | void setup() { |
---|
| | pinMode(bLed, OUTPUT); |
---|
| | pinMode(rgLed, INPUT); |
---|
| | |
---|
| | pinMode(enc1pinA, INPUT); // configure the pin connections as inputs |
---|
| | pinMode(enc1pinB, INPUT); |
---|
| | pinMode(enc1pinA, INPUT_PULLUP); // turn on internal pull-up resistor for each input |
---|
| | pinMode(enc1pinB, INPUT_PULLUP); |
---|
| | delay(1); // allow 1ms for encoder voltages to setle |
---|
| | enc1oldPins = (digitalRead(enc1pinA)<<1|digitalRead(enc1pinB)); // read the initial state of encoder |
---|
| | |
---|
| | lastCheck = millis(); // for sleep state |
---|
| | |
---|
| | pinMode(rx,INPUT); // setup and print to serial |
---|
| | pinMode(tx,OUTPUT); |
---|
| | Serial.begin(9600); |
---|
| | Serial.println("Running"); |
---|
| | } |
---|
| | |
---|
| | void green(int del){ // turn on green LED for delay() |
---|
| | pinMode(rgLed, OUTPUT); |
---|
| | analogWrite(rgLed, HIGH); |
---|
| | delay(del); |
---|
| | pinMode(rgLed, INPUT); |
---|
| | } |
---|
| | void red(int del){ // turn on red LED for delay() |
---|
| | pinMode(rgLed, OUTPUT); |
---|
| | analogWrite(rgLed, 255); |
---|
| | delay(del); |
---|
| | pinMode(rgLed, INPUT); |
---|
| | } |
---|
| | |
---|
| | void keepAwake(int dir){ // runs every time rottary encoder is turned to keep deviec awake |
---|
| | lastCheck = millis(); |
---|
| | if(sleepState == 1){ |
---|
| | sleepState = 0; |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | void sleep(){ |
---|
| | println("Sleeping"); |
---|
| | sleepState = 1; |
---|
| | analogWrite(bLed, LOW); |
---|
| | |
---|
| | GIMSK |= _BV(PCIE); // Enable Pin Change Interrupts |
---|
| | PCMSK |= _BV(PCINT2); // Use pin 2 as interrupt pin |
---|
| | PCMSK |= _BV(PCINT3); // Use pin 3 as interrupt pin |
---|
| | PCMSK &= ~_BV(PCINT3); // Turn off pin 3 as interrupt pin |
---|
| | ADCSRA &= ~_BV(ADEN); // ADC off |
---|
| | set_sleep_mode(SLEEP_MODE_PWR_DOWN); // replaces above statement |
---|
| | |
---|
| | sleep_enable(); // Sets the Sleep Enable bit in the MCUCR Register (SE BIT) |
---|
| | sei(); // Enable interrupts |
---|
| | sleep_cpu(); // sleep |
---|
| | |
---|
| | cli(); // Disable interrupts |
---|
| | PCMSK &= ~_BV(PCINT3); // Turn off PB3 as interrupt pin |
---|
| | sleep_disable(); // Clear SE bit |
---|
| | ADCSRA |= _BV(ADEN); // ADC on |
---|
| | |
---|
| | sei(); // Enable interrupts |
---|
| | } |
---|
| | |
---|
| | void loop(){ |
---|
| | enc1newPins = 0; // Empty byte ready to shift-in new pins |
---|
| | enc1newPins = (digitalRead(enc1pinA)<<1|digitalRead(enc1pinB)); // read the current state of encoder1 pins |
---|
| | enc1move = RotaryDecodeTable[enc1oldPins][enc1newPins]; // used RotaryDecodeTable to decide movement, if any |
---|
| | enc1oldPins = enc1newPins; // update encoder1state to be current pin values |
---|
| | if (enc1move == B01){ // if result was move right (CW), decrement counter |
---|
| | counter--; |
---|
| | keepAwake(); |
---|
| | } |
---|
| | if (enc1move == B10){ // if result was move left (anti-CW), inrement counter |
---|
| | counter++; |
---|
| | keepAwake(); |
---|
| | } |
---|
| | |
---|
| | // inactive > 10 secs so go into sleep state |
---|
| | if ( (millis() - lastCheck > 10000) && sleepState == 0 ) { // 10000 == 10 secs |
---|
| | sleep(); |
---|
| | } |
---|
| | } |
---|
| | |