Help with code for Anemometer and BME280 in Rpi 3

Dear Community,
I m a newbie and would like to implement an anemometer and BME280 sensor to my weather station project.
Regarding the anemometer, the code I show here is from our colleagues of projects.raspberrypi.org. In this approach, the Rpi detects via GPIO pin (the anemometer has 2 wires, one goes to GPIO and the other to GND), how many times the reed switch within the anemometer is triggered (twice for a complete rotation) and then, by counting and timing these signals, the speed of the wind is calculated. The gpiozero library is used in this project. The code is attached below.
I beg for a good samaritan to give me a hand with this code to adapt it to MQTT and be compatible with cayenne. Any other way to find a solution is welcome…(e.g. use other gpio library and end with gpio.cleanup, etc).

…I also beg for the same or another good samaritan, to share a code to connect BME280 (temp, humidity and pressure sensor) via MQTT protocol to cayenne…

Many many thanks in advance,

Oscaranemometer.txt (1.3 KB)

For anemometer, send the sensor data to cayenne using GitHub - myDevicesIoT/Cayenne-MQTT-Python: Python Library for Cayenne MQTT API.
for BME280 use this code RPi.bme280 ¡ PyPI to get data and use the above cayenne Python library to send data.
Make sure to use the correct data types Data types for Cayenne MQTT API

Thanks Shramik, but I need some more detail to adapt and send data via MQTT to cayenne, because I don t see clearly how is done with the examples provided in those links.

Oscar

Here are the docs for the API Cayenne Docs

You have to use client.virtualWrite(1, x) where 1 is the channel and x is the data to be sent. so in the cayenne example, you have to add anemometer and BME280 code in it.

1 Like

Thanks again Shramik.
Using the example file now I get the read of the anemometer in cayenne dashboard every 10 seconds BUT first read is 0 (0 secs), second read (after 10 secs) is an individual real read (the one I want), BUT third value (after 20 secs of running) is the result obtained in second read added to the current one…and so on in the following reads.
Please, I don t see the modifications I need to do in the script to get every 10 secs an invidual result and not a summatory function I am getting now instead.
Thanks again,
Oscar

can you share the code you are using?

Sure! I really appreciate your interest Shramik. The problem I see in the code might be to establish a fixed interval to count the number of spins of the anemometer (and then do the calculations to get the speed), but in true, I m lost…

Thanks,

Oscar

testanemometer10s.txt (1.6 KB)

can you make this change and try again:

if (time.time() > timestamp + wind_interval):
       wind_count = 0
        x = calculate_speed(wind_interval)
        print(x)
        client.windspeedWrite(1,x)
        timestamp = time.time()

Hi again. Unfortunately it doesn t work and keeps adding the speed of the last measure in each new value.

Oscar

Add the below code and share the output from the terminal here.

if (time.time() > timestamp + wind_interval):
       wind_count = 0
        x = calculate_speed(wind_interval)
        print("x value is" + x )
        client.windspeedWrite(1,x)
        timestamp = time.time()

ok. As it is (wind_count = 0 is not in line with the rest of the code below) returns:

pi@raspberrypi:~/estasio_meteo/wind $ python3 testwindnewMQTTmod3_1.py
File “testwindnewMQTTmod3_1.py”, line 50
x = calculate_speed(wind_interval)
^
IndentationError: unexpected indent

If I move wind_count = 0 to be in line with the rest of the code below:

pi@raspberrypi:~/estasio_meteo/wind $ python3 testwindnewMQTTmod3_1.py
Connecting to mqtt.mydevices.com:8883
Traceback (most recent call last):
File “testwindnewMQTTmod3_1.py”, line 51, in
print(“x value is” + x )
TypeError: Can’t convert ‘float’ object to str implicitly

Oscar

replace with print("x value is " + str(x))

Now says that speed is 0.0 in each read:

x value is 0.0
PUB v1/de4c7a50-2a13-11e9-810f-075d38a26cc9/things/ce58c7a0-2c63-11e9-9c33-75e6b356cec4/data/1
wind_speed,kmh=0.0

Oscar

does this code give you correct reading?

Yes it does.

Oscar

try this code.

#!/usr/bin/env python
import cayenne.client
from gpiozero import Button
import time
import logging

import math

MQTT_USERNAME  = ""
MQTT_PASSWORD  = ""
MQTT_CLIENT_ID = ""

wind_count = 0 # counts how many half-rotations

radius_cm = 9.0 # radius in cm of the anemometer

wind_interval = 5 # how often (secs) to report speed

ADJUSTMENT = 1.18 # adjustment of the anemometer given by the manufacturer

# The callback for when a message is received from Cayenne.
def on_message(message):
    print("message received: " + str(message))
    # If there is an error processing the message return an error string, otherwise return nothing.

client = cayenne.client.CayenneMQTTClient()
client.on_message = on_message
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, loglevel=logging.INFO)

# every half-rotation, add 1 count

def spin():
 
    global wind_count

    wind_count = wind_count + 1

    # print("spin" + str(wind_count))



# calculate the wind speed

def calculate_speed(time_sec):

        global wind_count

        circumference_cm = (2 * math.pi) * radius_cm

        rotations = wind_count / 2.0

        dist_km = (circumference_cm * rotations) / 100000.0 # divided by cm in a km

        km_per_sec = dist_km / time_sec

        km_per_hour = km_per_sec * 3600 # multiplied by secs in an hour

        return km_per_hour * ADJUSTMENT



def reset_wind():

    global wind_count

    wind_count = 0

    # recommended function to reset the wind_count to zero when assembling the weather station


wind_speed_sensor = Button(5)

wind_speed_sensor.when_pressed = spin


i=0
timestamp = 0

# loop to measure wind speed and report at 5 secs interval
while True:
        client.loop()
        if (time.time() > timestamp + 10):
                wind_count = 0
                x = calculate_speed(wind_interval)
                client.virtualWrite(1,x)
                print(x)
                timestamp = time.time()

Hi Shramik, thank you for your willingness.

I say in advance that every time I test your new code, I run the anemometer.txt that I know it works before just to check that everything is well connected.

This time, after running your last code, I get:

0.0
PUB v1/de4c7a50-2a13-11e9-810f-075d38a26cc9/things/ce58c7a0-2c63-11e9-9c33-75e6b356cec4/data/1
0.0

So, it doesn t detect the spins/wind speed of the anemometer. As usual, however, I see in cayenne dashboard a 0.0 icon (channel1).

Really appreciate your help…

Oscar

i am really sorry for making such a stupid mistake. try this code.

# loop to measure wind speed and report at 5 secs interval
while True:
        client.loop()
        if (time.time() > timestamp + 10):
                x = calculate_speed(wind_interval)
                client.virtualWrite(1,x)
                print(x)
                wind_count = 0
                timestamp = time.time()

…At last, I m glad to say IT WORKS.

I m gonna add some notes to the code and upload it here for the rest of community.

Thanks again Shramik!

Oscar