Arduino uno + rfm_01 + rfm02

rigl
Offline
Зарегистрирован: 15.10.2014

Здравствуйте,

Помогите разобратся с приемником и передатчиком  - никак не могу установить устойчивую связь.

Код передатчика

#define RF02FREQ(freq)  ((freq-430.0)/0.0025)
 
#define RF_PORT  PORTB
#define RF_DDR  DDRB
#define RF_PIN  PINB

#define LED_PORT  PORTD
#define LED_DDR   DDRD
#define LED_PIN   PIND


#define SDI   0 // SDI,  -> RF02   Atmega PB0 Arduino 8
#define SCK   1 // SCK,  -> RF02   Atmega PB1 Arduino 9 
#define CS    2 // nSEL, -> RF02   Atmega PB2 Arduino 10 
#define IRQ   4 // nIRQ, <- RF02   Atmega PB4 Arduino 12
//------------------// FSK: Pullupto VCC

#ifndef cbi
#define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit)) 
#endif
#ifndef sbi
#define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))  
#endif



unsigned char test[32]="     55555      \n";

void rf02_changeText( unsigned char* ptr, uint8_t number){

  if (number> 32)number = 32;
    memcpy( test, ptr, number);
 
}

void rf02_sendData(){

  rf02_txdata( test, sizeof test);
}



void rf02_trans(unsigned short  value)
{ uint8_t i;

  cbi(RF_PORT, CS);

  for (i=0; i<16; i++)
  { if (value&0x8000) //0x8000
      sbi(RF_PORT, SDI);
    else
      cbi(RF_PORT, SDI);

    sbi(RF_PORT, SCK);
    value<<=1;
    _delay_us(0.1);
    cbi(RF_PORT, SCK);
  }
  sbi(RF_PORT, CS);
}



void rf02_init(void)
{
  RF_PORT=(1<<CS);
  RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);

  for (unsigned char i=0; i<15; i++)
    _delay_ms(10);      // wait until POR done
  rf02_trans(0xCC00);     // power settings
  rf02_trans(0x8861);// fsk in rfm02 = afc in rf12
//    rf02_trans(0x80C7);
  rf02_trans(0xC220);     // enable tx sync bit, disable low bat detector

  //LED_DDR= 0xFF;
}

void rf02_setmodfreq(uint8_t bandwidth)
{
  rf02_trans(0x8F80|(bandwidth&7));
  //rf02_trans(0x8F70);
}

void rf02_setfreq(unsigned short freq)
{ if (freq<96)        // 430,2400MHz
    freq=96;
  else if (freq>3903)     // 439,7575MHz
    freq=3903;
  rf02_trans(0xA000|freq);

  //rf02_trans(0xA640); //= 434 MHz
}

void rf02_setpower(uint8_t power)
{
  rf02_trans(0xB000|((power&7)<<8));
}

void rf02_setbaud(unsigned short baud)
{
 
  if (baud<1345)
    baud=1345;
  if (baud<19000)
    rf02_trans(0xD240);   // 25% PLL current
  else if (baud<37000)
    rf02_trans(0xD2C0);   // 33% PLL current
  else
    rf02_trans(0xD200);   // 50% PLL current

  rf02_trans(0xC800|((344828UL/baud)-1)); // Baudrate= 344827,59/(R+1)
 
  rf02_trans(0xC806);
}

void rf02_txdata( unsigned char * data, uint8_t number)
{ 
  uint8_t i,value;
  //rf02_trans(0xc039);
  value=0xC6;          //1100 0110
  cbi(RF_PORT, CS);   //nSel

  for (i=0; i<8; i++)
    { if (value&0x80)   //1000 0000 = 80
        sbi(RF_PORT, SDI);
      else
        cbi(RF_PORT, SDI);

      sbi(RF_PORT, SCK);
      value<<=1;
      //_delay_us(0.1);
      cbi(RF_PORT, SCK);
    }
  rf02_shiftout(0xAA);
  rf02_shiftout(0xAA);
  rf02_shiftout(0xAA);//10101010
  rf02_shiftout(0x2D);//00101101
  rf02_shiftout(0xD4);//11010100
  
  
  // no checkbit, in experimenting some letters were transmitted wrong!

  for (i=0; i<number; i++)
    rf02_shiftout(*data++);

  sbi(RF_PORT, CS);
  sbi(RF_PORT, SCK);
  while(RF_PIN&(1<<IRQ));   // wait until transfer done
   rf02_trans(0xC001);       // TX off after 10us

}

