Hallo zusammen mit diesem Quelltext ist es möglich FS20 Komponente mit Hilfe eines Atmegas und dem FS20 Sender "HF-Sendemodul TX868-75" anzusteueren. Es gibt nur noch ein Problem bei den Timings um den Heizungsregler anzusteuern, da dieser nur alle 2 Minuten für ein paar Millisekunden aktiv ist und genau dann der Befehl für die Ventilstellung annimmt. Das Stellen funktioniert zwar schon, allerdings geht der Heizungsregler nach ein paar Minuten in die Notabschaltung, weil er keine Befehle mehr empfängt. Sobald ich die Syncronisation des Heizungsreglers hinbekommen habe, werde ich es updaten. Vielleicht hat das auch schon jemand von euch gemacht. Ich wäre für jeden Hilfe, in der Hinsicht, dankbar. Wenn noch was unklar ist fragt. mfg Christian
Hallo! Ein kurzes Beispiel wäre nicht schlecht! Gruß Denny
Was für ein Beispiel meinst du? Wie man das ganze verwendet oder den Aufbau?
Die Verwendung! (bin nicht gerade der C-Profi :-( ) Gruß
Damit kannst du mit Hilfe des TX868 http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=12789&flv=0 und einem Atmega zum Beipsiel den Dimmer von ELV http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=21023&flv=0 oder den Heizumngsregler http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=11173&flv=0 ansteuern. Ich lass zum Beispiel meinen Atmega die komplette Raumsteurung übernehmen. Also er regelt zum Beispiel die von mir eingestellt Temperatur im Raum oder kann meine Lampen dimmen oder weckt mich zu einer eingestellten Zeit. Da wird dann zum Beispiel früh die Kaffemaschine angemacht und mein Rechner wird schon hochgefahren . Das ganze wird dann vom Mediaportal auf meinem HTPC gesteuert (hab nen plugin dafür geschrieben). ICh hoffe du hast jetzt nen Bild davon.
Hallo! Hast du auch ein kleines Codebeispiel, wie man das ganze einbindet? Kann man damit auch die ganz normalen FS20 Steckdosen steuern? Hatte das auch so ungefär vor wie du, habe aber bis jetzt immer in Bascom programmiert und da komme ich an einige stellen nicht weiter und habe deswegen jetzt angefangen alles in C zu schreiben. Gruß Denny
Ja die kannst du damit auch ansteuern einfach. Genau wie die Dimmer. Einfach erst anlernen und dann über die An-Aus Befehle schalten. Hier ein Codebeispiel. Der ATmega16 bekommt seine Befehle über die USART Schittstelle.
1 | ISR (USART_RXC_vect) |
2 | {
|
3 | unsigned char rx_daten; |
4 | rx_daten = UDR; |
5 | _delay_ms(50); |
6 | if(rx_daten==1) |
7 | {
|
8 | print("Heizung anlernen"); |
9 | Heizung_code_senden(0x00,0x2F00); |
10 | Heizung_code_senden(0x00,0x2F00); |
11 | |
12 | }
|
13 | if(rx_daten==2) |
14 | {
|
15 | print("Heizung stellen auf 0"); |
16 | Heizung_code_senden(0x00,0xA600); |
17 | Heizung_code_senden(0x00,0xA600); |
18 | |
19 | }
|
20 | if(rx_daten==3) |
21 | {
|
22 | // damit lassen sich auch die stekcdosen steuern
|
23 | // zum anlernen einfach An oder Aus senden
|
24 | // und auf die Adressen vergabe achten
|
25 | print("Licht an"); |
26 | Dimmer_code_senden(0x01,0x10); |
27 | Dimmer_code_senden(0x01,0x10); |
28 | Dimmer_code_senden(0x01,0x10); |
29 | }
|
30 | if(rx_daten==4) |
31 | {
|
32 | print("Licht aus"); |
33 | Dimmer_code_senden(0x01,0x00); |
34 | Dimmer_code_senden(0x01,0x00); |
35 | Dimmer_code_senden(0x01,0x00); |
36 | }
|
37 | }
|
Für die Steckdosen hab ich übrigens einfach Funk-Steckdosenset 2605 von Pollin genommen und hab die fernbedienung an den Atmega angeschlossen. Kostet nämlich nur 10euro ;) mfg Christian
Könnte es denn sein, daß die Heizungssteller solange sie noch unsynchronisiert sind, bis zu einem Timeout einfach auf das Signal der Steuerung horchen ? Solange kein Sync vorhanden also mehr als nur die paar Millisekunden. Falls mehrere Steller zueinander unsynchronisiert sind, so würde das ein Timeout von knapp 4 Minuten ergeben. Wenn diese Erstsynchronisation stattgefunden hat, dann horchen die Steller im Zeitfenster der von Dir beschriebenen paar Millisekunden wieder auf ein Signal, evtl. auch ein zweites Mal nach erneuten 2 Minuten, damit nicht eine einzelne Funkstörung zum Ausfall führt. Kommt dann immer noch kein gültiges Signal, gehen sie auf Störung. Der Steller besitzt einen Uhrenquarz. Das bedeutet sobald einmal synchronisiert wurde, ist das nötige Fenster der Datenübertragung sehr klein. Wird offensichtlich gemacht, um den Stromverbrauch vor allem durch den Empfängerbaustein gering zu halten Und damit Du diese Fenster erwischt, musst Du einfach nur die exakte Zeit zwischen zwei Signalen einhalten und sie mit Deiner Steuerung senden.
Ja genau aber die Zeit konnte ich leider noch nicht genau bestimme. Hast du vielleicht ne Idee wie ich das genau bestimmen könnte?
Ja klar, wenn Du keinen LA hast der den Zeitbereich loggen kann, dann programmier Dir ein kleines Tool auf 'nem Atmel mit einem genau genug aufgelösten Timer. Den Start/Stop Eingang des Timers hängst Du an Pin 29, P6.0/KS0 des ELV Stellers, vor den Transistor, der den Empfänger aufsteuert. Nimm das Ganze dann normal in Betrieb. Der Ausgang wird immer im richtigen Zyklus aktiv, wenn Du dann den Timerwert über die Serielle ausliest, hast Du was Du brauchst.
Hier noch als Nachtrag die Schaltung. @MES danke für den Tipp ich werd es mal versuchen. Würdest du da den 16bit Timer nehmen? Und mein Problem is noch das ich selbst mit dem Vorteiler 1024 nicht auf 2 Minuten komme.
Natürlich reicht Dir da ein 16Bit Zähler nicht aus, aber Du kannst den Zähler per OVFL ISR beliebig erweitern, so dass Du sowohl Auflösung, als auch Zeitbereich bekommst.
Also ich hab jetzt 14 Durchläufe und danach ist TIMSK 0x5368 oder 0x536A oder 0x5363 schwank also. Ich benutze den internen 8Mhz Quarz können es daran liegen?
Der interne RC Oszillator ist nicht sehr genau, ob der soviel abweicht kann ich nicht sagen. Die Abweichung laut Deinen Angaben ist ca. 0.8mS. Falls Du nicht irgendetwas Merkwürdiges misst, denn ich hoffe das mit TIMSK ist nicht Dein Ernst :D
Evtl. wirst Du auf einen Atmel umsteigen müssen, an den Du einen Uhrenquarz ranflanschen kannst. Nicht umsonst ist so einer im Steller drin.
habs jetzt mal mit nem atmega8 und nem externen 3.6864 Mhz Quarz getest. Jetzt komm ich immer genau auf 6 Durchläufe und am ende hat TCNT1 den Wert 0x584A. Den Uhrenquarz kann ich doch irgendwie an den Timer hängen oder? Weißt du zufälligerweise an welche Pins der muss und wie ich die Register setzen muss?
Also der Sender sendet alle 115,5 Sekunden
Dann bist Du ja schon einen Schritt weiter. Der Uhrenquarz wird verwendet, da er genauer abgeglichen ist und außerdem bei der Frequenz 32768Hz einen geringeren Stromverbrauch hat. Für Geräte die nur ab und zu aktiv werden. So wie der Steller. Ich kann mir vorstellen, daß die Zeit von einer zur nächsten Synchronisierung auch mit dem 3.6 MHz Quarz ausreichend genau bestimmt werden kann. Ob Du den Uhrenquarz brauchst kommt drauf an, was Dein Ziel ist, und wie oft der PC über die serielle Schnittstelle die Zeit korrigieren kann. Soll das Gerät autonom agieren können, wäre es sinnvoll ein ausreichend exaktes Zeitnormal drin zu haben. Du kannst nicht an jeden Atmel einen zweiten Quarz anschließen, verwendest Du z.B. den Mega32, dann geht das. Der hat einen RTC, Real Time Counter. Der kann auch im Power-Save Modus weiterarbeiten und macht damit ein batteriebetriebenes Gerät möglich.
Ich hab den Atmega 16, dann muss ich den Quarz an Tosc1 und machen oder? Brauch ich dann noch 2 Kondensatoren oder kann man intern irgendwelche aktivieren?
Nein, beim ATMega16 musst Du den Quarz zwischen TOSC1/TOSC2 Pin 28/29 anschließen. Ohne Kondensatoren. Timer2 wird dann zum RTC, AS2 im ASSR Register für asynchronen Mode setzen. Datenblatt Seite 135.
Ok vielen DANK ich werd es morgen gleich probieren. Jetzt hab ich nur noch das Problem das ich noch nich weiß wie ich am genausten auf 115,5 sekunden komme mit den Uhrenquarz.
Prescaler 1024, OVFL ISR aufsetzen, darin einen Zähler hochzählen, bei 32 ist eine Sekunde vergangen, bei 16 eine Halbe. Hier würde es sich anbieten jede halbe Sekunde einen Zähler hochzuzählen. Wenn der den Wert 231 erreicht hat, sind 115,5 Sekunden rum.
Oops, gerade gemerkt, daß ich mich bei Prescaler und der Rechnung dazu vertan habe. Der Timer2 läuft nur bei Prescaler 64 jede halbe Sekunde über. Damit dann den 155,5 Sekunden Zähler hochzählen. Alternativ kannst Du eine COMP ISR mit größerem Prescaler in Verbindung mit CTC aufsetzen. Hätte den Vorteil, daß für Batteriebetrieb das Aufwecken aus dem Sleep variabel gestaltet werden kann. Das spart Strom.
WIeso mit dem Prescaler bei 1024 stimmt es doch. 1/32678*1024*16=0,5 sekunden oder täusch ich mich da gerade?
ach verdammt ich hab die Zahlen verdreht du hast recht
JA!!! Also bis jetzt geht alles mal schaun ob es syncron bleibt. Danke nochmal für alles.
Super. Gern geschehen. Ich glaube nicht, daß die Synchronisierung absolut über die Uhrzeit geschieht, denn dann könnte sich auch unter günstigen Umständen ein Fehler aufgrund Quarztoleranzen einschleichen. Deshalb denke ich, daß nach jeder erfolgreichen Übertragung die Synchronisierung neu erfolgt, d.h. die Heizungssteller ihren Timer neu starten. Die Abweichung des Uhrenquarzes während 115 Sekunden ist minimal, und es kann sich damit kein Fehler aufsummieren. Du hast die Zeit dafür raus, wenn's über ein paar Minuten läuft, sollte es auch auf Dauer funktionieren. Kannst ja über Deine Erfahrungen berichten und den Code hier reinstellen.
ALso ich habs jetzt mehrer Stunden getest und bis jetzt ist er nicht in die Notabschaltung gegangen und er lässt sich verstellen. Hier mein Code, ich sende den Atmega über die usart Schnittstelle die befehle. Der Rest ist fast selbst erklärend.
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | #include <stdlib.h> |
4 | #include "global.h" |
5 | #include "uartsend.h" |
6 | #include "i2cmaster.h" |
7 | #include "FS20.h" |
8 | |
9 | #define F_CPU 8000000UL
|
10 | #include <util/delay.h> |
11 | |
12 | unsigned char timer_position; |
13 | unsigned int letzter_befehl; |
14 | |
15 | |
16 | // ITimer2 überlauf nach 0,5 Sekunden 115,5s/0,5 = 231
|
17 | |
18 | ISR (TIMER2_OVF_vect) |
19 | {
|
20 | TCNT2= 0; |
21 | timer_position++; |
22 | if (timer_position==231) |
23 | {
|
24 | TCNT2= 0; |
25 | //zuletzt gesendeter Befehle wird wieder geschickt
|
26 | Heizung_code_senden(0x00,letzter_befehl); |
27 | Heizung_code_senden(0x00,letzter_befehl); |
28 | timer_position=0; |
29 | print("senden"); |
30 | }
|
31 | }
|
32 | |
33 | //ISR (USART_RXC_vect)
|
34 | void uart_empfangen() |
35 | {
|
36 | //sei();
|
37 | unsigned char rx_daten; |
38 | rx_daten = UDR; |
39 | _delay_ms(50); |
40 | switch(rx_daten) |
41 | {
|
42 | case 1:steckdose1_an();break; |
43 | case 2:steckdose1_aus();break; |
44 | case 3:steckdose2_an();break; |
45 | case 4:steckdose2_aus();break; |
46 | case 5:steckdose4_an();break; |
47 | case 6:steckdose4_aus();break; |
48 | case 7:Alarmzeit();break; |
49 | case 8:Heizung_stellen();break; |
50 | case 9: |
51 | {
|
52 | print("lernen"); |
53 | Heizung_code_senden(0x00,0x2F00); |
54 | Heizung_code_senden(0x00,0x2F00); |
55 | letzter_befehl=0xA600; |
56 | _delay_ms(4000); |
57 | timer_position=0; |
58 | TCNT2= 0; |
59 | Heizung_code_senden(0x00,letzter_befehl); |
60 | Heizung_code_senden(0x00,letzter_befehl); |
61 | }break; |
62 | case 10: |
63 | {
|
64 | print("Licht an"); |
65 | Dimmer_code_senden(0x00,0x10); |
66 | Dimmer_code_senden(0x00,0x10); |
67 | Dimmer_code_senden(0x00,0x10); |
68 | }break; |
69 | case 11: |
70 | {
|
71 | print("Licht aus"); |
72 | Dimmer_code_senden(0x00,0x00); |
73 | Dimmer_code_senden(0x00,0x00); |
74 | Dimmer_code_senden(0x00,0x00); |
75 | }break; |
76 | default:; |
77 | }
|
78 | }
|
79 | |
80 | int main(void) |
81 | {
|
82 | initUART(); |
83 | steckdoseninit(); |
84 | i2c_init(); |
85 | //Heizung_init();
|
86 | timer_position=0; |
87 | //timer einstellungen
|
88 | TIMSK= 0b01000000; |
89 | TCCR2= 0b00000100; |
90 | ASSR=0b00001000; |
91 | |
92 | print("Init fertig"); |
93 | TCNT2= 0; |
94 | sei(); |
95 | |
96 | for (;;) |
97 | {
|
98 | if(UCSRA&(1<<RXC)) uart_empfangen(); |
99 | //Wert wird von Ehctzeit Uhr gelesen, hat aber nix mit dem Timer für den Heizungsregler zutun
|
100 | read_clock(); |
101 | }
|
102 | }
|
103 | |
104 | |
105 | void read_clock() |
106 | {
|
107 | i2c_start(adresse+I2C_WRITE); |
108 | i2c_write(0x00); |
109 | i2c_rep_start(adresse+I2C_READ); |
110 | sekunde = i2c_readAck(); |
111 | minute = i2c_readAck(); |
112 | stunde = i2c_readNak(); |
113 | // hier kann dann später auch das datum mit ausgelesen werden
|
114 | stunde= (((stunde>>4) & 0x03)*10)+ (stunde & 0x0F); |
115 | minute= (((minute>>4) & 0x07)*10)+ (minute & 0x0F); |
116 | sekunde= (((sekunde>>4) & 0x07)*10)+ (sekunde & 0x0F); |
117 | i2c_stop(); |
118 | }
|
119 | |
120 | void Alarmzeit() |
121 | {
|
122 | alarmstunde = uart_getc(); |
123 | asm("nop"); |
124 | asm("nop"); |
125 | asm("nop"); |
126 | alarmminute = uart_getc(); |
127 | |
128 | }
|
129 | |
130 | |
131 | uint8_t uart_getc(void) |
132 | {
|
133 | while (!(UCSRA & (1<<RXC))) ; // warten bis Zeichen verfuegbar |
134 | return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben |
135 | }
|
136 | |
137 | |
138 | void Heizung_stellen() |
139 | {
|
140 | unsigned char wert; |
141 | wert=uart_getc(); |
142 | letzter_befehl=0xA600+wert; |
143 | }
|
Danke für den Code, freut mich daß er geht. Ich hab' momentan nur Einige der FS20 Funkschaltdosen im Einsatz, sind von guter Qualität und Reichweite. Nur der Funk Timer den ich letzthin bestellt habe, war schon mal aus der Schachtel kaputt. Endkontrolle findet leider beim Kunden statt. Ging aber nach Einlöten eines neuen Uhrenquarzes wie er sollte. Den Code den Du geschrieben hast, kann man immer brauchen. Wobei ich Bascom mit Assembler bevorzuge. C kann ich lesen als auch schreiben, brauch' nur länger dafür, da ich wenig Übung drin habe. Wie ich sehe, hast Du einen Echtzeituhr über I2C dran. Die hättest Du übrigens auch über sleep / power save und dem asynchronen Timer2 direkt im Mega16 realisieren können. Geht recht gut, Stromverbrauch ist auch gering, da man den µC nur aufweckt, wenn man die Sekunde updated. Wenn man Timer2 und Prescaler ausnutzt, muss man nur alle 8 Sekunden aufwecken. Und nach 115 Sekunden muss der µC sowieso aktiv werden, damit der Heizungssteller zufrieden ist.
Ich habe oben in der Beschreibung gelesen, dass du Pollin Funksteckdosen "auch" damit ansteuerst. Hast du auch dafür eine Anleitung/Program? Es kann also FS20, FHT und Dimmer auf FS20-Basis. Die Pollin-Geschichte hat ja ein ganz anderes Datenformat, hast du es nachgebildet? Mit Dimmer-Funktion.
Ja hab ich auch. Hier ist der Code und der Verweis auf die Seit mit dessen Hilfe ich das zusammen gesetzt hab. Sind bis jetzt nur 3 Steckdosen, wird aber diese Woche um 3 weiter erweitert. Du musst nur auf die Adresse achten die du dann bei den Steckdosen einstellst. http://avr.börke.de/Funksteckdosen.htm Ich hoffe es Hilft dir. @MWS das mit der Echtzeituhr war damals nur mein erster Schritt, damit ich zu einer bestimmten Uhrzeit geweckt wurde. Ich wusste ja vor ein paar Tagen noch nich das man an den Atmega16 noch nen Uhrquarz dranhängen kann. Danke nochmal;)
Und ja es kann zurzeit FHT und die Dimmer, aber es lässt sich denk ich mal mit allen Dingen aus der FS20 Serie erweitern. FS20 Funksteckdosen gehen damit auch, weil sie fast genau so wie die Dimmer arbeiten
Hallo! @Christian Lutze Könnte man über den Timer auch mehrere FHT ansteuern in unterschiedlichen Räumen? Es gibt ja ein Modul von ELV was 4 Stück ansteuern kann, aber das is doof. Danke Gruß Denny
Jo klar man muss nur noch neue "timer_position" und "Stellungs" Variablen einführen damit jedem empfänger ca. alle 2 min seine stellung gesendet wird.
Hallo! So der FHT quittiert schon mal den Empfang mit einem Pips! Nun will ich noch die 115,2 sek über Timer 1 realisieren, wie mache ich das? Mein Quarz ist ein 20MhZ! Habe jetzt schon ewig hier hin und her gerechnet, aber auf 0,5 sek für den Timer1 komme ich! Ja und ich habe das Tuturial gelesen! Gruß Denny
Der ist zwar nicht ganz genau: http://www.avr-praxis.de/forum/attachment.php?attachmentid=983&d=1240469666 Gruß jochen PS. Kannst du den Code mal anhängen?
Hallo! Hat sich zufällig noch jemand von euch mit den FHT8 Stellantrieben beschäftigt? Ich messe bei mir immer ein Zeitfenster zum Empfangen von 118 sek! Nun sende ich auch alle 118 sek und das scheint ganz gut zu passen. Gruß Denny
Also bei mir sind es 115,5 Sekunden. Und das ganze realisiere ich mit dem Timer2 und einen externen Uhrenquarz, damit kannst du den Timer so einstellen das bei eienm Überlauf genau 0,5s vorbei sind.
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.