kleiner Test
/**************************LCD *****************************************************
Variants of German umlauts Ä Ö Ü
LCD in parallel 4 bit Mode
open tasks:
- ISO 8583 Latin 1 - 4 Characters on LCD with SPI connector
Hardware:
LCD should be wired as follows:
LCD UNO
--------------------------
VSS GND GND
VDD 5V Vin
V0 - contrast - connect a poti to GND
RS P0 RS
RW GND - Read/Write not used in this library - Pulldown to GND
E P2 EN
DB0 -
DB1 -
DB2 -
DB3 -
D4 P4 DB4
D5 P5 DB5
D6 P6 DB6
D7 P7 DB7
LEDA 5V
LEDK GND P10 Backlight circuitry (HIGH signal enables backlight using a simple NPN transistor)
by noiasca
2021-05-16
2020-09-01 base 4bit 2928/296
******************************************************************************
*/
const byte cols = 16; // columns/characters per row
const byte rows = 2; // how many rows
const byte rs = 34;
const byte en = 32;
const byte d4 = 31;
const byte d5 = 33;
const byte d6 = 35;
const byte d7 = 37;
const byte bl = 36; // set to 255 if not used
//#define CLICK_NO_SHORT // MobaTools: das ‚shortPress‘ Ereignis wird gelöscht, wenn beim Aufruf von ‚clicked‘ ein Einfach- oder Doppel-Klick erkannt wurde.
#define MAX8BUTTONS // MobaTools: maximal acht Taster
#include <MobaTools.h>
#include <AVR_PWM.h>
#include <Wire.h>
#include <NoiascaEncoder.h> // download library from http://werner.rothschopf.net/microcontroller/202202_noiasca_encoder_en.htm
#include <NoiascaLiquidCrystal.h> // download library from https://werner.rothschopf.net/202009_arduino_liquid_crystal_intro.htm
//#include <NoiascaHW/lcd_4bit.h> // parallel interface, 4bit
#include <NoiascaHW/lcd_PCF8574_fast.h>// include the proper IO interface *** Nur für Simm Martin ****
//LiquidCrystal_4bit LCD(rs, en, d4, d5, d6, d7, bl, cols, rows);
LiquidCrystal_PCF8574_fast LCD(0x27, 16, 2); // *** Nur für Simm Martin ****
button_t getHW( void ); // macht den Compiler hinsichtlich Reihenfolge glücklich
MoToButtons taster( getHW, 20, 2000 ); // 50ms Entprellzeit, 2000ms für den Unterschied kurz/lang gedrückt.
enum tasterNr { TASTER_S, TASTER_O, TASTER_U, TASTER_D , Button1, Button2, Button3}; // Index für die MobaTools
Encoder myEnc(28, 24);// Interruptpin wählen // (DT grau und CLK grün)
const byte DrehTast = 26; // Taster Drehencoder *gelb
const byte tasterS = 4; // Taster Stopp
const byte tasterU = 3; // Taster Unten / vorne runter
const byte tasterO = 2; // Taster Oben / vorne rauf
const byte Butt_1 = 30; // Handtaster rechts / vorne rauf *blau
const byte Butt_2 = 27; // Handtaster links / vorne runter *pink
const byte Butt_3 = 25; // Handtaster Stopp *violett
button_t getHW( void ) // Einlesen der Tasterstatus (Plural lt. Duden)
{
button_t tasterTemp = 0;
bitWrite( tasterTemp, 0, !digitalRead(tasterS) ); // 0
bitWrite( tasterTemp, 1, !digitalRead(tasterO) ); // 1
bitWrite( tasterTemp, 2, !digitalRead(tasterU) ); // 2
bitWrite( tasterTemp, 3, !digitalRead(DrehTast) ); // 3
bitWrite( tasterTemp, 4, !digitalRead(Butt_1) ); // 4
bitWrite( tasterTemp, 5, !digitalRead(Butt_2) ); // 5
bitWrite( tasterTemp, 6, !digitalRead(Butt_3) ); // 6
return tasterTemp;
}
const byte Poti = A0; // Potischleifer an Pin Poti ca. 10-50 K Ohm als Spannungsteiler mit C = 10 uF Schleifer / GND
MoToServo DornServo;
// *************** PWM Motor ***********//
uint32_t PWM_Pins[] = { 46, 6 }; // A Timer 5 und 4
//uint32_t PWM_Pins[] = { 7, 45 }; // B Timer 45 RichtungA 7 RichtungB
//uint32_t PWM_Pins[] = { 8, 44 }; // C Timer 44 Richtung C für Lok B
#define NUM_OF_PINS ( sizeof(PWM_Pins) / sizeof(uint32_t) )
float dutyCycle[] = { 0.0f, 0.0f };
float freq[] = {20000.0f , 20000.0f}; // 1. Paternosterantrieb , 2. für Lok
AVR_PWM* PWM_Instance[NUM_OF_PINS];
const byte RichtungA = 45; // Drehrichtung H-Brücke 1 * Paternoster *
const byte RichtungB = 7; // Drehrichtung H-Brücke 2 * Lok 1 *
const byte RichtungC = 44; // Drehrichtung H-Brücke 3 * Lok 2 * Nur wenn Paternoster frei
const byte LokB = 47; // Wechsel auf Lok B ** SETUP für LokB: RichtungA = LOW ; LokB = HIGH ***
const byte Enabel = 8; // H-Bruecke Ein / Aus
const byte Enabel2 = 5; // H-Bruecke für Lok 1 Ein / Aus
// ****************** Sensoren ******************* //
const byte TCRT = A4; // Pin Sensor TCRT Gondel Postition
const byte SlowO = A2; // Pin Sensoren Langsamfahrt
const byte SlowU = A3; // Pin Sensoren Langsamfahrt
const byte TCRTG = A1; // Pin Sensor TCRT für Gondel Lesen Strichcode
const byte BGondel = A5; // Pin Belgtmeldung Gondel Abfrage
const byte Haltepunkt = 37; // Wert Haltepunkt Gondel für Sensor TCRT5000
// ****************** Sonstiges ******************* //
const byte R1Gondel = 38; // Relais 1 Gondel Belegtmeldung
const byte R2Gondel = 39; // Relais 2 Gondel Belegtmeldung
const byte Dorn = 22; // PIN Erkennung Dornlage Dorn Hinten?
const byte Panel = 29; // PIN Erkennung Handpanel Tasten / Drehgeber Gesteckt orange
const byte LED = 13; // LED Arduino Board
const byte Servo = 12; // Servo an PIN
// ****************** Gondel / Gondelfahrt ******************* //
uint16_t Setzzeit[3]; // verrechnungszeiten Gondel Lesen
uint16_t Lesezeit[7]; // verrechnungszeiten Gondel Lesen
const byte Teiler= 10; // Teiler 10 aus 10 mm breite der obersten und untersten Balken der Strichcodes
const byte Tolleranz = 4; // Tolleranzwert Genauigkeit Lesen Strichcode
uint8_t gondel,gondelAlt,GondelSetz; // Vari für Gondelfahrt
byte Richtung; // Fahrtrichtung
enum Richtung {Halt,Oben,Unten,Stop,Vor,Ruek};
byte Status,GStatus,GFehler,GLesen; // Vari für Paternosterfahrt Nr. Lesen
enum Status {Aus,Anfahren,Bremsen,SlowOben,SlowUnten,ASlowUnten};
// Start PWM Richtung Oben ***********
// | Max PWM Richtung Oben
// | | Slow PWM Richtung Oben
// | | | Start PWM Richtung Unten
// | | | | Max PWM Richtung Unten
// | | | | | Slow PWM Richtung Unten
uint8_t Rampe[] = { 10, 50, 20, 10, 50, 20}; // **** Anfang PWM /Beschleunigung / Slow Fahrt
// Rampe auf neue PWM angepasst da 0 bis 100% gegeben sind. Werte sind durch Versuche zu ermitteln
// ********** Motorzeiten / Zeiten ******************* //
MoToTimer pause;
const uint8_t intervall = 80; // Intervall Zeit Poti einlesen
const uint8_t Gintervall = 2; // Intervall Zeit GondelPositions Abfrage
const uint8_t Motorintervall = 10; // Intervall Zeit Beschleunigung **** 10 nur für Simm
const uint8_t Bremsintervall = 8; // Intervall Zeit Bremsen **** 8 nur für Simm
const uint8_t StopIntervall = 5; // Intervall Zeit Bremsen bei Slow Fahrt
const uint8_t Pulswelle = 5; // PWM % +/- im Interwall
uint32_t zeitAlt, Time1, Time2, Time3, Time4;
const uint8_t warteLCD =5; // Zeit in Sec. für No Backlight LCD
uint16_t speed,speedAlt; // PWM Geschwindigkeiten Potieinstellung
uint8_t pwb,pw,pwh; // PWM Übergabevaiable pwh für Handpanel
uint8_t pwLok1,pwLok2; // PWM Lock 1 und Lok 2
const byte PWMax=99; // Maximale PWM
const byte Servospeed = 50; // Servogeschwindigkeit
const byte Servolage[] {50,155,95}; // Servoendlagen !! Wert muss erst ermittelt werden Werte nur zur Simmulation
enum Servolage{Frei,Geklemmt,Mitte};
const uint16_t S_fahrzeit =1500; // verfahrzeit für Servo
const uint16_t Kontakt=100; // Gemessender Wert wenn Dorn geklemmt !! Muss noch ermittelt werden!!
uint8_t val,valOld; // Vari für Servoeinstellung
uint8_t SWE = 0; //
uint8_t SW, SW1, SW2, SW3, SW4, SW5, SER, KON, Fehler, Belegt, Lok_1, Lok_2 ; // ******* Allgemeine Laufschalter ****** //
int wert;
char zeichen = 0;
// ***************** Drehgeber ************************ //
long newPosition = 42; // the current value to be used in your sketch
long oldPosition = 42; // internal used previous value
void setup()
{
Wire.begin();
LCD.begin();Time4=millis(); LCD.backlight();
ALCD(1,0,3,0,0);ALCD(0,1,1,1,0);
pinMode(DrehTast, INPUT_PULLUP);
pinMode(tasterS, INPUT_PULLUP);
pinMode(tasterO, INPUT_PULLUP);
pinMode(tasterU, INPUT_PULLUP);
pinMode(Butt_1, INPUT_PULLUP);
pinMode(Butt_2, INPUT_PULLUP);
pinMode(Butt_3, INPUT_PULLUP);
pinMode(Enabel, OUTPUT);
pinMode(Enabel2, OUTPUT);
pinMode(TCRT, INPUT);
pinMode(TCRTG, INPUT_PULLUP);
pinMode(LED, OUTPUT);
// pinMode(R1Gondel, OUTPUT);
// pinMode(R2Gondel, OUTPUT);
pinMode(BGondel,INPUT);
pinMode(SlowO, INPUT_PULLUP);
pinMode(SlowU, INPUT_PULLUP);
pinMode(Panel, INPUT_PULLUP);
pinMode(RichtungA, OUTPUT);
pinMode(RichtungB, OUTPUT);
pinMode(RichtungC, OUTPUT);
pinMode(LokB, OUTPUT);
pinMode(Dorn, INPUT_PULLUP); /* Dorn Pin 22 ist mit Brücke auf 5V */
digitalWrite(Enabel,0);digitalWrite(Enabel2,0);
for (uint8_t index = 0; index < NUM_OF_PINS; index++)
{
PWM_Instance[index] = new AVR_PWM(PWM_Pins[index], freq[index], dutyCycle[index]);
analogWrite(PWM_Pins[index],0);
}
Serial.begin(115200);
Serial1.begin(38400); // Pin 18 TX Pin 19 RX auf Bluetooth HC-05
myEnc.begin();
delay(500);
char buf[150];
snprintf( buf, sizeof(buf), "\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n\n", __FILE__, __TIMESTAMP__, ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10);
Serial.print(buf); // Ausgabe des Sketchnamens
DornServo.attach(Servo); //Servo an Pin 12
DornServo.setSpeed( Servospeed ); // Verfahrgeschwindigkeit einstellen
if(!digitalRead(Panel)){// Ist Panel beim Start eingesteckt wird gleich zum Handpanel gestellt //
LCD.backlight();
Serial.println("Handpanel angeschlossen");
ALCD(1,0,3,0,1);
}else{
PRINTStart();
}
SERVO(Frei) ;
if(digitalRead(Dorn)) {
Fehler=1;}
else{
ALCD(1,0,3,0,0);ALCD(0,1,5,1,8);} // LCD Ausgabe ** Paternoster Bereit **
gondelAlt=5;gondel=5; // Zu Testzwecken solange keine Gondel ins EEProm vermekt wird Start mit Gondel 5//
pwLok1=50;pwLok2=80; // Nur zu Testzwecke ****************
}
void loop()
{
delay(1000);
LCD.noBacklight();
delay(5000);
LCD.backlight();
}
void SERVO( byte stell) {
switch (stell){
case Frei:
Serial.println("Frei klappt");SW=0;
DornServo.write(Servolage[Frei]);
delay(S_fahrzeit);
if(digitalRead(Dorn)){
for(byte i=0;i<6;i++){
DornServo.write(Servolage[Mitte]);
delay(S_fahrzeit/2);
DornServo.write(Servolage[Frei]);SW++;
delay(S_fahrzeit);
if(!digitalRead(Dorn)) {stell=7;break;}
}
if(SW >= 5 ) {
Serial.println("Fehler Servo");
ALCD(1,0,2,1,4);ALCD(0,0,8,1,9);
DornServo.write(Servolage[Mitte]);
delay(S_fahrzeit);
DornServo.detach(); digitalWrite(Enabel,0); Fehler=1;GStatus=0;
}
}
break;
case Geklemmt:
Serial.println("Geklemmt klappt");SW=0;
DornServo.write(Servolage[Geklemmt]);
delay(S_fahrzeit);
val=map(analogRead(BGondel),0,1023,0,255);
if(val < Kontakt) {
for(byte i=0;i<6;i++){
DornServo.write(Servolage[Mitte]);
delay(S_fahrzeit/2);
DornServo.write(Servolage[Geklemmt]);SW++;
delay(S_fahrzeit);
val=map(analogRead(BGondel),0,1023,0,255);
if(val >= Kontakt) {stell=7;break;}
}
if(SW >= 5 ) {
Serial.println("Fehler Servo");
ALCD(1,0,2,1,4);ALCD(0,0,8,1,9);
DornServo.write(Servolage[Mitte]);
delay(S_fahrzeit);
DornServo.detach(); digitalWrite(Enabel,0); Fehler=1;GStatus=0;
}
}
break;
case 4: ALCD(1,0,2,1,4);ALCD(0,0,8,1,9);
Fehler++;
if(!digitalRead(Dorn)) {
Fehler=0;ALCD(1,0,3,0,0);ALCD(0,1,1,1,8);
digitalWrite(Enabel,1);break;
}
GStatus=0;
break;
case 7: break;
}
}
void PRINTStart(){ // Startausgabe Serial Monitor
Serial.println("e H-Brueke EIN / AUS"); Serial.println("");
Serial.println("Wahl Drehrichtung Motor");
Serial.println("r Rechts Gondelfahrt nach Oben");
Serial.println("l Links Gondelfahrt nach Unten");
Serial.println("Space Gondel Stop");Serial.println(" ");
Serial.print("t Auto Stop bei Halt ");Serial.print(Haltepunkt);Serial.println(" am TCRT erreicht ");
Serial.println("g Gondel lesen Ein/Aus");Serial.println(" ");
Serial.println("a Beschleunigungsfahrt ");//Serial.println(" ");
Serial.println("b Bremsen ");Serial.println(" ");
}
void LCDPWM(uint8_t pw){ // LCD Ausgabe PWM
Time4=millis();LCD.backlight();
ALCD(4,1,8,0,5);LCD.setCursor(12, 1); LCD.print(pw); LCD.setCursor(14, 1); LCD.print('%');
}
const byte maxT0 = sizeof("Paternoster"); // anpassen!
const char T0[14][maxT0] PROGMEM = {"Paternoster","Handpanel","Menue","Start","Stop","PWM ","Gondel","Richtung ","OBEN ","UNTEN","Bremsen","Anfahren","Neu","Pos." };
const char * const T0_table[] PROGMEM = {T0[0], T0[1], T0[2], T0[3], T0[4], T0[5], T0[6], T0[7],T0[8], T0[9], T0[10], T0[11], T0[12], T0[13], T0[14]};
const byte maxT1 = sizeof("Initialisierung");
const char T1[11][maxT1] PROGMEM = { "Initialisierung", "Störung", "Zeit", "Dorn", "Servo", "NOT AUS", "POTI Stellung", "Position","Bereit", "Fehler", "Kontakt" };
const char * const T1_table[] PROGMEM = {T1[0], T1[1], T1[2], T1[3], T1[4], T1[5], T1[6], T1[7], T1[8], T1[9], T1[10], T1[11]};
void ALCD(byte loesch, uint8_t zeile, uint8_t spalte, uint8_t Tx, uint8_t text) {
byte maxT = max(maxT, maxT0);
maxT = max(maxT, maxT1); // längster Text
char buf[maxT]; // Der Buffer zum Lesen der Daten muss so lang sein wie der längste Text!
switch (loesch) {
case 1: LCD.clear(); break;
case 2:
LCD.setCursor(0, zeile);
LCD.print(" ");
break;
case 3:
LCD.setCursor(0, zeile);
LCD.print(" ");
break;
case 4:
LCD.setCursor(8, zeile);
LCD.print(" ");
break;
//resume : break;
}
LCD.setCursor(spalte, zeile);
switch (Tx) {
case 0:
strncpy_P(buf, (char*)pgm_read_word(&(T0_table[text])), sizeof(buf));
LCD.print(buf);
break;
case 1:
strncpy_P(buf, (char*)pgm_read_word(&(T1_table[text])), sizeof(buf));
LCD.print(buf);
break;
}
}