Fixing Arduino Ethernet and RFM12 Communication
Unfortunately, Arduino’s Ethernet shield does not play very nice with other devices that want to use its select pins. After many searches, I came across jcw’s discussion board and Martin’s implementation doc.
Because the ethernet shield uses digital pin 10 select, RF12 select line needs to use digital pin 9. You also need to disable interrupts. As such, you need to modify both your w5100 and rf12 libraries.
Based on jcw and Martin’s posts.
Martin’s post
jcw post
Another great post explaining SPI
Step 1:
Change w5100.h
From:
#else
inline static void initSS() { DDRB |= _BV(2); };
inline static void setSS() { PORTB &= ~_BV(2); };
inline static void resetSS() { PORTB |= _BV(2); };
#endif
#else
inline static void initSS() { DDRB |= _BV(2); };
inline static void setSS() { cli(); PORTB &= ~_BV(2); };
inline static void resetSS() { PORTB |= _BV(2); sei(); };
#endif
Step 2:
Change RF12.cpp
From:
// ATmega168, ATmega328, etc.
#define RFM_IRQ 2
#define SS_DDR DDRB
#define SS_PORT PORTB
#define SS_BIT 2 // for PORTB: 2 = d.10, 1 = d.9, 0 = d.8
To:
// ATmega168, ATmega328, etc.
#define RFM_IRQ 2
#define SS_DDR DDRB
#define SS_PORT PORTB
#define SS_BIT 1 // for PORTB: 2 = d.10, 1 = d.9, 0 = d.8
//Changed from 2 = d.10 to a = d.9
Step 3:
You also need to change the order of your includes. You must include Ethernet.h before JeeLib.h
#include <Ethernet.h>
#include <JeeLib.h>
#include <avr/sleep.h>
#include <SPI.h>
You also need to change your initialization sequence. You must initialize rf12 before ethernet.
Serial.begin(57600);
rf12_initialize(26, RF12_433MHZ, 4);
Ethernet.begin(mac); //initialize ethernet
Serial.println("\n[TimedReceive]");
Serial.println("connecting...");
delay(1000); // give it time to boot
Example of timedRecv that works:
/// @dir timedRecv
/// Experiment with time-controlled periodic reception.
// 2011-06-24 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php
#include <Ethernet.h>
#include <JeeLib.h>
#include <avr/sleep.h>
#include <SPI.h>
struct {
byte start; // time at which we started listening for a packet
byte later; // how long we had to wait for packet to come in
} payload;
ISR(WDT_vect) { Sleepy::watchdogEvent(); }
byte mac[] = { 0x90,0xA2,0xDA,0x00,0x55,0x8D}; //Replace with your Ethernet shield MAC
EthernetClient client;
IPAddress server(192,168,1,101); //localhost
void setup () {
Serial.begin(57600);
rf12_initialize(26, RF12_433MHZ, 4);
Ethernet.begin(mac); //initialize ethernet
Serial.println("initialized mac");
Serial.println("\n[TimedReceive]");
Serial.println("connecting...");
delay(1000); // give it time to boot
}
void loop () {
if (rf12_recvDone() && rf12_crc == 0) {
// process incoming data here
Serial.println("rf12_recDone = true");
if (RF12_WANTS_ACK) {
Serial.println("rf12 wants ack");
payload.later = (byte) millis() - payload.start;
rf12_sendStart(RF12_ACK_REPLY, &payload, sizeof payload);
rf12_sendWait(1); // don't power down too soon
}
String data;
data+="";
data+="uid=";
data+="12345";
data+="&tid=";
data+="eeefffeee";
data+="&ql=";
data+="333444111";
if (client.connect(server,80)) {
Serial.println("connected");
client.println("POST /tupper/data.php HTTP/1.1");
client.println("Host: www.your-website.com");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(data.length());
client.println();
client.print(data);
client.println();
Serial.println(data);
//Prints your post request out for debugging
client.println("POST /tupper/data.php HTTP/1.1");
client.println("Host: www.your-website.com");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(data.length());
client.println();
client.print(data);
client.println();
}
delay(2000);
if (client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
}
// power down for 2 seconds (multiple of 16 ms)
rf12_sleep(RF12_SLEEP);
Sleepy::loseSomeTime(2000);
rf12_sleep(RF12_WAKEUP);
// just woke up, start listening for a packet again
payload.start = millis();
} else {
// switch into idle mode until the next interrupt
Serial.println("setting sleep mode");
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_mode();
}
}