here comes the full code:
SwitchPCB_Test_RotaryEncoder_v02.h
Code:
/**
** see SwitchPCB_Test_RotaryEncoder_v02.ino **
**/
/**
* Includes Core Arduino functionality
**/
#if ARDUINO < 100
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
/** type and struct definition **/
const byte state_UNDEFINED = 0;
const byte state_CW = 1;
const byte state_CCW = 2;
const byte state_HalfStep = 3;
// Input Event
struct sEncoder
{
const byte bNr;
byte pin_A;
byte pin_B;
boolean bA;
boolean bB;
boolean bA_last;
boolean bB_last;
boolean bLastFullStep;
byte bState;
unsigned long ulTimeStamp;
tCBF_OnStep cbfOnStep;
};
typedef struct sEncoder tEncoder;
// typdef for step callback
typedef void (* tCBF_OnStep) (tEncoder *encObj);
/** END **/
** see SwitchPCB_Test_RotaryEncoder_v02.ino **
**/
/**
* Includes Core Arduino functionality
**/
#if ARDUINO < 100
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
/** type and struct definition **/
const byte state_UNDEFINED = 0;
const byte state_CW = 1;
const byte state_CCW = 2;
const byte state_HalfStep = 3;
// Input Event
struct sEncoder
{
const byte bNr;
byte pin_A;
byte pin_B;
boolean bA;
boolean bB;
boolean bA_last;
boolean bB_last;
boolean bLastFullStep;
byte bState;
unsigned long ulTimeStamp;
tCBF_OnStep cbfOnStep;
};
typedef struct sEncoder tEncoder;
// typdef for step callback
typedef void (* tCBF_OnStep) (tEncoder *encObj);
/** END **/
SwitchPCB_Test_RotaryEncoder_v02.ino
Code:
/**************************************************************************************************
** RotaryEncoder Tester **
** Tests the Rotary Encoders of the SwitchPCBs at 2ChControll Project **
** based on infos and ideas from: **
** ~ http://www.mikrocontroller.net/articles/Drehgeber **
** ~ http://www.mikrocontroller.net/topic/drehgeber-auslesen **
** ~ http://www.mikrocontroller.net/topic/38863 **
** ~ http://hacks.ayars.org/2009/12/using-quadrature-encoder-rotary-switch.html **
** ~ http://playground.arduino.cc/Main/RotaryEncoders#Waveform **
** written by stefan krueger (s-light), stefan@s-light.eu, http://s-light.eu **
** changelog / history **
** 17.02.2013 22:25 created **
** 23.04.2013 15:06 uncomment code for posting and testing in forum. **
** **
** **
** TO DO: **
** ~ ask for help with the call back function **
** ~ get this into a library or **
** ~ a 'addon' file to add to projects (to much customization needed to fit every encoder?! **
** **
**************************************************************************************************/
/** Include yourselfs header file (used to define structs and co) **/
#include "SwitchPCB_Test_RotaryEncoder_v02.h"
// use "" for files in same directory as .ino
/** definitions **/
tEncoder enc_left = {
111, //const byte bNr;
22, // byte pin_A;
26, // byte pin_B;
0, // boolean bA;
0, // boolean bB;
0, // boolean bA_last;
0, // boolean bB_last;
0, // boolean bLastFullStep;
state_UNDEFINED, // byte bState;
0, // unsigned long ulTimeStamp;
callback_Encoder_OnStep, // tCBF_OnStep cbfOnStep;
};
tEncoder enc_right = {
222, //const byte bNr;
24, // byte pin_A;
28, // byte pin_B;
0, // boolean bA;
0, // boolean bB;
0, // boolean bA_last;
0, // boolean bB_last;
0, // boolean bLastFullStep;
state_UNDEFINED, // byte bState;
0, // unsigned long ulTimeStamp;
callback_Encoder_OnStep, // tCBF_OnStep cbfOnStep;
};
/** functions **/
void callback_Encoder_OnStep (tEncoder *encObj) {
/** Debug Out **/
Serial.print((*encObj).bNr);
Serial.print(":");
Serial.println((*encObj).bState);
/** **/
}
/************************************************/
/** read Encoder and rect **/
/************************************************/
void readEncoder(tEncoder *encObj) {
/**
rast punkt immer bei 0,0 oder 1,1
CCW
---- A, B
111: 0, 1
111: 0, 0 !
111: 1, 0
111: 1, 1 !
---- A, B
111: 0, 1
111: 0, 0 !
111: 1, 0
111: 1, 1 !
CW
---- A, B
111: 1, 0
111: 0, 0 !
111: 0, 1
111: 1, 1 !
---- A, B
111: 1, 0
111: 0, 0 !
111: 0, 1
111: 1, 1 !
Error
---- A, B
111: 1, 0
111: 0, 0
111:1
111+1
111: 0, 1
111: 1, 1
111:1
111+1
111: 1, 0
111: 1, 1
111:2 <--Wrong reading!!!
111-1
111: 1, 0
111: 0, 0
111:1
111+1
this reading is wrong.
it is not alowed to have 1,1; 1,0; 1,1
**/
boolean bTemp_A = digitalRead((*encObj).pin_A);
boolean bTemp_B = digitalRead((*encObj).pin_B);
if ( (bTemp_A != (*encObj).bA) || (bTemp_B != (*encObj).bB)) {
//status changed.
(*encObj).bA = bTemp_A;
(*encObj).bB = bTemp_B;
Serial.print((*encObj).bNr);
Serial.print(": ");
Serial.print((*encObj).bA);
Serial.print(", ");
Serial.println((*encObj).bB);
// half step; save state of encoder pins for direction check
if ((*encObj).bA != (*encObj).bB) {
(*encObj).bA_last = (*encObj).bA;
(*encObj).bB_last = (*encObj).bB;
(*encObj).bState = state_HalfStep;
} else {
// full step; one step is finished. --> This is Only true if the last full step was not the same level (high or low)
if ( ((*encObj).bA == (*encObj).bB) && ((*encObj).bA != (*encObj).bLastFullStep) ) {
//remember LastFullStep (error correction)
(*encObj).bLastFullStep = (*encObj).bA;
// Encoder turns CW
if ((*encObj).bA == (*encObj).bB_last) {
//Do Something
(*encObj).bState = state_CW;
/** RUN CALLBACK Function: **/
(*encObj).cbfOnStep(encObj);
// direct call for testing..
//callback_Encoder_OnStep(encObj);
/** **/
Serial.print((*encObj).bNr);
Serial.println(": +1");
/** **/
} else {
// Encoder turns CCW
if ((*encObj).bB == (*encObj).bA_last) {
//Do Something
(*encObj).bState = state_CCW;
/** RUN CALLBACK Function: **/
(*encObj).cbfOnStep(encObj);
// direct call for testing..
//callback_Encoder_OnStep(encObj);
/** **/
Serial.print((*encObj).bNr);
Serial.println(": -1");
/** **/
}
}
}
}
}
}
void setup() {
pinMode(enc_left.pin_A, INPUT_PULLUP);
pinMode(enc_left.pin_B, INPUT_PULLUP);
pinMode(enc_right.pin_A, INPUT_PULLUP);
pinMode(enc_right.pin_B, INPUT_PULLUP);
} // setup
/** Main Loop **/
void loop() {
readEncoder(&enc_left);
readEncoder(&enc_right);
}
** RotaryEncoder Tester **
** Tests the Rotary Encoders of the SwitchPCBs at 2ChControll Project **
** based on infos and ideas from: **
** ~ http://www.mikrocontroller.net/articles/Drehgeber **
** ~ http://www.mikrocontroller.net/topic/drehgeber-auslesen **
** ~ http://www.mikrocontroller.net/topic/38863 **
** ~ http://hacks.ayars.org/2009/12/using-quadrature-encoder-rotary-switch.html **
** ~ http://playground.arduino.cc/Main/RotaryEncoders#Waveform **
** written by stefan krueger (s-light), stefan@s-light.eu, http://s-light.eu **
** changelog / history **
** 17.02.2013 22:25 created **
** 23.04.2013 15:06 uncomment code for posting and testing in forum. **
** **
** **
** TO DO: **
** ~ ask for help with the call back function **
** ~ get this into a library or **
** ~ a 'addon' file to add to projects (to much customization needed to fit every encoder?! **
** **
**************************************************************************************************/
/** Include yourselfs header file (used to define structs and co) **/
#include "SwitchPCB_Test_RotaryEncoder_v02.h"
// use "" for files in same directory as .ino
/** definitions **/
tEncoder enc_left = {
111, //const byte bNr;
22, // byte pin_A;
26, // byte pin_B;
0, // boolean bA;
0, // boolean bB;
0, // boolean bA_last;
0, // boolean bB_last;
0, // boolean bLastFullStep;
state_UNDEFINED, // byte bState;
0, // unsigned long ulTimeStamp;
callback_Encoder_OnStep, // tCBF_OnStep cbfOnStep;
};
tEncoder enc_right = {
222, //const byte bNr;
24, // byte pin_A;
28, // byte pin_B;
0, // boolean bA;
0, // boolean bB;
0, // boolean bA_last;
0, // boolean bB_last;
0, // boolean bLastFullStep;
state_UNDEFINED, // byte bState;
0, // unsigned long ulTimeStamp;
callback_Encoder_OnStep, // tCBF_OnStep cbfOnStep;
};
/** functions **/
void callback_Encoder_OnStep (tEncoder *encObj) {
/** Debug Out **/
Serial.print((*encObj).bNr);
Serial.print(":");
Serial.println((*encObj).bState);
/** **/
}
/************************************************/
/** read Encoder and rect **/
/************************************************/
void readEncoder(tEncoder *encObj) {
/**
rast punkt immer bei 0,0 oder 1,1
CCW
---- A, B
111: 0, 1
111: 0, 0 !
111: 1, 0
111: 1, 1 !
---- A, B
111: 0, 1
111: 0, 0 !
111: 1, 0
111: 1, 1 !
CW
---- A, B
111: 1, 0
111: 0, 0 !
111: 0, 1
111: 1, 1 !
---- A, B
111: 1, 0
111: 0, 0 !
111: 0, 1
111: 1, 1 !
Error
---- A, B
111: 1, 0
111: 0, 0
111:1
111+1
111: 0, 1
111: 1, 1
111:1
111+1
111: 1, 0
111: 1, 1
111:2 <--Wrong reading!!!
111-1
111: 1, 0
111: 0, 0
111:1
111+1
this reading is wrong.
it is not alowed to have 1,1; 1,0; 1,1
**/
boolean bTemp_A = digitalRead((*encObj).pin_A);
boolean bTemp_B = digitalRead((*encObj).pin_B);
if ( (bTemp_A != (*encObj).bA) || (bTemp_B != (*encObj).bB)) {
//status changed.
(*encObj).bA = bTemp_A;
(*encObj).bB = bTemp_B;
Serial.print((*encObj).bNr);
Serial.print(": ");
Serial.print((*encObj).bA);
Serial.print(", ");
Serial.println((*encObj).bB);
// half step; save state of encoder pins for direction check
if ((*encObj).bA != (*encObj).bB) {
(*encObj).bA_last = (*encObj).bA;
(*encObj).bB_last = (*encObj).bB;
(*encObj).bState = state_HalfStep;
} else {
// full step; one step is finished. --> This is Only true if the last full step was not the same level (high or low)
if ( ((*encObj).bA == (*encObj).bB) && ((*encObj).bA != (*encObj).bLastFullStep) ) {
//remember LastFullStep (error correction)
(*encObj).bLastFullStep = (*encObj).bA;
// Encoder turns CW
if ((*encObj).bA == (*encObj).bB_last) {
//Do Something
(*encObj).bState = state_CW;
/** RUN CALLBACK Function: **/
(*encObj).cbfOnStep(encObj);
// direct call for testing..
//callback_Encoder_OnStep(encObj);
/** **/
Serial.print((*encObj).bNr);
Serial.println(": +1");
/** **/
} else {
// Encoder turns CCW
if ((*encObj).bB == (*encObj).bA_last) {
//Do Something
(*encObj).bState = state_CCW;
/** RUN CALLBACK Function: **/
(*encObj).cbfOnStep(encObj);
// direct call for testing..
//callback_Encoder_OnStep(encObj);
/** **/
Serial.print((*encObj).bNr);
Serial.println(": -1");
/** **/
}
}
}
}
}
}
void setup() {
pinMode(enc_left.pin_A, INPUT_PULLUP);
pinMode(enc_left.pin_B, INPUT_PULLUP);
pinMode(enc_right.pin_A, INPUT_PULLUP);
pinMode(enc_right.pin_B, INPUT_PULLUP);
} // setup
/** Main Loop **/
void loop() {
readEncoder(&enc_left);
readEncoder(&enc_right);
}
and the errors when i try to compile:
Code:
In file included from SwitchPCB_Test_RotaryEncoder_v02.ino:51:
SwitchPCB_Test_RotaryEncoder_v02.h:46: error: 'tCBF_OnStep' does not name a type
SwitchPCB_Test_RotaryEncoder_v02:89: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02:109: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02.ino: In function 'void readEncoder(tEncoder*)':
SwitchPCB_Test_RotaryEncoder_v02:208: error: 'struct sEncoder' has no member named 'cbfOnStep'
SwitchPCB_Test_RotaryEncoder_v02:224: error: 'struct sEncoder' has no member named 'cbfOnStep'
SwitchPCB_Test_RotaryEncoder_v02.h:46: error: 'tCBF_OnStep' does not name a type
SwitchPCB_Test_RotaryEncoder_v02:89: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02:109: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02.ino: In function 'void readEncoder(tEncoder*)':
SwitchPCB_Test_RotaryEncoder_v02:208: error: 'struct sEncoder' has no member named 'cbfOnStep'
SwitchPCB_Test_RotaryEncoder_v02:224: error: 'struct sEncoder' has no member named 'cbfOnStep'
if i put the typedef of the function for the sEncoder struct i have some other / similar errors
Code:
In file included from SwitchPCB_Test_RotaryEncoder_v02.ino:51:
SwitchPCB_Test_RotaryEncoder_v02.h:27: error: typedef 'tCBF_OnStep' is initialized (use __typeof__ instead)
SwitchPCB_Test_RotaryEncoder_v02.h:27: error: 'tEncoder' was not declared in this scope
SwitchPCB_Test_RotaryEncoder_v02.h:27: error: 'encObj' was not declared in this scope
SwitchPCB_Test_RotaryEncoder_v02.h:48: error: 'tCBF_OnStep' does not name a type
SwitchPCB_Test_RotaryEncoder_v02:89: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02:109: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02.ino: In function 'void readEncoder(tEncoder*)':
SwitchPCB_Test_RotaryEncoder_v02:208: error: 'struct sEncoder' has no member named 'cbfOnStep'
SwitchPCB_Test_RotaryEncoder_v02:224: error: 'struct sEncoder' has no member named 'cbfOnStep'
SwitchPCB_Test_RotaryEncoder_v02.h:27: error: typedef 'tCBF_OnStep' is initialized (use __typeof__ instead)
SwitchPCB_Test_RotaryEncoder_v02.h:27: error: 'tEncoder' was not declared in this scope
SwitchPCB_Test_RotaryEncoder_v02.h:27: error: 'encObj' was not declared in this scope
SwitchPCB_Test_RotaryEncoder_v02.h:48: error: 'tCBF_OnStep' does not name a type
SwitchPCB_Test_RotaryEncoder_v02:89: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02:109: error: too many initializers for 'tEncoder'
SwitchPCB_Test_RotaryEncoder_v02.ino: In function 'void readEncoder(tEncoder*)':
SwitchPCB_Test_RotaryEncoder_v02:208: error: 'struct sEncoder' has no member named 'cbfOnStep'
SwitchPCB_Test_RotaryEncoder_v02:224: error: 'struct sEncoder' has no member named 'cbfOnStep'
i think i missing some basic understanding of this..
thanks for your help
sunny greetings stefan
PS: how do you prefer such code? in-line or as attached file? i had to remove some formating comments to get under 9500 characters..
