/********************************************************************************
    Getränke Dosiermaschine mit vier Pumpen
 ********************************************************************************/
#include <Adafruit_NeoPixel.h> // RGB LEDs
#include <HX711_ADC.h> // Bibliothek Wägebalken
#include <IRremote.h> // Bibliothek Infrarot
#include <SPI.h>             // SPI für die Kommunikation
#include <Adafruit_GFX.h>    // Adafruit Grafik-Bibliothek wird benötigt
#include <Adafruit_ST7735.h> // Adafruit ST7735-Bibliothek wird benötigt
#include <SD.h> // SD-Leser
#include <Keypad.h> // 4x4 Matrix Tastatur

String Version = "2.0";

//********************************************************************************
// TFT Display ST7735:
/* Pinnung neue Version Statt D7..D10 jetze D46 .. D49
    Display (Pin) - Arduino Nano
    VCC  (1) - 5V   
    GND  (2) - GND  
    CS   (3) - D10 (D49)
    RES  (4) - D8  (D47)
    RS/A0(5) - D9 (D48)
    SDA  (6) - D51
    SCK  (7) - D52
    LEDA (8) - 3.3V  

    SD Kartenleser Pinning
    (Pin) - Arduino Nano/Uno in Klammern MEGA2560
    SCK   - D52
    MISO  - D50
    MOSI  - D51
    CS    - D7  (D46)

*/
#define TFT_PIN_CS   10 // Arduino-Pin an Display CS   
#define TFT_PIN_DC   9  // Arduino-Pin an Display A0/RS
#define TFT_PIN_RST  8  // Arduino Reset-Pin

#define SD_PIN_CS   7   // SD-Leser CS Pin


Adafruit_ST7735 tft = Adafruit_ST7735(TFT_PIN_CS, TFT_PIN_DC, TFT_PIN_RST);  // ST7735-Bibliothek Setup

//********************************************************************************
// Korrektur der Farbfehler im Include File ST7735.h im 565 (16 Bit) System
#define C_RED 0x001F      //ST7735_BLUE
#define C_BLUE 0xF800     //ST7735_RED
#define C_GREEN 0x07E0    //ST7735_GREEN
#define C_CYAN 0xFFE0     //ST7735_YELLOW
#define C_ORANGE 0x04bf   //ST7735_ORANGE
#define C_MAGENTA 0xF81F  //ST7735_MAGENTA
#define C_YELLOW 0x07FF   //ST7735_CYAN
#define C_WHITE 0xFFFF    //ST7735_WHITE
#define C_BLACK 0x0000    //ST7735_BLACK

// Positonen der Texte
#define PosSoll 75
#define PosIn   90
#define PosTara 110
#define PosGewicht 40
#define PosPumpe 140

//********************************************************************************
// Wägebalken
HX711_ADC Gewicht(4, 5);
#define StabTime 1000

//********************************************************************************
// Infrarot Empfänger
int RECV_PIN = 2; // Digitalpin für Infrarot
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned int IR_ein = 0;

//********************************************************************************
// SD Card
File myFile;
String textin;
char produkt[40];
String code;
unsigned int menge[5];
String SollFile = "SOLLWERT.TXT"; // Datei für Sollgewicht bei Neustart
String CodeFile = "Drinks.csv"; //Code Datenbank

//********************************************************************************
// Globale Variable
long t;
int a = 1;
float calValue = 744.78; //Kalibrierfaktor
float nachLauf = 3.4;
float lastGewicht = -99.0;
unsigned int AnzPump = 4;
unsigned int  sollGewicht[5] = {0, 100, 110, 120, 130}; // Voreinstellung sollGewicht (abschalten)
int rwert = -1; // Rückgabe wert aus IR leseroutine
bool pOFF = HIGH;
bool pON = LOW;

//********************************************************************************
/*
// Funktions RGB-LEDs auf Analogport 1 und 2
#define aLOW 0
#define aHIGH 1023
// ColorLED ans Analog Ausgängen
#define LEDrot A3
#define LEDgruen A4
#define LEDblau A5
*/
// Seriall LED
// LEDs
// SETUP YOUR OUTPUT PIN AND NUMBER OF PIXELS
#define PIN 3
#define NUM_PIXELS  1
#define vel 100 // Velocity in milliseconds
#define aLOW 0
#define aHIGH 255
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_RGB + NEO_KHZ400);


