Problema comunicazione NRF24L01+

Home Forum FORUM ELETTRONICA MICROCONTROLLORI E CODICI Problema comunicazione NRF24L01+

Taggato: 

  • Questo topic ha 18 risposte, 2 partecipanti ed è stato aggiornato l'ultima volta 6 anni, 2 mesi fa da ne555. This post has been viewed 2263 times
Stai visualizzando 15 post - dal 1 a 15 (di 19 totali)
  • Autore
    Post
  • #4304
    Led_ON
    Partecipante

    Buonasera a tutti,
    mi chiamo Elia, felice di essere parte di questo sito.

    Sto realizzando una semplice comunicazione tra due modulini NRF24L01+ con due PIC18F25K22. Il codice l’ho preso da questo sito, a questo LINK https://www.ne555.it/trasmissione-di-dati-wireless-con-il-modulo-nrf24l01/

    Ho scaricato il file alla fine dell’articolo e ho riadattato il codice al mio micro. Uso MikroC.
    Ho montato correttamente il circuito, ma non funziona.

    Vi posto il codice, che è lo stesso messo sul sito eccetto per il while(1) e perchè ho tolto la dichiarazione del PIN IRQ che non uso. L’ho comunque collegato alla 3.3V.

    • Questo topic è stato modificato 6 anni, 2 mesi fa da ne555.
    #4306
    Led_ON
    Partecipante

    CODICE TRASMETTITORE: (provo a vedere se riesco a postare)

    
    sbit RF_CS_TRIS at TRISB3_bit;       //PIN CHIP SELECT
    sbit RF_CE_TRIS at TRISB2_bit;       //PIN ENABLE
    sbit SCK_TRIS at TRISB1_bit;         //CLK SPI
    sbit SDI_TRIS at TRISB0_bit;         //DATA IN
    sbit SDO_TRIS at TRISB5_bit;         //DATA OUT
    //----------------------------------------------------------------------------------------------------------------------------//
    sbit SS_pin at RB3_bit;
    sbit CE_pin at RB2_bit;
    sbit SCK_pin at RB1_bit;
    sbit MOSI_pin at RB5_bit;
    sbit MISO_pin at RB0_bit;
    //----------------------------------------------------------------------------------------------------------------------------//
    sbit Led at RB4_bit;                 //LED INDICAZIONE
    //----------------------------------------------------------------------------------------------------------------------------//
    #define R_REGISTER_cmd                0x00           //COMANDO DI SCRITTURA
    #define W_REGISTER_cmd                0x20           //COMANDO DI LETTURA
    #define R_RX_PL_WID_cmd               0x60           //LEGGI DIMENSIONE PAYLOAD
    #define R_RX_PAYLOAD_cmd              0x61           //LEGGI PAYLOAD RICEVUTO
    #define W_TX_PAYLOAD_cmd              0xA0           //SCRIVI PAYLOAD
    #define W_ACK_PAYLOAD_cmd             0xA8           //ACK DEL PAYLOAD
    #define W_TX_PAYLOAD_NO_ACK_cmd       0xB0           //DISABILITA AUTO ACK
    #define FLUSH_TX_cmd                  0xE1           //SVUOTA LA FIFO DEL TX
    #define FLUSH_RX_cmd                  0xE2           //SVUOTA LA FIFO DELL'RX
    #define REUSE_TX_PL_cmd               0xE3           //RIUTILIZZA ULTIMO PAYLOAD INVIATO
    #define NOP_cmd                       0xFF           //NESSUN COMANDO
    //----------------------------------------------------------------------------------------------------------------------------//
    #define CONFIG_reg                    0b00000000     //INTERRUPT , CRC, ON/OFF, TX MODE SETTING
    #define EN_AA_reg                     0x01           //AUTO ACK PIPE
    #define EN_RXADDR_reg                 0x02           //ABILITAZIONE INDIRIZZI RX
    #define SETUP_AW_reg                  0x03           //NUMERO DI INDIRIZZI (5)
    #define SETUP_RETR_reg                0x04           //SETTING TEMPO DI RITRASMISSIONE (250uS)
    #define RF_CH_reg                     0x05           //CANALE 5
    #define RF_SETUP_reg                  0b00000110     //{b5-b3 => (00 1Mbps),(01 2Mbps), (10 250Kbps)} {b2:b1 => (00 -18dBm), (01 -12dBm), (10 -6dBm), (11 0dBm)}
    #define STATUS_reg                    0x07           //REGISTRO DI STATO, INVIATO AL PIN MOSI
    #define OBSERVE_TX_reg                0x08           //CONTA I LOST PACKET E I RETRASMITTED PACKET
    #define RPD_reg                       0x09           //AVVERTE SE VI è UN TRASMETTITORE ATTIVO
    #define RX_ADDR_P0_reg                0x0A           //RICEVE L'INDIRIZZO 0
    #define RX_ADDR_P1_reg                0x0B           //
    #define RX_ADDR_P2_reg                0x0C           //
    #define RX_ADDR_P3_reg                0x0D           //
    #define RX_ADDR_P4_reg                0x0E           //
    #define RX_ADDR_P5_reg                0x0F           //
    #define TX_ADDR_reg                   0x10           //TRASMISSIONE INDIRIZZI
    #define RX_PW_P0_reg                  0x11           //NUMERO DI BYTE DEL PAYLOAD NEL DATA PIPE 0
    #define RX_PW_P1_reg                  0x12           //
    #define RX_PW_P2_reg                  0x13           //
    #define RX_PW_P3_reg                  0x14           //
    #define RX_PW_P4_reg                  0x15           //
    #define RX_PW_P5_reg                  0x16           //
    #define FIFO_STATUS_reg               0x17           //RIUTILIZZA TRASMISSIONE E STATO DELLA FIFO
    #define DYNPD_reg                     0x1C           //ENABLE DYNAMIC PAYLOAD LENGHT
    #define FEATURE_reg                   0x1D           //ABILITAZIONE MODALITà DYPLD, ACK, NO ACK
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char x = 0;                                 //CONTIENE IL BYTE DA INVIARE
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char nRF24L01_read()                        //questo sottoprogramma simula una comunicazione SPI
    {
      unsigned char s = 0;                               //variabile per esegguire 8 esecuzioni
      unsigned char msg = 0;
    
      for(s = 0; s < 8; s++){                            //esegue 8 volte
          msg <<= 1;                                     //shifto msg
          SCK_pin = 1;                                   //attivo il clock
          delay_us(8);                                   //aspetto 8us (f spi 62Kbps)
          if(MISO_pin != 0)                              //se in=0
          {
            msg |= 1;                                    //azzero il bit di msg
          }
          SCK_pin = 0;                                   //disattivo il clock
          delay_us(8);
      }
    
      return msg;                                       //ritorno il valore letto
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void nRF24L01_write(unsigned char d){                //sottoprogramma che simula una scrittura spi
      unsigned char s = 0;
    
      for(s = 0; s < 8; s++)                            //questo for serve a trasmettere sul pin mosi bit per bit il dato d
      {
        if((d & 0x80) != 0)
        {
          MOSI_pin = 1;                                 //se il bit scandito è 1 trasmetto 1
        }
        else
        {
          MOSI_pin = 0;                                 //altrimenti 0
        }
        d <<= 1;                                        //shifto d per inviare il prossimo bit
        SCK_pin = 1;                                    //creo un clock
        delay_us(8);
        SCK_pin = 0;
        delay_us(8);
      }
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void register_write(unsigned char reg, unsigned char value)                //sottoprogramma per scrivere i registri
    {
      SS_pin = 0;                                                              //indico che sto per inviare un comando
      nRF24L01_write((reg | W_REGISTER_cmd));                                  //maschero il registro con il comando per scrivere
      nRF24L01_write(value);                                                   //invio il valore che voglio scrivere nel registro
      SS_pin = 1;
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void write_command(unsigned char cmd) {                                    //sottoprogramma scrittura comandi
      SS_pin = 0;                                                              //indico che voglio inviare un comando
      nRF24L01_write(cmd);                                                     //scrivo il comando cmd
      SS_pin = 1;                                                              //ripristino il pin ss
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char register_read(unsigned char reg)                            //sottoprogramma lettura registri
    {
      unsigned char value = 0;
    
      SS_pin = 0;
      nRF24L01_write((reg | R_REGISTER_cmd));                                 //indico che voglio leggere e quale registro leggere
      value = nRF24L01_read();                                                //leggo il dato che il modulo mi manda
      SS_pin = 1;
      delay_us(8);
    
      return value;
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void set_TX_RX_address(unsigned char *addr, unsigned char bytes, unsigned char reg)      //sottoprogramma per scrivere gli indirizzi
    {
      unsigned char n = 0;
    
      SS_pin = 0;
      nRF24L01_write((reg | W_REGISTER_cmd));                                               //indico che voglio scrivere i registri
      for(n = 0; n < bytes; n++)
      {
        nRF24L01_write(addr[n]);                                                            //bytes contiene il numero di indirizzi
      }                                                                                     //scrivo gli n indirizzi
      SS_pin = 1;
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void flush_TX_RX()                                      //sottoprogramma per cancellare le FIFO
    {
      register_write(STATUS_reg, 0x70);
      write_command(FLUSH_TX_cmd);
      write_command(FLUSH_RX_cmd);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void send_data(unsigned char bytes, unsigned char *value)        //sottoprogramma per inviare i dati
    {
      unsigned char s = 0;
    
      flush_TX_RX();                                                //cancello le FIFO
      register_write(CONFIG_reg, 0x3A);                             //setto la modalità tx da CONFIG_reg e attivo il modulo
    
      SS_pin = 0;
      nRF24L01_write(W_TX_PAYLOAD_cmd);                             //scrivo nel registo di trasmissione i bit da inviare
      for(s = 0; s < bytes; s++)
      {
        nRF24L01_write(value[s]);
      }
      SS_pin = 1;
      delay_us(8);
    
      CE_pin = 1;                                                 //faccio partire l'invio, aspetto 60us e poi disattivo il modulo
      delay_us(60);
      CE_pin = 0;
    
      register_write(CONFIG_reg, 0x38); //En modo RX se quita
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void receive_data(unsigned char bytes, unsigned char *value)         //sottoprogramma per la ricezione, indico il numero di bytes del dato
    {                                                                    //value contiene il dato letto
      unsigned char s = 0;
    
      SS_pin = 0;                                                        //scrivo il comando che indica che voglio leggere
      nRF24L01_write(R_RX_PAYLOAD_cmd);
      for (s = 0; s < bytes; s++)
      {
        value[s] = nRF24L01_read();                                      //leggo il dato che il modlo mi sta inviando
      }
      SS_pin = 1;
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void nrF24L01_init_TX()                                             //sottoprogramma per settare la modalità trasmissione
    {
      unsigned char address[5] = {0x99, 0x99, 0x99, 0x99, 0x99};        //indirizzo a 5bytes con valore a piacere(devo coincidere però con il rx)
    
      CE_pin = 0;
    
      register_write(SETUP_RETR_reg, 0x00);                             //ritrasmissione disabilitata
      register_write(SETUP_AW_reg, 0x03);                               //setto che ho indirizzo a 5bytes
      register_write(RF_SETUP_reg, 0x0E);                               //potenza 0dbm e velocità 250Kbps
      register_write(RF_CH_reg, 0x09);                                  //setto il canale di trasmissione, canale 9 in questo caso(il ricevitore deve avere uguale canale)
      register_write(EN_AA_reg, 0x00);                                  //auto ack disabilitato
      register_write(CONFIG_reg, 0x38);                                 //interrupt abilitati su TX_DS e MAX_RT, crc abilitato
      set_TX_RX_address(address, 5, TX_ADDR_reg);                       //inserisco gli indirizzi nell'apposito registro
      set_TX_RX_address(address, 5, RX_ADDR_P0_reg);
      flush_TX_RX();                                                    //cancella le fifo
    
      CE_pin = 1;
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void nrF24L01_init_RX()                                             //programma per settare la modalità RX
    {
      unsigned char address[5] = {0x99, 0x99, 0x99, 0x99, 0x99};        //indirizzo a 5bytes uguale a quello del TX
    
      CE_pin = 0;
    
      register_write(CONFIG_reg, 0x38);                                 //Crc abilitato, no interrup di ricezione
      register_write(SETUP_RETR_reg, 0x00);                             //ritrasmissione non richiesta
      register_write(SETUP_AW_reg, 0x03);                               //indirizzo a 5bytes
      register_write(RF_SETUP_reg, 0x0E);                               //potenza 0dbm e velocità 250Kbps
      register_write(RF_CH_reg, 0x09);                                  //canale9
      register_write(EN_AA_reg, 0x00);                                  //no ack
      register_write(RX_PW_P0_reg, 0x01);                               //dato a 1byte
      register_write(CONFIG_reg, 0x3B);                                 //setto il modulo come RX
      set_TX_RX_address(address, 5, TX_ADDR_reg);                       //scrivo gli indirizzi nell'apposito registro
      set_TX_RX_address(address, 5, RX_ADDR_P0_reg);
      flush_TX_RX();                                                    //cancello le fifo
    
      CE_pin = 1;
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char get_Status_Reg()                       //sottoprogramma per leggere lo status register che mi fornisce info sul modulo
    {
      return register_read(STATUS_reg);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    
    void main(){                                        //programma principale
    
     TRISA     =  0x00;                                 //setto in e output e inizializzo le uscite a 0
     TRISB     =  0x00;                                 //indicare solo le porte disponibile sul microcontrollore
     TRISC     =  0x00;
     PORTA = 0X00;
     PORTB = 0X00;
     PORTC = 0x00;
    
    //----------------------------------------------------------------------------------------------------------------------------//
     RF_CS_TRIS = 0;
     RF_CE_TRIS = 0;
     SCK_TRIS = 0;
     SDI_TRIS = 1;                                      //MISO
     SDO_TRIS = 0;                                      //MOSI
    
     CE_pin = 0;
     SS_pin = 0;
     SCK_pin = 0;
     MOSI_pin = 0;                                    //fine settaggio porte di comunicazione col modulo
     //----------------------------------------------------------------------------------------------------------------------------//
    
     delay_ms(10);
    
     nrF24L01_init_TX();                             //setto il modulo come TX
    
     delay_ms(100);                                  //delay di assestamento
    
     while(1){                                        //ciclo infinito
      x=10;                                //il dato lo prendo dall'adc (si può prendere da altre fonti)
      delay_ms(3000);                                //aspetto 3sec prima di un nuovo invio
      send_data(1, &x);                              //invio 1byte e il byte è la variabile x
      PORTC = x;                                     //visualizzo il dato inviato sul trasmettitore
    
     }
    
    
    #4307
    Led_ON
    Partecipante

    Ok, posto anche il ricevitore, scusate.

    CODICE RICEVITORE:

    
    sbit RF_CS_TRIS at TRISB3_bit;       //PIN CHIP SELECT
    sbit RF_CE_TRIS at TRISB2_bit;       //PIN ENABLE
    sbit SCK_TRIS at TRISB1_bit;         //CLK SPI
    sbit SDI_TRIS at TRISB0_bit;         //DATA IN
    sbit SDO_TRIS at TRISB5_bit;         //DATA OUT
    //----------------------------------------------------------------------------------------------------------------------------//
    sbit SS_pin at RB3_bit;
    sbit CE_pin at RB2_bit;
    sbit SCK_pin at RB1_bit;
    sbit MOSI_pin at RB5_bit;
    sbit MISO_pin at RB0_bit;
    //----------------------------------------------------------------------------------------------------------------------------//
    sbit Led at RB4_bit;                 //LED INDICAZIONE
    //----------------------------------------------------------------------------------------------------------------------------//
    #define R_REGISTER_cmd                0x00           //COMANDO DI SCRITTURA
    #define W_REGISTER_cmd                0x20           //COMANDO DI LETTURA
    #define R_RX_PL_WID_cmd               0x60           //LEGGI DIMENSIONE PAYLOAD
    #define R_RX_PAYLOAD_cmd              0x61           //LEGGI PAYLOAD RICEVUTO
    #define W_TX_PAYLOAD_cmd              0xA0           //SCRIVI PAYLOAD
    #define W_ACK_PAYLOAD_cmd             0xA8           //ACK DEL PAYLOAD
    #define W_TX_PAYLOAD_NO_ACK_cmd       0xB0           //DISABILITA AUTO ACK
    #define FLUSH_TX_cmd                  0xE1           //SVUOTA LA FIFO DEL TX
    #define FLUSH_RX_cmd                  0xE2           //SVUOTA LA FIFO DELL'RX
    #define REUSE_TX_PL_cmd               0xE3           //RIUTILIZZA ULTIMO PAYLOAD INVIATO
    #define NOP_cmd                       0xFF           //NESSUN COMANDO
    //----------------------------------------------------------------------------------------------------------------------------//
    #define CONFIG_reg                    0b00000000     //INTERRUPT , CRC, ON/OFF, TX MODE SETTING
    #define EN_AA_reg                     0x01           //AUTO ACK PIPE
    #define EN_RXADDR_reg                 0x02           //ABILITAZIONE INDIRIZZI RX
    #define SETUP_AW_reg                  0x03           //NUMERO DI INDIRIZZI (5)
    #define SETUP_RETR_reg                0x04           //SETTING TEMPO DI RITRASMISSIONE (250uS)
    #define RF_CH_reg                     0x05           //CANALE 5
    #define RF_SETUP_reg                  0b00000110     //{b5-b3 => (00 1Mbps),(01 2Mbps), (10 250Kbps)} {b2:b1 => (00 -18dBm), (01 -12dBm), (10 -6dBm), (11 0dBm)}
    #define STATUS_reg                    0x07           //REGISTRO DI STATO, INVIATO AL PIN MOSI
    #define OBSERVE_TX_reg                0x08           //CONTA I LOST PACKET E I RETRASMITTED PACKET
    #define RPD_reg                       0x09           //AVVERTE SE VI è UN TRASMETTITORE ATTIVO
    #define RX_ADDR_P0_reg                0x0A           //RICEVE L'INDIRIZZO 0
    #define RX_ADDR_P1_reg                0x0B           //
    #define RX_ADDR_P2_reg                0x0C           //
    #define RX_ADDR_P3_reg                0x0D           //
    #define RX_ADDR_P4_reg                0x0E           //
    #define RX_ADDR_P5_reg                0x0F           //
    #define TX_ADDR_reg                   0x10           //TRASMISSIONE INDIRIZZI
    #define RX_PW_P0_reg                  0x11           //NUMERO DI BYTE DEL PAYLOAD NEL DATA PIPE 0
    #define RX_PW_P1_reg                  0x12           //
    #define RX_PW_P2_reg                  0x13           //
    #define RX_PW_P3_reg                  0x14           //
    #define RX_PW_P4_reg                  0x15           //
    #define RX_PW_P5_reg                  0x16           //
    #define FIFO_STATUS_reg               0x17           //RIUTILIZZA TRASMISSIONE E STATO DELLA FIFO
    #define DYNPD_reg                     0x1C           //ENABLE DYNAMIC PAYLOAD LENGHT
    #define FEATURE_reg                   0x1D           //ABILITAZIONE MODALITà DYPLD, ACK, NO ACK
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char x = 0;                                 //CONTIENE IL BYTE ricevuto
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char nRF24L01_read()                        //questo sottoprogramma simula una comunicazione SPI
    {
      unsigned char s = 0;                               //variabile per esegguire 8 esecuzioni
      unsigned char msg = 0;
    
      for(s = 0; s < 8; s++){                            //esegue 8 volte
          msg <<= 1;                                     //shifto msg
          SCK_pin = 1;                                   //attivo il clock
          delay_us(8);                                   //aspetto 8us (f spi 62Kbps)
          if(MISO_pin != 0)                              //se in=0
          {
            msg |= 1;                                    //azzero il bit di msg
          }
          SCK_pin = 0;                                   //disattivo il clock
          delay_us(8);
      }
    
      return msg;                                       //ritorno il valore letto
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void nRF24L01_write(unsigned char d){                //sottoprogramma che simula una scrittura spi
      unsigned char s = 0;
    
      for(s = 0; s < 8; s++)                            //questo for serve a trasmettere sul pin mosi bit per bit il dato d
      {
        if((d & 0x80) != 0)
        {
          MOSI_pin = 1;                                 //se il bit scandito è 1 trasmetto 1
        }
        else
        {
          MOSI_pin = 0;                                 //altrimenti 0
        }
        d <<= 1;                                        //shifto d per inviare il prossimo bit
        SCK_pin = 1;                                    //creo un clock
        delay_us(8);
        SCK_pin = 0;
        delay_us(8);
      }
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void register_write(unsigned char reg, unsigned char value)                //sottoprogramma per scrivere i registri
    {
      SS_pin = 0;                                                              //indico che sto per inviare un comando
      nRF24L01_write((reg | W_REGISTER_cmd));                                  //maschero il registro con il comando per scrivere
      nRF24L01_write(value);                                                   //invio il valore che voglio scrivere nel registro
      SS_pin = 1;
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char register_read(unsigned char reg)                            //sottoprogramma lettura registri
    {
      unsigned char value = 0;
    
      SS_pin = 0;
      nRF24L01_write((reg | R_REGISTER_cmd));                                 //indico che voglio leggere e quale registro leggere
      value = nRF24L01_read();                                                //leggo il dato che il modulo mi manda
      SS_pin = 1;
      delay_us(8);
    
      return value;
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void write_command(unsigned char cmd){                                      //sottoprogramma scrittura comandi
      SS_pin = 0;                                                              //indico che voglio inviare un comando
      nRF24L01_write(cmd);                                                     //scrivo il comando cmd
      SS_pin = 1;                                                              //ripristino il pin ss
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void set_TX_RX_address(unsigned char *addr, unsigned char bytes, unsigned char reg)      //sottoprogramma per scrivere gli indirizzi
    {
      unsigned char n = 0;
    
      SS_pin = 0;
      nRF24L01_write((reg | W_REGISTER_cmd));                                               //indico che voglio scrivere i registri
      for(n = 0; n < bytes; n++)
      {
        nRF24L01_write(addr[n]);                                                            //bytes contiene il numero di indirizzi
      }                                                                                     //scrivo gli n indirizzi
      SS_pin = 1;
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void flush_TX_RX()                                      //sottoprogramma per cancellare le FIFO
    {
      register_write(STATUS_reg, 0x70);
      write_command(FLUSH_TX_cmd);
      write_command(FLUSH_RX_cmd);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void send_data(unsigned char bytes, unsigned char *value)        //sottoprogramma per inviare i dati
    {
      unsigned char s = 0;
    
      flush_TX_RX();                                                //cancello le FIFO
      register_write(CONFIG_reg, 0x3A);                             //setto la modalità tx da CONFIG_reg e attivo il modulo
    
      SS_pin = 0;
      nRF24L01_write(W_TX_PAYLOAD_cmd);                             //scrivo nel registo di trasmissione i bit da inviare
      for(s = 0; s < bytes; s++)
      {
        nRF24L01_write(value[s]);
      }
      SS_pin = 1;
      delay_us(8);
    
      CE_pin = 1;                                                 //faccio partire l'invio, aspetto 60us e poi disattivo il modulo
      delay_us(60);
      CE_pin = 0;
    
      register_write(CONFIG_reg, 0x38); //En modo RX se quita
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void receive_data(unsigned char bytes, unsigned char *value)         //sottoprogramma per la ricezione, indico il numero di bytes del dato
    {                                                                    //value contiene il dato letto
      unsigned char s = 0;
    
      SS_pin = 0;                                                        //scrivo il comando che indica che voglio leggere
      nRF24L01_write(R_RX_PAYLOAD_cmd);
      for (s = 0; s < bytes; s++)
      {
        value[s] = nRF24L01_read();                                      //leggo il dato che il modlo mi sta inviando
      }
      SS_pin = 1;
      delay_us(8);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void nrF24L01_init_TX()                                             //sottoprogramma per settare la modalità trasmissione
    {
      unsigned char address[5] = {0x99, 0x99, 0x99, 0x99, 0x99};        //indirizzo a 5bytes con valore a piacere(devo coincidere però con il rx)
    
      CE_pin = 0;
    
      register_write(SETUP_RETR_reg, 0x00);                             //ritrasmissione disabilitata
      register_write(SETUP_AW_reg, 0x03);                               //setto che ho indirizzo a 5bytes
      register_write(RF_SETUP_reg, 0x0E);                               //potenza 0dbm e velocità 250Kbps
      register_write(RF_CH_reg, 0x09);                                  //setto il canale di trasmissione, canale 9 in questo caso(il ricevitore deve avere uguale canale)
      register_write(EN_AA_reg, 0x00);                                  //auto ack disabilitato
      register_write(CONFIG_reg, 0x38);                                 //interrupt abilitati su TX_DS e MAX_RT, crc abilitato
      set_TX_RX_address(address, 5, TX_ADDR_reg);                       //inserisco gli indirizzi nell'apposito registro
      set_TX_RX_address(address, 5, RX_ADDR_P0_reg);
      flush_TX_RX();                                                    //cancella le fifo
    
      CE_pin = 1;
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void nrF24L01_init_RX()                                             //programma per settare la modalità RX
    {
      unsigned char address[5] = {0x99, 0x99, 0x99, 0x99, 0x99};        //indirizzo a 5bytes uguale a quello del TX
    
      CE_pin = 0;
    
      register_write(CONFIG_reg, 0x38);                                 //Crc abilitato, no interrup di ricezione
      register_write(SETUP_RETR_reg, 0x00);                             //ritrasmissione non richiesta
      register_write(SETUP_AW_reg, 0x03);                               //indirizzo a 5bytes
      register_write(RF_SETUP_reg, 0x0E);                               //potenza 0dbm e velocità 250Kbps
      register_write(RF_CH_reg, 0x09);                                  //canale9
      register_write(EN_AA_reg, 0x00);                                  //no ack
      register_write(RX_PW_P0_reg, 0x01);                               //dato a 1byte
      register_write(CONFIG_reg, 0x3B);                                 //setto il modulo come RX
      set_TX_RX_address(address, 5, TX_ADDR_reg);                       //scrivo gli indirizzi nell'apposito registro
      set_TX_RX_address(address, 5, RX_ADDR_P0_reg);
      flush_TX_RX();                                                    //cancello le fifo
    
      CE_pin = 1;
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char get_Status_Reg()                       //sottoprogramma per leggere lo status register che mi fornisce info sul modulo
    {
      return register_read(STATUS_reg);
    }
    
    //----------------------------------------------------------------------------------------------------------------------------//
    unsigned char val = 0;
    
    //----------------------------------------------------------------------------------------------------------------------------//
    void main(){                                 //programma principale
    
    TRISA     =  0x00;                         //configuro inizialmente tutte le porte uscite e le setto a 0
    TRISB     =  0x00;
    TRISC     =  0x00;
    PORTA = 0X00;
    PORTB = 0X00;
    PORTC = 0x00;
    
    //----------------------------------------------------------------------------------------------------------------------------//
                                     //configurazione I/O microprocessore per comunicare col modulo
    RF_CS_TRIS = 0;
    RF_CE_TRIS = 0;
    SCK_TRIS = 0;
    SDI_TRIS = 1;
    SDO_TRIS = 0;
    
    CE_pin = 0;
    SS_pin = 0;
    SCK_pin = 0;
    MOSI_pin = 0;
    
    LED = 1;
    delay_ms(100);            //faccio lampeggiare una volta il led
    LED = 0;
    
    //----------------------------------------------------------------------------------------------------------------------------//
     delay_ms(10);
    
     nrF24L01_init_RX();                //inizializzo il modulo come rx
    
     delay_ms(100);                     //delay assestamento
    
    //----------------------------------------------------------------------------------------------------------------------------//
     while(1){                          //ciclo infinito
      if(get_Status_Reg() == 0x40)      //controllo nello status register se il bit di segnalazione di dato ricevuto è alto
      {
        receive_data(1, &x);            //se si vado a leggere il dato
        PORTC = x;                       //e in questo caso lo visualizzo sulle portB
      }
     }
    

    Grazie,
    Elia

    #4335
    ne555
    Amministratore del forum

    Ciao Elia, hai controllato che canale, bit rate e altri parametri di trasmissione siano uguali tra i due moduli?

    #4336
    Led_ON
    Partecipante

    Ciao ne555!

    A dirti la verità non ho controllato.
    Tuttavia nelle funzioni INIT_TX e INIT_RX sembra faccia proprio quello che dici e pure correttamente.

    Diciamo che mi sono fidato ciecamente del codice, sperando che il lavoro sporco lo facesse lui…mea culpa.

    Ad oggi purtroppo non riesco a farli funzionare. Se hai qualche idea è ben accetta 🙂 .

    Grazie
    Led_ON

    #4339
    ne555
    Amministratore del forum

    Questo codice è sempre stato un pò rognoso, lo avevo realizzato per un progetto universitario a cui avevo preso trenta, quindi funzionava hahahahahaha forse durante l’esportazione sul sito o ho copiato una versione vecchia non funzionante oppure non so cosa sia successo. hai controllato che il codice nel file da scaricare e scritto sul sito sono uguali? questa è la prima prova da fare.

    Il codice non è mio al 100%, spero pomeriggio di fornirti la fonte del codice originale. il codice originale aveva qualche problema di ricezione, lo avevo modificato e fatto funzionare, però avevo create una 20ina di file intermedi non funzionanti o funzionanti in parte, credo pèer sbaglio di aver postato una di queste versioni 🙁

    pomeriggio darò un occhiata

    #4340
    Led_ON
    Partecipante

    Il codice nel file da scaricare ed il codice sul sito non sono uguali. Io però ho utilizzato il codice scaricato. Anche perchè sul sito hai riportato due esempi di codice, uno per il TX ed uno per l’RX, ma sono identici 😉 .
    Comunque nessun problema. Infine ho adattato il codice ai PIN del mio microcontrollore PIC18F25K22 lasciando tutto il resto invariato.

    Te ne sarei gratissimo se trovassi la fonte o, ancora meglio, visto che hai già usato questi modulini, se tu potessi dirmi il perché non funziona. Sto diventando pazzo.
    Se hai sempre i sorgenti funzionanti, me li puoi mandare?

    E’ un progetto a cui sto lavorando insieme ad altre persone e per adesso non va niente.

    Grazie dell’aiuto.
    Fai pure con calma.

    Led_ON

    #4356
    ne555
    Amministratore del forum

    Ciao,
    il sorgente l’ho preso da qui, prova a vedere se a te funziona, a me con i pic 18f252 non funzionava (https://libstock.mikroe.com/projects/view/1438/nordic-nrf24l01-tx-and-rx-generic-library).

    anche se i codici per tx ed rx sono uguali ognuno ha le le funzioni sia per ricevere che per trasmettere, cambiano solo per il contenuto del loop. il codice funzionante esiste, provo a cercare anche tra i vecchi file dell’esame se no le versioni precedenti a quella postata.

    Fammi sapere se il codice sorgente a te funziona

    #4371
    Led_ON
    Partecipante

    Ciao,

    entro fine settimana adatto lo schema elettrico e provo i sorgenti. Ti faccio sapere. Grazie

    Intanto, hai mica trovato il tuo vecchio codice dell’esame? 😉

    Led_ON

    #4373
    Led_ON
    Partecipante

    Ciao Ne555!

    Ho provato il codice, montato un circuito identico su breadbord, quarzo a 8Mhz, ma non funziona 🙁
    Sono disperato. Tra l’altro confrontando con il datasheet sembra che tutte le impostazioni siano corrette.

    Hai mica trovato il tuo codice funzionante?

    Elia

    #4374
    ne555
    Amministratore del forum

    Ciao Elia,
    nella cartella dell’esame ho trovato solo questa versione, spero sia quella funzionate.

    https://ne555.it/File/nRF24L01%20versione%204.rar

    fammi sapere, speriamo bene 🙂

    #4375
    Led_ON
    Partecipante

    Grazie mille Ne555!

    Senza ombra di dubbio ti faccio sapere se funziona. Domani mi arrivano i PIC18F458, così faccio proprio la prova uguale. Se va a buon fine, provo anche sui PIC18F25K22.

    Una domanda: Ma hai usato un quarzo da 20MHz ?

    P.S: Mi sono schiantato dal ridere quando ho aperto il progetto “my project” e come prova di scrittura sull’LCD c’era LCD_OUT(“SUCA”); ahahahhah

    Grazie,
    LED_on

    #4376
    Led_ON
    Partecipante

    Ultima domanda: Hai mica uno schema elettrico ?

    Per evitare di sbagliare. Altrimenti nessun problema, traduco i PIN dal firmware

    #4377
    ne555
    Amministratore del forum

    hahahahahha nn avevo controllato cosa c’era scritto sul display, c’era quella scritta perché ci ho lavorato fino alle 3 di notte prima di un esame per farlo funzionare hahahahhaha comunque elimina il display, mi dava problemi, come test usa un invio di char semplici.

    la frequenza del quarzo su breadboard non conviene mai farla andare oltre gli 8, a volte anche a 8MHZ da problemi.

    Se non sbaglio la connessione è la stessa di quella dello schema dell’articolo, ti conviene controllare però

    Se non dovesse funzionare nemmeno quello spero nella prossima settimana di provare il lo schema e il codice, ma purtroppo sono strapieno di lavoro 🙁

    #4384
    Led_ON
    Partecipante

    Allora grandi notizie!

    Sembra funzionare! In realtà non ho usato il tuo codice, ma proprio quello che avevo postato all’inizio. L’unica cosa che ho fatto è stata sostituire i due NRF24L01+ con due nuovi ed adesso va tutto!

    Secondo me li ho bruciati, perchè alimentavo il PIC a 5V ed i modulini a 3.3V. Però pensavo che fossero tolleranti ai 5V. Boh.

    Tuttavia non va ancora come dovrebbe: Ho implementato un programma dove il master conta da 0 a 255 aumentando di un’unità ogni 1secondo e manda il nuovo numero al ricevitore. Tuttavia il ricevitore non “segue bene” il conteggio.

    Ovvero, i numeri che manda il TX, il ricevitore li mostra, ma non tutti. Alle volte il TX avanza il conteggio anche di 3-4 unità e lui rimane indietro. Poi improvvisamente si “risveglia” e mostra l’ultimo numero ricevuto. Non so se mi sono spiegato…

    Ti mando i while(1) dei due programmi:

    TRASMETTITORE:

    
    x = 1;                                           //inizializzo x ad 1
    while(1){                                        //ciclo infinito
      send_data(1, &x);                              //invio 1byte e il byte è la variabile x
      PORTC = x;                                     //visualizzo il dato inviato sul trasmettitore
      delay_ms(1000);
      x++;
     }

    RICEVITORE:

     while(1){                          //ciclo infinito
      if(get_Status_Reg() == 0x40)      //controllo nello status register se il bit di segnalazione di dato ricevuto è alto
      {
        receive_data(1, &x);            //se si vado a leggere il dato
        PORTC = x;                       //e in questo caso lo visualizzo sulle portB
      }
Stai visualizzando 15 post - dal 1 a 15 (di 19 totali)
  • Devi essere connesso per rispondere a questo topic.