Poolpumpensteuerung mit Solar 2.4 TFT - Touchscreen - NEUE FRAGE - SHIFTREGISTER

Hi Leute,

ich habe mich jetzt auch mal hier angemeldet, da ich schon sehr viele nützliche Projekte gesehen habe und auch hier viel know-how vorhanden ist.

Ich habe schon einige kleine Dinge mit Arduinos gemacht, kenne also die Basics.

Ein Arduino ist zur Zeit auch schon im Dauereinsatz (Ambilight für den TV, der auch ein Relais einschaltet für die Spannungsversorgung).

Jetzt möchte ich aber ein neues Projekt angehen. Und zwar eine Poolpumpensteuerung. Dabei müssen eigentlich “nur” 2 Temperatursensoren ausgelesen werden und danach die Pumpe Ein /Ausgeschaltet werden.

Dazu möchte ich den Arduino uno verwenden, ein 2,4 Zoll TFT Touchscreen, 2 Temperatursensoren, ein Relais und eine RTC

Ich habe hier im Forum diesen Thread gefunden: http://forum.arduino.cc/index.php?topic=174706.0
Das wäre im Prinzip auch schon das, was ich haben will, nur dass eben nur eine Pumpe angesteuert werden soll und ich auch keine Zeitschaltfunktion brauche. Jedoch möchte ich das alles mit meinem vorhandenen LCD realisieren.
Da ich soetwas aber noch nie gemacht habe, brauche ich eure Hilfe. Wie die Grafik aussieht ist mir dabei egal, die kann ich dann ja selbst anpassen, es geht eher ums Programm.

Hier also erstmal meine Komponenten:
arduino uno
tft touchscreen: http://www.aliexpress.com/item/For-Arduino-UNO-2-4-inch-TFT-touch-screen-supporting-For-UNO-R3/1224038230.html
Temperatursensoren möchte ich mir die DS18B20 bestellen, natürlich in wasserfester Ausführung. Gibt da ganz gute auf ebay
RTC DS1307 muss ich mir auch noch bestellen.

So, also wie gesagt, es ist sehr änlich wie im anderen Thread. Das Display hat übrigens auch schon einen SD Kartenslot, den ich später auch für logs nutzen möchte.

Nun zum Menü.
Ich habe mir das so vorgestellt.

Oben sollte immer die Uhrzeit stehen, vl auch das Datum, falls das möglich ist.
Im Hauptscreen soll dann die Temperatur 1, Temperatur 2, Temperaturdifferenz - Einstellung, Pumpe Ein/Aus angezeigt werden. Dann ein Feld für den Handbetrieb Ein/Aus und ein Feld für Setup. Nice to Have wäre dann noch ein Feld für “Topwerte”.

Wenn man das Feld Handbetrieb berührt, sollte die Pumpe immer eingeschaltet werden, beim nochmaligen drauftippen soll die Pumpe aus sein, und bei erneutem tippen wieder Automatikbetrieb.

Im Feld Setup möchte ich gerne die Mindesttemperatur Fühler 1 einstellen können. Ab dieser Temperatur soll die Automatik erst anfangen zu arbeiten. Weiters ein Feld für die Temperaturdifferenz und ein Feld für die Hysterese. Werte veränderbar durch einen eingeblendeten Pfeil “Rauf” und “Runter” um die Temperaturen auf 0,1*C schritten zu ändern. Eventuell noch ein Feld für die Beleuchtungsdauer in Sekunden schritten.

Nice to Have - Feld Topliste: Dort sollte die höchste gemessene Temperatur Fühler 1 und höchste gemessene Temperatur Fühler 2 angezeigt werden. Am besten mit Uhrzeit und Datum. Aber wie gesagt, dass ist jetzt überhaupt nicht wichtig und wäre nur als Extra zu verstehen.

Das Aufzeichnen auf die SD Karte wäre auch ein Nice to have, ist aber auch nicht soooo wichtig, da ich die Daten dann ja nur auslesen könnte, wenn ich die Karte entnehme und das wird wahrscheinlich nicht so oft der Fall sein.

Was auch noch wichtig wäre, dass die LCD Hintergrundbeleuchtung nach 2 Minuten ausschaltet. Wenn man den Screen berührt sollte sie wieder eingeschaltet werden.

So das wäre es jetzt einmal alles gewesen. Ich hoffe das ist überhaupt möglich mit dem Arduino und würde mich freuen, wenn ihr mir dabei helfen könntet.

Hier noch ein Video zum Screen selbst:

lg
Daniel

