Sending values from sensor.

Started by mattt, July 21, 2014, 02:23:11 AM

mattt

Hi,

I was hoping someone could point out where i've gone wrong in this sketch. I can get the node to send the sensor value to the gateway using the Struct_receive and Struct_send examples. But it seems like the loop is no longer working correctly and the node is not sending ACK requests from the gateway. I tried putting the sensor code in a function but this did not work either.

#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>
#include <Wire.h>
#include "Adafruit_HTU21DF.h"

#define NODEID      2
#define NETWORKID   100
#define GATEWAYID   1
#define FREQUENCY   RF69_433MHZ //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 = 3000; //transmit a packet to gateway so often (in ms)
byte sendSize=0;
boolean requestACK = false;
SPIFlash flash(8, 0xEF30); //EF40 for 16mbit windbond chip
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
float celsius;
float hum;
RFM69 radio;

typedef struct {		
  int           nodeId; //store this nodeId
  unsigned long uptime; //uptime in ms
  float         temp2;   //temperature maybe?
} Payload;
Payload theData;

void setup() {
  Serial.begin(SERIAL_BAUD);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.setHighPower(); //uncomment only 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?)");
  if (!htu.begin()) {
    Serial.println("Couldn't find sensor!");
    while (1);
  }

}

long lastPeriod = -1;
void loop() {
	celsius = htu.readTemperature();
  //process any serial input
  if (Serial.available() > 0)
  {
    char input = Serial.read();
    if (input >= 48 && input <= 57) //[0,9]
    {
      TRANSMITPERIOD = 100 * (input-48);
      if (TRANSMITPERIOD == 0) TRANSMITPERIOD = 1000;
      Serial.print("\nChanging delay to ");
      Serial.print(TRANSMITPERIOD);
      Serial.println("ms\n");
    }
    
    if (input == 'r') //d=dump register values
      radio.readAllRegs();
    //if (input == 'E') //E=enable encryption
    //  radio.encrypt(KEY);
    //if (input == 'e') //e=disable encryption
    //  radio.encrypt(null);
    
    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)
  {
    //fill in the struct with new values
    theData.nodeId = NODEID;
    theData.uptime = millis();
    theData.temp2 = celsius; //it's hot!
    
    Serial.print("Sending struct (");
    Serial.print(sizeof(theData));
    Serial.print(" bytes) ... ");
    if (radio.sendWithRetry(GATEWAYID, (const void*)(&theData), sizeof(theData)))
      Serial.print(" ok!");
    else Serial.print(" nothing...");
    Serial.println();
    Blink(LED,3);
	//Sensortemp();
    lastPeriod=currPeriod;
  }

 

}

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

//float Sensortemp()
//{
//celsius = htu.readTemperature();
//return celsius;
//}


Serial data from gateway:

[2]  [RX_RSSI:-34] nodeId=2 uptime=564037 temp=22.27 - ACK sent. Pinging node 2 - ACK...nothing
[2]  [RX_RSSI:-34] nodeId=2 uptime=567011 temp=22.29 - ACK sent.
[2]  [RX_RSSI:-34] nodeId=2 uptime=570027 temp=22.28 - ACK sent.
[2]  [RX_RSSI:-34] nodeId=2 uptime=573041 temp=22.28 - ACK sent. Pinging node 2 - ACK...nothing


Note serial data:

Transmitting at 433 Mhz...
SPI Flash Init OK!
Sending struct (10 bytes) ...  ok!
Sending struct (10 bytes) ...  ok!
Sending struct (10 bytes) ...  ok!
Sending struct (10 bytes) ...  ok!
Sending struct (10 bytes) ...  ok!

Felix

My guess is you're not checking radio.receiveDone() often enough and may be spending too much time reading temperature.
Your top priority in code is the radio, everything revolves around it, especially when you expect packets any time and want ACKs back. A replying node will send an ACK immediately. If you're off to reading sensors and doing other things you might be missing that ACK.

mattt

Ok thanks for the tip. I don't really need the gateway to send extra ACK's anyway. How is it possible to insure the gateway receives all transmissions if I had for example 100 nodes. If two nodes transmit at the same time I assume that the gateway will miss one of these transmissions?

Felix

Please read the documentation on the library if you have a few minutes.
There is a listen-before-talk feature. You should not have collisions in either case, or they should be very limited.
You can follow the Send/Receive examples for how to send with retries (just use sendWithRetry): https://github.com/LowPowerLab/RFM69/tree/master/Examples

luisr320

Can you please post the code loaded on the Gateway?

mattt

My code is a mess at the moment I am trying to integrate the gateway into emoncms without success.

Felix

I've done it, it was pretty easy. Read the serial stream in python with pyserial, then call the emon REST URL with the sensor values, emonCMS does the rest. It was a long time ago, can't remember the details but it was straight forward, I'm sure it's still the same or they made it even easier.