LowPowerLab Forum

Hardware support => General topics => Topic started by: LaneF on October 22, 2015, 08:24:47 PM

Title: Programming a SwitchMote PSU for a Load
Post by: LaneF on October 22, 2015, 08:24:47 PM
I'll just say it right out of the gate... I don't get it...

In the instructions it states you have to load the  SwitchMoteConfig sketch (http://switchmoteconfig%20sketch) first, OK let's start with that.    This EEPROM keeps all of your structure info Node, Encryp, Gateway so it can communicate with the Pi Gateway...  how, where.  Do I fill that in
Quotestruct configuration {
  byte frequency;
  byte isHW;
  byte nodeID;
  byte networkID;
  char encryptionKey[16];
  byte separator1;          //separators needed to keep strings from overlapping
  char description[10];
  byte separator2;
} CONFIG;
section and if so whats the syntax.  The instructions throw you off a cliff.  It says the EEPROM is permanent.

QuoteBe sure to use Putty or an equivalent terminal app for the configuration utility:
And.... ??
I understand the terminal, type what, enter what, program how, is there a py script I need to run or what.  I write the Config Sketch to the Moteino, start my terminal set to the Comm Port and the menu pops up?  How do I get to this configuration menu land?  I don't want to just burn it if its permanent and you get one shot at it.

I like the idea of
QuoteSetup once and forget!
I just can't get off "GO".

Advise ?

Title: Re: Programming a SwitchMote PSU 1 for a Load
Post by: Felix on October 23, 2015, 07:24:33 AM
Lane,
Once you load the sketch, open it in Putty or any serial terminal. There you will be presented by a MENU and instructions how to fill the EEPROM with the settings. You just need to type certain keys on the keyboard to enter the different menu options where you give the IDs and encryption key etc. This sketch is only temporary to facilitate saving the settings to EEPROM, where the SwitchMote sketch will pick them up from.
If you still have questions let me know.
Title: Re: Programming a SwitchMote PSU 1 for a Load
Post by: LaneF on October 28, 2015, 07:34:37 PM
OK, I'm still stuck... here's the strange thing.  I can't get IDE or Codebender or anything to recognize my SPIFlash.h library.

I read the note from Felix with the link to Arduino's 096 class on libraries and I get it, you need to make sure everything is in order. 

Look at the pic posted with this; so the computer can't find the correct library when I try to verify the code ok, so I use "Import Library" so that I can force IDE to recognize the missing library.  But NO that would be too easy, the warning says "We can't import a library that's ALREADY EXSIST"  !!!!  Make up your mind.  Either you can't find it or you can !!

Any hints?  I'm not sure what else I can do when the computer knows it "exists".  I've deleted the library and reloaded it five times, same out come.

LaneF
Title: Re: Programming a SwitchMote PSU 1 for a Load
Post by: Felix on October 29, 2015, 09:43:53 AM
Lane,
I haven't seen that particular error before.
Without sitting in front of your computer to see what's happening and where files are on disk etc, I can only point you to the library tutorial, that steps you through installing a library as expected by the IDE.
See this: https://www.arduino.cc/en/Guide/Libraries
Perhaps check the manual installation section in that tutorial.
Once you understand how libraries work in the Arduino IDE then you should not have a problem in the future. Doing it the manual way helps with understanding it better.
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on October 29, 2015, 12:48:48 PM
back to 096
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on October 30, 2015, 05:25:35 PM
OK, I got through the issue of not recognizing the SPIFlash.h by reloading IDE again and adding the line #include <spi.h>.  ( it stopped seeing any of the libraries)

Now when I run "Verify" I get this cavelcade of errors.  This is way over my head.  Do I ignore these errors and just load it to the R4 Moteino or does the compiler have to verify before I can proceed?

QuoteSwitchConfig.ino: In function 'void setup()':
SwitchConfig.ino:51:3: error: 'EEPROM' was not declared in this scope
SwitchConfig.ino:62:24: error: expected primary-expression before '>' token
SwitchConfig.ino:63:24: error: expected primary-expression before '>' token
SwitchConfig.ino: In function 'void handleMenuInput(char)':
SwitchConfig.ino:104:64: error: 'EEPROM' was not declared in this scope
SwitchConfig.ino:209:32: error: 'EEPROM' was not declared in this scope
SwitchConfig.ino: In function 'void eraseSYNC()':
SwitchConfig.ino:250:3: error: 'EEPROM' was not declared in this scope
SwitchConfig.ino:250:25: error: expected primary-expression before '>' token
SwitchConfig.ino:251:25: error: expected primary-expression before '>' token
Error compiling.
Title: Re: Programming a SwitchMote PSU for a Load
Post by: Felix on October 31, 2015, 11:34:58 PM
It's complaining about compile errors.
Can you please copy paste the exact code that is giving these errors over here?
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 01, 2015, 11:12:22 AM
Thanks for reviewing this:  Using Arduino 1.6.1  I had to add SPI.h because SPIFlash.h wouldn't run without the other in the code.

I tried to copy/paste the exact code but the forum rules limit a post to 10k characters so I'll delete out the licensing comments and see if I can drop it under the limit and leave you the meat to review.  (it worked)

Thanks LaneF

// *************************************************************************************************************
//                                   SwitchMote configuration utility sketch
// *************************************************************************************************************


#include <EEPROM.h>     //get it here: http://playground.arduino.cc/Code/EEPROMex
#include <RFM69.h>         //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h>      //get it here: http://github.com/lowpowerlab/spiflash
#include <SPI.h>
#include <avr/wdt.h>       //comes with Arduino

//these settings are for the SwitchMotes, should match the same values exactly from the SwitchMote sketch
#define SYNC_MAX_COUNT     10  //max number of other nodes to SYNC with, keep the same with same setting in SwitchMote sketch!
#define SYNC_EEPROM_ADDR   64  //SYNC_TO and SYNC_INFO data starts at this EEPROM address
byte SYNC_TO[SYNC_MAX_COUNT];  // stores the address of the remote SM(s) that this SM has to notify/send request to
int SYNC_INFO[SYNC_MAX_COUNT]; // stores the buttons and modes of this and the remote SM as last 4 digits:

struct configuration {
  byte frequency;
  byte isHW;
  byte nodeID;
  byte networkID;
  char encryptionKey[16];
  byte separator1;          //separators needed to keep strings from overlapping
  char description[10];
  byte separator2;
} CONFIG;

void setup()
{
  Serial.begin(115200);
  EEPROM.readBlock(0, CONFIG);
  if (CONFIG.frequency!=RF69_433MHZ && CONFIG.frequency!=RF69_868MHZ && CONFIG.frequency!=RF69_915MHZ) // virgin CONFIG, expected [4,8,9]
  {
    Serial.println("No valid config found in EEPROM, writing defaults");
    CONFIG.separator1=CONFIG.separator2=0;
    CONFIG.frequency=RF69_915MHZ;
    CONFIG.description[0]=0;
    CONFIG.encryptionKey[0]=0;
    CONFIG.isHW=CONFIG.nodeID=CONFIG.networkID=0;
  }
 
  EEPROM.readBlock<byte>(SYNC_EEPROM_ADDR, SYNC_TO, SYNC_MAX_COUNT);
  EEPROM.readBlock<byte>(SYNC_EEPROM_ADDR+SYNC_MAX_COUNT, (byte *)SYNC_INFO, SYNC_MAX_COUNT*2); //int=2bytes so need to cast to byte array
 
  displayMainMenu();
}

void displayMainMenu()
{
  Serial.println();
  Serial.println("-----------------------------------------------");
  Serial.println("   Moteino-RFM69 configuration setup utility");
  Serial.println("-----------------------------------------------");
  Serial.print(" f - set frequency (current: ");Serial.print(CONFIG.frequency==RF69_433MHZ?"433":CONFIG.frequency==RF69_868MHZ?"868":"915");Serial.println("mhz)");
  Serial.print(" i - set node ID (current: ");Serial.print(CONFIG.nodeID);Serial.println(")");
  Serial.print(" n - set network ID (current: ");Serial.print(CONFIG.networkID);Serial.println(")");
  Serial.print(" w - set RFM69 type (current: ");Serial.print(CONFIG.isHW?"HW":"W/CW");Serial.println(")");
  Serial.print(" e - set encryption key (current: ");Serial.print(CONFIG.encryptionKey);Serial.println(")");
  Serial.print(" d - set description (current: ");Serial.print(CONFIG.description);Serial.println(")");
  Serial.println(" s - save CONFIG to EEPROM");
  Serial.println(" E - erase whole EEPROM - [0..1023]");
  Serial.print(" S - erase SYNC data [");Serial.print(SYNC_EEPROM_ADDR);Serial.print("..");Serial.print(SYNC_EEPROM_ADDR+3*SYNC_MAX_COUNT-1);Serial.print("]:[");
    displaySYNC();
    Serial.println(']');
  Serial.println(" r - reboot");
  Serial.println(" ESC - return to main menu");
}

char menu = 0;
byte charsRead = 0;
void handleMenuInput(char c)
{
  switch(menu)
  {
    case 0:
      switch(c)
      {
        case 'f': Serial.print("\r\nEnter frequency (4 = 433mhz, 8=868mhz, 9=915mhz): "); menu=c; break;
        case 'i': Serial.print("\r\nEnter node ID (1-255 + <ENTER>): "); CONFIG.nodeID=0;menu=c; break;
        case 'n': Serial.print("\r\nEnter network ID (0-255 + <ENTER>): "); CONFIG.networkID=0; menu=c; break;
        case 'e': Serial.print("\r\nEnter encryption key (type 16 characters): "); menu=c; break;
        case 'w': Serial.print("\r\nIs this RFM69W/CW/HW (0=W/CW, 1=HW): "); menu=c; break;
        case 'd': Serial.print("\r\nEnter description (10 chars max + <ENTER>): "); menu=c; break;
        case 's': Serial.print("\r\nCONFIG saved to EEPROM!"); EEPROM.writeBlock(0, CONFIG); break;
        case 'E': Serial.print("\r\nErasing EEPROM ... "); menu=c; break;
        case 'S': Serial.print("\r\nErasing SYNC EEPROM ... "); menu=c; break;
        case 'r': Serial.print("\r\nRebooting"); resetUsingWatchdog(1); break;
        case  27: displayMainMenu();menu=0;break;
      }
      break;
     
    case 'f':
      switch(c)
      {
        case '4': Serial.println("Set to 433Mhz"); CONFIG.frequency = RF69_433MHZ; menu=0; break;
        case '8': Serial.println("Set to 868Mhz"); CONFIG.frequency = RF69_868MHZ; menu=0; break;
        case '9': Serial.println("Set to 915Mhz"); CONFIG.frequency = RF69_915MHZ; menu=0; break;
        case  27: displayMainMenu();menu=0;break;
      }
      break;

    case 'i':
      if (c >= '0' && c <= '9')
      {
        if (CONFIG.nodeID * 10 + c - 48 <= 255)
        {
          CONFIG.nodeID = CONFIG.nodeID * 10 + c - 48;
          Serial.print(c);
        }
        else
        {
          Serial.print(" - Set to ");Serial.println(CONFIG.nodeID);
          menu=0;
        }
      }
      else if (c == 13 || c == 27)
      {
        Serial.print(" - Set to ");Serial.println(CONFIG.nodeID);
        displayMainMenu();
        menu=0;
      }
      break;

    case 'n':
      if (c >= '0' && c <= '9')
      {
        if (CONFIG.networkID * 10 + c - 48 <= 255)
        {
          CONFIG.networkID = CONFIG.networkID * 10 + c - 48;
          Serial.print(c);
        }
        else
        {
          Serial.print(" - Set to ");Serial.println(CONFIG.networkID);
          menu=0;
        }
      }
      if (c == 13 || c == 27)
      {
        Serial.print(" - Set to ");Serial.println(CONFIG.networkID);
        displayMainMenu();
        menu=0;
      }
      break;

    case 'e':
      if (c >= ' ' && c <= '~') //human readable chars (32 - 126)
        if (++charsRead<=16)
        {
          CONFIG.encryptionKey[charsRead-1] = c;
          CONFIG.encryptionKey[charsRead] = 0;
          Serial.print(c);
        }
      if (charsRead >= 16 || c == 27 || c == 13)
      {
        //Serial.print(" - Set to [");Serial.print(CONFIG.encryptionKey);Serial.println(']');
        Serial.println(" - DONE");
        displayMainMenu();menu=0;charsRead=0;
      }
      break;

    case 'd':
      if (c >= ' ' && c <= '~') //human readable chars (32 - 126)
      {
        if (++charsRead<=10)
        {
          CONFIG.description[charsRead-1] = c;
          CONFIG.description[charsRead] = 0;
          Serial.print(c);
        }
      }
      if (charsRead>=10 || c == 13 || c == 27)
      {
        //Serial.print(" - Set to [");Serial.print(CONFIG.description);Serial.println(']');
        Serial.println(" - DONE");
        displayMainMenu();menu=0;charsRead=0;
      }
      break;

    case 'w':
      switch(c)
      {
        case '0': Serial.println("Set to RFM69W\\CW"); CONFIG.isHW = 0; menu=0; break;
        case '1': Serial.println("Set to RFM69HW"); CONFIG.isHW = 1; menu=0; break;
        case  27: displayMainMenu();menu=0;break;
      }
      break;
    case 'E':
      for (int i=0;i<1024;i++) EEPROM.write(i,255); //eeprom_write_byte((unsigned char *) i, 255);
      Serial.println("DONE");
      //resetUsingWatchdog(1);
      menu=0;
      break;
    case 'S':
      eraseSYNC();
      Serial.println("DONE");
      menu=0;
      break;
  }
}

void loop()
{
  if(Serial.available())
    handleMenuInput(Serial.read());
}

void resetUsingWatchdog(boolean DEBUG)
{
  wdt_enable(WDTO_15MS);
  while(1) if (DEBUG) Serial.print('.');
}

void displaySYNC()
{
  for (byte i=0; i < SYNC_MAX_COUNT; i++)
  {
    Serial.print(SYNC_INFO[i]);
    if (i!=SYNC_MAX_COUNT-1) Serial.print(',');
  }
}

void eraseSYNC()
{
  for(byte i = 0; i<SYNC_MAX_COUNT; i++)
  {
    SYNC_TO[i]=0;
    SYNC_INFO[i]=0;
  }
  EEPROM.writeBlock<byte>(SYNC_EEPROM_ADDR, SYNC_TO, SYNC_MAX_COUNT);
  EEPROM.writeBlock<byte>(SYNC_EEPROM_ADDR+SYNC_MAX_COUNT, (byte*)SYNC_INFO, SYNC_MAX_COUNT*2);
}
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 01, 2015, 11:55:11 AM
Felix,

Problem solved (this one for now).  I had to reload Arduino and instead of installing 1.0.6 I did the current default load.  That's the problem.  I re-read some of your past post and spotted your comment about using 1.0.6 "..it works for me" so I uninstalled the current ver and went back to 1.0.6.

Thanks
LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 01, 2015, 12:30:51 PM
Felix,

I'm afraid I've come full circle, I've got past the compiling errors and I've uploaded Switchmote Config to the new R4.   I'm stuck on how to get the menu you talk about to show in my Terminal window for completion.  When I upload JSs using IDE it shows my Serial Port as /dev/cu.usbserial.DAO1I8NA for the Moteino R4.  How? Or what command do I type to get to the configuration menu?

LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 01, 2015, 07:01:24 PM
I'm plug-n along.  I figured out how to get the configuration file on my Motenio R4 to run in Terminal, by using the "Screen Serial Port Descp 115200" command.  OK that's saved to the EEPROM, next step.

I'm trying to upload the SwitchMote Sketch but when it "verifies" the code, it throws-up. 

As you know, nothing is entered by the user, you just uploaded after you confirm your EEPROM is correct.  I don't think I caused this one but I'm also not sure how to fix it. 

SEE THE PIC ATTACHED

Thanks

LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: Felix on November 01, 2015, 10:07:28 PM
Lane,
I think the problem is the sketch itself. The correct EEPROM Config sketch is here (https://github.com/LowPowerLab/SwitchMote/blob/master/SwitchMoteConfig.ino).
Then the actual SwitchMote sketch is here (https://github.com/LowPowerLab/SwitchMote/blob/master/SwitchMote.ino).
Please try those.
Did  you get the links to what you have somewhere on my site? If so where? I'd like to fix those if they are pointing to some old code that won't compile.
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 02, 2015, 06:13:45 PM
Felix,

I'll give these links a try.

I compared the two links you added in your reply: the Config files are the same link but the SwitchMote Sketch is different.  The link I used was on your Switchmote Project page under "programming".  https://github.com/LowPowerLab/SwitchMote/blob/master/SwitchMote.ino (https://github.com/LowPowerLab/SwitchMote/blob/master/SwitchMote.ino). (missing the "_R1" text your new Github link has)

Thanks LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: Felix on November 02, 2015, 08:57:38 PM
Ah, my mistake again, SwitchMote sketch is here (http://then%20the%20actual%20[url=https://github.com/LowPowerLab/SwitchMote/blob/master/SwitchMote.ino).]the correct one is indeed this one, without the _R1[/url].
I can compile all of these without an issue or any errors. Make sure you got the EEPROMEx library installed as well.
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 04, 2015, 01:39:05 PM
Felix,

Interesting... I loaded the R1 ver between our communications and it worked.  That'll twist your brain. 

One funny thing I found out was that the encryption didn't work.  Not that the code didn't work but a little factoid I learned.  In the Switchmote config file it asks for your Motenio password, mine happens to end with the character " ) " .  Guess what the only special character you can't end your encryption with?  It takes that as the end of the password and doesn't include it.  I had to re-flash my PI Motieno Gateway, my Garagemote and WeatherMote with a new one that doesn't use the last character as " ) ".  Lesson learned, the hard way.

LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: Felix on November 04, 2015, 02:41:12 PM
Quote from: LaneF on November 04, 2015, 01:39:05 PM
One funny thing I found out was that the encryption didn't work.  Not that the code didn't work but a little factoid I learned.  In the Switchmote config file it asks for your Motenio password, mine happens to end with the character " ) " .  Guess what the only special character you can't end your encryption with?  It takes that as the end of the password and doesn't include it.  I had to re-flash my PI Motieno Gateway, my Garagemote and WeatherMote with a new one that doesn't use the last character as " ) ".  Lesson learned, the hard way.

This is the reason why, look in SwitchMoteConfig.ino (https://github.com/LowPowerLab/SwitchMote/blob/master/SwitchMoteConfig.ino#L165):

    case 'e':
      if (c >= ' ' && c <= '~') //human readable chars (32 - 126)
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 04, 2015, 06:52:25 PM
Sorry Felix - I recognize the characters, but I have no idea what that means:

    case 'e':
      if (c >= ' ' && c <= '~') //human readable chars (32 - 126)


LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: Felix on November 05, 2015, 09:33:11 AM
Again, if you look at the larger picture, you will notice that the Config sketch expects a certain range of characters for the ENCRYPTION KEY.
That range is: c >= ' ' && c <= '~' //human readable chars (32 - 126) in the ASCII table

Ie between space and tilda, and that would include parentheses:

(http://www.asciitable.com/index/asciifull.gif)
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 06, 2015, 05:40:05 PM
Felix -
I tried your fix.  I ran the Switchmote Sketch (non R1 ver) from GitHub and confirmed my encryption.  Everything balances out and the SwitchMote PSU1 connects to the Motenio Gateway  *** 1 time*** (see below @ 3:23.04pm #4) then nothing.  This node #4 won't come up on my Gateway display but it shows as recognized in the Serial Monitor window.  Why one place and not the other.  Also, is this mote supposed to "ping" every now and again so you know it's alive?  Is there a "action" button I can put on the Gateway under the Switchmote to make it just turn on and off since it's not a light switch but a "load"?

Quote
3:24:27 PM : {"_id":2,"updated":1446848667077,"type":"WeatherMote","label":"Temperature Sensor ","descr":"###### Foyer","rssi":52,"metrics":{"V":{"label":"V","value":4.86,"unit":"v","updated":1446848667077},"F":{"label":"F","value":76.6,"unit":"°","updated":1446848667077,"pin":1,"graph":1},"H":{"label":"H","value":38,"unit":"%","updated":1446848667077,"pin":0,"graph":0},"P":{"label":"P","value":25.98,"unit":"\"","updated":1446848667077,"pin":1,"graph":1},"START":{"label":"START","value":"Started","updated":1446436019407}}}
3:23:04 PM : {"_id":2,"updated":1446848528025,"type":"WeatherMote","label":"Temperature Sensor ","descr":"###### Foyer","rssi":55,"metrics":{"V":{"label":"V","value":4.86,"unit":"v","updated":1446848528025},"F":{"label":"F","value":76.55,"unit":"°","updated":1446848528025,"pin":1,"graph":1},"H":{"label":"H","value":38,"unit":"%","updated":1446848528025,"pin":0,"graph":0},"P":{"label":"P","value":25.98,"unit":"\"","updated":1446848528025,"pin":1,"graph":1},"START":{"label":"START","value":"Started","updated":1446436019407}}}
3:23:04 PM : {"_id":4,"updated":1446397958993,"label":"SwitchMote (1x PSU)","rssi":77,"metrics":{},"type":"SwitchMote","events":{}}
3:23:04 PM : {"_id":3,"updated":1446848321923,"type":"GarageMote","label":"Garage","descr":"Double Garage Doors","rssi":71,"metrics":{"Status":{"label":"Status","value":"CLOSED","updated":1446848321923,"pin":1,"graph":1}}}
3:23:04 PM : Connected!

Thanks
LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: LaneF on November 06, 2015, 09:15:06 PM
Update:
I think the line in the Serial Monitor on the Gateway that refers to the Node#4 is not a 433HW transmission, I think it's just the remnants or read off the Gateway itself from a "Blink Tx/Rx" test Sketch from 5d?hrs ago.  The reason it says Switchmote  and PSU1 is because after I ran the Tx/Rx test I simple relabeled it in the Gateway.  Summary, I don't think the Switchmote is Tx or Rx.  Nothing from Node #4 shows coming through the Pi Serial Port using Minicom.  I re-verified the EPROM initial settings, Network, Node, Gateway it all matches. What about Parity, Baud etc in the SwitchMote Config settings, I didn't change them, do I need to?
Quote3:23:04 PM : {"_id":4,"updated":1446397958993,"label":"SwitchMote (1x PSU)","rssi":77,"metrics":{},"type":"SwitchMote","events":{}}
At the end of an ACK Tx/Rx shouldn't the Gateway Serial Monitor show a "updated":144686122###" after each successful exchange?

Thanks LaneF
Title: Re: Programming a SwitchMote PSU for a Load
Post by: Felix on November 09, 2015, 08:30:01 AM
Ok so apart from the password issue, I take things are starting to work out for you?
I would encourage you to think of ways you can debug the code and try to get a little familiar with it. That way you know what your device is doing and will get a sense of where to look when/if things don't work the way you thought they would.
Serial.print statements can help a lot here, they are basic but for beginners they are much easier to use that advanced techniques like JTAG debugging etc (JTAG is only available on atmega1284 aka MoteinoMEGA).