[Texane] picked up a 2.4 GHz transmitter/receiver pair for transmitting sensor data wirelessly. After using them in a project he wanted to try pushing them a bit to see what the limits are when it comes to higher bandwidths. He ended up building a wireless speaker that transmits audio at about 90 KB/s. That link leads to a subfolder of his git repository. The code for this project is in the RX and TX folders, with images and video in the DOC folder.
The radio hardware that he’s using is a Nordic nRF24L01P chip which is available on a breakout board from Sparkfun. [Texane] mentioned to us that the chip includes error checking, packet ACK, and automatic retransmission. But these add overhead that can slow things down. The chip does offer the option to disable these features to get lower level access to the hardware. That’s exactly what he did and he mentions that the example code he wrote for the transmitter and receiver make every cycle count. This makes us wonder if it’s the speed of the ATmega328 chip that is the bottleneck, or the transceivers themselves?
Check this:
http://www.elektroda.pl/rtvforum/topic1709962.html
it’s 320kbps mp3 encoded stereo.
Transmitter is made from tiny Logitech Unifying receiver.
Those nRF24L01 modules can be had for less than $5 on ebay :/
Someone on some sparkfun forum says the radios can put up to 1.75Mbps throughput, which is a lot higher. ( https://forum.sparkfun.com/viewtopic.php?f=13&t=8136 )
He’s using an arduino and probably bit banging the SPI which is slow… my bet is on the arduino or bad programming.
But… i fail tu understand the context of the build. Audio quality has to be terrible… so… why?
Because he could? Isn’t this what hacking is about?
Of course…. but i want to know what he is using it for since quality will probably be quite bad.
Of course many things are built because people can, but that doesn’t mean that they don’t need to be used and provide some quality.
its called playing with circuits.
if you do not like it when people make things that suck andor are of poor quality,
then go to another website.
the intent of posting them is NOT to show you how to make something that sucks.
its because some people actually “LIKE” reading about how something was done differently.
this website is SPECIFICALLY intended for inferior andor unfinished andor poor quality andor NO INTENDED use circuitry.
this website is(should be) about HOW to make/modify the circuits, NOT why or what or how perfect
if this makes you angry, then maybe i can suggest a link to help you out.
ebay walmart zellers costco sony dell ibm
we will not stop because you tell us our projects are not up to YOUr standards.
PS: im wasting my time retrofitting retro electronics from outdated, crappy stuff into the shells of different retro stuff, be jealous, very jealous! HAHAHAHAHAH &(*$&^#*&^
PPS: i guarentee someone will enjoy reading about how i wired it all up
You misunderstood what i said. I said i don’t understand the context of the build, as in i there’s NO ARTICLE from the builder that says anything about the project, why he build it(educational, recreational, to talk to his neighbor for free etc) and what he is hoping to achieve (as in why is the throughput too low).
I did not say that he shouldn’t have built it. Sorry, you misunderstood, I do support such builds and do this myself. Your reply, not for me.
Second, the HAD article asks where the problem is. A while ago i built an intercom based on the RFM12 which is much slower, but i could achieve 64kbps for audio payload. So, i instantly understood the problem is not with the module but somewhere in the micro.
Hacking is about producing bad-quality junk? (With all due respect to the original hacker, I do think it’s important to encourage people to use their skills for productive ends. That said, this is obviously a great starting point if nothing else)
Hi,
To answer hackaday people, the bottleneck is the ATMEGA328P ADC on the
TX side. It can barely achieve more than 10KS/s without precision loss. This due
to the 125khz ADC clocking (if I remember well), which is the spec limit (actually,
the spec limit is a 250khz clock, but the best prescaler setting lead to 125khz at
16mhz) . BUT I pushed the ADC clock to 1MHZ, leading to a loss of precision (ie.
refer to the ATMEGA328P specs for more info). I sampled faster and higher
resolution ADCs from TEXAS INSTRUMENT recently.
Another thing is that it is difficult to meet realtime deadlines @40khz, leading
to the somewhat interleaved code.
@bodgan: Please, take a look at the code before posting, this is what opensource
is for. The only bad programming practices are stuffs like aggressive function inlining,
global variables and inclusion of C files. The reason was to optimize link resolution. I
actually use both hard and soft SPI to avoid having to lock the module if it is already
use, leading to better performance (without these trick, I cannot meet 40khz realtime
deadline).
I did not yet have a look at the SPARKFUN code you mention, but I will … but one
have to keep in mind that bandwidth is not the most important thing when doing
realtime. For instance, I had to switch to a 16 byte NRF packet payload size to
meet 40khz deadlines, leading to a reduced bandwidth (ie. more packet overhead).
@texane. There is a common problem with people using the arduino with software SPI, USART etc leading to slow code. I’m sorry for not going through the code, but i would prefer to see a project description and goals and then go through code. Otherwise i’m looking at a bunch of code which would take hours to understand without having a start point, so I avoid it(like many others). I don’t know what you want to do..
You see, there’s no understanding where your signal comes from, what your goals are etc (see, previously i just said i don’t understand what you want with this project).
Obviously the ADC can give you 15Ksps at 10 bit which is a higher throughput. The article on HAD questions whether the bottleneck might be the micro or the radio. According to the sparkfun formum post the chip can go much higher. So i naturally presumed that the problem might be the soft spi (you have no idea how common this is throughout arduino users). I also assumed that you have some sort of digital signal available and not rely on the ADC.
Maybe if you could provide a description of your project that would help a lot..
@bogdan:
In the SPARKFUN post you mentionned, no one said they actually
got a useful bandwidth of 1.75mbps. They just derived it from the NRF
specs, taking the ideal 2mpbs and removing the overhead. In practice,
you obviously have to consider times related writing fifos and control
registers for each transfer. This is dependant of the MCU used, and
the SPI clock too. Taking all this into account, I got 90kB/s (720kb/s)
on at ATMEGA328 @16mhz with full speed SPI clock (ie. 8mhz).
I implemented a simple client server to measure this, the code being
available in the repo. My point is that it is normal to be far from 2mbps,
not a sign of a bad coding practice at all.
Concerning the SOFTSPI I do not use it for the NRF module, only for
the DAC.
Concerning the setup, it consists of a ARDUINO/NRF based transmitted
taking the signal from the soundcard of my laptop, transmitting it digitized
over the air. The receiver side is the same hardware + a DAC to a 4ohm
speaker.
This is quite a coincidence–I happen to be working with these modules at the moment for an application which requires an exceptionally reliable one-way link. It’s not high bandwidth, but working with this IC, it’s pretty obvious where there’s a bunch of somewhat silly-sounding bottlenecks to achieving full 2Mbps throughput. For one, reading data out of the FIFO actually requires you to /turn off/ the receiver, read the data out of the FIFO, clear flags, and then turn on the receiver again, which takes 130 microseconds to reliably turn on once again. This significantly limits your packet rate. If you use the longest 32-byte packet length with minimum overhead, you get 256/296 effective bits (86% of 2Mbps right there). The time it takes to transmit this is 148 microseconds at 2Mbps, but if you turn off the receiver you lose 130 microseconds of data reception reducing it to 40% of 2Mbps.
If you don’t turn on the receiver, this chip seems to do this weird thing where reading data off of the FIFO does not actually clear the packet you just read, so you have to manually flush the FIFO. The problem with this is that unless you have done enough testing and are absolutely certain that you can perform the read faster than the next packet can be processed, you risk a race condition where you can flush a new packet that just came in or not flush fast enough if you’re waiting for the FIFO to be full and lose packets. I think this project does the latter to achieve the excellent data rates it already gets, but I think it is much less sensitive to a few dropped packets so doing this is perfectly fine.
The other problem you run into if you’re going for high reliability is that your required bandwidth may actually go down when you increase the overhead (or more descriptively, decrease the total packet length). Additionally, you most likely need to retransmit the packet to achieve the reliability you want. My current testing in some pretty WiFi-polluted environments is showing some fairly high BER (bit-error-rate). Now the .1% BER threshold may sound pretty good in the data sheet, but at a packet length of 296 bits that turns into ~25% packet error rate (PER) (99.9% probability of each bit being successful ^ 296). Transmitting the same packet a few times fixes all this and gives you excellent reliability: 3 times, and it drops to 1.6% error rate (25% ^ 3), five times, and it’s down to negligible at .1% PER. My gut isn’t telling me much useful about whether or not there’s an obvious bit length here to minimize PER, but when I get around to working it out, I’ll probably post it somewhere.
I’m actually very curious what effective BERs and PERs people who’ve worked on this chip have been getting. Admittedly I need to do a little more searching of the spectrum, but I’m measuring some fairly atroicous PERs with what I’m doing (easily 10% is being lost, and I’m running at 250kbps). I have this suspicion that the cheap chinese modules I’m using probably have not selected their loading capacitors properly (or maybe it’s the flux contamination) and that there’s significant frequency error between the modules accounting for most of this problem. Or perhaps it’s the matching network on the antenna input. Anyone else have results to share?
The bottleneck is the serial connection to the arduino. Even w/ usb you can only do 115kbps
This nRF module from sparkfun is very expensive.
I always buy the cheap modules from chinese sellers on eBay/Ali for $15,99 for 10 (!) modules. You don’t need a chip antenna. PIFA antenna is good enough.
true….
you can also find RFM73 or 70 for cheaper. TME at least has them quite cheap. I believe they are similar in specs to the NRF. (do they contain the same chip?)
RFM7X have other chips (I think it is the Beken BK2421). They are very similar to the nRF24L01 but they need a little bit more initialization code, because you have to write almost all registers after reset and the RM7X has two register banks.
The nRF24L01 only has one Bank and need much less initialization code since the registers have the right values after reset.
Yes, these chips are capable of over 2 Mbps at quite decent range {kilometers} when used as the common breakout board with built in amplifiers for Tx/Rx and a decent high gain antennae. I am not going to link to one of these boards, because I am not trying to provide advertisement, but Google can quickly show you the way.
Considering their low cost and quite high performance, I’m quite surprised that these chips are not finding much more use in the hacker/maker community. They are run with a very simple SPI connection.
These chips show a functionality at the ‘hardware’ level that is somewhat reminiscent of TCP communications over the net, as far as the automatic buffering, automatic retransmission for dropped packets, multiple channel communication, etc.
rfm73 and nrf24l01+ are 99% compatible. skip magic bank init in nRF, and you can transmit between them.
Sweet, I have the same loudspeakers!
Isn’t there an nRF24 variant made specifically for streaming audio?
Yes there is: nRF24Z1
C’mon Hackaday…Quit using “bandwidth” when it should be “throughput”.