The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
433MHz / 2.4GHz communications with Netduino/Netduino Plus
I have been working with my Netduino & Netduino Plus for the last 18 months, built about half dozen projects with them. I have immensely benefited from the posts in this forum and the really generous community spirit of helping fellow hobbyists learn how to build things with the Netduino family of products.
On the side, I occasionally dabble with Arduino and its variants, including the Arduino Pro Mini. I recently acquired a bunch of 433MHz Tx/Rx modules as well as 2.4GHz nRF24L01+ modules for connecting remote units to a central Arduino-based internet-connected master unit. So far, I have been successful in getting a remote unit talk to the master and upload the data to COSM (Here is feed - https://cosm.com/feeds/106000, the setup can be seen in the attached photo).
I would like to use the Netduino Plus for receiving data with 433MHz / 2.4GHz and upload it to COSM or any other such service. I am struggling to find any resources on connecting the 433MHz / 2.4GHz modules with Netduino/Netduino Plus. I read about the slow clock speed in the Netduino/Netduino Plus being a problem with some sensor, however, I am not sure if this is an issue with the wireless module.
Has anyone tried to interface 433MHz / 2.4GHz modules with the Netduino/Netduino Plus? If yes, what is your experience and where did you start?
I understand XBee has been used by hobbyists with Netduino/Netduino Plus, however, I have been asked to keep the cost low for each remote unit and the master unit and would therefore prefer the 433MHz / 2.4GHz modules.
I had a lot of trouble until I realized that the CodePlex Netduino driver writes the Most Significant Byte first, when it should--or at least the Arduino library expects--the Least Significant Byte to be written first. A few quick hacks to reverse the byte order on things like the addresses and data being sent/received and everything seems to be working smoothly. So to anyone who wants to use these with the Arduino library, be sure to reverse the byte order.
Sure thing! Just as an example for where the library sets the address:
public void Configure(byte[] address, byte channel)
{
CheckIsInitialized();
AddressWidth.Check(address);
//Least significant byte first!
byte[] buffer = new byte[address.Length];
for (int i = 0; i < address.Length; i++)
buffer[i] = address[address.Length - (i + 1)];
buffer.CopyTo(address, 0);
....
}
That's just a snippet from the library, and it's not the most efficient solution, just a quick and dirty one. You'll need to use the buffer and for loop every place the code uses an address or sends data.
I've attached a version of the file from the library I modified to do that, as well as modifying it to be able to send data from an interrupt.
I've attached the code for both the Arduino and Netduino I used to communicate. The Arduino code has two buttons that send a 1 or a 2 respectively, and the Netduino will print the number that is received. This was originally for a doorbell project, so they're labeled button and bell.
Two things to point out: I've installed the doorbell so I can't test this code again right now. More importantly, I couldn't get this to work with a Netduino Plus 1, I could only get a Netduino 2 or Netduino Plus 2 to work (I didn't try a Netduino 1). For whatever reason, the Netduino Plus 1 wouldn't communicate, it wouldn't even acknowledge receiving any signal. As I needed to get this project finished under a bit of a time crunch, I didn't investigate it very much.
Basically, it has to be under 1 milliwatt and periodic use or something like that. Also the device has to have an FCC Part 15 sticker on it. If it doesn't then it didn't pass FCC inspection. Anything above you need to have a ham license. Just to note, it is easy to get a technician level ham license. It's a $15 test. Find a local club that does classes.
433 is getting more popular. 433 is used in r/c aircraft for long distance control and telemetry. With the recent popularity in multirotors you are seeing more and more people get 433 equipment without realizing that they may need a license for it.
433 is also an ISM band in Europe and Africa - so definitely stay away from that if you are in that region.
Im looking at this RF module to communicate data between 2 netduinos wirelessly. Has anyone done that and if so do you have any example code for the Transmitter / Receiver (1 ND+2 transmits data to a second ND+2 receiving).
I actually used an Arduino for the bell part, but it shouldn't be too hard to use the modified driver I posted above to transmit with the Netduino. Below is an example for how this could be done, but note that I haven't actually tested this code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using Gralin.NETMF.Nordic;
namespace Transmitter
{
public class Program
{
private static NRF24L01Plus _module = new NRF24L01Plus();
private static byte[] _transmitterAddress = new byte[] { 0xF5, 0xF0, 0xF0, 0xF0, 0xF2 };
private static byte[] _receiverAddress = new byte[] { 0xF5, 0xF0, 0xF0, 0xF0, 0xF4 };
private static InterruptPort _button = new InterruptPort(Pins.GPIO_PIN_D0, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);
public static void Main()
{
_module.Initialize(SPI_Devices.SPI1, Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D8);
_module.Configure(_transmitterAddress, 76);
_module.Execute(Commands.W_REGISTER, Registers.RF_SETUP, new byte[] { (byte)(1 << Bits.RF_DR_LOW | 3 << Bits.RF_PWR) });
_module.Enable();
_button.OnInterrupt += _button_OnInterrupt;
Debug.Print("Ready");
Thread.Sleep(Timeout.Infinite);
}
private static void _button_OnInterrupt(uint data1, uint data2, DateTime time)
{
Debug.Print("Sending...");
byte[] data = new byte[] { 0xF, 0x05 };
_module.SendTo(_receiverAddress, data);
}
}
}
Note that I've configured this radio to use the highest transmitting power and slowest data-rate to maximize range, but you may want to change this.
Im new to this radio, can you also show me how to configure the radios for different powers / transfer rates? In my application I want to send only very short range (less than 20 feet) but at high data rate. Im guessing its in the _module.execute line?
You're right about the execute line: it's executing a register write command on the RF_SETUP register using some predefined values from the Bits enum. I should point out that even the slowest data-rate is 250Kbps. Reading the data sheet is, as always, super useful, but if you want to use the default settings (data-rate 1Mbps) you can just omit that line.
Thanks again ill give it a try. I was wading through the driver on above when I found your project which seemed much simpler to implement without all the roles classes. We are looking at a number of different radios that are small for our work and came across this forum! awesome!
I got it all working but im unable to get every message from the transmitter. It seems to only receive every other message (I have a counter byte in the message). I found this to be true with the library on codeplex also using the "simplesendreceivetest" provided. My message is very small (1 byte!) and I am trying to send one every 20 ms. Any ideas where to start looking?
I dumped my register setup as follows:
Radio Config and Status Summary ============================== RF_CH: 76
Radio SETUP_AW Information ============================== ADDRESS WIDTH (bytes): 5
Radio SETUP_RETR Information ============================== AUTO RETRANSMIT COUNT: 15 AUTO RETRANSMIT DELAY (uSec): 4000
Radio CONFIG Information ============================== Mask interrupt caused by RX_DR (MASK_RX_DR): True Mask interrupt caused by TX_DS (MASK_TX_DS): True Mask interrupt caused by MAX_RT (MASK_MAX_RT): True Enable CRC if Auto ACK is on (EN_CRC): False CRC encoding scheme (CRCO): 2 Bytes In Power Up Mode (PWR_UP): True Current Mode (PRIM_RX): RX CE PIN State (True = Rx Mode, False = Tx Mode): True
Radio EN_AA (E-Shockburst) Information ============================== Enable auto acknowledgement data pipe 5 (ENAA_P5): False Enable auto acknowledgement data pipe 4 (ENAA_P4): False Enable auto acknowledgement data pipe 3 (ENAA_P3): False Enable auto acknowledgement data pipe 2 (ENAA_P2): False Enable auto acknowledgement data pipe 1 (ENAA_P1): False Enable auto acknowledgement data pipe 0 (ENAA_P0): False
Radio EN_RXADDR (Enabled RX Addresses) Information ============================== Enable data pipe 5 (ERX_P5): False Enable data pipe 4 (ERX_P4): False Enable data pipe 3 (ERX_P3): False Enable data pipe 2 (ERX_P2): False Enable data pipe 1 (ERX_P1): True Enable data pipe 0 (ERX_P0): True
Radio RF_SETUP Information ============================== CONT_WAVE: False PLL_LOCK (TEST ONLY): False RF_DR_LOW (250 kbps): True RF_PWR: -18 dBm
Radio STATUS Information ============================== RX_DR (Data Ready in Rx FIFO): False TX_DS (Data Sent in Tx FIFO): False
Thanks again for all the help! I even slowed the transmitting down to 1/second with same result and the two units are close to each other (basically on my desk about 3 feet apart).
I guess one other question if im able to get this pair to work. I ultimately want to broadcast a message from a transmitter to multiple receivers. Does this unit support a broadcast address (I didn't see it in the data sheet) or is it as simple as setting all the receiver to the same address.?
First, I don't think he radio supports a broadcast address, but I could be wrong, you'd have to check the data-sheet.
As for your other issues, it's hard to say offhand what the problem is. I know that the CodePlex driver is interrupt driven, and I've often had problems with interrupts getting backed up in a queue or lost, especially if there are several sources of interrupts. If you can, you might want to try modifying the driver to poll the radio at an interval fast enough to receive your messages. If a message is sent to the radio, but there's already a message in the receive buffer, you'd probably lose one of those messages, which might happen if an interrupt isn't firing properly.
As a workaround, if it's reliably missing every other message, you could send a clearing message, a 0x00 or something, after each of your real messages. It's not an elegant solution, but hey, if it works, good enough.