0

I've downloaded webserver code from https://docs.micropython.org/en/v1.8/esp8266/esp8266/tutorial/network_tcp.html, it worked well. But after adding code reading dht11 values, webserver stops responding. What's wrong with my code?

import machine
import dht
import socket
import network
sta_if = network.WLAN(network.STA_IF)
sta_if.connect(SSID, PASS)

addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
d = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_UP)

def measure():
    d.measure()
    temp = d.temperature()
    hum = d.humidity()
    return temp, hum

s = socket.socket()
s.bind(addr)
s.listen(1)

print('listening on', addr)

while True:
    cl, addr = s.accept()
    print('client connected from', addr)
    cl_file = cl.makefile('rwb', 0)
    while True:
        line = cl_file.readline()
        if not line or line == b'\r\n':
            break
    response = measure()
    cl.send(response)
    cl.close()
A. Makarevich
  • 365
  • 1
  • 3
  • 18
  • You don't seem to be using a [DHT11 object](https://docs.micropython.org/en/latest/esp8266/tutorial/dht.html) to read the sensor. Have you checked separately that you can read the temperature and humidity, and that your webserver code behaves as expected (e.g. by modifying `measure()` to return dummy values without trying to read the sensor)? – nekomatic Jan 21 '19 at 09:59
  • Thanks, really looks like you're right. Will try it tonight. – A. Makarevich Jan 21 '19 at 10:29
  • @nekomatic Unfortunately it didn't work. I replaced d = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_UP) with d = dht.DHT11(machine.Pin(5)). I'm able to run d.measure() and d.temperature() in WEBREPL (it returns valid answer), but web server doesn't response in this case. – A. Makarevich Jan 21 '19 at 17:58
  • Well at least we've narrowed it down. The next thing that looks suspicious to me is that the output of `measure()` is a numeric tuple and you're passing that directly to `cl.send()`, but it looks to me as if that method needs a [bytes object](https://docs.micropython.org/en/latest/library/usocket.html?highlight=socket#usocket.socket.send) - I think you need to encode the two values into a string then convert that into bytes first. – nekomatic Jan 21 '19 at 20:47
  • I'm returning only one value from measure() now: def measure(): d.measure() temp = d.temperature() hum = d.humidity() return temp And I'm converting measure() output to string before passing it to cl.send: response = str(measure()) – A. Makarevich Jan 21 '19 at 21:12
  • It looks like converting to string really worked. Thanks a lot @nekomatic The sad thing is that I didn't make any delay in my code, so now I can't update script on esp: it hangs. – A. Makarevich Jan 21 '19 at 21:30
  • Cool, I've written that up into an answer. How to fix the last problem you mention is dependent on which ESP8266 board you have, I guess; I would ask that on the [MicroPython forum](http://forum.micropython.org/). – nekomatic Jan 22 '19 at 10:25
  • Looks like I need to reload/update firmware. – A. Makarevich Jan 22 '19 at 11:59

1 Answers1

0

I see two problems with your code:

First, to read the DHT11 sensor you need to use a DHT object. Try replacing

d = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_UP) 

with

d = dht.DHT11(machine.Pin(5))

Second, the output of your measure() function is a numeric tuple and you're passing that directly to cl.send(), but that method needs a bytes object. You need to encode the two values into a string then convert that into bytes first. Instead of

cl.send(response)

you probably want something like

message = 'Temperature {} Humidity {}'.format(response[0], response[1])
cl.send(bytes(message, 'utf-8'))
nekomatic
  • 5,988
  • 1
  • 20
  • 27