Where is the IOShield?

Started by luisr320, August 29, 2015, 08:04:07 PM

luisr320


Felix

HAHA!
It's a surprise. I have a video and new node for the gateway to release soon. I just was too busy over the weekend and didn't have the time to blog about it :)
But it's pending!!

Felix

It's published now ;D
Two kits made available in the shop, production will follow in the coming near future.

luisr320

WHAT??? I uncover the best hidden secret of Lowpower lab and someone grab both boards from the shop and now there is none for me? That's not fair!!! 😭😭😭😪😪😪

Oh well, lesson learned. Next time I'll keep my mouth shut.

Any idea what hen they will be available?

luisr320

Felix,

I stumbled on a dorment bug on the  RFM69/Examples/IOShield/IOShield.ino
(https://github.com/LowPowerLab/RFM69/blob/master/Examples/IOShield/IOShield.ino)
If I uncomment lines 99 and 100 which contains

  //sprintf(buff, "IOShield : %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  //DEBUGln(buff);


I get an error on the COM monitor, with a report of: SPI Flash Init FAIL! (is chip present?)

But if I change the size of buff[20] to buff[22], no error is reported and the Flash chip is reported as OK.

I have absolutely no idea why these two events are related but it works :)

Felix

Fixed!
Also, IOShields PCBs are being manufactured, I hope to have some assembled by next weekend (beginning of October 2015)!

luisr320

#6
So I tried to setup a 8 relay board with a 74HC595 shift register to control them with a Moteino.
I loaded th ioshield.ino on the moteino with the 595 and the relays, but then I got stuck. There is no example sketch on how to send the "OFF", "ALL", "PRG 1:10" or the "ON:1" as expected by the ioshield.ino. I suppose the sketch is to be used with the Raspberry Pi gateway where all this is clearer. Maybe. But I really wanted to try my setup so I decided to make a small sketch to pass the commands wirelessly to the relay board Moteino.
This is what I came up:

// **********************************************************************************************************
// Moteino String Parser
// Ver 1.0
// This sketch sends any text message to a node in a format that allows it to be interpreted as a command,
// using Moteinos equipped with HopeRF RFM69HW
// 2015-09-26 (C) [email protected]
// **********************************************************************************************************
// Adapted from [email protected], http://www.LowPowerLab.com mote.ino
// **********************************************************************************************************
// It receives text from the Serial Monitor and sends it to a destination node trough the radio
// **********************************************************************************************************
// Creative Commons Attrib Share-Alike License
// You are free to use/extend this code/library but please abide with the CCSA license:
// http://creativecommons.org/licenses/by-sa/3.0/
// **********************************************************************************************************

#include <RFM69.h>         //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h>      //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h>           //comes with Arduino IDE (www.arduino.cc)

//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/SITUATION!
//*****************************************************************************************************************************
#define NODEID 9 //unique for each node on same network
#define DESTNODEID 8 //To what node shall the commands be sent to?
#define NETWORKID 100 //the same on all nodes that talk to each other
#define FREQUENCY RF69_433MHZ //Match with the correct radio frequency
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes! No more, no less!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME 50 //max # of ms to wait for an ACK to be received
#define LED 9 //Moteinos have LEDs on D9
#define SERIAL_BAUD 115200 //Make sure your Serial monitor has the same baud rate
#define SERIAL_EN                //comment out if you don't want any serial output

#ifdef SERIAL_EN
  #define DEBUG(input)   Serial.print(input)
  #define DEBUGln(input) Serial.println(input)
#else
  #define DEBUG(input)
  #define DEBUGln(input)
#endif

RFM69 radio; //initiate a radio instance
/////////////////////////////////////////////////////////////////////////////
// flash(SPI_CS, MANUFACTURER_ID)
// SPI_CS          - CS pin attached to SPI flash chip (8 in case of Moteino)
// MANUFACTURER_ID - OPTIONAL, 0xEF30 for windbond 4mbit flash (Moteino OEM)
/////////////////////////////////////////////////////////////////////////////
SPIFlash flash(8, 0xEF30); //regular Moteinos have FLASH MEM on D8, MEGA has it on D4
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network

void setup()
{
  Serial.begin(SERIAL_BAUD); //Initialize the Serial port at the specified baud rate
  delay(10); //Wait for the Serial port to settle down
  
  //Initialize the radio
  radio.initialize(FREQUENCY,NODEID,NETWORKID); //Initialize the radio
  radio.setHighPower(); //Use if using RFM69HW
  radio.encrypt(ENCRYPTKEY); //Turn the radio Encryption ON
  radio.promiscuous(promiscuousMode);//Turn the radio Promiscuous mode according to what in the promiscuousMode variable 
  Serial.println("Transmiting at 433 Mhz");
}

