Rotary encoder tellen pulsen te snel, help

Hardware geleverd door Arduino
Berichten: 8
Geregistreerd: 14 Feb 2024, 09:55

Rotary encoder tellen pulsen te snel, help

Berichtdoor BartM » 14 Feb 2024, 10:10

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

Advertisement

Berichten: 8
Geregistreerd: 14 Feb 2024, 09:55

Re: Rotary encoder tellen pulsen te snel, help

Berichtdoor BartM » 14 Feb 2024, 21:11

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
);
}

Berichten: 4067
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Rotary encoder tellen pulsen te snel, help

Berichtdoor shooter » 15 Feb 2024, 10:41

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

Berichten: 8
Geregistreerd: 14 Feb 2024, 09:55

Re: Rotary encoder tellen pulsen te snel, help

Berichtdoor BartM » 15 Feb 2024, 22:44

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 ?

Berichten: 80
Geregistreerd: 02 Nov 2022, 13:03

Re: Rotary encoder tellen pulsen te snel, help

Berichtdoor ThHe » 16 Feb 2024, 01:11

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.
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

Gebruikers-avatar
Berichten: 631
Geregistreerd: 15 Nov 2015, 11:54

Re: Rotary encoder tellen pulsen te snel, help

Berichtdoor Gij Kieken » 17 Feb 2024, 21:38

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.

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();
}

Terug naar Arduino hardware

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 37 gasten