• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Решено не могу подружить esp8622 с ds18b20

blak soft

Member
это мой первый опыт
никак не могу сделать простой термометр
использую
1. NodeMCU Lua V2 wi-fi на базе ESP8266 (CP2102)
2. Датчик температуры DS18B20 в герметичном корпусе

нашел листинги
ds18b20.lua
Код:
--------------------------------------------------------------------------------
-- DS18B20 one wire module for NODEMCU
-- NODEMCU TEAM
-- LICENCE: http://opensource.org/licenses/MIT
-- Vowstar <vowstar@nodemcu.com>
-- 2015/02/14 sza2 <sza2trash@gmail.com> Fix for negative values
--------------------------------------------------------------------------------

-- Set module name as parameter of require
local modname = ...
local M = {}
_G[modname] = M
--------------------------------------------------------------------------------
-- Local used variables
--------------------------------------------------------------------------------
-- DS18B20 dq pin
local pin = nil
-- DS18B20 default pin
local defaultPin = 9
--------------------------------------------------------------------------------
-- 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
setfenv(1,M)
--------------------------------------------------------------------------------
-- Implementation
--------------------------------------------------------------------------------
C = 'C'
F = 'F'
K = 'K'
function setup(dq)
  pin = dq
  if(pin == nil) then
    pin = defaultPin
  end
  ow.setup(pin)
end

function addrs()
  setup(pin)
  tbl = {}
  ow.reset_search(pin)
  repeat
    addr = ow.search(pin)
    if(addr ~= nil) then
      table.insert(tbl, addr)
    end
    tmr.wdclr()
  until (addr == nil)
  ow.reset_search(pin)
  return tbl
end

function readNumber(addr, unit)
  result = nil
  setup(pin)
  flag = false
  if(addr == nil) then
    ow.reset_search(pin)
    count = 0
    repeat
      count = count + 1
      addr = ow.search(pin)
      tmr.wdclr()
    until((addr ~= nil) or (count > 100))
    ow.reset_search(pin)
  end
  if(addr == nil) then
    return result
  end
  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.")
      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)
        if (t > 32767) then
          t = t - 65536
        end

        if (addr:byte(1) == 0x28) then
          t = t * 625  -- DS18B20, 4 fractional bits
        else
          t = t * 5000 -- DS18S20, 1 fractional bit
        end

        if(unit == nil or unit == 'C') then
          -- do nothing
        elseif(unit == 'K') then
          t = t + 2731500
        else
          return nil
        end
        -- Fix by noss. Returns formatted string.
        --t = t / 10000

        t1 = t / 10000
        t2 = (t >= 0 and t % 10000) or (10000 - t % 10000)
        t = t1 .. "."..string.format("%04d", t2)

        --end of fix
      
        return t
      end
      tmr.wdclr()
    else
    -- print("Device family is not recognized.")
    end
  else
  -- print("CRC is not valid!")
  end
  return result
end

function read(addr, unit)
  t = readNumber(addr, unit)
  if (t == nil) then
    return nil
  else
    return t
  end
end

-- Return module table
return M
main.lua
Код:
t = require('ds18b20')
-- ESP-01 GPIO Mapping
gpio0 = 3
t.setup(gpio0)
function getTmp(t)
local tempr = t.read()
print("Temp:"..tempr.." C\n")
end
tmr.alarm(1, 1000,1, function() getTmp(t) end )
init.lua
Код:
tmr.register (0, 15000, tmr.ALARM_SINGLE, function (t) tmr.unregister (0); print ( "запуск файла main.lui"); dofile ( "main.lua") end)
tmr.start (0)
заливаю через программу "ESPlorer" но выдает ошибку
unprotected error in call to Lua API (ds18b20.lua:44: attempt to index upvalue '?' (a nil value))

