OK IT IS Real because - Here is the obligatory Youtube video link as proof that the wireless Moteino servo project works -
http://youtu.be/-AFmAWcR1ccBelow is the code for a single servo. Just edit to double, triple or
the instances for the devices.
Thanks again Alex for the great inexpensive product, involved code examples, good information on the web site, and the access to imagination. I am now an old but, burgeoning new 'C' Programmer of wireless embedded systems.
Transmitter Code /* Wirelessly transmit Potentiometer signals via an RFM69HW enabled Moteino connection.
Referenced & using example code, logic, format from:
* https://github.com/LowPowerLab/RFM69/tree/master/Examples
Lowpowerlab.com RFM69 examples: Node & Struct_send by Felix Rusu
* http://www.instructables.com/id/Arduino-2-Servos-Thumbstick-joystick/step4/The-Code/
by Biomech75 2012
* http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
code by David A. Mellis 2005; modified by Paul Stoffregen 8 Feb 2010
* http://www.jeremyblum.com/2011/02/27/arduino-tutorial-9-wireless-communication/
code by Jeremy Blum
* http://forum.arduino.cc/index.php?PHPSESSID=jts7bh8gq4mos865mb4kbsi4l0&topic=151699.15
code examples within forum string by 'ashh'
* Credit for RFM12B code from Glyn Hudson openenergymonitor.org GNU GPL V3 12/4/12
* Credit to JCW from Jeelabs.org for RFM12 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
* http://forum.arduino.cc/index.php/topic,154463.0.html
This example code is in the public domain.
B.Stott 2013
*/
#include <RFM69.h>
#include <RFM69registers.h>
#include <SPI.h>
#include <SPIFlash.h>
#define NODEID 99
#define NETWORKID 100
#define GATEWAYID 1
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define LED 9
#define SERIAL_BAUD 9600
//#define ACK_TIME 30 // # of ms to wait for an ack ---- Not Currently Used.
// Ack will not be used. This is a streaming application. If a packet is lost the next servo position data
// will be accurate enough to update and move the servo.
SPIFlash flash(8, 0xEF30); //EF40 for 16mbit windbond chip
RFM69 radio; // initiate radio object
int potpin0 = 0; // analog pin used to connect the potentiometer
int val0 = 0; // variable initialized for storing potpin0 value
typedef struct
{
int Pot_0; //create transmit variable & store data potentiometer 0 data
} Payload;
Payload theData; // create transmission package 'theData'.
void setup()
{
Serial.begin(SERIAL_BAUD);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
radio.setHighPower(); //uncomment only for RFM69HW!
radio.encrypt(KEY);
char buff[50];
sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff); // Output to serial operating frequency of transceiver
if (flash.initialize())
Serial.println("SPI Flash Init OK!"); // Output to serial regarding status if Flash memory exists.
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
}
void loop()
{
// Output to serial some communications information - Data length, RSSI
for (byte i = 0; i < radio.DATALEN; i++)
Serial.print((char)radio.DATA[i]);
Serial.print(" [RX_RSSI:");Serial.print(radio.readRSSI());Serial.print("]");
Serial.println();
// translate Pot rotation to Servo position.
theData.Pot_0 = map(analogRead(potpin0), 0, 1023, 0, 179); // assign servo position to transmit packet variable.
// Transmit payload - theData
radio.send(GATEWAYID, (const void*)(&theData), sizeof(theData)); // transmit data to other end
// Output to serial information of # bytes sent.
Serial.print("Sending struct (");
Serial.print(sizeof(theData));
Serial.println(" bytes) ");
Serial.println();
Blink(LED,3);
// Board indicator of radio transmitting/receiving.
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
Receiver Code /* Wirelessly receive potentiometer signals to actuate a servo motor using an
RFM69HW enabled Moteino connection
Referenced & using example code, logic, format from:
* https://github.com/LowPowerLab/RFM69/tree/master/Examples
Lowpowerlab.com RFM69 examples: Node & Struct_send by Felix Rusu
* http://www.instructables.com/id/Arduino-2-Servos-Thumbstick-joystick/step4/The-Code/
by Biomech75 2012
* http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
code by David A. Mellis 2005; modified by Paul Stoffregen 8 Feb 2010
* http://www.jeremyblum.com/2011/02/27/arduino-tutorial-9-wireless-communication/
code by Jeremy Blum
* http://forum.arduino.cc/index.php?PHPSESSID=jts7bh8gq4mos865mb4kbsi4l0&topic=151699.15
code examples within forum string by 'ashh'
* Credit for RFM12B code from Glyn Hudson openenergymonitor.org GNU GPL V3 12/4/12
* Credit to JCW from Jeelabs.org for RFM12 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
* http://forum.arduino.cc/index.php/topic,154463.0.html
This example code is in the public domain.
B.Stott 2013
*/
#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>
#include <Servo.h>
#define NODEID 1
#define NETWORKID 100
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define LED 9
#define SERIAL_BAUD 9600
#define ACK_TIME 30 // # of ms to wait for an ack --- Not currently used.
// Ack will not be used. This is a streaming application. If a packet is lost the next servo position data
// will be accurate enough to update and move the servo.
RFM69 radio; // initiate radio object
SPIFlash flash(8, 0xEF30); //EF40 for 16mbit windbond chip
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
// Setup Servo Objects
Servo Servo0;
typedef struct
{
int Pot_0; //designate transmitted data for this potentiometer 0 value
} Payload;
Payload theData;
void setup()
{
// Attach Servo Objects to respective PWM pins
Servo0.attach(5);
// Radio initialization
Serial.begin(SERIAL_BAUD);
delay(100);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
radio.setHighPower(); //uncomment only for RFM69HW!
radio.encrypt(KEY);
radio.promiscuous(promiscuousMode);
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff); // Output operting frequency of transceiver
if (flash.initialize())
Serial.println("SPI Flash Init OK!"); // Print status of Flash memory
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
}
byte ackCount=0;
void loop()
{
//process any serial input
if (Serial.available() > 0) {
char input = Serial.read();
}
if (radio.receiveDone())
{
//Output to serial information of: NodeID & RSSI
Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
Serial.print(" [RX_RSSI:");Serial.print(radio.readRSSI());Serial.println("]");
if (promiscuousMode)
{
Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
}
if (radio.DATALEN != sizeof(Payload))
Serial.print("Invalid payload received, not matching Payload struct!");
else
{
theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
// Adjust RF data for Servo Output
theData.Pot_0 = constrain(theData.Pot_0, 0, 180);
// Print to Serial Terminal to verify RF data and Servo degree conversions.
Serial.print(" Data_Servo0 ");
Serial.println(theData.Pot_0);
Serial.println();
Servo0.write(theData.Pot_0); // Write position to servo0
}
}
Blink(LED,3); // Blink indicates transceiver operation.
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}