void rf02_shiftout(unsigned char value)
{ uint8_t j;
  for (j=0; j<8; j++)
  { while(RF_PIN&(1<<IRQ));
      while(!(RF_PIN&(1<<IRQ)));
    if (value&128)             
        sbi(RF_PORT, SDI);
      else
        cbi(RF_PORT, SDI);
      value<<=1;
  
  
    }
}
void setup()
{
  //  CLKPR = 1<<CLKPCE;
  //CLKPR = 3;
// Serial.begin(9600);
  rf02_init();         
  rf02_setfreq(RF02FREQ(438));  // 433,92MHz
  rf02_setpower(1);       // -12dBm 
  rf02_setmodfreq(3);       // 120kHz 
  rf02_setbaud(19200);     // 19200 Baud 
}
void loop(){
  unsigned char buf[] = { "123456789012345678901234567890 " };
  uint8_t crc = 0;
  uint8_t i;
  rf02_changeText( buf, sizeof buf);
  rf02_sendData();
  delay(10);
  
}

Код приемника:

#define RF_PORT  PORTB
#define RF_DDR  DDRB
#define RF_PIN  PINB

#define SDI   3 // RF01  SDI
#define SCK   5 // RF01  SCK
#define CS    2 // RF01  nSEL
#define SDO   4 // RF01  SDO
//----------------- // RF01  niRQ, arduino  02 cannot be changed
//------------------// RF01  nFFS: 1-10k Pullup too Vcc

#define RF01FREQ(freq)  ((freq-430.0)/0.0025)
#define rf01_data       (rf01_buf + 2)
// nFFS: 1-10k Pullup an Vcc !!!

#ifndef cbi
#define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit)) 
#endif
#ifndef sbi
#define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))  
#endif


// maximum receive buffer
#define RF_MAX   32
unsigned char  rf01_buf[RF_MAX];  // recv buf

#include <util/delay.h>

void rf01_receive(){
  rf01_rxdata(rf01_data, 32);
}

void rf01_prepAll(){
  rf01_init();          // ein paar Register setzen (z.B. CLK auf 10MHz)
  rf01_setfreq(RF01FREQ(438));  // Sende/Empfangsfrequenz auf 433,92MHz einstellen
  rf01_setbandwidth(2);     // 4 200kHz Bandbreite
  rf01_setreceiver(2,4);      //2,4 -6dB Verstдrkung, DRSSI threshold: -79dBm 
  rf01_setbaud(38400);      // 19200 Baud

}

static unsigned char sdrssi, sgain;
static char right[] = "123456789012345678901234567890";


void rf01_trans(unsigned short wert)
{ 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);
    sbi(RF_PORT, SCK);
    wert<<=1;
    //_delay_us(1);

    cbi(RF_PORT, SCK);
  }
  sbi(RF_PORT, CS);
}

void rf01_init(void)
{ unsigned char i;

  RF_PORT=(1<<CS);
  RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);

  for (i=0; i<11; i++)
    _delay_ms(10);      // wait until POR done
#define CLC_FRQ 2
  rf01_trans(0x0000);
  rf01_trans(0xC200|(CLC_FRQ<<6)|0); 
  //rf01_trans(0xC240);
  rf01_trans(0xC42A);     // Data Filter: internal
  rf01_trans(0xCE88);     // FIFO mode
  rf01_trans(0xC62C);     // AFC settings: autotuning: -10kHz...+7,5kHz
  rf01_trans(0xE000);     // disable wakeuptimer
  rf01_trans(0xCC00);     // disable low duty cycle


}

void rf01_setbandwidth(unsigned char bandwidth)
{
  rf01_trans(0x8970|((bandwidth&7)<<1));
}

void rf01_setreceiver(unsigned char gain, unsigned char drssi)
{
  sdrssi=drssi;
  sgain=gain;
}

void rf01_setfreq(unsigned short freq)
{ if (freq<96)        // 430,2400MHz
    freq=96;
  else if (freq>3903)     // 439,7575MHz
    freq=3903;
  rf01_trans(0xA000|freq);
}

