/* A / B Fake - Geber per Software mit Hilfe von Tone-Funktion
ACHTUNG -- die ganzen Berechnung erfolgen in Micro Sekunden / micros
*/
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialisierung abgeschrieben !
// Pin-2 muss frei bleiben für INT-0 zur Frequenzberechnung
const byte speedm_Pb = 3; // Taster Fake-Geber langsamer
const byte speedp_Pb = 4; // Taster Fake-Geber schneller
const byte dir_Sw = 5; // Schalter zur Richtungsvorgabe
const byte Reset_Pb = 6; // Taster Reset Fake-Geber
const byte Dir_Cnt_Out = 7; // Binärer Zähler Anzeige Richtung auf/ab, auf=1 ab=0
const byte F_Gen_Out = 8; // Ausgang des man. erzeugten Taktsignal
const byte Enc_A_Out = 9; // Encoder Spur-A Ausgang low => on
const byte Enc_B_Out = 10; // Encoder Spur-B Ausgang npn-System
unsigned long taktzeit4tel_min = 6250; // Taktzeitvariable 4-tel n-min 6.250 mys
unsigned long taktzeit4tel_max = 83; // Taktzeitvariable 4-tel n-max 83,3 mys nur Ganzzahlen !
unsigned long taktzeit4tel = 0; // Taktzeitvariable -- muss 4-mal höher sein als Bin-Zählertakt
unsigned int frequenz = 0; // theoretische Frequenz vom erzeugten Fake-Geber
boolean counter_dir = 1; // Binärer Zähler Richtung auf/ab, auf=1 ab=0
volatile unsigned long highTime = 0; // Impulsdauer von was ?
volatile unsigned long lowTime = 0; // Pausendauer von was ?
volatile unsigned long startmicros = 0; // ? Die Zeiten sind 2-mal so lang wie die Zählertaktzeit !!! ?
volatile byte bin_counter = 0; // Binärer Zähler 0-3 als Grundlage
volatile boolean bin_0 = 0; // Bit-0 in bin_counter
volatile boolean bin_1 = 0; // Bit-1 in bin_counter
volatile byte gray_fake_counter = 0; // Gray-Code Zähler 0-3 zur Impulsausgabe
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 unsigned long actualtime = 0; // Zähler ab Programmstart in ca. Microsekunden !!!
void setup() {
lcd.init();
lcd.backlight();
// Serial.begin(115200);
pinMode(speedm_Pb, INPUT_PULLUP); // Taster sw
pinMode(speedp_Pb, INPUT_PULLUP); // Taster ws
pinMode(dir_Sw, INPUT_PULLUP); // Schalter
pinMode(Reset_Pb, INPUT_PULLUP); // Taster rt
pinMode(Dir_Cnt_Out, OUTPUT); // LED gelb
pinMode(F_Gen_Out, OUTPUT); // LED rot
pinMode(Enc_A_Out, OUTPUT); // LED ws
pinMode(Enc_B_Out, OUTPUT); // LED türkis
// attachInterrupt(digitalPinToInterrupt(0), messung, CHANGE); // automatischer Aufruf der Funktion "messung",
// wenn Pin-2 mit Ausgang verbunden wird
// NICHT in Loop aufrufen !!!
actualtime = 0; // aktuelle Zeit auf 0
taktzeit4tel = 3000; // TESTWERT für n-max/2 // 1/4 Taktzeit für binären Zähler in mys !!!
}
//---------------------------------------------------------------------------------------------------------------------------------
// !!! BIS HIER HIN ALLES NEU !!!
// Frequenz Generator: zum Betrieb des Bin-Zählers, Taktzeit muss 4-mal schneller sein als Soll Taktfrequenz
// bei < Fmin. muss Frequenz = 0 sein, F-max. = 12 kHz bzw. 4 kHz Zählerfrequenz
// SPÄTER zu übergeben sind Fmin, Fmax, Rückgabe ist Frequenz
void frq_generator() {
if (micros() >= (actualtime + taktzeit4tel)) { // oder so: // if (micros() - taktzeit4tel >= actualtime)
actualtime = micros(); // aktuelle Zeit neu setzen ...
if (counter_dir == 1) { // Drehrichtungsvorgabe berücksichtigen / 1 => Zähler +, 0 => Zähler -
if (bin_counter == 3) { // wenn der Zähler = 3 dann OHNE Hochzählen sofort auf 0
bin_counter = 0;
} else {
bin_counter++; // Counterclockwise, definiert rechts rum von 0 bis 3
}
} else {
if (bin_counter == 0) { // wenn der Zähler = 0 dann OHNE Runterzählen sofort auf 3
bin_counter = 3;
} else {
bin_counter--;
}
}
}
// hier die Frequenz über taktzeit4tel einstellen von min. -- max.
// n-min == 6.250 mys -- n-max == 83,3 mys
// ACHTUNG Zählergschwindigkeit umgekehrt zum Vorgabewert
if (digitalRead(speedm_Pb) == LOW) { // Speed-minus-Taster für taktzeit4tel / Taktzeit Fake-Geber
if ( taktzeit4tel < taktzeit4tel_min ) { // 6.250 mys n-min
taktzeit4tel++;
}
}
if (digitalRead(speedp_Pb) == LOW) { // Speed-plus-Taster für taktzeit4tel / Taktzeit Fake-Geber
if ( taktzeit4tel > taktzeit4tel_max ) { // 83 mys n-max
taktzeit4tel--;
}
}
}
//---------------------------------------------------------------------------------------------------------------------------------
/*
// Fake-Encoder: mit 4-facher "Tone-Frequenz" endlos laufen lassen
void gray_fake_encoder () {
if (millis() >= actualtime + taktzeit4tel) { // oder so: // if (millis() - taktzeit4tel >= actualtime)
actualtime = millis(); // aktuelle Zeit neu setzen ...
if ((PIND >> 3) & 1) { // DrehrichtungsVORGABE erkennung / 1 => Zähler +, 0 => 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
// 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 !!!
// jetzt direkt in Ausgangsport schreiben / ACHTUNG vorher abfragen ob 1 oder 0 gesetzt werden soll
if ( gray_fake_0 == 0 ) { // PortB1 / PIN-D8 schreiben
PORTB &= B11111110;
} else {
PORTB |= B00000001;
}
if ( gray_fake_1 == 0 ) { // PortB1 / PIN-D9 schreiben
PORTB &= B11111101;
} else {
PORTB |= B00000010;
} // fertig
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 "taktzeit4tel"
lcd.setCursor(8, 1);
lcd.print( lowTime); // Die Zeit ist gleich 2-mal der "taktzeit4tel"
}
}
*/
//---------------------------------------------------------------------------------------------------------------------------------
// Werte zum Test auf`s Display schreiben
void lcd_print () { // Ausgabe auf LCD-Display, keine weitere Ausgaben
lcd.setCursor(0, 0);
lcd.print(bin_counter);
lcd.setCursor(3, 0);
lcd.print(taktzeit4tel);
}
//---------------------------------------------------------------------------------------------------------------------------------
void loop() {
frq_generator ();
lcd_print ();
// gray_fake_encoder ();
if (digitalRead(Reset_Pb) == LOW) { // Reset-Taster für LCD-Display ...
lcd.clear();
}
if (digitalRead(dir_Sw) == LOW) { // Richtungsschalter für Taktzeit Fake-Geber
counter_dir = 1;
}else{
counter_dir = 0;
}
digitalWrite(Dir_Cnt_Out, counter_dir); // Binärer Zähler Anzeige Richtung auf/ab, auf=1 ab=0
}
//---------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------
/*
// 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;
// ilowTime = ilowTime + lowTime;
} else {
// highTime = micros() - startmicros;
highTime = millis() - startmicros;
// ihighTime = ihighTime + highTime;
}
// startmicros = micros();
startmicros = millis();
}
*/
//---------------------------------------------------------------------------------------------------------------------------------
// ENDE des Ganzen ...