Forum: Mikrocontroller und Digitale Elektronik RFM12 Modul Probleme Komunikation mit Modul


von Sonke A. (soeni)


Lesenswert?

Hallo, ich habe eine Problem mit der Inbetriebname des RFM12 Moduls.

Folgende Hardware liegt vor:

Atmega128 mit HardwareSPI und entsprechend angeschlossenem RFM12 Modul.

Als Software versuchte ich diese Hier: 
Beitrag "Beispielprogramm für RFM12 433MHz Funk-Module"

Leider funktionierte diese nicht. Also erkundigte ich mich und kam 
darauf, dass es öfters probleme gibt, wenn man eine SoftwareSPI benutzt, 
also wollteich das umstellen auf HardwareSPI nur finde ich das 
Datenblatt des RFM12 Moduls nicht sehr aussagekräftig. Gibt es eventuell 
eine ähnliche Rutine, die mit der HardwareSPI arbeitet? (Ich habe leider 
keine Gefunden)

Oder kennt jemand eine gute beschreibung / Datenblatt /sonstige 
Beispiele zum RFM12 Modul, aus denen man die einzelnen Befehlssequenzen 
ablesen kann.

Ich scheiter leider schon daran nach der Initialisierung den Status des 
Moduls auszulesen.

Wäre schön, wenn ihr mir da helfen könntet.

Sönke

von Fasti (Gast)


Lesenswert?

Hi,

der verwendete IC auf den RFM Boards ist von Integration, jetzt Silabs, 
und zwar von IA4420/21. Einfach mal dort reinschauen und das Datenblatt 
saugen. Dort gibts auch einige nette Application Notes, mit denen kann 
man jedes Problem welches mit dem Chip auftaucht lösen.

Grüße

Fasti

von Sonke A. (soeni)


Lesenswert?

danke hab eins gefunden, aber irgendwie steht da auch nicht mehr drin, 
als bei Pollin, nur beispielschaltungen, jedoch kein beispielcode.

Gibt es den eine Fertige gut kommentierte rutine, welche per SPI 
(Hardware) funktioniert? oder kann mir jemand bei meiner helfen?

von Sonke A. (soeni)


Lesenswert?

Gesetzt den Fall meine Hardware ist richtig initialisiert, kann man 
irgendwie den Status des Moduls auslesen?

von Michael U. (amiga)


Lesenswert?

Hallo,

Ja, wie im Datenblatt beschrieben: Kommando 0x0000 rüberschieben und die 
zurückgelesenen 16Bit interpretieren. Erst kommen die 6 Interruptbits, 
dann die 10 Statusbits. Wenn weiter getaktet wird kommt der FIFO-Inhalt.

Status lesen als erste Amtshandlung ist zu empfehlen, einige meiner 
Module waren ziemlich eigensinnig, wenn ich das nicht gemacht habe.

Meine Initialisierung als Empfänger:
1
;***************************** RFM12 Init **********************************
2
; Sub: Initialisiert den RFM02
3
; Parameter:  -
4
; Return:    -
5
; Scratch-Reg:  Z, TEMP_0, TEMP_1
6
;***************************************************************************
7
8
RFM12_init:
9
  load_p  Z,0x0000      ; Status read
10
  rcall  RFM12_send_cmd
11
12
  load_p  Z,0x80D7      ; FIFO ein, 433MHZ-Band, C = 12pF
13
  rcall  RFM12_send_cmd
14
15
  load_p  Z,0xC2AB      ; Clock Recovery Auto, Filter digital, DQD-Thresold 3
16
  rcall  RFM12_send_cmd
17
18
  load_p  Z,0xCA81      ; FIFO-Level 8 Bit, Sync Pattern ein, High senity Reset aus 
19
  rcall  RFM12_send_cmd
20
21
  load_p  Z,0xC4F3      ; AFC immer, +7,5 / -10kHz, Add Freq-Offset zur PLL, Berechne Freq. Offset aus AFC
22
  rcall  RFM12_send_cmd
23
24
  load_p  Z,0xA620      ; Frequenz 433,92MHz
25
  rcall  RFM12_send_cmd
26
27
  load_p  Z,0x946C      ; VDI Output, VDI Fast, Bandbreite 200kHz, LBA-Gain -6dB, RSSI-Thresold .79dB
28
  rcall  RFM12_send_cmd
29
30
  load_p  Z,0xC610      ; Baudrate 19200
31
  rcall  RFM12_send_cmd
32
33
  load_p  Z,0x8281      ; Empfänger ein, Clock Out aus
34
  rcall  RFM12_send_cmd
35
36
  load_p  Z,0xCA81      ; set FIFO mode
37
  rcall  RFM12_send_cmd
38
39
  load_p  Z,0xCA83      ; enable FIFO
40
  rcall  RFM12_send_cmd
41
42
  ret

Harware-SPI bei mir Mode0, 1MHz Takt.

Laß am besten die Taktausgabe des RFM erstmal an (0x8280) und setze den 
Takt auf was anderes als 1MHz (0xC080 setzt 2,5MHz). Die müßten dann am 
CLK rauskommen.

Gruß aus Berlin
Michael

von Sonke A. (soeni)


Lesenswert?

Hallo,

Danke erstmal, ich probgammiere in C ich hoffe du kannst meinen Code 
lesen:

[c]

// Momentan nutze ich mangels wissen leider nicht den HardwareSPI. wenn 
das einfach zu erledigen ist (besonders das Einlesen bin ich für 
Ratschläge gerne offen.)


// Sendet daten an das Modul
unsigned short rf12_trans(unsigned short wert)
{  unsigned short werti=0;
  unsigned char i;

  cbi(RF_PORT, CS);
  for (i=0; i<16; i++)
  {  if (wert&32768)
      sbi(RF_PORT, SDI);
    else
      cbi(RF_PORT, SDI);
    werti<<=1;
    if (RF_PIN&(1<<SDO))
      werti|=1;
    sbi(RF_PORT, SCK);
    wert<<=1;
    _delay_us(0.3);
    cbi(RF_PORT, SCK);
  }
  sbi(RF_PORT, CS);
  return werti;
}


// Meine Initialisierung
void rf12_init(void)
{
  //RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
  RF_PORT=(1<<CS);

  //for (unsigned char i=0; i<10; i++)
    _delay_ms(100);      // wait until POR done


  rf12_trans(0x0000);      // Status auslesen
  set_cursor(0,3);
  char str[10];
  itoa(rf12_trans(0x0000), str, 2); // Binär anzeigen
  lcd_string("Status: 0b");      // Ausgabe auf LCD
  lcd_string(str);
  _delay_ms(1000);



  rf12_trans(0xC0E0);      // AVR CLK: 10MHz
  rf12_trans(0x80D7);      // Enable FIFO
  rf12_trans(0xC2AB);      // Data Filter: internal
  rf12_trans(0xCA81);      // Set FIFO mode
  rf12_trans(0xE000);      // disable wakeuptimer
  rf12_trans(0xC800);      // disable low duty cycle
  rf12_trans(0xC4F7);      // AFC settings: autotuning: -10kHz...+7,5kHz

  rf12_setfreq(RF12FREQ(433.92));  // Sende/Empfangsfrequenz auf 
433,92MHz einstellen

  set_cursor(0,4);
  lcd_string("Freq gesetzt");

  rf12_setbandwidth(4, 1, 4);    // 200kHz Bandbreite, -6dB Verstärkung, 
DRSSI threshold: -79dBm

  set_cursor(0,4);
  lcd_string("Bandbreite gesetzt             ");

  rf12_setbaud(19200);      // 19200 baud

  set_cursor(0,4);
  lcd_string("Baudrate gesetzt              ");

  rf12_setpower(0, 6);      // 1mW Ausgangangsleistung, 120kHz 
Frequenzshift

  set_cursor(0,4);
  lcd_string("Power On gesetzt                ");

}

// Die einzelnen funktionen senden auch nur Daten ans Modul

// In dieser Funktion bleibt das Modul beim Senden oft hängen.
void rf12_ready(void)
{  cbi(RF_PORT, CS);
  while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
}


// Funktion zum übermitteln der Daten
void rf12_txdata(unsigned char *data, unsigned char number)
{  unsigned char i;
  rf12_trans(0x8238);      // TX on
  rf12_ready();
  rf12_trans(0xB8AA);
  rf12_ready();
  rf12_trans(0xB8AA);
  rf12_ready();
  rf12_trans(0xB8AA);
  rf12_ready();
  rf12_trans(0xB82D);
  rf12_ready();
  rf12_trans(0xB8D4);
  for (i=0; i<number; i++)
  {    rf12_ready();
    rf12_trans(0xB800|(*data++));
  }
  rf12_ready();
  rf12_trans(0x8208);      // TX off
}


// Die Endlossendetestfunktion

void send(void)
{  unsigned char test[]="Dies ist ein 433MHz Test !!!\n   ";
  rf12_txdata(test,32);
}









// Testfunktionen

void funk_sendetest(void){


  rf12_init();          // ein paar Register setzen (z.B. CLK auf 10MHz)

  set_cursor(0,4);
  lcd_string("Init complet           ");



  //unsigned char i=0;
  unsigned char i=0;


  // Displayausgabe
  //lcd_clear();
  set_cursor(0,1);

  uart_puts("\r\n\r\n   Funktest Senden: \r\n");      // Ausgabe UART
  lcd_string("Funktest Senden:   ESC=exit");  // Ausgabe LCD


  set_cursor(0,3);

  char str[10];
  itoa(rf12_trans(0x0000), str, 2); // Binär anzeigen

  lcd_string("Status: 0b");
  lcd_string(str);


  set_cursor(0,2);



  while(uart_ask() != 27){   // kein Escape gedrückt  ??

    if(!ENCODERTAST) {

      beep_short();    // Kurz piepen
      _delay_ms(500);
      return;      // Programmabbruch
    }


    if(i>10){
      set_cursor(0,2);
      lcd_string("                ");// Zeile löschen
      set_cursor(0,2);
      i=0;
    }

    i++;


      lcd_string("-");
      send();
      _delay_ms(1000);




    }




}

[\c]

So nachdem ich nun den Status auslese bringt mich das auch nicht weiter, 
da dieser immer 0 ist. vor und nach dem init.

von Benedikt K. (benedikt)


Lesenswert?

Sönke Paschko wrote:

> So nachdem ich nun den Status auslese bringt mich das auch nicht weiter,
> da dieser immer 0 ist. vor und nach dem init.

Klingt nach einem Hardwareproblem, also einem falsch angeschlossenen 
RFM12 (oder in der Software falsch eingestellte Pins).

von Sonke A. (soeni)


Lesenswert?

hm du meinst meine software ist richtig?

also meine Pinkonfiguration sieht wiefolgt aus, vielleicht sehe ich ja 
den wald vor lauter Bäumen nicht mehr.
1
#define RF_PORT  PORTB
2
#define RF_DDR  DDRB
3
#define RF_PIN  PINB
4
5
#define SDI    2
6
#define SCK    1
7
#define CS    0  // nsel?
8
#define SDO    3
9
10
// Datadirectionregister für PortB (die anderen 4 bit nurtze ich für einen Encoder)
11
DDRB = 0b01000111;  // Eingang Encoder / Funkmodul

Außerdem nutze ich noch einen 10k an FSK/DATA/nFFS

(Ich hoffe mein Modul ist nicht kaputt. Sind die sehr empfindlich?)

von Sonke A. (soeni)


Lesenswert?

achso und Anschlüsse:

Atmega128

Portpin   Beschreibung   Modulpin
PB3         MISO            SDO
PB2         MOSI            SDI
PB1         SCK             SCK
PB0         Für ChipSelect  CS/nSel

von Benedikt K. (benedikt)


Lesenswert?

Sönke Paschko wrote:
> hm du meinst meine software ist richtig?

Wenn nichtmal das Auslesen des Status Registers nicht funktioniert, dann 
liegt es eher nicht an der Software.
Wenn du die Software nahezu unverändert übernommen hast, dann sollte 
diese passen. Die Anpassungen an den mega128 scheinen zumindest auch ok 
zu sein.

Wenn jetzt noch die Hardware auch ok ist, sollte es eigentlich 
funktionieren.

von Jean P. (fubu1000)


Lesenswert?

Hi,
das mit der Beschaltung hatten wir doch schon mal in nem anderen Thread 
von dir geklärt. Kurz gesagt das passt.

>Außerdem nutze ich noch einen 10k an FSK/DATA/nFFS

Ich hoffe gegen VCC.
Mit Wieviel Volt betreibst du denn den At128 und den RFM12 ?

n8

von Sonke A. (soeni)


Lesenswert?

Bei 5v und ja gegen VCC.  Kannst du mir beim HardwareSPI helfen? 
vielleicht klappt es da besser. Wie kann ich denn bei einem HardwareSPI 
auf die Daten im FIFO zugreifen oder einfach nur den Status ausgeben? 
wie Mus ich das SPI initialisieren?

ist SPCR = 0b01010001 richtig? (Master, SPI enable, Interrupt Disable, 
CPU-Takt durch 16, Polarität auf
null und Datenübernahme bei der ersten Taktflanke)

Und vor allem wie lese ich Daten??

von Jean P. (fubu1000)


Lesenswert?

Ok,

also so setzt du den Master Mode , CPU-Takt / 8 und SPI enable:

void SetSpiRateForRFM12()
{
  //SPI Clock = 16Mhz / 8
  SPSR = 0x01;
  SPCR = 0x51;
}


In deiner RFM12.h legst du das hier an:

typedef union converter {
  unsigned int w;
  unsigned char b[2];
} ConvertWord;



Damit sendest du:

unsigned short RFM12_trans(unsigned short data)
{
  ConvertWord value;
  value.w=data;
  PORTB &= ~(1 << CS);
  SPDR = value.b[1];
  while(!(SPSR & (1<<SPIF)) );
  value.b[1]=SPDR;
  SPDR = value.b[0];
  while(!(SPSR & (1<<SPIF)) );
  value.b[0]=SPDR;
  PORTB |= (1 << CS);

  return value.w;
}


Gruß

von Sonke A. (soeni)


Lesenswert?

Woooooow so weit war ich noch nie, er meldet kurz einen Status, 
0b10010000 nach dem ersten Initialisieren, anschließend resettete sich 
der Mega128 und der Status ist wieder 0. Die Schleife läuft durch, und 
tut so als würde sie senden. Aber der Status ist immer noch 0
Ich konnte noch einmal einen Status entlocken, auch wieder mit Reset, 
der war 0b10000000

Kann es sein, das ich das Modul beim Start des uCs initialisieren muss? 
Ich mach das alles erst später, wenn ich das Modul brauche und aufrufe.

von Sonke A. (soeni)


Lesenswert?

Was soll ich nun machen?

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.