//********************************************************************************
// PumpenPin ist D11 für Pumpe 1, und D12 für Pumpe2
int PumpPin[5] = {0, 22, 24, 26, 28};
int PumpeAkt = 0; // aktuell aktive Pumpe 0=keine, 1 ... 4 Pumpe 1...4

//********************************************************************************
// definition 4x4 KeyPAD
const byte SPALTEN = 4;
const byte ZEILEN = 4;
char TASTEN[ZEILEN][SPALTEN] = {
  {'D', '#', '0', '*'},
  {'C', '9', '8', '7'},
  {'B', '6', '5', '4'},
  {'A', '3', '2', '1'}
};
byte SpaltenPIN[SPALTEN] = {30, 32, 34, 36};
byte ZeilenPIN[ZEILEN] = { 38, 40, 42, 44 };
Keypad myKeypad = Keypad(makeKeymap(TASTEN), ZeilenPIN, SpaltenPIN, ZEILEN, SPALTEN);

//********************************************************************************
void setup() {
  int cnt;

  Serial.begin(9600);
  Serial3.begin(9600);
  Serial.print("Drink Mixer ");
  Serial.println(Version);
  Serial.println("hiz 12/2020\n");

  //---------------------------------------------------------------------
  //Pumpen ausschalten
  for (cnt == 1; cnt <= AnzPump; cnt++) {
    pinMode(PumpPin[cnt], OUTPUT);
    digitalWrite(PumpPin[cnt], pOFF);
  }

  //---------------------------------------------------------------------
  // Color LED auf Weiss 50%
/*
  pinMode (LEDrot, OUTPUT);
  pinMode (LEDgruen, OUTPUT);
  pinMode (LEDblau, OUTPUT);
  ColorLED(aHIGH, aHIGH, aHIGH);
*/
strip.begin();
ColorLED(128, 128, 128);

  //---------------------------------------------------------------------
  /***
    ST7735-Chip initialisieren (INITR_BLACKTAB / INITR_REDTAB / INITR_GREENTAB)
    Muss bei AZ-Delivery 1.77'' 160x128px RGB TFT INITR_GREENTAB sein ansonsten Pixelfehler rechts und unten.
    Hinweis: https://github.com/adafruit/Adafruit-ST7735-Library/blob/master/examples/soft_spitftbitmap/soft_spitftbitmap.ino#L52
    Zeile 52-65
  ***/
  tft.initR(INITR_GREENTAB);
 tft.setRotation(4);
  // fillScreen(farbe);
  tft.fillScreen(C_BLACK);
  // setTextSize(groesse);
  tft.setTextSize(2);
  // setCursor(links,oben);
  tft.setCursor(0, 10);
  // setTextColor(farbe);
  tft.setTextColor(C_WHITE);
  // print(text);
  tft.print("DrinkMixer\nVers.");
  tft.println(Version);
  tft.println("\n----------\n");
  PumpeAkt = 0;

  //---------------------------------------------------------------------
  // Open SD-Karte
  if (!SD.begin(SD_PIN_CS)) {
    Serial.println("SD-Card Fehler!");
    tft.fillRect(0, 80, 127, 100, C_BLACK);
    tft.setCursor(10, 80);
    tft.setTextSize(2);
    tft.println("SD Fehler");
    delay(1000);
  }
  else if (!SD.exists(CodeFile)) {
    Serial.println("SD-Card File fehlt!");
    tft.fillRect(0, 80, 127, 100, C_BLACK);
    tft.setCursor(10, 80);
    tft.setTextSize(2);
    tft.println("File fehlt");
  }


  else {
    Serial.println("SD-Card erfolgreich.");
    tft.println("SD ok");

    // Einlesen Sollwert
    if (SD.exists(SollFile)) {
      myFile = SD.open(SollFile);
      for (cnt = 1; cnt <= AnzPump; cnt++) {
        textin = myFile.readStringUntil('\n');
        sollGewicht[cnt] = textin.toInt();
        Serial.println (sollGewicht[cnt]);
      }
      myFile.close();
    }
  }
  //---------------------------------------------------------------------
  // Initialisieren Infrarot
  irrecv.enableIRIn();

  // Initialisieren Wägebalken
  Gewicht.begin();
  Gewicht.start(StabTime);

  //---------------------------------------------------------------------
  // Wägebalken
  if (Gewicht.getTareTimeoutFlag()) {
    Serial.println("DMS Fehler");
    tft.println("DMS Fehler");
  }
  else {
    Gewicht.setCalFactor(calValue);
    Serial.println("DMS ok");
    tft.println("DMS ok");
  }
  delay(1000);
  // Screen vorbereiten
  // fillScreen(farbe);
  tft.fillScreen(C_BLACK);

  //---------------------------------------------------------------------
  // Tara setzen
  SetTara();

  // setTextSize(groesse);
  tft.setTextSize(1);
  tft.setTextColor(C_WHITE);

  tft.setCursor(10, 10);
  tft.print("Gewicht:");
  tftSollGewicht();

  Pumpen(pOFF);
  delay(1000);
  Pumpen(pOFF);
}

