nodeMCU dimmer/switch/temp.sensor without arduino

9 years 1 month ago #739 by EasyIoT

EasyIoT wrote:

First of all, nice to hear you got it working.

Regarding "christmas": do you have easyIoT open on more than one device?

If I have easyIoT opened on smartphone and pc at the same time, and change dimmer value, it sometimes goes crazy with the LEDs for me too. But the node itself is not the problem, it is more like if easyIoT is going into some kind of race condition, and values start changing rapidly and endlessly in the easyIoT console. It will never recover by itself from this state. If I restart easyIoT server, everythings fine again...


This is EasyIoT server beta 7 issue. Sometimes Dimmer control on virtual driver is going in loop and change values. It helps only if you restart server. I will fix that in final release.


If you are using EasyIoT server 0_7b2 just replace Ha.WebApp.js in easyiot\html\js folder with Ha.WebApp.js . Dimmer loop problem should be fixed. You need to restart EasyIoT server after replacing file.
The following user(s) said Thank You: cdj, Dennis

Please Log in or Create an account to join the conversation.

9 years 1 month ago - 9 years 1 month ago #742 by Dennis
Thanks.

With the replaced HA.WebApp.js, the dimmer wheel position is not updated anymore on the other clients (purely graphical problem; dimmer works).
Also, when I call now in automation code
ModuleHelper.SetProperty(m.Domain, m.Address, "Sensor.DimmerLevel", (Convert.ToInt32(p.Value)*100).ToString());
            	EventHelper.SetEvent(m.Domain, m.Address, "Sensor.DimmerLevel");

Then the wheel positions don't get updated anymore on the other clients (but the displayed numeric value is updated fine everywhere). Is there some helper method to *visually update* a module after setting its properties in code?

regards

Please Log in or Create an account to join the conversation.

9 years 1 month ago - 9 years 1 month ago #744 by Dennis

cdj wrote: Thanks a lot, tomorrow I try everything. But I think that optimal is to have TEMP AND HUM together... Suppose that in automation we can do a GETHUM request or something similar, but how to combine lua? We need two files dht22, one for temp and one for HUM???

Thanks again! :woohoo:


Hello,

here's working code for dimmer/switch on GPIO2, and DHT11 on GPIO0, and WITH BOTH TEMPERATURE AND HUMIDITY readout (new TCP command sent to nodeMCU is GETHUM).

dht22.lua:
------------------------------------------------------------------------------
-- DHT11/22 query module
--
-- LICENCE: http://opensource.org/licenses/MIT
-- Vladimir Dronnikov <dronnikov@gmail.com>
--
-- Example:
-- print("DHT11", dofile("dht22.lua").read(4))
-- print("DHT22", dofile("dht22.lua").read(4, true))
-- NB: the very first read sometimes fails
------------------------------------------------------------------------------
local M
do
  -- cache
  local gpio = gpio
  local val = gpio.read
  local waitus = tmr.delay
  --
  local read = function(pin, dht22, hum)
    -- wait for pin value
    local w = function(v)
      local c = 255
      while c > 0 and val(pin) ~= v do c = c - 1 end
      return c
    end
    -- NB: we preallocate incoming data buffer
    --     or precise timing in reader gets broken
    local b = { 0, 0, 0, 0, 0 }

    -- kick the device
    gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
    gpio.write(pin, 1)
    waitus(10)
    gpio.mode(pin, gpio.OUTPUT)
    gpio.write(pin, 0)
    waitus(20000)
    gpio.write(pin, 1)
    gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
    -- wait for device presense
    if w(0) == 0 or w(1) == 0 or w(0) == 0 then
      return nil, 0
    end
    -- receive 5 octets of data, msb first
    for i = 1, 5 do
      local x = 0
      for j = 1, 8 do
        x = x + x
        if w(1) == 0 then return nil, 1 end
        -- 70us for 1, 27 us for 0
        waitus(30)
        if val(pin) == 1 then
          x = x + 1
          if w(0) == 0 then return nil, 2 end
        end
      end
      b[i] = x
    end
    -- check crc. NB: calculating in receiver loop breaks timings
    local crc = 0
    for i = 1, 4 do
      crc = (crc + b[i]) % 256
    end
    if crc ~= b[5] then return nil, 3 end
    -- convert
    local t, h
    -- DHT22: values in tenths of unit, temperature can be negative
    if dht22 then
      h = (b[1] * 256 + b[2])
      t = (b[3] * 256 + b[4])
      if t > 0x8000 then t = -(t - 0x8000) end
    -- DHT11: no negative temperatures, only integers
    -- NB: return in 0.1 Celsius
    else
      h = (10 * b[1])
      t = (10 * b[3])
    end
    if hum then
       return h
    else   
       return t --, h
    end
  end
  -- expose interface
  M = {
    read = read,
  }
