Project

General

Profile

package contents are wrong

Added by Alban_T over 3 years ago

Hi,

I’m using one Jeenode as a receiver and 1 to take measurements using a SHT1x temp/humidity sensor and 2 DS18B20 temp sensors.
My receiver sents out a package containing the NodeID and my sensor reconizes its own NodeID (=1) and sents back the data.
So far so good, the measurements are correct and I’m running this for a few weeks now.

Tonight I tried to add another sensor node (NodeID=2) and tried to receive its measurements. For now I only have connected a SHT1x and changed the code to sent back 0 for both DS18B20 sensors. Thru serial on the sensor node I see the measurement and see correct values.
But the receiver receives incorrect data while Node 1 still returns correct values.

ReceiverNode.ino
myId = 30
 A i1 g212 @ 868 MHz o26912 x1
RequestData(1,1)

Received payload: 
temptx.nodeID = 1
temptx.temp0 = 2181
temptx.temp1 = 2000
temptx.tempSHT = 2580
temptx.humiSHT = 69
temptx.supplyV = 241
*************************
Request took 2046ms
RequestData(2,1)

Received payload: 
temptx.nodeID = 2
temptx.temp0 = 0
temptx.temp1 = 0
temptx.tempSHT = 21724
temptx.humiSHT = 4412
temptx.supplyV = 280
*************************
Request took 1537ms

Sensornode shows:

myId = 2
 B i2 g212 @ 868 MHz o26912 x2
SensorNode.ino

Received payload: 
RequestPayload.Jeenode = 2
RequestPayload.Requestcode = 1
*************************
That's me!!! I'll sent the data out!!
Send payload: 
temptx.nodeID = 2
temptx.temp0 = 0
temptx.temp1 = 0
temptx.tempSHT = 2098
temptx.humiSHT = 67
temptx.supplyV = 280
*************************

I really hope someone can explain to me what is going on here!?

For completeness I add both ino files below:

Receiver:

#include 

// interrupt handler for JeeLabs Sleepy power saving
ISR(WDT_vect) { Sleepy::watchdogEvent(); }  

const int myNodeID = 30;                            // RF12 node ID in the range 1-30
const int network = 210;                            // RF12 Network group
const int freq = RF12_868MHZ;                       // Frequency of RFM12B module
byte myId;                                          // remember my own node ID

const int LEDpin = 4;                               // a LED is connected between DIO1 and GND on the JeeNode
const int LEDpinRed = 7;
int numSensors;     // Variable used to determine the amount of parallel DS18B20 sensors in the network
const boolean DEBUG = true;


//############################################################################################################
//Data Structure to be sent
typedef struct {
    int nodeID;     // ID of the node
    int supplyV;    // Supply voltage
    int temp0;      // Temperature reading
    int temp1;      // Temperature 2 reading
    int tempSHT;    // Temperature 3 reading
    int humiSHT;    // Humidity reading
} Payload;
Payload temptx;     // Instantiate a Payload object

typedef struct {
    byte Jeenode;       // identify the Jeenode
    byte Requestcode;   // identify the needed response
} RequestPayload;
RequestPayload requesttx;

//############################################################################################################

void setup() {
    Serial.begin(9600);
    Serial.println("ReceiverNode.ino");
    pinMode(LEDpin,OUTPUT);
    pinMode(LEDpinRed,OUTPUT);

    digitalWrite(LEDpin,HIGH);
    digitalWrite(LEDpinRed,HIGH);
    delay(500);
    digitalWrite(LEDpin,LOW);
    digitalWrite(LEDpinRed,LOW);

    myId = rf12_initialize(myNodeID,freq,network);          // Initialize RFM12 with settings defined above
    //myId = rf12_configSilent();                       // Initialize RFM12 with its internal settings
    Serial.print("myId = ");Serial.println(myId);
    rf12_configDump();                              // Print the settings to the serial port
    Serial.flush();

}


long prevMillis;
long diffMillis;
void loop() {

    // receive a space (ASCII 32) thru Serial to trigger the request
    // send data only when you receive data:
    if (Serial.available() > 0) {
        // read the incoming byte:
        byte incomingByte = Serial.read();
        byte node = incomingByte - 48;
        if (node >= 1 && node <= 9) {
            digitalWrite(LEDpin,HIGH);
            if (DEBUG == true) {
                Serial.print("RequestData("); Serial.print(node); Serial.println(",1)");
                Serial.flush();
            }

            prevMillis = millis();
            RequestData(node,1);
            digitalWrite(LEDpin,LOW);
        }
    }   

        ReceiveData();



}

