Forum: HF, Funk und Felder rfm sendeproblem


von Christian (Gast)


Lesenswert?

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
void send(void);
12
void receive(void);
13
14
int main(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
void receive(void)
34
{  unsigned char test[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
void send(void);
10
void receive(void);
11
12
int main(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 (unsigned char i=0; i<100; i++){
26
      _delay_ms(3);
27
    }    
28
    send();
29
    LED_AUS(LED1);
30
    for (unsigned char i=0; i<100; i++){
31
      _delay_ms(3);
32
    }
33
  }
34
35
}
36
void send(void)
37
{  unsigned char test[]="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

von Stefan H. (Firma: dm2sh) (stefan_helmert)


Angehängte Dateien:

Lesenswert?

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

von Christian (Gast)


Lesenswert?

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

von Stefan H. (Firma: dm2sh) (stefan_helmert)


Lesenswert?

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.

von Christian (Gast)


Lesenswert?

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

von Christian (Gast)


Lesenswert?

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_t w=0;w<1000;w++) LED2(1);
2
for(uint32_t w=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?

von Christian (Gast)


Lesenswert?

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
int main(void)
2
{
3
  gRXptr = 0;
4
  uint16_t test;
5
  uint32_t w;
6
  uint32_t v;
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
  return 0;

Die Funktion RXfunc hab ich umgeschrieben zu (wenn ein Oktett empfangen 
wird, dann soll die LED leuchten):
1
void RXfunc(uint8_t recv_octet)
2
{
3
  uint32_t x;
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

von Stefan H. (Firma: dm2sh) (stefan_helmert)


Lesenswert?

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.

von Christian Maurer (Gast)


Lesenswert?

Hallo Stefan,

habe jetzt den Frame angepasst wie du gesagt hast und die ACK-Methode 
umgebaut, jetzt funktionierts :)

Danke!
LG

von Stefan H. (Firma: dm2sh) (stefan_helmert)


Lesenswert?

Siehste, kaum macht man es richtig, funktioniert es.

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
Noch kein Account? Hier anmelden.