Wednesday, August 27, 2014

RFM12B Radio

The radio part was left out a bit since beginning of the project. I believe in wires in such way that they are more reliable, and also can carry the power for the remote nodes. But the radio is important for future expansions as well. It can be used for remote self-powered PIR sensors, authorization nodes or for data gathering.
Yesterday I have decided to give them a try, because I had two RFM12B at home along with one bought antenna for the main station. Main station is build in metal enclosure and connected to earth that would block the radio waves. I put together one node with ATMega168 and soldered a radio on it. Then the 1/4 wave length antenna made out of single wire:

Wire lengths:

433 1/4 wave = 164.7mm
433 1/2 wave = 329.4mm
433 full wave = 692.7mm

868 1/4 wave = 82.2mm
868 1/2 wave = 164.3mm
868 full wave = 345.5mm

915 1/4 wave = 77.9mm
915 1/2 wave = 155.9mm
915 full wave = 327.8mm


And went for a search for library. I have found this library from LowPowerLab that looked good and suitable to my needs. Radios didn't work out of the box, but I had suspected it because my wiring are not using the ports the library expect. Main Board uses different pin for radio interrupt.

#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
  #define RFM_IRQ     10    // PCINT 10 / INT2

Allowing the PINCHG_IRQ instead of attachInterrupt did not work as well. But luckily changing the attachInterrupt form 0 to 2:

#else
  if (nodeID != 0)
    #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
      attachInterrupt(2, RFM12B::InterruptHandler, LOW);
    #else
      attachInterrupt(0, RFM12B::InterruptHandler, LOW);
    #endif 
  else
    #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
      detachInterrupt(2);
    #else
      detachInterrupt(0);
    #endif 
#endif

And packets started for flow through. For a short while, or they would go on on the main board, but the Ethernet stopped working. They both work on the SPI and the RTOS has no direct driver for it. A solution  worked fine:

#elif defined(__AVR_ATmega1284P__)
  #warning W5200 for AlarmBoard only!
  inline static void initSS()    { DDRB  |=  _BV(1); };
  inline static void setSS()     { cli(); PORTB &= ~_BV(1); };  // no interrupt while the SPI bus is busy
  inline static void resetSS()   { PORTB |=  _BV(1); sei();};   // no interrupt while the SPI bus is busy

Edit the Arduino Ethernet library file W5100.h so that it doesn’t allow RFM12b to interrupt while the SPI bus is busy handling Wiznet5100. Just add a cli(); and sei();. I will publish the modified libraies to GitHub.

No comments:

Post a Comment