Wireless Speaker Made Using Arduinos And 2.4 GHz Tranceivers

[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?

22 thoughts on “Wireless Speaker Made Using Arduinos And 2.4 GHz Tranceivers

      1. 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.

        1. 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

          1. 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.

      2. 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)

    1. 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).

      1. @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..

        1. @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.

      2. 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?

      1. 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.

        1. 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.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.