LowPowerLab Forum

Hardware support => Moteino => Topic started by: jbeale on October 23, 2013, 01:10:34 AM

Title: new Moteino R4 versions
Post by: jbeale on October 23, 2013, 01:10:34 AM
Congrats on the new Moteino R4 (http://lowpowerlab.com/blog/2013/10/23/moteino-r4-is-here/) designs; looks good! The R4-USB looks similar in function to the JeeLink (http://jeelabs.com/products/jeelink)  which is not entirely cheap at 32.5 Euro, or $36.50 from ModernDevice (http://moderndevice.com/product/jeelink-module-assembled/).

So feel free to price your R4-USB lower than that, if you can! :-)

Does having a single board to host either RFM12B or RFM69W/HW modules imply that we will eventually be able to inter-operate (eg. some code that can send packets from the 12B and receive them on the 69W, or the reverse?)  Just this week I put in an order for several Moteino R3 modules since the RFM69 looks like the wave of the future, but I still have a number of JeeNodes and it would be nice to have them all talk to one host, if possible.
Title: Re: new Moteino R4 versions
Post by: Felix on October 23, 2013, 08:20:36 AM
Thanks, I will try to price it lower :)
I really want to make the two libs talk to each other, however there are a few breaking decisions to make - like encryption. To mention just one - the 12B has no AES hardware encryption, which means I either figure out how to implement the exact same algorithm in firmware (which could prove difficult and increase the code significantly) or drop it on both ends (which I don't want since encryption is pretty vital) or maybe implement the simplistic encryption in the 12b lib on the RFM69 (which defeats the purpose of having the fast AES hardware encryption). Then there's the packet engine which is different, etc. I did try to make them talk early on with the most default settings but had no success. I probably did not match the settings exactly right and I don't have the expensive tools to analyze RF signals and such. Maybe the experts in the forum can devise a clever solution...

Perhaps a bridge between the two types of transceiver networks would be more within reach.
Title: Re: new Moteino R4 versions
Post by: john k2ox on October 23, 2013, 10:10:17 AM
Do I see pads for a UF l coax connector?
Title: Re: new Moteino R4 versions
Post by: Felix on October 23, 2013, 10:13:01 AM
I wanted to add that but didn't really find a good way to place it. On the other hand it could be soldered between the ANT and GND pads which are spaced just right to make that possible.
In fact both UF.l and SMA connectors can be soldered with a little care. I will take some photos of both of those and post them to the blog sometime...
Title: Re: new Moteino R4 versions
Post by: john k2ox on October 23, 2013, 10:58:17 AM
Yes. I've been doing that.  Was using SMA, now Uf.l.  Glad the pads still accommodate Uf.l

Glad to see you're still innovating!

BTW did you just add a spell checker to the forum?
Title: Re: new Moteino R4 versions
Post by: Felix on October 23, 2013, 07:47:11 PM
Thanks. No I didn't add a spell checker.
Title: Re: new Moteino R4 versions
Post by: jbeale on October 24, 2013, 02:26:47 AM
Just got some of the new R4 boards in (I'd ordered them as R3, before the announcement). Very happy to see them working nicely. It is really great to see the RSSI readout, as previously I've only used RFM12B units where you had to guess.  You really get to see what matters and what doesn't as far as antennas, positions, & etc.  It looks like (for the RFM69W unit) the difference between max and min Tx power settings
radio.setPowerLevel(0);  // 0 = min power, 31 = max power
is consistently 35 dB in reported RSSI at the other end. 

According to the data sheet the Tx power range is -18 to +13 dB, which is a range of 31 dB.  I'm sending 3 packets at low power and 3 at high power, and the readings are pretty steady, within 2 units. I guess it's just that the RSSI units are not exactly calibrated at 1.0 dB per unit.

[99]  [RX_RSSI:-87] 18 - ACK sent.Lo  Pinging node 99 - ACK...ok! 999,957,1019,100
[99]  [RX_RSSI:-86] 19 - ACK sent.Hi  Pinging node 99 - ACK...ok! 1000,957,1019,101
[99]  [RX_RSSI:-86] 20 - ACK sent.Lo  Pinging node 99 - ACK...ok! 997,957,1019,102
[99]  [RX_RSSI:-51] 21 - ACK sent.Hi  Pinging node 99 - ACK...ok! 999,957,1019,103
[99]  [RX_RSSI:-51] 22 - ACK sent.Lo  Pinging node 99 - ACK...ok! 997,957,1019,104
[99]  [RX_RSSI:-51] 23 - ACK sent.Hi  Pinging node 99 - ACK...ok! 1000,957,1019,105
[99]  [RX_RSSI:-86] 24 - ACK sent.Lo  Pinging node 99 - ACK...ok! 997,957,1019,106
[99]  [RX_RSSI:-87] 25 - ACK sent.Hi  Pinging node 99 - ACK...ok! 1000,957,1019,107
[99]  [RX_RSSI:-86] 26 - ACK sent.Lo  Pinging node 99 - ACK...ok! 997,957,1019,108
[99]  [RX_RSSI:-51] 27 - ACK sent.Hi  Pinging node 99 - ACK...ok! 999,957,1019,109
[99]  [RX_RSSI:-51] 28 - ACK sent.Lo  Pinging node 99 - ACK...ok! 998,957,1019,110
[99]  [RX_RSSI:-51] 29 - ACK sent.Hi  Pinging node 99 - ACK...ok! 999,957,1019,111
[99]  [RX_RSSI:-86] 30 - ACK sent.Lo  Pinging node 99 - ACK...ok! 1001,957,1019,112
[99]  [RX_RSSI:-86] 0 - ACK sent.Hi  Pinging node 99 - ACK...ok! 993,957,1019,113
[99]  [RX_RSSI:-86] 1 - ACK sent.Lo  Pinging node 99 - ACK...ok! 998,957,1019,114

Title: Re: new Moteino R4 versions
Post by: jbeale on October 24, 2013, 02:33:22 AM
In case of interest- what generated output in previous post:

slightly modified node sketch
#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>

#define NODEID      99
#define NETWORKID   100
#define GATEWAYID   1
#define FREQUENCY   RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define LED         9
#define SERIAL_BAUD 115200
#define ACK_TIME    30  // # of ms to wait for an ack

int TRANSMITPERIOD = 1000; //transmit a packet to gateway so often (in ms)
char payload[] = "123 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
byte sendSize=0;
boolean requestACK = false;
bool hiPower = true;    // set radio Tx to maximum power
long packetCount = 0;
SPIFlash flash(8, 0xEF30); //EF40 for 16mbit windbond chip
RFM69 radio;

void setup() {
  Serial.begin(SERIAL_BAUD);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  //radio.setHighPower(); //must uncomment for RFM69HW!
  radio.encrypt(KEY);
  char buff[50];
  sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  if (flash.initialize())
    Serial.println("SPI Flash Init OK!");
  else
    Serial.println("SPI Flash Init FAIL! (is chip present?)");
}

long lastPeriod = -1;
void loop() {
  //process any serial input
  if (Serial.available() > 0)
  {
    char input = Serial.read();
   
    if (input == 'r') //d=dump register values
      radio.readAllRegs();
   
    if (input == 'd') //d=dump flash area
    {
      Serial.println("Flash content:");
      int counter = 0;

      while(counter<=256){
        Serial.print(flash.readByte(counter++), HEX);
        Serial.print('.');
      }
      while(flash.busy());
      Serial.println();
    }
    if (input == 'e')
    {
      Serial.print("Erasing Flash chip ... ");
      flash.chipErase();
      while(flash.busy());
      Serial.println("DONE");
    }
    if (input == 'i')
    {
      Serial.print("DeviceID: ");
      word jedecid = flash.readDeviceId();
      Serial.println(jedecid, HEX);
    }
  }

  //check for any received packets
  if (radio.receiveDone())
  {
    Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
    for (byte i = 0; i < radio.DATALEN; i++)
      Serial.print((char)radio.DATA[i]);
    Serial.print("   [RX_RSSI:");Serial.print(radio.readRSSI());Serial.print("]");

    if (radio.ACK_REQUESTED)
    {
      radio.sendACK();
      Serial.print(" - ACK sent");
      delay(10);
    }
    Blink(LED,5);
    Serial.println();
  }
 
  int currPeriod = millis()/TRANSMITPERIOD;
  if (currPeriod != lastPeriod)
  {
    lastPeriod=currPeriod;
    Serial.print(packetCount);
    Serial.print(" Sending[");
    Serial.print(sendSize);
    Serial.print("]: ");
    for(byte i = 0; i < sendSize; i++)
      Serial.print((char)payload[i]);

    if (radio.sendWithRetry(GATEWAYID, payload, sendSize))
     Serial.print(" ok!");
    else Serial.print(" nothing...");
   
    if (hiPower) radio.setPowerLevel(31);
    else radio.setPowerLevel(0);  // 0 = min power, 31 = max power

    if ((packetCount++)%3==0)
      hiPower = !hiPower;  // toggle signal strength

    sendSize = (sendSize + 1) % 31;
    Serial.println();
    Blink(LED,3);
  }
}

void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}


slightly modified gateway sketch
#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>

#define NODEID      1
#define NETWORKID   100
#define FREQUENCY   RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define LED         9
#define SERIAL_BAUD 115200
#define ACK_TIME    30  // # of ms to wait for an ack

RFM69 radio;
SPIFlash flash(8, 0xEF30); //EF40 for 16mbit windbond chip
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
bool showData = false;  // should we print out the received packet?
bool firstPacket = true; // is this the first packet ever received?
bool hiPower = true;    // set radio Tx to maximum power

long totalRec = 0;    // total # packets received
long lastTime;    // time of most recent reception
long maxTime = 0;     // maximum time interval between packet reception
long minTime = 1000000; // minimum time interval between packets

void setup() {
  Serial.begin(SERIAL_BAUD);
  delay(10);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  //radio.setHighPower(); //must uncomment for RFM69HW!
 
  radio.encrypt(KEY);
  radio.promiscuous(promiscuousMode);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  if (flash.initialize())
    Serial.println("SPI Flash Init OK!");
  else
    Serial.println("SPI Flash Init FAIL! (is chip present?)");
}

byte ackCount=0;
void loop() {
  long thisTime;  // current time of packet reception
  long dTime;    // interval between current & previous packets
 
  //process any serial input
  if (Serial.available() > 0)
  {
    char input = Serial.read();
    if (input == 'r') //d=dump all register values
      radio.readAllRegs();
    if (input == 'E') //E=enable encryption
      radio.encrypt(KEY);
    if (input == 'e') //e=disable encryption
      radio.encrypt(null);
    if (input == 'p')
    {
      promiscuousMode = !promiscuousMode;
      radio.promiscuous(promiscuousMode);
      Serial.print("Promiscuous mode ");Serial.println(promiscuousMode ? "on" : "off");
    }
   
    if (input == 'd') //d=dump flash area
    {
      Serial.println("Flash content:");
      int counter = 0;

      while(counter<=256){
        Serial.print(flash.readByte(counter++), HEX);
        Serial.print('.');
      }
      while(flash.busy());
      Serial.println();
    }
    if (input == 'e')
    {
      Serial.print("Erasing Flash chip ... ");
      flash.chipErase();
      while(flash.busy());
      Serial.println("DONE");
    }
    if (input == 'i')
    {
      Serial.print("DeviceID: ");
      word jedecid = flash.readDeviceId();
      Serial.println(jedecid, HEX);
    }
if (input == 't')
    {
      byte temperature =  radio.readTemperature(-1); // -1 = user cal factor, adjust for correct ambient
      byte fTemp = 1.8 * temperature + 32; // 9/5=1.8
      Serial.print( "Radio Temp is ");
      Serial.print(temperature);
      Serial.print("C, ");
      Serial.print(fTemp); //converting to F loses some resolution, obvious when C is on edge between 2 values (ie 26C=78F, 27C=80F)
      Serial.println('F');
    }
  }

  if (radio.receiveDone())
  {
    totalRec += 1;    // total number of packets received
    if (firstPacket == true) {
      lastTime = millis();
      firstPacket = false;
    } else {       
      thisTime = millis();
      dTime = thisTime - lastTime;
      lastTime = thisTime;
      if (dTime > maxTime) maxTime = dTime;
      if (dTime < minTime) minTime = dTime;
    }
    Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
    if (promiscuousMode)
    {
      Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
    }
    if (showData == true) {
      for (byte i = 0; i < radio.DATALEN; i++)
        Serial.print((char)radio.DATA[i]);
    }
    Serial.print(" [RX_RSSI:");Serial.print(radio.readRSSI());Serial.print("] ");
    Serial.print(radio.DATALEN);
   
    if (radio.ACK_REQUESTED)
    {
      byte theNodeID = radio.SENDERID;
      radio.sendACK();
      Serial.print(" - ACK sent.");
     
      if (hiPower) Serial.print("Hi ");
      else Serial.print("Lo ");

      // When a node requests an ACK, respond to the ACK
      // and also send a packet requesting an ACK (every 3rd one only)
      // This way both TX/RX NODE functions are tested on 1 end at the GATEWAY
      // if (ackCount++%3==0)
      if (true)
      {
        Serial.print(" Pinging node ");
        Serial.print(theNodeID);
        Serial.print(" - ACK...");
        delay(3); //need this when sending right after reception .. ?
        if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0))  // 0 = only 1 attempt, no retries
          Serial.print("ok!");
        else Serial.print("nothing");
      }
      if (hiPower) radio.setPowerLevel(31);
      else radio.setPowerLevel(0);  // 0 = min power, 31 = max power
      hiPower = !hiPower;  // toggle signal strength

     
    }
    if (firstPacket == false) {
      Serial.print(" ");
      Serial.print(dTime);
      Serial.print(",");
      Serial.print(minTime);
      Serial.print(",");
      Serial.print(maxTime);
      Serial.print(",");
      Serial.print(totalRec);
    }
    Serial.println();
    Blink(LED,3);
  }
}

