zakkemble / nrf905 Goto Github PK
View Code? Open in Web Editor NEWnRF905 AVR Library
Home Page: https://blog.zakkemble.net/nrf905-avrarduino-librarydriver/
License: GNU General Public License v3.0
nRF905 AVR Library
Home Page: https://blog.zakkemble.net/nrf905-avrarduino-librarydriver/
License: GNU General Public License v3.0
Hi Zak,
I have just sent you an email asking the same question, I do not know how often you check your email, so I am writing to you by this mean as well, just in case.
I would like to use the library with a "Pro Micro" (
https://www.sparkfun.com/products/12640 ) board. which files should I modify in order to get the library works?. Is it only necessary to modify the file "nRF905_config.h" (section Pin Stuff)?
Regards,
nRF905_setFrequency(NRF905_BAND_915, 915000000UL);
doesn't work in your ping_server/client examples on Arduino's... I put this before '_receive()' in setup.
I noticed in defaultConfig()
you set the default channel to 108 (433.2MHz), however, when I listen to /examples/ping_client/ping_client.ino with a logic analyzer, I see the channel being set as 216 over SPI.
I saw your note in /arduino/nRF905/nRF905.h about the high band being set as 0x02 as its bit shifted right by 1. I am not sure about this one... Right shifting the band so the math in your NRF905_CALC_CHANNEL macro is simpler?
// NOTE:
// When using NRF905_BAND_868 and NRF905_BAND_915 for calculating channel (NRF905_CALC_CHANNEL(f, b)) they should be value 0x01,
// but when using them for setting registers their value should be 0x02.
// They're defined as 0x02 here so when used for calculating channel they're right shifted by 1
I get it but...
eg.
#define NRF905_CALC_CHANNEL(f, b) ((((f) / (1 + (b>>1))) - 422400000UL) / 100000UL)
NRF905_CALC_CHANNEL(444000000, 0) == 216 :)
NRF905_CALC_CHANNEL(444000000, 1) == 216 o.O
NRF905_CALC_CHANNEL(888000000, 0) == 4656 >.<
NRF905_CALC_CHANNEL(888000000, 1) == 4656 >.<
NRF905_CALC_CHANNEL(888000000, 2) == 216 :)
The nRF905 datasheet suggests using formula:
Frequency in MHz = (422.4 + (CH_NO/10)) * (1+HFREQ_PLL)
(CH_NO/10 as the low band has 0.1MHz steps, high band 0.2MHz steps)
Which can be rewritten as:
Frequency in Hz = 422,400,000 + (channel * 100,000) * (1 + band)
Not sure why you are storing the high band as 0x02 then right shifting by 1, when you could just store the band bit (HFREQ_PLL) as 0x00 or 0x01.
If you change the macro to skip shifting the b(and)
#define NRF905_CALC_CHANNEL(f, b) ((((f) / (1 + b)) - 422400000UL) / 100000UL)
and change the nRF905_band_t
enum to use 0x01 for NRF905_BAND_868 and NRF905_BAND_915, doesn't that make more sense?
You should also & 0xff the channel in spi_transfer_nr(channel);
in defaultConfig()
to eliminate the MSB set in reg1.
In the nRF905 datasheet, Channel (CH_NO) is 9 bits, and the MSB is stored in the 2nd byte of the config register, along with Band (HFREQ_PLL).
Byte 0 = CH_NO[7:0]
Byte 1 = bit[7:6] not used, AUTO_RETRAN, RX_RED_PWR, PA_PWR[1:0], HFREQ_PLL, CH_NO[8]
If I set the channel to 364 (1 0110 1100), I would expect to see the least 8 bits (0110 1100) sent to Byte 0 and the most significant bit (1) sent to the Byte 1 as the least significant bit. When setting reg1 you are putting the MSB in there as I would expect ((channel>>8) & 0x01).
Unless I am totally wrong and CH_NO[8] in the datasheet refers to the LSB, not MSB!
Low band (HFREQ_PLL=0)
Channel 108 = 433.2MHz (422.4 + (108 * 0.1MHz))
Channel 216 = 444.0MHz (422.4 + (216 * 0.1MHz))
High band (HFREQ_PLL=1)
Channel 108 = 866.4MHz (844.8 + (108 * 0.2MHz))
Channel 216 = 888.0MHz (844.8 + (216 * 0.2MHz))
/arduino/nRF905/nRF905_config.h:
#define NRF905_FREQ 433200000UL
#define NRF905_BAND NRF905_BAND_433
/arduino/nRF905/nRF905_defs.h:
#define NRF905_CALC_CHANNEL(f, b) ((((f) / (1 + (b>>1))) - 422400000UL) / 100000UL)
/arduino/nRF905/nRF905.cpp:
uint16_t channel = NRF905_CALC_CHANNEL(NRF905_FREQ, NRF905_BAND);
/arduino/nRF905/nRF905.cpp:
spi_transfer_nr(NRF905_CMD_W_CONFIG);
spi_transfer_nr(channel);
spi_transfer_nr(reg1);
spi_transfer_nr((NRF905_ADDR_SIZE<<4) | NRF905_ADDR_SIZE);
spi_transfer_nr(NRF905_PAYLOAD_SIZE); // RX payload size
spi_transfer_nr(NRF905_PAYLOAD_SIZE); // TX payload size
for(uint8_t i=4;i--;)
spi_transfer_nr(0xE7); // Default receive address
spi_transfer_nr(reg2);
Is being captured as:
MOSI: 0 = NRF905_CMD_W_CONFIG
MOSI: 216 = channel
MOSI: 12 = reg1
MOSI: 68 = NRF905_ADDR_SIZE
MOSI: 32 = RX NRF905_PAYLOAD_SIZE
MOSI: 32 = TX NRF905_PAYLOAD_SIZE
MOSI: 231 = Default receive address (1/4)
MOSI: 231 = Default receive address (2/4)
MOSI: 231 = Default receive address (3/4)
MOSI: 231 = Default receive address (4/4)
MOSI: 32 = reg2
2x Saleae Logic captures attached:
ping_client.zip
You can open them with the free Saleae Logic app, if you don't already have it: https://www.saleae.com/downloads
I was trying to send a different button data with this library so as you see when I press button 4 then it sends 4 and the receiver receives 4 it's perfect.
now when I press button 12 it sends 12 and the receiver receives 12. Now the problem starts for no reason it stores the last digit of the received value.
after reading the data I had tried to put the module in standby and power-down mode and back to power on and RX mode but the issue is still there.
so when I press button 4 now then the transmitter is sending 4 as data but the receiver is saying that it's button 42.
See the attached image.
Can you please guide me to fix this problem.
Hi Zac,
I'd like to use your library on a non AVR Arduino, however this looks like its possibly going to be a bit challenging.
I'm actually trying to port to the STM32 running the Arduino IDE, but the port would equally apply to the Due and the Zero as all of these processors are ARM based.
The main issue I'm having is the interrupt definitions, as none of them exist for the Due etc.
Can you give me some general advice on the best way to approach this port ?
Thanks
Roger Clark
PS. My Arduino for STM32 is in github at https://github.com/rogerclarkmelbourne/Arduino_STM32
How can I compare the Received packet with a string. For example if I have compare "*CR#" with received packet and if true, do something.
Inside /arduino/nRF905/nRF905.cpp, line 75.
Can you please explain what these lines are used for?
#define STANDBY (enableStandbyMode())
#define CHIPSELECT(standby) standby; \
for(bool cs = cselect(); cs; cs = cdeselect())
Is the CHIPSELECT
macro an optimised way of wrapping a block of code with cselect()
+ cdeselect()
and optionally calling enableStandbyMode()
first?
eg.
CHIPSELECT(STANDBY)
{
spi_transfer_nr(NRF905_CMD_W_CONFIG | NRF905_REG_CHANNEL);
spi_transfer_nr(channel);
spi_transfer_nr(config.reg1);
}
I noticed the pattern is repeated in the NRF905_ATOMIC macro:
#define NRF905_ATOMIC() for(bool cs = interrupt_off(); cs; cs = interrupt_on())
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.