Jump to content

Recommended Posts

Posted

Hi I found next script from git:

https://github.com/Vitalik-Samets/DHT11-Python-library-Orange-PI

It working OK.

But I faced with problem how to upload my data to https://thingspeak.com

 

With next code from git: https://github.com/magiccow/mqtt-client I'm able to upload constant data to my channel..

BUt if I want to put in python code varible it do not want to uplad data.

Can someone help me how to do?

#import RPi.GPIO as GPIO
import dht11
import time
import datetime
import paho.mqtt.client as mqtt



# initialize GPIO
#gpio.setwarnings(False)
#gpio.setmode(GPIO.BCM)
PIN2 = port.PA6
gpio.init()
#gpio.cleanup()

def fun1():
    fun1.var = result.temperature
    print(fun1.var)


# read data using pin 14
instance = dht11.DHT11(pin=PIN2)
#result = instance.read()
channelId = "myid"         # Put your channel ID here,i.e.. the number from the URL, https://thingspeak.com/channels/285697
apiKey = "mykey"  				 # Put the API key here (the Write API Key from the API Keys tab in ThingSpeak)
client = mqtt.Client()
client.connect("mqtt.thingspeak.com",1883,60)
while True:
    result = instance.read()
    if result.is_valid():
        print("Last valid input: " + str(datetime.datetime.now()))
        print("Temperature: %d C" %result.temperature)
        print("Humidity: %d %%" % result.humidity)
        client.publish("channels/%s/publish/%s" % (channelId,apiKey), "field1=fun1()&field2=1013")
        fun1()
        client.loop(2)
time.sleep(1)

 

Problem is in line:

client.publish("channels/%s/publish/%s" % (channelId,apiKey), "field1=fun1()&field2=1013")

With part ..."field1=fun1()

It do not want to send data, but if I put constant value it will upload to https://thingspeak.com

Where I makeing mistake..

Btw, is there someone who have full code what working on Orange PI, readinf the sensor + upload to https://thingspeak.com ?

Thx for help!

Posted

Hi,

 

I think your errors are only python (basic) errors. If you put fun1() between quotes, it is a text an not a function call. Do you know how to program in Python? Because, I don't understand fun1() definition. Maybe you should take time to look a short tutorial on Python, like: https://learnxinyminutes.com/docs/python/

If you want your funtion to return a value, you have to use the return keyword, and not print function that print values into the console. Moreover, what is fun1.var? If you want to declare a local variable, in python you just have to state var = result.temperature. Then, result is unknown in the context of fun1. You have to pass it as a parameter. I stop here, but you really need to look at some basic documentation about programming and about Python language if this is the langauge you want to use.

Posted

Hi, and thx for help..

FIrst of all, I do not know python, neither I do not want to enter in this language..

I try to quote it but the results are same..

Thats why Im asking for help to change the code to be able to use the script..

The fun1() logic is just to show that it returning a value normaly but when I call it it do not want to upload that value!

 

Posted

I didn't try these libraries, but here is what I would write according to your code and the links you give:

 

from pyA20.gpio import gpio
from pyA20.gpio import port

import dht11

import paho.mqtt.client as mqtt

import time
import datetime

#initialize GPIO
PIN2 = port.PA6
gpio.init()

#read data using pin port.PA6
instance = dht11.DHT11(pin=PIN2)

channelId = "myid"         # Put your channel ID here,i.e.. the number from the URL, https://thingspeak.com/channels/285697
apiKey = "mykey"  				 # Put the API key here (the Write API Key from the API Keys tab in ThingSpeak)
client = mqtt.Client()
client.connect("mqtt.thingspeak.com",1883,60)

while True:
    result = instance.read()
    if result.is_valid():
        print("Last valid input: " + str(datetime.datetime.now()))
        print("Temperature: %d C" %result.temperature)
        print("Humidity: %d %%" % result.humidity)
        client.publish("channels/%s/publish/%s" % (channelId,apiKey), "temp="+str(result.temperature)+"&humidity="+str(result.himidity))
        client.loop(2)
	time.sleep(1)

