mikrocontroller.net

Forum: HF, Funk und Felder RFM12B-868-D


Autor: CRT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe vor einigen Wochen drei Funkchips RFM12B-868-D gekauft und 
versuche seither erfolglos, die Chips (die ja für 3.3V Stromkreise 
ausgelegt sind) in einem 5V Stromkreis zum Laufen zu bekommen. Die 
Übersetzungslogik zwischen den Spannungen funktioniert inzwischen 
zuverlässig, die Software-Seite gestaltet sich jedoch schwierig.

Da das Datasheet an einigen Stellen fehlerhaft / ungenau ist, habe ich 
noch andere Quellen hinzugezogen und versucht, mir einen eigenen Code zu 
schreiben, der sich einfach auf andere Szenarien portieren lässt:
// _I = INPUT PORT
// _O = OUTPUT PORT
// _P = PORT INDEX
// _D = DATA DIRECTION REGISTER

// SPI SCK (clock, output)
#define  RFM12B_SCK_I  PINA
#define  RFM12B_SCK_O  PORTA
#define  RFM12B_SCK_P  5
#define  RFM12B_SCK_D  DDRA

#define  RFM12B_SCK_INIT()  RFM12B_SCK_D |=  (1<<(RFM12B_SCK_P))
#define  RFM12B_SCK_LOW()   RFM12B_SCK_O &= ~(1<<(RFM12B_SCK_P))
#define  RFM12B_SCK_HIGH()  RFM12B_SCK_O |=  (1<<(RFM12B_SCK_P))

// SPI MISO / SDO (master in slave out, input)
#define  RFM12B_MISO_I  PINA
#define  RFM12B_MISO_O  PORTA
#define  RFM12B_MISO_P  3
#define  RFM12B_MISO_D  DDRA

#define  RFM12B_MISO_INIT()  ;
#define  RFM12B_MISO_LOW()   ~(RFM12B_MISO_HIGH())
#define  RFM12B_MISO_HIGH()  RFM12B_MISO_I & (1<<(RFM12B_MISO_P))

// SPI MOSI / SDI (master out slave in, output)
#define  RFM12B_MOSI_I  PINA
#define  RFM12B_MOSI_O  PORTA
#define  RFM12B_MOSI_P  4
#define  RFM12B_MOSI_D  DDRA

#define  RFM12B_MOSI_INIT()  RFM12B_MOSI_D |=  (1<<(RFM12B_MOSI_P))
#define  RFM12B_MOSI_LOW()   RFM12B_MOSI_O &= ~(1<<(RFM12B_MOSI_P))
#define  RFM12B_MOSI_HIGH()  RFM12B_MOSI_O |=  (1<<(RFM12B_MOSI_P))

// SPI SS / CS (slave select, output)
#define  RFM12B_SS_I  PINA
#define  RFM12B_SS_O  PORTA
#define  RFM12B_SS_P  6
#define  RFM12B_SS_D  DDRA

#define  RFM12B_SS_USE  1  // use SS ?

#if RFM12B_SS_USE == 1
  #define  RFM12B_SS_INIT()  RFM12B_SS_D |=  (1<<(RFM12B_SS_P))
  #define  RFM12B_SS_LOW()   RFM12B_SS_O &= ~(1<<(RFM12B_SS_P))
  #define  RFM12B_SS_HIGH()  RFM12B_SS_O |=  (1<<(RFM12B_SS_P))
#else
  #define  RFM12B_SS_INIT()  ;
  #define  RFM12B_SS_LOW()   ;
  #define  RFM12B_SS_HIGH()  ;
#endif

// IRQ (input)
#define  RFM12B_IRQ_I  PINA
#define  RFM12B_IRQ_O  PORTA
#define  RFM12B_IRQ_P  2
#define  RFM12B_IRQ_D  DDRA

#define  RFM12B_IRQ_INIT()  ;
#define  RFM12B_IRQ_LOW()   ~(RFM12B_IRQ_HIGH())
#define  RFM12B_IRQ_HIGH()  RFM12B_IRQ_I & (1<<(RFM12B_IRQ_P))
#define  RFM12B_IRQ_WAIT()  while(RFM12B_IRQ_HIGH())

// send and receive a 16bit-word via spi
uint16_t RFM12B_spi(uint16_t cmd)
{
  uint8_t i;
  uint16_t recv = 0;
  // start communication
  RFM12B_SCK_LOW();
  RFM12B_SS_LOW();
  // read 16 bits
  for(i=0; i<16; i++)
  {
    // send bit
    if(cmd & 0x8000)
      RFM12B_MOSI_HIGH();
    else
      RFM12B_MOSI_LOW();
    // clock
    RFM12B_SCK_HIGH();
    recv<<=1;
    // receive bit
    if(RFM12B_MISO_HIGH())
    {
      recv|=0x0001;
    }
    // clock
    RFM12B_SCK_LOW();
    cmd<<=1;
  }
  // end communication
  RFM12B_SS_HIGH();
  return recv;
}

// initialize hardware (atmel)
void RFM12B_init_hard() {
  // set default values
  RFM12B_SS_HIGH();
  RFM12B_MOSI_HIGH();
  RFM12B_SCK_LOW();
  // init ports
  RFM12B_SCK_INIT();
  RFM12B_MOSI_INIT();
  RFM12B_MISO_INIT();
  RFM12B_SS_INIT();
  RFM12B_IRQ_INIT();
}

// initialize software (rfm12b)
//   uint8_t  receiver  whether the rfm12b should be used as receiver or transmitter
void RFM12B_init_soft(uint8_t receiver)
{
  RFM12B_spi(0x80E7); //EL,EF,868band,12.0pF
  // init mode
  if(receiver)
    RFM12B_spi(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC (bug was here)
  else
    RFM12B_spi(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
  RFM12B_spi(0xA640); //frequency select
  RFM12B_spi(0xC647); //4.8kbps
  // RFM12B_spi(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
    RFM12B_spi(0x94A5);
  RFM12B_spi(0xC2AC); //AL,!ml,DIG,DQD4
  RFM12B_spi(0xCA81); //FIFO8,SYNC,!ff,DR
  RFM12B_spi(0xCED4); //SYNC=2DD4AG
  RFM12B_spi(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
  RFM12B_spi(0x9850); //!mp,90kHz,MAX OUT
  RFM12B_spi(0xCC17); //OB1ACOB0, LPX,Iddy,CDDIT,CBW0
  RFM12B_spi(0xE000); //NOT USED
  RFM12B_spi(0xC800); //NOT USED
  RFM12B_spi(0xC040); //1.66MHz,2.2V
}

// clear fifo buffer
void RFM12B_clear_fifo()
{
  RFM12B_spi(0xCA81);
  RFM12B_spi(0xCA83);
}

// send a byte
//   uint8_t  data  data to send
void RFM12B_put(uint8_t data)
{
  RFM12B_IRQ_WAIT();
  RFM12B_spi(0xB800 + data);
}

// receive a byte
uint8_t RFM12B_get()
{
  uint8_t data;
  while(1)
  {
    data = RFM12B_spi(0x0000);
    if ((data&0x8000))
    {
      data = RFM12B_spi(0xB000);
      return (data&0x00FF);
    }
  }
}

Mein Problem ist, dass die testweise Kommunikation zwischen zwei µCs 
(ein ATtiny45 bei 3.3V mit einem Funkchip und diesem Code und ein 
ATmega32 bei 5V mit Pegelkonverter und Funkchip) nicht funktioniert. Auf 
der Receiver-Seite wird nie ein Interrupt ausgelöst und auch das 
abgefragte Interrupt-Bit im Statusregister bei "RFM12B_get()" ist nie 
gesetzt, obwohl in unmittelbarer Nähe der andere Funkchip wie wild 
sendet/senden sollte. Nichtmal irgendwelcher "Müll" kommt an.

Meine Fragen sind folgende:
1. Hat jemand den Chip RFM12B schonmal erfolgreich zum Laufen gebracht?
2. Welcher Code wurde verwendet?
3. Vielleicht hat jemand ähnliche Probleme gehabt und kann mir ein wenig 
auf die Sprünge helfen.

Vielen Dank im Voraus!

CRT

Autor: Analog (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beitrag "Beispielprogramm für RFM12 433MHz Funk-Module"

ist zwar für 433MHz, kannst Dir aber das SPI-Protokoll mal ansehen.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
War bei deinen "anderen Quellen" bereits die Elektor Januar 2009 dabei? 
Dort ist ein längerer Artikel von B. Kainka zu diesen Modulen sogar 
speziell auf 868 MHz. Programmiersprache ist allerdings BASCOM AVR.

Autor: CRT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die schnellen Antworten.

@Analog: Ich habe mir den Link angesehen und werde es in der nächsten 
Zeit mit der dort verwendeten SPI Implementation versuchen. Was mir 
immernoch etwas schleierhaft ist: Laut dem Datasheet des Controllers 
überträgt dieser das erste Bit des Statusregisters bereits mit dem 
ersten Bit des "Commands" - ich frage mich, wie bei einer syncronen 
Datenübertragung möglich ist, dass der Slave schon weiß, was er mir 
schicken soll, bevor der Master die Übertragung des ersten Bits beendet 
hat. Weißt du dazu Genaueres?

@Stefan B.: Ich kannte die Elektor bisher noch nicht, entsprechend 
gehörte sie noch nicht zu meinen Quellen. Ich werde aber versuchen, sie 
in den nächsten Tagen irgendwo aufzutreiben. Zu Rate gezogen habe ich 
bisher v.A. das Datasheet des Herstellers (weitestgehend unbrauchbar), 
das Code-Example des Herstellers (ebenso unbenutzbar) und diese 
Quickstart-Anleitung: 
http://zenburn.net/~goroux/rfm12b/rfm12b_and_avr-%... 
Außerdem habe ich einen kurzen Blick auf den Code bei 
http://www.das-labor.org/ geworfen. An allen Implementationen hat mich 
gestört, dass man nicht vollständig frei definieren könnte, welche Pins 
man verwenden möchte, sondern dass es immer Randbedingungen gab (meist, 
dass sie im gleichen Port sein müssen). Störend ist natürlich auch, wenn 
die Implementationen schlicht fehlerhaft sind.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CRT wrote:
> Was mir
> immernoch etwas schleierhaft ist: Laut dem Datasheet des Controllers
> überträgt dieser das erste Bit des Statusregisters bereits mit dem
> ersten Bit des "Commands" - ich frage mich, wie bei einer syncronen
> Datenübertragung möglich ist, dass der Slave schon weiß, was er mir
> schicken soll, bevor der Master die Übertragung des ersten Bits beendet
> hat.

Sobald CS auf Low geht, gibt der RF12 das FFIT Bit aus.
Das Datenblatt ist etwas uneindeutig was das Statusregister angeht:
Version 1:
Parallel zum Senden eines (beliebigen) Befehls, wird das Statusregister 
ausgegeben. Dies sieht man auch im Timingdiagramm auf Seite 13 des 
Datenblatts.
Version 2:
Nur das FFIT Bit wird ausgegeben, was danach kommt ist sonst was. Wenn 
man das Statusregister komplett lesen möchte, muss man den Befehl 0x0000 
senden. Dies steht auf Seite 23.

Beides kann in die Angaben aus dem Datenblatt hineininterpretieren. 
Welche Version richtig ist, habe ich noch nicht ausprobiert. Mit Version 
2 ist man aber auf der sicheren Seite.

> Ich kannte die Elektor bisher noch nicht, entsprechend
> gehörte sie noch nicht zu meinen Quellen. Ich werde aber versuchen, sie
> in den nächsten Tagen irgendwo aufzutreiben.

Schau aber erst rein ehe du die kaufst. Da wurde im Prinzip nur das 
Datenblatt wiedergegeben und ein paar Bascom Beispiele gezeigt. Nichts 
was man nicht auch kostenlos und besser im Internet finden kann.

Autor: CRT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank auch dir, Benedikt K., für deine schnelle und hilfreiche 
Antwort!

Ich habe die von mir verwendete Implementation mit der in dem anderen 
Beitrag und der von Wikipedia 
(http://en.wikipedia.org/wiki/Serial_Peripheral_Int...) 
verglichen und musste feststellen, dass es auch hier wieder Unterschiede 
gibt, wobei die von mir verwendete Implementation näher an dem 
Wikipedia-Beispielcode ist. Da der Funkchip aber vermutlich nach dem 
Heruntersetzen der Clock schnell genug sein nächstes Bit auf den Bus 
schaufelt, bevor der Atmel es lesen möchte und du außerdem den Code 
erfolgreich verwendest, muss es wohl ebenso funktionieren. Dass ich 
dennoch bisher bei meinem Receiver das erste Bit nie gesetzt bekam, bei 
meinem Chip im Transmitter-Modus aber halbwegs sinnvolle Werte beim 
Status-Read-Command rauskamen (0xA040, 0xE040 bei der ersten Abfrage), 
muss ich nun davon ausgehen, dass meine SPI-Implementation zwar stimmt, 
mein Chip aber schlicht und einfach nichts empfängt, was er mir liefern 
könnte.

@Benedikt K.: Warum hast du SPI so implementiert, wie du es 
implementiert hast? Hast du außerdem detailierte Informationen bezüglich 
des nFFS-Pins? Du schreibst in deinem Post, man möge ihn mit 10 kOhm auf 
Vdd pullen, das habe ich auch getan. Im Datasheet des auf elektor 
verlinkten Si4420 
(https://www.silabs.com/Support%20Documents/Technic...) 
steht auf Seite 4 "nFFS | FIFO select input (active low) In FIFO mode, 
when bit ef is set in Configuration Setting Command"; "ef" ist sowohl in 
deiner alsauch meiner Implementation auf 1, müsste dann nicht nFFS auf 
logisch high, also physisch low sein, um den FIFO zu verwenden?

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CRT wrote:
> Warum hast du SPI so implementiert, wie du es
> implementiert hast?

Weil es so dem Timing aus dem Datenblatt entspricht.

> Hast du außerdem detailierte Informationen bezüglich
> des nFFS-Pins? Du schreibst in deinem Post, man möge ihn mit 10 kOhm auf
> Vdd pullen, das habe ich auch getan. Im Datasheet des auf elektor
> verlinkten Si4420
> (https://www.silabs.com/Support%20Documents/Technic...)
> steht auf Seite 4 "nFFS | FIFO select input (active low) In FIFO mode,
> when bit ef is set in Configuration Setting Command"; "ef" ist sowohl in
> deiner alsauch meiner Implementation auf 1, müsste dann nicht nFFS auf
> logisch high, also physisch low sein, um den FIFO zu verwenden?

Datenblatt RF12, Seite 14: Bit ef enables FIFO mode. -> ef muss 1 sein 
wenn man das FIFO verwendet. Gleichzeitig wird nFFS auch ein eigener 
Chipselect für das FIFO, man kann dann ohne Befehle zu senden, direkt 
die Daten auslesen, wenn man nFFS auf Low zieht anstelle von nSEL. Da 
ich dies aber nicht mache, muss nFFS deaktiviert werden, daher der 
Pullup.

Autor: CRT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmals vielen Dank für all eure Hilfe! Ich habe es nun geschafft, 
einen Transmitter so zu programmieren, dass er auf die Flags im 
Status-Register Rücksicht nimmt und wartet, bis der Chip bereit ist, die 
nächsten Daten zu verarbeiten.

Ich werde mich nun wieder an einem Receiver versuchen und weitere 
Ergebnisse und Fragen hier posten. Mein Quellcode sieht inzwischen so 
aus:
// _I = INPUT PORT
// _O = OUTPUT PORT
// _P = PORT INDEX
// _D = DATA DIRECTION REGISTER

// SPI SCK (clock, output)
#define  RFM12B_SCK_I  PINA
#define  RFM12B_SCK_O  PORTA
#define  RFM12B_SCK_P  5
#define  RFM12B_SCK_D  DDRA

#define  RFM12B_SCK_INIT()  RFM12B_SCK_D |=  (1<<(RFM12B_SCK_P))
#define  RFM12B_SCK_LOW()   RFM12B_SCK_O &= ~(1<<(RFM12B_SCK_P))
#define  RFM12B_SCK_HIGH()  RFM12B_SCK_O |=  (1<<(RFM12B_SCK_P))

// SPI MISO / SDO (master in slave out, input)
#define  RFM12B_MISO_I  PINA
#define  RFM12B_MISO_O  PORTA
#define  RFM12B_MISO_P  3
#define  RFM12B_MISO_D  DDRA

#define  RFM12B_MISO_INIT()  RFM12B_MISO_D &= ~(1<<(RFM12B_MISO_P))
#define  RFM12B_MISO_LOW()   ~(RFM12B_MISO_HIGH())
#define  RFM12B_MISO_HIGH()  RFM12B_MISO_I & (1<<(RFM12B_MISO_P))

// SPI MOSI / SDI (master out slave in, output)
#define  RFM12B_MOSI_I  PINA
#define  RFM12B_MOSI_O  PORTA
#define  RFM12B_MOSI_P  4
#define  RFM12B_MOSI_D  DDRA

#define  RFM12B_MOSI_INIT()  RFM12B_MOSI_D |=  (1<<(RFM12B_MOSI_P))
#define  RFM12B_MOSI_LOW()   RFM12B_MOSI_O &= ~(1<<(RFM12B_MOSI_P))
#define  RFM12B_MOSI_HIGH()  RFM12B_MOSI_O |=  (1<<(RFM12B_MOSI_P))

// SPI SS / CS (slave select, output)
#define  RFM12B_SS_I  PINA
#define  RFM12B_SS_O  PORTA
#define  RFM12B_SS_P  6
#define  RFM12B_SS_D  DDRA

#define  RFM12B_SS_INIT()  RFM12B_SS_D |=  (1<<(RFM12B_SS_P))
#define  RFM12B_SS_LOW()   RFM12B_SS_O &= ~(1<<(RFM12B_SS_P))
#define  RFM12B_SS_HIGH()  RFM12B_SS_O |=  (1<<(RFM12B_SS_P))

#define  RFM12B_STATUS       RFM12B_spi(0x0000)

// INTs
#define  RFM12B_RGIT()       (RFM12B_STATUS & 0x8000)
#define  RFM12B_WAIT_RGIT()  while(!RFM12B_RGIT()) {  }
#define  RFM12B_FFIT()       (RFM12B_STATUS & 0x8000)
#define  RFM12B_WAIT_FFIT()  while(!RFM12B_FFIT()) {  }

// send and receive a 16bit-word via spi
uint16_t RFM12B_spi(uint16_t cmd)
{
  uint8_t i;
  uint16_t recv = 0;
  // start communication
  RFM12B_SCK_LOW();
  RFM12B_SS_LOW();
  // read 16 bits
  for(i=0; i<16; i++)
  {
    // send bit
    if(cmd & 0x8000)
      RFM12B_MOSI_HIGH();
    else
      RFM12B_MOSI_LOW();
    // clock
    RFM12B_SCK_HIGH();
    recv<<=1;
    // receive bit
    if(RFM12B_MISO_HIGH())
    {
      recv|=0x0001;
    }
    // clock
    RFM12B_SCK_LOW();
    cmd<<=1;
  }
  // end communication
  RFM12B_SS_HIGH();
  return recv;
}

// initialize hardware (atmel) (CHECKED)
void RFM12B_init_hard()
{
  // set default values
  RFM12B_SS_HIGH();
  RFM12B_MOSI_HIGH();
  RFM12B_SCK_LOW();
  // init ports
  RFM12B_SCK_INIT();
  RFM12B_MOSI_INIT();
  RFM12B_MISO_INIT();
  RFM12B_SS_INIT();
}

// initialize software (rfm12b) (CHECKED)
void RFM12B_init_soft()
{
/*  RFM12B_spi(0xC0E0); // CLK: 10MHz,2.2V*/
/*  RFM12B_spi(0x80E7); // EL,EF,868band,12.0pF*/
/*  RFM12B_spi(0xC2AB); // AL,!ml,DIG,DQD 3*/
/*  RFM12B_spi(0xCA81); // FIFO8,SYNC,!ff,DR*/
/*  RFM12B_spi(0xE000); // WakeUp-Timer: NOT USED*/
/*  RFM12B_spi(0xC800); // Low-Duty-Cycle: NOT USED*/
/*  RFM12B_spi(0xC4F7); // AFC settings: autotuning: -10kHz...+7,5kHz*/
/*  */
/*  RFM12B_spi(0xA640); //frequency select*/
/*  // RFM12B_spi(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm*/
/*  RFM12B_spi(0x94A5);*/
/*  RFM12B_spi(0xC647); //4.8kbps*/
/*  RFM12B_spi(0x9850); //!mp,90kHz,MAX OUT*/
  RFM12B_spi(0x80D7);//EL,EF,433band,12.0pF
  RFM12B_spi(0x8239);//!er,!ebb,ET,ES,EX,!eb,!ew,DC
  RFM12B_spi(0xA640);//434MHz
  RFM12B_spi(0xC647);//4.8kbps
  RFM12B_spi(0x94A0);//VDI,FAST,134kHz,0dBm,-103dBm
  RFM12B_spi(0xC2AC);//AL,!ml,DIG,DQD4
  RFM12B_spi(0xCA81);//FIFO8,SYNC,!ff,DR
  RFM12B_spi(0xCED4);//SYNC=2DD4;
  RFM12B_spi(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN
  RFM12B_spi(0x9850);//!mp,90kHz,MAX OUT
  RFM12B_spi(0xCC77);//OB1,OB0, LPX,!ddy,DDIT,BW0
  RFM12B_spi(0xE000);//NOT USE
  RFM12B_spi(0xC800);//NOT USE
  RFM12B_spi(0xC040);//1.66MHz,2.2V
}

// send a byte (CHECKED)
//   uint8_t  data  data to send
void RFM12B_put(uint8_t data)
{
  RFM12B_WAIT_RGIT();
  RFM12B_spi(0xB800 + data);
}

// receive a byte (CHECKED)
uint8_t RFM12B_get()
{
  RFM12B_WAIT_FFIT();
  return RFM12B_spi(0xB000) & 0x00FF;
}

// transmit multiple bytes (CHECKED)
//   uint8_t  data[]  data to transmit
//   uint8_t  length  length of the data to transmit
void RFM12B_transmit(uint8_t data[], uint8_t length)
{
  uint8_t i;
  // enable TX
  RFM12B_spi(0x8238);
  RFM12B_put(0xAA);
  RFM12B_put(0xAA);
  RFM12B_put(0xAA);
  RFM12B_put(0x2D);
  RFM12B_put(0xD4);

  for(i = 0; i < length; i++)

  {
    RFM12B_put(data[i]);

  }

  RFM12B_WAIT_RGIT();
  // disable TX

  RFM12B_spi(0x8208);
}


// receive multiple bytes (CHECKED)
//   uint8_t  data[]  buffer for received data
//   uint8_t  length  length of data to receive

void RFM12B_receive(uint8_t *data, uint8_t length)

{
  uint8_t i;
  // enable RX

  RFM12B_spi(0x82C8);
  // set FIFO mode

  RFM12B_spi(0xCA81);
  // enable FIFO

  RFM12B_spi(0xCA83);

  for(i = 0; i < length; i++)

  {
    data[i] = RFM12B_get();

  }
  RFM12B_WAIT_FFIT();
  // disable RX

  RFM12B_spi(0x8208);

}

Die Software-Initialisierung muss ich nochmal durchgehen, damit ich sie 
verstehe.

Wenn jemand einen Fehler findet oder Denkanstöße in irgendeine Richtung 
für mich hat, immer her damit! :)

Autor: CRT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein RFM12B-Treiber funktioniert nun! Ich arbeite gerade noch daran, ihn 
an einigen Stellen zu überarbeiten, außerdem versuche ich mich an der 
Interrupt-Implementation und gehe nochmal die Initialisierung durch. 
Wenn er tadellos funktioniert werde ich ihn hier als Code-Schnipsel zur 
freien Verwendung durch andere verlinken.

Eine Frage kam mir noch bzgl. Frequenzen: Das 868 MHz-Band ist relativ 
restriktiv limitiert (Quellen: 
http://de.wikipedia.org/wiki/Short_Range_Devices und 
http://www.roboternetz.de/wissen/index.php/Funkmodule). Stellenweise 
darf man nur mit Duty Cycle 0,1% oder 1% senden, hier sind offenbar auch 
kritische Funkdienste wie sogenannte "Social Alarms" unterwegs, deren 
Störung unbedingt vermieden werden muss.

Aus diesem Grund würde es mich freuen, wenn möglichst viele Augen den 
folgenden Gedankengang und die Rechnung nachvollziehen und ihre 
Meinung/Bedenken darüber äußern würden:

Laut Wikipedia (http://de.wikipedia.org/wiki/Short_Range_Devices) und 
RoboterNetz (http://www.roboternetz.de/wissen/index.php/Funkmodule) ist 
der Bereich 869,3 - 869,4 MHz im 868 MHz-Band "offen"; ich kenne mich 
mit der Terminologie nicht aus, nehme aber an, dass das bedeutet, dass 
hier keine Duty Cycle und Nutzungseinschränkungen gemacht werden. Ist 
das richtig?

Das Code-Datensheet sagt auf Seite 2 zum Frequency Setting Command, die 
Frequenz berechne sich über Fc = 860 + F * 0.0050 MHz; möchte ich nun 
also auf 869,3 MHz senden, muss ich nach F auflösen, Fc einsetzen und 
bekomme dann für F (also den Wert von f11..f0) 1860 oder 0x744. Ist das 
richtig?

Was bedeuten die Frequenzangaben beim AFC Command (Seite 5) und TX 
Configuration Control Command (Seite 6)?

Die Einschränkung der 10mW sollte nicht überschritten werden, denn: Laut 
Datasheet Seite 5 beträgt die "Max. available output power" im 868 
MHz-Band typischerweise 4 dBm; laut Wikipedia 
(http://en.wikipedia.org/wiki/DBm#Unit_conversions) entspricht das 
2,5mW; ist das richtig?

Ich hätte nun, davon ausgehend, dass ich die Basis-Frequenz einstellen 
muss und der Funkchip dann die Basisfrequenz +- die Frequency Deviation 
besendet, folgende Einstellungen vorgenommen:

Frequency Setting Command (0xA74E): Fc = 869,350 MHz (Mitte des 
Bereiches 869,300 - 869,400 MHz) => F = 1870 = 0x74E
TX Configuration Control Command (0x9820): p = 000b (Output Power: 
0dBm), m = 0010b (Frequency Deviation: 45kHz)

AFC und den Receiver Control Command hätte ich außenvor gelassen, da sie 
scheinbar nur beim Empfangen der Signale eine Rolle spielen.

Autor: MrNice (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,

habe mir soeben auch diese Module zugelegt und würde mich für deine 
Implementierung interessieren. Die Ansätze hier sind schon sehr 
hilfreich!

Hast du weiter gearbeitet oder ist das Projekt tot?
Würde mich über jeden Codefetzen freuen ;)

Danke...

Autor: CRT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Entschuldige, dass ich mich erst so spät melde, ich wollte eigendlich 
den Code noch überarbeiten und dann hier hochladen. Dabei ist mir aber 
der normale Alltag dazwischengekommen und ich habe das ganze aus den 
Augen verloren.

Meine bisherige unbereinigte (!!!) Version habe ich hier online 
gestellt: http://www.joachim-neu.de/index.php?lang=1&id=102

Dort werde ich auch Änderungen einpflegen und den Code falls nötig 
aktualisieren.

Ich möchte mich nochmal für die Hilfe aus dem Forum hier bedanken, 
namentlich bei Benedikt K., Stefan B. und Analog. Ich hoffe der Code 
hilft anderen bei der Ansteuerung ihrer Funkmodule!

CRT

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.