//********************************************************************************
// --------------------------------------------------------------------
// ------------------- Loop ------------------------------------------
// --------------------------------------------------------------------
void loop() {
  String sollcode;
  float aktGewicht;
  float sGewicht;
  int cnt;

  // Eingabe von Zeichen?
  Get_Taste();

  //---------------------------------------------------------------------
  // Auswerten Rückgabecode
  switch (rwert) {
    //---------------------------------------------------------------------
    // pumpen Starten
    case 126:
      if (PumpeAkt == 0) {
        do {
          PumpeAkt++;

        } while ((sollGewicht[PumpeAkt] == 0) && (PumpeAkt <= AnzPump));
        if (PumpeAkt <= AnzPump) {
          Pumpe (PumpeAkt, pON);
        }
      }
      break;
    //---------------------------------------------------------------------
    // Pumpe Stoppen
    case 125:
      PumpeAkt = 0;
      Pumpen(pOFF);
      break;
    //---------------------------------------------------------------------
    // Tara setzen
    case 124:
      // Tara
      SetTara();
      break;
    //---------------------------------------------------------------------
    // Start Eingabe
    case 127:
      sollEin();
      break;
    //---------------------------------------------------------------------
    // Eingabe Code und Einlesen SD-Karte
    case 121:
      //Serial.println("Code Eingabe");
      // get Code
      sollcode = getCode();
      FindeCode(sollcode);
      break;
    //---------------------------------------------------------------------
    // Setzen Sollcode
    case 123:
      GetSoll();
      break;
    //---------------------------------------------------------------------
    // einlesen Barcode und finden auf SD
    case 122:
      sollcode = getBarCode();
      Serial.println(sollcode);
      FindeCode(sollcode);
      break;
    //---------------------------------------------------------------------
    default:
      Gewicht.update();
      aktGewicht = Gewicht.getData();
      aktGewicht = roundf(aktGewicht * 10) / 10.0; // Runden auf eine Stelle nach Komma
      if (PumpeAkt > 0) {
        sGewicht = 0;
        for (cnt = 1; cnt <= PumpeAkt; cnt++) {
          sGewicht = sGewicht + sollGewicht[cnt];
        }
        if ((aktGewicht >= (sGewicht - nachLauf)) ) {
          if (PumpeAkt < AnzPump) {
            Pumpe(PumpeAkt, pOFF);
            PumpeAkt++;
            Pumpe(PumpeAkt, pON);
          } else {
            Pumpen(pOFF);
          }
        }
      }
      //---------------------------------------------------------------------
      // Ausgabe aktuelles Gewicht
      if (aktGewicht != lastGewicht) {
        tftGewicht(C_BLACK, lastGewicht);
        tftGewicht(C_WHITE, aktGewicht);
        lastGewicht = aktGewicht;
      }
  }
}

//********************************************************************************
// finde Code auf SDKarte
void FindeCode(String suchCode) {
  int cnt;
  // code vorhanden?
  // open File
  myFile = SD.open(CodeFile);
  // Einlesen bis code gefunden oder EOF
  while ((myFile.available()) && (code != suchCode)) {
    textin = myFile.readStringUntil('\n');
    Zerlegen(textin);
  }
  // Close File
  myFile.close();

  // Richtiger Code - Menge setzen
  if (code == suchCode) {
    for (cnt = 1; cnt <= AnzPump; cnt++) {
      sollGewicht[cnt] = menge[cnt];
    }
  }
  tftSollGewicht();
  tft.setCursor(0, PosSoll + 35);

  // Richtiger Code - dann produkt
  if (code == suchCode) {
    tft.print(" ");
    tft.print(produkt);
  } else {
    tft.setTextColor(C_RED);
    tft.print(" Nichts gefunden");
  }
  Pumpen(pOFF);
}

//********************************************************************************
// TFT ausgabe Sollgewicht
void tftSollGewicht() {
  int cnt;
  tft.setTextSize(1);
  tft.fillRect(0, PosSoll, 127, 100, C_BLACK);
  tft.setCursor(0, PosSoll);
  tft.setTextColor(C_WHITE);
  for (cnt = 1; cnt <= AnzPump; cnt++) {
    tft.print(" Sollwert " + (String)cnt + ": ");
    tft.println ((long)(sollGewicht[cnt] + .5));
  }
}

//********************************************************************************
// TFT Ausgabe Gewicht
void tftGewicht( int color, float inGewicht) {

  tft.setTextSize(2);
  tft.setTextColor(color);
  tft.setCursor(10, PosGewicht);
  tft.print(inGewicht);
  //  tft.print((long)inGewicht);
}

//********************************************************************************
// Tara auf 0 setzen
void SetTara () {
  ColorLED(aLOW, aLOW, aHIGH);
  tft.setTextSize(2);
  tft.setTextColor(C_WHITE);
  tft.setCursor(10, PosTara);
  tft.print("Tara");
  Gewicht.update();
  Gewicht.tare();
  delay(100);
  tft.setTextColor(C_BLACK);
  tft.setCursor(10, PosTara);
  tft.print("Tara");
  ColorLED(aHIGH, aLOW, aLOW);
}

//********************************************************************************
// Einlesen Barcode
String getBarCode() {
  String BarCode;
  int EinWert;

  BarCode = "";

  ColorLED(aLOW, aLOW, aHIGH);
  tft.setTextSize(1);
  tft.fillRect(0, PosSoll, 127, 100, C_BLACK);
  tft.setCursor(10, PosSoll);
  tft.setTextColor(C_WHITE);
  tft.print("Einlesen Barcode:");
  // Buffer leeren
  while (Serial3.available() > 0) {
    EinWert = Serial3.read();
  }
  //warten auf erstes Zeichen oder CR gedrückt
  do {
    Get_Taste();
  }
  while ((Serial3.available() == 0) && (rwert != 120) && (rwert != 122));

  if ((rwert != 120) && (rwert != 122)) {
    // Einlesen barcode
    while (Serial3.available() > 0) {
      // read the incoming byte:

      EinWert = Serial3.read();
      // nur wenn größer >= Space hinzufügen (Löschen Sonderzeichen)
      if (EinWert >= 32) {
        BarCode = String(BarCode + char(EinWert));
      }
      delay(10);
    }
    tft.print(BarCode);
    return (BarCode);
  }
}


//********************************************************************************
// Aktueller Wert als Sollwert setzen
void GetSoll() {
  int altsoll;
  int cnt;
  // altes gewicht merken
  Pumpen(pOFF);
  ColorLED(aLOW, aLOW, aHIGH);
  tft.setTextSize(1);
  tft.fillRect(0, PosSoll, 127, 100, C_BLACK);
  tft.setCursor(10, PosSoll);
  tft.setTextColor(C_YELLOW);
  tft.print("Setzen Soll NR:");
  // Nummersetzen
  do {
    Get_Taste();
  } while (rwert == -1);
  if ((rwert > 0) && (rwert <= AnzPump)) {
    cnt = rwert;
    tft.print(cnt);

    altsoll = sollGewicht[cnt];
    tft.setTextSize(2);
    Gewicht.update();
    sollGewicht[cnt] = Gewicht.getData();
    tft.setCursor(10, PosIn);
    tft.print(sollGewicht[cnt]);

    // ok? taste nochmal drücken -  sonst vergessen
    tft.print(" - OK?");
    do {
      Get_Taste();
    } while (rwert == -1);
    if ((rwert != 123) && (rwert != 120)) {
      sollGewicht[cnt] = altsoll;
    }
  }
  tft.setTextSize(1);
  tft.fillRect(0, PosSoll, 127, 100, C_BLACK);
  tft.setCursor(0, PosSoll);
  tft.setTextColor(C_WHITE);
  for (cnt = 1; cnt <= AnzPump; cnt++) {
    tft.print(" Sollwert " + (String)cnt + ": ");
    tft.println(sollGewicht[cnt]);
  }
  // falls richtige Taste gedückt
  if ((rwert == 123) || (rwert == 120)) {
    // in Datei Schreiben, Dtei löschen falls schon existiert
    if (SD.exists(SollFile)) {
      SD.remove(SollFile);
    }
    myFile = SD.open(SollFile, FILE_WRITE);
    if (myFile) {
      for (cnt = 1; cnt <= AnzPump; cnt++)
        myFile.println(sollGewicht[cnt]);
    }

    myFile.close();
  }
  delay(1000);
  Pumpen(pOFF);
}