The last line is not well displayed, it should only be shifted by 1 tab and not 2.

Posted
1 hour ago, Pol Isidor said:

FIrst of all, I do not know python, neither I do not want to enter in this language..

Well, then you should hire someone who does the job for you.... Or go for 'commercial' stuff which is programmed and does the stuff you need. No willingness to learn it and hope that someone other will do all the debug for you for free is IMHO a bit questionable.... 

 

 

Posted

@jeanrhum

Thx for code, but..

I tried your version but the correct form is like this:

client.publish("channels/369197/publish/S3990G19LH3TRFOQ", "field1=26&field2=1013")

 

root@orangepipc:~/temp# python sht11_ex*
  File "dht11_example.py", line 40
    client.publish("channels/%s/publish/%s" % (channelId,apiKey), "filed1="+str(result.temperature)+"&field2="+str(result.humidity))
    ^
IndentationError: unexpected indent

So it generating me an error..

I tried few combination..but I still where I was..

As you see, if I sned the numbers directly and not the variable then the data is showed in graphs.

Screenshot(1).thumb.png.6f48835ce2f2434a72b792b06714ba81.png

Any other suggestion?

Posted

I use pyGPIO instead of pyPA20 but it's more or less the same:

#import pyGPIO & mqtt client
from pyGPIO.gpio import gpio
from pyGPIO.gpio import port
import paho.mqtt.client as mqtt

#import dht11 
import dht11

import time
import datetime

channelId = "xxx"
apiKey = "xyz"
client = mqtt.Client()
client.connect("mqtt.thingspeak.com",1883,60)

PIN26 = port.GPIO7
gpio.init()

# read data using GPIO7
instance = dht11.DHT11(pin=PIN26)

while True:
	result = instance.read()
	if result.is_valid():
		client.publish("channels/%s/publish/%s" % (channelId,apiKey), "field1=" + str(result.temperature) + "&field2=" + str(result.humidity))

	time.sleep(5)

and it works without any issues... 

 

thingspeak.jpg.0a3b7bd189b4fda62edc167632bd9a25.jpg

 

As @jeanrhum suggested, you should understand the basics of python to do such projects... Doesn't need that much effort learn it.. ;) 

 

 

Posted
9 minutes ago, chwe said:

Doesn't need that much effort learn it.. ;)

 

Indeed, it took me 20 minutes while watching Youtube videos about cats.  @chwes initial recommendation is still the right one, he is just shamelessly promoting his GPIO project (I use it too ;)).

Posted

@chwe Thx for the code..

But I'm coping with a next problem:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    from pyGPIO.gpio import gpio
ImportError: No module named pyGPIO.gpio

I try to istall with:

pip install pyGPIO.gpio
pip install gpio
pip install pyGPIO
pip install RPi.GPIO

but without success.

Can yu help me?

Posted
3 minutes ago, chwe said:

When you read my whole last post (including link to the other thread) you'll find it out... :P 

Hmm..same..

I chose econd option when I complie the pyGPIO, Orange PI PC Plus, but I Have Orange PC and as I know the pin out is same..

error message is:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    from pyGPIO.gpio import gpio
ImportError: No module named pyGPIO.gpio
root@orangepipc:~/temp#

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    from pyGPIO.gpio import gpio
ImportError: No module named pyGPIO.gpio
root@orangepipc:~/temp# 

Any other advise?

Posted

Sorry now I see, that I can not install:

error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

I heve few errors while I compiling:

Quote