перед запуском программы выдает следующее
ets Jan 8 2013,rst cause:2, boot mode:(3,7)
load 0x40100000, len 27556, room 16
tail 4
chksum 0xf8
load 0x3ffe8000, len 2440, room 4
tail 4
chksum 0x48
load 0x3ffe8988, len 136, room 4
tail 4
chksum 0x4b
csum 0x4b
NodeMCU custom build by frightanic.com
branch: dev
commit: bb9a5977d3eddd65b653b76dc4769cfd35be630e
SSL: false
modules: bme280,cron,crypto,file,gpio,http,i2c,net,node,rtctime,sntp,spi,tmr,u8g2,uart,websocket,wifi,wifi_monitor,wps
build created on 2018-11-18 07:57
powered by Lua 5.1.4 on SDK 2.2.1(6ab97e9)

подскажите что делаю не так
 

blak soft

Member
попробовал еще один вариант
ds18b20.lua
Код:
--------------------------------------------------------------------------------
-- DS18B20 one wire module for NODEMCU
-- NODEMCU TEAM
-- LICENCE: http://opensource.org/licenses/MIT
-- @voborsky, @devsaurus, TerryE  26 Mar 2017
----------------------------------------------------------------------------------------------------------------------------------------------------------------
local modname = ...

-- Used modules and functions
local table, string, ow, tmr, print, type, tostring, pcall, ipairs =
      table, string, ow, tmr, print, type, tostring, pcall, ipairs
-- Local functions
local ow_setup, ow_search, ow_select, ow_read, ow_read_bytes, ow_write, ow_crc8, ow_reset, ow_reset_search, ow_skip, ow_depower =
      ow.setup, ow.search, ow.select, ow.read, ow.read_bytes, ow.write, ow.crc8, ow.reset, ow.reset_search, ow.skip, ow.depower
local node_task_post, node_task_LOW_PRIORITY = node.task.post, node.task.LOW_PRIORITY
local string_char, string_dump = string.char, string.dump
local now, tmr_create, tmr_ALARM_SINGLE = tmr.now, tmr.create, tmr.ALARM_SINGLE
local table_sort, table_concat = table.sort, table.concat
local math_floor = math.floor
local file_open = file.open

table, string, tmr, ow = nil, nil, nil, nil

local DS18B20FAMILY   = 0x28
local DS1920FAMILY    = 0x10  -- and DS18S20 series
local CONVERT_T       = 0x44
local READ_SCRATCHPAD = 0xBE
local READ_POWERSUPPLY= 0xB4
local MODE = 1

local pin, cb, unit = 3
local status = {}

local debugPrint = function() return end

--------------------------------------------------------------------------------
-- Implementation
--------------------------------------------------------------------------------
local function enable_debug()
  debugPrint = function (...) print(now(),' ', ...) end
end