arduino_89: Was auch noch wichtig wäre, dass die LCD Hintergrundbeleuchtung nach 2 Minuten ausschaltet. Wenn man den Screen berührt sollte sie wieder eingeschaltet werden.

Da musst du aufpassen. Das geht standardmäßig nicht bei allen Displays. Meistens ist die Beleuchtung fest verdrahtet. Ich habe ein 3,2" Shield so umgebaut, dass es geht. Aber dazu muss man an den Vorwiderstand kommen und einen Transistor einbauen.

Bei dieser Lib ist eine Beleuchtungssteuerung nicht dabei: https://github.com/Smoke-And-Wires/TFT-Shield-Example-Code/blob/master/SWTFT-Shield/SWTFT.h Das wird Software technisch sehr wahrscheinlich nicht gehen.

Bei der RTC, greif bitte zur DS3231. Die DS1307 sind i.d.R. sehr ungenau.

Wow, das ging aber schnell. Danke schonmal für deine Antwort.

Ich dachte eigentlich, dass man die Hintergrundbeleuchtung über einen Pin, der direkt mit dem LCD verbunden ist, ein und ausschaltet. Damit müsste das über die software relativ einfach gehen. Aber wenn die Beleuchtung, so wie du schreibst, direkt verbunden ist, dann lass ich es erstmal dabei. Es wäre jetzt nicht das wichtigste. Und einen Transistor einbauen wird jetzt für mich auch nicht das Problem sein. Aber das möchte ich dann eher erst am Schluss angehen, wenn der Rest funktioniert. Habe gerade nochmal mein Display angeschaut, bei den Pins steht nirgends "backlight" oder so etwas dabei. Anscheinend wird die Beleuchtung wirklich nicht so angesteuert, wie ich dachte. Danke schon einmal für den Hinweis.

Ok, sehr gut, dann werde ich mir die DS3231 holen.

Hättest du schon eine Idee, wie man das alles umsetzen kann?

Vielen Dank

Ich habe so ein Menu mit mehreren Untermenüs für diverse Anzeigen und Einstellungen für eine Heizungsteuerung halbweg am Laufen (auf einem 3,2" mit UTFT). Das ist aber nicht wirklich trivial. Ich habe es wahrscheinlich nicht am vernünftigsten gemacht, aber man braucht schon einiges an Code dafür. Da deshalb schnelle und allgemeine Tips zu geben ist etwas schwierig. Außerdem gibt es mehrere Wege das zu machen. Meine Version ist sicherlich nicht das Beste, da ich das auch zum ersten mal gemacht habe.

Am besten du fängst erst mal klein an und erweiterst das dann. Die ganzen reinen Anzeige Element sind kein Problem. Das geht auch nicht viel anders wie auf character LCDs. Das sollte das erste sein was du machst. Einstellungen können da erst mal fest im Programm oder auf SD Karte sein. Bei den Buttons fang mal mit einem Button an und steigere dich dann.

Ich habe für jedes Untermenü ein struct aus den Eingabewerten und dann nochmal die eigentlichen Variablen extra. Dann ändere ich erst mal die Werte im struct und erst wenn man OK drückt wird der Wert wirklich übernommen. So schlägt sich nicht jede Änderung sofort auf die Steuerung aus und es läuft alles weiter während man editiert. Das kostet aber auch das doppelte an Speicher für die Variablen.

Was SD betrifft: die Einstellungen müssen ja auch irgendwo gespeichert werden wenn der Strom weg ist. EEPROM ist natürlich eine Möglichkeit. SD Karte ist aber auch sehr bequem. Auch weil man die Einstellungen dann auch so einfach editieren kann ohne dass man ein Menü hat.

Was auch der Fall ist: auf dem UNO bekommst du eventuell mit dem Speicher an die Grenzen (sowohl was das Flash als auch das RAM betrifft). Erst mal auf dem UNO anfangen wird aber am vernünftigsten sein, dann siehst du auch wie groß es wird. Umsteigen kann man immer noch.

Hey, danke für deine Antwort.
Das wäre ja dann im Prinzip das was ich gerne hätte. Aber ok, ich habe mich jetzt mal damit beschäftigt und den ganzen Tag nur “rumgespielt”.
Hab inzwischen schon meinen Homescreen so halbwegs fertig gestellt.
In meinem Setupscreen (vom Display dann) habe ich nur mal eine Überschrift und einen Text für “zurück zum Homescreen” inkl. Rechteck usw. angelegt.
Wollte dann vom Homescreen auf den Setupscreen “touchen”, funktionierte zuerst gar nicht. Nach 3 Stunden schafte ich wenigstens einen sprung in die Schleife. Und nach einer weiteren Zeit klappte es auch mit der Grafik vom Setupscreen, der mir dann auch am Display angezeigt wurde. Nun wollte ich nur noch beim berühren des Homescreen Feldes wieder zurück zum Homescreen hüpfen. Das klappte leider gar nicht.
Hab dann vieles versucht, bis es endlich klappte, aber nur laut dem Serial Monitor. Also ich sehe jetzt meinen Homescreen, wenn ich auf Hilfe oder Handbetrieb tippe, sehe ich im Serial Monitor auch, dass ich die Felder angetippt habe. Habe extra die Serial Ausgabe in der Programmierung eingebaut dafür. Wenn ich auf Setup gehe, dann sagt mir der Serial Montor auch, dass ich in der Setupschleife bin, aber das Display zeigt den Setupscreen nicht mehr an. Habe schon so vieles ausprobiert.

Und vor dem rumprobieren, als das mit der Anzeige im Setupscreen geklappt hat, hatte ich Probleme mit dem Touchscreen. Dauernd kamen falsche, negative Koordinaten über den Serial Monitor, und selbst wenn ich wo getippt habe, kamen immer die gleichen. Hab das versucht zu bereinigen, aber es klappte nicht, oder zumindest nur so wie es jetzt ist.

Also noch mal zusammengefasst. Es funktioniert eigentlich wie es soll. Der Setup-Buttondruck wird erkannt. Die Schleife für die Grafik wird aufgerufen, der HomeButton wird generiert und wenn ich ich blind draufgehe, dann wird er auch registriert und ich komm zurück zum mainscreen. NUR der Setupscreen wird im Display nicht angezeigt.

Ich hoffe ihr könnt mir dabei helfen.

Hier der Code

#include <Adafruit_GFX.h>    // Core graphics library
#include <SWTFT.h> // Hardware-specific library
#include <TouchScreen.h>




#define YP A2  // must be an analog pin, use "An" notation!
#define XM A1  // must be an analog pin, use "An" notation!
#define YM 6   // can be a digital pin
#define XP 7   // can be a digital pin

#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);



// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define Pumpenrelais 13
#define Ein LOW
#define Aus HIGH

SWTFT tft;

#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;
float temp1; // Temperatur 1 Solar
float temp2; // Temperatur 2 Pool
float tempdif; // Temperaturdifferenz zwischen temp1 und temp2
float tempdifein; // Temperaturdifferenz ab der die Pumpe eingeschaltet wird
float hysterese; // Temperaturdifferenz ab der die Pumpe wieder ausgeschaltet wird
int Handbetrieb = 0; // Handbetriebvariable, 0=Auto, 1=Ein, 2=Aus
unsigned long prev;
int interval = 10000;
int merker = 0;

void setup(void) {
  Serial.begin(9600);
  Serial.println(F("Poolsteuerung"));
  
  tft.reset();
  
  uint16_t identifier = tft.readID();

  Serial.print(F("LCD driver chip: "));
  Serial.println(identifier, HEX);
    

  tft.begin(identifier);

  tft.fillScreen(BLACK);
 
  prev = millis();
}

#define MINPRESSURE 10
#define MAXPRESSURE 1000

unsigned long mainscreen() {
  Serial.println("Ich bin jetzt in der Mainscreen Funktion");
  tft.fillScreen(BLACK);
  tft.setCursor(30,10);
  tft.drawRect(20,0,200,30,WHITE);
  tft.setTextColor(WHITE); tft.setTextSize(2);
  tft.println("Pumpensteuerung");
  tft.setTextColor(YELLOW); tft.setTextSize(1);
  tft.setCursor(0,70);
  tft.print("Temperatur 1:");
  tft.setCursor(130,70);
  tft.print(temp1, 2);
  tft.drawCircle(165, 70, 2, YELLOW);
  tft.setCursor(170,70);
  tft.println("C");
  tft.setTextColor(BLUE);
  tft.setCursor(0,80);
  tft.print("Temperatur 2:");
  tft.setCursor(130,80);
  tft.print(temp2, 2);
  tft.drawCircle(165, 80, 2, BLUE);
  tft.setCursor(170,80);
  tft.println("C");
  tft.setTextColor(YELLOW);
  tft.setCursor(0,90);
  tft.print("Temperaturdifferenz:");
  tft.setCursor(130,90);
  tft.print(tempdif, 2);
  tft.drawCircle(165, 90, 2, YELLOW);
  tft.setCursor(170,90);
  tft.println("C");
  tft.setTextColor(BLUE);
  tft.setCursor(0,100);
  tft.print("Einschaltdifferenz");
  tft.setCursor(130,100);
  tft.print(tempdifein,2);
  tft.drawCircle(165, 100, 2, BLUE);
  tft.setCursor(170,100);
  tft.println("C");
  tft.setTextColor(YELLOW);
  tft.setCursor(0,110);
  tft.print("Hysterese:");
  tft.setCursor(130,110);
  tft.print(tempdif, 2);
  tft.drawCircle(165, 110, 2, YELLOW);
  tft.setCursor(170,110);
  tft.println("C");
  tft.setCursor(10,150);
  tft.setTextColor(WHITE); tft.setTextSize(3);
  tft.print("SETUP");
  tft.drawRect(5, 140, 100, 40, WHITE);
  tft.setCursor(130,150);
  tft.print("HILFE");
  tft.drawRect(120,140,110,40, WHITE);
  tft.setCursor(10,220);
  tft.print("Handbetrieb");
  tft.drawRect(5,210,210,40, WHITE);

  
  
  // we have some minimum pressure we consider 'valid'
  // pressure of 0 means no pressing

}
void schalten()
{ if (Handbetrieb = 0){ //Handbetrieb ist auf Automatik
  if (tempdif>tempdifein)  
    digitalWrite(Pumpenrelais,Ein);
  else if (tempdif<hysterese)    
    digitalWrite(Pumpenrelais,Aus);
  else ; // sonst nichts schalten, Schaltzustand beibehalten  
  }
  if (Handbetrieb = 1) {   //Handbetrieb ist auf Ein
    digitalWrite(Pumpenrelais,Ein);
  }
  if (Handbetrieb = 2) {   //Handbetrieb ist auf Aus
    digitalWrite(Pumpenrelais,Aus);
  }
}

unsigned long setupscreen(){
  Serial.println("Ich bin jetzt im Setupscreen");
  tft.fillScreen(BLACK);
  tft.setCursor(30,10);
  tft.drawRect(20,0,200,30,WHITE);
  tft.setTextColor(WHITE); tft.setTextSize(2);
  tft.println("Setupscreen");
  tft.setTextColor(YELLOW); tft.setTextSize(2);
  tft.setCursor(70,70);
  tft.print("Homescreen");
  tft.drawRect(65, 65, 140, 40,WHITE);
    }

void loop()
{
  // Recently Point was renamed TSPoint in the TouchScreen library
  // If you are using an older version of the library, use the
  // commented definition instead.
  // Point p = ts.getPoint();
  TSPoint p = ts.getPoint();
  // if sharing pins, you'll need to fix the directions of the touchscreen pins
  //pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  //pinMode(YM, OUTPUT);
  temp1 = 20.6756756;
  temp2 = 24.8956756;
  tempdif = 5.0065756;
  hysterese = 2.56756856;
  tempdifein = 3,456547;
  merker = 0;
  if((millis() - prev) > interval){
  prev = millis();
  Serial.println("Ich bin jetzt in der Schleife");
  mainscreen();
  Serial.println("Ich verlasse jetzt die Schleife");}
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
    p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));

  if(p.x > 5 && p.x < 105 && p.y > 140 && p.y < 180){
    merker=0;
    while(merker < 1){
     if((millis() - prev) > interval){
  prev = millis();
  Serial.println("Ich bin jetzt in der Setupscreenschleife");
  setupscreen ();
  Serial.println("Ich verlasse jetzt die Setupscreenschleife");}
  TSPoint p = ts.getPoint();
    if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
    p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
      Serial.print("Koordinaten x:");
  Serial.print(p.x);
  Serial.print("   y:");
  Serial.println(p.y);
  if (p.x>65 && p.x<205 && p.y>65 && p.y<105){
    Serial.println("Button gedrückt");  
    merker=1;}}}}
  if(p.x>120 && p.x<230 && p.y>140 && p.y<180){
    Serial.println("Hilfe gedrückt");
  }
  if (p.x>5 && p.x<215 && p.y>215 && p.y<250){
    Serial.println("Handbetrieb gedrückt");
  }
  }
  }

