INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Brennersteuerung
12.12.2013, 05:05
Beitrag #25
RE: Brennersteuerung
Hallo,

habe lernen müssen, das das was in der Simulation von Virtronics v0.99 funktioniert, noch lange nicht in der Arduino-IDE funzt, und umgekehrt.
Daher ist Virtronics leider etwas Zeit-, und Geldverschwendung, oder?
War aber ein netter Einstieg.

Hier der zum Teil laufende Code des Programms.
Dort gibt es auch eine Lösung für das obige Stringproblem.

Code:
//Simulate Mega
#include <LiquidCrystal.h>
#include <Servo.h>
#include <PString.h>

Servo myServo;
int servoPinLuft = 7;   // Servo mit freiem Digital-Pin verbunden
int myAngle=90;     // Drehwinkel des Servos ca 0-180 Grad
int servoStep=5;    //
int center=90;      // 0 Grad
int pulseWidth;     // Variable der servoPulse-Funktion;

int DelayMS=1000;
int analogpin = A0;


LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int backLight = 12;

int inp=3;
double a_input=1.1;
char buf[20];
int menu=0;
String versio="Regomat V0.2";
double LbdCen=1.54;
double LbdSpr=0.05;
int kw=5;
int T1=0,T2=0,T3=0,T4=0,T5=0,T6=0;
byte R1=LOW, R2=LOW;

void servoPulse(int servoPin, int myAngle) {
  pulseWidth = (myAngle * 10) + 600; // bestimmt die Verzögerung
  digitalWrite(servoPin, HIGH);      // setzt den Ausgang auf HIGH
  delayMicroseconds(pulseWidth);     // Mikrosekunden Pause
  digitalWrite(servoPin, LOW);       // setzt den Ausgang auf LOW
}

void PRINT(int x, int y, String str) {
  if(x!=99 && y!=99)
    lcd.setCursor(x,y);
  if(y==99)
    lcd.print(str+"\n");
  else
    lcd.print(str);
  Serial.println(str);
}

void readData() {
  inp=analogRead(analogpin);
  if(a_input>LbdCen+LbdSpr/2 && myAngle>0)
    myAngle=center-servoStep;
  else if(a_input<LbdCen-LbdSpr/2 && myAngle<180)
    myAngle=center+servoStep;
  else
    myAngle=center;
  a_input=5.0/1023.0;
  a_input=a_input*(double)inp;
}

void printLCD() {
  String s="i="+String(inp)+" ";
  ;
  s=s+"Lbd="+str(a_input,3)+" ";
  s=s+"o="+str(myAngle,0)+"\n";
  PRINT(0,3,s);
}

void setServoLuft() {
  servoPulse(servoPinLuft, myAngle);
  delay(DelayMS);
}

void setRelaisPelletsLOW() {
  digitalWrite(20,LOW);
}
void setRelaisPelletsHIGH() {
  digitalWrite(20,HIGH);
}
void setRelaisAscheLOW() {
  digitalWrite(21,LOW);
}
void setRelaisAscheHIGH() {
  digitalWrite(21,HIGH);
}
String str(double d, int nk) {
  PString(buf, sizeof(buf),d,nk);
  return(buf);
}
void readTasten() {
  T1=digitalRead(14);//ESC, Einstellung beenden
  T2=digitalRead(15);//Links, Ebene zurück
  T3=digitalRead(16);//Rechts, Ebene vor
  T4=digitalRead(17);//Oben, nach oben
  T5=digitalRead(18);//Unten, nach unten
  T6=digitalRead(19);//Reset
  if(T1+T2+T3+T4+T5+T6 != 0) {
    if(T1==1) { //ESC
    }
    if(T2==1) { //Links
      if(menu==200) menu=100;
      if(menu==210) menu=200;
      if(menu==211) menu=210;
      //usw...
    }
  }
  delay(DelayMS);
}

void printFree(int zeile) {
  lcd.setCursor(0,zeile);
  lcd.print("                    ");
}
void printFree3() {
  printFree(3);
}
void printFree2() {
  printFree(2);
  printFree(3);
}
void printFree1() {
  printFree(1);
  printFree(2);
  printFree(3);
}
void printFree0() {
  printFree(0);
  printFree(1);
  printFree(2);
  printFree(3);
}
void printLCDmenu000() {
  printFree0();
  PRINT(0,0,versio+" M000");
  PRINT(0,1,"Initialisierung");
  PRINT(0,2,"Bitte warten");
  PRINT(0,3,"Finish");
}

void printLCDmenu100() {
  printFree0();
  PRINT(0,0,versio+" M100");
  PRINT(0,1,"Betriebsart");
}

void printLCDmenu110() {
  printFree0();
  PRINT(0,0,versio+" M110");
  PRINT(0,1,"Automatik200");
  PRINT(0,2,"Manuell300");
  PRINT(0,3,"Einstellung400");
}

void printLCDmenu111() {
}
void printLCDmenu112() {
  printFree0();
  PRINT(0,0,versio+" M111");
  PRINT(0,1,"Automatik");
  PRINT(0,2,"Einstellung kw");
  PRINT(0,3,"Eingabe kw : ___");
}
void printLCDmenu113() {
}
void printLCDmenu120() {
  printFree0();
  PRINT(0,0,versio+" M120");
  PRINT(0,1,"Betriebsart Manuell");
}
void printLCDmenu200() {
  printFree0();
  PRINT(0,0,versio+" M200 Automatik");
  PRINT(0,1,"Einstell. kw("+String(kw)+") -->M210");
  PRINT(0,2,"Einstell. LC("+str(LbdCen,2)+") -->M220");
  PRINT(0,3,"Einstell. LS("+str(LbdSpr,2)+") -->M230");
}
void printLCDmenu210() {//Einstellung Lambda Center
  printFree0();
  PRINT(0,0,versio+" M210 Automatik");
  PRINT(0,1,"Einstell. Lbd Center");
  PRINT(0,2,"Alter Wert : "+printf("%i",LbdCen));
  PRINT(0,3,"Neuer Wert : _");
}
void printLCDmenu220() {
  printFree0();
  PRINT(0,0,versio+" M220 Automatik");
  PRINT(0,1,"Einstell. Lbd.Spreizung");
  PRINT(0,2,"Alter Wert : "+printf("%i",LbdSpr));
  PRINT(0,3,"Neuer Wert : _");
}
void printLCDmenu230() {
  printFree0();
  PRINT(0,0,versio+" M230 Automatik");
  PRINT(0,1,"Einstell. Kessel kw");
  PRINT(0,2,"Alter Wert : "+kw);
  PRINT(0,3,"Neuer Wert : _");
}
void printLCDmenu300() {
  printFree0();
  PRINT(0,0,versio+" M300 Manuell");
  PRINT(0,1,"Pellets Ein 0/1");
  PRINT(0,2,"Zuluft +/-");
  PRINT(0,3,"Aschetransport 0/1");
}
void printLCDmenu400() {
  printFree0();
  PRINT(0,0,versio+" M400 Nur Einst.");
  PRINT(0,1,"Pellets Ein 0/1");
  PRINT(0,2,"Zuluft +/-");
  PRINT(0,3,"Aschetransport 0/1");
}

