Skip to content

Instantly share code, notes, and snippets.

@arduinoboard
Created July 28, 2011 06:05
Show Gist options
  • Save arduinoboard/1111051 to your computer and use it in GitHub Desktop.
Save arduinoboard/1111051 to your computer and use it in GitHub Desktop.
The file that is currently on an Arduino Uno with a serial number of test
/*
Created by WilliamK @ Wusik Dot Com (c) 2010
http://arduino.wusik.com
*/
#include "WConstants.h"
#include "Encoder.h"
// ------------------------------------------------------------------------------------------- //
Encoder::Encoder(int8_t pinLeft, int8_t pinRight, int8_t pinClick)
{
encoderPinLeft = pinLeft;
encoderPinRight = pinRight;
encoderPinClick = pinClick;
pinMode(encoderPinLeft, INPUT);
digitalWrite(encoderPinLeft, HIGH);
pinMode(encoderPinRight, INPUT);
digitalWrite(encoderPinRight, HIGH);
pinMode(encoderPinClick, INPUT);
digitalWrite(encoderPinClick, HIGH);
isClicked = false;
prevClickValue = 1;
integerMode = false;
isClickedEvent = false;
currentPosition = 0;
prevPosition = 0;
tempPosition = 0;
tempPosition2 = 0;
maxValue = 127;
minValue = 0;
moveRate = 1.0f;
timeLastClick = millis();
timeClickStarted = 0;
}
// ------------------------------------------------------------------------------------------- //
void Encoder::lowLevelTick(void)
{
tempPosition2 = (digitalRead(encoderPinRight) * 2) + digitalRead(encoderPinLeft);
if (encodeSeq[tempPosition2] == tempPosition) currentPosition -= moveRate;
else if (encodeSeq[tempPosition] == tempPosition2) currentPosition += moveRate;
tempPosition = tempPosition2;
}
// ------------------------------------------------------------------------------------------- //
void Encoder::lowLevelClick(void)
{
newClickValue = digitalRead(encoderPinClick);
if (newClickValue != prevClickValue)
{
if ((millis() - timeLastClick) < clickDebounceTime) return;
if (newClickValue == 0 && !isClicked)
{
isClickedEvent = true;
isClicked = true;
timeClickStarted = millis();
}
else if (newClickValue == 1) isClicked = false;
timeLastClick = millis();
}
prevClickValue = newClickValue;
}
// ------------------------------------------------------------------------------------------- //
boolean Encoder::onClickHold(void)
{
if (isClicked && (millis() - timeClickStarted) >= clickHoldTime) return true;
return false;
}
// ------------------------------------------------------------------------------------------- //
boolean Encoder::hasClick(void)
{
if (isClickedEvent)
{
isClickedEvent = false;
return true;
}
return false;
}
// ------------------------------------------------------------------------------------------- //
void Encoder::setIntegerMode(boolean mode)
{
integerMode = mode;
}
// ------------------------------------------------------------------------------------------- //
boolean Encoder::tick(void)
{
lowLevelTick();
lowLevelClick();
return (hasChanged() || isClickedEvent);
}
// ------------------------------------------------------------------------------------------- //
boolean Encoder::hasChanged()
{
currentPosition = constrain(currentPosition, minValue, maxValue);
if (integerMode)
{
if ((int)getPosition() != (int)prevPosition)
{
prevPosition = getPosition();
return true;
}
}
else
{
if (getPosition() != prevPosition)
{
prevPosition = getPosition();
return true;
}
}
return false;
}
// ------------------------------------------------------------------------------------------- //
float Encoder::getPosition(void)
{
if (integerMode) return (int)currentPosition;
return currentPosition;
}
// ------------------------------------------------------------------------------------------- //
void Encoder::setMinMax(float _min, float _max)
{
minValue = _min;
maxValue = _max;
currentPosition = constrain(currentPosition, minValue, maxValue);
}
// ------------------------------------------------------------------------------------------- //
void Encoder::setPosition(float _position)
{
currentPosition = _position;
currentPosition = constrain(currentPosition, minValue, maxValue);
}
// ------------------------------------------------------------------------------------------- //
void Encoder::setRate(float _rate)
{
moveRate = _rate;
}
/*
Created by WilliamK @ Wusik Dot Com (c) 2010
http://arduino.wusik.com
*/
#ifndef ENCODER_h
#define ENCODER_h
#include <inttypes.h>
#include "HardwareSerial.h"
const int8_t encodeSeq[] = {1, 3, 0, 2};
#define clickDebounceTime 50
#define clickHoldTime 500
// ------------------------------------------------------------------------------------------- //
class Encoder
{
public:
Encoder(int8_t pinLeft, int8_t pinRight, int8_t pinClick);
boolean tick(void);
void lowLevelTick(void);
void lowLevelClick(void);
float getPosition(void);
void setMinMax(float _min, float _max);
void setPosition(float _position);
void setRate(float _rate);
boolean hasChanged(void);
boolean hasClick(void);
boolean onClickHold(void);
void setIntegerMode(boolean mode);
boolean isClicked;
private:
int8_t encoderPinLeft;
int8_t encoderPinRight;
int8_t encoderPinClick;
float prevPosition;
float maxValue;
float minValue;
float currentPosition;
float moveRate;
int8_t tempPosition;
int8_t tempPosition2;
boolean isForward;
boolean isClickedEvent;
int8_t prevClickValue;
int8_t newClickValue;
boolean integerMode;
unsigned long timeLastClick;
unsigned long timeClickStarted;
};
#endif
/*
Code by Dave Vondle, IDEO 12/14/2011
Encoder Library Created by WilliamK @ Wusik Dot Com (c) 2010
http://arduino.wusik.com
SparkFun Keypad Example Code by: Jim Lindblom
SparkFun Electronics
date: 4/26/11
license: Creative Commons Share-Alike attribution v3.0
This example code will quickly get you up and running with the
SparkFun U/D/L/R/Flame Keypad. Pressing the flame button will
turn on/off the red LED. Up and down adjust the brightness of
the LED. And left and right are just there to look pretty will
output their status via the serial monitor.
Multiple touches are not supported in this code.
The circuit:
SparkFun Keypad Arduino
-----------------------------------------
Wire 1 (NC) ------------- No connection
Wire 2 (LEDR) ----------------- D3
Wire 3 (GND) ------------------GND
Wire 4 (P5.1) ----------------- D5
Wire 5 (P5.3) ----------------- D6
Wire 6 (P5.2) ----------------- D7
*/
#include <WProgram.h>
#include "Encoder.h"
///////////////////////////////// Pin definitions
//keypad
int LEDpin = 4;
int p51 = 3;
int p53 = 2;
int p52 = 15;
//Encoders
Encoder BlackEncoder = Encoder(13,12,0);
Encoder ClearEncoder = Encoder(6,5,7);
int redLED = 8;
int greenLED = 9;
//Buttons
int redButton = 11;
int whiteButton = 10;
///////////////////////////////// Global variables
//keypad
int button = 0;
int oldButtonState = 0;
//encoders
int encoderData = 0;
boolean blackEncoderPressed=false;
boolean clearEncoderPressed=false;
//slider
int sliderData=0;
const int sliderRollingAvgNum=30;
int sliderTmp[sliderRollingAvgNum];
int sliderSum;
int i=0;
//buttons
boolean redButtonPressed=false;
boolean whiteButtonPressed=false;
///////////////////////////////// Setup
void setup()
{
Serial.begin(115200);
//keypad
pinMode(LEDpin, OUTPUT);
pinMode(p51, INPUT);
pinMode(p53, INPUT);
pinMode(p52, INPUT);
digitalWrite(p51, HIGH);
digitalWrite(p52, HIGH);
digitalWrite(p53, HIGH);
//encoders
BlackEncoder.setMinMax(1,10000);
BlackEncoder.setPosition(5000);
BlackEncoder.setRate(1.0f);
BlackEncoder.setIntegerMode(true);
ClearEncoder.setMinMax(1,10000);
ClearEncoder.setPosition(5000);
ClearEncoder.setRate(1.0f);
ClearEncoder.setIntegerMode(true);
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
//buttons
pinMode(redButton, INPUT);
pinMode(whiteButton, INPUT);
digitalWrite(redButton, HIGH);
digitalWrite(whiteButton, HIGH);
}
///////////////////////////////// Loop
void loop()
{
///////////////////////////////// Output to LEDS
if (Serial.available() > 0) {
char message = Serial.read();
if(message=='A')
digitalWrite(LEDpin, HIGH);
if(message=='a')
digitalWrite(LEDpin, LOW);
if(message=='B')
digitalWrite(redLED, HIGH);
if(message=='b')
digitalWrite(redLED, LOW);
if(message=='C')
digitalWrite(greenLED, HIGH);
if(message=='c')
digitalWrite(greenLED, LOW);
}
///////////////////////////////// Input from Knobs, Sliders and Buttons
//Simple Buttons
if (digitalRead(redButton)==HIGH && redButtonPressed==true){
redButtonPressed=false;
Serial.print("B1"); //1 released
Serial.write((byte)0);
delay(1);
}else if (digitalRead(redButton)==LOW && redButtonPressed==false){
redButtonPressed=true;
Serial.print("B1"); //1 pressed
Serial.write((byte)1);
delay(1);
}
if (digitalRead(whiteButton)==HIGH && whiteButtonPressed==true){
whiteButtonPressed=false;
Serial.print("B2");
Serial.write((byte)0);
delay(1);
}else if (digitalRead(whiteButton)==LOW && whiteButtonPressed==false){
whiteButtonPressed=true;
Serial.print("B2");
Serial.write((byte)1);
delay(1);
}
//Keypad
button = getButtonState(); // Get button status
if (button == 0x04 && button != oldButtonState) // FLAME
{
Serial.print("B3");
Serial.write((byte)1);
oldButtonState=button;
delay(1); // "debounce"
}
else if (button == 0x02 && button != oldButtonState) // UP
{
Serial.print("B4");
Serial.write((byte)1);
oldButtonState=button;
delay(1); // "debounce"
}
else if (button == 0x01 && button != oldButtonState) // DOWN
{
Serial.print("B5");
Serial.write((byte)1);
oldButtonState=button;
delay(1); // "debounce"
}
else if (button == 0x08 && button != oldButtonState) // RIGHT
{
Serial.print("B6");
Serial.write((byte)1);
oldButtonState=button;
delay(1); // "debounce"
}
else if (button == 0x10 && button != oldButtonState) // LEFT
{
Serial.print("B7");
Serial.write((byte)1);
oldButtonState=button;
delay(1); // "debounce"
}
else if (button == 0 && button != oldButtonState) // UP
{
if (oldButtonState == 0x04) // FLAME
{
Serial.print("B3");
Serial.write((byte)0);
}
else if (oldButtonState == 0x02) // UP
{
Serial.print("B4");
Serial.write((byte)0);
}
else if (oldButtonState == 0x01) // DOWN
{
Serial.print("B5");
Serial.write((byte)0);
}
else if (oldButtonState == 0x08) // RIGHT
{
Serial.print("B6");
Serial.write((byte)0);
}
else if (oldButtonState == 0x10) // LEFT
{
Serial.print("B7");
Serial.write((byte)0);
}
oldButtonState=button;
delay(1); // "debounce"
}
if(blackEncoderPressed && !BlackEncoder.isClicked){
Serial.print("B8");
Serial.write((byte)0);
blackEncoderPressed=false;
}
if(clearEncoderPressed && !ClearEncoder.isClicked){
Serial.print("B9");
Serial.write((byte)0);
clearEncoderPressed=false;
}
if (BlackEncoder.tick())
{
if (BlackEncoder.hasClick()){
Serial.print("B8");
Serial.write((byte)1);
blackEncoderPressed=true;
}else{
encoderData = BlackEncoder.getPosition();
Serial.print("E1");
Serial.write(encoderData>>8);
Serial.write(encoderData);
}
}
if (ClearEncoder.tick())
{
if (ClearEncoder.hasClick()){
Serial.print("B9");
Serial.write((byte)1);
clearEncoderPressed=true;
}else{
encoderData = ClearEncoder.getPosition();
Serial.print("E2");
Serial.write(encoderData>>8);
Serial.write(encoderData);
}
}
//This stuff is to keep the slider from triggering events from noise (basically it's hysteresis)
i++; //for averaging slider data
i=i%sliderRollingAvgNum; // i loops from 0 to sliderRollingAvgNum-1
sliderTmp[i]=analogRead(0);
sliderSum=0;
for(int j=0; j<sliderRollingAvgNum; j++){
sliderSum+=sliderTmp[j]; //add past readings
}
//make sure new reading is different enough from the average of past readings
if (sliderTmp[i]<((sliderSum/sliderRollingAvgNum)-2) || sliderTmp[i]>((sliderSum/sliderRollingAvgNum)+2)){
sliderData=sliderTmp[i];
Serial.print("S1");
Serial.write(sliderData>>8);
Serial.write(sliderData);
}
}
//Sparkfun example code for gathering input from their keypad
uint8_t getButtonState()
{
// Initially set all buttons as inputs, and pull them up
pinMode(p52, INPUT);
digitalWrite(p52, HIGH);
pinMode(p51, INPUT);
digitalWrite(p51, HIGH);
pinMode(p53, INPUT);
digitalWrite(p53, HIGH);
// Read the d/u/flame buttons
if (!digitalRead(p53))
return 0x01; // Down
if (!digitalRead(p52))
return 0x02; // Up
if (!digitalRead(p51))
return 0x04; // Flame
// Read right button
pinMode(p52, OUTPUT); // set p52 to output, set low
digitalWrite(p52, LOW);
if (!digitalRead(p53))
return 0x08; // Right
pinMode(p52, INPUT); // set p52 back to input and pull-up
digitalWrite(p52, HIGH);
// Read left button
pinMode(p51, OUTPUT); // Set p51 to output and low
digitalWrite(p51, LOW);
if (!digitalRead(p53))
return 0x10; // Left
pinMode(p51, INPUT); // Set p51 back to input and pull-up
pinMode(p51, HIGH);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment