Hallo,
ich baue derzeit einen Empfänger (Sender ist schon fertig), der über das
Aurel 433MHz-Modul ein Rechteckssignal ausgibt. Ich würde gerne den
AtTiny13 dafür verwenden, um das Digitale Signal aufnehmen und auf seine
"richtigkeit" und reihenfolge zu prüfen - sprich, stimmt das Empfangene
Signal mit dem von mir vorgegebenen Signal überein, so so er eine LED
testweise einschalten.
Bis jetzt habe ich folgendes:
1
#define F_CPU 960000UL
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
5
6
// Sendefolge: 11110001 Binär: 0b10001111
7
8
volatileuint8_tcode=0x00;
9
volatileuint8_tbreakcount=0;
10
uint8_tready=0;
11
uint8_tactive=0;
12
13
ISR(INT0_vect){
14
TCNT0=0;//Rücksetzen des "Auszähltimers"
15
code=0x00;
16
breakcount=1;
17
GIMSK&=~(1<<INT0);//deaktivieren des externen Interrupts, wenn
Klappt aber nicht so ganz, wie ich mir das vorstelle, habt ihr eine
Idee, wie ich das mit dem Tiny lösen kann? Oder muss ich doch zu einem
anderen µController greifen?
Habe bereit im Forum ca. 5 Stunden lang herum gesucht, wurde aber nicht
fündig. Vielleicht habe ich auch nur nach den falschen Begriffen
gesucht.
Ich danke euch trotzdem schoneinmal im vorraus für euere Unterstützung.
Mfg
Mattias
Ohhh nein, habe den Oszilator (intern) auf 9,6MHz eingestellt.
Verdammt^^
Mir passieren immer so kleine Fehler.
1
#define F_CPU 9600000UL
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
Bin C++ Programmierer für Windows, habe mit dem µC erst angefangen.
Erkennt sonst noch jemand einen Fehler? habe es nocheinmal versucht,
funktioniert trotzdem nicht.
Danke!
Hallo,
was gibt dein Empfangsmodul aus wenn dein Sender nicht sendet?
Nach kurzem Blick ins Datenblatt - wenn ich das richtige erwicht habe -
kommt dort in dem Falle ein digitales Rauschen raus. Damit decodiert
deine Software ständig irgendwas und es währe Zufall wenn während einer
Sendephase die Auswertung an der richtigen Bitposition beginnt.
Am Sender brauchst du also ein Startbit das du aufgrund seiner Dauer am
Empfänger eindeutig idendifizieren kannst. Dann kannst du auch nicht
damit rechnen, das bei einer Funkübertragung das Signal störungsfrei am
Empfänger ankommt - einfach den Bitzustand einlesen wird daher auch
nicht funktionieren.
Schau dir mal die IR-Protolle an - die kannst du auch für Funk nehmen
und es gibt auch schon passenden Routinen.
Sascha
Zuerst einmal - danke.
Im Anhang habe ich das Datenblatt des Empfängers eingefügt, das ich zu
dem Modul erhalten habe. Das Modul habe ich übrigens bei Conrad gekauft.
Bei der Artikelbeschreibung des Moduls sind auch Datenblätter, die sind
jedoch anders als die, die ich hier habe.
Mfg
... gut dann hatte ich das richtige Datenblatt.
Der Ausgang des Moduls liefert nur dann ein stabiles Signal wenn ein
Träger auf der entsprechenden Frequenz gesendet wird. Ansonsten hast du
nach einigen 10..100ms nur Rauschen am Ausgang. Deshalb sollte man die
Daten auch nicht so senden wie du, da dort zu viel
'Gleichspannungsanteil' vorhanden ist (u.u. viele aufeinanderfolgende
0'en oder 1'sen).
Sascha
Okay, d.h. ich soll die Übertragungsgeschwindigkeit erhöhen!?
Derzeit liegt die Länge für ein Bit bei 10,05ms. (War eigentlich nur zum
Test)
Also fasse ich nochmal meine Änderungen zusammen:
* Übertragungsgeschwindigkeit erhöhen auf max. 250µS/Bit also 4KHz
* Startbits setzten z.b. 2ms High (VCC)
* Dann z.b. ein 8 Bit Datensatz übertragen
Könnte das dann so ungefähr klappen?
Lg
Gleichspannungsfrei senden bedeutet, eine andere Codierform benutzen,
das meint er.
Z.B. Manchestercode. Schau mal bei Wikipedia danach, dort findest du
dieser Code ist Gleichspannungsfrei. Alternativen ebendort.
Mattias Köpke schrieb:> Okay, d.h. ich soll die Übertragungsgeschwindigkeit erhöhen!?
nicht unbedingt
> Derzeit liegt die Länge für ein Bit bei 10,05ms. (War eigentlich nur zum> Test)
nicht die Bits direkt kodieren, sondern den Bitzustand in der
Sendedauer, oder Pausenlänge kodieren
schau mal hier bei den IR-Protokollen
http://www.mikrocontroller.net/articles/IRMP#Die_IR-Protokolle_im_Detail
Die angegebene Frequenz kannst du natürlich vergessen, die ist bei dir
ja 433MHz.
>> Also fasse ich nochmal meine Änderungen zusammen:> * Übertragungsgeschwindigkeit erhöhen auf max. 250µS/Bit also 4KHz
Wenn du nicht viele Daten zu übertragen hast, kann die Sendendauer ruhig
ein paar ms dauern
> * Startbits setzten z.b. 2ms High (VCC)
ja - auf jeden Fall so, das es sich von einem Datenbit deutlich
unterscheidet
> * Dann z.b. ein 8 Bit Datensatz übertragen
z.B.
> Könnte das dann so ungefähr klappen?
mit der zum Protokoll passenden Auswertung auf jeden Fall
Die Pulse-Distance Protokolle währen sicher ein Ansatz für dich, mit dem
Timer lassen sich die Signal- und Pausenlängen gut messen, eine gewisse
Filterung gegen Störungen musst du aber einbauen, so das kurze Spikes
die Messung nicht sofort beenden.
Sascha
warum greifen nur so viele zu den AM-Modulen ...
Hab mit den Dingern vor Jahren mal rumgespielt, der Haken daran ist,
dass wenn die Sendung für kurze Zeit aussetzt die Geschichte ausschwingt
und bei Wiederaufnahme der Sendung die ersten paar ms der Übertragung
ins Nirvana gehen. Darum sendet man bei AM erst ne Präambel und danach
in Manchester Code wenns Daten sein sollen.
Es gibt aber auch FM-Module von Aurel, die hatten das in meinen
versuchen nicht.
Danke ihr seid mir eine große Hilfe!
Ich werde das in den kommenden Tagen in Angriff nehmen.
@elektronikbastler:
Sorry, das ist mein erstes Projekt mit Funk, ich habe damit wenig
Erfahrung.
Trotzdem danke für eure Tollen, Ausführlichen und schnellen Antworten!
Meld mich wieder.
Lg
Mattias
Soo,
ich habe mir das IR-Protokoll mal angesehen, ihr meintet mir dem
"Gleichspannungsanteil" nehme ich mal an folgendes:
Start-Bit 2400µs Puls, 600µs Pause
0-Bit 600µs Puls, 600µs Pause
1-Bit 1200µs Puls, 600µs Pause
Ich habe ja jeweils für das Bit 0 und 1 10ms "Bitdauer" gehabt. Und
das soll ich ändern!?
lg
Mattias
Mattias Köpke schrieb:> Soo,>> ich habe mir das IR-Protokoll mal angesehen, ihr meintet mir dem> "Gleichspannungsanteil" nehme ich mal an folgendes:>> Start-Bit 2400µs Puls, 600µs Pause> 0-Bit 600µs Puls, 600µs Pause> 1-Bit 1200µs Puls, 600µs Pause
genau - jedes übertragene Bit sollte aus einer Sendephase und einer
Sendepause bestehen.
> Ich habe ja jeweils für das Bit 0 und 1 10ms "Bitdauer" gehabt. Und> das soll ich ändern!?
Die Zeiten kannst du relativ frei wählen, nur die Pause sollte nicht zu
lang werden sonst kommt in der Zwischenzeit wieder Rauschen am Ausgang
raus.
Sascha
Ich denke da brauchst du nur einen Timer für. Und vermeide gleich von
Anfang an mit dem Ausgang vom Aurel einen Interrupt auszulösen. Der hat
am Ausgang genügend kurze Spikes die dich in den Wahnsinn treiben
werden. Lass den Timer z.b. mit 100us oder mehr einen zyklischen
Interrupt auslösen und sample dann. Dann sind die Spikes kein Problem
mehr und auch das Rauschen, wenn lange kein Signal anliegt, wird nicht
zur unkalkulierbaren Interruptquelle. Die benötigte Zeit im Interrupt
dürfte bei geschickter Programmierung vetretbar sein.
du brauchst ja nur einen Timer, mit dem du die Zeiten misst. Man könnte
immer bis zu einem Signalwechsel warten und dann den Timerwert lesen
(Impus- oder Pausendauer), und diesen anschließend wider auf Null
zurücksetzen. Und auf den nächsten Signalwechsel warten. Das Problem bei
diesem Ansatz ist nur, das auch sehr kurze Störimpulse als Signalwechsel
erkannt werden. Bei einem IR-Empfäger geht das noch bei Funk nur bei
sehr gutem Empfang.
Für das Auslesen eines Funkaußensensors einer Wetterstation hab ich
folgenden Ansatz gewählt.
Bsp: Startbit 5ms, Bitpause 1ms, 0-Bit 1ms, 1-Bit 2ms
Das Eingangssignal wird mit einem Timer im Abstand von 0.1ms eingelesen
(1/10 der kürzesten Bit/Pausenzeit).
Mit einem Zähler lässt sich erst mal das Startbit recht zuverlässig
erfassen.
Für jeden 1ms-Abschnitt gibts im RAM ein Byte.
Nach dem erkennen des Startbit's, wird der Wert im korrespondierenden
Byte im RAM je nach Eingangssignal um eins erhöht oder verrigert. Nach
10 Messungen wird ins nächste Byte geschrieben. Dadurch ergibt sich eine
einfache Majoritätsfunktion, mit der sich Störungen rech gut filtern
lassen.
Die Erfassung läuft immer bis zum Ende durch, auch wenn das
Eingangssignal aufgrund der unterschiedlichen Bitdauern mal kürzer, oder
länger sein kann.
Danach kannst du die gespeicherten Daten in Ruhe auswerten.
Sascha
Mattias Köpke schrieb:> Soll ich den Timer dann im CTC Mode laufen lassen?
Kommt darauf an an welcher Messmethode du dich versuchen willst.
Für das Sampling mit konstanter Zeit - ja
Für das einfache Messen der Bitdauer - nein
Sascha
Mattias Köpke schrieb:> Ich würde gerne das Messen der Bitdauer versuchen, kommt mir sinnvoller> vor.
ja bitte - Versuch mach kluch ;-)
Dann lass den Timer mit einer Geschwindigkeit laufen (Vorteiler), das
bei den Zeiten die du messen willst der Timer (8- o. 16-Bit) möglichst
weit ausgeschöpft wird aber kein Überlauf auftritt. Ein Überlauf währe
dann schon mal ein Anzeichen, das das Signal nicht gültig sein kann. Die
'krume' Messdauer die sich aus dem Vorteiler ergibt brauch dich ja nicht
interessieren - das kann der Compiler ja bei der Erstellung des
Programms für dich berechnen.
Sascha
Sascha Weber schrieb:> Dann lass den Timer mit einer Geschwindigkeit laufen (Vorteiler), das> bei den Zeiten die du messen willst der Timer (8- o. 16-Bit) möglichst> weit ausgeschöpft wird aber kein Überlauf auftritt.
D.h. wenn mein
Bit 1: 300µs lang,
Bit 0: 400µs lang
meine Pause 600µs lang wäre, müsste mein Timer an der Grenze von 1000µs
= 1ms oder an der Grenze 600µs liegen?
Lg
4800000 ms µs
clk 5,333E-05 5,333E-02 5,333E+01
clk/8 0,000426667 0,426666667 426,6666667
clk/64 0,003413333 3,413333333 3413,333333
clk/256 0,013653333 13,65333333 13653,33333
clk/1024 0,054613333 54,61333333 54613,33333
Das sind die möglichen Zeiten, die ich nutzten könnte, bevor der Timer
einen Overflow aufruft.
Lg
Ich denke der Ansatz ist immer noch nicht optimal. Du verpulverst im
deiner main-Schleife alle Zeit des mc und es bleibt nichts mehr für was
anderes übrig. Ausserdem fällt dein Code wieder auf jeden Spike herein
den er erwischen kann.
Im Beitrag:
Beitrag "S555HT AVR Beispielcode"
habe ich mal einen Weg für die ELV Wetterdatensender beschrieben. Das
Protokoll findest du hier:
http://www.dc3yc.privat.t-online.de/protocol.htm
Hier macht ein Timer einen zykl. Interrupt von 100us. Darin wir der Pin
abgefragt und festgehalten wieviel mal 0 oder 1 hintereinander kommen.
Dann wird dann bei jedem Wechsel von 0 auf 1 getestet ob die Zähler für
0 und 1 in dem Bereich liegen den eine Tabelle vorgibt. Daran wird dann
entschieden ob die Sequenz als 0 oder 1 oder Müll gewertet wird.
Ich teste im Interrupt den Pin alle 32us. Ist er 1 wird c1 erhöht, ist
er 0 wird c0 erhöht. Der Zustand am Pin wird sich gemerkt und der
Interrupt verlassen. Wenn im nächsten Interrupt der Pin 1 ist und der
gemerkte Zustand 0 (0-1 Flanke), dann sehe ich nach ob die Werte in c0
und c1 zum Protokoll passen, merke mir das gefundene Bit und verlasse
den Interrupt. Das wiederholt sich bis ich alle Bits habe. Das ist jetzt
nur eine grobe Beschreibung, für eine komplette Doku fehlt mir die Zeit.
Hallo,
ich hab mich nochmals an den Code gesetzt, und bin zu folgendem TEST
Ergebnis gekommen:
Ich sende erst mein Startbit (35us lang) dann eine 1 (120us Lang) und
dann eine 0 (30us).
1
#define F_CPU 9600000UL
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
5
6
// Sendefolge: 11110001 Binär: 0b10001111
7
//PB4 Data in
8
9
10
volatileuint8_tcode=0;
11
volatileuint8_tcode2=0;
12
volatileuint8_trec[8];
13
volatileuint8_tready=0;
14
uint8_tstartrec=0;
15
uint8_thigh=0;
16
uint8_tlow=0;
17
18
uint8_tin=0;
19
uint8_tbitcount=0;
20
21
// Sollwert für High: 116,725µs
22
//Sollwert für Low: 50,025µs
23
#define O_HIGHMAX 20 // 20*6,67µs = 133,4µs
24
#define O_HIGHMIN 15 // 15*6,67µs = 100,05µs
25
#define O_LOWMAX 10 // 10*6,67µs = 66,7µs
26
#define O_LOWMIN 5 // 5*6,67µs = 33,35µs
27
28
29
ISR(TIM0_OVF_vect){
30
in<<=1;
31
if(PINB&(1<<PB4))
32
in|=1;
33
34
if((in&0x1F)==0x1F)// 0x7 = 0b11111 Startbit müsste dann 5*6,67µs= 33,35µs lang sein
Ich habe es dank Jürgens Ansatz hinbekommen. Aber ein fehler habe ich
noch.. es funktioniert zwar, aber nur wenn ich am Sender Lange auf den
Knopf drücke und das ist ja nicht sinn der Sache, könnte mir da noch
jemand helfen?
1
#define F_CPU 4800000UL
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
5
6
// PB4 Data in
7
// 8 Bit übertagung
8
9
uint8_tcode=0;
10
volatileuint8_tcode2=0;
11
volatileuint8_tready=0;
12
uint8_tstartrec=0;
13
uint8_tbitcnt=0;
14
15
uint8_tin=0;
16
uint8_til=0;
17
uint8_tih=0;
18
19
// Sollwert für High: 700µs
20
// Sollwert für Low : 1000µs
21
// Pause : 500µs
22
23
#define LOWMAX 20 // 20*53,33µs = 1066,6µs
24
#define LOWMIN 18 // 18*53,33µs = 959,94µs
25
26
#define HIGHMAX 14 // 14*53,33µs = 746,62µs
27
#define HIGHMIN 12 // 12*53,33µs = 639,96µs
28
29
#define PAUSEMAX 11 // 11*53,33µs = 586,63µs
30
#define PAUSEMIN 8 // 8*53,33µs = 426,64µs
31
32
ISR(TIM0_OVF_vect){
33
34
//starten der Bitaufnahme
35
if(in>36)
36
startrec=1;
37
38
//Bitaufnahme gestartet
39
if(startrec==1){
40
if((PINB&(1<<PB4)))
41
ih++;
42
else
43
il++;
44
45
if(bitcnt==8){
46
if(!ready)
47
code2=code;
48
ready=1;
49
ih=0;
50
il=0;
51
bitcnt=0;
52
startrec=0;
53
in=0;
54
}
55
56
if(ih<HIGHMAX&&ih>HIGHMIN){
57
ih=0;
58
il=0;
59
code<<=1;
60
code|=1;
61
bitcnt++;
62
}
63
if(il<LOWMAX&&il>LOWMIN){
64
ih=0;
65
il=0;
66
code<<=1;
67
bitcnt++;
68
}
69
}
70
else
71
{
72
if((PINB&(1<<PB4)))
73
in++;
74
}
75
}
76
77
78
intmain(void){
79
DDRB|=(1<<PB3);
80
DDRB&=~(1<<PB4);// PB4 Eingang PB3 Ausgang
81
PORTB&=~(1<<PB4);
82
PORTB&=~(1<<PB3);
83
84
PORTB|=(1<<PB3);
85
_delay_ms(100);
86
PORTB&=~(1<<PB3);
87
88
TCCR0B=(1<<CS02);// Prescaler 256 Alle 53,33µs ein Overflow-Interrupt
Hallo,
das Startbit sollte immer wesentlich länger sein als die Datenbits,
sonst kann es sein das sich die Auswertung auf ein Datenbit als Startbit
syncronisiert und dann stimmt nix mehr.
Sascha
Hi,
so ein Infrarot Protokol ist ja als Beispiel auch nicht falsch.
Natürlich kann man bei Funk tie einzelnen Zeiten deutlich verkürzen
aber es stellt doch deutlich die Verhältnisse dar.
Fürs NEc protocol hat man hier
* a 9ms leading pulse burst (16 times the pulse burst length used
for a logical data bit)
* a 4.5ms space
* the 8-bit address for the receiving device 'erstes Datenbyte
* the 8-bit logical inverse of the address 'invers zur
fehlerkontrolle
* the 8-bit command '2 tes Datenbyte
* the 8-bit logical inverse of the command ' und wieder invers zur
kontrolle
* a final 562.5µs pulse burst to signify the end of message
transmission.
genaueres steht hier:
http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol
und auch hier:
http://www.mcselec.com/index.php?option=com_content&task=view&id=223&Itemid=57
Gruss Klaus
Wie schnell darf ich denn Maximal übertragen (laut Datenblättern)?
Bzw. wie kurz darf mein Pegel maximal sein?
Im Datenblatt steht was von 3KHz beim Empfänger, hat das etwas mit der
Übertragungsgeschwindigkeit zu tun?
@Klaus, die Protokolle kannste vergessen, ich kann keine Interrupts bei
steigender oder fallender Flanke benutzen wegen den Spikes. (Siehe
erster betrag).
Mattias
Ich hab mir gerade nochmal das Manchester Protokoll genau unter die Lupe
genommen - das ist mit dem Aurel Modulen gar nicht möglich, da ich mit
dem Pegel nicht ins negative gehen kann.
Lg
Mattias
Mattias Köpke schrieb:> Ich hab mir gerade nochmal das Manchester Protokoll genau unter die Lupe> genommen
WO?
> - das ist mit dem Aurel Modulen gar nicht möglich, da ich mit> dem Pegel nicht ins negative gehen kann.
wieso braucht man da negative Pegel??
0=GND und 1=+Ub genügen
Sascha