void EinstellLbdCen() {
}
void EinstellLbdSpr() {
}
void initTimer() {
}

void setup() {
  initTimer();
  Serial.begin(9600);
  pinMode(14,INPUT);
  pinMode(15,INPUT);
  pinMode(16,INPUT);
  pinMode(17,INPUT);
  pinMode(18,INPUT);
  pinMode(19,INPUT);
  pinMode(20,OUTPUT);
  pinMode(21,OUTPUT);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH);
  lcd.begin(20,4);                    // 4 zeilen a 20 Zeichen
  lcd.clear();
  if(menu==0) printLCDmenu000();
  myServo.attach(servoPinLuft);
  myAngle=center;
  setServoLuft();
  if(1==2) setRelaisPelletsHIGH();
  else setRelaisPelletsLOW();
  if(2==3) setRelaisAscheHIGH();
  else setRelaisAscheLOW();
}  

void loop() {
  if(menu==  0) menu=200;
  if(menu==000) printLCDmenu000(); //Initiale Ausgabe
  if(menu==100) printLCDmenu100(); //Betriebsart
  if(menu==110) printLCDmenu110(); // Betrieb,Automatik
  if(menu==111) printLCDmenu111(); //  Betrieb,Automatik,kw
  if(menu==112) printLCDmenu112(); //  Betrieb,Automatik,LCenter
  if(menu==113) printLCDmenu113(); //  Betrieb,Automatik,LSpreiz
  if(menu==120) printLCDmenu120(); // Betrieb,Manuell
  if(menu==200) printLCDmenu200(); //Einstellung
  if(menu==210) printLCDmenu210(); // Einstellung,LambdaCenter
  if(menu==211) EinstellLbdCen();  //Justierung,LambdaCenter
  if(menu==220) printLCDmenu220(); // Einstellung,LambdaSpreizung
  if(menu==221) EinstellLbdSpr();  //Justierung,LambdaSpreizung
  if(menu==230) printLCDmenu230(); // Einstellung,kw
  if(menu==300) printLCDmenu300(); // Manueller Betrieb
  if(menu==400) printLCDmenu400(); // Nur Einstellungen
  readData();
  printLCD();
  setServoLuft();
  setRelaisPelletsLOW();
  setRelaisAscheLOW();
  readTasten();
}

Ist natürlich noch nicht alles ausprogrammiert, aber es geht doch Stück für Stück etwas weiter.
Heute werde ich mich darum kümmern, ob der Servo auch das tut, was er soll.
Wenn jemand noch Vorschläge hat, damit ich schneller vorankomme, nur zu. Würde sehr helfen.
Die Zeit ist knapp, und ich schon über 50 ;-)

Gruß Joe

Unser Projekt Rolleyes http://global-science-circle.net http://global-science-circle.org http://global-science-circle.info UND http://radio-gsc1.info
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
13.12.2013, 07:03 (Dieser Beitrag wurde zuletzt bearbeitet: 13.12.2013 07:05 von JoeDorm.)
Beitrag #26
RE: Brennersteuerung
Hallo,

bräuchte mal dringend Hilfe bei der Formel, um die Pausenzeit der Pelletszuführung zu berechnen, wenn ich nur kw/Stunde vorgebe.

Es gilt :
Brennwert/kg = 4,9 kw/Std
Zuführungszeit = 1 Sekunde

Zuführungspause bei gewünschten X kw = ???

Hab mich da verrannt Undecided
Knoten im Hirn... :Huh

Gruß Joe

Unser Projekt Rolleyes http://global-science-circle.net http://global-science-circle.org http://global-science-circle.info UND http://radio-gsc1.info
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
13.12.2013, 16:53
Beitrag #27
RE: Brennersteuerung
Hallo Joe,
Zitat:Wenn jemand noch Vorschläge hat, damit ich schneller vorankomme, nur zu. Würde sehr helfen.
Mahr arbeiten, weniger schlafen und essen Big GrinBig Grin
Ne ernsthaft, sag wo man dir wie helfen könnte bei der Programmierung.
Habe dieses WE relative Ruhe, daher zu allen "Schandtaten" bereit.

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
13.12.2013, 22:03 (Dieser Beitrag wurde zuletzt bearbeitet: 13.12.2013 22:14 von JoeDorm.)
Beitrag #28
RE: Brennersteuerung
(13.12.2013 16:53)rkuehle schrieb:  Hallo Joe,
Zitat:Wenn jemand noch Vorschläge hat, damit ich schneller vorankomme, nur zu. Würde sehr helfen.
Mahr arbeiten, weniger schlafen und essen Big GrinBig Grin
Ne ernsthaft, sag wo man dir wie helfen könnte bei der Programmierung.
Habe dieses WE relative Ruhe, daher zu allen "Schandtaten" bereit.

Grüße Ricardo

Ja gerne :-)

Praktische Ausführungen::
Die Steuerung des Servos habe ich soweit fertig. Er funzt leicht verzögert und nicht hektisch, arbeitet sich gemütlich an die passende Stellung heran. Gezappel ist da eher kontraproduktiv. Werde mich jetzt um die Montage am Brenner kümmern. Wird wohl sowas wie ein doppelseitiges Klebeband werden, womit es auf dem Lüfter fixiert wird. Auf den Servo kommt ein Zwischenstück, das dafür sorgt, das der Servo sich nicht im Betrieb deplatziert, da der Gehäusedeckel dann eine leichte Klemmung übernimmt. Dann noch die Luftplappe lösen und mit einer leichten Feder in FastZu-Stellung bringen. Der Servo geht erstmal in die Grundeinstellung mit mittlerer Luft und macht bei zu großem Lambda die Klappe Stück für Stück im 4-Sekunden-Takt zu; Jeweils 1 Grad. Die Verbindung zwischen Servo und Luftschieber kann ein einfacher Draht oder ein Seil sein. Alles ist leicht demontierbar und der Urzustand wieder herstellbar. Von aussen wir kaum etwas sichtbar sein, ausser einer unten herausgeführten kleinen Steckbuchse, die da herumbaumeln kann. Der Stecker hat die 3 Kontakte für den Servo.

Die Spannungsversorgung muß vom Netzteil für den Lambdacomputer, also 12V abgezwickt werden. Die Spannungsdifferenz zu 9V der Arduino-Versorgung erreiche ich durch mehrere Dioden in Serie, deren Sperrspannung(0.7V) die 12 V einfach und zuverlässig reduziert. Wichtig ist, das das Minuspotential zwischen Lambdageber und Arduino gleich sind.

