Pol Isidor Posted November 22, 2017 Posted November 22, 2017 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!
jeanrhum Posted November 22, 2017 Posted November 22, 2017 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.
Pol Isidor Posted November 22, 2017 Author Posted November 22, 2017 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!
jeanrhum Posted November 22, 2017 Posted November 22, 2017 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.
chwe Posted November 22, 2017 Posted November 22, 2017 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....
Pol Isidor Posted November 23, 2017 Author Posted November 23, 2017 @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. Any other suggestion?
chwe Posted November 23, 2017 Posted November 23, 2017 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... As @jeanrhum suggested, you should understand the basics of python to do such projects... Doesn't need that much effort learn it.. ;)
TonyMac32 Posted November 23, 2017 Posted November 23, 2017 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 ).
Pol Isidor Posted November 23, 2017 Author Posted November 23, 2017 @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?
chwe Posted November 23, 2017 Posted November 23, 2017 When you read my whole last post (including link to the other thread) you'll find it out...
Pol Isidor Posted November 23, 2017 Author Posted November 23, 2017 3 minutes ago, chwe said: When you read my whole last post (including link to the other thread) you'll find it out... 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?
Pol Isidor Posted November 23, 2017 Author Posted November 23, 2017 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?
chwe Posted November 23, 2017 Posted November 23, 2017 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) replace pyGPIO with pyA20 (in my provided code snippet) Correct the pin naming as you had it before test if it works take some time to learn Python
Pol Isidor Posted November 23, 2017 Author Posted November 23, 2017 @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)
chwe Posted November 23, 2017 Posted November 23, 2017 And now it's time to learn Python.... 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 ). And now it's up to you to bring it in a better shape....
Pol Isidor Posted November 24, 2017 Author Posted November 24, 2017 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!
Pol Isidor Posted December 4, 2017 Author Posted December 4, 2017 (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 December 4, 2017 by Tido added spoiler
Pol Isidor Posted December 18, 2017 Author Posted December 18, 2017 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
Recommended Posts