STM32F407Disc: DHT22 Checksum Error

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

STM32F407Disc: DHT22 Checksum Error

Post by nikhiledutech » Wed Jan 10, 2018 7:04 am

Hello,
I need help with my code. i am currently interfacing DHT22 with STM32F407dic board and displaying its O/P asynchronously on LCD.

But always i get "Checksum error". Kindly help me with this code. I have seen other drivers available drivers, some are using Timers for counting interval. But i am using utime module for providing us delay

Below is my code:
#Write a program to interface temp and humidity Sensor and display data on LCD
#Temperature & Humidity Driver File
import pyb
from pyb import Pin,LED
import utime as time
import uasyncio as asyncio
from alcd import LCD, PINLIST

lcd = LCD(PINLIST,cols=16)

#Pin Configuration
def DHT22_PinConfig(mode): #Mode : Pin.IN, Pin.OUT or Pin.OUT_PP
sig = pyb.Pin('PC6',Pin.PULL_UP)
sig.init(mode)

#Sensor Initialisation
def DHT22_Init():
DHT22_PinConfig(Pin.IN) #Input mode


#Reading data
async def DHT22_read():
led1= pyb.LED(1)
led2= pyb.LED(2)
led3= pyb.LED(3)
led4= pyb.LED(4)

for secs in range(20, -1, -1):
sig = pyb.Pin('PC6',Pin.PULL_UP)
DHT22_Init()
pyb.delay(2000)
lastHumidity1 = lastHumidity2 = 0
lastTemperature1 = lastTemperature2 = 0
i = j = retryCount = 0
currentTemperature = currentHumidity = checkSum = 0
csPart1 = csPart2 = csPart3 = csPart4 = 0
bitTimes = bytearray(41)

for x in range (41):
bitTimes[x] = 0

# Pin needs to start HIGH, wait until it is HIGH with a timeout
while (sig.value() == False): #exit on DHT22 return 'High' Signal within 250us
if retryCount > 125 :
lcd[0] = "DHT22 Bus Busy!"
lcd[1] = " "
await asyncio.sleep(1)
retryCount+=1
time.sleep_us(2)




#" Send the activate pulse
# * Step 1: MCU send out start signal to DHT22 and DHT22 send
# * response signal to MCU.
# * If signal is high-voltage-level, it means DHT22 is not
# * working properly, please check the electrical connection status. """

DHT22_PinConfig(Pin.OUT_PP) #Set pin to transmit data
sig.value(0) #MCU sends Start singnal on DHT22
time.sleep_ms(18) #18ms delay
sig.value(1) #MCU Pull Up
time.sleep_us(40) #40us delay
DHT22_PinConfig(Pin.IN) #Set pin to recieve data

#Find the start of the ACK Pulse
retryCount = 0
while (sig.value() == True): #Exit on DHT22 pull low within 40us
if (retryCount > 40):
lcd[0] = "DHT22 Not "
lcd[1] = "Responding"
await asyncio.sleep(1)
retryCount+=1
time.sleep_us(1)
time.sleep_us(80) #DHT pull up ready to transmit data



#* Reading the 5 byte data stream
#* Step 2: DHT22 send data to MCU
# * Start bit -> low volage within 50us (actually could be anything from 35-75us)
# * 0 -> high volage within 26-28us (actually could be 10-40us)
# * 1 -> high volage within 70us (actually could be 60-85us)



for i in range (5): #5 Bytes
for j in range (8): #8 bits
retryCount = 0
while (sig.value() == False): #Exit on DHT22 pull low within 40us
if (retryCount > 75):
led4.toggle()
lcd[0] = "DHT Timeout!"
lcd[1] = "Waiting for Data"
await asyncio.sleep(1)
retryCount+=1
time.sleep_us(1)

time.sleep_us(40) #Waiting for 40us

if (sig.value() == True):
bitTimes[i*8+j] = 1 #If pin is still high, bit value is a 1
else :
bitTimes[i*8+j] = 0 #The bit value is a 0

count = 0
while (sig.value() == True & count < 100):
time.sleep_us(1)
count+=1

DHT22_PinConfig(Pin.OUT_PP) #Re-initalising DHT22 in O/P mode
sig.value(1)




#Now bitTimes have the actual bits that were needed to find the end of each data bit
currentHumidity = currentTemperature = checkSum = 0

#First 16 bits is Humidity
for i in range (16):
if (bitTimes[i+1] > 0):
currentHumidity |= ( 1 << (15-i))

#Second 16 bits is Temperature
for i in range (16):
if (bitTimes[i+17] > 0):
currentTemperature |= ( 1 << (15-i))

#Last 8 bits is checksum
for i in range (8):
if (bitTimes[i+33] > 0):
checkSum |= (1 << (7-i))
# lcd[0] = 'CS{}'.format(checkSum) #Checksum values read are 028-192-224-240-252
# lcd[1] = ''
# await asyncio.sleep(1)


lastHumidity1 = currentHumidity/10
lastHumidity2 = currentHumidity%10



#If first bit of currentTemperature is 1, it is negative value.
if ((currentTemperature & 0x8000)== 0x8000):
lastTemperature1 = ((currentTemperature & 0x7FFF) / 10) * -1;
lastTemperature2 = currentTemperature % 10
# lcd[0] = 'Temp1{}'.format(lastTemperature1)
# lcd[1] = 'Temp2{}'.format(lastTemperature2)
# await asyncio.sleep(1)
else:
lastTemperature1 = currentTemperature / 10.0
lastTemperature2 = currentTemperature % 10
#
#Calculate Check Sum
csPart1 = currentHumidity >> 8
csPart2 = currentHumidity & 0xFF
csPart3 = currentTemperature >> 8
csPart4 = currentTemperature & 0xFF

#Checksum value read above in data frame and the addition of cspart1:4 &0xFF are not same, which is causing problem.

if (checkSum == ((csPart1 + csPart2 + csPart3 + csPart4) & 0xFF)):
lcd[0] = 'T1{}'.format(lastTemperature1) # 1870.5
lcd[1] = 'T2{}'.format(lastTemperature2) # 25-27
await asyncio.sleep(1)
else:
lcd[0] = 'Checksum error' # 1870.5
await asyncio.sleep(1)

## pyb.delay(500)


while True:
loop = asyncio.get_event_loop()
loop.run_until_complete(DHT22_read())
So it means data packets are getting lost.
So please help me with your valuable inputs and help me with this code.

Post Reply