Ik heb de 868MHz RF01, RF02 versie aangeschaft en dit heb ik aangesloten op de ATmega32. Echter ontvang ik volgens mij wel wat, maar niet wat ik verwacht. Ik heb de code gebruikt en aangepast aan de ATmega. Om te testen stuur ik elke seconde een waarde waarmee led0 t/m 7 aangaat, een voor een. Ook heb ik twee leds als status. Groen als de ChkSum overeenkomt met alle verzonden bij elkaar opgetelde waarden van 1 Send methode. Rood als het niet zo is.
Ze zijn allebei aan, dus ik ga er van uit dat hij soms wel, soms niet ontvangt. Echter zijn alle leds altijd aan, terwijl hij eigenlijk hoort te beginnen bij led0, 1 seconde, led2, seconde.. etc.
Als ik de verzender uitzet, dan is de status soms ook gewoon groen en staan alle leds ook aan. Terwijl er niet eens wat verzonden word.
Ik heb op het moment geen idee en ik hoop dat er wat mensen zijn die me in de goede richting kunnen helpen. Hier is de infopagina van de 2 modules, inclusief datasheet.
Ontvanger: http://ideetron.biedmeer.nl/Webwinkel-Product-182196/FSK-ontvangermodu…
Verzender: http://ideetron.biedmeer.nl/Webwinkel-Product-182077/FSK-zendermodule-…
En mijn code voor verzender:
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#define DDR_IN 0
#define DDR_OUT 1
#define PORT_SEL PORTB
#define PIN_SEL PINB
#define DDR_SEL DDRB
#define PORT_SDI PORTB
#define PIN_SDI PINB
#define DDR_SDI DDRB
#define PORT_SCK PORTB
#define PIN_SCK PINB
#define DDR_SCK DDRB
#define PORT_SDO PORTB
#define PIN_SDO PINB
#define DDR_SDO DDRB
#define RFXX_SCK 7 // SCK 6
#define RFXX_SDO 6 // SDO = SPI data input -
#define RFXX_SDI 5 // MOSI 3
#define RFXX_SEL 4 // nSEL 5
#define RFXX_DATA 3 // FSK 1
#define PB2 2 // -
#define PB1 1 // -
#define PB0 0 // -
#define SEL_OUTPUT() DDR_SEL |= (1<<RFXX_SEL)
#define HI_SEL() PORT_SEL |= (1<<RFXX_SEL)
#define LOW_SEL() PORT_SEL &=~(1<<RFXX_SEL)
#define SDI_OUTPUT() DDR_SDI |= (1<<RFXX_SDI)
#define HI_SDI() PORT_SDI |= (1<<RFXX_SDI)
#define LOW_SDI() PORT_SDI &=~(1<<RFXX_SDI)
#define SDO_INPUT() DDR_SDO &=~(1<<RFXX_SDO)
#define SDO_HI() PIN_SDO&(1<<RFXX_SDO)
#define SCK_OUTPUT() DDR_SCK |=(1<<RFXX_SCK)
#define HI_SCK() PORT_SCK |=(1<<RFXX_SCK)
#define LOW_SCK() PORT_SCK &=~(1<<RFXX_SCK)
void RFXX_PORT_INIT(void) { // initialise all neccesary ports
HI_SEL(); // set bit SEL
HI_SDI(); // set bit SDI
LOW_SCK(); // reset bit SCK
SEL_OUTPUT(); // set port SEL as output
SDI_OUTPUT(); // set port SDI as output
SDO_INPUT(); // set port SDO as input
SCK_OUTPUT(); // set port SCK as output
}
unsigned int RFXX_WRT_CMD( unsigned int aCmd) { // to send commands
unsigned char i;
unsigned int temp;
LOW_SCK(); // reset bit SCK
LOW_SEL(); // reset bit SEL
for(i=0;i<16;i++)
{
temp<<=1; // temp=temp<<1;
if(SDO_HI()) { // if SPI (PIN5 SDO) data input is high
temp|=0x0001; // temp is a 16-bit integer
}
LOW_SCK(); // reset bit SCK
if(aCmd&0x8000) { // if((aCmd&0x8000)==0x8000)
HI_SDI(); // set bit SDI
}
else {
LOW_SDI();// reset bit SDI
}
HI_SCK(); // set bit SCK
aCmd<<=1; // aCmd=aCmd<<1
}
LOW_SCK(); // reset bit SCK
HI_SEL(); // set bit SEL
return(temp);
}
void RF02B_SEND(unsigned char aByte) { // send a byte
unsigned char i;
for(i=0;i<8;i++)
{
while(PINB&(1<<RFXX_SDO)); // polling nIRQ
while(!(PINB&(1<<RFXX_SDO)));
if(aByte&0x80)
{
PORTB|=(1<<RFXX_DATA); // set bit(FSK): request data input
}
else {
PORTB&=~(1<<RFXX_DATA); // reset bit(FSK): request data input
}
aByte<<=1; // aByte=aByte<<1
}
}
void Send (unsigned int byte) {
unsigned int i, j, ChkSum;
RFXX_WRT_CMD(0xC039); // start TX
ChkSum=0;
RF02B_SEND(0xAA); // PREAMBLE
RF02B_SEND(0xAA); // PREAMBLE
RF02B_SEND(0xAA); // PREAMBLE
RF02B_SEND(0x2D); // HEAD HI BYTE
RF02B_SEND(0xD4); // HEAD LOW BYTE
RF02B_SEND(byte); // Data0
ChkSum+=byte;
RF02B_SEND(byte); // Data1
ChkSum+=byte;
RF02B_SEND(byte); // Data2
ChkSum+=byte;
RF02B_SEND(byte); // Data3
ChkSum+=byte;
RF02B_SEND(byte); // Data4
ChkSum+=byte;
RF02B_SEND(byte); // Data5
ChkSum+=byte;
RF02B_SEND(byte); // Data6
ChkSum+=byte;
RF02B_SEND(byte); // Data7
ChkSum+=byte;
RF02B_SEND(byte); // Data8
ChkSum+=byte;
RF02B_SEND(byte); // Data9
ChkSum+=byte;
RF02B_SEND(byte); // Data10
ChkSum+=byte;
RF02B_SEND(byte); // Data11
ChkSum+=byte;
RF02B_SEND(byte); // Data12
ChkSum+=byte;
RF02B_SEND(byte); // Data13
ChkSum+=byte;
RF02B_SEND(byte); // Data14
ChkSum+=byte;
RF02B_SEND(byte); // Data15
ChkSum+=byte;
RF02B_SEND(ChkSum);// Data16
RF02B_SEND(0xAA); // dummy byte
RFXX_WRT_CMD(0xC001); // close TX
for(i=0;i<5000;i++)
for(j=0;j<123;j++);
}
void wait() {
for(int i=0;i<=10;i++)
_delay_ms(100);
}
void main(void) {
RFXX_PORT_INIT(); // initialise all neccesary ports
RFXX_WRT_CMD(0xCC00); // read internal status register content
RFXX_WRT_CMD(0x9361); // 868band, 2MHz CLK pin, 11.5pF, 60kHz
RFXX_WRT_CMD(0xA640); // 868MHz (86 + 6 )
RFXX_WRT_CMD(0xD040); // RATE/2 <<------------------?
RFXX_WRT_CMD(0xC823); // 4.8kbps
RFXX_WRT_CMD(0xC220); // ENABLE BIT SYNC
RFXX_WRT_CMD(0xC001); // CLOSE ALL
PORTB|=(1<<RFXX_DATA);// set bit FSK
DDRB|=(1<RFXX_DATA); // set port FSK as output
while(1) {
Send(0xFF); // led0 on - 00000001
wait();
Send(0xFE); // led1 on - 00000010
wait();
Send(0xFD); // led3 on - 00000100
wait();
Send(0xFB); // led 4....
wait();
Send(0xF7);
wait();
Send(0xEF);
wait();
Send(0xDF);
wait();
Send(0xBF);
wait();
Send(0x7F);
wait();
}
}En nu de ontvanger:
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define DDR_IN 0
#define DDR_OUT 1
#define PORT_SEL PORTB
#define PIN_SEL PINB
#define DDR_SEL DDRB
#define PORT_SDI PORTB
#define PIN_SDI PINB
#define DDR_SDI DDRB
#define PORT_SCK PORTB
#define PIN_SCK PINB
#define DDR_SCK DDRB
#define PORT_SDO PORTB
#define PIN_SDO PINB
#define DDR_SDO DDRB
#define PORT_LED PORTC
#define DDR_LED DDRC
#define RFXX_SCK 7 // SCK 11
#define RFXX_SDO 6 // SDO = SPI data input // MISO 10
#define RFXX_SDI 5 // MOSI --> SDI 2
#define RFXX_SEL 4 // SS --> SEL 3
#define RFXX_DATA 3 // -
#define PB2 2 // -
#define PB1 1 // -
#define PB0 0 // -
#define SEL_OUTPUT() DDR_SEL |= (1<<RFXX_SEL)
#define HI_SEL() PORT_SEL |= (1<<RFXX_SEL)
#define LOW_SEL() PORT_SEL &=~(1<<RFXX_SEL)
#define SDI_OUTPUT() DDR_SDI |= (1<<RFXX_SDI)
#define HI_SDI() PORT_SDI |= (1<<RFXX_SDI)
#define LOW_SDI() PORT_SDI &=~(1<<RFXX_SDI)
#define SDO_INPUT() DDR_SDO &=~(1<<RFXX_SDO)
#define SDO_HI() PIN_SDO&(1<<RFXX_SDO)
#define SCK_OUTPUT() DDR_SCK |=(1<<RFXX_SCK)
#define HI_SCK() PORT_SCK |=(1<<RFXX_SCK)
#define LOW_SCK() PORT_SCK &=~(1<<RFXX_SCK)
#define LED_OUTPUT() DDR_LED|=0x0F // DDR_LED = output
#define LED0_ON() PORT_LED&=~(1<<0)
#define LED0_OFF() PORT_LED|=(1<<0)
#define LED0_TRG() PORT_LED^=(1<<0)
#define LED1_ON() PORT_LED&=~(1<<1)
#define LED1_OFF() PORT_LED|=(1<<1)
#define LED1_TRG() PORT_LED^=(1<<1)
#define LED2_ON() PORT_LED&=~(1<<2)
#define LED2_OFF() PORT_LED|=(1<<2)
#define LED2_TRG() PORT_LED^=(1<<2)
#define LED3_ON() PORT_LED&=~(1<<3)
#define LED3_OFF() PORT_LED|=(1<<3)
#define LED3_TRG() PORT_LED^=(1<<3)
unsigned char RF_RXBUF[22];
void RFXX_PORT_INIT(void) {
HI_SEL(); // set bit SEL
HI_SDI(); // set bit SDI
LOW_SCK(); // reset bit SCK
SEL_OUTPUT(); // set port SEL as output
SDI_OUTPUT(); // set port SDI as output
SDO_INPUT(); // set port SDO as input
SCK_OUTPUT(); // set port SCK as output
}
unsigned int RFXX_WRT_CMD( unsigned int aCmd) { // // to send commands
unsigned char i;
unsigned int temp;
LOW_SCK(); // reset bit SCK
LOW_SEL(); // reset bit SEL
for(i=0;i<16;i++)
{
temp<<=1; // temp=temp<<1;
if(SDO_HI()) { // if SPI (PIN5 SDO) data input is high
temp|=0x0001; // temp is a 16-bit integer
}
LOW_SCK(); // reset bit SCK
if(aCmd&0x8000) { // if((aCmd&0x8000)==0x8000)
HI_SDI(); // set bit SDI
}
else {
LOW_SDI();// reset bit SDI
}
HI_SCK(); // set bit SCK
aCmd<<=1; // aCmd=aCmd<<1
}
LOW_SCK(); // reset bit SCK
HI_SEL(); // set bit SEL
return(temp);
}
unsigned char RF01_RDFIFO(void) {
unsigned char i, Result;
LOW_SCK();
LOW_SDI();
LOW_SEL();
for(i=0;i<16;i++) { // skip status bits
HI_SCK();
HI_SCK();
LOW_SCK();
LOW_SCK();
}
Result=0;
for(i=0;i<8;i++) { // read fifo data byte
Result<<=1; // Result=Result<<1;
if(SDO_HI()) {
Result|=1;
}
HI_SCK();
HI_SCK();
LOW_SCK();
LOW_SCK();
}
HI_SEL();
return(Result);
}
void main(void) {
unsigned int intI, intJ;
unsigned char i, j, ChkSum;
for(intI=0;intI<10000;intI++)for(intJ=0;intJ<123;intJ++);
RFXX_PORT_INIT(); // initialize
RFXX_WRT_CMD(0x0000); // read internal status register
RFXX_WRT_CMD(0X918A); // 868MHz, crystal oscillator, 12,5pF, 134KHz
RFXX_WRT_CMD(0xA640); // 868MHz (860 + 6 )
RFXX_WRT_CMD(0XC847); // 4.8kbps
RFXX_WRT_CMD(0xC6AB); // AFC setting
RFXX_WRT_CMD(0XC42A); // clock recovery manual control, digital filter, DQD=4
RFXX_WRT_CMD(0xC240); // output 1.66Mhz
RFXX_WRT_CMD(0xC080);
RFXX_WRT_CMD(0xCE88); // use FIFO
RFXX_WRT_CMD(0xCE8B);
RFXX_WRT_CMD(0xC081); // open RX
DDRB|=(1<<RFXX_DATA);
DDRD&=~(1<<2); // everything 0 except int0
LED_OUTPUT(); // DDR_LED = output
PORTC=0xFF; // TEMP
DDRA=0xFF; // TEMP
i=0;
while(1) {
while((PIND&(1<<2))) { // polling the nIRQ data
RF_RXBUF[i++]=RF01_RDFIFO(); // read FIFO data
if(i==18) {
i=0;
RFXX_WRT_CMD(0xCE88); // reset FIFO for next frame recognition
RFXX_WRT_CMD(0xCE8B);
ChkSum=0;
for(j=0;j<16;j++) {
ChkSum+=RF_RXBUF[j]; // calculate checksum
}
if(ChkSum==RF_RXBUF[16]) { // frame check
LED3_TRG(); // receive indication
}
else( LED2_TRG());
PORTA=RF_RXBUF[1];
}
}
}
}hallo UneXisted hebt jij toevallig ook nog een schema van die led cube heb er zelf ook een gemaakt maar het programeren lukte niet
als u het schema heeft zou u dan ook zo vriendelijk willen wezen om hem naar mij te sturen?
Emailadres in profiel openbaar
[Bericht gewijzigd door Henry S. op (11%)]
Bart Hiddink
Bart Hiddink is Ideetron; electronics and projects, http://www.ideetron.nl. LoRaWAN Nutcase.
Op 12 maart 2009 20:40:04 schreef Bart Hiddink:
Heb je ze bij mij gekocht of ergens anders?
Bij jou.
Ik heb ze bij jou gekocht.
Ik was aardig op weg. Als ik weer tijd heb ga ik er nog eens naar kijken. Ik vind het wel heel naar dat het voorbeeld totaal niet klopt en werkt.
Bart Hiddink
Bart Hiddink is Ideetron; electronics and projects, http://www.ideetron.nl. LoRaWAN Nutcase.
Je bedoelt dan wrsch het voorbeel van Hope RF.
Ik heb daar al meer klachten over.
Ik heb het zelf alleen gebruikt als opstapje.
Ik kijk vandaag even naar je code.
Dit is al van lang geleden!
Ik ga er komende weken nog even aan sleutelen. Als het dan niet lukt mail ik je.
Bart Hiddink
Bart Hiddink is Ideetron; electronics and projects, http://www.ideetron.nl. LoRaWAN Nutcase.
Dat klopt helaas.
Het is een beetje lastig voor mij om alle 'bugs' te verzamelen.
Het grootste probleem met het voorbeeld is dat je op het verkeerde been wordt gezet door het MISO en MOSI verhaal.
Dat wekt de suggestie dat de SPI interface van de micro wordt gebruikt maar dat is niet zo.
Ik heb het vermoeden dat de programmeur de code portable heeft willen maken en daarbij de aansluitingen naar de RFM is vergeten.
Ook worden in de RFM02 eigenlijk 2 verschillende poorten gebruikt; De SPI poort (hier wel!) voor initialisatie en de FSK pin (poort) voor het versturen van data.
En data versturen kan ook nog op een andere manier, maar vergeet dat gelijk maar weer..
De fouten bij de zender (waarvan ik weet) zijn:
(ATmega source)
De MOSI (Master Out Slave In) uitgang wordt niet gebruikt.
Dat is PB4 geworden en dat is gewoon een uitgang.
Het gaat dus mis bij het rijtje #Define voor PB.
Daarbij moet je even goed naar het schema staren.
Het zenden van een frame gaat als volgt:
1. de RFM wordt geïnitialiseerd:
Dat doe je via de SPI interface van de RFM.
Kijk in RF02_code.pdf op blz. 1; 1. Timing diagram voor een voorbeeld van de timing.
nSEL is laag, SDI bevat de data en met SCK klok je het naar binnen.
Achtereenvolgens de volgende groepen van 16bits:
0xCC00 : status tegister read
0x8B61 : Band select: 434 MHz, CLK out select
(alt: 0x9361 : 868 MHz)
0xA640 : 434.000 MHz (868.000 MHz)
0xD040 : PLL setting, Data Rate/2
0xC823 : Data Rate = 4800 bps (9600 instellen!)
0xC220 : Enable bit sync
0xC001 : Enable clk out but close all other processes
Nu is de RFM klaar voor gebruik.
Als je een frame wilt verzenden dan moet je eerst de zender aanzetten.
Met dezelfde functie als de groepen hierboven, schijf dan naar de SPI poort:
0xC039 : Open TX
Daarna moet met een andere functie de data naar de RFM worden geschreven.
De nSEL uitgang zet je hoog en dat is het teken voor de RFM om data op de FSK ingang uit te zenden.
De RFM bepaalt door de status van nIRQ of het volgende bit op de FSK lijn overgenomen gaat worden.
Omdat de timing dus wordt bepaald door de RFM kun je begrijpen dat het dus op dit punt critisch kan worden. Hier zitten ook de meeste fouten in de programmering.
Doordat de timing voor de zender niet goed is, zal de ontvanger de syncronisatie verliezen en komt er helemaal of maar soms een deel van de data aan.
Dit is ook de reden dat de RFM02 beter een eigen microcontroller kunt geven en die via SPI of UART kunt koppelen aan de micro van je doelontwerp.
(zie de setup van Easy-RF).
Het frame bestaat altijd uit een preamble:
0xAA
0xAA
0xAA
(mogen er meer zijn)
En daarna de code:
0x2D
0xD4
Hierdoor kan de RFM01 (ontvanger) syncroniseren.
Daarna komt je data.
Let erop dat je niet teveel allemaal '0' of '1' achter elkaar verstuurd, dit kan de syncronisatie verstoren.
Afhankelijk van wat parameters (waar ik nu niet op in zal gaan), zijn 8 '0'-en of '1'-en achter elkaar het maximum.
Als je klaar bent met de data dan kun je afsluiten en met een CRC of weer een paar maal 0xAA.
Tot zover werkt het voorbeeld heel aardig.
De fouten bij de ontvanger (waarvan ik weet) zijn:
(ATmega source)
De nIRQ uitgang van de RFM zit niet aangesloten in het schema. Dat moet wel, want daarmee geeft de RFM aan dat de ontvanger gesynchroniseerd is en dat een byte klaar staat in de FIFO. Erg belangrijk dus..
Vergeet vooral de 10k weerstand tussen VCC en DATA niet!
Dat staat wel goed in het schema.
Initialiseren gaat op dezelfde manier als de zender maar dan met wat meer parameters.
De manier van werken is hetzelfde en je kunt dezelfde functie gebruiken.
De ontvanger staat in het voorbeeld altijd aan en is klaar voor ontvangst.
De ontvanger haalt de data uit de detector en zal blijven proberen te syncroniseren.
Als de ontvanger juist is ingesteld en een signaal valt binnen de 'lock' van de PLL, dan geeft ze intern een bitsyncronisatie signaal af.
Dan gaat ze wachten op de combinatie 0x2D en 0xD4.
Als dat is geweest, dan zal de ontvanger de nIRQ laag maken.
Op dat moment moet je code de data uit de FIFO lezen.
De manier om dat te doen is om in totaal 24 bits te gaan 'halen'.
Je maakt de uitgang SEL laag en dan kun je de data naar buiten clocken via CLK.
De eerste 16 bits bevat alle informatie van de ontvanger.
Mijn code bestuurt hier de firmware MAC mee.
Voor een uitleg van de individuele bits, zie :RF01.pdf, blz. 17.
De 8 bits daarna (uitgaande van een 8bits systeem) zijn de bits in de FIFO.
Als je alle 24 bits hebt gelezen, dan is de FIFO leeg en kun je wachten op de volgende nIRQ.
Als je een fout ontvangt, dan is het mogelijk om dat uit de eerste 16 bits te herkennen. Dan is het zaak om zo snel mogelijk de FIFO weer leeg te maken (te resetten) voor de volgende byte.
Dat die je door de volgende combinatie te sturen naar de SPI poort van de RFM:
0xCE88
0xCE8B
Dat wordt de FIFO gereset.
~~
Op de Fysieke laag kunnen de volgende fouten optreden:
- verkeerde frequentie
- verkeerde data rate
- bandbreedte van de zender/ontvanger (~1:1.5)
- storingen
Op MAC niveau kunnen de volgende fouten optreden:
- geen bitsyncronisatie
- geen byte synchonisatie
- timing van de zender (muy, muy importante!!!!)
Op systeemniveau (data verbindingslaag) kunnen de volgende fouten voorkomen:
- een afgebroken verbinding door bitfouten; teveel '0'-en en '1'-en achter elkaar.
- CRC fout
Enfin, buiten de fouten in de beide datasheets dus nog een heleboel ellende in de code en de timing van de code.
Er is nog Hope
Ik ben nu een nieuw boek aan het schrijven met daarin een zeer uitgebreide uiteenzetting van de chips met nog veel meer tips en truuks voor het programmeren van een firmware stack.
Ik hoop dat je hiermee wat verder kan komen.
Je kunt mij overigens altijd privé mailen met vragen.
Voor de rest nodig ik iedereen uit eventuele andere fouten in de source van Hope RF (datasheets: RF01_code.pdf en RF02_code.pdf) hier te posten.
Ik zal ze dan verzamelen en de datasheet in het Nederlands herschrijven.
Misschien hebben we binnenkort wel nieuwe datasheets met wel werkende voorbeelden! 
Hi Bart e.a.
Ik weet hij is oud, maar ik bump hem toch maar even...
Ik zit ook te worstelen met deze modules. En ik hoopte met jouw aanwijzingen weer iets verder te komen. Het zou perfect zijn als we gezamenlijk tot een werkende 'datasheet' zouden kunnen komen.
In de beschrijving van het ontvang gedeelte heb je het over het binnenklokken via de CLK pin. Dat staat inderdaad ook zo in het originele datasheet, maar moet dat niet ook gewoon via de SCK pin zijn?
Voor de rest gebruik ik de volgende init code voor de ontvanger:
rf_write_cmd( 0x898A ); // 433 MHz, Low battery detect off, Wake up timer disabled, Xtal enabled, Bandwidth 134 kHz, Clk enabled
rf_write_cmd( 0xA640 ); // 434 MHz
rf_write_cmd( 0xC847 ); // 4800 baud
rf_write_cmd( 0xC69B ); // VDI + offset, range -16 - +15, offset in output reg, no AFC high accuracy, AFC output enabled, AFC enabled
rf_write_cmd( 0xC42A ); // no clock recover auto-lock, No clock recover fast mode, data filter = Digital, DQD treshold = 2
rf_write_cmd( 0xC260 ); // Clk freq 2 MHz, low voltage treshold = 0v
rf_write_cmd( 0xC080 ); // VDI = clock recover lock output, LNA gain = 0dbm, DRSSI treshold = -103dbm, receiver not enabled
rf_write_cmd( 0xCE88 ); // FIFO interrupt level = 8, FIFO fill start = Sync-word, FIFO fill off, FIFO off
Bij het ontvangen krijg ik van de SDO pin alleen status bits terug. Op volgorde: 0x0F02, 0x0DC0, ...
Ik vermoed echter dat als er problemen zijn met bit-synchronisatie deze waarden niet te vertrouwen zijn. De VDI uitgang is wel hoog gemaakt door de RFM in deze periode. Dus dat spreekt daar weer tegen. Gebruik jij de VDI?
Het gekke is wel dat ik van de FFIT poort een soort van clock terug krijg. Maar als ik die gebruik om mijn FFS binnen te klokken dan zie ik daar consequent maar 12 klokpulsen dus dat is ook vreemd. Gebruik jij die FFIT poort ueberhaupt?
Ik weet dat er andere modules zijn, zoals de RFM12 en nu de RFM22 en RFM23, maar voor een simplex applicaties zouden dit in theorie perfecte en betaalbare modules zijn dus ik wil nog niet opgeven!
edit: RMF34 veranderd in RMF23
Bart Hiddink
Bart Hiddink is Ideetron; electronics and projects, http://www.ideetron.nl. LoRaWAN Nutcase.
Inmiddels is er voor de RFM12 werkende source geschreven:
http://www.ideetron.nl/Hope/Verzenden%20en%20ontvangen%20met%20de%20RF…
Ik kan niet goed beoordelen waar het vout gaat.
Kun je mij jou source sturen?
Binnen deze reeks zijn het de RFM01 (ontvanger) RFM02 (zender) en RFM12 (zend- ontvanger).
Dus nu ook leverbaar als ALPHA module via Farnell.
De RFM22 en 23 zijn echt hele andere dingen.
Die hebben ook een veel complexere interface.
Ja, precies die Alpha dingen gebruik ik. Ik werk overigens met PICs. In dit geval hangt-ie aan een LF14k50.
Dit is de zendcode
main start:
reply = rf_write_cmd( 0xCC00 ); // read status register
reply = rf_write_cmd( 0x8B61 ); // 433MHz, 2MHz clock, polarity fo+df, 60kHz deviation
reply = rf_write_cmd( 0xA640 ); // 434MHz
reply = rf_write_cmd( 0xD040 ); // PLL, datarate / 2
reply = rf_write_cmd( 0xC823 ); // 9600 / 2 = 4800 baud
reply = rf_write_cmd( 0xC220 ); // No wake up timer, TX bit synch, Low battery treshold = 0v
reply = rf_write_cmd( 0xC001 ); // Osc and synth manual, Power amp manual, Xtal disabled, Syntesizer disabled, Power amp disabled
// Low voltage detect disabled, CLK output enabled
while(1)
{
reply = rf_write_cmd( 0xC039 ); // Start transmitter
rf_write_data( 0xAA ); // Warm up sequence; preamble
rf_write_data( 0xAA ); // ||
rf_write_data( 0xAA ); // ||
rf_write_data( 0x2D ); // ||
rf_write_data( 0xD4 ); // \__/
// write data bytes here
// finish with writing checksum or crc
rf_write_data( 0x55 ); // Just send 'U' characters
rf_write_data( 0x55 ); // Just send 'U' characters
rf_write_data( 0xAA );
reply = rf_write_cmd( 0xC001 );
// delay long time ( 1 sec)
WAIT1s;
}
main end:
void rf_write_0( void )
{
nSCK = 0;
Delay1TCY();
nSDI = 0;
// delay 15 cycles @ 10 MHz = 6 usec
WAIT6u;
nSCK = 1;
Delay1TCY();
}
void rf_write_1( void )
{
nSCK = 0;
Delay1TCY();
nSDI = 1;
// delay 15 cycles @ 10 MHz = 6 usec
WAIT6u;
nSCK = 1;
Delay1TCY();
}
void rf_write_data( BYTE data )
{
BYTE n = 8;
nSEL = 1;
while( n-- )
{
if( data&0x80 )
nFSK = 1;
else
nFSK = 0;
// delay 15 cycles @ 10 MHz = 6 usec
WAIT6u;
data <<= 1;
}
nSEL = 0;
}
WORD rf_write_cmd( WORD cmd )
{
BYTE n = 16;
WORD result = 0;
nSEL = 0;
while( n-- )
{
if( cmd&0x8000 )
rf_write_1();
else
rf_write_0();
cmd <<= 1;
}
nSEL = 1;
return result;
}
En de receive code:
main lus start:
rf_write_cmd( 0x0000 ); // read status register
rf_write_cmd( 0x898A ); // 433 MHz, Low battery detect off, Wake up timer disabled, Xtal enabled, Bandwidth 134 kHz, Clk enabled
rf_write_cmd( 0xA640 ); // 434 MHz
rf_write_cmd( 0xC847 ); // 4800 baud
rf_write_cmd( 0xC69B ); // VDI + offset, range -16 - +15, offset in output reg, no AFC high accuracy, AFC output enabled, AFC enabled
rf_write_cmd( 0xC42A ); // no clock recover auto-lock, No clock recover fast mode, data filter = Digital, DQD treshold = 2
rf_write_cmd( 0xC260 ); // Clk freq 2 MHz, low voltage treshold = 0v
rf_write_cmd( 0xC080 ); // VDI = clock recover lock output, LNA gain = 0dbm, DRSSI treshold = -103dbm, receiver not enabled
rf_write_cmd( 0xCE88 ); // FIFO interrupt level = 8, FIFO fill start = Sync-word, FIFO fill off, FIFO off
WAIT1s;
rf_write_cmd( 0xCE8B ); // FIFO interrupt level = 8, FIFO fill start = Sync-word, FIFO fill on, FIFO on
rf_write_cmd( 0xC081 ); // VDI = clock recover lock output, LNA gain = 0dbm, DRSSI treshold = -103dbm, Receiver enabled
while(1)
{
while( !nIRQ )
{
receiveBuffer[i++] = rf_read_fifo();
if( i == 8 )
{
rf_write_cmd( 0xCE88 ); // FIFO interrupt level = 8, FIFO fill start = Sync-word, FIFO fill on, FIFO on
rf_write_cmd( 0xCE8B ); // FIFO interrupt level = 8, FIFO fill start = Sync-word, FIFO fill on, FIFO on
i = 0;
}
}
}
main lus end:
void rf_write_data( BYTE data )
{
BYTE n = 8;
nSEL = 1;
while( n-- )
{
if( data&0x80 )
nFSK = 1;
else
nFSK = 0;
// delay 15 cycles @ 10 MHz = 6 usec
WAIT6u;
data <<= 1;
}
nSEL = 0;
}
rf_wite_cmd identiek aan zender
Dit is de code die ik nu heb. Ik had n.a.v. jouw opmerkingen een paar dingen veranderd: PLL in zender, FIFO commando's van CE84/CE87 naar wat jij had. In principe ging ik nog steeds uit van de Hope datasheets.
Hier een stukje van de output uit de analyzer:
http://img21.imageshack.us/img21/1808/analyzer.png
Npg even over die output van de analyzer. Vanaf ong. de helft zie je 0xCE88 en 0xCE8B commando`s weggeschreven worden. Het gekke is dat aan het einde van het eerste commando (0xCE88) de RFM al FFIT interupts/clocks begint te geven en bits uitspuugt op SDO. In dit geval 12 bits: 0xCFE
[Bericht gewijzigd door Henry S. op (3%)]
Het echo-ed een beetje hier... 
Ondertussen heb ik het aan de praat gekregen. Dankzij hulp van Hope RF (Mark ofwel ?? als ik het goed heb) was bijzonder behulpzaam. En hoewel hij me niet echt heeft kunnen helpen, behalve door duidelijk te maken dat de bandbreedte van de ontvanger minimaal 2x de frequentie 'deviation' van de zender moet zijn, was het wel daardoor dat ik bleef zoeken.
Uiteindelijk bleek er niet zoveel fout te zijn, maar wel dat de timing van het zenden uiterst cruciaal is wanneer je de gegevens via FSK binnen klokt.
Onmiddellijk als je het zendcommando gegeven hebt, begint de transmitter irq's te genereren 'op de maat van' de ingestelde baudrate. Die pulsen zijn dan laag voor de duur van 1 baud en daarna heel even hoog (1.6usec) om daarna weer laag te gaan. In het voorbeeld staat er dat je daarom
while( !nIRQ) ; while( nIRQ );moet doen om dat af te vangen. En dat gaat vaak niet goed. Niet alleen moet je je MCU op een voldoende hoge clock laten draaien om sowieso de eerste puls al te vangen, maar veel MCU's hebben meerdere clockcycli nodig om die tweede while uit te voeren en omdat deze maar 1.6 usec duurt (bij alle in te stellen snelheden voor de transmitter trouwens, zo leek wel) mis je dus het afvangen daarvan. In dat geval moet je inclock routine dus exact gelijk lopen met de irq pulsen en dat is niet te doen.
Ik heb dat opgelost door toch een gewone IRQ routine te gebruiken die een bool zet als er een irq binnenkomt. In mijn routine hoef ik dus alleen maar daarop te wachten. En bij 4800 baud bijv. heb je dan meer dan genoeg tijd om de lus uit te voeren voor de volgende puls.
Welke clockfrequentie en welke baudrate je gebruikt zijn niet bijzonder van invloed op de werking trouwens. Ik heb verschillende geprobeerd en dat werkte allemaal vlekkeloos.
Willem
Op 3 december 2009 18:36:00 schreef WJR:
Het echo-ed een beetje hier...Ondertussen heb ik het aan de praat gekregen. Dankzij hulp van Hope RF (Mark ofwel ?? als ik het goed heb) was bijzonder behulpzaam. En hoewel hij me niet echt heeft kunnen helpen, behalve door duidelijk te maken dat de bandbreedte van de ontvanger minimaal 2x de frequentie 'deviation' van de zender moet zijn, was het wel daardoor dat ik bleef zoeken.
Uiteindelijk bleek er niet zoveel fout te zijn, maar wel dat de timing van het zenden uiterst cruciaal is wanneer je de gegevens via FSK binnen klokt.
Onmiddellijk als je het zendcommando gegeven hebt, begint de transmitter irq's te genereren 'op de maat van' de ingestelde baudrate. Die pulsen zijn dan laag voor de duur van 1 baud en daarna heel even hoog (1.6usec) om daarna weer laag te gaan. In het voorbeeld staat er dat je daaromwhile( !nIRQ) ; while( nIRQ );moet doen om dat af te vangen. En dat gaat vaak niet goed. Niet alleen moet je je MCU op een voldoende hoge clock laten draaien om sowieso de eerste puls al te vangen, maar veel MCU's hebben meerdere clockcycli nodig om die tweede while uit te voeren en omdat deze maar 1.6 usec duurt (bij alle in te stellen snelheden voor de transmitter trouwens, zo leek wel) mis je dus het afvangen daarvan. In dat geval moet je inclock routine dus exact gelijk lopen met de irq pulsen en dat is niet te doen.
Ik heb dat opgelost door toch een gewone IRQ routine te gebruiken die een bool zet als er een irq binnenkomt. In mijn routine hoef ik dus alleen maar daarop te wachten. En bij 4800 baud bijv. heb je dan meer dan genoeg tijd om de lus uit te voeren voor de volgende puls.
Welke clockfrequentie en welke baudrate je gebruikt zijn niet bijzonder van invloed op de werking trouwens. Ik heb verschillende geprobeerd en dat werkte allemaal vlekkeloos.Willem
Heeft iemand toevallig een volledig werkende code inmiddels? (+schema etc) Ik heb de -02 module hier, en wil graag voor de hobby wat dingen testen.