Hallo beisammen, ich bin gerade dabei mir einen Aquariencomputer zu bauen mit allem was man da so brauchen kann. Unter anderem z.B.: * 8 230V Schaltkanäle * 8 Düngerpumpenkanäle * 8 PWM Kanäle Die Anforderungen sind, dass man für jeden Wochentag mehrere Ein- und Ausschaltzeiten für die 230V Kanäle festlegen kann bzw für die Düngerkanäle mehrere Aufrufe pro Tag möglich sind. Ich habe allerdings noch keine gute Idee, wie ich das ganze im Speicher abbilden soll. Eine Idee wäre für jeden Kanal und Wochentag im EEPROM beispielsweise 3 Zeiten zu speichern. Was mir daran nicht gefällt, ist das das ganze dann doch recht unflexibel und speicherplatzraubend ist. Wäre es evtl schlauer soetwas wie [Wochentag, Stunde, Minute, AuszuführendeAktion] mit "AuszuführendeAktion" als Nummer einer Funktion zu speichern? Ein anderes Feature, dass ich gerne bauen möchte ist eine Dimmung für 8 Kanäle. Einerseits, soll es einen Modus geben, bei dem es eine Sonnenauf- und Untergangszeit gibt mit zwischendrin einer Wolkensimulation (das ist mehr oder minder schon im Programm vorhanden) und andererseits möchte ich gerne einen für den Tag festgelegten Helligkeitsverlauf abfahren können. Dieser soll dann (irgendwann mal) per PC-Programm an den µC gesendet werden können. Zu dieser Geschichte dachte ich mir ich könnte eine bestimmte Anzahl an Tripeln aus Stunde, Minute und PWM-Wert im EEPROM ablegen und zwischen diesen interpolieren. Gibts da noch bessere Ideen? Ich hoffe mal ihr könnt mir ein paar hilfreiche Tipps geben. Viele Grüße, Marcel
Was ist daran unflexsibel die Werte im EEprom zu speichern ? Wenn du ein EEprom von 1 K nimmst, reicht das vollkommen aus um deine paar Daten zu speichern. Abspeichern mußte, Tag,Monat, Uhrzeit, Programmplatz und vielleicht das Jahr noch. Diese dann im EEprom speichern und bei Bedarf wieder abrufen.
Marcel Kr. schrieb: > * 8 PWM Kanäle Hier geht es wohl um die Dimmung von Licht oder? Da musst du nochmal differenzieren. Musst du Wechselspannung dimmen, so solltest du dich mit Phasenan- und Phasenabschnittssteuerung beschäftigen. Macht man dann mit einem Triac. Da braucht man den Komparator für die Nulldurchgangserkennung. http://de.wikipedia.org/wiki/Phasenanschnittsteuerung Wenn du Gleichstrom-Lampen (ergo LEDs) hast, dann passt die PWM, musst halt vernünftige Mosfets verbauen. Marcel Kr. schrieb: > Die Anforderungen sind, dass man für jeden Wochentag mehrere Ein- und > Ausschaltzeiten für die 230V Kanäle festlegen kann bzw für die > Düngerkanäle mehrere Aufrufe pro Tag möglich sind. Ich habe allerdings > noch keine gute Idee, wie ich das ganze im Speicher abbilden soll. Eine > Idee wäre für jeden Kanal und Wochentag im EEPROM beispielsweise 3 > Zeiten zu speichern. Was mir daran nicht gefällt, ist das das ganze dann > doch recht unflexibel und speicherplatzraubend ist. Wäre es evtl > schlauer soetwas wie [Wochentag, Stunde, Minute, AuszuführendeAktion] > mit "AuszuführendeAktion" als Nummer einer Funktion zu speichern? Also Grundsätzlich wirst du ja sicher eine RTCC verwenden. Eine RTCC (real time calendar clock) ist ein unabhäniger Uhrenbaustein der dir an einer Schnittstelle die aktuelle Uhr zur Verfügung stellt. Das ganze ist sehr genau. Bei den meisten ist auch ein Kalender dabei. Schau dir mal den DS1337 (Reichelt 2,10) an. Der ist über I2C angebunden und hat nen Kalender dabei. Grundsätzlich stellt sich die Frage, ob du irgendwo repetetive Sequenzen hast. Ergo jeden Tag um 0700 Licht an, um 2000 Licht aus. Jeden zweiten Tag düngen, etc. Das musst du wissen. Da solltest du dir vorher einen Plan machen. Ansonsten holst du dir halt jede Sekunde (oder Minute) die Uhrzeit von deiner RTCC ab und holst dir beim Anschalten deiner Steuerung die Daten aus dem EEPROM in den RAM. Keinesfalls solltest du zu viele Zugriffe auf den EEPROM haben - darum lade es beim Systemstart in den RAM wenn du die RAM-Kapazitäten dazu hast. So kannst du dir deinen eigenen Stack von Abläufen bauen. Im FIFO Prinzip: http://de.wikipedia.org/wiki/First_In_%E2%80%93_First_Out Also das aktuellste Element (die nächstgelegene Uhrzeit) wird mit der aktuellen Uhrzeit verglichen. Das genügt ja wenn es sekündlich (oder wenn du willst auch minütlich) passiert. Nachdem ich davon ausgehe, dass du wirklich wiederholende Sequenzen hast sollte das kein großer Aufwand sein. Ich würde mir da Funktionen zur Datumsberechnung machen. Wenn du z.B. alle 5 Tage düngen möchtest, so kannst du die 5 ja im EEPROM ablegen (zwecks Veränderlichkeit) und dir eine Funktion gibt dir das nächste Datum für die Düngung an. Das letzt Datum wird ebenfalls im EEPROM gepeichert. Beim Einschalten, lässt du also die Funktionen durchlaufen und erstellst dir so einen Stack (wie oben besprochen). Diese Datumsfunktionen gibt es bereits fertig oder man kann sie sich echt einfach schreiben. Schaltjahre sind schnell bestimmt siehe Wikipedia, die Anzahl der Tage im Monat sollte ebenfalls bekannt sein. So würde ich das jetzt mal lösen. Wenn deine Fischlein natürlich jeden Tag eine neus Programm brauchen musst du dir was überlegen. Marcel Kr. schrieb: > Zu dieser Geschichte dachte ich mir ich könnte eine bestimmte Anzahl an > Tripeln aus Stunde, Minute und PWM-Wert im EEPROM ablegen und zwischen > diesen interpolieren. Gibts da noch bessere Ideen? Das passt schon. Ich weiß nur immer nicht was du mit deinem EEPROM willst. Da legst du ja nur feste Basiswerte ab, die in Laufzeit ohne Neuprogrammierung veränderbar sein müssen. So viele sind das in meinen Augen allerdings nicht. Die Frage ist inwiefern du überhaupts was verändern musst. Das musst aber du wissen. Ich würde schon auch einen EEPROM verwenden. Im EEPROM legst du ja nur die Anfangszeit und Endzeit der Dimmung und Anfangs- und Endwert ab. Den Rest interpoliert ja wie du schon gesagt hast eine Funktion. Dazu noch eine Zufallsfunktion für die Wolken wie rand() und srand() mit einer Variable um auch wirklich halbwegs zufällig zu bleiben (http://www.cplusplus.com/reference/clibrary/cstdlib/rand/) und das war's eigentlich. Ich würde da nie und nimmer tausende Werte in den EEPROM legen. Wenn du noch Fragen / Probleme hast melde dich gerne.
Hey, also die Dimmung selbst ist kein Problem, für jeden Kanal wird das PWM Signal raus geführt und für 4 der Kanäle gibt es noch eine 1-10V Rausführung für dimmbare EVGs. Die 8 PWM Kanäle will ich auf einen ATtiny auslagern, der das ganze per Soft-PWM macht und die Befehle vom Haupt-µC per I²C empfängt. So muss ich dem nur Kanal und Helligkeitswert schicken und der kümmert sich um den Rest. Das mit den festen Zeiten ist so ne Sache. Ich wollte das Gerätchen gut dokumentiert bauen, so dass es auch andere Leute nachbauen können. Deshalb wollte ich sehr flexibel sein in den Zeiten. Ich denke ich muss mir jetzt nochmal genau die Funktionen überlegen, die ich haben will und mir einen detaillierten Plan machen und Schritt für Schritt vorgehen. Bei so einem - für mich doch recht großen Projekt - bringt es wenig einfach drauf los zu programmieren hab ich festgestellt :) Morgen mach ich mir mal ein paar genauere Gedanken dazu, was genau ich jetzt brauche. Gute Nacht, Marcel
> Ich hoffe mal ihr könnt mir ein paar hilfreiche Tipps geben.
EEPROM hilft, die Daten wenigstens bei Stromausfall nicht zu vergessen.
Klar kostet es ein paar Byte mehr Programm.
Aber du baust nichts anderes, als SPS schon seit 30 Jahren machen
können, oder eben Aquariencomputer für 1 Becken statt deiner 8 Becken.
Schaltpläne für Relaisausgang und TRIAC-Ausgang sind ja wohl hinlänglich
im Netz, Tasten und alphanumerisches LCD an einem per Trafo versorgten
uC auch kein Problem.
Im Moment sehe ich vor allem, daß die immense Zahl an Daten den Benutzer
überfordert und die Übersicht leiden lässt. Immerhin willst du nicht
auch noch nach Wochentag differenzieren.
Wenn man sich schon die Mühe macht, so eine Schaltung zu entwerfen,
sollte man darauf achten, daß sie auch für andere Einsatzzwecke nützlich
sein kann, und das heisst neben der immensen Zahl von Ausgängen auch
Eingänge: Optokoppler zur potentialgetrennten Erfassung von 5V, 24V und
230V~ Signalen je nach Bestückung, und Analogeingänge nicht nur für
0-10V, sondern auch für verstärkte Signale z.B. aus Pt100 oder KTY
Temperatursensoren, also mit OpAmps so angeordnet daß die üblichen
Schaltungen daraus bestückt werden können. Vielleicht willst du die
Temperaturregelung ja dem uC überlassen (wovon ich bei teuren Fischen
Abstand nehmen würde, der uC stürzt leichter ab als ein Heizstab, aber
er könnte überwachen und bei Abweichung Alarm schlagen).
Wenn dann die Platine noch in ein orndentliches Gehäuse passt, kann sie
auch für andere Leute (mit verändertem Programm) nützlich sein.
Hallo Marcel! Um flexibel zu bleiben würde ich mir einzelne „Zeit Kanäle“ im EEprom einrichten, die dann z.B. 1x pro Minute abgefragt werden. Aufteilung im EEprom: Wochentag = Byte (1 Bit für jeden Wochentag) Zeit = Word (Werte von 0 bis 2359) Befehl = Byte (Ansteuerung/Aufruf der einzelnen Ports) Daten = Byte (Zahlenwert für den Aufruf/Ansteuerung vom Port) Damit würde man 5 Bytes im EEprom für einen „Zeit Kanal“ benötigen. Bei einem Mµ mit 1K EEprom könnte man so ca. 200 „Zeit Kanäle“ einrichten, dass sollte mehr als ausreichend sein. Durch die Verwendung eines Bits beim Wochentag kann man zusätzlich entscheiden ob der „Zeit Kanal“ nur an einem Tag der Woche, oder die ganze Woche verwendet werden soll. Und man kann dieses Byte auch gleich zur Auswertung „Zeit Kanal aktiv“ heranziehen (alle Bits 0 = nicht aktiviert). Wenn Dir eine Zeitschaltuhr mit Wochenprogramm und 200 verschiedenen Schaltzeiten ausreicht, dann könnte das ein Lösungsansatz sein. Beispiele: 127;600;1;30 Jeden Tag der Woche um 6:00 Uhr Sonnenaufgang1 (Befehl1 = Dimmeransteuerung Nr.1 hoch zählen) mit einer Geschwindigkeit von 30 (z.B. 30 Minuten). 127;2030;2;30 Jeden Tag der Woche um 20:30 Uhr Sonnenuntergang1 (Befehl2 = Dimmersteuerung Nr1 runter zählen) mit einer Geschwindigkeit von 30. 42;900;3;1 Di, Do und Sa wird um 9:00 Uhr gefüttert (Befehl3 = Futtern), bei der Station Nr1. 0;1200;4;5 Wird nicht ausgeführt, da kein Wochentag aktiviert wurde. Ansonsten um 12:00 Uhr Programm4 abfahren (z.B. Gewitter) mit einer Laufzeit von 5 Minuten. Insgesamt würden Dir so 256 verschieden Befehle (Programme) zur Verfügung stehen, mit einem Übergabewert (Daten) von 0 bis 256. Damit kann man schon ordentlich Ballet veranstalten. Die Einstellungen würde ich über einen PC vornehmen und dann in den EEprom schieben... LG Jens
Nachtrag, einen habe ich noch... Im Byte „Wochentag“ wird ja das Bit7 (achte Bit) nicht verwendet. Wenn Du dieses Bit mit setzt, dann kannst Du auch noch eine Monatsabfrage mit einbauen, ohne dass Du etwas am Aufbau/Aufteilung im EEprom ändern musst. Ist Bit7 gesetzt, dann wertest Du einfach die Tage im Monat aus. Beispiel: 132;1200;4;5 Es wird am 4. des Monats um 12:00 Uhr Programm4 abfahren (z.B. Gewitter) mit einer Laufzeit von 5 Minuten. Damit kannst Du ganz einfach entscheiden ob ein „Zeit Kanal“ monatlich oder wöchentlich ausgeführt werden soll. Dir steht so also eine Zeitschaltuhr mit Monat und Wochentagsprogramm zur Verfügung... LG Jens
Hi ihr, danke für eure ausführlichen Antworten! @Mawin: Klar, es soll auch Eingänge zur Temperaturmessung geben, auch für z.B. einen Pegelschalter oder PH-Elektrode und Leitwertmessung, wobei ich das selbst nicht am Aquarium hab und von daher hat das bisher noch nicht so hohe Priorität. Ja klar kann das schon jede SPS, aber ich will das hier ja speziell auf's Aquarium münzen. Und außerdem ne SPS kaufen kann jeder, aber denen entgeht dann der Spaß an der Entwicklung und der Löterei ;) @Jens, danke für die Ideen, vor allem das mit dem Byte für den Wochentag finde ich super - auch die Monatserweiterung ist eine super Idee. Maximale Speicherplatznutzung :D Ich hatte auch ein Byte für den Wochentag eingeplant, allerdings wäre da dann nur 1, 2, ..., 7 drin gestanden für eben diese Tage. Mit deiner Version spart man sich da dann noch speicher, wenn man ein Programm an mehreren Tagen haben möchte. Außerdem habe ich jetzt, nach deinem Vorschlag, die 220V Kanäle und Düngung zu einer Struktur im Speicher gemacht, so hat man volle Flexibilität. Hier mal die Strukturen die ich mir ausgedacht habe:
1 | Lichtautomatik |
2 | 8 mal folgende Struktur |
3 | 1B Modus |
4 | 1B PWM-Wert |
5 | 1B Wolkensimulation an/aus |
6 | 2B Sonnenaufgang Minute |
7 | 1B Sonnenaufgang Dauer |
8 | 2B Sonnenuntergang Minute |
9 | 1B Sonnenuntergang Dauer |
10 | 1B Max. Helligkeit |
11 | 1B Min. Helligkeit |
12 | 1B 220V Kanal (um EVGs komplett abzuschalten) |
13 | [8 x 12B = 96B] |
14 | |
15 | Lichtprogramm |
16 | 20 mal (oder mehr?) folgende Struktur |
17 | 2B Minute |
18 | 1B PWM-Wert |
19 | [20 x 3B = 60B] |
20 | |
21 | 220V Schaltkanäle und Düngung |
22 | 1B Tag |
23 | 2B Minute |
24 | 1B Funktion (220V Schalter/Düngung und jeweils Kanal) |
25 | 1B Parameter (220V: ein/aus - Düngung: zeit) |
26 | [Rest des EEPROM: 1024B - 156B = 868B -> 868B / 5 = 173 mögliche Zeiten] |
Speziell für die Beleuchtung will ich das so machen, dass man folgende Modi zur Verfügung hat: Manuell: Dürfte klar sein Lichtautomatik: Ein und Aus zu fester Zeit mit bestimmter Dauer für Sonnenauf- und untergang. Zwischendrin wenn gewünscht Wolkensimulation Lichtprogramm: Abfahren einer vorher festgelegten Reihe an Werten Zur Erklärung für die Speicherstruktur für die "Lichtautomatik" ist zu sagen, dass hier auch gleich die sonstigen Einstellungen zu diesem Lichtkanal abgelegt sind, da diese Struktur ja nur ein mal pro Kanal vor kommt und es mir logisch erschien da einfach den rest noch dazu zu legen. So weit so gut, ich glaube da könnte man schon gut Ballett veranstalten, wie du so schön sagtest ;) Noch Ideen? Viele Grüße, Marcel
Für meine Timer hab ich diese Struktur geplant: Stunde -> 5bit (0-31) Minute -> 6Bit (0-63) Tag -> 6Bit (0-63) Monat -> 6Bit (0-63) Kanal -> 3Bit (0-7) Programm -> 4Bit (0-15) macht 30Bit und somit 4Byte in denen 2Bit Reserve sind (für mehr Kanäle/Programme/oder was anderes) Tag: 0-30 -> Tag (+1) (Ausbaustufe 3) 31-37 -> Wochentag 41-47 -> Wochentag gerade Woche 51-57 -> Wochentag ungerade Woche Monat: 0-11 -> Monat (+1) (Ausbaustufe 3) 12-63 -> Kalenderwoche Das spart Platz (4 statt 6 bis 10Byte). Bisher hab ich micht jedoch noch nicht mit eeprom über i2c beschäftigt, aber ich hoffe, das ich das auch da drin so speichen kann.
Ok, das ist nochmal etwas komprimierter, dafür musst du das mühevoll wieder auseinander klabustern. Ich bin grad recht zufrieden mit der Möglichkeit, die ich oben beschrieben habe und wenn keiner noch ne bessere Idee hat dann werd ich das so in Angriff nehmen. Ich denke bei der Möglichkeit oben hat man noch genügend programmierbare Schaltzeiten und auch nicht zu viel Programmierarbeit ;) (Ok, ein paar Byte werden noch für andere zu speichernde Einstellungen drauf gehen bei mir, aber ob es jetzt 173 oder 160 Schaltzeiten sind ... ich glaub das ist genügend) EEPROM über I²C sollte kein Problem sein. Da kann man sich ja Funktionen zum schreiben und abholen von Bytes aus dem EEPROM schreiben. Viele Grüße
> Klar, es soll auch Eingänge zur Temperaturmessung geben, auch für z.B. > einen Pegelschalter oder PH-Elektrode und Leitwertmessung Achte drauf, daß Eingänge, die elektrisch im Wasser hängen, potentialfrei sein müssen, es darf nicht sein, daß z.B. Strom von der Leitwertelektrode zur pH-Elektrode fliesst, weil zwischen ihnen eine Spannung liegt.
Lehrmann Michael schrieb: > Also Grundsätzlich wirst du ja sicher eine RTCC verwenden. Eine RTCC > (real time calendar clock) ist ein unabhäniger Uhrenbaustein der dir an > einer Schnittstelle die aktuelle Uhr zur Verfügung stellt. Das ganze ist > sehr genau. Bei den meisten ist auch ein Kalender dabei. > Schau dir mal den DS1337 (Reichelt 2,10) an. Der ist über I2C > angebunden und hat nen Kalender dabei. Da würde ich gern einhaken. Dieser Vorschlag von Michael ist bestimmt gut gemeint aber wird dich durch die Ungenauigkeit dann doch nerven. Wenn also ne RTC eingebaut wird dann doch besser etwas gutes wie DS3232. Gruss Klaus de Lisson
> Ok, das ist nochmal etwas komprimierter, dafür musst du das > mühevoll wieder auseinander klabustern. nö, ich finde das recht einfach: -> http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Bitfelder struct { unsigned Stunde:5 unsigned Minute:6 unsigned Tag:6 unsigned Monat:6 unsigned Kanal:3 unsigned Programm:4 } TIMER[20]; so sieht das bei mir aus und rankommen geht über TIMER[0].Stunde ... TIMER[20].Programm
Hallo Marcel! > Außerdem habe ich jetzt, nach deinem Vorschlag, die 220V Kanäle und > Düngung zu einer Struktur im Speicher gemacht, so hat man volle Flexibilität. Da fällt mir noch was zu den Ausgängen ein. Hier wolltest Du die PWM Ausgänge über einen ATtiny realisieren, per Software PWM. Ich würde hier lieber einen ATmega (z.B. den ATmega48) verwenden, dann kannst Du auf das TWI-Modul zurückgreifen. Des Weiteren würde ich alle Ausgänge (im ATmega48) als PWM Ausgänge programmieren und so 16 PWM-Ports zur Verfügung stellen. Der Vorteil wäre dass Du so per I2C-Bus um 16 Ports erweitern kannst und hier kann dann jeder Port alles (ist also egal wofür Du ihn verwendest). Benötigest Du PWM-Ports, dann steuerst Du sie mit Daten von 0 bis 256 an. Und benötigst Du nur Ein-Aus-Ports, dann steuerst Du sie mit 0 = Aus und 256 = Ein an. Beim „Master Mµ“ würde ich alle Ports als Eingang definieren (bzw. für Messfühler) und die Ausgänge eben über I2C zur Verfügung stellen. Da die Ausgänge hier nicht all zu schnell reagieren müssen wäre eine I2C Lösung durchaus möglich. In dem Zusammenhang währe vielleicht auch eine „Modulare Programmierung“ interessant. Dazu müsstest Du allerdings noch ein weiteres Byte zur Ansteuerung opfern (fehlt dann also im EEprom). Insgesamt würden Dir dann 6 Bytes an Stelle der 5 Bytes (pro „Zeit Kanal“) zur Verfügung stehen, wodurch Du dann eine gezielte Modulzuweisung aufrufen kannst. Beispiel: Wochentag, Zeit, Modul, Port, Daten 127;600;1;5;30 Jeden Tag der Woche um 6:00 Uhr wird das Modul1 (Programm1) mit Port5 und den dazugehörigen Daten = 30 aufgerufen. Im Modul1 wird dann festgelegt was für eine Ansteuerung der Port erhält. Das Modul1 wäre hier also der Dimmer „Sonnenaufgang“, der den Port5 in der gewünschten Zeit30 hoch fährt. Von diesen Modulen brauchst Du dann nur so viel zu programmieren wie Du maximal benötigst (z.B. 10 Module mit Sonnenaufgang und 10 Module mit Sonnenuntergang). Und genau so machst Du es dann auch mit den Futterpumpen, hier wäre es ein Modul „Zeitglied“, welches für eine Zeit X dann einen Port einschaltet. Maximal könntest Du so 256 verschiedene Module für verschiedene Aufgaben programmieren. Und jedes Modul könnte mit jedem Port verknüpft werden, flexibler geht es dann wirklich nicht mehr. Der Nachteil wäre dann aber dass Du selber darauf achten musst das ein Modul nicht mehrfach verwendet wird (oder Du programmierst die PC Eingabesoftware so dass sie darauf achtet). > Hier mal die Strukturen die ich mir ausgedacht habe: > Rest des EEPROM: 1024B - 156B = 868B -> 868B / 5 = 173 mögliche Zeiten Ich würde den internen EEprom vom Mµ für die Zeitkanäle nutzen, denn der ist schön schnell. Bei der Änderung auf 6 Bytes pro „Zeit Kanal“ würden Dir dann immer noch ca. 166 Einträge zur Verfügung stehen. Alle anderen „Einstellungen“ würde ich in einen I2C-Bus EEprom hinterlegen, denn hier spielt die Geschwindigkeit keine große Rolle. Hier könntest Du dann auch die Daten für „Wolken“ hinterlegen, die müssen ja auch nicht sehr schnell nachgeladen werden... ano2011 schrieb: > struct > { > unsigned Stunde:5 > unsigned Minute:6 > unsigned Tag:6 > unsigned Monat:6 > unsigned Kanal:3 > unsigned Programm:4 > } TIMER[20]; Kann ich so eine Struktur auch im EEprom anlegen? Wenn ja, wie? Wenn nein, wie lade ich die EEprom Daten in die Struktur? LG Jens
@Jens weiter oben hatte ich schon geschrieben: > Bisher hab ich micht jedoch noch nicht mit eeprom über i2c beschäftigt, > aber ich hoffe, das ich das auch da drin so speichen kann. also kann ich es dir noch nicht aus eigener Erfahrung sagen. Ich denke aber, das man die Arrays als Block im eeprom lesen/speichern kann. Ich hab derzeit aber noch nicht die TLC-Hardware fertig, erst wenn die fertig ist, will ich mit der Programmierung weiter machen.
Hey, tolle Ideen tun sich hier auf, freut mich ;) Im Moment bin ich gerade in er Klausurphase, deshalb mach ich keine wirkliche Soft- oder Hardwareentwicklung, sonder sammel mal nur die Erkenntnisse wie ich was mache und was ich gerne hätte und so weiter. Nur falls sich einer wundert, dass es hier mehr oder minder nur um die graue Theorie geht. Aber am 29.9. is die Klausuphase rum und die Entwicklung kann los gehen :D @MaWin, wie realisiere ich eine solche potentialfreiheit? @Klaus, DS3232 als RTC, ist aufgenommen @Jens Stimmt, das mit dem Mega48 ist ne gute Idee, da die I/O Ports eh zu knapp sind und ich sonst noch einen Portexpander auf die Platine hätte packen müssen. Mit dem Mega48 sollte es glaube ich auch ohne gehen gehen. Das mit den Modulen ist auch eine gute Idee, aber ich glaube das wäre fast schon wieder zu viel des guten ;) Ein zusätzlicher EEPROM, darüber hab ich auch schon nachgedacht, dann muss man sich keine großen Gedanken mehr machen, alles so kompakt wie möglich zu speichern. Ich glaube die Geschwindigkeit des abrufens aus dem EEPROM ist bei dieser Art der Anwendung relativ unkritisch oder? @ano, also wenn man diese Struktur so im EEPROM speichern kann wäre das natürlich super, aber wie wüsste ich jetzt spontan auch nicht. Man müsste halt wissen wie dieses struct intern behandelt wird. Wahrscheinlich verwurstet der Compiler das in einzelne 8 bit Variablen, aber keine Ahnung wie man die einzeln speichert und wieder in das struct rekonstruieren kann. Viele Grüße, Marcel
schau dir mal das an: Beitrag "EEPROM array of struct" evtl. ist das genau das, was wir brauchen! ich komm leider vorerst nicht dazu (die Hardware für die LED Stripes muß erst stehen, bevor ich mit der Software weiter machen kann)
Klaus De lisson schrieb: > Lehrmann Michael schrieb: >> Also Grundsätzlich wirst du ja sicher eine RTCC verwenden. Eine RTCC >> (real time calendar clock) ist ein unabhäniger Uhrenbaustein der dir an >> einer Schnittstelle die aktuelle Uhr zur Verfügung stellt. Das ganze ist >> sehr genau. Bei den meisten ist auch ein Kalender dabei. >> Schau dir mal den DS1337 (Reichelt 2,10) an. Der ist über I2C >> angebunden und hat nen Kalender dabei. > > Da würde ich gern einhaken. Dieser Vorschlag von Michael ist bestimmt > gut > gemeint aber wird dich durch die Ungenauigkeit dann doch nerven. > > Wenn also ne RTC eingebaut wird dann doch besser etwas gutes wie DS3232. > > Gruss Klaus de Lisson Alternativ wäre ein PIC18 - da gibt es einige mit eingebauter RTC oder zusätzlich ein DCF77 Empfänger.
@ano2011, so wie's aussieht wird da im Quellcode schon festgelegt, was ins EEPROM kommt. Das ist doch folgende Zeile aus dessen Quellcode wenn ich mich nicht irre:
1 | Preset_str eePresets[6] EEMEM = |
2 | ... |
Ich weiß nicht ob das schreiben eines solchen structs in den EEPROM während der Laufzeit möglich ist. Wenn ich jetzt hier mist erzähle, verbessert mich :) @Michael, auf PIC werde ich wohl nicht mehr umsteigen, hab mich schon an die Atmels gewöhnt ;) Über DCF77 hab ich auch schon nachgedacht, aber in einem anderen Thread, hat einer den DS3232 in einer Uhr verbaut und die ging nach einem Jahr um 3 Sekunden falsch. Von daher wäre mir das zu viel Aufwand, wenn ich auch mit dem RTC-Baustein eine so genaue Uhr bekomme. Viele Grüße, Marcel
Marcel Kr. schrieb: > @ano2011, so wie's aussieht wird da im Quellcode schon festgelegt, was > ins EEPROM kommt. Das ist doch folgende Zeile aus dessen Quellcode wenn > ich mich nicht irre: >
1 | Preset_str eePresets[6] EEMEM = |
2 | > ... |
Das stimmt schon. > Ich weiß nicht ob das schreiben eines solchen structs in den EEPROM > während der Laufzeit möglich ist. Natürlich ist das möglich. Sonst wäre ja ein EEPROM nicht sehr sinnvoll, wenn man es zur Laufzeit nicht beschreiben könnte.
Du darfst uns auch gerne an deiner Weisheit teilhaben lassen :) Zeig doch mal einen Codeschnipsel, wie man solch einen Struct in das EEPROM schreibt. Das man das EEPROM grundsätzlich während der Laufzeit beschreiben kann ist mir klar, wie man einen Struct da rein drückt jedoch nicht.
Marcel Kr. schrieb: > Du darfst uns auch gerne an deiner Weisheit teilhaben lassen :) > Zeig doch mal einen Codeschnipsel, wie man solch einen Struct in das > EEPROM schreibt. Rate mal :-) Wenn man es mit der Funktion eprom_read_block ausliest, wie wird wohl die Funktion heißen, mit der man es beschreibt? http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM
ohne alles gelesen zu haben: ich habe für die düngung eine autoscheibenwischerpumpe genommen (eBay für 10.-), und die steuere ich 1x/tag für 0.x sekunden an. die düngflüssigkeit habe ich massiv mit wasser verdünnt, und auf den pumpeneinlass umgekehrt eine Petflasche gesteckt. passt alles wunderbar und günstiger geht es wohl kaum :-) viel glück und spass beim basteln!
Ok Karl Heinz, ich habs mir fast schon gedacht, als ich kurz im AVR-GCC Tut vorbei geschaut hab ;) Hier mal ein Fetzen, den ich schnell geschrieben habe um zu gucken wie das funktioniert:
1 | #include <avr/io.h> |
2 | #include <avr/eeprom.h> |
3 | #include <stdlib.h> |
4 | |
5 | typedef struct |
6 | { |
7 | unsigned stunde:5; |
8 | unsigned minute:6; |
9 | } struct_lichtkanal; |
10 | |
11 | struct_lichtkanal lichtkanal_preset[8] EEMEM; |
12 | |
13 | int main (void) |
14 | { |
15 | struct_lichtkanal lichtkanal[8]; |
16 | lichtkanal[0].stunde = 12; |
17 | |
18 | eeprom_write_block(&lichtkanal, &lichtkanal_preset[0], sizeof(struct_lichtkanal)); |
19 | } |
Wenn ich was im EEPROM gespeichert hab hab ich das bisher immer mit manuell festgelegten Adressen gemacht, irgendwie war mir das ein bisschen suspekt das dem Compiler zu überlassen. Kann mich einer aufklären was der da im Hintergrund macht? Sprich wo hin schreibt der das und woher weiß der beim nächsten mal kompilieren, das dieses eine Byte wieder an die selbe Adresse kommt? @Master Snowman, bei ebay bietet ein sogenannter "xtronmann" immer wieder Dosierpumpen an. Teils als Auktion, teils als Sofortkauf. Ich denke die sind für den Zweck optimal (40ml/min bei 12V)
Hallo! > Preset_str eePresets[6] EEMEM = > > ... Ich habe das gestern mal versucht ein zu geben, bin aber an der Umsetzung jämmerlich gescheitert. Mein Verständnisproblem liegt bei der Array, denn die Struktur ist ja eine Array und damit komme ich nicht klar. Dazu habe ich mal eine Frage an die Fachleute. Kann man eine Struktur nicht „zwei mal“ aufteilen? Zum einen in die Struktur wie ich sie haben will und zum anderen z.B. in 5 Bytes (unsignet Char) auf die ich zugreifen kann. Das währe dann quasi wie eine Doppelbelegung der 5 Bytes, nur dass man die 5 Bytes mit Hilfe der Struktur unterschiedlich beschreiben kann. Wenn das funktionieren würde, dann wäre das universal und auch EEprom unabhängig. Wenn ich zugriff auf die 5 Bytes hätte, dann könnte ich die z.B. mit „eeprom_write_byte()“ in den internen EEprom schreiben, oder mit „I2C_Write()“ in einen externen EEprom. Wäre so eine Strukturaufteilung möglich? LG Jens
Marcel Kr. schrieb: > Hier mal ein Fetzen, den ich schnell geschrieben habe um zu gucken wie > das funktioniert: Fast perfekt. Wenn du ein Array hast, brauchst du kein & um seine Adresse festzustellen. Ein Array wird immer so übergeben, dass seine Startadresse übergeben wird. Und beim sizeof solltest du dir angewöhnen, die Variable zu benutzen und nicht explizit den Datentyp. Das ist bei Änderungen des Datentyps einfacher, weil dir der Compiler einen Arbeitsschritt abnimmt. D.h.
1 | // das ganze Array
|
2 | eeprom_write_block( lichtkanal, lichtkanal_preset, sizeof(lichtkanal_preset) ); |
3 | |
4 | // oder nur 1 Element davon
|
5 | eeprom_write_block( &lichtkanal[2], &lichtkanal_preset[2], sizeof(*lichtkanal_preset) ); |
> Wenn ich was im EEPROM gespeichert hab hab ich das bisher immer mit > manuell festgelegten Adressen gemacht, irgendwie war mir das ein > bisschen suspekt das dem Compiler zu überlassen. Kann mich einer > aufklären was der da im Hintergrund macht? Sprich wo hin schreibt der > das und woher weiß der beim nächsten mal kompilieren, das dieses eine > Byte wieder an die selbe Adresse kommt? Na ja. Der Compiler (eigentlich der Linker) benutzt ja keinen Würfel um die Adressen zu vergeben. Der allokiert einfach von 0 beginnend die EEMEM-Variablen. D.h. wenn du noch was im EEPROM brauchst, schreibst du es einfach hinten an die Auflistung der EEMEM Variablen drann und gut ists.
Ok, danke für die Tipps! Nutzt der Linker dann eigentlich jedes einzelne Bit aus? Also wenn ich ein Struct mit meinetwegen zwei 3 Bit variablen habe und das nächste Struct mit zwei 5 Bit Variablen, werden dann genau 2 Byte aus dem EEPROM Benutzt? Prinzipiell ja wahrscheinlich nicht, da ich ja in eeprom_write_block eine Zieladresse angebe. Aber wird dann wenigstens bei einem Struct-Array jedes Bit genutzt? Ich frage, weil ich ja auch wissen muss, wieviel Platz ich noch habe um die Anzahl der möglichen Zeitschaltuhren auszurechnen. Viele Grüße, Marcel
Hallo alle Miteinander! Die Geschichte mit der Struktur hat mir keine ruhe gelassen und so ist dann doch noch etwas „universelles“ entstanden. Ausgangspunkt waren hierbei die alten Daten: Wochentag ---> Wochentag oder Tag des Monats Stunde ---> Stunden Minute ---> Minuten Programm ---> bis 63 unterschiedliche Programme programmierbar Port ---> maximal erweiterbar bis 128 Ausgangsports Daten ---> Zahlen von 0 bis 255 Alle Bits zusammengerechnet ergeben 5 Bytes. Es werden also 5 Bytes pro „Zeit Kanal“ im EEprom benötigt (nicht wie vorher 6 Bytes). Daraus ist nun folgende Struktur entstanden: union Zeit_Kanal_Maske { // Maske für Zeit-Kanal struct ZK_Byte { // Aufteilung für Maske unsigned long Stunde:5; // Zahlen von 0 bis 31 unsigned long Minute:6; // Zahlen von 0 bis 63 unsigned long Programm:6; // Zahlen von 0 bis 63 unsigned long Port:7; // Zahlen von 0 bis 127 unsigned long Daten:8; // Zahlen von 0 bis 255 unsigned char Wochentag:8; // Zahlen von 0 bis 255 } ZK_Maske; // Aufruf Maske unsigned char ZK_Byte[5]; // Aufteilung für Bytes } ZK; // Aufruf Zeit-Kanal Die Struktur kann nun wie folgt beschrieben werden: ZK.ZK_Maske.Stunde = 22; ZK.ZK_Maske.Minute = 31; ZK.ZK_Maske.Programm = 2; ZK.ZK_Maske.Port = 9; ZK.ZK_Maske.Daten = 158; ZK.ZK_Maske.Wochentag = 47; Und wie folgt ausgelesen werden: Variable1 = ZK.ZK_Maske.Stunde; Variable2 = ZK.ZK_Maske.Minute; Variable3 = ZK.ZK_Maske.Programm; Variable4 = ZK.ZK_Maske.Port; Variable5 = ZK.ZK_Maske.Daten; Variable6 = ZK.ZK_Maske.Wochentag; Darüber hinaus besteht nun aber auch noch die Möglichkeit an die einzelnen Bytes heran zu kommen (also ohne Maske). Man kann die Struktur wie folgt befüllen: ZK.ZK_Byte[0] = eeprom_read_byte(&Daten1[0]); ZK.ZK_Byte[1] = eeprom_read_byte(&Daten2[0]); ZK.ZK_Byte[2] = eeprom_read_byte(&Daten3[0]); ZK.ZK_Byte[3] = eeprom_read_byte(&Daten4[0]); ZK.ZK_Byte[4] = eeprom_read_byte(&Daten5[0]); Die Daten könnten z.B. aus dem EEprom stammen und so in die Struktur geladen werden. Und anders herum geht es natürlich auch, so könnte man z.B. Daten in einen EEprom schreiben: eeprom_write_byte(&Daten1[0], ZK.ZK_Byte[0]); eeprom_write_byte(&Daten2[0], ZK.ZK_Byte[1]); eeprom_write_byte(&Daten3[0], ZK.ZK_Byte[2]); eeprom_write_byte(&Daten4[0], ZK.ZK_Byte[3]); eeprom_write_byte(&Daten5[0], ZK.ZK_Byte[4]); Da nun auf jedes der einzelnen 5 Bytes zugegriffen werden kann, besteht nun auch die Möglichkeit die Daten in einen externen EEprom zu schreiben (oder ein anderes externes Medium). Bei einem 24C256 EEprom könnte die Ansteuerung z.B. so aussehen: I2C_Start(160); // Adresse I2C_Write(0); // High-Register I2C_Write(0); // Low-Register I2C_Write(ZK.ZK_Byte[0]); // Byte1 I2C_Write(ZK.ZK_Byte[1]); // Byte2 I2C_Write(ZK.ZK_Byte[2]); // Byte3 I2C_Write(ZK.ZK_Byte[3]); // Byte4 I2C_Write(ZK.ZK_Byte[4]); // Byte5 I2C_Stop() Anbei noch ein Bild von einem Terminalprogramm, wo ich die Struktur getestet habe... LG Jens
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.