Hjemmelaget temperaturkontroll for gjæringsskap

Så – som nevt i et tidligere innlegg har jeg bygget en provisorisk temperaturkontroll for gjæringsskapet mitt.

Den gjør vel omtrent havlparten av jobben som en STC-1000 gjør, og koster mer å bygge pluss at man må ha en apache/mysql-server stående, men det har vi vel alle?

Riggen betår av

1 stk NodeMCU fra Kjell & Co
1 stk ds18b20 1-wire temperatursensor
1 stk relekort 10A250V, for eksempel dette – selv gikk jeg for 2 releer, da det sørget for to-fase brudd i varmekildens strømtilførstel.

NodeMCU må settes opp mot nettverk, dette kan gjøres på flere måter, men jeg valgte å sette den opp som en klient med statisk ip, uten DNS.

Filnavn: networking.lua

--connect network
wifi.setmode(wifi.STATION)
wifi.sta.config("din ssid","ditt wpa2 passord")
wifi.sta.setip({ip="ip-adresse",netmask="subnet-maske",gateway="gateway-adresse"})

I tillegg fant jeg et bibliotekskrevet av Peter Scargill som håndterte ett stk ds18b20-sensor uten noe hassle

Filnavn: ds18b20.lua

--------------------------------------------------------------------------------
-- DS18B20 one wire module for NODEMCU
-- LICENCE: http://opensource.org/licenses/MIT
-- Vowstar <vowstar@nodemcu.com>
-- 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
setfenv(1,M)
--------------------------------------------------------------------------------
-- Implementation – you don’t get any shorter than this
--------------------------------------------------------------------------------

function readNumber(pin)
ow.setup(pin)
ow.reset(pin)
ow.write(pin, 0xCC, 1)
ow.write(pin, 0xBE, 1)
data = nil
data = ""
for i = 1, 2 do
data = data .. string.char(ow.read(pin))
end
t = (data:byte(1) + data:byte(2) * 256) / 16
if (t>100) then
t=t-4096
end
ow.reset(pin)
ow.write(pin,0xcc,1)
ow.write(pin, 0x44,1)
return t
end

-- Return module table
return M

Serverside laget jeg en php som returnerte <maxtemp> og <mintemp> i en særs forenklet xml – jeg kalte den for reg.php

reg.php har også fuksjonaliteten som poster currentTemp til mySQL-basen beer og tabellen dataLogger

filnavn reg.php

<?php

$scurrTemp = $_GET['currTemp'];
$srelayState = $_GET['relayState'];
$sqlServer = "localhost";
$sqlUser = "username"; //byttes ut med din mysql bruker
$sqlDB = "beer";

//koble til databaseserver
$dbhandle = mysql_connect($sqlServer, $sqlUser,"mypassword")
 or die("Klarte ikke koble til $sqlServer");

// Koble til riktig database
$selected = mysql_select_db($sqlDB, $dbhandle)
 or die("Klarte ikke åpne $sqlDB");

$sql = "INSERT INTO datalogger (currTemp, relayState) VALUES(".$scurrTemp.",".$srelayState.")";

mysql_query($sql);
echo "<maxtemp>28</maxtemp>";
echo "<mintemp>26</mintemp>"

?>

datalogger-tabellen ser slik ut

mysql> describe datalogger;
+-------------+--------------+------+-----+-------------------+----------------+
| Field       | Type         | Null | Key | Default           |          Extra |
+-------------+--------------+------+-----+-------------------+----------------+
| id          | int(11)      | NO   | PRI | NULL              | auto_increment |
| currTemp    | decimal(7,4) | NO   |     | NULL              |                |
| relayState  | int(1)       | NO   |     | NULL              |                |
| tidsstempel | timestamp    | NO   |     | CURRENT_TIMESTAMP |                |
+-------------+--------------+------+-----+-------------------+----------------+

Også til slutt lua-koden for polling og posting av temperatur.
Det er nok sikkert veldig tydelig at lua ikke er et språk jeg påstår jeg behersker.

Filnavn; beercontrol13.lua

--- Beercontroller by tdegerdalen
--- version 0.13
--- uses ds18b20.lua by Peter Scargill 
--- uses networking.lua to configure wifi and static ip
---
--- todo: relaybug at startup (see below)
--- todo2: enable more sensors and average between them
---
---
--- note; to avoid memory issues this script should be compiled before run

maxTemp = 20
minTemp = 18
currTemp = 0
relayState = 0

--define pin for one 1-wire dallas tempsensor.
sensorPin = 7

--define pins to control relay, set them to output
--relay module attached kicks in when pulled low
--bug: relay kicks in a few millisecs at boot - might fix it witch capacitator

relay1pin = 3
relay2pin = 4
gpio.mode(relay1pin,gpio.OUTPUT)
gpio.mode(relay2pin,gpio.OUTPUT)
gpio.write(relay1pin,gpio.HIGH)
gpio.write(relay2pin,gpio.HIGH)


--- triggers
--- every 5 seconds, poll tempsensor
--- every 30 seconds, post to net and get temperature thresholds

tmr.alarm(1, 5000, 1, function() pollTemp() end )
tmr.alarm(2, 30000, 1, function() postData() end )

--- functions below

function pollTemp()
 t=require("ds18b20") 
 currTemp = t.readNumber(sensorPin)
 print(currTemp) 
 print("maxtemp", maxTemp)
 if currTemp > maxTemp and relayState == 1 then
 relayOff()
 end
 if currTemp < minTemp and relayState == 0 and currTemp ~= -0.0625 then
 relayOn()
 end
 if currTemp == -0.0625 then
 relayOff()
 end
 t = nil 
 ds18b20 = nil 
 package.loaded["ds18b20"]=nil
end

function postData()
 conn=net.createConnection(net.TCP, 0) 
 conn:on("connection",function(conn, payload)
 conn:send("GET /beer/reg.php?currTemp="..currTemp.."&relayState="..relayState.." HTTP/1.1\r\n".. 
 "Host: 10.0.0.2\r\n"..
 "Accept: */*\r\n"..
 "User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)"..
 "\r\n\r\n") 
 end)
 
 conn:on("receive", function(conn, payload)
 tStreng,maxTempStart = string.find(payload,"<maxtemp>")
 maxTempEnd, tStreing = string.find(payload,"</maxtemp>")
 maxTempStart = maxTempStart + 1
 maxTempEnd = maxTempEnd - 1
 
 maxTempDeg = string.sub(payload, maxTempStart, maxTempEnd)

 tStreng,minTempStart = string.find(payload,"<mintemp>")
 minTempEnd, tStreing = string.find(payload,"</mintemp>")
 minTempStart = minTempStart + 1
 minTempEnd = minTempEnd -1
 minTempDeg = string.sub(payload, minTempStart, minTempEnd)

 print(minTempDeg, maxTempDeg)
 maxTemp = tonumber(maxTempDeg)
 minTemp = tonumber(minTempDeg)
 maxTempDeg = nil
 minTempDeg = nil
 conn:close()
 end)
 
 conn:connect(80,'10.0.0.2') 
end

function relayOn()
 relayState = 1
 print("RelayOn")
 gpio.write(relay1pin,gpio.LOW)
 gpio.write(relay2pin,gpio.LOW)
end

function relayOff()
 relayState=0
 print("RelayOff")
 gpio.write(relay1pin,gpio.HIGH)
 gpio.write(relay2pin,gpio.HIGH)
end
Dette innlegget ble publisert i Øl, Tech. Bokmerk permalenken.