Der Flowgrow Aquacomp

Matz

Moderator
Teammitglied
Hallo Biotoecus (würd' ja gerne einen Namen verwenden?),
warum immer gleich so beissende Kommentare, wenn mal was nicht deiner/n Vorstellung/en entspricht?
Bisschen gechillter geht doch auch :wink: !
Schönen Abend noch,
gesendet von meinem PC aus :D
:bier:
PS.: ich versteh' von all den Abkürzungen auch nix, und vom Rest nur die Hälfte. Aber das Projekt ist doch schon mal gut und hat nach einer Strukturierung, welche ja auch angedacht ist, durchaus Potential allen die Verbindung von moderner Technik und Altbewährtem zur Arbeitserleichterung zu ermöglichen. Zwar grad jetzt noch nicht, aber nach ersten Prototypen und Verfeinerungen schon.
 

MajorMadness

Active Member
Soooo, mir war grade langweilig und Freundin ist im Bett, also ich konnte mal wieder bisschen was niederschreiben. Ich versuchs so gut wie möglich zu erklären und hoffe es ist nachvollziebar. Evt hat ja einer noch ne Idee. :flirt:

Die Lichtdimmung ist ja das so ziemlich umfangreichste und auch wichtigste des Controllers, also kommt da leider eine sehr komplexe funktion. Zuerst einmal alles was wir brauchen fürs licht und einstellen können:
Code:
typedef struct {
  boolean Active;
  float Sunrise;  //34200;    // 9:30
  float Sunset;   //77400;    //21:30
  int Min;  // Inverse Schaltung! 4095 = off
  int Max;  // Wir wollen ja nicht übertreiben, daher LED's nicht voll ausfahren
  int Dim_in;
  int Dim_out;
}LIGHT;


LIGHT light_channels[20] = { 
{ 1, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 1, get_ts(10,30,0), get_ts(19,0,0),4080, 2000, 60, 120}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),4080, 2000, 30, 45}, 
/*Das ganze 16 mal, dann 4 mal für 10V Dimmung*/
{ 1, get_ts(10,0,0), get_ts(20,0,0),10, 255, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),10, 255, 30, 45}, 
{ 0, get_ts(10,0,0), get_ts(20,0,0),10, 255, 30, 45}, 
{ 1, get_ts(10,0,0), get_ts(20,0,0),10, 255, 30, 45}
};

//Abweichung für Tageslicht basierten Verlauf Das sind quasi % werte von -100 bis +100 also mittags 10% mehr wäre LightOffset[12]=10;

int LightOffset[24]={
  0,0,0,0,0,0,
  0,0,0,0,0,0,
  0,0,0,0,0,0,
  0,0,0,0,0,0
};
Hiermit können wir alle Kanäle einzeln dimmen, tag und nacht dimmung festlegen und sogar nen verlauf. Mondphasen, wolken müssen wir anderes mal machen...

Dann, wenn der Controller einfach so läuft kommt irgendwann der Aufruf:
setLight(0); // Wir übergeben 0 damit automatisch nen Value errechnet wird
Jetzt gehts in unsere Steuermethode:
Code:
void setLight(int Value){
  boolean SetRelay=false;  
  if(Value==0){
Wir prüfen also ob es nen automatischen aufruf oder einen mit nem wert gab. Wenn wir nen wert inizialisieren, dann greift der 2te teil (weiter unten).
Nun feiern wir alle kanäle ab und setzen sie wenn nötig neu:
Code:
// TLC5940 Resetten bzw Speicher löschen
    Tlc.clear(); 
// Alle Kanäle ausrechnen und setzen
    for( int i=0;i <  16; i++){
      // Überprüfen ob wir den Kanal überhaupt einstellen sollen
      if(light_channels[i].Active==1){
         // Aktuelles PWM Level errechnen
        int c_PWM = PWM_Licht(RTC.daystamp, light_channels[i].Sunrise, light_channels[i].Sunset, light_channels[i].Dim_in, light_channels[i].Dim_out, light_channels[i].Min, light_channels[i].Max);
        // % Anpassung im Tageslichtverlauf
     // c_PWM = 3800/100*(100-15) => c_PWM = 3230
        c_PWM= int(float(c_PWM/100*(100-LightOffset[RTC.hour])));  // Aufpassen Inverse schaltung. 0 ist max 4095 Wenigste
    // Stell sicher das Relay an ist
        if(c_PWM!=0){
          SetRelay=true;
        }
        Tlc.set(i, c_PWM);
      }
    }
// Alles fertig, updaten
    Tlc.update();
:? Soweit klar? :roll: Naja wir rechnen mit der Methode
Code:
int PWM_Licht(float time, float Start, float Ende, int  Dim_in, int Dim_out, int Min, int Max){
  
    // Starten der Dimmung von Min
    if (time >= Start  && time <= Start+float(Dim_in*60)){ 
      Serial.println ("Raufdimmen");
      float s = time-Start+0.5;    // vergangene Sekunden ~1616
      int m = Min-Max;    // 135
      float f= float(Dim_in*60)/float(m);    // 3000/135 ~22
      float p = s/f;    // 1616 / 22
      int pwm = Min-int(p);
      
      return pwm;
    }
  
    // Voll an keine Dimmung
    if (time > Start+float(Dim_in*60)  && time < Ende-float(Dim_out*60)){
   	return Max;
    }
  
    // Ende der Dimmung
    if (time >= Ende-float(Dim_out*60)  && time <= Ende){
      Serial.println ("Runterdimmen");
      float s = time+float(Dim_out*60)-Ende+0.5;    // vergangene Sekunden ~1616
      int m = Min-Max;    // 135
      float f= float(Dim_out*60)/float(m);    // 3000/135 ~22
      float p = s/f;    // 1616 / 22
      int pwm = Max+int(p);
      return pwm;
    }
  
    // Der Rest
    return 0;
    
}
nen PWM Value aus und passen das dann wenn nötig dem Tagesverlauf an. Wer das nicht will der lässt LightOffset bei 0 und nix passiert.
Dann machen wir das auch nochmal für alle 10V Kanäle:
Code:
    if(light_channels[17].Active==1){
      int c_PWM = PWM_Licht( RTC.daystamp, light_channels[17].Sunrise, light_channels[17].Sunset, light_channels[17].Dim_in, light_channels[17].Dim_out, light_channels[17].Min, light_channels[17].Max);
        c_PWM= int(float(c_PWM/100*(100+LightOffset[RTC.hour])));
        if(c_PWM!=0){
          SetRelay=true;
        }
      analogWrite(DIM2, c_PWM);
    }
    if(light_channels[18].Active==1){
      int c_PWM = PWM_Licht( RTC.daystamp, light_channels[18].Sunrise, light_channels[18].Sunset, light_channels[18].Dim_in, light_channels[18].Dim_out, light_channels[18].Min, light_channels[18].Max);
        c_PWM= int(float(c_PWM/100*(100+LightOffset[RTC.hour])));
        if(c_PWM!=0){
          SetRelay=true;
        }
      analogWrite(DIM3, c_PWM);
    }
    if(light_channels[19].Active==1){
      int c_PWM = PWM_Licht( RTC.daystamp, light_channels[19].Sunrise, light_channels[19].Sunset, light_channels[19].Dim_in, light_channels[19].Dim_out, light_channels[19].Min, light_channels[19].Max);
        c_PWM= int(float(c_PWM/100*(100+LightOffset[RTC.hour])));
        if(c_PWM!=0){
          SetRelay=true;
        }
      analogWrite(DIM4, c_PWM);
    }
Hier habe ich glaube ich noch nen fehler drin, weil beim TLC in Verbindung mit KSQ ist 4095 wie aus und 0 wie voll an. Bei 10V ist aber 255 voll an. Muss da also wohl nochmal dran. Grade nur bisschen Müde...
Am Ende machen wir dann das ganze noch einmal falls wir die Methode von hand aufrufen, sprich wenn wir nen festes Value vergeben:
Code:
  }else{
    Tlc.clear(); 
    for( int i=0;i <  16; i++){
      if(light_channels[i].Active==1){
        Tlc.set(i, Value);
      }
    }
    Tlc.update();
    
    if(light_channels[16].Active==1){
      analogWrite(DIM1, Value);
    }
    if(light_channels[17].Active==1){
      analogWrite(DIM2, Value);
    }
    if(light_channels[18].Active==1){
      analogWrite(DIM3, Value);
    }
    if(light_channels[19].Active==1){
      analogWrite(DIM4, Value);
    }
    // Stell sicher das Relay an ist
      SetRelay=true;
  }
  // Relays noch schalten falls das Nötig war...
  switchLight(SetRelay);  
}
die switchLight() macht eigentlich nix andere als kurz schauen ob relay an ist und wenn nicht, an schalten (oder aus).
Code:
void switchLight(boolean setHigh){
    //Müssen wir Relays schalten?
    
    // Wenn wir schalten sollen und RELAY HIGH/aus ist
    if(setHigh==true   && digitalRead(RELAY2)==HIGH){ 
        digitalWrite(RELAY2,LOW);
        
    }
    // Wenn wir schalten sollen UND RELAY LOW/an ist
    else if(setHigh==false && digitalRead(RELAY2)==LOW){
        digitalWrite(RELAY2,HIGH);
    }
}

