ESP8266 IOT TEMP SENSOR

A month or so ago, I bought an ESP8266-12 chip to use as a micro-controller.  After thinking about a few projects, I thought it would be neat to get the venerable DS18B20 running on this chip and upload the temperature of the sensor to thingspeak.com.  If you don’t know what thingspeak is, it’s a website that has an API that allows you to upload data from an IoT device and graph it, or use that data and produce some event driven program. Pushingbox is another similar service, though it’s more geared towards event driven behavior, than just graphing results.

The first step to completing this project is to correctly wire our chip so that we can communicate to it (via serial), and also connect our DS18B20 sensor to the chip.

IMG_0549

In this photo, I have a FTDI FT232R chip (which I found was counterfeit)* at the top which I draw 3.3v power off of (seems to be enough for the ESP8266 chip, unless you are using a wireless-g router instead on wireless-n). The ESP8266 seems to draw between 80-160mA  during use according to my oscilloscope. I also wire my GND from the FTDI chip to the GND pin of the ESP8266 diagram below.

*A note about counterfeit FT232R chips. FTDI saw fit to brick any counterfeit FT232R chip using their drivers in Windows. If you make the mistake of using a current FTDI driver, it will reset the PID of your USB device to all zeros, rendering the device useless. First delete the FTDI version “2.12.00” driver off of your machine. Then you will need to reset the PID of the USB device to it’s original configuration. See http://www.minipwner.com/index.php/unbrickftdi000 for more details regarding this fix.

The connections made are as follows. FTDI 3.3v pin to ESP8266 VCC pin . ESP8266 VCC pin jumped to ESP8266 CH_PD pin. FTDI GND pin to ESP8266 GND pin. FTDI RX pin to ESP8266 TXD pin. FTDI TX pin to ESP8266 RXD pin.  ESP8266 GPIO15 pin to ESP8266 GND. This is the setup I use, which allows me to communicate over USB to the ESP8266 chip using a serial interface. While this setup works great when sending lua script to the devices, and reading output from the device, to actually flash the NodeMCU firmware we still have a few steps.

The first step is to flash the ESP8266-12 chip with new firmware. I did that by setting up the above circuit, then I made one change. Connect a wire from ESP8266 GPIO 0 to ESP8266 GND. This will set the chip into programming mode, and allow you to flash it’s firmware. To flash the firmware we will use NodeMCU flasher. Download the correct version for the Windows installation you are using.

 

Screen-Shot-2015-01-08-at-3.40.37-PM

This is the window you will see, using this tool. Head over to the Config tab to open the version firmware you want to flash. After you select the version firmware you want go back to the Operation tab and click “Flash(F)”. As long as you have your FTDI chip and ESP8266 chip connected correctly and you have the programming pin set to GND, then it will be possible to flash a new firmware to this chip.

ESP12pinout

 

The second step to completing this project is to verify the NodeMCU firmware was uploaded to our ESP8266 chip. I am using NodeMCU because it supports LUA as a language and you can use a rather nice Java base IDE called ESPlorer. Being Java based, it will run on OS X, Linux, and Windows.

After downloading ESPlorer, run the program.

Screen-Shot-2015-01-08-at-3.48.26-PM

 

Make sure you can connect to your device, and write files to it.

The next step is to create a thingspeak.com account. After that, create a channel. The website should look similar to this.

Screen-Shot-2015-01-08-at-2.50.15-PM

 

After you create a channel, go to Channel Settings. Give the channel some name and name the first field whatever you want to appear as the title for your Y-axis. There is no need to enter anything else in Channel Settings at this time, just “Save Channel”. Then visit the “API Keys” tab and take note of your “Write API Key”. This key will allow you to upload the data from your DS18B20 sensor to thingspeak.com.

We will need to upload two lua scripts to the ESP8266. The first is called init.lua, the second speak.lua. The init.lua is as follows. Also this script is very basic and this is only capable of reading one sensor.  It will output in celsius.

init.lua


wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","passwordhere")
print(wifi.sta.getip())
tmr.alarm(0, 60000, 1, function() dofile("speak.lua") end )

speak.lua