// receive measurement results from JeeNode 2
 void ReceiveData() {
    if (rf12_recvDone() && rf12_crc == 0){
        digitalWrite(LEDpinRed,HIGH);
        const Payload* p = (const Payload*) rf12_data;

        if (DEBUG == true) {
            Serial.println("");
            Serial.println("Received payload: ");
            Serial.print("temptx.nodeID = "); Serial.println(p->nodeID);
            Serial.print("temptx.temp0 = "); Serial.println(p->temp0);
            Serial.print("temptx.temp1 = "); Serial.println(p->temp1);
            Serial.print("temptx.tempSHT = "); Serial.println(p->tempSHT);
            Serial.print("temptx.humiSHT = "); Serial.println(p->humiSHT);
            Serial.print("temptx.supplyV = "); Serial.println(p->supplyV);
            Serial.println("*************************");
            diffMillis = millis() - prevMillis;
            Serial.print("Request took ");Serial.print(diffMillis);Serial.println("ms");
            Serial.flush();
        }
        else {
            Serial.print(p->nodeID);Serial.print(";");
            Serial.print(p->temp0);Serial.print(";");
            Serial.print(p->temp1);Serial.print(";");
            Serial.print(p->tempSHT);Serial.print(";");
            Serial.print(p->humiSHT);Serial.print(";");
            Serial.print(p->supplyV);Serial.print(";");
            diffMillis = millis() - prevMillis;
            Serial.print(diffMillis);Serial.println(";");
            Serial.flush();
        }
        digitalWrite(LEDpinRed,LOW);
   }
}

void RequestData(int node, byte request) {

    // request temperature data from the other Jeenodes
    requesttx.Jeenode = node;
    requesttx.Requestcode = request;
    if (rf12_canSend()) {
        rf12_recvDone();
        rf12_sendStart(0, &requesttx, 2);       
        rf12_sendWait(2);                                //wait for RF to finish sending while in standby mode
    }       

}

SensorNode:

#include 
#include 
#include 
const int  ONE_WIRE_BUS = 7;                        // DIO4 on je JeeNode = D7 on Arduino
const int  sensorPWR = A3;                          // Power pin is connected to AIO4 on the JeeNode = A3 on Arduino
const int  ReadInterval = 15;                       // Duration of sleep between measurements, in minutes
const int  debugging = 1;

OneWire oneWire(ONE_WIRE_BUS);                      // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);                // Pass our oneWire reference to Dallas Temperature.

#include 

// Specify data and clock connections and instantiate SHT1x object
const int dataPin = 6;                              // DIO3 on the JeeNode
const int clockPin = A2;                            // AIO3 on the JeeNode
SHT1x sht1x(dataPin, clockPin);                     // Create a sht1x instance
float Temp_SHT;                                     // Variable to store the measured temperature
float RV_SHT;                                       // Variable to store the measured humidity

// interrupt handler for JeeLabs Sleepy power saving
ISR(WDT_vect) { Sleepy::watchdogEvent(); }  

const int myNodeID = 2;                             // RF12 node ID in the range 1-30
const int network = 210;                            // RF12 Network group
const int freq = RF12_868MHZ;                       // Frequency of RFM12B module
byte myId;                                          // remember my own node ID

const int LEDpin = 4;                               // a LED is connected between DIO1 and GND on the JeeNode

//############################################################################################################
//Data Structure to be sent
typedef struct {
    int nodeID;     // ID of the node
    int supplyV;    // Supply voltage
    int temp0;      // Temperature reading
    int temp1;      // Temperature 2 reading
    int tempSHT;    // Temperature 3 reading
    int humiSHT;    // Humidity reading
} Payload;
Payload temptx;     // Instantiate a Payload object

typedef struct {
    byte Jeenode;       // identify the Jeenode
    byte Requestcode;   // identify the needed response
} RequestPayload;
RequestPayload requesttx;

int numSensors;     // Variable used to determine the amount of parallel DS18B20 sensors in the network
//############################################################################################################

void setup() {
    Serial.begin(9600);


    myId = rf12_initialize(myNodeID,freq,network);          // Initialize RFM12 with settings defined above
    //myId = rf12_configSilent();                       // Initialize RFM12 with its internal settings
    Serial.print("myId = ");Serial.println(myId);
    rf12_configDump();                              // Print the settings to the serial port
    Serial.flush();
    rf12_control(0xC000);                           // Adjust low battery voltage to 2.2V
    rf12_sleep(0);                                  // Put the RFM12 to sleep
    PRR = bit(PRTIM1);                              // only keep timer 0 going
    ADCSRA &= ~ bit(ADEN);                          // Disable the ADC
    bitSet (PRR, PRADC);                            // Power down ADC
    bitClear (ACSR, ACIE);                          // Disable comparator interrupts
    bitClear (ACSR, ACD);                           // Power down analogue comparator
    pinMode(sensorPWR, OUTPUT);                     // set power pin for DS18B20 to output
    digitalWrite(sensorPWR, HIGH);                  // turn sensor power on
    Sleepy::loseSomeTime(50);                       // Allow 50ms for the sensor to be ready
    sensors.begin();                                // Activate the one-wire connection to the DS18B20
    numSensors=sensors.getDeviceCount() + 2;        // Count DS18B20 sensors in the network + 2 for SHT1x sensor

    pinMode(LEDpin, OUTPUT);                        // Set the LEDpin as an output
    FlashLED(50);                                   // Flash the LED to confirm that Setup has executed
    Serial.println("SensorNode.ino");
    //TakeMeasurement();
}