void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}
Title: Re: new Moteino R4 versions
Post by: john k2ox on October 24, 2013, 09:11:50 AM
I've checked the RSSI here with a lab grade signal generator and found a one to one relationship of dbm output power and RSSI.  I remember being extremely impressed.

jbeale, now you have me thinking.   

I'll have to check to see how well the radio Tx output power follows the power settings.
Title: Re: new Moteino R4 versions
Post by: john k2ox on October 24, 2013, 09:17:24 AM
Hi Felix,

As per the spell checker. 

IE was my old browser and I just switched to Firefox.  Looks like it adds the spell checking. 

I'm feeling much smarter now, posting in half the time!  :0

Title: Re: new Moteino R4 versions
Post by: jbeale on October 25, 2013, 10:12:28 AM
@John k2ox: Seems to me that the Tx power level has a step right in the middle at a setting of 15 to 16. See attached graph (with Tx/Rx at very short range, about 6 feet). Looks like a little compression at the top end also, not too surprisingly.
Title: Re: new Moteino R4 versions
Post by: Felix on October 25, 2013, 01:01:08 PM
Hm, weird step, but at least the rest looks pretty consistent...
Title: Re: new Moteino R4 versions
Post by: jbeale on October 25, 2013, 03:31:54 PM
I took some more data, here are two different Tx Moteino v4 (RFM69W) at several different distances, showing the received RSSI (from a 3rd Moteino, with modified gateway sketch) versus applied power level setting at the Tx side.  Note the vertical axis shows absolute value of RSSI, but all the values really should be negative.