Hey Leute,

bin jetzt schon etwas weiter, mach das Menü jetzt komplett anders. Habe aber erneut eine Frage.

Und zwar mein Display inkl. Touchscreen und SD Karte belegt schon die meisten I/O's vom Arduino. Hätte nur noch A5 frei und von den digitalen ports 0 und 1, welche aber nicht verwendet werden sollen. Da ich aber die Temperatursensoren, die RTC und das Relais auch noch anschließen möchte / muss, gehen mir die I/O's aus.

Jetzt kam mir die Idee, ein shift register zu verwenden. Nur welches? Weiters ist mir unklar, ob ich die SD Karte, die RTC und das Relais über das shift Register ansteuern kann? Das Relais geht sicher aber die anderen? Es wäre auch noch möglich, das LCD über das shift register anzusteuern, aber das wird dann glaube ich zu kompliziert. Und noch eine letzten Frage. Ist eine PWM über ein shiftregister überhaupt möglich? (Eventuell für die Hintergrundbeleuchtung)

Bin auf die Antworten gespannt :)

lg Daniel

Weiters ist mir unklar, ob ich die SD Karte, die RTC und das Relais über das shift Register ansteuern kann?

SD wird über SPI angesteuert und die RTC über I2C. Also nein.

arduino_89: Ist eine PWM über ein shiftregister überhaupt möglich?

Ja, hiermit: www.elcojacobs.com/shiftpwm/ https://www.pjrc.com/teensy/td_libs_ShiftPWM.html Schieberegister kannst du auch über den SPI Bus ansteuern. Du brauchst nur einen Pin für Chip Select.

Ansonsten gibt es auch noch I2C Port Expander wie den PCF8574

Du könntest dir aber auch einfach einen Mega zulegen. Das Display sollte auch damit laufen. Was aber auf dem Mega nicht so ohne weiteres geht ist die SD Karte, da die SPI Pins woanders liegen. Man kann aber mit der SdFat Library auch Software SPI nutzten (man muss nur eine Config Datei anpassen). Ist natürlich langsamer, aber wenn man nicht viel macht geht es auch. Das ist genau dazu gedacht um UNO Shields auf dem Mega zu verwenden.

Vielen Dank für deine Antwort.

Hmm.... hab ich mir schon gedacht, dass das nicht ganz so einfach ist mit der Porterweiterung. Ich weiß nicht, wie ich das jetzt am besten lösen könnte.

Hab hier mal eine Auflistung der verwendeten Pins von meinem Display gefunden: http://www.smokeandwires.co.nz/blog/a-2-4-tft-touchscreen-shield-for-arduino/

Also um jetzt einen I²C Bus zu machen, brauche ich 2 analoge Pins. Habe nur einen frei. Also fällt das mal weg.

Also kann ich die ganze Idee mit der RTC schon wieder vergessen :(

Aber SPI ist über ein shift register wohl auch nicht möglich.

Hmm das einzige was ich jetzt wohl machen könnte ist einen mega zu kaufen. Oder eben die ganze Steuerung nur mit dem uno + display + touchscreen + relais + den Temperatursensoren machen oder?

Die Einstellungen für die Differenztemperatur, die Hintergrundbeleuchtung und die Hysterese könnte ich im internen EEPROM machen, dann hätte ich eigentlich alles bis auf die Uhrzeit oder?

Ja. Das Shield belegt so ziemlich alles. Und dummerweise auch A4. Das ist nicht gut.

Aber SPI ist über ein shift register wohl auch nicht möglich.

Prinzipiell geht das natürlich. Was sehr wahrscheinlich nicht geht ist ShiftPWM und SD zur gleichen Zeit.

Aber SPI ist genauso wie I2C ein Bus und man kann beliebig Devices anschließen. Du brauchst nur einen freien Pin für die CS Pins der Schieberegister. Oder wenn du die SD Karte nicht verwendest, kann man wohl auch den Standard CS Pin verwenden (Pin 10).

Wenn du weder SPI weder für SD noch sonst was verwendest, sind noch Pins 10-13 frei.

Der Mega wird das jedoch das vernünftigste sein. Selbst wenn du Schieberegister an SPI hast, kannst du damit nämlich keine DS18B20 einlesen!

Ok verstehe. Aber wenn ich die Hintergrundbeleuchtung nur Ein und Aus schalten will, was mir auch schon reichen würde, dann könnte ich das schon machen oder? Sprich das Shiftregister soll dann die SD Karte, die Hintergrundbeleuchtung und das Relais ansteuern?

Wenn ja, welches Shiftregister ist dafür am besten geeignet?

Ja das mit dem Mega werde ich auch mal machen, aber zuvor möchte ich es erstmal mit dem uno soweit schaffen. Den einzigen Vorteil hätte ich mit dem Mega dann mit der RTC, die ich aber so nicht unbedingt bräuchte.

Vielen Dank lg