Macht das irgenwie sinn was ich da grade geschrieben habe oder fällt jemanden was auf der schonmal programmiert hat oder mein wirrwarr versteht? Kompilieren tut er das, aber testen kann ich es halt grade nicht. :down: Prototypen sind noch in Produktion.... :keule:
 

MajorMadness

Active Member
Matz":lx5xg9xy schrieb:
...
und hat nach einer Strukturierung, welche ja auch angedacht ist, durchaus Potential allen die Verbindung von moderner Technik und Altbewährtem zur Arbeitserleichterung zu ermöglichen. Zwar grad jetzt noch nicht, aber nach ersten Prototypen und Verfeinerungen schon.
Du solltest mal meinen Schreibtisch sehen und in der Firma die Brainstorming Wand :lol: :pfeifen: :gdance: :irre: Dagegen ist das hier die Strukturierung in Person. :eek:
Ne ohne scherz, mein Chef hat mal gesagt ein komplexes Project machtst du immer 2 mal:
1. Du schreibst alles nach vorgaben und mit bestehenden daten, korriegierst, fixed alles, debuggst es und dann
2. du löschst alles und schreibst es neu. Nur so haste sauberen und pflegbaren code...
Naja, das Projekt hier ist schon bei V3 vom Code her. 2 Versuche hat mich der gekostet der auf meinem Arduino läuft in meine rAbdeckung und jetzt kommt dieser mit den Vorschlägen und anregungen der anderen User zusammen. Klar das da die Strukturierung und übersicht vollends verlohren geht. Ich find es aber toll welchen Rückhalt auch solche Projekte hier in der Comm bei den Mods und Admins haben und den meisten Usern.
Da macht das Coden Spaß und ist ne willkommene abwechslung zum Alltagsgeschäft von Webseiten bauen, Rechenkernels erweitern und irgendwelchen Apps entwickeln... :keule:
 

gartentiger

Active Member
Hi Moritz,

lauf aber nicht Gefahr, zuviel mit der Steuerung machen zu wollen :D

Wenn das Menü zum Schluss eher schlank ausfällt, wäre mir das sehr recht. Will das ja auch noch irgendwie bedienen ohne jedesmal ins "Handbuch" guggn zu müssen :pfeifen:

Wäre es möglich, das man z.B. 2 oder 3 verschiedene Beleuchtungssimulationen im Code hinterlegt und im Display einfach nur über + und - die jeweilige Simulation an seine Bedürfnisse anpasst, ähnlich im Radio die Bedienung des Equalizer? Und das dann intern für die unterschiedlichen Dimm-Versionen gleich schaltet?

Könnte man ja über ne interne Abfrageroutine umsetzen?

Also so in der Art:

Menü:
Dimmung---> Kurve 1
---> Kurve 2...

Intern :
Dimmung---> 0-10V [true/false]
---> PWM [true/false]

0-10V [true]--->Sim_01
0-10V [false]--->PWM [true/false]
PWM [true]--->Sim_02
PWM [false]---> ...

Dadurch wäre schonmal die richtige Dimmart eingestellt und bei Auswahl einer Kurve muss dann nur noch die korrekte Beschreibung aufgerufen werden. Im Grunde hast du das ja so in der Art ne Seite vorher beschrieben. Nur das schlanke Menü fehlt mir dazu noch :eek:ps:

Ansonsten aber ist mir noch eine Sache eingefallen.

Besteht die Möglichkeit ne einfache softwareseitige Kindersicherung reinzupacken?

Alternativ käme eine Klappe dran, die ich dann in *hübsch* machen müsste.


Noch was: Hab hier noch nen Smartphone mit 3,7" Touchdisplay und defektem Rahmen rumliegen. Funzt noch einwandfrei, aber ne Rep würde den Wert des Handys übersteigen. Ließe sich sowas generell für ne spätere Version einsetzen?

Also "Arduino 2.1 touch me"?

lg Chris
 

Skibbie

Member
MajorMadness":1dp2d8c6 schrieb:
Macht das irgenwie sinn was ich da grade geschrieben habe oder fällt jemanden was auf der schonmal programmiert hat oder mein wirrwarr versteht?

C verstehe ich zwar sehr gut, aber ich kann dir da gerade ziemlich schlecht Folgen, da mir die ganzen Bezeichnungen nicht so viel sagen. Kannst du vielleicht einmal den kompletten Code uppen?
Es wird mir leichter fallen dir zu folgen, wenn ich die Hardware hier vor mir habe und dann auch genau weiß wann was passieren soll. Bin mir nämlich gerade nichtmal im klaren, wie du 0-10V hardwaremäßig löst...
 

