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.