Interfacing an Arduino with a Microchip MRF89XA radio.
You'll need two MRF89XAM8A modules and two Arduino boards. The MRF89XAM8A is not 5V compatible, so you'll need a 3V3-Arduino board. Following the instructions on Adafruit shows you how to convert your Arduino Uno to one that has 3V3 IO-voltage. The explanation is for an older version of the Arduino Uno. If you have a Arduino Uno R3, you'll need to order another LDO.
You'll need the following connections between the Arduino Uno and the MRF89XAM8A:
MRF89XA | Arduino Uno |
1: GND | GND |
2: RESET | do not connect |
3: /CSCON | IO5 |
4: IRQ0 | IO4 |
5: SDI | ICSP pin 4 |
6: SCK | ICSP pin 3 |
7:SDO | ICSP pin 1 |
8: /CSDATA | IO3 |
9: IRQ1 | IO2 |
10: VIN | 5V (the voltage on this pin should be 3V3 after "3V3"-ing your Arduino Uno) |
11: GND | GND |
12: GND | GND |
Solder a 100nF capacitor directly on pin 10 and pin 11 of the MRF89XAM8A.
This firmware interfaces the MRF89XAM8A, which will communicate at 868MHz. That's in a European ISM-band. If you happen to live in the US, you'd better buy the MRF89XAM9A and program it to work in the 915MHz band.
The MRF89XA chip on this module is a very versatile chip, which makes it also quite complicated to set up correctly. The library only demonstrates a limited part of the functionality (e.g. there's no possibility yet to use different radio channels): FSK-modulation with a datarate of 20kbps.
In order to compile and run the application below, you'll have to download the library.
Make a folder RadioHead in the Arduino library folder and copy all the files from here into that.
The library is based on the RadioHead library, where the MRF89XA driver has been added and changes have been made to accommodate modules with two chip-selects. The RadioHead library is released under GPL V2.
Program one Arduino Uno with #define SERVER_MRF89XA
commented out. Program the other Arduino Uno with #define CLIENT_MRF89XA
commented out.
You'll now have a Client and a Server. Both will communicate to each other in a reliable way (i.e. acknowledgements will be sent to indicate that packets have been received correctly).
/*Demo application of MRF89XA driver Copyright (C) 2014 Christoph Tack This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ //#define SERVER_MRF89XA #define CLIENT_MRF89XA #include <RH_MRF89XA.h> #include <RHReliableDatagram.h> #define CLIENT_ADDRESS 1 #define SERVER_ADDRESS 2 // IRQ1 = MRF89XAM8A: pin 9 => Arduino Uno pin 2 // /CSDATA = MRF89XAM8A: pin 8 => Arduino Uno pin 3 // /CSCON = MRF89XAM8A: pin 3 => Arduino Uno pin 5 // IRQ0 = MRF89XAM8A: pin 4 => Arduino Uno pin 4 RH_MRF89XA driver(3, 5, 4, 2); // Class to manage message delivery and receipt, using the driver declared above #ifdef CLIENT_MRF89XA #ifdef SERVER_MRF89XA #error You have to choose: client OR server, not both #endif RHReliableDatagram manager(driver, CLIENT_ADDRESS); #elif defined(SERVER_MRF89XA) #ifdef CLIENT_MRF89XA #error You have to choose: client OR server, not both #endif RHReliableDatagram manager(driver, SERVER_ADDRESS); #endif uint8_t data[] = "Hello World!"; // Dont put this on the stack: uint8_t buf[RH_MRF89XA_MAX_MESSAGE_LEN]; void setup() { Serial.begin(9600); if (!manager.init()){ Serial.println("init failed"); return; } Serial.println("init ok"); } void loop() { #ifdef CLIENT_MRF89XA Serial.println("Sending to mrf89xa_reliable_datagram_server"); // Send a message to manager_server if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS)) { // Now wait for a reply from the server uint8_t len = sizeof(buf); uint8_t from; if (manager.recvfromAckTimeout(buf, &len, 2000, &from)) { Serial.print("got reply from : 0x"); Serial.print(from, HEX); Serial.print(": "); Serial.println((char*)buf); } else { Serial.println("No reply, is mrf89xa_reliable_datagram_server running?"); } } delay(500); #elif defined(SERVER_MRF89XA) if (manager.available()) { // Wait for a message addressed to us from the client uint8_t len = sizeof(buf); uint8_t from; if (manager.recvfromAck(buf, &len, &from)) { Serial.print("got request from : 0x"); Serial.print(from, HEX); Serial.print(": "); Serial.println((char*)buf); // Send a reply back to the originator client if (!manager.sendtoWait(data, sizeof(data), from)) Serial.println("sendtoWait failed"); }else{ Serial.println("not valid"); } } #endif }