end
return M

init.lua:
--
--print("init")
--dofile("dht22.lua").read(4)
--tmr.delay(1000000)
--print("read")
--myval = dofile("dht22.lua").read(4)
--print(myval)
--


pwm.setup(3, 1000, 000)
pwm.start(3)

LED1_current=000
LED1_target=000

SWITCH1_state = 0

Fadetime1=1000

Stepcounter1=0
PosStepcounter1=0
DimTimer1=0


wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","PASSWORD")



srv=net.createServer(net.TCP) 
srv:listen(43333,function(conn) 
    conn:on("receive",function(conn,payload) 
   
    print("Input: "..payload) 
 
	if string.find(payload,"GETTEMP") then
	 print("Received temperature request")
	 --print("init")
      dofile("dht22.lua").read(4,false,false)
      tmr.delay(1000000)
      print("read")
      myval = (dofile("dht22.lua").read(4,false,false)/10)
      print(myval)
	 conn:send(myval)

     elseif string.find(payload,"GETHUM") then
      print("Received humidity request")
      --print("init")
      dofile("dht22.lua").read(4,false,true)
      tmr.delay(1000000)
      print("read")
      myval = (dofile("dht22.lua").read(4,false,true)/10)
      print(myval)
      conn:send(myval)

     elseif string.find(payload,"SWITCH1") then
     SWITCH1_state=tonumber(string.sub(payload, 9) )
     print("Received SWITCH1 target Value: "..SWITCH1_state)
     if SWITCH1_state == 1 then
          pwm.setduty(3, 1023)
          LED1_current = 1023
      elseif SWITCH1_state == 0 then
          pwm.setduty(3, 0)
          LED1_current = 0
        end
     

     
    elseif string.find(payload,"LED1") then
     LED1_target=tonumber(string.sub(payload, 13) )
     print("Received LED1 Target Value: "..LED1_target)

     Stepcounter1=(LED1_target)-(LED1_current)
     
     if (Stepcounter1) < 0 then
      PosStepcounter1=(Stepcounter1)*-1
      else PosStepcounter1=(Stepcounter1)
     end
     
     if (PosStepcounter1) == 0 then
      PosStepcounter1=(PosStepcounter1)+1
      else PosStepcounter1=(PosStepcounter1)
     end
          
     DimTimer1=(Fadetime1)/(PosStepcounter1)

     if (DimTimer1) == 0 then 
      DimTimer1=(DimTimer1)+1
      else DimTimer1=(DimTimer1)
     end

      print (Fadetime1)
      print (Stepcounter1)
      print (PosStepcounter1)
      print (DimTimer1)
      print (LED1_current)
      print (LED1_target)


    tmr.alarm(0, (DimTimer1), 1, function() 
     if LED1_current < LED1_target then 
      LED1_current = (LED1_current + 1) 
      pwm.setduty(3, LED1_current)
    elseif LED1_current > LED1_target then 
      LED1_current = (LED1_current - 1) 
      pwm.setduty(3, LED1_current)
    elseif LED1_current == LED1_target then tmr.stop(0)
     end end )
    

    end
    end)
    end)

print ("easyIoT dimmer/switch/temperature sensor for nodeMCU")
print ("Based on QuinLED_ESP8266_V0.4")

You need a virtual module set up as "Humidity (AI)", with just one property, "Sensor.Humidity".