void rf01_setbaud(unsigned short baud)
{
  if (baud<336)
    return;
  if (baud<5400)        // Baudrate= 344827,58621/(R+1)/(1+CS*7)
    rf01_trans(0xC880|((43104/baud)-1));
  else
    rf01_trans(0xC800|((344828UL/baud)-1));

  rf01_trans(0xC806);
}

void rf01_rxdata(unsigned char *data, unsigned char number)
{ unsigned char i,j,c;

  rf01_trans(0xC0C1|((sgain&3)<<4)|((sdrssi&7)<<1));  // RX on
  rf01_trans(0xCE89);     // set FIFO mode
  rf01_trans(0xCE8B);     // enable FIFO
  cbi(RF_PORT, SDI);
  for (i=0; i<number; i++)
  { cbi(RF_PORT, CS);
    while (!(RF_PIN&(1<<SDO))); // wait until data in FIFO
    for (j=0; j<16; j++)  // read and discard status register
    { 
      sbi(RF_PORT, SCK);
      //asm("nop");
      cbi(RF_PORT, SCK);


    }
    c=0;
    for (j=0; j<8; j++)
    { c<<=1;
      if (RF_PIN&(1<<SDO))
        c|=1;
      sbi(RF_PORT, SCK);
      _delay_us(0.2);
      cbi(RF_PORT, SCK);
    }
    *data++=c;
    sbi(RF_PORT, CS);
  }

  rf01_trans(0xC0C0|((sgain&3)<<4)|((sdrssi&7)<<1));  // RX off

}

uint16_t error,correct = 0;
void setup() {
  
  Serial.begin(115200);
  Serial.println("\nRF02 receive");
  delay(250);

  rf01_prepAll();

  delay(250);
  Serial.println("startup");
}

void loop() {

  rf01_receive();
  char* buf = (char*) rf01_data;
  //Serial.println(buf);
  (memcmp(right,buf,30) == 0) ? correct++ : error++;
  if((error+correct)/100 == 1)
  {
  Serial.println(float(correct)/(error+correct));
  error = correct = 0;
  }

  
}

 

С изменением задержек, частоты, скорости - удавалось добится примерно 35-40% корректных передач, остальные бьются. Вроде бы это проблема синхронизации приемника и передатчика, но как их синхронизировать - не понятно. Еще пишут, что 5V не очень им нравится, подключил приемник к 3,3, передатчик не вышло (передача не идет, может питания не хватает). Хотя до этого зашивал код в Attiny45 и питал ее от 3,3 работал - но с прежним результатом. Резисторы на nFFS и FSK 10K

Вот вывод Serial:

1234567™љ›њ™љ›њ
121љ›њ™љЌЌОLLЊН
MЌП&
12345678908™љ›њ™Н
MЌОL
123456789012345678<™љ›њ
123456789012345678901234567890#
123456789012345678901234567890#
1234567њ™љ›њњLЊН
MЌОL
12љ›њ™љMЌОLLЊН
MЌЗ&
1234567890™љ›њЂ21љ›њ
123456789012345678™љ›њ
123456789012345678901234567890 
123456789012345678901234567890#
1234563њ™љ›њЊLЊН
MЌОL
12љ›њ™љMЌОLLЊН
MЌз&
1234567890™љ›њ™Н
MЌОL
123456789012345678901234567890 
123456789012345678901234567890 
123456789012345678901234567890#
123456;њ™љ›њМLЊН
MЌОL
13љ›њ™љMЌОLLЊН
MЌз&
1234567890™љ›њ™Н
MЌОL
1234567890123456789012345678900
123456789012345678901234567890 
123456789012345678901234567890#
12345678900™љ›њ™љ›њ
123456њ™љ›њLLЊН
MЌОL
11љЂ678901234›њ™љ›ОO
1234567898123456789012љ›њ
123456789012345678901234567890
123456789012345678901234567890 
12;456789012345678901234567890 
12345678900™љ›њ™љ›њ
123456њ™љ›њLLЊН
MЌОL
19љ›њ™љ
MЌОLLЊН
MЋз&

 

kokuam
kokuam аватар
Offline
Зарегистрирован: 10.01.2017

Привет, получилось победить модуль?