1

I use a sensor to measure the temperature. This is returned as float. I feed this float using typecasting (int) to a blink function. This works fine.
But the next is step is using this same unchanged integer in a struct and send it over 433MHz using RadioHead. Here the integer is no longer an integer and it never gets sent.

When I hard code the sensor measurement value, it works. When I hard code the value in the struct it works. When I hard code the value anywhere it works.

My assumption is: when the blink works it must be an integer. When sending a hard coded integer works it must also send the measured value confirmed to be an integer. What am I missing here?

The chip is an ATtiny85
The sensor is a DS18B20
TinyHead, my light RadioHead version: https://gitlab.com/thijsvanulden/TinyHead

This is the Logic Analyzer view of what happens measured on the Data pin of the 433MHz transmitter. So something is happening at least. I can't find an Analyzer 'plugin' to translate the message coded in RadioHead, it's not Manchester encoding as it seems.

logic analyzer

Memory Usage -> http://bit.ly/pio-memory-usage
DATA:    [========  ]  75.8% (used 388 bytes from 512 bytes)
PROGRAM: [========= ]  86.4% (used 7080 bytes from 8192 bytes)

#include <Arduino.h>
#include <util/delay.h>
#include <OneWire.h>
#include <RH_ASK.h>
#include <DallasTemperature.h>

#define TICKLE_ID 0

#define ONE_WIRE_BUS 2

#define RADIOHEAD_BAUD 2000
#define RADIOHEAD_TX_PIN 1
#define RADIOHEAD_RX_PIN -1

#define LEDPIN 0

struct tickle {
  uint16_t id = TICKLE_ID;
  uint16_t value1;
  uint16_t value2;
};

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
RH_ASK driver(RADIOHEAD_BAUD, RADIOHEAD_RX_PIN, RADIOHEAD_TX_PIN);

void blink(int repeat) {
  for (int i = 0; i < repeat; i++) {
    digitalWrite(LEDPIN, HIGH);
    _delay_ms(100);
    digitalWrite(LEDPIN, LOW);
    _delay_ms(100);
  }
}

void senddata(float temperatuur) {
  blink((int) temperatuur); // this always works
  struct tickle package; // make a Tickle package
  package.id = TICKLE_ID; // hard-coded device ID
  package.value1 = 0; // any positive int up to 2^16
  package.value2 = temperatuur * 100; // any positive int up to 2^16
  driver.send((uint8_t *)&package, sizeof(package));
  driver.waitPacketSent(); // wait for it ~Barney
}

void setup() {
  pinMode(LEDPIN, OUTPUT);
  digitalWrite(LEDPIN, HIGH);
  sensors.begin();
  driver.init();
  _delay_ms(100);
  digitalWrite(LEDPIN, LOW);
}

void loop() {
  sensors.requestTemperatures();
  _delay_ms(100);
  senddata(sensors.getTempCByIndex(0)); // hard coded 17.07 works
  _delay_ms(10000);
}
22
  • Which arduino board do you use? The OneWire and DallasTemperature require some memory, but the RadioHead requires a lot of memory. Commented Jan 15, 2019 at 22:21
  • 1
    Is it possible you think you are sending three bytes of data while you might actually be sending six bytes of data. Commented Jan 16, 2019 at 5:24
  • 1
    @Thijs I think I did not read it very well and was rude, my apologies. Can you do a test: fool the compiler to make it think that getTempCByIndex is used, but send a constant. In the function senddata: convert it: uint16_t t = temperature; get rid of it: t /= 10000; add a constant: t += 1789; fill the package: package.value2 = t;. Linking the getTempCByIndex function into the binary might be too much for the ram usage. Commented Jan 16, 2019 at 21:08
  • 1
    Casting values is like telling the compiler "don't mind what these memory locations were, now I want you to treat them differently". So, you used 6 bytes of memory to store 3 uint16_t values. Then you told the compiler to look at the 6 bytes of memory as if they were uint8_t values. You further cemented your intentions by specifying the "size" of the values. That is, the size of function returned that you had used 6 bytes of memory for the storage of the 3 uint16_t variables or, as you casted them, 6 uint8_t variables. Commented Jan 17, 2019 at 15:21
  • 1
    In this line: driver.send((uint8_t *)&package, sizeof(package)); Commented Jan 18, 2019 at 3:22