Here's automation code for easyIoT (similar to temperature code, just adjust node IP address/module address, and the command is now "GETHUM" instead of GETTEMP...
const String ESP8266_IP_ADDRESS = "192.168.119.58";
const String NODE_ADDRESS = "N6S0";
/*
  This code is running one time when program is enabled
*/
public void Setup()
{
}
/*
  This code is running periodicaly when program is enabled. 
  Cron job detirmine running period.
*/
public void Run()
{
  String response = QueryServer("GETHUM");
  Console.WriteLine(response);
  ModuleHelper.SetProperty("Virtual", NODE_ADDRESS, "Sensor.Humidity", response.ToString());
  EventHelper.SetEvent("Virtual", NODE_ADDRESS, "Sensor.Humidity");
}
private static string QueryServer(String message)
{
try
	{
		Console.WriteLine("TCP client command: " + message + "\r\n");
		Int32 port = 43333;
		System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient( ESP8266_IP_ADDRESS, port);
		Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
		System.Net.Sockets.NetworkStream stream = client.GetStream();
		stream.Write(data, 0, data.Length);
		
		data = new Byte[256];
		String responseData = String.Empty;
		Int32 bytes = stream.Read(data, 0, data.Length);
		responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
		// Close everything.
		stream.Close();
		client.Close();
		return responseData;
	}
	catch(Exception e)
	{
		Console.WriteLine(e.StackTrace + "\r\n");
	}
		
return "0.00";
}

This is how it looks like now:




regards
Attachments:
The following user(s) said Thank You: cdj

Please Log in or Create an account to join the conversation.

9 years 1 month ago - 9 years 1 month ago #745 by EasyIoT

Dennis wrote: Thanks.

With the replaced HA.WebApp.js, the dimmer wheel position is not updated anymore on the other clients (purely graphical problem; dimmer works).
Also, when I call now in automation code

ModuleHelper.SetProperty(m.Domain, m.Address, "Sensor.DimmerLevel", (Convert.ToInt32(p.Value)*100).ToString());
            	EventHelper.SetEvent(m.Domain, m.Address, "Sensor.DimmerLevel");

Then the wheel positions don't get updated anymore on the other clients (but the displayed numeric value is updated fine everywhere). Is there some helper method to *visually update* a module after setting its properties in code?

regards


Yes, I've removed position update. If I update position, then event to send value is triggered again - this is why sometimes it goes in loop. So I've removed position update. I don't know better method to disable event when value is updated.

Please Log in or Create an account to join the conversation.

9 years 1 month ago - 9 years 1 month ago #746 by cdj
Amazing, and in the same way we can use :

BMP085 for BMP180 on the other GPIO ? but this sensor come with I2C data and I2C clock as pins.... how it works ? can we use only one "data" pin ?

In this way with one init.lua we can have a switch, a dimmer, a dht and a bmp ? i LOVE nodemcu without arduino.... so little space used...

Have you try to power up an "esp with dht" with two AA rechargeable? or pheraps it's better 3 ? (3,6v)....or pheraps esp power consumption is too high ?

Thanks for everything you are doing !
Dario

Please Log in or Create an account to join the conversation.

9 years 1 month ago - 9 years 1 month ago #748 by Dennis
Hello Dario,

I suppose it is possible, but I've no BMP080 or BMP180 here to test.
edit - but I think when it needs two pins, then we can only connect BMP sensor and nothing else with ESP-01 modules. And esp is very power-hungry, I had a node running on 9V block with regulator set to 3,3v, it lasted only one day...

Hello easyIoT,

If I update position, then event to send value is triggered again - this is why sometimes it goes in loop. So I've removed position update. I don't know better method to disable event when value is updated.


The "update" event is triggered by graphical change of wheel position? What about triggering separate "graphical update" event for wheel, when sensor value changes, without triggering another update event for value change?
So that you've got two events: one for "real" change in module's values (initiated by user or automation; which also triggers graphical change event), the other just for the graphical change of wheel position (triggers *no* other event)?
ATM the numeric dimmer value works just like this I think, even with new js script you provided, it is visually updated properly on all clients when changed. Without loop.

edit - or you need to somehow differenciate between "wheel changed by user interaction" and "wheel changed by graphical update mechanism" to get wheel position updates to work properly?

edit2 - or what about detaching the "value changed" event handler while updating the wheel position, and re-enable the event handler afterwards? Something like here: stackoverflow.com/questions/744494/winfo...ble-an-event-handler

regards
The following user(s) said Thank You: cdj

Please Log in or Create an account to join the conversation.

Time to create page: 0.523 seconds

Forum latest

  • No posts to display.