local function to_string(addr, esc)
  if type(addr) == 'string' and #addr == 8 then
    return ( esc == true and
             '"\\%u\\%u\\%u\\%u\\%u\\%u\\%u\\%u"' or
             '%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8))
  else
    return tostring(addr)
  end
end

local function readout(self)
  local next = false
  local sens = self.sens
  local temp = self.temp
  for i, s in ipairs(sens) do
    if status[i] == 1 then
      ow_reset(pin)
      local addr = s:sub(1,8)
      ow_select(pin, addr)   -- select the  sensor
      ow_write(pin, READ_SCRATCHPAD, MODE)
      data = ow_read_bytes(pin, 9)

      local t=(data:byte(1)+data:byte(2)*256)
      -- t is actually signed so process the sign bit and adjust for fractional bits
      -- the DS18B20 family has 4 fractional bits and the DS18S20s, 1 fractional bit
      t = ((t <= 32767) and t or t - 65536) *
          ((addr:byte(1) == DS18B20FAMILY) and 625 or 5000)
     
      if 1/2 == 0 then
        -- integer version
        if unit == 'F' then
          t = (t * 18)/10 + 320000
        elseif unit == 'K' then
          t = t + 2731500
        end     
        local sgn = t<0 and -1 or 1
        local tA = sgn*t
        local tH=tA/10000
        local tL=(tA%10000)/1000 + ((tA%1000)/100 >= 5 and 1 or 0)
             
        if tH and (t~=850000) then
          temp[addr]=(sgn<0 and "-" or "")..tH.."."..tL
          debugPrint(to_string(addr),(sgn<0 and "-" or "")..tH.."."..tL)
          status[i] = 2
        end
        -- end integer version
      else
        -- float version
        if t and (math_floor(t/10000)~=85) then
          t = t / 10000
          if unit == 'F' then
            t = t * 18/10 + 32
          elseif unit == 'K' then
            t = t + 27315/100
          end     
          self.temp[addr]=t
          debugPrint(to_string(addr), t)
          status[i] = 2
        end
        -- end float version
      end
    end
    next = next or status[i] == 0
  end
  if next then
    node_task_post(node_task_LOW_PRIORITY, function() return conversion(self) end)
  else
    --sens = {}
    if cb then
      node_task_post(node_task_LOW_PRIORITY, function() return cb(temp) end)
    end
  end
end

local function conversion(self)
  local sens = self.sens
  local powered_only = true
  for _, s in ipairs(sens) do powered_only = powered_only and s:byte(9) ~= 1 end
  if powered_only then
    debugPrint("starting conversion: all sensors")
    ow_reset(pin)
    ow_skip(pin)  -- select the sensor
    ow_write(pin, CONVERT_T, MODE)  -- and start conversion
    for i, s in ipairs(sens) do status[i] = 1 end
  else
    for i, s in ipairs(sens) do
      if status[i] == 0 then
        local addr, parasite = s:sub(1,8), s:byte(9)
        debugPrint("starting conversion:", to_string(addr), parasite == 1 and "parasite" or " ")
        ow_reset(pin)
        ow_select(pin, addr)  -- select the sensor
        ow_write(pin, CONVERT_T, MODE)  -- and start conversion
        status[i] = 1
        if parasite == 1 then break end -- parasite sensor blocks bus during conversion
      end
    end
  end
  tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
end

local function _search(self, lcb, lpin, search, save)
  self.temp = {}
  if search then self.sens = {}; status = {} end
  local temp = self.temp
  local sens = self.sens
  pin = lpin or pin
 
  local addr
  if not search and #sens == 0 then
    -- load addreses if available
    debugPrint ("geting addreses from flash")
    local s,check,a = pcall(dofile, "ds18b20_save.lc")
    if s and check == "ds18b20" then
      for i = 1, #a do sens[i] = a[i] end
    end
    debugPrint (#sens, "addreses found")
  end
 
  ow_setup(pin)
  if search or #sens == 0 then
    ow_reset_search(pin)
    -- ow_target_search(pin,0x28)
    -- search the first device
    addr = ow_search(pin)
  else
    for i, s in ipairs(sens) do status[i] = 0 end
  end
  local function cycle()
    debugPrint("cycle")
    if addr then
      local crc=ow_crc8(addr:sub(1,7))
      if (crc==addr:byte(8)) and ((addr:byte(1)==DS1920FAMILY) or (addr:byte(1)==DS18B20FAMILY)) then
        ow_reset(pin)
        ow_select(pin, addr)
        ow_write(pin, READ_POWERSUPPLY, MODE)
        local parasite = (ow_read(pin)==0 and 1 or 0)
        sens[#sens+1]= addr..string_char(parasite) -- {addr=addr, parasite=parasite, status=0}
        debugPrint("contact: ", to_string(addr), parasite == 1 and "parasite" or " ")
      end
      addr = ow_search(pin)
      node_task_post(node_task_LOW_PRIORITY, cycle)
    else
      ow_depower(pin)
      -- place powered sensors first
      table_sort(sens, function(a, b) return a:byte(9)<b:byte(9) end) -- parasite
      -- save sensor addreses
      if save then
        debugPrint ("saving addreses to flash")
       
        local addr_list = {}
        for i =1, #sens do
          local s = sens[i]
          addr_list[i] = to_string(s:sub(1,8), true)..('.."\\%u"'):format(s:byte(9))
        end
        local save_statement = 'return "ds18b20", {' .. table_concat(addr_list, ',') .. '}'       
        debugPrint (save_statement)
        local save_file = file_open("ds18b20_save.lc","w")
        save_file:write(string_dump(loadstring(save_statement)))
        save_file:close()
      end
      -- end save sensor addreses
      if lcb then node_task_post(node_task_LOW_PRIORITY, lcb) end
    end
  end
  cycle()
end

local function read_temp(self, lcb, lpin, lunit, force_search, save_search)
  cb, unit = lcb, lunit or unit
  _search(self, function() return conversion(self) end, lpin, force_search, save_search)
end
-- Set module name as parameter of require and return module table
local M = {
  sens = {},
  temp = {},
  C = 'C', F = 'F', K = 'K',
  read_temp = read_temp, enable_debug = enable_debug
}
_G[modname or 'ds18b20'] = M
return M
выдает ошибку
unprotected error in call to Lua API (ds18b20.lua:14: attempt to index global 'ow' (a nil value))
 

blak soft

Member
пробовал еще этот вариант
main.lua
Код:
local ow_pin = 3
ds18b20.setup(ow_pin)

-- read all sensors and print all measurement results
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
    end,{});

-- read only sensors with family type 0x28 and print all measurement results
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
    end,{},0x28);

-- save device roms in a variable
local addr = {}
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        addr[ind] = {string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)"))}
    end,{});

