• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Ошибка attempt to index global 'ds18b20'

sER

New member
Здравствуйте. Мучаю датчик температуры, получаю ошибку:
Код:
lua: dallas.lua:8: attempt to index global 'ds18b20' (a nil value)
ds18b20.lua
nodemcu-firmware/ds18b20.lua at master · nodemcu/nodemcu-firmware · GitHub

init.lua
Код:
print(wifi.sta.getip())
wifi.setmode(wifi.STATION)
wifi.sta.config("apname","password")
print(wifi.sta.getip())
dofile('dallas.lua')
dallas.lua
Код:
require('ds18b20')
gpio0 = 3
ds18b20.setup(gpio0)
function sendData()
t1=ds18b20.read()
t1=ds18b20.read()
print("Temp:"..t1.." C\n")
end
tmr.alarm(0, 60000, 1, function() sendData() end )

В чём у меня ошибка?
 

Gorodnov

New member
Во первых в прошивку должны быть включены модули 1-Wire и encoder.
Во вторых инициализация и обмен с датчиком происходят как я понял по другому.
Только вчера начал изучать ESP и тоже с этим столкнулся.
Пример как у тебя у меня тоже не работал, вылетал с этой ошибкой.
Скомпилировал прошивку и применил пример из SDK, всё сразу завелось.
Подставь этот код вместо своего в файл dallas.lua

Код:
t = require("ds18b20")
pin = 3 -- gpio0 = 3, gpio2 = 4

function readout(temp)
  for addr, temp in pairs(temp) do
    -- print(string.format("Sensor %s: %s 'C", addr, temp))
    print(string.format("Sensor %s: %s В°C", encoder.toHex(addr), temp)) -- readable address with base64 encoding is preferred when encoder module is available
  end

  -- Module can be released when it is no longer needed
  t = nil
  package.loaded["ds18b20"]=nil
end

-- t:readTemp(readout) -- default pin value is 3
t:readTemp(readout, pin)
if t.sens then
  print("Total number of DS18B20 sensors: "..table.getn(t.sens))
  for i, s in ipairs(t.sens) do
    -- print(string.format("  sensor #%d address: %s%s", i, s.addr, s.parasite == 1 and " (parasite)" or ""))
    print(string.format("  sensor #%d address: %s%s",  i, encoder.toHex(s.addr), s.parasite == 1 and " (parasite)" or "")) -- readable address with base64 encoding is preferred when encoder module is available
  end
end
 

sER

New member
Благодарю, заработало.

1-Wire я добавил,а encoder не было, собрал новую прошивку, заработало.
 

sER

New member
Подключил два датчика
Sensor 281398d70200005d: 26 В°C
Sensor 28ff57a3811603c0: 26.5 В°C

Как считать температуру только с нужного мне адреса?
 

sER

New member
Код:
-- main.lua --
tmr.alarm(0, 1000, 1, function()
if wifi.sta.getip() == nil then
print("Connecting to AP...\n")
else
ip, nm, gw=wifi.sta.getip()
print("IP Info: \nIP Address: ",ip)
print("Netmask: ",nm)
print("Gateway Addr: ",gw,'\n')
tmr.stop(0)
end
end)

text='pusto'
t = require('ds18b20')
pin = 3

-- a simple http server
srv = net.createServer(net.TCP, 30)
srv:listen(80,function(conn)
conn:on("receive",function(conn,get)
na=string.find(get,"z=");





function dallas(temp)
text=''
for addr, temp in pairs(temp) do
text = text .. string.format("Sensor %s: %s", encoder.toHex(addr), temp.."n")
end
end





function zagolovok()
con=string.find(get,"HTTP");
zag=string.sub(get, na,con-2);
if zag == "z=1" then "Первая страничка"
elseif zag == "z=sensor1" then t:readTemp(dallas, pin)
elseif zag == "z=sensor2" then text="Второй сенсор"
else text="Иная" end
end
if na~=nil then zagolovok() end

conn:send('HTTP/1.1 200 OK\n')
conn:send('Access-Control-Allow-Origin:*\n\n')
conn:send(text)
conn:on("sent", function(conn) conn:close() end)
end)
end)
Так считываю оба датчика
 

Gorodnov

New member
Глянуть смогу только вечером.
У меня немного другая задача, мне нужен наглядный график работы термометров.
Вот что у меня будет.
 

Вложения

sER

New member
Модуль ds18b20.lua показывает отрицательную температуру?


