Você está na página 1de 8

This is an Arduino Code

// Include LCD library and initialise

#include <LiquidCrystal.h>

// Define Adruino pin numbers for LCD

// Set LCD

LiquidCrystal lcd(1,2,4,5,6,7);

/* ROTARY ENCODER AND PUSH BUTTON POLLING CODE */

#define Clk 9

#define DT 8

#define SW 10

// Poll and debounces a Keyes rotary and push button switch

// Inputs:

// Clk (Pin A with 10k pullup resistor)

// DT (Pin B with 10k pullup resistor)

// SW (Switch without a pullup resistor)

// + (Power for pullup resistors)

// Gnd

// Exports:

// UpdateSwitch (bool) [true|false]

// Switch (byte) [LOW|HIGH]

// EncoderPos (char) [-128..127]

volatile bool UpdateSwitch=false;

volatile byte Switch=HIGH;

volatile char EncoderPos=0;

ISR(TIMER0_COMPB_vect) {

static byte testClk=(PIND>>Clk)&1;

static byte testDT=(PIND>>DT)&1;

static byte lastClk=LOW;

static byte lastDT=LOW;


static bool flagClk=false;

static bool flagDT=false;

static char encoderDir=0;

static byte testSW=HIGH;

static byte statusSW=HIGH;

static byte cntSW=0;

// Update Encoder Position

lastClk=testClk; // Save Clk

lastDT=testDT; // Save DT

testClk=(PIND>>Clk)&1; // Get Clk

testDT=(PIND>>DT)&1; // Get DT

if (testClk!=lastClk) { // Change in Clk?

flagClk=true; // Flag Clk has changed

encoderDir=-1; // Assume it is the last flag to change

if (testDT!=lastDT) { // Change in DT?

flagDT=true; // Flag DT has changed

encoderDir=1; // Assume it is the last flag to change

if (flagClk&&flagDT) { // Both flags have changed

EncoderPos+=encoderDir; // Update the encoder

flagClk=false; // Reset Clk flag

flagDT=false; // Reset DT flag

// Update switch with 10ms debounce

testSW=(PIND>>SW)&1;

if (testSW!=statusSW) {

statusSW=testSW;

cntSW=10;
}

if (cntSW>0) {

cntSW--;

if (cntSW==0) {

Switch=statusSW;

UpdateSwitch=true;

/* MENU SET UP */

char* menuName[]={"Done ","Year ","Month ","Day ","Hour ","Minute ","Second ","Adjustment "};

int menuSize=sizeof(menuName)/sizeof(char*);

char menuValue[]= { 0, 0, 1, 1, 0, 0, 0, 0};

char menuNumeric[]= {'N','Y','Y','Y','Y','Y','Y', 'Y'};

char menuValueMin[]={ 0, 0, 1, 1, 0, 0, 0,-126};

char menuValueMax[]={ 1,126, 12, 31, 23, 59, 59, 126};

char menuLevel=0;

int led =13;

void setup() {

// Initialise rotary encoder and push button

pinMode(Clk,INPUT_PULLUP); // Rotary Clk

pinMode(DT,INPUT_PULLUP); // Rotary DT

pinMode(SW,INPUT_PULLUP); // Rotary SW

// Turn on polling ISR

OCR0B=0xA0;

TIMSK0|=1<<OCIE0B;

// Initialise LCD
pinMode(led,OUTPUT);

digitalWrite(led,HIGH);

lcd.begin(16,2);

lcd.print("Rotary Encoder");

delay(3000);

bool processMenu(void) {

static char lastPos=0;

static char lastMenuLevel=-1;

// Pre-empt menu level display

if (menuLevel!=lastMenuLevel) {

lastMenuLevel=menuLevel;

lcd.clear();

lcd.setCursor(0,0);

if (menuLevel==0) {

lcd.print("Menu:");

lcd.setCursor(0,1);

lcd.print(menuName[EncoderPos]);

if (menuNumeric[EncoderPos]=='Y') {

lcd.print((int)menuValue[EncoderPos]);

} else {

if (menuValue[EncoderPos]!=0) {

lcd.print("Y");

} else {

lcd.print("N");

} else if (menuLevel==1) {

lcd.print("Set:");
lcd.setCursor(0,1);

lcd.print(menuName[lastPos]);

if (menuNumeric[lastPos]=='Y') {

lcd.print((int)menuValue[lastPos]);

} else {

if (menuValue[lastPos]!=0) {

lcd.print("Y");

} else {

lcd.print("N");

} else {

lcd.print("Rotary Encoder?");

// If push button pushed toggle menuLevel

if (UpdateSwitch) {

UpdateSwitch=false;

if (Switch==LOW) {

// Re-enter menu if button pushed (for long enough)

if (menuLevel==-1) {

menuLevel=0; // Item menu

lastPos=1; // Trigger menu update

EncoderPos=0; // Done

menuValue[0]=0; // N

} else {

// Toggle menu level

menuLevel=1-menuLevel;

if (menuLevel==0) {

// Save item menu position


EncoderPos=lastPos;

// Exit menu if done!

if ((EncoderPos==0)&&(menuValue[EncoderPos]!=0)) menuLevel=-1;

} else {

// Set value for edit menu

EncoderPos=menuValue[lastPos];

// If encoder turned

if (menuLevel==0) { // Select menu item

if (lastPos!=EncoderPos) {

if (EncoderPos>=menuSize) EncoderPos=0;

if (EncoderPos<0) EncoderPos=menuSize-1;

lastPos=EncoderPos;

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Menu:");

lcd.setCursor(0,1);

lcd.print(menuName[EncoderPos]);

if (menuNumeric[EncoderPos]=='Y') {

lcd.print((int)menuValue[EncoderPos]);

} else {

if (menuValue[EncoderPos]!=0) {

lcd.print("Y");

} else {

lcd.print("N");

}
}

} else if (menuLevel==1) { // Edit menu item value

if (menuValue[lastPos]!=EncoderPos) {

if (EncoderPos>menuValueMax[lastPos]) EncoderPos=menuValueMin[lastPos];

if (EncoderPos<menuValueMin[lastPos]) EncoderPos=menuValueMax[lastPos];

menuValue[lastPos]=EncoderPos;

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Set:");

lcd.setCursor(0,1);

lcd.print(menuName[lastPos]);

if (menuNumeric[lastPos]=='Y') {

lcd.print((int)menuValue[lastPos]);

} else {

if (menuValue[lastPos]!=0) {

lcd.print("Y");

} else {

lcd.print("N");

return (menuLevel!=-1); // Return true if menu active

void loop() {
if (!processMenu()) { // Menu not active

// Present the results

int i;

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Running");

lcd.setCursor(0,1);

for (i=0;i<menuSize;i++) {

if (menuNumeric[i]=='Y') {

lcd.print((int)menuValue[i]);

} else {

if (menuValue[i]!=0) {

lcd.print("Y");

} else {

lcd.print("N");

lcd.print(" ");

delay(3000);

Você também pode gostar