Die Relay-Platine kommt in ein Gehäuse von einem alten Leistungsregler, der einfach in den Stromkreislauf zwischen Steckdose und Stecker der Förderschnecke zwischenpositioniert wird. Einziger Knackpunkt ist eine zusätzliche Zuführung von 220V sein. 4 Kabel, 5V, GND, 2xRelayansteuerung, werden auch nicht vergessen.

So das mal aktuell, was ich fürs Weekend auf dem Plan habe. Sobald der Brennerumbau fertig ist, gibts auch Fotos.


Bei Untigem kann sich gerne jemand einklinken und den übernommenen Part Programmierung für sich reservieren, damit nichts doppelt angefaßt wird.
Kann man das etwas komplexe Projekt auch simulieren? VBB?

A) Habe die Menülösung noch nicht ernsthaft angefaßt.
Bekomme das Display mit den 6 Tasten 4x20(I2C? brauchts da einen Shield für?)
Da hast Du ja Erfahrung mit, wie ich lesen konnte.
Habe das Display aber noch nicht da.
Aber man könnte den Programmteil weitestgehend vorbereiten, vermute ich.

B) Ein Problem habe ich auch noch mit der Pausenzeitberechnung bei der Brennstoffzuführung. Will ja nur die kw vorgeben, und bei fix eingestellter Förderzeit(1sek) brauchts dann eine passende Pause. Habe 3,8kg in 10Minuten Dauerförderung, woraus man errechnen kann, wieviel je Sekunde an kg da durchpoltern(ca. 0.006kg). Der Brennwert(4,9kw/kg) alsauch die kg/10Minuten möchte ich in der Grunddaten per Menü einstellbarmachen.
Mehr Parameter brauchts eigentlich nicht, um die Förderpause entsprechend über die Soll-kw-Leistung auszurechnen. Habe mich da aber extrem verheddert.

C) Die Übernahme nach dem Start, das der Brenner eine Flamme hat, ist der Zeitpunkt, wo der Arduino dann die Beschickung komplett übernehmen soll.
Dafür habe ich eine Relay-Platine mit 2 Relays. Das erste Relay unterbricht die bestehende 220V-Stromführung. und stellt quasi ersatzweise auf gleicher Phase die 220V Dauerspannung zur Verfügung, die in Relay 2 dann getaktet wird.
Dafür brauchts einen INPUT-Kanal zur Flammenerkennung, welche ich am Sensor abnehmen könnte. Hoffe, das ich da mich parallel anschalten kann, ohne die Startfunktion des A25-Brenners durcheinanderzubringen. Hierzu brauchts dann auch noch einen genauen Timer.
Die bereits zugeführten kg oder kw möchte ich auch zwischenspeichern, wieauch die Einstellungen. Wie geht das Speichern und wo wirds abgelegt. Wie oft kann man einen Speicherort überschreiben?

D) Sowohl die Zuluftregelung nach Lambda, alsauch die Beschickung sollen parallel laufen. Wie geht das mit den interuptgesteuerten Möglichkeiten? Da müßte dann wohl etwas im Programm umgestellt werden, oder? Wie kann man dies geschickt lösen?

Also, da ist genug zum mitanfassen, falls jemand gerne helfen möchte. Die Lösung und die Durchführung nebst Programm ist dann ja hier hinreichlich dokumentiert, falls da jemand einen anderen Pelletskessel nachrüsten möchte.

Gruß Joe

Unser Projekt Rolleyes http://global-science-circle.net http://global-science-circle.org http://global-science-circle.info UND http://radio-gsc1.info
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
14.12.2013, 01:32 (Dieser Beitrag wurde zuletzt bearbeitet: 14.12.2013 01:34 von JoeDorm.)
Beitrag #29
RE: Brennersteuerung
Bei Punkt B) habe ich schon mal weiter geforscht.

Habe im Atmosforum was gefunden, was hilfreich sein könnte.

Code:
Die Berechnungsmethode im Quellcode der Atmos-Berechnungs-Seite ist::
function atmos_function(){
Tmin=parseFloat(document.Tmin.Tmin.value);
Mikg=parseFloat(document.Mikg.Mikg.value);
HwkW=parseFloat(document.HwkW.HwkW.value);
Kwgr=parseFloat(document.Kwgr.Kwgr.value);
Tzuf=parseFloat(document.Tzuf.Tzuf.value);
Tpau=parseFloat(document.Tpau.Tpau.value);
Pgeh= 60 / Tmin * Mikg * HwkW /(100/Kwgr);
//Turn= 3600/ (Tzuf + Tpau)
HLG= 3600/ (Tzuf + Tpau) * Tzuf * Pgeh / 3600
document.HLG.HLG.value=runden(HLG);
}

Da Turn nicht benutzt wird, kann man Turn auskommentieren, was ich mal gemacht habe.

So verbleibt::
Pgeh= 60 / Tmin * Mikg * HwkW /(100/Kwgr);
HLG= 3600/ (Tzuf + Tpau) * Tzuf * Pgeh / 3600

Auf eine Zeile gebracht::
HLG= 3600/ (Tzuf + Tpau) * Tzuf * ((( 60 / Tmin * Mikg * HwkW /(100/Kwgr) ))) / 3600

Nun müßte man nur noch die Formel so umstellen(das war in der Schule dran als ich damals krank war) das man statt HLG(Heizleistung) Tpau(Pausenzeit) herausbekommt.

Bekommt das jemand hin, die Berechnung auf Tpau umzustellen?

Gruß Joe

Unser Projekt Rolleyes http://global-science-circle.net http://global-science-circle.org http://global-science-circle.info UND http://radio-gsc1.info
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
14.12.2013, 13:03
Beitrag #30
RE: Brennersteuerung
Moin Joe,
mal ein paar Worte:

Zitat:Die Spannungsdifferenz zu 9V der Arduino-Versorgung erreiche ich durch mehrere Dioden in Serie, deren Sperrspannung(0.7V) die 12 V einfach und zuverlässig reduziert.
Den Aufwand musst du nicht treiben. Arduino verträgt 7-12 Volt.
Zitat:Bekomme das Display mit den 6 Tasten 4x20(I2C? brauchts da einen Shield für?)
Es reicht für das LCD ein 4-adriges Kabel als I2C Anbindung.
(VCC, GND, SCL, SDA)
Zitat:Kann man das etwas komplexe Projekt auch simulieren? VBB?
Du meinst "VBA" ? Würde ich nicht machen, da die Sprachebenen doch zuweit auseinander liegen.
Zitat:Habe die Menülösung noch nicht ernsthaft angefaßt.
Aber man könnte den Programmteil weitestgehend vorbereiten, vermute ich.
Ja sollte gehen. Zumidest kann man die komplette Menüstruktur aufbauen und die Punkte (vorerst) mit "Blindfunktionen" belegen,
die dann nach und nach befüllt werden.
Hast du nochmal eine Auflistung der Menüpunkte bzw./und der dahinterliegenden Aufgaben?
Zitat:Der Brennwert(4,9kw/kg) alsauch die kg/10Minuten möchte ich in der Grunddaten per Menü einstellbarmachen.
Die bereits zugeführten kg oder kw möchte ich auch zwischenspeichern, wieauch die Einstellungen.
Die Einstellungen zu speichern ist nicht wirklich problematisch. Kann man im EEPROM hinterlegen. Die Werte bleiben dann auch bei Poweroff erhalten.
Was meinst du mit "zwischenspeichern für die bereits zugeführten kg oder kw"?
Sollen die Daten
a) später/parallel irgendwie ausgewertet oder dargestellt werden, oder
b) brauchst du die Werte nur um sie zwischendurch abfragen zu können?
Wenn a) würde ich zu bestimmten Zeitpunkten oder Vorgängen in eine Datenbank oder auf SD-Karte schreiben.
Wenn b) müssten die Daten auch in den EEPROM und über einen zusätzlichen Menüpunkt abgefragt werden können
Zitat:Sowohl die Zuluftregelung nach Lambda, alsauch die Beschickung sollen parallel laufen.
Wie geht das mit den interuptgesteuerten Möglichkeiten?
Da müßte dann wohl etwas im Programm umgestellt werden, oder? Wie kann man dies geschickt lösen?
Vorsicht, nicht Äpfel und Birnen zusammenschmeißen!
Interrupt:
Ganz allgemein werden Signaländerungen an definierten Pins überwacht. Treten die Änderungen auf, werden alle laufenden Operationen
unterbrochen und die dem Interrupt zugewiesene Funktion abgearbeitet.
Problematisch hier: diese "Interruptfunktionen" müssen in aller Regel ohne übergebene oder zurück gegebene Werte auskommen.
Erst danach werden die sonstigen Abläufe wieder aufgenommen/weiter abgearbeitet.
Parallel:
Über die Time/TimeAlarm - Library kann man Abläufe zeitgesteuert aufrufen. Entweder zu bestimmten Zeiten (einmal oder mehrfach), oder generell zyklisch
(zB. alle 20 Sekunden).
Die Frage: Welche Methode brauchst du?

So, jetzt trinke ich noch einen Kaffee und gucke dann mal in deinen Code ;-)

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
14.12.2013, 18:15 (Dieser Beitrag wurde zuletzt bearbeitet: 14.12.2013 18:43 von rkuehle.)
Beitrag #31
RE: Brennersteuerung
Hallo Joe,

ich habe den Code jetzt mal ein wenig "renoviert"
Die wesentlichen Änderungen:
- Variablen umdefiniert (Konstanten etc.)
- die LCD Ansteuerung auf I2C umgestellt
- die Routinen für die Relais zusammengefasst
- die delay-Funktion ersetzt, da es ansonsten bei zukünftigen Interrupt/Timer-Routinen Probleme gibt
Code:
#include <Servo.h> // Servo
#include <PString.h> // Strings
#include <Wire.h> // I2C Funktionen
#include <LiquidCrystal_I2C.h> // LCD Funktionen
// Servo
Servo myServo;
const int servoPinLuft = 7;   // Servo mit freiem Digital-Pin verbunden
const int servoStep = 5;  //
const int center = 90;    // 0 Grad
int pulseWidth;     // Variable der servoPulse-Funktion;
int myAngle = 90;   // Drehwinkel des Servos ca 0-180 Grad
// LCD I2C - Adresse 0x3F muss angepasst werden
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7);
const int backLight = 12;
// Taster
const int T_ESC = 14; //ESC, Einstellung beenden
const int T_LEFT = 15; //Links, Ebene zurück
const int T_RIGHT = 16; //Rechts, Ebene vor
const int T_UP = 17; //Oben, nach oben
const int T_DOWN = 18; //Unten, nach unten
const int T_RST = 19; //Reset
// Status der Taster
int T1 = 0, T2 = 0, T3 = 0, T4 = 0, T5 = 0, T6 = 0;
// Relais
const int R_P = 20; // Pellets
const int R_A = 21; // Asche
// Lambdasonde
const int analogpin = A0;
// Zeitdifferenz
const unsigned long DelayMS = 1000;
// Bedeutung ist mir noch nicht klar!
int inp = 3;
double a_input = 1.1;
char buf[20];
int menu = 0;
String versio = "Regomat V0.2";
double LbdCen = 1.54;
double LbdSpr = 0.05;
int kw = 5;

void setup() {
  // LCD starten
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(0);
  lcd.begin(20, 4);
  lcd.setCursor(0, 0);
  lcd.clear();
  initTimer();
  Serial.begin(9600);
  pinMode(T_ESC, INPUT);
  pinMode(T_LEFT, INPUT);
  pinMode(T_RIGHT, INPUT);
  pinMode(T_UP, INPUT);
  pinMode(T_DOWN, INPUT);
  pinMode(T_RST, INPUT);
  pinMode(R_P, OUTPUT);
  pinMode(R_A, OUTPUT);

  if (menu == 0) printLCDmenu000();
  myServo.attach(servoPinLuft);
  myAngle = center;
  setServoLuft();
  if (1 == 2) setPegel(R_P,1);
  else setPegel(R_P,0);
  if (2 == 3) setPegel(R_A,1);
  else setPegel(R_A,0);
}

void loop() {
  if (menu ==  0) menu = 200;
  if (menu == 000) printLCDmenu000(); //Initiale Ausgabe
  if (menu == 100) printLCDmenu100(); //Betriebsart
  if (menu == 110) printLCDmenu110(); // Betrieb,Automatik
  if (menu == 111) printLCDmenu111(); //  Betrieb,Automatik,kw
  if (menu == 112) printLCDmenu112(); //  Betrieb,Automatik,LCenter
  if (menu == 113) printLCDmenu113(); //  Betrieb,Automatik,LSpreiz
  if (menu == 120) printLCDmenu120(); // Betrieb,Manuell
  if (menu == 200) printLCDmenu200(); //Einstellung
  if (menu == 210) printLCDmenu210(); // Einstellung,LambdaCenter
  if (menu == 211) EinstellLbdCen(); //Justierung,LambdaCenter
  if (menu == 220) printLCDmenu220(); // Einstellung,LambdaSpreizung
  if (menu == 221) EinstellLbdSpr(); //Justierung,LambdaSpreizung
  if (menu == 230) printLCDmenu230(); // Einstellung,kw
  if (menu == 300) printLCDmenu300(); // Manueller Betrieb
  if (menu == 400) printLCDmenu400(); // Nur Einstellungen
  readData();
  printLCD();
  setServoLuft();
  setPegel(R_P,0);
  setPegel(R_A,0);
  readTasten();
}