-- read only sensors listed in the variable addr
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
    end,addr);

-- print only parasitic sensors
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        if (par == 1) then
            print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
        end
    end,{});

-- print if temperature is greater or less than a defined value
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        if (t > 25) then
            print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
        end
        if (t < 20) then
            print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
        end
    end,{});
 

blak soft

Member
ds18b20.lua

пример взял отсюда

выдает ошибку

main.lua:2: attempt to index global 'ds18b20' (a nil value)
я подозреваю что в файле main.lua во второй строке ошибка но как ее исправить
и еще один вопрос если датчик ds18b20 не истравен что должна показать программа
 

Вложения

nikolz

Well-known member
пробовал еще этот вариант
main.lua
Код:
local ow_pin = 3
ds18b20.setup(ow_pin)


            print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
        end
    end,{});
вы не подключили модуль ds1820.lua
поэтому и ругается
а файл который вы приложили - это программа на СИ для VM Lua. Она нужна если будете собирать свою прошивку луа.
-------------------------
В вашей прошивке нет модуля ds1820 поэтому у Вас и не работает ничего.
modules: bme280,cron,crypto,file,gpio,http,i2c,net,node,rtctime,sntp,spi,tmr,u8g2,uart,websocket,wifi,wifi_monitor,wps
надо собрать новую на сайте (не помню название поищите в инете или на форуме)
 

blak soft

Member
спасибо за подсказку пересобрал прошивку залил файл
Код:
local ow_pin = 3
ds18b20.setup(ow_pin)

-- read all sensors and print all measurement results
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
    end,{});

-- read only sensors with family type 0x28 and print all measurement results
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
    end,{},0x28);

-- save device roms in a variable
local addr = {}
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        addr[ind] = {string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)"))}
    end,{});

-- read only sensors listed in the variable addr
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
    end,addr);

-- print only parasitic sensors
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        if (par == 1) then
            print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
        end
    end,{});

-- print if temperature is greater or less than a defined value
ds18b20.read(
    function(ind,rom,res,temp,tdec,par)
        if (t > 25) then
            print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
        end
        if (t < 20) then
            print(ind,string.format("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)")),res,temp,tdec,par)
        end
    end,{});
ошибку не выдает но и на экран ничего не выводит
датчик пробовал уже ко всем ножкам подключать
и ещевопрос если переподключить датчик достаточно нажать кнопку ресет для повторного запуска или нет
 

blak soft

Member
а как можно проверить ds18b20 на работоспособность у меня в гермитичном корпусе
цеплял по схеме и "local ow_pin = 3" поменял на "local ow_pin = 2"
 

nikolz

Well-known member
а как можно проверить ds18b20 на работоспособность у меня в гермитичном корпусе
цеплял по схеме
почти уверен, что нормальная
у меня их более десятка и все работаю исправно.
проверить можно осциллографом или логическим анализатором
посмотреть на шине (пине)
 

blak soft

Member
А можно какой нибудь простой пример чтобы температуру с датчика снять
 
Сверху Снизу