void loop() {

    if (Serial.available() > 0) {
        // read the incoming byte:
        byte incomingByte = Serial.read();
        byte node = incomingByte - 48;
        if (node >= 1 && node <= 9) {
            TakeMeasurement();
        }
    }

    if (ReceiveData()==true) {
        TakeMeasurement();
    }
}


//--------------------------------------------------------------------------------------------------
// Send payload data via RF
//--------------------------------------------------------------------------------------------------
static void rfwrite(){
    rf12_sleep(-1);                                 // wake up RF module
    while (!rf12_canSend())                         // wait until RF module is ready to send
    rf12_recvDone();                                // check to see if no packages are being received
    rf12_sendStart(0, &temptx, numSensors*2 + 2 + 2);   // send two bytes for battery + 2*numSensors for the sensors
    rf12_sendWait(2);                               // wait for RF to finish sending while in standby mode (mode = 2)
    rf12_sleep(0);                                  // put RF module to sleep
}

//--------------------------------------------------------------------------------------------------
// Reads current voltage
//--------------------------------------------------------------------------------------------------
void vccRead(){
    bitClear(PRR, PRADC);                           // power up the ADC
    ADCSRA |= bit(ADEN);                            // enable the ADC
    Sleepy::loseSomeTime(10);                       // wait for 10ms
    temptx.supplyV = map(analogRead(6), 0, 1023, 0, 660);   // read the voltage
    ADCSRA &= ~ bit(ADEN);                          // disable the ADC
    bitSet(PRR, PRADC);                             // power down the ADC
}

//--------------------------------------------------------------------------------------------------
// Flash the LED for an amount of ms
//--------------------------------------------------------------------------------------------------
void FlashLED(int ms){
    digitalWrite(LEDpin, 1);                        // turn LED on
    Sleepy::loseSomeTime(ms);                       // wait for x ms
    digitalWrite(LEDpin, 0);                        // turn LED off
}


boolean ReceiveData() {
    if (rf12_recvDone() && rf12_crc == 0){
        const RequestPayload* p = (const RequestPayload*) rf12_data;
        Serial.println("");
        Serial.println("Received payload: ");
        Serial.print("RequestPayload.Jeenode = "); Serial.println(p->Jeenode);
        Serial.print("RequestPayload.Requestcode = "); Serial.println(p->Requestcode);
        Serial.println("*************************");
        Serial.flush();
        if (p->Jeenode == myId) {
            Serial.println("That's me!!! I'll sent the data out!!");
            return true;
        }
        else {
            return false;
        }

    }
    else {
        return false;
    }
}

void TakeMeasurement() {
        digitalWrite(LEDpin, 1);                        // turn the LED on to signal a measurement and transmission

        temptx.nodeID = myNodeID;

        pinMode(sensorPWR, OUTPUT);                     // set power pin for DS18B20 to output
        digitalWrite(sensorPWR, HIGH);                  // turn DS18B20 sensor on
        Sleepy::loseSomeTime(10);                       // Allow 10ms for the sensor to be ready

        //DS18B20 readings:
        sensors.requestTemperatures();                  // Send the command to get temperatures
        temptx.temp0=(sensors.getTempCByIndex(0)*100.); // read sensor 0: 20.45deg * 100 => 2045
        temptx.temp1=(sensors.getTempCByIndex(1)*100.); // read sensor 1: 20.45deg * 100 => 2045
        temptx.temp0 = 0;
        temptx.temp1 = 0;

        //SHT11 readings:
        temptx.tempSHT = (sht1x.readTemperatureC()*100.);// read temperature from SHT1x sensor
        temptx.humiSHT = sht1x.readHumidity();          // read humidity from SHT1x sensor

        if (temptx.tempSHT < 0) {
            temptx.tempSHT = -1;
        }

        if (temptx.humiSHT < 0) {
            temptx.humiSHT = -1;
        }

        digitalWrite(sensorPWR, LOW);                   // turn sensors off
        pinMode(sensorPWR, INPUT);                      // set sensorPWR to input before sleeping: saves power
        vccRead();                                      // Read current supply voltage
        Serial.println("Send payload: ");
        Serial.print("temptx.nodeID = "); Serial.println(temptx.nodeID);
        Serial.print("temptx.temp0 = "); Serial.println(temptx.temp0);
        Serial.print("temptx.temp1 = "); Serial.println(temptx.temp1);
        Serial.print("temptx.tempSHT = "); Serial.println(temptx.tempSHT);
        Serial.print("temptx.humiSHT = "); Serial.println(temptx.humiSHT);
        Serial.print("temptx.supplyV = "); Serial.println(temptx.supplyV);
        Serial.println("*************************");
        Serial.println("");
        Serial.flush();

        rfwrite();                                      // Send data via RF

        digitalWrite(LEDpin, 0);                        // Turn the LED off after transmission

        //for(byte j = 0; j < ReadInterval; j++) {      // Enter low power mode for x seconds
        //  Sleepy::loseSomeTime(1000);             //valid range 16-65000 ms
        //}
}