Fisch15

New Member
Hi Moritz,

Du hast meinen Respekt wenn ich sehe wie du die Scripte erstellst.
Auch wenn ich so langsam nicht mehr durchblicke. :(

Das was Chris geschrieben hat mit dem Touchscreen find ich gut.. :pfeifen:

Bin gespannt auf den Prototyp :gdance:
 

MajorMadness

Active Member
Es geht vorran! :gdance:
Heute Packet mit 15 Wasserdichten Temperatur Sensoren bekommen und da mir noch nix sinnvolles mit dem Menü eingefallen ist mal schnell das erste Keypad gelötet und getestet. Es klappt :grow:
(Gesammtgröße: 80x55mm, man könnte es aber auch auf 55x50 verkleinern :lol: )
 

Anhänge

  • 2013-03-14 17.49.55.jpg
    2013-03-14 17.49.55.jpg
    309 KB · Aufrufe: 337

Biotoecus

Active Member
oophaga":3g8z7vhx schrieb:
@bioerrectus oder so: wenn man keine ahnung hat, einfach mal :censored:

hi ooohstoehner oder so, jepp ich werde meine Fresse nun halten.

Und entschuldigung, dass ich meine Unzulänglichkeiten formulierte.
 

Matz

Moderator
Teammitglied
Hallo Biotoecus :),
"Fresse halten" fände ich schade, sehr viele deiner Beiträge haben ja Hand und Fuß!
Ich fänd's halt gut, wenn's nicht ab und zu "mit dir durchgeht" :roll: ; bissl gechillter halt und den beissenden (manchmal fast schon bösen) Sarkasmus einfach weglassen :wink: !
In diesem Sinne einen schönen Abend noch,
bis bald,
:bier:
PS.: die Erwiderung von oophaga war auch NICHT die feine englische Art!
 

MajorMadness

Active Member
rwerene81":gz1ezvlo schrieb:
Ach... Mit echten Knöpfen? :? :

Kein kapazitiver Touchscreen? :hechel:

Kleiner Scherz.

LG René
Irgendwann ibts auch touch ;) nur zum testen uss ich erstmal selber eins haben.
Wer schenkt mir das 3,2" touch shield?
Kein kleiner scherz. :lol: :bier:
 

oophaga

Member
hey moritz,
keypad is ja schonmal geil :thumbs:
gibts da schon ein plan für das optische drumherum?
hätte auch connections um etwas lasern zu lassen.. wenn alle das pad in gleicher größe haben, das wir auch auf ne stückzahl von 10 kommen, könnt ich mir da was schönes für display und pad aus gebürstetem edelstahlblech vorstellen :pfeifen:
 
Ähnliche Themen
Themenersteller Titel Forum Antworten Datum
Ewald Flowgrow Forum Uhr - der Zeit voraus? Kein Thema - wenig Regeln 2
HaManFu HaManFu grüßt den Rest der Welt@Flowgrow Mitgliedervorstellungen 15
Tobias Coring Der Flowgrow Dünger ist da ;) Nährstoffe 127
J Tropica Dünger in der Einfahrphase Nährstoffe 16
B4m8i Aquarium in der Arbeit - Proxima 250 ohne allem Aquarienvorstellungen 0
E Wasserfluss in der Cristalprofi I-Linie (Innenfilter) Technik 6
S Verzweifel bei der Dosierung von Nährstoffen Nährstoffe 24
Wuestenrose Entkarbonisierung – was passiert mit der Leitfähigkeit? Kein Thema - wenig Regeln 11
F Pflanzen wachsen schlecht seit Umstellung der Beleuchtung Erste Hilfe 20
M Krasses Wachstum nach Auslichtung der Anubias Nana Aquarienvorstellungen 12
C Schädlinge - Nützlinge im Nanoaquarium - Hilfe bei der Bestimmung Erste Hilfe 1
C Hallo, ich bin in der "Findungsphase" Mitgliedervorstellungen 12
Andrej Neue Bewohner an der Oberfläche Kein Thema - wenig Regeln 2
E Was kommt nach der JBL Solar Natur LED? Kein Thema - wenig Regeln 2
M Wachsen Pflanzen langsamer und schlechter während der Einfahrphase? Pflanzen Allgemein 1
R Woher kommt der üble beißende Gestank? Erste Hilfe 12
P Erfahrung mit der Fa. WIO. Äste ins Aquarium - wässern Kein Thema - wenig Regeln 14
F Hallo aus der Voreifel Mitgliedervorstellungen 3
Pavelix Grüße aus der Sächsischen Schweiz Mitgliedervorstellungen 3
J Neuer aus der Eifel Mitgliedervorstellungen 1

Ähnliche Themen

Oben