HTML:
<html>
  <head>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', {'packages':['corechart']});
      google.charts.setOnLoadCallback(drawChart);

      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Температура', 'Морозильная камера', 'Холодильная камера'],
          ['15:00:00',  -10,      -3],
          ['15:05:00',  -12,      -5],
          ['15:10:00',  -15,      -7],
          ['15:15:00',  -9,      -10]
        ]);

        var options = {
          title: 'Датчики температуры',
          hAxis: {title: 'Температура',  titleTextStyle: {color: '#333'}},
          vAxis: {minValue: 0}
        };

        var chart = new google.visualization.AreaChart(documыent.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 500px;"></div>
  </body>
</html>
 

Gorodnov

New member
Да показывает.
Вот модуль целиком.
В строке 78 проверяется знак, и если он присутствует, то в строке 79 показания поправляются для отображения отрицательного результата.

Код:
--------------------------------------------------------------------------------
-- DS18B20 one wire module for NODEMCU
-- by @voborsky, @devsaurus
-- encoder module is needed only for debug output; lines can be removed if no
-- debug output is needed and/or encoder module is missing
--
-- by default the module is for integer version, comment integer version and
-- uncomment float version part for float version
--------------------------------------------------------------------------------

return({
  pin=3,
  sens={},
  temp={},

  conversion = function(self)
    local pin = self.pin
    for i,s in ipairs(self.sens) do
      if s.status == 0 then
        print("starting conversion:", encoder.toHex(s.addr), s.parasite == 1 and "parasite" or " ")
        ow.reset(pin)
        ow.select(pin, s.addr)  -- select the sensor
        ow.write(pin, 0x44, 1)  -- and start conversion
        s.status = 1
        if s.parasite == 1 then break end -- parasite sensor blocks bus during conversion
      end
    end
    tmr.create():alarm(750, tmr.ALARM_SINGLE, function() self:readout() end)
  end,

  readTemp = function(self, cb, lpin)
    if lpin then self.pin = lpin end
    local pin = self.pin
    self.cb = cb
    self.temp={}
    ow.setup(pin)

    self.sens={}
    ow.reset_search(pin)
    -- ow.target_search(pin,0x28)
    -- search the first device
    local addr = ow.search(pin)
    -- and loop through all devices
    while addr do
      -- search next device
      local crc=ow.crc8(string.sub(addr,1,7))
      if (crc==addr:byte(8)) and ((addr:byte(1)==0x10) or (addr:byte(1)==0x28)) then
        ow.reset(pin)
        ow.select(pin, addr)   -- select the found sensor
        ow.write(pin, 0xB4, 1) -- Read Power Supply [B4h]
        local parasite = (ow.read(pin)==0 and 1 or 0)
        table.insert(self.sens,{addr=addr, parasite=parasite, status=0})
        print("contact: ", encoder.toHex(addr), parasite == 1 and "parasite" or " ")
      end

      addr = ow.search(pin)
      tmr.wdclr()
    end

    -- place powered sensors first
    table.sort(self.sens, function(a,b) return a.parasite<b.parasite end)

    node.task.post(node.task.MEDIUM_PRIORITY, function() self:conversion() end)
  end,

  readout=function(self)
    local pin = self.pin
    local next = false
        if not self.sens then return 0 end
    for i,s in ipairs(self.sens) do
      -- print(encoder.toHex(s.addr), s.status)
      if s.status == 1 then
        ow.reset(pin)
        ow.select(pin, s.addr)   -- select the  sensor
        ow.write(pin, 0xBE, 0) -- READ_SCRATCHPAD
        data = ow.read_bytes(pin, 9)

        local t=(data:byte(1)+data:byte(2)*256)
        if (t > 0x7fff) then t = t - 0x10000 end
        if (s.addr:byte(1) == 0x28) then
          t = t * 625  -- DS18B20, 4 fractional bits
        else
          t = t * 5000 -- DS18S20, 1 fractional bit
        end

        if 1/2 == 0 then
          -- integer version
          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 (tH~=85) then
            self.temp[s.addr]=(sgn<0 and "-" or "")..tH.."."..tL
            print(encoder.toHex(s.addr),(sgn<0 and "-" or "")..tH.."."..tL)
            s.status = 2
          end
          -- end integer version
        else
          -- float version
          if t and (math.floor(t/10000)~=85) then
            self.temp[s.addr]=t/10000
            print(encoder.toHex(s.addr), t)
            s.status = 2
          end
          -- end float version
        end
      end
      next = next or s.status == 0
    end
    if next then
      node.task.post(node.task.MEDIUM_PRIORITY, function() self:conversion()  end)
    else
      self.sens = nil
      if self.cb then
        node.task.post(node.task.MEDIUM_PRIORITY, function()  self.cb(self.temp) end)
      end
    end

  end
})
 

sER

New member
Приветствую. Удалось считать датчики по отдельности (адресу)?
 

sER

New member
У Вас всегда считывается температура или модуль уходит в перезагрузку? PANIC...
 
Сверху Снизу