pin = 1
ow.setup(pin)
count = 0
repeat
count = count + 1
addr = ow.reset_search(pin)
addr = ow.search(pin)
tmr.wdclr()
until((addr ~= nil) or (count > 100))
if (addr == nil) then
print("No more addresses.")
else
print(addr:byte(1,8))
crc = ow.crc8(string.sub(addr,1,7))
if (crc == addr:byte(8)) then
if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then
print("Device is a DS18S20 family device.")
--repeat
ow.reset(pin)
ow.select(pin, addr)
ow.write(pin, 0x44, 1)
tmr.delay(1000000)
present = ow.reset(pin)
ow.select(pin, addr)
ow.write(pin,0xBE,1)
print("P="..present)
data = nil
data = string.char(ow.read(pin))
for i = 1, 8 do
data = data .. string.char(ow.read(pin))
end
print(data:byte(1,9))
crc = ow.crc8(string.sub(data,1,8))
print("CRC="..crc)
if (crc == data:byte(9)) then
t = (data:byte(1) + data:byte(2) * 256) * 625
t1 = t / 10000
t2 = t % 1000
print("Temperature= "..t1.."."..t2.." Centigrade")

end
tmr.wdclr()
–until false
else
print(“Device family is not recognized.”)
end
else
print(“CRC is not valid!”)
end
end

conn=net.createConnection(net.TCP, 0)
conn:on("receive", function(conn, payload) print(payload) end )
conn:connect(80,"184.106.153.149")
conn:send("GET /update?key=ENTERYOURKEYHERE&field1="..t1.."."..t2.." HTTP/1.1\r\nHost: api.thingspeak.com\r\n"
.."Connection: close\r\nAccept: */*\r\n\r\n")

The first change needed is to put your thingspeak.com API write key in the speak.lua script, so change this line to the key from thingspeak.com “key=ENTERYOURKEYHERE&field1=”..t1..”.”..t2..” HTTP/1.1\r\nHost:” , next change the GPIO pin in the line “pin = 1″ to the GPIO pin that you have your sensor plugged into. A map of GPIO pins is available here. Then upload the script to your ESP8266 using ESPlorer.  Next change this line “wifi.sta.config(“SSID”,”password here”)” in init.lua to match your wireless network settings. Then upload the init.lua script.

So make sure both init.lua and speak.lua are uploaded to the ESP8266 chip using ESPlorer.

After you upload both scripts to the ESP8266, you should be able to select “DoFile” which should initalize init.lua and allow your script to run, if it isn’t already running. When everything is done you should see something similar to this output in your thingspeak channel.

Screen-Shot-2015-01-08-at-4.07.21-PM

You can find my sensor here.

Credit goes out to  claudiuchiruVasilijHCN, and sancho for the code, with a small change to fix a send issue by me.

Also, I am rewriting this script to run on the DS18B20 NodeMCU library with the ability to select between Fahrenheit, Celsius, and Kelvin scales. I will post my code in the next week or so.

2 Responses

  1. MGA says:

    Great information.. Thanks for sharing the cde.
    Could u please share the idea how to modify the code to display the tmp in Fahrenheit. It would be great if you if share it… Thanks again

    • aonko says:

      In the link there is some example code that will allow you to output in Fahrenheit.

      https://github.com/nodemcu/nodemcu-firmware

      -- read temperature with DS18B20
      node.compile("ds18b20.lua") -- run this only once to compile and save to "ds18b20.lc"
      t=require("ds18b20")
      t.setup(9)
      addrs=t.addrs()
      -- Total DS18B20 numbers, assume it is 2
      print(table.getn(addrs))
      -- The first DS18B20
      print(t.read(addrs[1],t.C))
      print(t.read(addrs[1],t.F))
      print(t.read(addrs[1],t.K))
      -- The second DS18B20
      print(t.read(addrs[2],t.C))
      print(t.read(addrs[2],t.F))
      print(t.read(addrs[2],t.K))
      -- Just read
      print(t.read())
      -- Just read as centigrade
      print(t.read(nil,t.C))
      -- Don't forget to release it after use
      t = nil
      ds18b20 = nil
      package.loaded["ds18b20"]=nil

      Change the line print(t.read(nil,t.C)) to print(t.read(nil,t.F))

Leave a Reply

Your email address will not be published. Required fields are marked *