I have successfully managed to get my Arduino Ethernet board based on WizNet5100 chip to work with the Sensing Shield‘s RFM12B. The Arduino Ethenet (don’t mix it with an Arduino Ethernet shield, this one is a complete Arduino+Ethertnet on one board) has addressed the nasty WizNet 5100 bug that prevents other SPI devices to be connected by having a 74LVC1G14DBV single schmitt-trigger inverter logic gate to control SEN with respect to /SCS, check out the schematic.
So, to get the Sensing Shield to work with Arduino Ethernet, I needed to do the following modifications. I edited the Arduino Ethernet library file W5100.h so that it doesn’t allow RFM12b to interrupt while the SPI bus is busy handling Wiznet5100. I added a cli(); and sei(); as follows:
#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
Suggestion was made by JCW in this thread.
Another change that is necessary is in the RFM12B library, I edited RF12.cpp around line 72 to get the CS to pin 5; Pin 10 is taken by the WizNet 5100. I have a solder jumper on the Sensing Shield that allows selecting either digital pin 10 or pin 5. My changes are as follows:
// ATmega168, ATmega328, etc. #define RFM_IRQ 2 #define SS_DDR DDRD // was originally DDRB #define SS_PORT PORTD // was originally PORTB #define SS_BIT 5 // was originally for PORTB: 2 = d.10, 1 = d.9, 0 = d.8
So with these changes in place I compiled the ping-pong firmware plus a simple http page so that both WizNet 5100 and RFM12B are active. I have a JeeNode v6 on the other side ot the ping-pong table. I ran the sketch for 6+hours successfully and conclude that all is fine. Quite happy with the results 🙂 🙂
#include "SPI.h" #include "Ethernet.h" #include "WebServer.h" #include "JeeLib.h" MilliTimer sendTimer; char payload[] = "Hello from Arduino Ethernet!"; byte needToSend; static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; static uint8_t ip[] = { 192, 168, 2, 2 }; #define PREFIX "" WebServer webserver(PREFIX, 80); void helloCmd(WebServer &server, WebServer::ConnectionType type, char *, bool) { server.httpSuccess(); if (type != WebServer::HEAD) { P(helloMsg) = "Hello, World!
"; server.printP(helloMsg); } } void setup() { rf12_initialize(5, RF12_868MHZ, 33); Serial.begin(9600); delay(1500); Serial.println("Starting.."); Ethernet.begin(mac, ip); webserver.setDefaultCommand(&helloCmd); webserver.addCommand("index.html", &helloCmd); webserver.begin(); } void loop() { char buff[64]; int len = 64; if (rf12_recvDone() && rf12_crc == 0) { Serial.print("OK "); for (byte i = 0; i < rf12_len; ++i) Serial.write(rf12_data[i]); Serial.println(); } if (sendTimer.poll(3000)) needToSend = 1; if (needToSend && rf12_canSend()) { needToSend = 0; rf12_sendStart(0, payload, sizeof payload); Serial.println("Sent..."); } webserver.processConnection(buff, &len); }
Hi,
good job you did ! I would like to know if it’s possible to do the same for a mega2560 + Ethernet Shield with SD ? Would you please help me to configure the files ?
Cheers
Vince
I used “Arduino Ethernet”, this is an Arduino with in-built ethernet for this project, not an Arduino Ethernet shield. The Arduino Ethernet Shield has a nasty bug that prevents other SPI devices from working correctly, this bug is addressed in the “Arduino Ethernet”. The bug can be fixed with hardware modifications of the Arduino Ethernet Shield with SD, see the links I provided, but this is no easy task. Alternatively you can use the Freetronics Ethercard that uses inverted PB2 CS pin (Arduino digital pin 10) to drive the W5100 SEN pin, thus allowing other devices to access the SPI BUS when SEN is low
Thank you Martin. I’ll check the hack, John suggests. But it seems not to be an easy task, you’re right ! The simplest is probably to use the freetronics shield.
Cheers.
Vince
Hey,
I want to do the same (Arduino+ethernet w5100 +RFM12B) but with an official arduino ethernet shield instead of arduino ethernet board. Is this hack useful?
Or the hardware just doesn’t allow it?
@AminfiBerlin , @Vince : I may be wrong to assume that Arduino Ethernet Shield doesn’t work with RFM12B because I only have (and tested) a v1 Ethernet Shield. Now that I look at the newer version’s schematic (v6) http://arduino.cc/en/uploads/Main/arduino-ethernet-shield-06-schematic.pdf
It seems that they too have the fix introduced. That means that my code above will work. Give it a try.
I changed the libraries code as suggested in your post.
the rfm12b module works perfectly alone, but not with the ethernet shield installed.
Once I try my setup with both the shield and the radio module, it seems to affect only the rfm12b module
I guess my ethernet shield has the problem you’re talking about (I bought it in Jan 2011)
Thanks for your help anyways.
1. Can you post what revision of the ethernet shield you have?
2. Also, can you try to explicitly deselect the Wiznet5100 prior to using the RFM12B (initialization, sending, etc).
pinMode(10, OUTPUT); // set the SS pin as an output
digitalWrite(10, HIGH); // turn off the W5100 chip
later when you are about to use the Wiznet, use a :
digitalWrite(10, LOW); // turn on the W5100 chip
delay(50);
3. What is the Chip Select pin on the RFM12B you use?
Thanks a ton for this post, Martin. I have V6 of the official Arduino Ethernet shield, and I can confirm that your patches work. I have the Arduino with the Ethernet shield and RFM12B using a modified version of jcw’s RFM12demo sketch, to which I added the webserver code and a one-second timer to trigger the “broadcast max-size test packet, with ack” function. A JeeNode is nearby that’s running the vanilla RFM12demo sketch. It’s been running now for about 4 and a half hours, and both the radio and the Ethernet devices are still working well. Thanks again!
P.S.- It looks like even V5 of the shield had the hardware fix. A good site for figuring out which version you have is here:
http://www.smallshire.org.uk/sufficientlysmall/2012/01/01/an-atlas-of-arduino-ethernet-shields/
UPDATE: the method is also valid for W5200 and RFM12B. Just for info
@Xerxes3rd: Hi, do you mean that with an Ethernet Shield v5, v6 and maybe R3, there’s no need to hack the hardware to be able to share correctly the SPI bus between all the SPI devices (like John suggests on his web page) ? Would you please post the modified RFM12demo sketch you use ?
Cheers.
Vince
This change works great for me. After successfully testing the changes as described, I found that Instead of modifying RF12.cpp as described, I can call the function rf12_set_cs() before rf12_initialize(). This function allows you to select between digital pins 8, 9, and 10. If you use either 8 or 9 it works with the Arduino Ethernet.
This allows me to upload sketches to both the Arduino Ethernet and to the Moteino (which uses pin 10 for CS) without using different copies of the same library.
.