Hallo zusammen,
ich habe mich seit einigen Wochen mit den RFM12 Modulen und den AVR
Evaluationsboards von Pollin beschäftigt. Nun hab ich mir aus diversen
Quellen (hier im Forum und im Netz) Code zusammengesucht und auf die
Controller gespielt. Zum Test hab ich auch die LEDs angesteuert um zu
sehen, was das Board jeweils macht. Beim Empfangen hab ich die LED 1
einfach eingeschaltet (als Status "Wartend") und die LED 2 wenn ein
passendes Zeichen [bei mir "T") übermittelt wird).
1
/*config for atmega16 and atmega8*/
2
#define F_CPU 1600000UL
3
// LEDs sind active-high geschaltet
4
#define LED_AN(LED) (PORTD |= (1<<(LED)))
5
#define LED_AUS(LED) (PORTD &= ~(1<<(LED)))
6
#define LED1 PD6
7
#define LED2 PD5
8
9
#include<util/delay.h>
10
11
voidsend(void);
12
voidreceive(void);
13
14
intmain(void)
15
{
16
rf12_init();
17
rf12_setfreq(RF12FREQ(433.92));
18
rf12_setbandwidth(4,1,4);
19
rf12_setbaud(19200);// 19200 baud
20
rf12_setpower(0,6);
21
22
DDRD|=(1<<LED1)|(1<<LED2);// Port D: Ausgang für LED1 und LED2
23
LED_AUS(LED2);
24
LED_AN(LED1);
25
while(1)
26
{
27
receive();
28
}
29
30
}
31
32
33
voidreceive(void)
34
{unsignedchartest[5];
35
rf12_rxdata(test,5);
36
if(test[0]=="T"){
37
LED_AN(LED2);
38
}
39
}
Auf der anderen Seite habe ich das Sendemodul, welches immer "T" senden
soll. Als Statuskontrolle soll LED 1 leuchten.
1
#define F_CPU 1600000UL
2
#define LED_AN(LED) (PORTD |= (1<<(LED)))
3
#define LED_AUS(LED) (PORTD &= ~(1<<(LED)))
4
#define LED1 PD6
5
#define LED2 PD5
6
7
#include<util/delay.h>
8
9
voidsend(void);
10
voidreceive(void);
11
12
intmain(void)
13
{
14
rf12_init();// ein paar Register setzen
15
rf12_setfreq(RF12FREQ(433.92));// frequenz auf 433,92MHz
16
rf12_setbandwidth(4,1,4);
17
rf12_setbaud(19200);
18
rf12_setpower(0,6);
19
20
DDRD|=(1<<LED1)|(1<<LED2);// Port D: Ausgang für LED1 und LED2
21
22
while(1)
23
{
24
LED_AN(LED1);
25
for(unsignedchari=0;i<100;i++){
26
_delay_ms(3);
27
}
28
send();
29
LED_AUS(LED1);
30
for(unsignedchari=0;i<100;i++){
31
_delay_ms(3);
32
}
33
}
34
35
}
36
voidsend(void)
37
{unsignedchartest[]="T\n ";
38
rf12_txdata(test,5);
39
}
Beim Senden wird die LED 1 aber nur angeschaltet und ändert sich danach
nicht mehr, das Senden scheint nicht durchzulaufen und Empfangen tu ich
auch nichts (auf der Empfängerseite).
Hab die Microcontroller schon getauscht (also den vom Senden und vom
Empfangen mit dem Verdacht, dass vielleicht eine Komponente (der
Controller oder das Funkmodul kaputt ist) aber ich hab bei beiden Boards
beim Senden das selbe Problem. Ich habe die Pinbelegung mit
Durchgangsprüfer und Datenblatt von RFM und ATMega16 geprüft, hier
scheint alles so zu sein wie es hier in diversen Artikeln beschrieben
wird (bzw. wie ich die Pins im rf12.c eingestellt habe).
1
/*config for atmega16*/
2
#define F_CPU 1600000UL
3
#define SDI 5
4
#define SCK 7
5
#define CS 4
6
#define SDO 6
Nun meine Frage: Kann mir jemand einen Hinweis geben, warum ich keine
Daten senden kann bzw. die Sende-Routine nicht durchzulaufen scheint?
Hab darauf geachtet, dass der Code für den Atmega 16 compiliert wird und
die LEDs leuchten ja (also das Programm läuft definitiv). Bin jetzt
leider seit 2 Tagen nicht weitergekommen und wäre um jeden Tipp dankbar.
LG
Christian
Das kann vieles sein:
* nicht lange genug gewartet nach Reset
* Sender nicht angeschaltet
* NIRQ vom Funkmodul nicht verbunden, rf12_txdata braucht aber dieses
Signal
Probier mal meinen Code
Hallo Stefan,
danke zuerst für deine Hilfe. War schon knapp vor dem Aufgeben. Deine
Punkte kann ich soweit ausschließen (mit dem Warten und dem einschalten
des Senders, da die LED's ja angegangen sind). Allerdings hab ich den
NIRQ bei den ersten Versuchen nicht verbunden gehabt, das hab ich aber
nachgeholt.
Ich habe nun deinen Quellcode genommen und auf den ATMega16
umgeschrieben, hab das Register für die Interrupts auf GICR geändert,
die Pinbelegung ist ja dieselbe.
Nun hab ich auch hinbekommen, dass der Sender sendet (LED 1 blinkt) und
beim Empfänger leuchtet diese auch kurz auf. Allerdings hört genau in
dem Moment, in dem ich den Empfänger einschalte der Sender auf zu senden
(LED 1 erlischt).
Ich habe daher den Verdacht, dass der Empfänger (der beim Einschalten ja
einen Frame sendet)
1
#ifdef EMPF
2
gOperation=0;
3
rf12_sendframe(RF12_example_frame);
am Sender einen Interrupt auslöst und diesen "abschießt". Hab ich in der
Konfiguration was übersehen oder schaut das wie eine Fehlfunktion des
Boards bzw. RFM12 aus?
Danke und LG
Christian
Ne, das ist so beabsichtigt. Der Empfänger bestätigt die Nachricht. Der
Sender weiß dann, dass er aufhören kann mit senden. Zum erneuten Senden
musst du PORTA.0 mit Masse verbinden.
Du musst das Board, das empfangen soll mit
#define EMPF
als Empfänger definieren.
Am Empfänger PORTD.7 kommt ein Lautsprecher ran. Der Piept kurz, wenn du
am Sender den einen Port mit Masse verbindest.
Haha... ok... das hab ich verschwitzt, sorry. Bin beim C-Code lesen noch
etwas langsam. Den Empfänger habe ich richtig definiert, das hat
hingehaut.
Vielen Dank für deine super Hilfe!
LG
Hi Stefan,
hab nun noch eine Frage, die ich mir beim genauen testen nicht
beantworten konnte: Wenn ich die Zeile bei der Empfänger-Definition
ändere und keinen Frame sende, sondern den Empfänger nur für den Empfang
aktiviere, dann müsste der Sender ja auch endlos senden (tut er auch).
1
#ifdef EMPF
2
gOperation=0;
3
//rf12_sendframe(RF12_example_frame);
4
rf12_activateRX;
Meine Frage ist aber, warum der Empfänger nicht mehr auf die Oktetts
reagiert (in der RXfunc). Dort habe ich einfach ein
1
for(uint32_tw=0;w<1000;w++)LED2(1);
2
for(uint32_tw=0;w<1000;w++)LED2(0);
eingebaut, und die Zeile grf12_frame_rdy_fp = rf12_activateRX; ist
deaktivert (der Empfänger soll kein Byte senden, braucht nach dem Senden
also auch nicht aktiv sein) damit der Empfänger bei jedem empfangenen
Byte einfach blinkt... leider macht er das aber nicht. Kannst du mir
nochmal auf die Sprünge helfen?
Hallo zusammen,
ich muss mich nochmal mit meiner Frage melden, da ich es nun trotz
mehrmaligen probieren nicht geschafft hab... also der Sender sendet
seine Pakete "ganz normal". Im Empfänger habe ich folgendes Programm:
1
intmain(void)
2
{
3
gRXptr=0;
4
uint16_ttest;
5
uint32_tw;
6
uint32_tv;
7
LED2(0);
8
RF12_init();
9
uart_init();
10
UDR='A';
11
test=rf12_cmd_transfer_blocking(0xFE00);
12
//wichtig! nach softreset warten
13
for(w=0;w<3000;w++){
14
LED2(1);
15
}
16
17
LED2(0);
18
19
// Bei ds (double speed) meist Störung
20
SPI_ns
21
22
23
//Funktion, die gerufen wird, wenn ein Octet empfangen wurde
24
grf12_recv_fp=RXfunc;
25
26
27
#ifdef EMPF
28
rf12_activateRX;
29
#else
30
gOperation=1;
31
#endif
32
33
while(1){
34
//warten und auf interrupt reagieren
35
}
36
37
38
39
return0;
Die Funktion RXfunc hab ich umgeschrieben zu (wenn ein Oktett empfangen
wird, dann soll die LED leuchten):
1
voidRXfunc(uint8_trecv_octet)
2
{
3
uint32_tx;
4
5
for(x=0;x<3000;x++){
6
LED1(1);
7
}
8
LED1(0);
9
}
Ich hab am Empfänger beim Programmstart das Kontrollleuchten der LED,
also sollte soweit alles passen. Nur: obwohl der Sender sendet, bekomme
ich am Empfänger kein Leuchten der "Empfangs-LED" aus der Funktion
RXfunc. Sind meine Änderungen so falsch oder woran kann's liegen?
Eingeschaltet und lange genug gewartet habe ich (die Kontroll-LED beim
Programmstart hat ja auch geleuchtet). Hab ich einen offensichtlichen
Fehler in den Änderungen die ich gemacht hab?
LG
Christian schrieb:> eingebaut, und die Zeile grf12_frame_rdy_fp = rf12_activateRX; ist> deaktivert (der Empfänger soll kein Byte senden, braucht nach dem Senden> also auch nicht aktiv sein) damit der Empfänger bei jedem empfangenen> Byte einfach blinkt... leider macht er das aber nicht. Kannst du mir> nochmal auf die Sprünge helfen?>
Du hast das glaube ich gerade vertauscht. RX steht für Empfangen. Das
muss also drin bleiben. Die andere Zeile auch, da der Empfänger erst
dann in den Empfangsmodus wechselt, wenn er den Rahmen gesendet wird.
Er wartet sozusagen auf die Antwort. Besser ist es, den
RF12_example_frame anders zu definieren. Man lässt den Sendeteil weg und
wechselt gleich zum Empfangsmodus.
In die RXfunc darf gar nichts rein, was lange dauert. Sie nimmt nur die
Octets entgegen und legt sie in ein Array ab.
Wenn du mehrfach senden willst, musst du nur beim Sender die Rahmen
immer wieder senden.