Help with code for Anemometer and BME280 in Rpi 3


#1

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)


#2

For anemometer, send the sensor data to cayenne using https://github.com/myDevicesIoT/Cayenne-MQTT-Python.
for BME280 use this code https://pypi.org/project/RPi.bme280/ 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


#3

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


#4

Here are the docs for the API http://mydevices.com/cayenne/docs/cayenne-mqtt-api/


#5

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.


#6

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


#7

can you share the code you are using?


#8

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)


#9

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()

#10

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

Oscar


#11

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()

#12

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


#13

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


#14

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


#15

does this code give you correct reading?


#16

Yes it does.

Oscar


#17

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()

#18

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


#19

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()

#20

…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