NRF24L01 SPI to I2C(2)
1 min read

NRF24L01 SPI to I2C(2)

In last post, i have try to put NRF24L01 i2c module in run, and found that receiver will get duplicated datas.

To remove the duplicated datas, i have encode the data in a special way to detect the duplication. As i always send ascii text, 7 bits will be enough, and let 1 bit for mark bit. That is, each consecutive data will have different mark bit. If it has the same mark bit, it is a duplicated data.

And the i2c module can only send/receive one byte at a time, not convenient. So i write a wrapper code to send/receive a strings, it work much better now.

nRF24L.h

class nRF24L{
public:
        nRF24L();
        void begin();
        int send(const char* buf, int len, int timeout=0);
        int recv(char* buf, int len, int timeout = 0);

protected:
        char  _send_mark;
        char  _last_recv;
};

nRF24L.cpp

#include "nRF24L.h"
#include <Arduino.h>
#include <Wire.h>



nRF24L::nRF24L(){
        _send_mark = 0;
        _last_recv = 0x47;
}

void nRF24L::begin(){
        Wire.begin();
}

int nRF24L::send(const char* buf, int len, int timeout){

        unsigned long start_time = millis();

        for(int i = 0; i < len; i++){
                char v = (buf[i] & 0x7F) | (_send_mark << 7);
                _send_mark = (_send_mark + 1) & 0x01;

                while(1){
                        Wire.beginTransmission(35);
                        Wire.write(v);
                        if(Wire.endTransmission(v)){
                                if(millis() - start_time > timeout){
                                        return i;
                                }

                                delay(10);
                        }else{
                                break;
                        }

                }
        }

        return len;
}
int nRF24L::recv(char* buf, int len, int timeout){
        int i = 0;
        unsigned long start_time = millis();
        while(i < len && Wire.requestFrom(35, 1) && Wire.available()){
                char v = Wire.read();

                if(0x47 == v){
                      if(millis() - start_time > timeout){
                              break;
                      }
                      else{
                        delay(10);
                        continue;
                      }
                }

               if(_last_recv == v)
                       continue;

                _last_recv = v;
                buf[i++] =  v & 0x7F;
        }

        return i;
}

But the transfer speed is too low, not practical to transfer datas other than short control commands.