1 Answer 1

0

Changes made as suggested by @Jot

    void senddata(float temperatuur) {
      temperatuur = (uint16_t) temperatuur;
      blink(temperatuur);
      struct tickle package; // make a Tickle package
      package.id = (uint16_t) TICKLE_ID; // hard-coded device ID
      package.value1 = (uint16_t) 0; // any positive int up to 2^16
      package.value2 = (uint16_t) 100; // any positive int up to 2^16
    
      blink(sizeof(package));
      driver.send((uint8_t *)&package, sizeof(package));
      driver.waitPacketSent(); // wait for it ~Barney
    }

Working code, the end result
You may need to skip the Powernap code, it's a sleep library for ATtiny85. And I use the TinyHead library for 433MHz. The OneWire interaction with the sensors is 'borrowed' from http://www.nerdkits.com/forum/thread/2849/ so please send the beer and kudo's there.

    #include <Arduino.h>
    #include <util/delay.h>
    #include <OneWire.h>
    #include <RH_ASK.h>
    #include <powernap.h>
    
    #define TICKLE_ID 0
    //
    #define ONE_WIRE_BUS 2
    //
    #define RADIOHEAD_BAUD 2000
    #define RADIOHEAD_TX_PIN 1
    #define RADIOHEAD_RX_PIN -1
    
    #define LEDPIN 0
    
    struct tickle {
      uint16_t id = TICKLE_ID;
      uint16_t value1;
      uint16_t value2;
    };
    
    Napper napper;
    OneWire TemperatureSensor(2);
    RH_ASK driver(RADIOHEAD_BAUD, RADIOHEAD_RX_PIN, RADIOHEAD_TX_PIN);
    
    void blink(int repeat) {
      for (int i = 0; i < repeat; i++) {
        digitalWrite(LEDPIN, HIGH);
        napper.delay(100);
        digitalWrite(LEDPIN, LOW);
        napper.delay(100);
      }
    }
    
    void senddata(float temperatuur) {
      blink((int) temperatuur);
      struct tickle package; // make a Tickle package
      package.id = TICKLE_ID; // hard-coded device ID
      package.value1 = 0; // any positive int up to 2^16
      package.value2 = temperatuur * 100; // any positive int up to 2^16
    
      blink(sizeof(package));
      driver.send((uint8_t *)&package, sizeof(package));
      driver.waitPacketSent(); // wait for it ~Barney
    }
    
    void setup() {
      pinMode(LEDPIN, OUTPUT);
      digitalWrite(LEDPIN, HIGH);
      driver.init();
      napper.setup();
      napper.delay(100);
      digitalWrite(LEDPIN, LOW);
    }
    
    void loop() {
      byte i;
      byte data[12];
      int16_t raw;
      float celsius, fahrenheit;
    
      TemperatureSensor.reset();       // reset one wire buss
      TemperatureSensor.skip();        // select only device
      TemperatureSensor.write(0x44);   // start conversion
    
      delay(1000);                     // wait for the conversion
    
      TemperatureSensor.reset();
      TemperatureSensor.skip();
      TemperatureSensor.write(0xBE);   // Read Scratchpad
      for ( i = 0; i < 9; i++) {       // 9 bytes
        data[i] = TemperatureSensor.read();
      }
    
      // Convert the data to actual temperature
      raw = (data[1] << 8) | data[0];
      celsius = (float)raw / 16.0;
      napper.delay(100);
      senddata(celsius);
      napper.napminutes(1);
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.