//********************************************************************************
// Eingabe Sollwert
unsigned int sollEin() {
  IR_ein = 0;
  int cnt;
  Pumpen(pOFF);
  ColorLED(aLOW, aLOW, aHIGH);

  for (cnt = 1; cnt <= AnzPump; cnt++) {
    tft.setTextSize(1);
    tft.fillRect(0, PosSoll, 127, 100, C_BLACK);
    tft.setCursor(10, PosSoll);
    tft.setTextColor(C_WHITE);
    tft.print("Eingabe Soll ");
    tft.print(cnt);
    tft.print(":");
    tft.setTextSize(2);
    //eingabe bis CR bzw 127
    do {
      Get_Taste();
      if (rwert != -1) {
        //Serial.println(rwert);
        if ((rwert >= 0) && (rwert <= 9)) {
          IR_ein = IR_ein * 10 + rwert;
          tft.setCursor(10, PosIn);
          tft.print(IR_ein);
        }
      }
    }
    while ((rwert != 127) && (rwert != 120));
    sollGewicht[cnt] = IR_ein;
    IR_ein = 0;
  }
  tft.setTextSize(1);
  tft.fillRect(0, PosSoll, 127, 100, C_BLACK);
  tft.setCursor(0, PosSoll);
  tft.setTextColor(C_WHITE);
  for (cnt = 1; cnt <= AnzPump ; cnt++) {
    tft.print(" Sollwert " + (String)cnt + ": ");
    tft.println(sollGewicht[cnt]);
  }
  Pumpen(pOFF);
}

// Abfragen ob Taste gedrückt. wenn Nicht rwert=-1
void Get_Taste() {
  rwert = -1;

  // zuerst Matrix-Keypad
  Get_Keypad();
  if (rwert == -1) {
    // alternativ IR
    Get_IR();
  }
}

//********************************************************************************
// --------------------------------------------------------------------
// IR Einlesen
// 0-128 Zeichen
// -1 leer
// Tastendefinition
// IR-Belegung Neu
#define IR_0        0xFF4AB5
#define IR_1        0xFF6897
#define IR_2        0xFF9867
#define IR_3        0xFFB04F
#define IR_4        0xFF30CF
#define IR_5        0xFF18E7
#define IR_6        0xFF7A85
#define IR_7        0xFF10EF
#define IR_8        0xFF38C7
#define IR_9        0xFF5AA5
#define IR_BarCode  0xFFA857
#define IR_SollSet  0xFFE01F
#define IR_Ein      0xFF52AD
#define IR_Aus      0xFF42BD
#define IR_SollEin  0xFF22DD
#define IR_Tara     0xFF906F
#define IR_CodeIn   0xFF02FD
#define IR_CR       0xFFC23D
// --------------------------------------------------------------------

// Codeumsetzung der IR Fernbedienung
/* alte Belegung
  unsigned long IR_Code[] = {IR_0, IR_1, IR_2, IR_3, IR_4 , IR_5, IR_6, IR_7, IR_8, IR_9,
                           IR_PLUS, IR_MINUS, IR_EQ, IR_PREV, IR_NEXT, IR_PLAY
                          };
*/
// Neue Belegung
unsigned long IR_Code[] = {IR_0, IR_1, IR_2, IR_3, IR_4 , IR_5, IR_6, IR_7, IR_8, IR_9,
                           IR_CR, IR_CodeIn, IR_BarCode, IR_SollSet, IR_Tara, IR_Aus, IR_Ein, IR_SollEin
                          };
int IR_Wert[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 120, 121, 122, 123, 124, 125, 126, 127};