void loop()
{

  if (radio.receiveDone())
  {
    
    DEBUG(F("["));DEBUG(radio.SENDERID);DEBUG(F("] "));
    DEBUG((char *)radio.DATA);
    DEBUG(F(" [RX_RSSI:"));DEBUG(radio.RSSI);DEBUGln("]");
    if (radio.ACKRequested()) radio.sendACK();
  }
  
  // wireless programming token check
  // DO NOT REMOVE, or this node will not be wirelessly programmable any more!
  CheckForWirelessHEX(radio, flash, true);

  //process any serial input
  if (Serial.available() > 0) //Wait for some data to be inputed on the Serial Monitor
  {
    String input = Serial.readString(); //Read the input data into a String type variable called "input"
    byte input_length = input.length(); //Calculate the lenght of the "data" contents to be sent
    const char *data = input.c_str(); //Convert the String "input" to a char called "data"
    Serial.println(data); //Display "data" contents on the local Serial Monitor       
    if (radio.sendWithRetry(DESTNODEID, data, input_length, 1, ACK_TIME))//Send the data via radio and wait for the ACK to be received
    {
      Serial.println("ACK Received"); //If the sent packet was delivered and an ACK received, send this message to the serial monitor
      delay(3); // Allow the the radio to switch to receive mode
      Blink(LED,100); //Blink the transmitter led to show the data was successfully sent
    }
  }
  
}

//----------------------------------------------------------------------//
//                         FUNCTIONS                                    //
//----------------------------------------------------------------------//

void Blink(byte PIN, int DELAY_MS)//The led blinking function
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}


If you want to try it out just adjust the radio configuration with your setup. Load it into a Moteino (the Sender), and load the regular ioshield.ino example (from the RFM69 libraries examples folder - https://github.com/LowPowerLab/RFM69/blob/master/Examples/IOShield/IOShield.ino) on the other one that has the shift register and the relay board (the Receiver).

Now open the Serial monitor on both (you will have to open two instances of the Arduino IDE to open two different com ports), and write the commands on the Sender Moteino to be sent to the Receiver Moteino. For instance, ALL (upper case), will turn all the relays ON at the same time. Not something you want to do on a sprinkler system, but it's ok for testing. And OFF will turn all the relays off. To turn a single relay on, just send ON:1, being 1 the required relay number to be controlled. When turning a relay on, the previous one will go off.
Read the header of the ioshield.ino sketch to know what else you can do.

I found out that you need to add a couple of lines on the ioshield.ino sketch in order to get the ACK back from the Sender.

On the zoneON and zonesOFF functions, add a delay(100) after the  radio.sendACK();.
Otherwise, there will be no time for the ACK to get back for display before the radio is used again.

void zoneON(byte which)
{
  //stopAndResetProgram(); //stop any running programs
  if (radio.ACKRequested()) radio.sendACK();
  delay(100); //Wait for the radio to be available again
  registersWriteBit(which-1);
  sprintf(buff, "ZONE:%d", which);
  if (radio.sendWithRetry(GATEWAYID, buff, strlen(buff)))
    {DEBUGln(F("..OK"));}
  else {DEBUGln(F("..NOK"));}
}


void zonesOFF()
{
  //stopAndResetProgram(); //stop any running programs
  if (radio.ACKRequested()) radio.sendACK();
    registersClear();
    delay(100); //Wait for the radio to be available again
  if (radio.sendWithRetry(GATEWAYID, "ZONES:OFF", 9))
    {DEBUGln(F("..OK"));}
  else {DEBUGln(F("..NOK"));}
}


I'm finishing a video with a presentation of this project that I will post soon, and I discuss both sketches for a better understanding of how they work.

If someone wants to understand how a shift register works, just watch this excellent video by Kevin Darrah:
https://www.youtube.com/watch?v=6fVbJbNPrEU&list=PLQqzVdag6mtenq2dnv9NGP9LVH5ZbAAud

luisr320


Felix

Awesome Luis, nice video, definitely worthy of showing on my IOSHield page once I have it up :D

My example that I gave was ready to work with the gateway sketch. You can pass that a message like "X:message" where X is the target node. That's how the gateway.js script passes any message from the UI to the actual node, in this case the IOShield. But great exercise showing how to use this with relays instead of TRIACs.

luisr320

Felix: did you notice my comment regarding the required delay(100) in the ioshield.ino in order for the ACK to come trough?

Felix

No i didn't, I'll watch again.
But there should not be any delay required. I have not noticed anything like that in my use. The pumps turn ON instantly and I get the ACK to reflect that in the UI also.

luisr320

No need to check the video. Just read my post, on the last two blocks of code.

Felix