void servoPulse(int servoPin, int myAngle) {
  pulseWidth = (myAngle * 10) + 600; // bestimmt die Verzögerung
  digitalWrite(servoPin, HIGH);      // setzt den Ausgang auf HIGH
  delayMicroseconds(pulseWidth);     // Mikrosekunden Pause
  digitalWrite(servoPin, LOW);       // setzt den Ausgang auf LOW
}

void PRINT(int x, int y, String str) {
  if (x != 99 && y != 99)
    lcd.setCursor(x, y);
  if (y == 99)
    lcd.print(str + "\n");
  else
    lcd.print(str);
  Serial.println(str);
}

void readData() {
  inp = analogRead(analogpin);
  if (a_input > LbdCen + LbdSpr / 2 && myAngle > 0)
    myAngle = center - servoStep;
  else if (a_input < LbdCen - LbdSpr / 2 && myAngle < 180)
    myAngle = center + servoStep;
  else
    myAngle = center;
  a_input = 5.0 / 1023.0;
  a_input = a_input * (double)inp;
}

void printLCD() {
  String s = "i=" + String(inp) + " ";
  ;
  s = s + "Lbd=" + str(a_input, 3) + " ";
  s = s + "o=" + str(myAngle, 0) + "\n";
  PRINT(0, 3, s);
}

void setServoLuft()
{
  servoPulse(servoPinLuft, myAngle);
  newDelay(DelayMS);
}
// Ersatzfunktion für delay() um den Arduino während des Wartens nicht stillzulegen
void newDelay(unsigned long diff)
{
  unsigned long lastnow = millis();
  while (1) {
    if (millis()-lastnow > diff)
    {
      lastnow=millis();
      break;
    }
  }
}
// Funktion zum setzen der Pegel als Ersatz für die bisherigen Einzelfunktionen
void setPegel(int pin,int level)
{
  if (level == 0) digitalWrite(pin,LOW);
  if (level == 1) digitalWrite(pin,HIGH);
}
String str(double d, int nk) {
  PString(buf, sizeof(buf), d, nk);
  return (buf);
}
void readTasten() {
  T1 = digitalRead(T_ESC); //ESC, Einstellung beenden
  T2 = digitalRead(T_LEFT); //Links, Ebene zurück
  T3 = digitalRead(T_RIGHT); //Rechts, Ebene vor
  T4 = digitalRead(T_UP); //Oben, nach oben
  T5 = digitalRead(T_DOWN); //Unten, nach unten
  T6 = digitalRead(T_RST); //Reset
  if (T1 + T2 + T3 + T4 + T5 + T6 != 0) {
    if (T1 == 1) { //ESC
    }
    if (T2 == 1) { //Links
      if (menu == 200) menu = 100;
      if (menu == 210) menu = 200;
      if (menu == 211) menu = 210;
      //usw...
    }
  }
  newDelay(DelayMS);
}

void printFree(int zeile) {
  lcd.setCursor(0, zeile);
  lcd.print("                    ");
}
void printFree3() {
  printFree(3);
}
void printFree2() {
  printFree(2);
  printFree(3);
}
void printFree1() {
  printFree(1);
  printFree(2);
  printFree(3);
}
void printFree0() {
  printFree(0);
  printFree(1);
  printFree(2);
  printFree(3);
}
void printLCDmenu000() {
  printFree0();
  PRINT(0, 0, versio + " M000");
  PRINT(0, 1, "Initialisierung");
  PRINT(0, 2, "Bitte warten");
  PRINT(0, 3, "Finish");
}

void printLCDmenu100() {
  printFree0();
  PRINT(0, 0, versio + " M100");
  PRINT(0, 1, "Betriebsart");
}

void printLCDmenu110() {
  printFree0();
  PRINT(0, 0, versio + " M110");
  PRINT(0, 1, "Automatik200");
  PRINT(0, 2, "Manuell300");
  PRINT(0, 3, "Einstellung400");
}

void printLCDmenu111() {
}
void printLCDmenu112() {
  printFree0();
  PRINT(0, 0, versio + " M111");
  PRINT(0, 1, "Automatik");
  PRINT(0, 2, "Einstellung kw");
  PRINT(0, 3, "Eingabe kw : ___");
}
void printLCDmenu113() {
}
void printLCDmenu120() {
  printFree0();
  PRINT(0, 0, versio + " M120");
  PRINT(0, 1, "Betriebsart Manuell");
}
void printLCDmenu200() {
  printFree0();
  PRINT(0, 0, versio + " M200 Automatik");
  PRINT(0, 1, "Einstell. kw(" + String(kw) + ") -->M210");
  PRINT(0, 2, "Einstell. LC(" + str(LbdCen, 2) + ") -->M220");
  PRINT(0, 3, "Einstell. LS(" + str(LbdSpr, 2) + ") -->M230");
}
void printLCDmenu210() {//Einstellung Lambda Center
  printFree0();
  PRINT(0, 0, versio + " M210 Automatik");
  PRINT(0, 1, "Einstell. Lbd Center");
  PRINT(0, 2, "Alter Wert : " + printf("%i", LbdCen));
  PRINT(0, 3, "Neuer Wert : _");
}
void printLCDmenu220() {
  printFree0();
  PRINT(0, 0, versio + " M220 Automatik");
  PRINT(0, 1, "Einstell. Lbd.Spreizung");
  PRINT(0, 2, "Alter Wert : " + printf("%i", LbdSpr));
  PRINT(0, 3, "Neuer Wert : _");
}
void printLCDmenu230() {
  printFree0();
  PRINT(0, 0, versio + " M230 Automatik");
  PRINT(0, 1, "Einstell. Kessel kw");
  PRINT(0, 2, "Alter Wert : " + kw);
  PRINT(0, 3, "Neuer Wert : _");
}
void printLCDmenu300() {
  printFree0();
  PRINT(0, 0, versio + " M300 Manuell");
  PRINT(0, 1, "Pellets Ein 0/1");
  PRINT(0, 2, "Zuluft +/-");
  PRINT(0, 3, "Aschetransport 0/1");
}
void printLCDmenu400() {
  printFree0();
  PRINT(0, 0, versio + " M400 Nur Einst.");
  PRINT(0, 1, "Pellets Ein 0/1");
  PRINT(0, 2, "Zuluft +/-");
  PRINT(0, 3, "Aschetransport 0/1");
}
void EinstellLbdCen() {
}
void EinstellLbdSpr() {
}
void initTimer() {
}
Wo ich überhaupt noch nicht durchsehe ist die von dir gewünschte Menüstruktur.
Kannst du mir (per PN?) diese mal zusenden? Es gibt eine recht gute Library mit der man Menüs generieren und per Taster auswerten kann.

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
14.12.2013, 21:10 (Dieser Beitrag wurde zuletzt bearbeitet: 15.12.2013 07:19 von JoeDorm.)
Beitrag #32
RE: Brennersteuerung
Hallo,
das Programm war offensichtlich nicht vollständig kopiert.
Daher unten nochmal meinen derzeitigen Stand.
Jetzt sieht man unten in der Loop was ich mir in etwa vorstelle.
Halte es durchaus für möglich, das ich ein von Dir eingebautes Menü abgeändert bekomme. Daher ist es nicht problematisch, wenn sich das Menü noch ändert.

Stelle mir vor, das man mit mit 5 Tasten, up down left right im Menü rumläuft, und mit enter in den Änderungsmodus kommt, und mit enter die Änderung bestätigt und wieder im Menü zum letzten Ausgangspunkt zurück kommt. Mit ganz links ESC sollte man in den Automatikmodus schnell herüberwechseln können.
Wichtig, wärend des Änderns oder Herumwanderns im Menü soll der Automatikbetrieb natürlich weiterlaufen! Wen nsich ein Wert, der Folgen für den Automatikbetrieb hat, geändert wird, dann muß jede mit Enter angeschlossene Eingabe, sofort im Automatikmodus berücksichtigt werden.

Um eine zwischenzeitliche serielle Mitausgabe zu ermöglichen, läuft die Ausgabe über die PRINT() Funktion. Die müßte für die I2C-Ausgabe angefaßt werden, da dies so noch nicht drin ist. Wäre gut, wenn die Du die Ausgabe dort mit reintust, sofern es Sinn macht.

Grundeinstellungen für kw-Umrechnung in Pausenzeit::
TestlaufzeitMinuten=10.0
kgInDieserZeit=3.8
FörderzeitSekunden=1.0
FörderzeitPauseSekunden=35.0 //wird bei kw-Eingabe neue berechnet
BrennwertFür1KgPelletsInKw=4.9

Grundeinstellung für den Servo::
double servoStep=0.25; // je Sekunde 0.25 Grad ist gute Verzögerung
double LbdCen=1.508;//Voreinstellung Wunschwert
double LbdAbw=0.005;//Additions-,Subtraktionswert für Vergleich Lambda, bevor reagiert wird.

Grundeinstellung ::
ProzessdauerServo=1.0;// 1 Sekunde, also in welchem Abstand Messung und Luftservo angeschoben werden sollen.
Ansonsten muß jede Sekunde geschaut werden, ob Pellets zugeführt werden müssen. Da wird für 1 Sekunde eingeschaltet, und dann z.B. 20 Sekunden Pause gemacht.
Wie man das auch programmiert, mit den zeitkritischen Sachen habe ich AUCH noch keine Ahnung.

Obige Grundeinstellungen muß ich im Menü Einstellungen unterbekommen. für die kw Pausenzeit Einstellungen kw, und darunter die einzelnen Werte anzeigen und bei Auswahl_navigation und Enter in den Editmodus. Die Werte müssen zuvor über das EPROM reingelesen werden und nach Änderung zurückgeschrieben werden.

Zweites Grundeinstellungesmenü: Servo, und darunter die 3 Werte. Lesen editieren und bei Änderung speichern, wie bei kw Pausenzeit.

Das wäre schonmal eine gute Brocke Arbeit, über die ich mich freuen würde, wenn Du das übernimmst.
Ich weiß, das, sofern man die Möglichkeiten der Umsetzung/Progeammierung beherrscht, es dann zügig voran geht.
Hoffe Du bist fit ;-)
Ich quäle mich derzeit noch auf Grund mangelnder Erfahrung.

Sehe grade, das Du das Programm schon angefaßt hast.
Ich schaue, was Du da reingetan hast, und übertrage es in den aktuell bei mir vorhandenen Programmstand.
Hoffe, ich stelle mich nicht zu dusselig an.
Danke

Gruß Joe

Code:
//Simulate Mega

#include <Servo.h> // Servo
#include <PString.h> // Strings
#include <Wire.h> // I2C Funktionen
//#include <LiquidCrystal.h> // LCD Funktionen
#include <LiquidCrystal_I2C.h> // LCD Funktionen

Servo myServo;
int servoPinLuft = 7;   // Servo mit freiem Digital-Pin verbunden
double myAngle=0;     // Drehwinkel des Servos ca 0-180 Grad
double servoStep=0.25;    //
double start=60;
double center=0;      // 0 Grad
double ende=90;

double LbdSol=1.508;//Voreinstellung
double LbdAbw=0.005;//Additions-,Subtraktionswert für Vergleich Lambda

int DelayMS=1000; // Der Zyklus für einen kompletten Durchlauf. Soll einstellbar!
int analogpinLambda = A0;//1..5V für Umrechnung in Lambda.

//LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);//OUTPUT f. LCD
// LCD I2C - Adresse 0x3F muss angepasst werden
//The PCF8574 extender is available in two versions, the PCF8574 and the PCF8574A.
//The only difference between the two is the I2C base address.
//The base address for the PCF8574 is 0x20 and the base address for the PCF8574A is 0x38.
//The examples included in this zip file assume the use of an PCF8574 set for address 0x20
//(A0, A1 and A3 grounded).
//alt 0x3F
LiquidCrystal_I2C lcd(0x38, 2, 1, 0, 4, 5, 6, 7);
int backLight = 12;//OUTPUT 12

int inp=3,oldInp=0;//Variable zum Einlesen Lambdaspannung 1L=1V 5L=5V über A0
double a_input=1.1;//Variable für Umrechnung Lambda
char buf[20];//String Buffer für PString Methode
int menu=0;//Aktueller Wert des Menüs
String versio="Regomat V0.2";

double kw=5.0;//voreinstellung kw. Läßt sich fast beliebig einstellen´
double pelletsTestzeitMin=10;//Für Berechnung Pelletsmenge/Pause
double pelletsTestzeitKg=3.8;//3.8kg in 10 Min Dauerförderung
double pelletsKgSek=0.00654321;//Wird berechnet
double pelletsBrennwertKg=4.9;//je nach Pellets-Herstellerangabe
double pelletsAnSek=1.0;// Laufzeit der Pelletsschnecke
double pelletsAusSek=35.0;//Pausenzeit der Pelletsschnecke

// Taster
const int T_ESC = 14; //ESC, Einstellung beenden
const int T_LEFT = 15; //Links, Ebene zurück
const int T_RIGHT = 16; //Rechts, Ebene vor
const int T_UP = 17; //Oben, nach oben
const int T_DOWN = 18; //Unten, nach unten
const int T_RST = 19; //Reset
// Status der Taster
int T1 = 0, T2 = 0, T3 = 0, T4 = 0, T5 = 0, T6 = 0;
// Relais
const int R_P1 = 20; // Relais1 Pellets
const int R_P2 = 21; // Relais2 Pellets
const int R_A = 22; // Asche
// Lambdasonde
const int analogpin = A0;//Lambda_Volt