void Get_IR() {
  unsigned long inwert;
  int cnt;
  int IR_anz = sizeof(IR_Code);

  rwert = -1;
  // Eingabe von Zeichen?
  if (irrecv.decode(&results)) {
    irrecv.resume();
    delay(100);
    inwert = results.value;
    if (inwert != 0xffffffff) {
      for (cnt = 0; cnt < IR_anz; cnt++) {
        if (inwert == IR_Code[cnt]) {
          rwert = IR_Wert[cnt];
        }
      }
    }
  }
}

//********************************************************************************
// Eingabe Matrix Tastatur
char MatrixCode[] = "0123456789ABCD*#";
int MatrixWert[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 122, 123, 126, 125, 124, 127};

void Get_Keypad() {
  char iwert;
  int cnt;
  int Matrix_anz = sizeof(MatrixCode);
  rwert = -1;
  iwert =  myKeypad.getKey();
  if (iwert) {
    for (cnt = 0; cnt < Matrix_anz; cnt++) {
      if (iwert == MatrixCode[cnt]) {
        rwert = MatrixWert[cnt];
      }
    }
  }
}

void Pumpen (bool stat) {
  int cnt;
  for (cnt = 1; cnt <= AnzPump; cnt++ ) {
    Pumpe (cnt, stat);
  }
  PumpeAkt = 0;
}

//********************************************************************************
void Pumpe (int nr, bool stat) {
  int xpos = (128 / AnzPump) * (nr - 1);
  tft.setTextColor(C_WHITE);
  tft.setTextSize(2);
  tft.setCursor(xpos, PosPumpe);

  if (stat == pON) {
    if (digitalRead(PumpPin[nr]) == pOFF) {
      digitalWrite(PumpPin[nr], pON);
      ColorLED(aLOW, aHIGH, aLOW);
      tft.fillRect(xpos, 130, (128 / AnzPump), 30, C_GREEN);
      tft.print(nr);
      tft.print("+");
    }
  } else {
    ColorLED(aHIGH, aLOW, aLOW);
    digitalWrite(PumpPin[nr], pOFF);
    tft.fillRect(xpos, 130, (128 / AnzPump), 30, C_RED);
    tft.print(nr);
    tft.print("-");
  }

}


//********************************************************************************
/*
   Zerlegen des ingelesenen Strings
*/
void Zerlegen(String txt) {
  String hstring;
  int von;
  int bis;
  int cnt;
  von = 0;

  // Emitteln Code
  bis = txt.indexOf(';');
  code = txt.substring(von, bis);
  //code = hstring.toInt();
  for (cnt = 1; cnt <= AnzPump; cnt++) {
    //Menge1 ermitteln
    von = bis + 1;
    bis = txt.indexOf(';', von);
    hstring = txt.substring(von, bis);
    menge[cnt] = hstring.toInt();
  }
  // Produkt ermitteln
  von = bis + 1;
  hstring = txt.substring(von);
  hstring.toCharArray(produkt, hstring.length());

}

//********************************************************************************
/*
    Schalten der Color LED übergben werden rot, grün blau
*/
void ColorLED(int arot, int agruen, int ablau) {
/*  analogWrite (LEDrot, aHIGH - arot);
  analogWrite (LEDgruen, aHIGH - agruen);
  analogWrite(LEDblau, aHIGH - ablau);
*/
strip.setPixelColor(0,strip.Color(arot,agruen,ablau));
strip.show();
}

//********************************************************************************
// Eingabe Code
String getCode() {
  //  unsigned int IR_wert = 0;
  String IR_String = "";
  //IR_ein=0;
  ColorLED(aLOW, aLOW, aHIGH);
  tft.setTextSize(1);
  tft.fillRect(0, PosSoll, 127, 100, C_BLACK);
  tft.setCursor(10, PosSoll);
  tft.setTextColor(C_WHITE);
  tft.print("Eingabe Code:");
  tft.setTextSize(2);
  //eingabe bis CR bzw 127
  do {
    Get_Taste();
    if (rwert != -1) {
      //Serial.println(rwert);
      if ((rwert >= 0) && (rwert <= 9)) {
        IR_String = IR_String + rwert;
        //IR_ein = IR_ein * 10 + rwert;
        tft.setCursor(10, PosIn);
        tft.print(IR_String);
      }
    }
  }
  while ((rwert != 127) && (rwert != 120));

  //return IR_ein;
  return IR_String;
}
