/* KY-040 Rotary Encoder Counter
Rotate clockwise to count up, counterclockwise to counter done.
Press to reset the counter.
Copyright (C) 2021, Uri Shaked
Warnung einfügen: ca. 10 cm vor erreichen der Sollänge einen #warnton ausgeben bei jedem cm.
*/
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//Für Bedienung
#define ENCODER_CLK 2
#define ENCODER_DT 5
#define ENCODER_SW 4
int counter = 0 ;
int laengeWahl = 1000 ;
int laengeWahlAlt =0;
float cm =0;
float cm1 =0;
bool einstellen = false ;
bool choice = false ;
//für Längenmessung
#define ENCODER2_CLK 3
#define ENCODER2_DT 6
#define ENCODER2_SW 7
int counter2 = 0 ;
int counter2alt = 0 ;
int counter2wahl = 1000 ;
#define RTASTER 12
#define Summer 10
#define LED 11
unsigned long lastPulseTime = 0; // Zeit des letzten Impulses
const unsigned long fastThreshold = 1000; // Schwellenwert für schnelle Drehung in Millisekunden
/*
Menü:
- Längenvorwahl
- individuelle Einstellung der gewünschten Leitungslänge in cm
- Start
Taster: aktuelle Länge auf 0 setzen
Summer + LED an: wenn gewünschte Länge erreicht ist
*/
void setup() {
// Initialize LCD
lcd.init();
lcd.backlight();
pinMode(Summer, OUTPUT); //LED
pinMode(LED, OUTPUT); //Summer
pinMode(RTASTER, INPUT_PULLUP); //
// Initialize encoder pins
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
pinMode(ENCODER2_CLK, INPUT);
pinMode(ENCODER2_DT, INPUT);
pinMode(ENCODER2_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER2_CLK), readEncoder2, FALLING);
menu ();
}
void readEncoder() {
unsigned long currentTime = millis();
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
counter++; // Clockwise
if (currentTime - lastPulseTime < fastThreshold) {
laengeWahl += 20; // Bei schneller Drehung um 10 erhöhen
} else {
laengeWahl++; // Bei normaler Drehung um 1 erhöhen
}
}
if (dtValue == LOW) {
counter--; // Counterclockwise
if (currentTime - lastPulseTime < fastThreshold) {
laengeWahl -= 20; // Bei schneller Drehung um 10 erhöhen
} else {
laengeWahl--; // Bei normaler Drehung um 1 erhöhen
}
}
lastPulseTime = currentTime;
}
void readEncoder2() {
int dtValue = digitalRead(ENCODER2_DT);
if (dtValue == HIGH) {
counter2++; // Clockwise
}
if (dtValue == LOW) {
counter2--; // Counterclockwise
}
}
// Get the counter value, disabling interrupts.
// This make sure readEncoder() doesn't change the value
// while we're reading it.
int getCounter() {
int result;
noInterrupts();
result = counter;
interrupts();
return result;
}
void resetCounter() {
noInterrupts();
choice = !choice ;
interrupts();
}
void menu ()
{
if (choice == false)
{
lcd.setCursor(0, 0);
lcd.print(" LEITUNG MESSEN ");
lcd.setCursor(0, 1);
lcd.print(" einstellen messen");
//lcd.setCursor(0, 2);
//lcd.print(" Two Five ");
//lcd.setCursor(3, 3);
//lcd.print("Three Six ");
einstellen = false ;
}
else if (counter == 1 && choice == true)
{
lcd.setCursor(0, 0);
lcd.print(" gew\365nschte L\341nge ");
lcd.setCursor(0, 1);
lcd.print(" einstellen ");
einstellen = true ;
}
else if (counter == 2 && choice == true && einstellen == false)
{
lcd.setCursor(0, 0);
lcd.print(" M E N U - 2 ");
lcd.setCursor(0, 1);
lcd.print(" 2 2 2 2 ");
}
}
void loop() {
//aktuelle Länge anzeigen
if (counter2alt != counter2){
cm1 = counter2 / 125.4;
lcd.setCursor(0, 2);
lcd.print(" gemessen ");
lcd.setCursor(13, 2);
lcd.print(cm1,4);
lcd.print(" m");
counter2alt = counter2;
}
//einstellen der gewünschten Länge
if (einstellen){
if (laengeWahlAlt != laengeWahl){
cm = laengeWahl / 100.0;
lcd.setCursor(0, 3);
lcd.print(" eingestellt ");
lcd.setCursor(13, 3);
lcd.print(cm,3);
lcd.print(" m");
laengeWahlAlt = laengeWahl;
}
}
//Länge auf 0 setzen
if (digitalRead(RTASTER) == LOW) {
counter2 = 0;
}
//Summer und LED nur einschalten, wenn gemessen wird
if (counter == 2){
if (cm1 >= cm){
digitalWrite(LED, HIGH);
digitalWrite(Summer, HIGH);
}else {
digitalWrite(LED, LOW);
digitalWrite(Summer, LOW);
}
//Vorwarnung
if (cm1 == cm - 0.6 || cm1 == cm - 0.4 || cm1 == cm - 0.2 || cm1 == cm - 0.1 ){
digitalWrite(LED, HIGH);
digitalWrite(Summer, HIGH);
}
if (cm1 == cm - 0.08 || cm1 == cm - 0.06 || cm1 == cm - 0.04 || cm1 == cm - 0.02 ){
digitalWrite(LED, HIGH);
digitalWrite(Summer, HIGH);
}
if (cm1 == cm - 0.5 || cm1 == cm - 0.3 || cm1 == cm - 0.11 || cm1 == cm - 0.01 ){
digitalWrite(LED, LOW);
digitalWrite(Summer, LOW);
}
if (cm1 == cm - 0.09 || cm1 == cm - 0.07 || cm1 == cm - 0.05 || cm1 == cm - 0.03 ){
digitalWrite(LED, LOW);
digitalWrite(Summer, LOW);
}
}
if (digitalRead(ENCODER_SW) == LOW) {
resetCounter();
menu () ;
}
if (counter == 1 && choice == false) {
menu () ;
lcd.setCursor(0, 1);
lcd.print(">");
}
else if (counter == 2 && choice == false) {
menu () ;
lcd.setCursor(13, 1);
lcd.print(">");
}
else if (counter > 3)
{
counter = 1 ;
menu () ;
}
else if (counter < 0 )
{
counter = 2 ;
menu () ;
}
else if (counter == 0 )
{
menu () ;
}
delay(50);
}