433MHz Arduino Transmitter and Receiver – Communicating Wirelessly
Another day, another project.
Again this is slightly to do with the CNC but it’s mainly about me learning about Arduino and getting things to work nicely. I ordered some 433MHz transmitter and receiver modules from China for a few pennies a few months ago. I lost hope of these arriving in all honesty and because they only cost pennies I wasnt worried about chasing these up. They arrived! I was surprised to open an envelope and there be the transmitter and receiver and they couldn’t have come at a better time.
I may have mentioned in a previous post at some point about making the buzzer for the CNC job completion wireless, I can’t remember! But anyway – this is what I plan to do with this. I have 2 or 3 or maybe about 11 Arduino Pro Mini’s (I found them on ebay for 70ish pence each!) lying around in my stuff box so I thought I’d put these to use – one as the transmitter and one as the receiver.
My first step was to get these working with some basic code – I read up on the internet (thanks google.) about the modules – literally just googled the letters printed onto the transmitter module – FS1000A. This yielded some good results which lead me onto this library for Arduino – VirtualWire.h – spot on for what I want to do. Let’s get started.
Before we begin – know the difference between the transmitter module and the receiver module.
The transmitter is not the one you think of:
And the receiver.
I HIGHLY RECOMMEND SOLDERING AN ANTENNA ONTO THE TRANSMITTER AND RECEIVER!! This will increase the range from a few centimeters to at least meters! It will also sort out any intermitance issues you are having. I have worked out that around a 17.5cm antenna made of single core wire will work pretty fine – I used the antenna length on my old RC equipment and have measured some pretty hardcore distance flights! I have marked the antenna solder pads on both the transmitter and receiver photos above.
Onto the software now – I opened up the Arduino IDE and started bashing on the keyboard. Not really I opened the IDE then looked at the examples that come with the VirtualWire Library. I learnt a lot from this and also this web page – http://www.airspayce.com/mikem/arduino/VirtualWire/ – this explained a lot. The project is no longer under virtual wire anymore, It’s now changed to “RadioHead” but as I only need basic information I stuck with the Virtual Wire library.
I then got to writing a test. I have settled on the buzzer I’m using – It’s very loud – and I’ve settled on a few other bits as well. I have a small pager vibration motor that I’m going to use and a lot (100ish) WS2812B LED’s, otherwise known as the NeoPixel LED’s, these are great. (I got sent them for free from a client to help develop the software for a big LED panel that was going into a nightclub.) These are pretty good and bright RGB LED’s so I’m going to use these to flash a pretty pattern on the completion of the job as well as the buzzer and the vibration motor, these can also show colours as to the status of the job – so if the machine has an error they can all be red and if it’s idling it can be blue and yellow if the machines queuing etc.
I’ve put together a test code available here: http://oliverwhysall.co.uk/wp-content/uploads/files/433MHz_TX_RX_OW.zip – I’ll explain the demo below. VirtualWire Library available here: http://oliverwhysall.co.uk/wp-content/uploads/files/VirtualWire.rar
I start this by including the virtual wire library. I then go to create the character controller – this is what I’ll be sending to the receiver. Open up the setup class. I’ve set the pin 13 LED on the board as an output just for debugging just to show the loop is working. vw_set_ptt_inverted(true) – this configures the “push to talk” polarity. It’s just something that needs setting. Next is the vw_set_tx_pin(12) – this sets pin 12 on the Arduino as the data pin – this is what the data pin on the transmitter module should be connected to. vw_setup(4000) – just setting the speed for the transmission – it’s basically like setting the baud for serial connections. For long distance transmissions use low numbers – like around 1200 – I’ve set this to 4000 just because it’s on my desk at work currently and not that far apart. I also setup the Serial.begin to 9600 just for debugging purposes.
The loop is pretty simple. I print the 1 to the serial – I then set the controller character to 1 – I then send this 1 to the receiver using the vw_send command. This command basically works like this – vw_send(message, length); – “message” is an array of the bytes to send, and “length” is the number of bytes stored in the array. This function returns immediately and the message is sent slowly by an interrupt-based background process. I then use the vw_wait_tx() command which does what it says basically – waits till the message is transmitted. I then turn the pin 13 LED on and set a delay. This is then repeated but changing the controller character. I send 0 with the LED turned off and 2 with it on 0 with it off, 3 with it on and then a last 0 with it off, I set Serial.println with REPEAT just for debugging then it loops over and over and over again!
That’s all that’s involved in the transmitter code – pretty simple but it is only a test. I’ve set the delay to 100, I’m sure it can go a lot faster but it’s distracting enough as it is – it looks like desk disco.
The receiver is slightly more complex, but not a lot. I start off with the three includes – Virtual Wire for the radio, Adafruit_NeoPixel for the LED and the WS2812_Definitions.h which includes a library of colours for the LED. I then go to define the LED data pin to be pin 2 and the total LED count to 1 because I only have 1 LED at the moment – the final version of my box will have multiple LED’s for brightness and pretty patterns on completion.
I then creat the NeoPixel instance entitled “leds”, the rest of this is just standard for the WS2812B’s, just go with it. The setup is similar to before – set the push to talk, set the RX pin on the Arduino for data then setup the speed to match the TX. I then set pin 13 LED for debugging and pin 2 as an output for the NeoPixel, you don’t have to but I do for sanity. I then use the vw_rx_start which starts the receiving process. I then blast through a few colours on the LED to make sure its working and to show the board is booted then leave it on white so I know if it doesn’t connect to the transmitter and receive anything. I start the serial at 9600 just for debugging.
The loop then beings – I start with this bit of code:
uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN;
This is another bit you just have to take my word for as it takes a lot of explaining! Then the actual handling of the received messages. I do a quick if opening – using the vw_get_message command I check there is something coming in. I then print this to the serial for debugging. I then run a series of if’s dependant on the character received. This is so I can set the LED different colours and do different things – so I send a 1 and it turns the LED green, I send a 0 and it turns the LED off, I send a 2 and it turns the LED red and the same with 3 turning it blue. I then just close everything up and close the loop.
I have a clearLEDs function at the bottom, this just sets all the LED’s in a string to off even if there is more than 1 LED it turns them all off.
And that’s all the code for the test. I then set the hardware up:
And that’s all that’s too it! I’m going to make some nice videos of this working this evening when I’ve soldered my antennas on properly and neaten’d the wiring up a tad – it currently looks like this:
UPDATE: I’ve made the units seperate and tidied them up a bit now :) I’ve just started moving the code into the serial spy firmware to use that as the transmitter. Antennas are connected and its working brilliantly! Pictures attached below: