Rotary encoder tellen pulsen te snel, help
6 berichten
• Pagina 1 van 1
Rotary encoder tellen pulsen te snel, help
Goede dag allemaal
ik ben een beginner met arduino en ben een uitlezing aan maken waarbij 2 rotary encoders (600 pulsen) ieder een afstand in mm moeten aangeven. een soort van aanslag op een machine.
heb een code aangepast van de arduino site, het werkt perfect enkel als ik heel traag de encoder draai
als ik sneller als 10 sec doe over een rotatie dan teld hij niet alle pulsen. dit moet toch veel vlotter gaan he
de encoder komt op een spindel te staan die ongeveer 2-3 sec per omwenteling maakt, dat moet toch normaal lukken om deze pulsen te tellen ?
Hulp zou heel welkom zijn, daar ik al alles afgezocht en code aangepast enz...
alvast bedankt, Bart
ik ben een beginner met arduino en ben een uitlezing aan maken waarbij 2 rotary encoders (600 pulsen) ieder een afstand in mm moeten aangeven. een soort van aanslag op een machine.
heb een code aangepast van de arduino site, het werkt perfect enkel als ik heel traag de encoder draai
als ik sneller als 10 sec doe over een rotatie dan teld hij niet alle pulsen. dit moet toch veel vlotter gaan he
de encoder komt op een spindel te staan die ongeveer 2-3 sec per omwenteling maakt, dat moet toch normaal lukken om deze pulsen te tellen ?
Hulp zou heel welkom zijn, daar ik al alles afgezocht en code aangepast enz...
alvast bedankt, Bart
Advertisement
Re: Rotary encoder tellen pulsen te snel, help
hierbij mijn code:
// Rotary encoder with Arduino to print
// source - www.circuitschools.com
#include <LiquidCrystal_I2C.h>
#define encoderA 6
#define encoderB 7
// Initialize the LCD library with I2C address and LCD size
LiquidCrystal_I2C lcd (0x27, 20,4);
int counter = 0;
int currentStateA = LOW;
int lastStateA = LOW;
void setup() {
// Set encoder pins as inputs
pinMode(encoderA,INPUT);
digitalWrite(encoderA, HIGH);
pinMode(encoderB,INPUT);
digitalWrite(encoderB, HIGH);
// pinMode(6, INPUT_PULLUP);
// pinMode(7, INPUT_PULLUP);
lcd. init (); // Turn on the backlight on LCD.
lcd.backlight();
lcd.print ("versie: 4");
lcd. setCursor (0, 1);
lcd.print ("Achteraanslag");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Achteraanslag in mm");
lcd.setCursor(0, 1);
lcd.print("Teller waarde:"); // Read the initial state of outputA
lastStateA = digitalRead(encoderA);
}
void loop() {
// Read the current state of outputA
currentStateA = digitalRead(encoderA);
// If last and current state of outputA are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateA != lastStateA && currentStateA == 1){
// If the outputB state is different than the outputA state then
// the encoder is rotating CCW so decrement
if (digitalRead(encoderB) != currentStateA) {
counter ++;
} else {
// Encoder is rotating CW so increment
counter --;
}
lcd.setCursor(15, 1);
lcd.print(counter) ;
}
// Remember last encoderA state
lastStateA = currentStateA;
// Put in a slight delay to help debounce the reading
delay(1
);
}
// Rotary encoder with Arduino to print
// source - www.circuitschools.com
#include <LiquidCrystal_I2C.h>
#define encoderA 6
#define encoderB 7
// Initialize the LCD library with I2C address and LCD size
LiquidCrystal_I2C lcd (0x27, 20,4);
int counter = 0;
int currentStateA = LOW;
int lastStateA = LOW;
void setup() {
// Set encoder pins as inputs
pinMode(encoderA,INPUT);
digitalWrite(encoderA, HIGH);
pinMode(encoderB,INPUT);
digitalWrite(encoderB, HIGH);
// pinMode(6, INPUT_PULLUP);
// pinMode(7, INPUT_PULLUP);
lcd. init (); // Turn on the backlight on LCD.
lcd.backlight();
lcd.print ("versie: 4");
lcd. setCursor (0, 1);
lcd.print ("Achteraanslag");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Achteraanslag in mm");
lcd.setCursor(0, 1);
lcd.print("Teller waarde:"); // Read the initial state of outputA
lastStateA = digitalRead(encoderA);
}
void loop() {
// Read the current state of outputA
currentStateA = digitalRead(encoderA);
// If last and current state of outputA are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateA != lastStateA && currentStateA == 1){
// If the outputB state is different than the outputA state then
// the encoder is rotating CCW so decrement
if (digitalRead(encoderB) != currentStateA) {
counter ++;
} else {
// Encoder is rotating CW so increment
counter --;
}
lcd.setCursor(15, 1);
lcd.print(counter) ;
}
// Remember last encoderA state
lastStateA = currentStateA;
// Put in a slight delay to help debounce the reading
delay(1
);
}
Re: Rotary encoder tellen pulsen te snel, help
een encoder heeft 4 eigenlijk zelfs 8 toestanden 4 cw en 4 ccw dus allemaal benoemen en haal de delay eruit want dat betekent eigenlijk dat je max 1000 pulsen kunt detecteren en ik zou even ter controle de led gebruiken bij een puls en ja ik weet dat paul stoffregen maar 1 toestand gebruikt
paul deelen
shooter@home.nl
shooter@home.nl
Re: Rotary encoder tellen pulsen te snel, help
Sorry maar hoe moet ik dit benoemen ? is er ergens een voorbeeld sketch waar dit in gebruikt word ? hoe ik die sketch optimaal kan maken ?
Re: Rotary encoder tellen pulsen te snel, help
Van rotary encoders weet ik niet veel maar met je verhaal erbij kan misschien een tip geven.
Je geeft aan dat je counters mist maar dat kan alleen als de loop te lang duur.
Een opmerking uit de praktijk is natuurlijk kijken naar delays maar ook input / output zijn soms tijd gebruikers.
Hier de Tip: Haal het presenteren van de counter uit het if statement en laat deze af en toe uitvoeren.
In het voorbeeld heb ik een tussenpauze voor display op 1 seconde.
Misschien is het een bijdrage aan de oplossing! Succes
Je geeft aan dat je counters mist maar dat kan alleen als de loop te lang duur.
Een opmerking uit de praktijk is natuurlijk kijken naar delays maar ook input / output zijn soms tijd gebruikers.
Hier de Tip: Haal het presenteren van de counter uit het if statement en laat deze af en toe uitvoeren.
In het voorbeeld heb ik een tussenpauze voor display op 1 seconde.
- Code: Alles selecteren
int lastStateA = LOW;
long nextDisplay = 0;
#define NEXT_DISPLAY 1000
.......
void loop() {
....
if (currentStateA != lastStateA && currentStateA == 1) {
..........
// VERVALLEN
// lcd.setCursor(15, 1);
// lcd.print(counter) ;
}
if (nextDisplay < millis())
{
lcd.setCursor(15, 1);
lcd.print(counter) ;
nextDisplay = millis() + NEXT_DISPLAY;
}
....
Misschien is het een bijdrage aan de oplossing! Succes
- Gij Kieken
- Berichten: 631
- Geregistreerd: 15 Nov 2015, 11:54
Re: Rotary encoder tellen pulsen te snel, help
Als je het sneller en beter wilt doen maak je best gebruik van interrupts en voor sneller port manipulation.
Afhankelijk van hoeveel encoders je wilt gebruiken neem je beter een Mega ipv een uno.
Er zijn tal van voorbeeldjes te vinden,bv
https://www.arduino.cc/reference/en/lan ... interrupt/
https://www.instructables.com/Arduino-a ... ipulation/
Een tijdje terug heb ik wat test dingetjes gemaakt voor te loggen in Exel, bijgevoegd de code.
Hierbij zijn geen libraries gebruikt en ook nog geen direct port manipulation.
Hier een ander voorbeeldje wel met Port Manipulation
Afhankelijk van hoeveel encoders je wilt gebruiken neem je beter een Mega ipv een uno.
Er zijn tal van voorbeeldjes te vinden,bv
https://www.arduino.cc/reference/en/lan ... interrupt/
https://www.instructables.com/Arduino-a ... ipulation/
Een tijdje terug heb ik wat test dingetjes gemaakt voor te loggen in Exel, bijgevoegd de code.
Hierbij zijn geen libraries gebruikt en ook nog geen direct port manipulation.
- Code: Alles selecteren
Meetlat X-Y pos
/*
Update: ver.03 08/02/2019
Clean up unused variables
Clean up layout
*/
/*
Purpose: Double 4x Bi-directional encoding
to represent the X-Y axis of a 2d object
and log it in .csv format.
Board: Arduino Mega 2560
Optical encoder open collector
Author: Gij Kieken
Date: 22/01/2019
Info: I am using two diferent methods to determine
the X and Y position
One with a switch case construction and one
with an array.
*/
// Used functions
/* myDebounceShortLongPress
Purpose: Debounce an array of push buttons and determine if they
where pressed a short or long time.(micro seconds)
In setup use pinMode(pin, INPUT_PULLUP) so no external
components are necessary.
Buttons connected 1-side to gnd the other to Arduino pin.
Author: Gij Kieken
*/
const byte maxButton = 3; //Number of buttons
const byte pinPushButton[maxButton] = {4, 5, 6}; //Arduino IN pins
const byte maxOutput = 4; //Number of outputs
const byte LED[maxOutput] = {9, 10, 11, 12}; //Arduino OUT pins
volatile long countX = 0;
volatile long countY = 0;
boolean A, B;
boolean C, D;
boolean modeStatus = false; // Keep track of Hole or Line mode
boolean printHeaderHole = true; // Print header once
boolean printHeaderLine = false; // Print header once
boolean printHeaderStop = false; // Print header once
//**********************
const unsigned long interval = 500000;
unsigned long previousStartMicros;
unsigned long previousStopMicros;
boolean enabledStop = false;
boolean enabledStart = false;
//***********************
byte stateX, statepX;
byte stateY, statepY;
//Quadrature Encoder Matrix
const byte QEM[16] = {0, -1, 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, -1, 0, 1, 0};
byte index = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(2, INPUT);//Channel A
pinMode(3, INPUT);//Channel B
pinMode(21, INPUT);//Channel C
pinMode(20, INPUT); //Channel D
//Initialize push button pins as inputs with pull-ups
// button[0]=startButton, button[1]=stopButton, button[2]=modeButton
for (byte i = 0; i < maxButton; i++) {
pinMode(pinPushButton[i], INPUT_PULLUP);
}
//Initialize LED pins as outputs
// LED[0]=HoleLed, LED[1]= LineLed, LED[2]=StartLed, LED[3]=StopLed
for (byte j = 0; j < maxOutput; j++) {
pinMode(LED[j], OUTPUT);
}
digitalWrite(LED[0], !modeStatus); //We start in hole mode
digitalWrite(LED[1], modeStatus); //LineLED=OFF
digitalWrite(LED[2], LOW); //StartLed=OFF
digitalWrite(LED[3], LOW); //StopLed=OFF
attachInterrupt(digitalPinToInterrupt(2), Achange, CHANGE); //Int 0
attachInterrupt(digitalPinToInterrupt(3), Bchange, CHANGE); //Int 1
attachInterrupt(digitalPinToInterrupt(21), Cchange, CHANGE); //Int 2
attachInterrupt(digitalPinToInterrupt(20), Dchange, CHANGE); //Int 3
//read the initial value of A & B
A = digitalRead(2);
B = digitalRead(3);
//read the initial value of C & D
C = digitalRead(21);
D = digitalRead(20);
//set initial stateX value
if ((A == HIGH) && (B == HIGH)) statepX = 1;
if ((A == HIGH) && (B == LOW)) statepX = 2;
if ((A == LOW) && (B == LOW)) statepX = 3;
if ((A == LOW) && (B == HIGH)) statepX = 4;
//set initial stateY value
if ((C == HIGH) && (D == HIGH)) statepY = 1;
if ((C == HIGH) && (D == LOW)) statepY = 2;
if ((C == LOW) && (D == LOW)) statepY = 3;
if ((C == LOW) && (D == HIGH)) statepY = 4;
// Start communication with Excel
Serial.println("CLEARSHEET");
Serial.println("LABEL,X-Pos,Y-Pos");
Serial.println("CELL,SET,C01, Gij Kieken X-Y pos ");
Serial.println("CELL,SET,C02, Long press Start to start log.");
Serial.println("CELL,SET,C03, Short press Start to tween.");
Serial.println("CELL,SET,C04, Short press mode to toggle.");
Serial.println("CELL,SET,C05, Short press Stop to stop log.");
Serial.println("DATA,HOLE-X,HOLE-Y");
}
void loop() {
// put your main code here, to run repeatedly:
static unsigned long previousTime = 0;
const byte timeInterval = 2000; //pick a short time interval
byte button[maxButton] = {}; //array to store the latest readings
// button[0]=startButton, button[1]=stopButton, button[2]=modeButton
// LED[0]=HoleLed, LED[1]= LineLed, LED[2]=StartLed, LED[3]=StopLed
// - check all buttons
if ((micros() - previousTime) > timeInterval) {
previousTime = micros();
for (byte i = 0; i < maxButton; i++) {
button[i] = checkButtons(i);
}
if (button[0] == 1) { // Code, when Start button is short-pushed
//***Continue to Log***
if (enabledStart) {
digitalWrite(LED[2], HIGH);
Serial.print("DATA,");
Serial.print(countX);
Serial.print(",");
Serial.println(countY);
Serial.println("BEEP");
previousStartMicros = micros();
}
}
if (button[0] == 2) { // Code, when Start button is long-pushed
//***Start to Log***
if (!enabledStart) {
digitalWrite(LED[2], HIGH);
enabledStart = true;
// Reset countX and countY
countX = 0;
countY = 0;
Serial.print("DATA,");
Serial.print(countX);
Serial.print(",");
Serial.println(countY);
Serial.println("BEEP");
previousStartMicros = micros();
}
}
if (button[1] == 1) { // Code, when Stop button is short-pushed
//***Stop to Log***
digitalWrite( LED[3], HIGH); // turn on led
if (!printHeaderStop) {
Serial.println("DATA,STOPPED-X,STOPPED-Y"); // Print header
// Reset the flags
modeStatus = LOW; // Reset modeStatus to hole mode
printHeaderLine = false;
printHeaderStop = true; // Make sure header is printed only once
enabledStart = false; // Reset the start flag
enabledStop = true; // Print offset X=0,Y=0 once
digitalWrite(LED[0], !modeStatus); // Change hole led state
digitalWrite(LED[1], modeStatus); // Change line led state
Serial.println("DATA,HOLE-X,HOLE-Y");
Serial.println("BEEP");
Serial.println("SAVEWORKBOOKAS,MyNewX-Y_pos");
printHeaderHole = true;
previousStopMicros = micros();
}
}
if (button[2] == 1) { // Code, when Mode button is short-pushed
//***Select the mode***
// modeStatus=0 ---> hole-modus, modeStatus=1 ---> line-modus
modeStatus = !modeStatus; // Toggle the LED value
digitalWrite(LED[0], !modeStatus); // Change hole led state
digitalWrite(LED[1], modeStatus); // Change line led state
//***Determine mode Hole or Line and printout appropriate header***
if (!modeStatus && !printHeaderHole && printHeaderLine) {
Serial.println("DATA,HOLE-X,HOLE-Y");
Serial.println("BEEP");
printHeaderHole = true; // Make sure header is printed only once
printHeaderLine = false;
}
else if (modeStatus && printHeaderHole && !printHeaderLine) {
Serial.println("DATA,LINE-X,LINE-Y");
Serial.println("BEEP");
printHeaderLine = true;
printHeaderHole = false;
}
}
}
// Switch off start led
if ( micros() - previousStartMicros >= interval) {
digitalWrite( LED[2], LOW); // turn off led
}
// Switch off stop led
if ( enabledStop) { // software timer is active
if ( micros() - previousStopMicros >= interval) {
digitalWrite( LED[3], LOW); // turn off led
enabledStop = false; // stop software timer
printHeaderStop = false; // Reset flag
}
}
} // End void loop()
//************************************************************************
/* Function: Checks one button for short or long press (micro seconds)
Accepts a byte for the button number
Returns a byte 0-none 1-short 2-long
Info: Action is executed when release button
*/
byte checkButtons(byte buttonNo) {
const unsigned long timeDebounce = 100000;//time to debounce
const unsigned long timeLong = 1000000; //minimum time for Long press
const unsigned long timeBreak = 200000; //time interval after button release,
//before ready for next press
static byte state[maxButton] = {}; //this initializes all elements to zero
static unsigned long previousTime[maxButton] = {};//this initializes all elements to zero
byte r = 0; // 0:not 1:short 2:long
if (state[buttonNo] == 0) { //no button has been pressed - check if
if (digitalRead(pinPushButton[buttonNo]) == LOW) {
previousTime[buttonNo] = micros();
state[buttonNo] = 1;
}
} else if (state[buttonNo] == 1) { //button was pressed - check for how long
if ( (micros() - previousTime[buttonNo]) > timeDebounce) {
if ( (micros() - previousTime[buttonNo]) < timeLong) {
if ( digitalRead(pinPushButton[buttonNo]) == HIGH) { //released -> short press
previousTime[buttonNo] = micros();
state[buttonNo] = 3;
r = 1;
}
} else { //it was a long press
state[buttonNo] = 2;
r = 2;
}
}
} else if (state[buttonNo] == 2) { //wait for long button press to end
if (digitalRead(pinPushButton[buttonNo]) == HIGH) {
previousTime[buttonNo] = micros();
state[buttonNo] = 3;
}
} else if (state[buttonNo] == 3) { //wait a little while after previous button press
if ( (micros() - previousTime[buttonNo]) > timeBreak) {
state[buttonNo] = 0;
}
}
return r;
}
void Achange() {
A = digitalRead(2);
B = digitalRead(3);
//determine state value
if ((A == HIGH) && (B == HIGH)) stateX = 1;
if ((A == HIGH) && (B == LOW)) stateX = 2;
if ((A == LOW) && (B == LOW)) stateX = 3;
if ((A == LOW) && (B == HIGH)) stateX = 4;
switch (stateX) {
case 1:
{
if (statepX == 2) countX--;
if (statepX == 4) countX++;
break;
}
case 2:
{
if (statepX == 1) countX++;
if (statepX == 3) countX--;
break;
}
case 3:
{
if (statepX == 2) countX++;
if (statepX == 4) countX--;
break;
}
default:
{
if (statepX == 1) countX--;
if (statepX == 3) countX++;
}
}
statepX = stateX;
}
void Bchange() {
A = digitalRead(2);
B = digitalRead(3);
//determine state value
if ((A == HIGH) && (B == HIGH)) stateX = 1;
if ((A == HIGH) && (B == LOW)) stateX = 2;
if ((A == LOW) && (B == LOW)) stateX = 3;
if ((A == LOW) && (B == HIGH)) stateX = 4;
switch (stateX) {
case 1:
{
if (statepX == 2) countX--;
if (statepX == 4) countX++;
break;
}
case 2:
{
if (statepX == 1) countX++;
if (statepX == 3) countX--;
break;
}
case 3:
{
if (statepX == 2) countX++;
if (statepX == 4) countX--;
break;
}
default:
{
if (statepX == 1) countX--;
if (statepX == 3) countX++;
}
}
statepX = stateX;
}
//*********************************************
void Cchange() {
C = digitalRead(21);
D = digitalRead(20);
//Determine state value
if ((C == HIGH) && (D == HIGH)) stateY = 0;
if ((C == HIGH) && (D == LOW)) stateY = 1;
if ((C == LOW) && (D == LOW)) stateY = 2;
if ((C == LOW) && (D == HIGH)) stateY = 3;
index = 4 * stateY + statepY;
countY = countY + QEM[index];
statepY = stateY;
}
void Dchange() {
C = digitalRead(21);
D = digitalRead(20);
//Determine state value
if ((C == HIGH) && (D == HIGH)) stateY = 0;
if ((C == HIGH) && (D == LOW)) stateY = 1;
if ((C == LOW) && (D == LOW)) stateY = 2;
if ((C == LOW) && (D == HIGH)) stateY = 3;
index = 4 * stateY + statepY;
countY = countY + QEM[index];
statepY = stateY;
}
Hier een ander voorbeeldje wel met Port Manipulation
- Code: Alles selecteren
/*
Update: ver.06 20/11/2019
Declare QEA and interrupt variables as volatile
in order to reserve memory in the compiler
Pitfall changed QEA into int8_t(negative numbers to)
Code not tested Yet
Purpose: Double 4x Bi-directional encoding
to represent the X-Y axis of a 2d object
and log it in .csv format.
Board: Arduino Mega 2560
Optical encoder open collector
Author: Gij Kieken
Info: I am using an array to determine
the X and Y position
*/
// Used functions
/* myDebounceShortLongPress
Purpose: Debounce an array of push buttons and determine if they
where pressed a short or long time.(micro seconds)
In setup use pinMode(pin, INPUT_PULLUP) so no external
components are necessary.
Buttons connected 1-side to gnd the other to Arduino pin.
Author: Gij Kieken
*/
const byte maxButton = 3; //Number of buttons
const byte pinPushButton[maxButton] = {4, 5, 6}; //Arduino IN pins
const byte maxOutput = 4; //Number of outputs
const byte LED[maxOutput] = {9, 10, 11, 12}; //Arduino OUT pins
boolean modeStatus = false; // Keep track of Hole or Line mode
boolean printHeaderHole = true; // Print header once
boolean printHeaderLine = false; // Print header once
boolean printHeaderStop = false; // Print header once
//**********************
const unsigned long interval = 500000;
unsigned long previousStartMicros;
unsigned long previousStopMicros;
boolean enabledStop = false;
boolean enabledStart = false;
//***********************
volatile long countX = 0;
volatile long countY = 0;
volatile byte stateX, statepX;
volatile byte stateY, statepY;
//Quadrature Encoder Array
volatile const int8_t QEA[16] = {0, -1, 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, -1, 0, 1, 0};
volatile byte Xindex, portD_Xval;
volatile byte Yindex, portD_Yval;
void setup() {
Serial.begin(9600);
pinMode(21, INPUT);//Channel A
pinMode(20, INPUT);//Channel B
pinMode(19, INPUT);//Channel C
pinMode(18, INPUT);//Channel D
//Initialize push button pins as inputs with pull-ups
// button[0]=startButton, button[1]=stopButton, button[2]=modeButton
for (byte i = 0; i < maxButton; i++) {
pinMode(pinPushButton[i], INPUT_PULLUP);
}
//Initialize LED pins as outputs
// LED[0]=HoleLed, LED[1]= LineLed, LED[2]=StartLed, LED[3]=StopLed
for (byte j = 0; j < maxOutput; j++) {
pinMode(LED[j], OUTPUT);
}
digitalWrite(LED[0], !modeStatus); //We start in hole mode
digitalWrite(LED[1], modeStatus); //LineLED=OFF
digitalWrite(LED[2], LOW); //StartLed=OFF
digitalWrite(LED[3], LOW); //StopLed=OFF
attachInterrupt(digitalPinToInterrupt(21), Xchange, CHANGE); //Int 0
attachInterrupt(digitalPinToInterrupt(20), Xchange, CHANGE); //Int 1
attachInterrupt(digitalPinToInterrupt(19), Ychange, CHANGE); //Int 2
attachInterrupt(digitalPinToInterrupt(18), Ychange, CHANGE); //Int 3
//set initial stateX value
portD_Xval = PIND & 0b00000011;//mask D21 and D20
if (portD_Xval == 0b00000011) stateX = 0;
if (portD_Xval == 0b00000010) stateX = 1;
if (portD_Xval == 0b00000000) stateX = 2;
if (portD_Xval == 0b00000001) stateX = 3;
//set initial stateY value
portD_Yval = PIND & 0b00000011;//mask D19 and D18
if (portD_Yval == 0b00001100) stateY = 0;
if (portD_Yval == 0b00001000) stateY = 1;
if (portD_Yval == 0b00000000) stateY = 2;
if (portD_Yval == 0b00000100) stateY = 3;
// Start communication with Excel
Serial.println("CLEARSHEET");
Serial.println("LABEL,X-Pos,Y-Pos");
Serial.println("CELL,SET,C01, Gij Kieken X-Y pos ");
Serial.println("CELL,SET,C02, Long press Start to start log.");
Serial.println("CELL,SET,C03, Short press Start to tween.");
Serial.println("CELL,SET,C04, Short press mode to toggle.");
Serial.println("CELL,SET,C05, Short press Stop to stop log.");
Serial.println("DATA,HOLE-X,HOLE-Y");
}
void loop() {
// put your main code here, to run repeatedly:
static unsigned long previousTime = 0;
const byte timeInterval = 2000; //pick a short time interval
byte button[maxButton] = {}; //array to store the latest readings
// button[0]=startButton, button[1]=stopButton, button[2]=modeButton
// LED[0]=HoleLed, LED[1]= LineLed, LED[2]=StartLed, LED[3]=StopLed
// - check all buttons
if ((micros() - previousTime) > timeInterval) {
previousTime = micros();
for (byte i = 0; i < maxButton; i++) {
button[i] = checkButtons(i);
}
if (button[0] == 1) { // Code, when Start button is short-pushed
//***Continue to Log***
if (enabledStart) {
digitalWrite(LED[2], HIGH);
Serial.print("DATA,");
Serial.print(countX);
Serial.print(",");
Serial.println(countY);
Serial.println("BEEP");
previousStartMicros = micros();
}
}
if (button[0] == 2) { // Code, when Start button is long-pushed
//***Start to Log***
if (!enabledStart) {
digitalWrite(LED[2], HIGH);
enabledStart = true;
// Reset countX and countY
countX = 0;
countY = 0;
Serial.print("DATA,");
Serial.print(countX);
Serial.print(",");
Serial.println(countY);
Serial.println("BEEP");
previousStartMicros = micros();
}
}
if (button[1] == 1) { // Code, when Stop button is short-pushed
//***Stop to Log***
digitalWrite( LED[3], HIGH); // turn on led
if (!printHeaderStop) {
Serial.println("DATA,STOPPED-X,STOPPED-Y"); // Print header
// Reset the flags
modeStatus = LOW; // Reset modeStatus to hole mode
printHeaderLine = false;
printHeaderStop = true; // Make sure header is printed only once
enabledStart = false; // Reset the start flag
enabledStop = true; // Print offset X=0,Y=0 once
digitalWrite(LED[0], !modeStatus); // Change hole led state
digitalWrite(LED[1], modeStatus); // Change line led state
Serial.println("DATA,HOLE-X,HOLE-Y");
Serial.println("BEEP");
Serial.println("SAVEWORKBOOKAS,MyNewX-Y_pos");
printHeaderHole = true;
previousStopMicros = micros();
}
}
if (button[2] == 1) { // Code, when Mode button is short-pushed
//***Select the mode***
// modeStatus=0 ---> hole-modus, modeStatus=1 ---> line-modus
modeStatus = !modeStatus; // Toggle the LED value
digitalWrite(LED[0], !modeStatus); // Change hole led state
digitalWrite(LED[1], modeStatus); // Change line led state
//***Determine mode Hole or Line and printout appropriate header***
if (!modeStatus && !printHeaderHole && printHeaderLine) {
Serial.println("DATA,HOLE-X,HOLE-Y");
Serial.println("BEEP");
printHeaderHole = true; // Make sure header is printed only once
printHeaderLine = false;
}
else if (modeStatus && printHeaderHole && !printHeaderLine) {
Serial.println("DATA,LINE-X,LINE-Y");
Serial.println("BEEP");
printHeaderLine = true;
printHeaderHole = false;
}
}
}
// Switch off start led
if ( micros() - previousStartMicros >= interval) {
digitalWrite( LED[2], LOW); // turn off led
}
// Switch off stop led
if ( enabledStop) { // software timer is active
if ( micros() - previousStopMicros >= interval) {
digitalWrite( LED[3], LOW); // turn off led
enabledStop = false; // stop software timer
printHeaderStop = false; // Reset flag
}
}
} // End void loop()
//************************************************************************
/* Function: Checks one button for short or long press (micro seconds)
Accepts a byte for the button number
Returns a byte 0-none 1-short 2-long
Info: Action is executed when release button
*/
byte checkButtons(byte buttonNo) {
const unsigned long timeDebounce = 100000;//time to debounce
const unsigned long timeLong = 1000000; //minimum time for Long press
const unsigned long timeBreak = 200000; //time interval after button release,
//before ready for next press
static byte state[maxButton] = {}; //this initializes all elements to zero
static unsigned long previousTime[maxButton] = {};//this initializes all elements to zero
byte r = 0; // 0:not 1:short 2:long
if (state[buttonNo] == 0) { //no button has been pressed - check if
if (digitalRead(pinPushButton[buttonNo]) == LOW) {
previousTime[buttonNo] = micros();
state[buttonNo] = 1;
}
} else if (state[buttonNo] == 1) { //button was pressed - check for how long
if ( (micros() - previousTime[buttonNo]) > timeDebounce) {
if ( (micros() - previousTime[buttonNo]) < timeLong) {
if ( digitalRead(pinPushButton[buttonNo]) == HIGH) { //released -> short press
previousTime[buttonNo] = micros();
state[buttonNo] = 3;
r = 1;
}
} else { //it was a long press
state[buttonNo] = 2;
r = 2;
}
}
} else if (state[buttonNo] == 2) { //wait for long button press to end
if (digitalRead(pinPushButton[buttonNo]) == HIGH) {
previousTime[buttonNo] = micros();
state[buttonNo] = 3;
}
} else if (state[buttonNo] == 3) { //wait a little while after previous button press
if ( (micros() - previousTime[buttonNo]) > timeBreak) {
state[buttonNo] = 0;
}
}
return r;
}
//*********************************************
// Faster ISR digital Read
void Xchange() {
cli();
statepX = stateX;
portD_Xval = PIND & 0b00000011;//mask D21 and D20
if (portD_Xval == 0b00000011) stateX = 0;
if (portD_Xval == 0b00000010) stateX = 1;
if (portD_Xval == 0b00000000) stateX = 2;
if (portD_Xval == 0b00000001) stateX = 3;
Xindex = 4 * stateX + statepX;
countX = countX + QEA[Xindex];
sei();
}
// Faster ISR digital Read
void Ychange() {
cli();
statepY = stateY;
portD_Yval = PIND & 0b00001100;//mask D19 and D18
if (portD_Yval == 0b00001100) stateY = 0;
if (portD_Yval == 0b00001000) stateY = 1;
if (portD_Yval == 0b00000000) stateY = 2;
if (portD_Yval == 0b00000100) stateY = 3;
Yindex = 4 * stateY + statepY;
countY = countY + QEA[Yindex];
sei();
}
6 berichten
• Pagina 1 van 1
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 3 gasten