Build a simple solar-powered weather station with LoRa & The Things Stack (part 1)

Please use the thread below to discuss the related blog post:

1 Like

Hello, can you tell me how to decode the code so I can use it in Cayenne?
I read there manual how to do that but I’m stuck on it now.
Hope someone can help me out.

Regards Reinier

Hello @reivis welcome to the balena forums! And happy to see you interested on trying this project!

I’m sure you can use it on Cayenne. I see several possibilities:

  1. Change the payload to Cayenne LLP. To this, you should update the Arduino sketch to prepare data into Cayenne format (e.g. CayenneLPP | The Things Network) . Maybe you can PR a new sketch for the project?
  2. Make an integration using webhooks or MQTT with Cayenne, once data is received and decoded.

Does it make sense to you? Let us know if we can help you more :slight_smile:

Hello, thank you for presenting this interesting project. Certainly a beginner’s question: Could additional sensors be integrated? For example one (or more) DS18b20, (or soil moisture sensor)? Can you even have 2 libraries for temperature? And if so, how?

1 Like

Hello @J_Paul welcome to the balena forums :slight_smile:

I’m not an expert on the Heltec Cubecell devices but i’m sure that you can find examples, such as this one here.

Let us know if that works!

Still stuck on how to convert the sketch to CayenneLPP. I have installed the CayenneLPP libary in the Arduino IDE and than…?

Hello @reivis did you adapt the code to something like this? CayenneLPP | The Things Network

let me know what errors do you get!

I don’t get any errors because I don’t know what steps I must take to convert the code in Arduino IDE.
I have installed the LPP libary and then …???

@reivis could you please share your Arduino code?

#include <LoRaWan_APP.h>
#include <Arduino.h>
#include <Seeed_BME280.h>
#include <Wire.h>
#include “ttnparams.h”

bool ENABLE_SERIAL = false; // enable serial debug output here if required
uint32_t appTxDutyCycle = 1200000; // the frequency of readings, in milliseconds(set 300s)

uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;
DeviceClass_t loraWanClass = LORAWAN_CLASS;
bool overTheAirActivation = LORAWAN_NETMODE;
bool loraWanAdr = LORAWAN_ADR;
bool keepNet = LORAWAN_NET_RESERVE;
bool isTxConfirmed = LORAWAN_UPLINKMODE;
uint8_t appPort = 2;
uint8_t confirmedNbTrials = 4;

int temperature, humidity, batteryVoltage, batteryLevel;
long pressure;

BME280 bme280;

static void prepareTxFrame( uint8_t port )
{
// This enables the output to power the sensor
pinMode(Vext, OUTPUT);
digitalWrite(Vext, LOW);
delay(500);

if(!bme280.init()){
if(ENABLE_SERIAL){
Serial.println(“Device error!”);
}
}

// This delay is required to allow the sensor time to init
delay(500);

temperature = bme280.getTemperature() * 100;
humidity = bme280.getHumidity();
pressure = bme280.getPressure();

Wire.end();

// Turn the power to the sensor off again
digitalWrite(Vext, HIGH);

batteryVoltage = getBatteryVoltage();
batteryLevel = (BoardGetBatteryLevel() / 254) * 100;

appDataSize = 12;
appData[0] = highByte(temperature);
appData[1] = lowByte(temperature);

appData[2] = highByte(humidity);
appData[3] = lowByte(humidity);

appData[4] = (byte) ((pressure & 0xFF000000) >> 24 );
appData[5] = (byte) ((pressure & 0x00FF0000) >> 16 );
appData[6] = (byte) ((pressure & 0x0000FF00) >> 8 );
appData[7] = (byte) ((pressure & 0X000000FF) );

appData[8] = highByte(batteryVoltage);
appData[9] = lowByte(batteryVoltage);

appData[10] = highByte(batteryLevel);
appData[11] = lowByte(batteryLevel);

if(ENABLE_SERIAL){
Serial.print("Temperature: ");
Serial.print(temperature / 100);
Serial.print(“C, Humidity: “);
Serial.print(humidity);
Serial.print(”%, Pressure: “);
Serial.print(pressure / 100);
Serial.print(” mbar, Battery Voltage: “);
Serial.print(batteryVoltage);
Serial.print(” mV, Battery Level: “);
Serial.print(batteryLevel);
Serial.println(” %”);
}
}

void setup()
{

boardInitMcu();
if(ENABLE_SERIAL){
Serial.begin(115200);
}
deviceState = DEVICE_STATE_INIT;
LoRaWAN.ifskipjoin();

}

void loop()
{
switch( deviceState )
{
case DEVICE_STATE_INIT:
{
printDevParam();
LoRaWAN.init(loraWanClass,loraWanRegion);
deviceState = DEVICE_STATE_JOIN;
break;
}
case DEVICE_STATE_JOIN:
{
LoRaWAN.join();
break;
}
case DEVICE_STATE_SEND:
{
prepareTxFrame( appPort );
LoRaWAN.send();
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE:
{
// Schedule next packet transmission
txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
LoRaWAN.cycle(txDutyCycleTime);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP:
{
LoRaWAN.sleep();
break;
}
default:
{
deviceState = DEVICE_STATE_INIT;
break;
}
}
}

Hello @reivis you should add the Cayenne Library (Cayenne LPP). More information here CayenneLPP | The Things Stack for LoRaWAN

Here you have an example Cayenne_encoding - #20 by naidu.hemanth9 - Helped - myDevices Cayenne Community

And here more information about the Cayenne Payload Cayenne Docs

Hi,

I have just a quick question. I have successfully built a weather station according to this guide. Working fine so far. I just stumbled over the battery level. It just shows 0 or 1 (when fully loaded) but is supposed to show a percentage …

I did not alter anything at the script nor the payload… Any hints?

1 Like

Hello @fhansi welcome to the balena.io community!

could you please confirm the value when the battery it’s not fully loaded? i think what is on Grafana is a visualization of the percentage of this value, but i’m not totally sure.

Let me know if this makes sense :slight_smile:

hi,

well in the payload I see this:

“decoded_payload”: {
“battery”: 4.16,
“battery_level”: 0,
“humidity”: 34,
“pressure”: 1005.04,
“temperature”: 12.87
},

I do not visualize via grafana…

Frank

@fhansi the source for this information is the firmware on the Heltec board. It’s returned as a value from the BoardGetBatteryLevel() function, then added to the LoRA packet along with all the other data.

You’d have to figure out where it’s getting lost, or even if it’s being reported correctly to begin with. I’d suggest starting with adding some debug lines to the Arduino to print the output to the log. You could also figure out the percentage yourself using the battery voltage levels based on a table like this one: Lipo Voltage Chart: Show the Relationship of Voltage and Capacity - Ampow Blog

1 Like