#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialisierung abgeschrieben !
const byte speedpin = 2; // Port-D Bit-2 Digital Pin-2 Wird als Spur-A eingelesen per Interrupt
const byte dirpin = 3; // Port-D Bit-3 Digital Pin-3 Wird als Spur-B mit eingelesen für Richtungserkennung
const byte Reset_Taster = 4; // Taster z.B. zum Reset falls vorhanden
const byte Enc_A_Out = 8; // Encoder Spur-A Ausgang low => on
const byte Enc_B_Out = 9; // Encoder Spur-B Ausgang npn-System
volatile unsigned long highTime; // Impulsdauer Encoder Spur-A
volatile unsigned long lowTime; // Pausendauer
volatile unsigned long startmicros; // Die Zeiten sind 2-mal so lang wie die Zählertaktzeit !!!
volatile byte gray_fake_counter = 0;
volatile boolean gray_fake_0 = 0; // Bit-0 in gray_fake_counter
volatile boolean gray_fake_1 = 0; // Bit-1 in gray_fake_counter
volatile byte bin_fake_counter = 0;
volatile boolean bin_fake_0 = 0; // Bit-0 in bin_fake_counter
volatile boolean bin_fake_1 = 0; // Bit-1 in bin_fake_counter
volatile unsigned long actualtime; // Zähler ab Programmstart in ca. Millisekunden
volatile unsigned long difftime; // Differenzzeit / 1/4-Taktzeit für Fake-Encoder in ms.
void setup() {
lcd.init();
lcd.backlight();
pinMode(speedpin, INPUT_PULLUP);
pinMode(dirpin, INPUT_PULLUP);
pinMode(Reset_Taster, INPUT_PULLUP);
pinMode(Enc_A_Out, OUTPUT);
pinMode(Enc_B_Out, OUTPUT);
attachInterrupt(0, messung, CHANGE); // automatischer Aufruf der Funktion "messung", NICHT in Loop aufrufen !!!
Serial.begin(9600);
actualtime = 0; // aktuelle Zeit auf 0
difftime = 1500; // Timerzeit in ms
}
//---------------------------------------------------------------------------------------------------------------------------------
void gray_fake_encoder () {
// Fake-Encoder mit 4-fach "difftime" Takt endlos laufen lassen
if (millis() >= actualtime + difftime) { // oder so: // if (millis() - difftime >= actualtime)
actualtime = millis(); // aktuelle Zeit neu setzen ...
if ((PIND >> 3) & 0) { // DrehrichtungsVORGABE erkennung / 0 => Zähler +, 1 => Zähler -
if (bin_fake_counter == 3) { // wenn der Zähler = 3 dann OHNE Hochzählen sofort auf 0
bin_fake_counter = 0;
} else {
bin_fake_counter++; // Counterclockwise, definiert rechts rum von 0 bis 3
}
} else {
if (bin_fake_counter == 0) { // wenn der Zähler = 0 dann OHNE Runterzählen sofort auf 3
bin_fake_counter = 3;
} else {
bin_fake_counter--;
}
}
// Bin to Gray -- "bin_fake_counter" in "gray_fake_counter" umwandeln
gray_fake_1 = bitRead(bin_fake_counter, 1); // gray Bit-1 = bin Bit-1, 1 zu 1 kopieren
gray_fake_0 = ( bitRead(bin_fake_counter, 1) ^ bitRead(bin_fake_counter, 0) ); // gray Bit-0 = bin Bit-1 EXOR bin Bit-0 !!!
bitWrite(gray_fake_counter, 0, gray_fake_0); // gray_fake_counter mit Bit 0 und Bit-1 laden
bitWrite(gray_fake_counter, 1, gray_fake_1);
// Bits nacheinander auf Ausgänge ausgeben - recht lagsam
// jetzt direkt in Ausgangsport schreiben
digitalWrite(Enc_A_Out, ! gray_fake_0); // Encoder Spur-A und B über LED anzeigen
digitalWrite(Enc_B_Out, ! gray_fake_1); // LED leuchtet bei Encoder = 0 !!!
// alternativ über Port Schreiben ausgeben
// PortB0 / PIN-D8 schreiben ??? 1 schreiben / 0 schreiben wie
// PortB1 / PIN-D9 schreiben
lcd.setCursor(0, 0);
lcd.print(bin_fake_counter);
lcd.setCursor(3, 0);
lcd.print(gray_fake_counter);
lcd.setCursor(0, 1);
lcd.print( highTime); // Die Zeit ist gleich 2-mal der "difftime"
lcd.setCursor(8, 1);
lcd.print( lowTime); // Die Zeit ist gleich 2-mal der "difftime"
}
}
//---------------------------------------------------------------------------------------------------------------------------------
void lcdputzen() {
lcd.clear();
}
//---------------------------------------------------------------------------------------------------------------------------------
void loop()
{
// delay(10); // every second
// Serial.print("highTime: "); Serial.print(highTime); Serial.print(" ");
// Serial.print("lowTime: "); Serial.print(lowTime); Serial.print(" ");
// Serial.println();
gray_fake_encoder ();
/* lcd.clear();
lcd.setCursor(0, 0);
lcd.print( highTime);
lcd.setCursor(0, 1);
lcd.print( lowTime);
*/
if (digitalRead(Reset_Taster) == LOW) {
lcdputzen();
}
}
//---------------------------------------------------------------------------------------------------------------------------------
// Funktion an Interrupt-0 / an Pin-2, Messung der Impuls- und Pausendauer durch Flankenauswertung
void messung() {
if ((PIND >> 2) & 1) {
// lowTime = micros() - startmicros;
lowTime = millis() - startmicros;
} else {
// highTime = micros() - startmicros;
highTime = millis() - startmicros;
}
// startmicros = micros();
startmicros = millis();
// lcd.setCursor(0, 0);
// lcd.print( highTime);
// lcd.setCursor(0, 1);
// lcd.print( lowTime);
}