Der Code ist noch im Entstehen, nicht lauffähig und noch etwas wirr 'verdrahtet'
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h> // übergibt die Daten für's Display an I2C-Chip
LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD I2C Adresse + Abmessungen
uint32_t lastIRempfang = millis(); //letzte EMpfangszeit
const uint16_t IrTimeout = 500; //TimeOut, Zeit, die Anzahl der empfangenen Zeichen auszugeben
uint16_t const maxPos = 1000; //Pufferlänge ist 1 länger (Zugriff per 0...xxx)
char empfangsPuffer[maxPos + 1]; //Ringspeicher
uint16_t writePos = 0;
uint16_t readPos = 0;
byte const IRpin = 8;
const byte startSequenz[] = { 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01 }; //start sequence of SML protocol
const byte stopSequenz[] = { 0x1B, 0x1B, 0x1B, 0x1B, 0x1A }; //end sequence of SML protocol
const byte powerSequenz[] = { 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00, 0x55 }; //Sequenz folgt "Wirkleistung" (4 Bytes)
const byte verbrauchSequenz[] = { 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x00, 0x01, 0x82, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59 }; //Sequenz folgt "Gesamtverbrauch" (8 Bytes)
typedef struct {
byte laenge; //Länge der zu suchenden Sequenz
uint16_t pointer; //dort ist der Anfang der Sequenz
byte bereitsgefunden; //aktuell zu Testendes Byte aus der Sequenz
byte folgebytes; //wenn wir die Sequenz gefunden haben, noch x Byte einlesen
} sequenzen;
const sequenzen sequenz[] = {
{sizeof(startSequenz), startSequenz, 0, 0},
{sizeof(stopSequenz), stopSequenz, 0, 0},
{sizeof(powerSequenz), powerSequenz, 0, 4},
{sizeof(verbrauchSequenz), verbrauchSequenz, 0, 8},
};
enum prgstatus {Einlesen, Stop};
enum irstatus {suchestart, suchestop, suchepower};
SoftwareSerial mySerial(IRpin, LED_BUILTIN); // RX, TX (muß angegeben werden, die Bord-LED ist dafür ganz ok)
void setup() {
//Der Photo-Transistor der CNY70 ist an IRpin angeschlossen, wo SoftSerial auf Saten wartet
mySerial.begin(9600);
lcd.begin(20, 04); //(Zeichen,Zeilen);
//lcd.backlight(); lcd.nobacklight(); lcd.clear();
// NOTE: Cursor Position: (X,Y) start at 0
lcd.setCursor(4, 0);
lcd.print("Hello, world!");
lcd.setCursor(0, 1); //Start at character 4 on line 0
pinMode(LED_BUILTIN, OUTPUT); //auch als TX für SoftSerial benutzt - am 'Lesekopf' unbenutzt
}
void loop() {
byte status = Einlesen;
uint16_t anzahl = 0;
switch (status) {
case Einlesen: {
if (mySerial.available()) {
anzahl++;
digitalWrite(LED_BUILTIN, HIGH); //Daten vorhanden
lastIRempfang = millis(); //Zeitpunkt merken
empfangsPuffer[writePos] = mySerial.read(); //in Puffer schreiben
writePosPlus();
}
break;
}
case Stop: {
break;
}
default:
break;
}
if (millis() - lastIRempfang > IrTimeout) {
//xx ms keine neuen Daten - wir sind wohl am Ende angekommen
digitalWrite(LED_BUILTIN, LOW);
//Ausgabe der Anzahl der empfangenen Bytes auf's Display
anzahl = 0;
}
//Hier bei jedem Durchlauf jede Sequenz auf das nächste Byte prüfen, sofern ein neues Byte empfangen wurde
if (readPos != writePos) {
//Es sind auszuwertende Bytes vorhanden
byte readbyte = empfangsPuffer[readPos]; //nächstes Byte aus dem Puffer einlesen
readPosPlus();
for (byte i = 0; i < sizeof(sequenz) / sizeof(sequenz[0]); i++) { //mit jeder Sequenz prüfen, ob diese Byte als Nächstes dort gefunden wurde
if (sequenzbyte(sequenz[i].pointer+sequenz[i].bereitsgefunden)==readbyte){
//Byte in der Sequenz entspricht dem gelesenem Byte
}
}
}
}
//####################
//erhöht die Lese-Position im Ringspeicher
void readPosPlus() {
readPos++; //Lesezeiger verschieben
if (readPos > maxPos) { //ist der Lesezeiger am Ende angekommen?
readPos = 0; //dann Den wieder auf Anfang setzen
}
}
//####################
//erhöht die Schreib-Position im Ringspeicher
//Der Lese-Zeiger wird 'vorher geschoben'
void writePosPlus() {
writePos++; //Schreib-Porision erhöhen
if (writePos > maxPos) { //am Ende angekommen?
writePos = 0; //auf Anfang setzen
}
if (writePos == readPos) { //Schreibzeiger auf Lese-Zeiger aufgelaufen?
readPosPlus();
}
}
//####################
// soll das Byte aus dem Speicher auslesen, berechnet wird die Position zuvor durch Start-Array + Zeichennummer
byte sequenzbyte(uint16_t pointer){
return &pointer;
}