Lua and the DS18B20/DS18B20P temperature sensor

DS18B20 or DS18B20PA long time ago, back in the dark ages when all we had were Arduinos (seems such a long time ago) I spent a bit of time playing with the Dallas DS18B20 chips.

There are a number of ways to read these and so I’ll explain my logic as I go along. Not everyone will agree with my conclusions and that’s fine. Works for me as they say.

The example that comes with the Lua interpreter caters for almost everyone by making the software check for missing chips, multiple chips and offering a range of output options including degrees C and F.  As the language subset does not include floats, it simulates that with two catenated numbers.

In order to avoid issues with delays stopping communications ( and I can confirm that delays WILL stop for example incoming MQTT messages), it also does away with the typical setup delay.

So –  a number of issues with this.  Firstly, for me, if I am reading temperature and maybe controlling something, I cannot for the life of me see the need for sub-degree precision. Accuracy yes but precision? Really, you’re going to keep the house at exactly 22.15c?   Probably not. I control 2 properties and this code will likely control the third – 24-7, 365 days as year if it works as reliably as the Arduino version.

Secondly, when I received my Dallas chips I got a mixed bunch on special offer and ended up with some with a P suffix. I quickly discovered that the delay is needed for these chips and today when using the example software with Lua I was set back temporarily before remembering this fact. The P suffix chips simply would not work AT ALL and constantly returned 85c. That delay is needed one way or another.

Because it has been removed, the first reading you take with the code will be incorrect.. and that’s not really a problem – you could take that during setup. There are ways around this but it’s not worth the bother when it’s so easy to circumvent.

Now personally I don’t see me using more than one chip per board and if I did I could always use another pin – so that whole search scenario is a waste of time, resources and RAM for me.

So given these criteria I have a MUCH simpler version of the driver for you – and one which will work without alteration with both chips. It’s also fast.

Instead of seeking the address of the chip, then starting the conversion, then reading the chip…  I assume one chip, simply read the value then start the conversion.

This seems utterly wrong but then remember your first reading is naff anyway. Assuming you don’t try to read the unit more than, say, once a second, the time in between reads will be more an enough to do the conversion for BOTH types of chip. I plan to stick this on a timer, say, every 10 seconds, dumping the value into a global variable so it’s “just there”.

Also as I’m just reading an integer, about the only check I have to do is for overflow so as to perhaps create a negative number (for freezing conditions) and finally all that CRC stuff and the buffer needed to store the data – why bother, with only one chip it’s not going to go wrong unless you have a long lead between the board and the chip. You only need to read 2 bytes!! Speed, storage…

So here’s the EASY version.

I have to say, I simply do not understand the registration system for LUA modules yet (wasn’t there last time I looked in) so those first few lines at the start I’ve copied verbatim.

Can you make it even simpler and also explain this stuff at the very first few lines to do with modname? Oh, I’m using all 3 leads (GND, D and VDD) of the Dallas chip and a 4k7 pull-up from D to VDD. I found the pull-up un-necessary on short leads but let’s not test fate?

Please note – this information has now been superseded by the info on the new blog at – please visit the new blog where you can search many hundreds of IOT-related entries.

— DS18B20 one wire module for NODEMCU
— Vowstar <>
— Dramatic simplification: Peter Scargill

— Set module name as parameter of require
local modname = …
local M = {}
_G[modname] = M
— Local used modules
— Table module
local table = table
— String module
local string = string
— One wire module
local ow = ow
— Timer module
local tmr = tmr
— Limited to local environment
— Implementation – you don’t get any shorter than this

function readNumber(pin)
ow.write(pin, 0xCC, 1)
ow.write(pin, 0xBE, 1)
data = nil
data = “”
for i = 1, 2 do
data = data .. string.char(
t = (data:byte(1) + data:byte(2) * 256) / 16
if (t>100) then
ow.write(pin, 0x44,1)
return t

— Return module table
return M

That’s it!!! So there’s the library done… now here’s the test code…

t = nil
ds18b20 = nil

Notice that this, too is simplified. “4” refers to GPIO2 in the Lua tables. I’m using an ESP-01 and I use GPIO0 to control a relay.

and here are the results showing a swing across through zero thanks to my handy liquid air spray. I do wish I could figure out how to turn the UART off except when I’m firing prints out – anyone know how to do this? Results buried in that mess are –2, 0, 1 and are degrees C (you could easily mod the code to F).  Suggest not trying to measure over 84C.

> t=require(“ds18b20”)
> t.setup(4)
> print(t.readNumber())
> t = nil
> ds18b20 = nil
> package.loaded[“ds18b20”]=nil
> t=require(“ds18b20”)
> t.setup(4)
> print(t.readNumber())
0t = nil
> ds18b20 = nil
> package.loaded[“ds18b20”]=nil
> t=require(“ds18b20”)
> t.setup(4)
> print(t.readNumber())
1t = nil
> ds18b20 = nil
> package.loaded[“ds18b20”]=nil

If you’re on Facebook why not LIKE here.

6 thoughts on “Lua and the DS18B20/DS18B20P temperature sensor

  1. Now that you have native development mostly sorted, what are the advantages of using Lua over native C code?

    Surely this is just using up additional ram space, when it’s not really required, or does Lua allow for a faster development cycle?

  2. Faster development but… I am starting to get sick of RAM and general reliability limitations so I would say at this point that I am not sure there are great benefits of using Lua. If I had some kind of file system for C and perhaps more documented library code I’m not sure I would bother with Lua. Right now it is up in the air and as for yesterdays efforts I ended up leaving without getting reliable MQTT operation for my sensor. I do know it will work in the stand alone version in C. In Lua I could send maybe 50 readings before some kind of failure. More experiments later today will confirm either way. Nothing like a good nights sleep to give you fresh ideas.

  3. Hi Peter

    I am on a parallel path to you, I am using a DHT22.

    After faffing about for over a day trying to get Nodemcu to read the device I gave up and flashed the example C code.

    Straight away I got a result. If I breathe on the device the temperature and humidity change.

    One problem I have is that the numbers I get are wildly out. I will have to trawl the data sheet and code to see if the correct data manipulation factors are being used.

    So, for me at the moment, the Lua code is wasting my time. A bit of a Pity!

    p,s, what happened to yesterdays replies to this topic?

  4. Ah yes and there is a tiny difference which I can’t recall. Suggestion for you – pay the extra £1 or so and get the 22s – the 11s are not very accurate and to prove that try putting several side by side and reading results – they’ll be all over the place. DHT22 are a good deal if you get them from China for sub £3

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s