The HopeRF RFM69W data sheet says "Programmable Pout: -18 to +13 dBm in 1dB steps".  Now, when I was a kid, my dad would start his after-dinner story with "I will tell you a story that is part true and part not true..."  and this data sheet is kind of like that.  You get basically 1 dB steps except where you don't, particularly around step 15 to step 16, and the magnitude and sign of that discontinuity changes between specific units. Also, one of the two I tested starts out with < 0.5 dB steps near max power, but the other one was near 1 dB. 

Probably few people care about this- most will just use the default max power setting. But it is good to know, if you were relying on the power setting to make some kind of measurement.

(https://lh5.googleusercontent.com/-9Y5GnafRGhM/UmrE4jT0YEI/AAAAAAAADLM/F0HY9yEJryE/s800/Kst%2520-%2520CDocuments%2520and%2520SettingsJohnMy%2520DocumentsRPiRFM69W-PowerSet2.kst%252010252013%2520122017%2520PM.jpg)

Also of possible interest: with the default bitrate, in my setup, at -100 dB RSSI you get only about 1% of the packets through.  At -97 dB you get about half of them.  At -90 you only miss a few percent. This is with a very short packet (1 byte payload).  RSSI is fractional in the table below because I am averaging over RSSI of all received packets with a given Tx power setting.
PowerSetting,NumPackets,abs(RSSI)
0,0,
1,0,
2,0,
3,0,
4,0,
5,1,100.000
6,10,98.800
7,24,98.500
8,62,97.516
9,86,96.686
10,103,96.019
11,100,94.940
12,113,94.177
13,112,93.009
14,114,91.947
15,116,90.948
16,113,92.487
17,114,91.561
18,115,90.400
19,115,89.678
20,115,88.635
21,117,87.556
22,117,86.615
23,117,85.521
24,117,84.590
25,117,83.803