Hallo zusammen, ich bastel gerade eine Aquariumbeleuchtung für meinen Schwager. Netz- und Steuerplatine sind fertig und funktionieren auch einwandfrei. mit dem Programm welches auf dem Atmega 168PA-PU von Atmel läuft habe ich aber noch ein wenig Probleme. Ich hoffe es kann mir jmd einen Tipp geben was ich ändern muss, damit die Beleuchtungsphasen mit der entsprechenden Helligkeit leuchten. Wie ihr aus dem pdf file für die Beleuchtungsphase entnehmen könnt, gibt es eine Art "Sonnenaufgang" mit 12 roten LEDs die von 08:00 Uhr bis 08:30 Uhr von 0% auf 50% Helligkeit gesteuert werden (von 0 auf 128 bit) mit entsprechenden delay funktionen zwischen den Erhöhungen. Dies funktioniert auch Tadellos. Jedoch wenn die 50% Helligkeit der 12 roten LEDs erreicht sind, schalten sich auch alle 12 blauen und 90 weißen LEDs zeitgleich ein auf 50% oder 100%... Jedoch sollte blau von 08:30 Uhr bis 09:00 Uhr auch wie rot innerhalt dieser halben Stunde von 0% auf 50% Helligkeit geregelt werden. Weiß in diesem Fall von 0% auf 12,5%. Anbei findet ihr noch den Schaltplan Screenshot von Eagle, 2 Bilder des Profils worauf die LEDs befestigt sind, sowie Netz- und Steuerplatine. Das ganze bekommt natürlich noch ein Gehäuse ;) Die Beleuchtungsphasen sind dem pdf zu entnehmen und die 2 Screenshots des Arduino Sketches natürlich nicht zu vergessen. PS. "for" Schleifen habe ich auch schon ausprobiert, jedoch hat dies nicht funktioniert. Ich hoffe es kann mir jmd mit der Programmierung des uC helfen. Grüße beavis2809
Die Beleuchtungsphase vergessen zu uppen :)
Die Lichtausbeute reicht aber nur für Plastikpflanzen. Grüsse
Der ganze Ansatz mit den delays taugt nix. Beschäftige dich erst mal damit, wie du eine 24 Stunden Uhr hinkriegst. Die zum jeweiligen Zeitpunkt gültige Helligkeit jeder LED_Gruppe wird dann aus der Zeitinformation errechnet, indem du dir Formeln überlegst, die genau das leisten. Die skuzessive Dimmung ergibt sich dann ganz von alleine, weil ja die Uhrzeit sich ändert und deine Formeln dann eben für den nächsten Zeitpunkt andere Helligkeitswerte errechnen. PS: die ganze Rechnerei vereinfacht sich, wenn du die Uhrzeiten erst mal in 'Sekunden ab Mitternacht' ausdrückst. Dann ist das ganze Problem im Grunde nicht mehr als ein Absuchen einer Tabelle, das feststellen der Parameter für einen Dreisatz aus dieser Tabell, Dreisatzrechnen und LED auf die errechnete Helligkeit stellen. Aber alles beginnt mit einer Uhr
Ah ok. Dann meinst du sowas wie diese RTC hier im Anhang oder? Hmm dann schau ich mal was ich da für Formeln nutzen könnte, die dann zur entsprechenden Uhrzeit die Helligkeit der LEDs berechnen und ausgeben. Danke dir kbuchegg
Guckmal hier : http://www.klytronic.de/website/shop-bausaetze/led-steuerung/mini-rgb-fader-v1x/aquarium-programm.html
Danke für die Hilfe Thomasderbastler, aber ich werde mich erstmal an dem Vorschlag von kbuchegg versuchen.
Sven M. schrieb: > Ah ok. Dann meinst du sowas wie diese RTC hier im Anhang oder? > Hmm dann schau ich mal was ich da für Formeln nutzen könnte, die dann > zur entsprechenden Uhrzeit die Helligkeit der LEDs berechnen und > ausgeben. Die blaue Kurve gibt den zu realisierenden Dimmverlauf an. H1 ist die Heligkeit, die die LED vor dem Zeitpunkt 'von' hat. H2 ist die Helligkeit, die die LED nach dem Zeitpunkt 'bis' haben soll. Hast du jetzt einen Zeitpunkt, der zwischen 'von' und 'bis' liegt, dann kannst du die 'Hgesucht' ausrechnen. Jeweils 2 grüne Linien (hell/dunkel) zusammen mit der blauen Schräge bilden ein Dreieck. Da die beiden Dreiecke gleiche Winkel haben, sind sie nicht einfach irgendwelche Dreiecke, sondern 'ähnliche Dreiecke' (Mathe-Ausdruck). D.h. es gilt der Strahlensatz bis - von H2 - H1 ----------- = ---------------- jetzt - von Hgesucht - H1 (wenn du mit der Zeichnung vergleichst, sind die einzelnen Teilausdrücke einfach nur die grünen Linien) nach Hgesucht auflösen, den jeweiligen Zeitpunkt und die restlichen 3 bekannten Werte einsetzen, noch H1 addieren (weil du ja Hgesucht in Bezug auf H1 berechnet hast) und du hast die Helligkeit, die zum Zeitpunkt 'jetzt' einzustellen ist. Alles was du brauchst ist eine Tabelle, die nach den Zeiten geordnet ist. In dieser Tabelle suchst du raus, welche Tabellenzeile zu der aktuellen Uhrzeit gültig ist, in den zugehörigen Spalten dieser Zeile findest du dann die restlichen Werte und hast damit alles um die zum Zeitpunkt 'jetzt' gültige Helligkeit zu berechnen.
Übrigens: Spitzen Idee, Programmcode als Bild zu posten. Da kann man sich so wunderbar in einer Antwort darauf beziehen.
Karl Heinz Buchegger schrieb: > Übrigens: Spitzen Idee, Programmcode als Bild zu posten. Da kann man > sich so wunderbar in einer Antwort darauf beziehen. Lieber das Bild in ein Word Dokument einfügen.
Problem gelöst. Wollte nur schnell Bescheid sagen, dass ich meinen Fehler in der Programmierung gefunden habe. Danke für die Vorschläge mit einer Uhr also RTC um die entsprechenden Werte zur bestimmten Uhrzeit zu berechnen mit Formeln etc. Da ich nur eine Kleinigkeit an meinem Programm ändern musste und es nun so läuft wie ich es haben möchte (Sonnenaufgang, Sonnenuntergang, Mondaufgang, Monduntergang und natürlich das Tageslicht) werde ich das Projekt nicht jetzt noch auf eine Uhr umstellen sondern belass es bei meinen "delay-skills" welche mich Zeit und Nerven gekostet haben, sodass innerhalb einer halben Stunde eine bestimmte Farbe von 0% auf 50% gefadet wird etc. Für alle die eventuell auch einen solchen Anfängerfehler haben, wie ich ihn nenne da ich mich erst seit ein paar Wochen mit der Arduino Programmierung beschäftige, werde ich hier nun kurz erläutern woran es lag. Problem: Nach 30min faden die roten LEDs von 0% auf 50% --> alles gut geklappt Dann geht schlagartig blau und weiß auch auf 50% (sollte eigentlich faden um die Fische nicht zu schocken!) Das Problem lag an der Deklarierung der Farben (Stufen von 0-255) Nur 1x die value der LEDs deklariert mit //int led_val = 0; dann rot innerhalb von 30min gefadet //while(led_val != 128) { analogWrite(rot,led_val); led_val++; delay(14060.93749992); --> jetzt ist die LED value schon auf 128 also 50% dann //while(led_val != 128) { analogWrite(blau,led_val); --> somit war blau, wie auch weiß (auch im Sketch vorhanden) sofort auf 50% Lösung: Für jede LED Farbe eigene values deklarieren. //int led_val_rot = 0; int led_val_blau = 0; int led_val_weiss = 0; :) PS: Für das nächste Projekt werde ich wohl auf eine RTC zurückgreifen um solche Fehler zu vermeiden. Grüße beavis2809
Hallo, da die Aquariumsteuerung zeitlich nicht exakt läuft, habe ich mir ein DS1307 Modul besorgt. Programmcode und Funktion ist einwandfrei. 17:56:15 6/3/13 Day_of_week:1 17:56:16 6/3/13 Day_of_week:1 usw. Jetzt bin ich dabei die Uhrzeit in Sekunden umzurechnen, da ich mit Hilfe von Arrays immer zu bestimmten Sekunden die Helligkeit verschiedenfarbener LEDs erhöhen oder senken möchte. Mit der Formel für die aktuelle Minute und Sekunde habe ich keine Probleme, jedoch macht mir das mit den Stunden einen Strich durch die Rechnung. Hier der Programmcode: void loop() { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; unsigned long neuesecond, neueminute, neuehour; unsigned long neuesmh; getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); Serial.print(hour, DEC); Serial.print(":"); Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC); Serial.print(" "); Serial.print(month, DEC); Serial.print("/"); Serial.print(dayOfMonth, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" Day_of_week:"); Serial.println(dayOfWeek, DEC); neuesecond = second; neueminute = minute*60; neuehour = hour*3600; neuesmh = neuesecond+neueminute+neuehour; Serial.print(neuesecond, DEC); Serial.println(" "); Serial.print(neueminute, DEC); Serial.println(" "); Serial.print(neuehour, DEC); Serial.println(" "); Serial.print(neuesmh, DEC); Serial.println(" "); delay(1000); } und das hier zeigt mein serieller Monitor. 18:7:5 6/3/13 Day_of_week:1 5 420 4294966560 4294966985 18:7:6 6/3/13 Day_of_week:1 6 420 4294966560 4294966986 Gibt es einen Trick oder vllt einen anderen Datentyp? Wenn ich statt "unsigned long" nur "long" deklariere, erhalte ich folgendes. 18:8:42 6/3/13 Day_of_week:1 42 480 -736 -214 18:8:43 6/3/13 Day_of_week:1 43 480 -736 -213 Bitte um Hilfe.
> neuehour = hour*3600; Am Beispiel 19 Uhr 19 * 3600 ergibt 68400 und das ist zu groß für einen unsigned int (oder auch einen int). Die Tatsache, dass du das Ergebnis einem unsigned long zuweist, ist dabei völlig unerheblich. C++ (genau wie C) funktioniert nicht so! Du hast eine arithmetische Operation a op b Wenn es darum geht zu entscheiden, wie die Operation op zu realisieren ist, in welchem Wertebereich die Operation durchgeführt wird, dann sind ausschliesslich und nur die Datentypen von a und b relevant, nicht jedoch, was mit diesem Ergebnis weiter geschieht! hour ist bei dir ein byte (also ein unsigned char) 3600 ist ein int. Damit wird die Multiplikation im Zahlenbereich int durchgeführt. Und das läuft nun mal über! FAQ: Datentypen in Operationen
Vielen Dank Karl Heinz Buchegger! ich habe einfach alle bytes durch unsigned long ersetzt. Ob das jetzt Sinn macht oder ob das Programm jetzt größer geworden ist, spielt für mich keine Rolle. Aber ich danke dir, dass du mir den Fehler in meinem Code gezeigt hast. Danke
Sven M. schrieb: > Vielen Dank Karl Heinz Buchegger! > > ich habe einfach alle bytes durch unsigned long ersetzt. Das war doch schon wieder Quatsch. Das macht ja doch auch keinen Sinn, wenn du da völlig sinnlos unsigned long durch die Gegend schleppst! hast du denn den Link nicht gelesen. Alles was du tun musst, ist einen der Operationsteilnehmer auf long hochzuhieven. Zum Beispiel die 3600. neuehour = hour * 3600UL; und fertig. Jaaaaaaa. Auch Konstante haben Datentypen! 3600 ist ein int 3600L ist ein long 3600UL ist ein unsigned long damit steht dann da unsigned_long = byte * unsigned_long und damit bleibt dem Compiler dann nichts anderes mehr übrig, als die Multiplikation als unsigned long Multiplikation zu implementieren und alles ist in Butter.
Schon wieder ein Problem :D zu ausgerechneter und richtig angezeigter Zeit im serial.print will mein Atmega 168PA-PU nicht die ihm erteilte Aktion ausführen (rote LED an PWM Pin 9 um 1bit erhöhen). Hier der Code. void setup() { unsigned long second, minute, hour, dayOfWeek, dayOfMonth, month, year; Wire.begin(); Serial.begin(9600); byte led_rot = 9; byte rot_val = 0; } void loop() { unsigned long second, minute, hour, dayOfWeek, dayOfMonth, month, year; unsigned long neuesecond, neueminute, neuehour; unsigned long neuesmh; getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); Serial.print(hour, DEC); Serial.print(":"); Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC); Serial.print(" "); Serial.print(month, DEC); Serial.print("/"); Serial.print(dayOfMonth, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" Day_of_week:"); Serial.println(dayOfWeek, DEC); neuesecond = second; neueminute = minute*60; neuehour = hour*3600; neuesmh = neuesecond+neueminute+neuehour; //Serial.print(neuesecond, DEC); //Serial.println(" "); //Serial.print(neueminute, DEC); //Serial.println(" "); //Serial.print(neuehour, DEC); //Serial.println(" "); Serial.print(neuesmh, DEC); Serial.println(" "); if(neuesmh==65650)rot_p(); if(neuesmh==65655)rot_m(); delay(1000); } void rot_p(void) { unsigned long neuesmh; if(neuesmh==65650) { analogWrite(led_rot,rot_val); rot_val++; } } void rot_m(void) { unsigned long neuesmh; if(neuesmh==65655) { analogWrite(led_rot,rot_val); rot_val--; } } kbuchegg ich benötige deine Hilfe :)
Sven M. schrieb: > void rot_p(void) > { > unsigned long neuesmh; diese Variable hier ist eine neue Variable! Die hat nichts mit der gleichnamigen Variablen in loop zu tun. Die beiden haben zufällig den gleichen Namen, das wars aber auch schon. Abgesehen davon sind die beiden komplett voneinander unabhängig. > > if(neuesmh==65650) und wie soll diese neue Variable zu einem Wert kommen? du hast ihr keinen zugewiesen, also steht da irgendwas drinnen. Das müsste schon ein gewaltiger Zufall sein, wenn diese Variable zufällig den Wert 65650 hätte. > kbuchegg ich benötige deine Hilfe :) Schön langsam muss ich sagen: Wenn du etwas programmieren willst, warum lernst du dann nicht erst mal programmieren? So richtig, mit Buch und Übungen und so.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.