int serpin=0; //setupvariable firstrun für Servo Luftzufuhr

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Ersatzfunktion für delay() um den Arduino während des Wartens nicht stillzulegen
void newDelay(unsigned long diff) {
  unsigned long lastnow = millis();
  while (1) {
    if (millis()-lastnow > diff)  {
      lastnow=millis();
      break;
    }
  }
}
// Funktion zum setzen der Pegel als Ersatz für die bisherigen Einzelfunktionen
void setPegel(int pin,int level) {
  if (level == 0) digitalWrite(pin,LOW);
  if (level == 1) digitalWrite(pin,HIGH);
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
String str(double d, int nk) {
  PString(buf, sizeof(buf),d,nk);
  return(buf);
}
void PRINT(int x, int y, String str) {
  if(x!=99 && y!=99)
    lcd.setCursor(x,y);
  if(y==99)
    lcd.print(str+"\n");
  else
    lcd.print(str);
  Serial.println(str);
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void servoWrite(double pos) {
  if(serpin==0) {//einmalig initialisieren
    serpin=servoPinLuft;
    myServo.attach(serpin);
  }
  if(pos<start) pos=start;
  if(pos>ende)  pos=ende;
  myAngle=pos;
  myServo.write(pos);
  delay(DelayMS);
}
void setServoLuft() {
  servoWrite(myAngle);
}
void calculateLambda() {
  int oldCenter=center;
  center = 60+(kw*2);//test mit je kw 2 Grad mehr Luft, um näher ans Ziel zu kommen
  int range=40;// + - 40 Grad von center
  start=center-range;
  ende =center+range;
  PRINT(99,99,"S="+str(start,1)+
    " C="+str(center,1)+
    " A="+str(myAngle,1)+
    " E="+str(ende,1) );
  if(myAngle==0 || center!=oldCenter)
    myAngle=center;
  a_input=5.0/1024.0;
  a_input=a_input*(double)inp+1;
  if(a_input > LbdSol+LbdAbw && myAngle>start) {
    myAngle=myAngle-servoStep;
    PRINT(99,99,"a_inp("+str(a_input,3)+")>>("+str(LbdSol+LbdAbw,3)+")");
  }
  else
    if(a_input < LbdSol-LbdAbw && myAngle<ende) {
      myAngle=myAngle+servoStep;
      PRINT(99,99,"a_inp("+str(a_input,3)+")<<("+str(LbdSol-LbdAbw,3)+")");
    }
    else
      PRINT(99,99,"a_inp("+str(a_input,3)+")==("+str(LbdSol,3)+")");
}
void readSensorLambdaSetGgfLuft() {
  inp=analogRead(analogpinLambda);
  if(inp!=oldInp) {
    calculateLambda();
    setServoLuft();
  }
  oldInp=inp;
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void setRelayPellets() {
  //MEINE BAUSTELLE
  //int kw=5;//voreinstellung kw. Läßt sich fast beliebig einstellen´
  //double pelletsTestzeitMin=10;//Für Berechnung Pelletsmenge/Pause
  //double pelletsTestzeitKg=3.8;//3.8kg in 10 Min Dauerförderung
  //double pelletsKgSek=0.01;//Wird berechnet
  //double pelletsBrennwertKg=4.9;//je nach Pellets-Herstellerangabe
  //double pelletsAnSek=1;
  //double pelletsAusSek=35;
  pelletsKgSek=pelletsTestzeitKg/(pelletsTestzeitMin*60);//Pellets kg/sek
  PRINT(99,99,"pelletsKgSek="+str(pelletsKgSek,5));
  double pEinTaktSek=pelletsAnSek+pelletsAusSek;
  double pTaktSek=60/(pEinTaktSek);
  PRINT(99,99,"pTaktSek="+str(pTaktSek,5));
  double pTakteStd=pEinTaktSek*60;
  PRINT(99,99,"pTakteStd="+str(pTakteStd,5));
  double pKgMin=pTaktSek*pelletsKgSek;
  double pKgStd=pKgMin*60;
  double pKwStd=pelletsBrennwertKg*pKgStd;
  double pKwSek=pKwStd/60;
  double pLfz1KwSek=1/(pTaktSek*60);
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void setRelayAsche() {
  setPegel(R_A,1);
  newDelay(1000*60);// 1 Minute Laufzeit
  setPegel(R_A,0);
  newDelay(1000*60*60*24 - 1000*60);// 24Std Pause
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void readTasten() {
  T1=digitalRead(14);//ESC, Einstellung beenden
  T2=digitalRead(15);//Links, Ebene zurück
  T3=digitalRead(16);//Rechts, Ebene vor
  T4=digitalRead(17);//Oben, nach oben
  T5=digitalRead(18);//Unten, nach unten
  T6=digitalRead(19);//Reset
  if(T1+T2+T3+T4+T5+T6 != 0) {// nicht keine Taste gedrückt, also Taste wurde gedrückt
    if(T1==1) { //ESC
      menu=200;//in Automatik Anzeige wechseln
    }
    if(T2==1) { //Links
      if(menu==200) menu=100;
      if(menu==210) menu=200;
      if(menu==211) menu=210;
      //usw...
    }
  }
  //delay(DelayMS);
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void printLambdaProzess() {
  String s="i="+String(inp)+" ";
  s=s+"Lbd="+str(a_input,3)+" ";
  s=s+"o="+str(myAngle,3)+"\n";
  PRINT(0,3,s);
}
void printFree(int zeile) {
  lcd.setCursor(0,zeile);
  lcd.print("                    ");
}
void printFree3() {
  printFree(3);
}
void printFree2() {
  printFree(2);
  printFree(3);
}
void printFree1() {
  printFree(1);
  printFree(2);
  printFree(3);
}
void printFree0() {
  printFree(0);
  printFree(1);
  printFree(2);
  printFree(3);
}
void printLCDmenu000() {
  printFree0();
  PRINT(0,0,versio+" M000");
  PRINT(0,1,"Initialisierung");
  PRINT(0,2,"Bitte warten");
  PRINT(0,3,"Finish");
}

void printLCDmenu100() {
  printFree0();
  PRINT(0,0,versio+" M100");
  PRINT(0,1,"Betriebsart");
}

void printLCDmenu110() {
  printFree0();
  PRINT(0,0,versio+" M110");
  PRINT(0,1,"Automatik200");
  PRINT(0,2,"Manuell300");
  PRINT(0,3,"Einstellung400");
}

void printLCDmenu111() {
}
void printLCDmenu112() {
  printFree0();
  PRINT(0,0,versio+" M111");
  PRINT(0,1,"Automatik");
  PRINT(0,2,"Einstellung kw");
  PRINT(0,3,"Eingabe kw : ___");
}
void printLCDmenu113() {
}
void printLCDmenu120() {
  printFree0();
  PRINT(0,0,versio+" M120");
  PRINT(0,1,"Betriebsart Manuell");
}
void printLCDmenu200() {
  printFree0();
  PRINT(0,0,versio+" M200 Automatik");
  PRINT(0,1,"Einstell. kw("+str(kw,1)+") -->M210");
  PRINT(0,2,"Einstell. LC("+str(LbdSol,2)+") -->M220");
  PRINT(0,3,"Einstell. LA("+str(LbdAbw,2)+") -->M230");
}
void printLCDmenu210() {//Einstellung Lambda Center
  printFree0();
  PRINT(0,0,versio+" M210 Automatik");
  PRINT(0,1,"Einstell. Lambda Soll");
  PRINT(0,2,"Alter Wert : "+printf("%i",LbdSol));
  PRINT(0,3,"Neuer Wert : _");
}
void printLCDmenu220() {
  printFree0();
  PRINT(0,0,versio+" M220 Automatik");
  PRINT(0,1,"Einstell. Lbd.Abweichng.");
  PRINT(0,2,"Alter Wert : "+str(LbdAbw,2));
  PRINT(0,3,"Neuer Wert : _");
}
void printLCDmenu230() {
  printFree0();
  PRINT(0,0,versio+" M230 Automatik");
  PRINT(0,1,"Einstell. Kessel kw");
  PRINT(0,2,"Alter Wert : "+str(kw,1));
  PRINT(0,3,"Neuer Wert : _");
}
void printLCDmenu300() {
  printFree0();
  PRINT(0,0,versio+" M300 Manuell");
  PRINT(0,1,"Pellets Ein 0/1");
  PRINT(0,2,"Zuluft +/-");
  PRINT(0,3,"Aschetransport 0/1");
}
void printLCDmenu400() {
  printFree0();
  PRINT(0,0,versio+" M400 Nur Einst.");
  PRINT(0,1,"Pellets Ein 0/1");
  PRINT(0,2,"Zuluft +/-");
  PRINT(0,3,"Aschetransport 0/1");
}

void EinstellLbdSoll() {//manuelle Vorgabe eingeben
}
void EinstellLbdAbw() {//manuelle Vorgabe eingeben
}
void initTimer() {//Für Pelletsladung initialisieren
}

void setup() {
  // LCD starten
  int POSITIVE=1;//IST DAS SO RICHTIG? Declaration fehlt.
  //lcd.setBacklightPin(3, POSITIVE); AUSKOMMENTIERT, WEIL ICH OFFENSICHTLICH die falsche LIB habe?
  //lcd.setBacklight(0);
  lcd.begin(20, 4);
  lcd.setCursor(0, 0);
  lcd.clear();
  initTimer();
  Serial.begin(9600);
  pinMode(T_ESC, INPUT);
  pinMode(T_LEFT, INPUT);
  pinMode(T_RIGHT, INPUT);
  pinMode(T_UP, INPUT);
  pinMode(T_DOWN, INPUT);
  pinMode(T_RST, INPUT);
  pinMode(R_P1,OUTPUT);//Pelletsförderung Übernahme Relay
  pinMode(R_P2,OUTPUT);//Pelletsförderung Relay
  pinMode(R_A,OUTPUT);//Asche Relay

  setPegel(R_P2,0);//Pelletsbeschickung garantiert aus
  setPegel(R_P1,1);//setzt Standard ausser Kraft und Dauer 220V f. 2.Relais
  setPegel(R_A,0); //Ascheschnecke aus
  initTimer();//Beide Prozesse, Pelletsförderung und Luftzufuhr sollen innerhalb DelayMS ausgeführt werden, zwischenzeitliche Pause wäre zu berechnen und ein Differenz-Delay nötig um auf DelayMS zu kommen. Scheint ja mit newDelay möglich zu sein?
  pinMode(backLight, OUTPUT);//Display
  digitalWrite(backLight, HIGH);//Display
  lcd.begin(20,4);                    // 4 zeilen a 20 Zeichen
  lcd.clear();
  if(menu==0) printLCDmenu000();
  //uhrzeitLesenUndSetzen();//Noch nicht habe das Shield ;-(
  //alternative Uhrzeit??? Geht das überhaupt?
  //UhrzeitDatum Shield mit gepuffertem Timer???
  //wieso ist sowas nicht auf dem Board???
}  

void loop() {
  if(menu==  0) menu=200;          //Sofort erstmal in Automatik
  if(menu==000) printLCDmenu000(); //Initiale Ausgabe
  if(menu==100) printLCDmenu100(); //Betriebsart
  if(menu==110) printLCDmenu110(); // Betrieb,Automatik
  if(menu==111) printLCDmenu111(); //  Betrieb,Automatik,kw Soll
  if(menu==112) printLCDmenu112(); //  Betrieb,Automatik,LambdaIst
  if(menu==113) printLCDmenu113(); //  Betrieb,Automatik,LambdaAbw
  if(menu==120) printLCDmenu120(); // Betrieb,Manuell
  if(menu==200) printLCDmenu200(); //Einstellung
  if(menu==210) printLCDmenu210(); // Einstellung,LambdaSoll
  if(menu==211) EinstellLbdSoll(); //Justierung,LambdaSoll
  if(menu==220) printLCDmenu220(); // Einstellung,Lambda Abweichung
  if(menu==221) EinstellLbdAbw();  //Justierung,Lambd Abweichung
  if(menu==230) printLCDmenu230(); // Einstellung,kw
  if(menu==300) printLCDmenu300(); // Manueller Betrieb
  if(menu==400) printLCDmenu400(); // Nur Einstellungen
  readSensorLambdaSetGgfLuft();
  //setServoLuft();
  setRelayPellets();
  setRelayAsche();
  printLambdaProzess();
  readTasten();
  newDelay(DelayMS);
}

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7); macht Schwierigkeiten. Sie unten im Beitrag.
Fehlermeldung:
Regomat_v0_2:24: error: no matching function for call to 'LiquidCrystal_I2C::LiquidCrystal_I2C(int, int, int, int, int, int, int, int)'
C:\Users\admin\Documents\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:58: note: candidates are: LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t, uint8_t, uint8_t)
C:\Users\admin\Documents\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:56: note: LiquidCrystal_I2C::LiquidCrystal_I2C(const LiquidCrystal_I2C&)

Ging ich doch davon aus, das dieses Display mit I2C nur noch einen digitalen OUTPUT bräuchte, und die Daten seriell reingeschoben weden???
Für was brauchts die Wire.h ???
Da wo ich die LiquidCrystal_I2C gezogen habe, wurde die Wire.h im Beispiel nicht benutzt.
Ist die lcd Ausgabe eine Einbahnstraße, sodaß ich annehmen darf, das die Tasten anders eingelesen werden, und daher die vielen zusätzlich angegebenen ditigalen Ports bei der lcd-Initialisierung gebraucht werden?
Gruß Joe

Unser Projekt Rolleyes http://global-science-circle.net http://global-science-circle.org http://global-science-circle.info UND http://radio-gsc1.info
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 2 Gast/Gäste