Replies (6)

RE: package contents are wrong - Added by lightbulb over 3 years ago

@Alban_T,

I am lazily on my phone reading this, so its hard to read all the code, and I’m not too familiar with SHT1x, but none the less, this simply looks like a typecasting problem.

I see your payload for SHT is something like:

int tempSHT; // Temperature 3 reading
int humiSHT; // Humidity reading

i cannot see your .H for SHT1x, but I bet its not an , so you may be suffering with a truncation problem.

you may do well to specifically cast your results to the expected type.

like I say - i’m on my phone so i cant make much sense of all the code.

RE: package contents are wrong - Added by Alban_T over 3 years ago

Hi,

That was my first idea as well but that doesn’t explain why the other SHT on node 1 returns the correct value running the exact same sketch.
Also the fact that the serial port for the sensor node returns the value from the struct correctly.
About the : The SHT returns a float which I multiply by 100 so 21.651 degrees becomes 21.651*100=2165.1 when put into an it would be 2165

To make sure I hardcoded interger values in the code and the result is still the same:

//DS18B20 readings:
        sensors.requestTemperatures();                  // Send the command to get temperatures
        temptx.temp0=(sensors.getTempCByIndex(0)*100.); // read sensor 0: 20.45deg * 100 => 2045
        temptx.temp1=(sensors.getTempCByIndex(1)*100.); // read sensor 1: 20.45deg * 100 => 2045
        temptx.temp0 = 0;
        temptx.temp1 = 0;

        //SHT11 readings:
        temptx.tempSHT = (sht1x.readTemperatureC()*100.);// read temperature from SHT1x sensor
        temptx.humiSHT = sht1x.readHumidity();          // read humidity from SHT1x sensor

        temptx.tempSHT = 2613;
        temptx.humiSHT = 66;

The sensor sends:

Received payload: 
RequestPayload.Jeenode = 2
RequestPayload.Requestcode = 1
*************************
That's me!!! I'll sent the data out!!
Send payload: 
temptx.nodeID = 2
temptx.temp0 = 0
temptx.temp1 = 0
temptx.tempSHT = 2613
temptx.humiSHT = 66
temptx.supplyV = 270
*************************

The receiver recieves:

RequestData(2,1)

Received payload: 
temptx.nodeID = 2
temptx.temp0 = 0
temptx.temp1 = 0
temptx.tempSHT = -23842
temptx.humiSHT = 25543
temptx.supplyV = 270
*************************
Request took 1537ms

RE: package contents are wrong - Added by lightbulb over 3 years ago

@Alban_T,

Appols for delay - been busy. Anyhow - still on phone so still hard to read, but your problem is probably here:

rf12_sendStart(0, &temptx, numSensors*2 + 2 + 2); // send two bytes for battery + 2*numSensors for the sensors

You packet should not be “variable” length unless you have somewhere to describe the “schema”, which i normally do in the first few “bits”.
Try setting your packet length using sizeof initially and take the variability out of the equation.

You may well review sizeof(int) and work from there - your probably just sending out whatever is in memory at those last few bytes….

—lightbulb

RE: package contents are wrong - Added by Alban_T over 3 years ago

Damn…. I think you are right! I’m away from home now so I can’t test it yet but it is true that I didn’t actually connect any DS18B20 on the node that is failing so it would make sense that numSensors will be 0 instead of the expected 2.
I’ll give it a go when I’m back home.
Thanks!

RE: package contents are wrong - Added by Alban_T over 3 years ago

Thanks “lightbulb”
That line was still there from the code I adapted my sketch from. Missed that completely :(
numSensors=4; did the trick

RE: package contents are wrong - Added by lightbulb over 3 years ago

Your welcome - glad your back and running again :)

—lightbulb

    (1-6/6)