root@orangepipc:~/temp# cd pyGPIO
root@orangepipc:~/temp/pyGPIO# python setup.py install
running install
running build
running build_py
creating build
creating build/lib.linux-armv7l-2.7
creating build/lib.linux-armv7l-2.7/pyGPIO
copying pyGPIO/__init__.py -> build/lib.linux-armv7l-2.7/pyGPIO
creating build/lib.linux-armv7l-2.7/pyGPIO/gpio
copying pyGPIO/gpio/__init__.py -> build/lib.linux-armv7l-2.7/pyGPIO/gpio
running build_ext
Detected processor: sun8i (Probably Allwinner H2+/H3)
Unknown board
Automatic board detection failed or your board is not supported (yet).
You can use a pin mapping from one of our supported boards or abort the
installation. This is only recommended for experienced users!
Pin mapping might be false and the library does not work as expected!
[1]  OrangePi Zero
[2]  OrangePi Pc Plus
[3]  OrangePi Plus 2E
[4]  OrangePi Lite
[5]  A20-OLinuXino-MICRO
[6]  A20-OLinuXIno-LIME
[7]  A20-OLinuXIno-LIME2
[8]  NanoPi Duo
[9]  NanoPi Neo
[10] Abort
2
building 'pyGPIO.gpio.gpio' extension
creating build/temp.linux-armv7l-2.7
creating build/temp.linux-armv7l-2.7/pyGPIO
creating build/temp.linux-armv7l-2.7/pyGPIO/gpio
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/usr/include/python2.7 -c pyGPIO/gpio/gpio_lib.c -o build/temp.linux-armv7l-2.7/pyGPIO/gpio/gpio_lib.o
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/usr/include/python2.7 -c pyGPIO/gpio/gpio.c -o build/temp.linux-armv7l-2.7/pyGPIO/gpio/gpio.o
arm-linux-gnueabihf-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security build/temp.linux-armv7l-2.7/pyGPIO/gpio/gpio_lib.o build/temp.linux-armv7l-2.7/pyGPIO/gpio/gpio.o -o build/lib.linux-armv7l-2.7/pyGPIO/gpio/gpio.so
building 'pyGPIO.i2c' extension
creating build/temp.linux-armv7l-2.7/pyGPIO/i2c
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/usr/include/python2.7 -c pyGPIO/i2c/i2c_lib.c -o build/temp.linux-armv7l-2.7/pyGPIO/i2c/i2c_lib.o
In file included from pyGPIO/i2c/i2c_lib.c:34:0:
/usr/include/linux/i2c-dev.h:37:8: error: redefinition of ‘struct i2c_msg’
 struct i2c_msg {
        ^
In file included from pyGPIO/i2c/i2c_lib.c:33:0:
/usr/include/linux/i2c.h:68:8: note: originally defined here
 struct i2c_msg {
        ^
In file included from pyGPIO/i2c/i2c_lib.c:34:0:
/usr/include/linux/i2c-dev.h:89:7: error: redefinition of ‘union i2c_smbus_data’
 union i2c_smbus_data {
       ^
In file included from pyGPIO/i2c/i2c_lib.c:33:0:
/usr/include/linux/i2c.h:128:7: note: originally defined here
 union i2c_smbus_data {
       ^
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
root@orangepipc:~/temp/pyGPIO# cd ..
root@orangepipc:~/temp# python test*
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    from pyGPIO.gpio import gpio
ImportError: No module named pyGPIO.gpio
root@orangepipc:~/temp# apt-get install python-dev
Reading package lists... Done
Building dependency tree       
Reading state information... Done
python-dev is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
root@orangepipc:~/temp# python test*              
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    from pyGPIO.gpio import gpio
ImportError: No module named pyGPIO.gpio
root@orangepipc:~/temp# ^C
root@orangepipc:~/temp# ^C
root@orangepipc:~/temp# apt-get install arm-linux-gnueabihf-gcc
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package arm-linux-gnueabihf-gcc

Any idea why?

Posted

pyGPIO is based on pyA20, the only difference is that the pin mapping is adjusted to the supported boards (still in testing phase!).  I didn't test if it ends in conflicts when pyA20 is installed on the same system in parallel. But if you would follow @jeanrhum or @TonyMac32 recommendations (learning the basics of python) you should come to the conclusion that you can use pyA20 instead of pyGPIO (since you get your temperature and humidity readings on console when using pyA20) 

  1. replace pyGPIO with pyA20 (in my provided code snippet) 
  2. Correct the pin naming as you had it before
  3. test if it works 
  4. take some time to learn Python ;) 
Posted

@chwe

Thx mate..this is the solution..

At the end it looks like this:
 

from pyA20.gpio import gpio
from pyA20.gpio import port
import paho.mqtt.client as mqtt

#import dht11
import dht11

import time
import datetime

PIN2 = port.PA6
gpio.init()

channelId = "xxxxxxx"         # Put your channel ID here,i.e.. the number from the URL, https://thingspeak.com/channels/285697
apiKey = "xxxxxxxxxx"  # Put the API key here (the Write API Key from the API Keys tab in ThingSpeak)
client = mqtt.Client()
client.connect("mqtt.thingspeak.com",1883,60)

instance = dht11.DHT11(pin=PIN2)
gpio.init()

# read data using GPIO7
#instance = dht11.DHT11(pin=PIN26)

while True:
    result = instance.read()
    if result.is_valid():
        client.publish("channels/%s/publish/%s" % (channelId,apiKey), "field1=" + str(result.temperature) + "&field2=" + str(result.humidity))

    time.sleep(5)

 

Posted

And now it's time to learn Python.... :P 

 

Clean and comment the code so that it is easier to maintain for you. E.g. comments like #read data using GPIO7 aren't correct for your script and makes it confusing when you read this script in *whatever time it needs to forget what you've done in the past*. Same confused me in the beginning when you had:

On 22.11.2017 at 6:09 AM, Pol Isidor said:

#import RPi.GPIO as GPIO

Cause you don't use a RPi and therefore also not RPi.GPIO as GPIO

 

Then you could replace 'import time' with: 'from time import sleep' (hint: time.sleep(5) needs to be adjusted, cause you don't load the whole time module) to make it a little bit more 'lightweight'. Since you don't use 

print("Last valid input: " + str(datetime.datetime.now()))

anymore, I think you don't have to load the datetime module at all. And then you should test what happens when your orangepi loses contact to the DHT11 sensor (might be interesting to recognize that something goes wrong). Furthermore, you should think about why you get new datapoints every ~15-20 seconds but your while loop has only a sleep of 5 seconds. Seems that: if result.is_valid()... only happens in ~25% of the cases...

 

To summarize: Your script 'works' but it's not what I would call 'stable' (more something like: pre-alpha :P ). And now it's up to you to bring it in a better shape.... 

Posted

Yes yes, I agree with u...

I just post the "working solution". I will do the cleaning, and I'm totally understand what are u talking about..

Anyway, thx for help!

Posted (edited)

Again me with problem..

I changed the sensor to DHT22 2303 because I wanted bigger precision..

Now I found a code dht22.py:

Spoiler

 


import time
from pyA20.gpio import gpio
from pyA20.gpio import port


class DHT22Result:
    'DHT22 sensor result returned by DHT22.read() method'

    ERR_NO_ERROR = 0
    ERR_MISSING_DATA = 1
    ERR_CRC = 2

    error_code = ERR_NO_ERROR
    temperature = -1
    humidity = -1

    def __init__(self, error_code, temperature, humidity):
        self.error_code = error_code
        self.temperature = temperature
        self.humidity = humidity

    def is_valid(self):
        return self.error_code == DHT22Result.ERR_NO_ERROR


class DHT22:
    'DHT22 sensor reader class for Raspberry'

    __pin = 0

    def __init__(self, pin):
        self.__pin = pin

    def read(self):
        gpio.setcfg(self.__pin, gpio.OUTPUT)

        # send initial high
        self.__send_and_sleep(gpio.HIGH, 0.05)

        # pull down to low
        self.__send_and_sleep(gpio.LOW, 0.02)

        # change to input using pull up
        #gpio.setcfg(self.__pin, gpio.INPUT, gpio.PULLUP)
	gpio.setcfg(self.__pin, gpio.INPUT)
	gpio.pullup(self.__pin, gpio.PULLUP)


        # collect data into an array
        data = self.__collect_input()

        # parse lengths of all data pull up periods
        pull_up_lengths = self.__parse_data_pull_up_lengths(data)

        # if bit count mismatch, return error (4 byte data + 1 byte checksum)
        if len(pull_up_lengths) != 40:
            return DHT22Result(DHT22Result.ERR_MISSING_DATA, 0, 0)

        # calculate bits from lengths of the pull up periods
        bits = self.__calculate_bits(pull_up_lengths)

        # we have the bits, calculate bytes
        the_bytes = self.__bits_to_bytes(bits)

        # calculate checksum and check
        checksum = self.__calculate_checksum(the_bytes)
        if the_bytes[4] != checksum:
            return DHT22Result(DHT22Result.ERR_CRC, 0, 0)

        # ok, we have valid data, return it
        return DHT22Result(DHT22Result.ERR_NO_ERROR, 
			   (((the_bytes[2] & 0x7F)<<8)+the_bytes[3])/10.00,
			   ((the_bytes[0]<<8)+the_bytes[1])/10.00)


    def __send_and_sleep(self, output, sleep):
        gpio.output(self.__pin, output)
        time.sleep(sleep)

    def __collect_input(self):
        # collect the data while unchanged found
        unchanged_count = 0

        # this is used to determine where is the end of the data
        max_unchanged_count = 100

        last = -1
        data = []
        while True:
            current = gpio.input(self.__pin)
            data.append(current)
            if last != current:
                unchanged_count = 0
                last = current
            else:
                unchanged_count += 1
                if unchanged_count > max_unchanged_count:
                    break

        return data

    def __parse_data_pull_up_lengths(self, data):
        STATE_INIT_PULL_DOWN = 1
        STATE_INIT_PULL_UP = 2
        STATE_DATA_FIRST_PULL_DOWN = 3
        STATE_DATA_PULL_UP = 4
        STATE_DATA_PULL_DOWN = 5

        state = STATE_INIT_PULL_DOWN

        lengths = [] # will contain the lengths of data pull up periods
        current_length = 0 # will contain the length of the previous period

        for i in range(len(data)):

            current = data[i]
            current_length += 1

            if state == STATE_INIT_PULL_DOWN:
                if current == gpio.LOW:
                    # ok, we got the initial pull down
                    state = STATE_INIT_PULL_UP
                    continue
                else:
                    continue
            if state == STATE_INIT_PULL_UP:
                if current == gpio.HIGH:
                    # ok, we got the initial pull up
                    state = STATE_DATA_FIRST_PULL_DOWN
                    continue
                else:
                    continue
            if state == STATE_DATA_FIRST_PULL_DOWN:
                if current == gpio.LOW:
                    # we have the initial pull down, the next will be the data pull up
                    state = STATE_DATA_PULL_UP
                    continue
                else:
                    continue
            if state == STATE_DATA_PULL_UP:
                if current == gpio.HIGH:
                    # data pulled up, the length of this pull up will determine whether it is 0 or 1
                    current_length = 0
                    state = STATE_DATA_PULL_DOWN
                    continue
                else:
                    continue
            if state == STATE_DATA_PULL_DOWN:
                if current == gpio.LOW:
                    # pulled down, we store the length of the previous pull up period
                    lengths.append(current_length)
                    state = STATE_DATA_PULL_UP
                    continue
                else:
                    continue

        return lengths

    def __calculate_bits(self, pull_up_lengths):
        # find shortest and longest period
        shortest_pull_up = 1000
        longest_pull_up = 0

        for i in range(0, len(pull_up_lengths)):
            length = pull_up_lengths[i]
            if length < shortest_pull_up:
                shortest_pull_up = length
            if length > longest_pull_up:
                longest_pull_up = length

        # use the halfway to determine whether the period it is long or short
        halfway = shortest_pull_up + (longest_pull_up - shortest_pull_up) / 2
        bits = []

        for i in range(0, len(pull_up_lengths)):
            bit = False
            if pull_up_lengths[i] > halfway:
                bit = True
            bits.append(bit)

        return bits

    def __bits_to_bytes(self, bits):
        the_bytes = []
        byte = 0

        for i in range(0, len(bits)):
            byte = byte << 1
            if (bits[i]):
                byte = byte | 1
            else:
                byte = byte | 0
            if ((i + 1) % 8 == 0):
                the_bytes.append(byte)
                byte = 0

        return the_bytes

    def __calculate_checksum(self, the_bytes):
        return the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3] & 255

The only difference if I compare with dht11.py in code is:

return DHT11Result(DHT11Result.ERR_NO_ERROR, the_bytes[2], the_bytes[0])

and in dht22.py is:

return DHT22Result(DHT22Result.ERR_NO_ERROR, 
			   (((the_bytes[2] & 0x7F)<<8)+the_bytes[3])/10.00,
			   ((the_bytes[0]<<8)+the_bytes[1])/10.00)

Of course it is renamed to DHT 22

 

Everything working nice but it do not showing the negative value of temperate..

It is like I using an absolute value of temperature..

If I run the code what is typed i C language the I see nicely the negative value:

root@orangepipc:~# ./dht
DHT22 temperature/humidity test
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.7 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
^C
root@orangepipc:~# ^C
root@orangepipc:~# ./dht
DHT22 temperature/humidity test
Humidity = 66.8 % Temperature = -1.0 *C (30.2 *F)
^C
root@orangepipc:~# ./dht
DHT22 temperature/humidity test
Humidity = 66.9 % Temperature = -1.0 *C (30.2 *F)
Humidity = 67.0 % Temperature = -0.4 *C (31.3 *F)
Humidity = 66.9 % Temperature = -0.4 *C (31.3 *F)

Where can be the problem?

Thx

Edited by Tido
added spoiler
Posted

Ok, I found the solution..

I understand the basic of python so I changed a code:

dht22.py
import time
from pyA20.gpio import gpio
from pyA20.gpio import port


class DHT22Result:
    'DHT22 sensor result returned by DHT22.read() method'

    ERR_NO_ERROR = 0
    ERR_MISSING_DATA = 1
    ERR_CRC = 2

    error_code = ERR_NO_ERROR
    temperature = -1
    humidity = -1
#    tmin = -1

    def __init__(self, error_code, temperature, humidity):
        self.error_code = error_code
        self.temperature = temperature
        self.humidity = humidity
#        self.tmin = tmin

    def is_valid(self):
        return self.error_code == DHT22Result.ERR_NO_ERROR


class DHT22:
    'DHT22 sensor reader class for Raspberry'

    __pin = 0

    def __init__(self, pin):
        self.__pin = pin

    def read(self):
        gpio.setcfg(self.__pin, gpio.OUTPUT)

        # send initial high
        self.__send_and_sleep(gpio.HIGH, 0.05)

        # pull down to low
        self.__send_and_sleep(gpio.LOW, 0.02)

        # change to input using pull up
        #gpio.setcfg(self.__pin, gpio.INPUT, gpio.PULLUP)
	gpio.setcfg(self.__pin, gpio.INPUT)
	gpio.pullup(self.__pin, gpio.PULLUP)


        # collect data into an array
        data = self.__collect_input()

        # parse lengths of all data pull up periods
        pull_up_lengths = self.__parse_data_pull_up_lengths(data)

        # if bit count mismatch, return error (4 byte data + 1 byte checksum)
        if len(pull_up_lengths) != 40:
            return DHT22Result(DHT22Result.ERR_MISSING_DATA, 0, 0)

        # calculate bits from lengths of the pull up periods
        bits = self.__calculate_bits(pull_up_lengths)

        # we have the bits, calculate bytes
        the_bytes = self.__bits_to_bytes(bits)

        # calculate checksum and check
        checksum = self.__calculate_checksum(the_bytes)
        if the_bytes[4] != checksum:
            return DHT22Result(DHT22Result.ERR_CRC, 0, 0)

        c = (float)(((the_bytes[2]&0x7F)<< 8)+the_bytes[3])/10;

        # ok, we have valid data, return it
        if ( c > 125 ):
            c = the_bytes[2]; 

       
        if (the_bytes[2] & 0x80):
            c = -c;

        return DHT22Result(DHT22Result.ERR_NO_ERROR, 
				c ,((the_bytes[0]<<8)+the_bytes[1])/10.00)


    def __send_and_sleep(self, output, sleep):
        gpio.output(self.__pin, output)
        time.sleep(sleep)

    def __collect_input(self):
        # collect the data while unchanged found
        unchanged_count = 0

        # this is used to determine where is the end of the data
        max_unchanged_count = 100

        last = -1
        data = []
        while True:
            current = gpio.input(self.__pin)
            data.append(current)
            if last != current:
                unchanged_count = 0
                last = current
            else:
                unchanged_count += 1
                if unchanged_count > max_unchanged_count:
                    break

        return data

    def __parse_data_pull_up_lengths(self, data):
        STATE_INIT_PULL_DOWN = 1
        STATE_INIT_PULL_UP = 2
        STATE_DATA_FIRST_PULL_DOWN = 3
        STATE_DATA_PULL_UP = 4
        STATE_DATA_PULL_DOWN = 5

        state = STATE_INIT_PULL_DOWN

        lengths = [] # will contain the lengths of data pull up periods
        current_length = 0 # will contain the length of the previous period

        for i in range(len(data)):

            current = data[i]
            current_length += 1

            if state == STATE_INIT_PULL_DOWN:
                if current == gpio.LOW:
                    # ok, we got the initial pull down
                    state = STATE_INIT_PULL_UP
                    continue
                else:
                    continue
            if state == STATE_INIT_PULL_UP:
                if current == gpio.HIGH:
                    # ok, we got the initial pull up
                    state = STATE_DATA_FIRST_PULL_DOWN
                    continue
                else:
                    continue
            if state == STATE_DATA_FIRST_PULL_DOWN:
                if current == gpio.LOW:
                    # we have the initial pull down, the next will be the data pull up
                    state = STATE_DATA_PULL_UP
                    continue
                else:
                    continue
            if state == STATE_DATA_PULL_UP:
                if current == gpio.HIGH:
                    # data pulled up, the length of this pull up will determine whether it is 0 or 1
                    current_length = 0
                    state = STATE_DATA_PULL_DOWN
                    continue
                else:
                    continue
            if state == STATE_DATA_PULL_DOWN:
                if current == gpio.LOW:
                    # pulled down, we store the length of the previous pull up period
                    lengths.append(current_length)
                    state = STATE_DATA_PULL_UP
                    continue
                else:
                    continue

        return lengths

    def __calculate_bits(self, pull_up_lengths):
        # find shortest and longest period
        shortest_pull_up = 1000
        longest_pull_up = 0

        for i in range(0, len(pull_up_lengths)):
            length = pull_up_lengths[i]
            if length < shortest_pull_up:
                shortest_pull_up = length
            if length > longest_pull_up:
                longest_pull_up = length

        # use the halfway to determine whether the period it is long or short
        halfway = shortest_pull_up + (longest_pull_up - shortest_pull_up) / 2
        bits = []

        for i in range(0, len(pull_up_lengths)):
            bit = False
            if pull_up_lengths[i] > halfway:
                bit = True
            bits.append(bit)

        return bits

    def __bits_to_bytes(self, bits):
        the_bytes = []
        byte = 0

        for i in range(0, len(bits)):
            byte = byte << 1
            if (bits[i]):
                byte = byte | 1
            else:
                byte = byte | 0
            if ((i + 1) % 8 == 0):
                the_bytes.append(byte)
                byte = 0

        return the_bytes

    def __calculate_checksum(self, the_bytes):
        return the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3] & 255
dht22_main.py
from pyA20.gpio import gpio
from pyA20.gpio import port
from time import gmtime, strftime
import paho.mqtt.client as mqtt

import dht22
import time
import datetime
import os



PIN2 = port.PA6
gpio.init()
n=150 #after every 150 (~10 minutes) load (connect to thingspeak) again!
i=0

channelId = "xxxxx"         # Put your channel ID here,i.e.. the number from the URL, https://thingspeak.com/channels/285697
apiKey = "xxxxxxxxxxxxxxx"  # Put the API key here (the Write API Key from the API Keys tab in ThingSpeak)
client = mqtt.Client()
client.connect("mqtt.thingspeak.com",1883,60)


instance = dht22.DHT22(pin=PIN2)
os.system('clear')

while True:
	result = instance.read()
	if result.is_valid():
		i=i+1
		print("\033[37;1mLast valid input: \033[0m" + "\033[33;1m" + str(strftime("%d.%m.%Y %H:%M:%S", gmtime())) + "\033[0m")
		print("\033[37;1mTemperature: \033[1;31m%.2f C\033[0m" % result.temperature)
		print("\033[37;1mHumidity: \033[32;1m%.2f %%\033[0m\n" % result.humidity)
		if i == n-1:
			
			print 'Now setting value i to zero\nLoading libary again'
			i=0
			
			client = mqtt.Client()
			client.connect("mqtt.thingspeak.com",1883,60)
			client.publish("channels/%s/publish/%s" % (channelId,apiKey), "field1=" + str(result.temperature) + "&field2=" + str(result.humidity))
		else:
			client.publish("channels/%s/publish/%s" % (channelId,apiKey), "field1=" + str(result.temperature) + "&field2=" + str(result.humidity))
	else:
		
		time.sleep(4)

 

Scrip for checking if proccess stop.

You need to put in crontab (at me every 5miutes)

 

chk_dht22_script.sh
#!/bin/bash

PID_OF_APP="/run/pidfile_dht22.pid"

PID_OF_PROCCESS=`ps -aux|grep dht22_main|grep -v grep|awk -F" " '{print $2}'`
PID_OF_PROCCESS=( $PID_OF_PROCCESS )
NUMBER_OF_OCCURENCE=`echo ${#PID_OF_PROCCESS[@]}`
#echo $NUMBER_OF_OCCURENCE


if [[ "$NUMBER_OF_OCCURENCE" == 0 ]];then
	echo -e "Proccess isn't started..\nNow process dht22_main.py and creating PID file..."
	python /emu/script/dht22_*  & disown & echo $! > /run/pidfile_dht22.pid
	exit
fi
if [[ "$NUMBER_OF_OCCURENCE" > 1 ]];then
	echo -e "Process dht22_main.py is started more than 1x"
	echo -e "Now killing all proccess one by one"
	PID_OF_PROCCESS=`ps -aux|grep dht22_main|grep -v grep|awk -F" " '{print $2}'`
	kill $PID_OF_PROCCESS
	rm -fr $PID_OF_APP
	echo -e "Starting process dht22_main.py and creating PID file..."
	python /emu/script/dht22_* & echo $! > /run/pidfile_dht22.pid
fi

 

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines