SOTM
Published © CC BY-NC

NodeMCU ESP8266 with Lua - Moisture Sensor and Display

Make sure your tomatoes and basil have optimal soil moisture by building this moisture sensor with display - with NodeMCU and Lua.

BeginnerProtip1 hour1,689
NodeMCU ESP8266 with Lua - Moisture Sensor and Display

Things used in this project

Hardware components

NodeMCU ESP8266
×1
830 Reconfigurable / Extendable Solderless Breadboard
×1
Nokia 5110 LCD
×1
Moisture Sensor
×1

Software apps and online services

NodeMCU firmware
NodeMCU firmware

Story

Read more

Code

init.lua

Lua
Code to read and output moisture sensor. upload a init.lua to ensure it gets executed when device turns on or resets.
--[[
	Moisture Sensor with output to display - PCD8544 (Nokia 5110 LED)

      run only once post reset/turn on (init.lua)
      - show welcome screen for three seconds
      - average moisture using 10 sample reads over 5 seconds, while showing
        user a "please wait message"
      - output average moisture

      Moisture reading to remain on display until device is turned off or
      reset button is pressed.
      
	15 November 2018 
	Author: dante@serveronthemove.com.au
	Hardware:
		nodeMCU ESP8266(EX) Devkit V3
		8 pin Nokia 5110 84x48 display w PCD8544
		Moisture sensor with Analog output

	Wiring:
		PCD8544		->	NodeMCU 8266
		1 - RST		->	D0/GPIO16
		2 - CE (CS)	->	D8/GPIO15 - pull down with 10K to GND
		3 - DC		->	D4/GPIO2
		4 - DIN		->	D7/HMOSI
		5 - CLK		->	D5/HSCLK
		6 - VCC		->	D1/GPIO5
		7 - BL		->	Not used in this example
		8 - GND		->	GND

        Moisture S  ->  NodeMCU 8266
        VCC         ->  D2/GPIO4
        GND         ->  GND
        AO          ->  A0/ADC0
	nodeMCU Firmware Build
		built against the master branch and includes the following modules: adc, file, gpio, i2c, net, node, spi, timer, u8g2, uart, wifi, tls
		u8g2 - SPI - pcd8544_84x48 module
		u8g2 - fonts: 6x10_tf, 5x8)tf

     Note about a few - not so elegant code below.
     
     .. through the code we are using tmr.delay() to wait, before something
        else id done. Using tmr.delay is usually not a good idea as nothing
        else gets run. Seeing that all we do is a single sensor read, it is
        acceptable.
        For "parallel" execution this should be implemented with
        tmr.alarm()
--]]

-- PIN Variables 
PIN_CS  = 8 -- GPIO15, pull-down 10k to GND
PIN_DC  = 4 -- GPIO2
PIN_RES = 0 -- GPIO16
PIN_LCD = 1 -- GPIO5 - VCC to LCD (turn on/off)
PIN_MOI = 2 -- GPIO4 - VCC to Moisture Sensor (turn on/off)

M_BUS 	= 1
MOIST_R = 10 -- Number of values from moisture sensor to generate an average

function outputMoistureData()
    -- vars we will use
	local loop_ctr = 0
	local aggregate_reading = 0
	
	-- setup screen with please wait
	disp:clearBuffer() -- start with clean buffer
	disp:setFont(u8g2.font_6x10_tf) -- set 6x10 font
	disp:drawStr(1, 1, "Please wait")
	disp:drawStr(1, 9, "Checking Soil")
    disp:sendBuffer() -- sent buffer to display

    -- turn moisture sensor on
    gpio.write(PIN_MOI, gpio.HIGH)
    tmr.delay(500 * 1000) -- wait for it to settle
	-- take number of readings and provide average
	while (loop_ctr < MOIST_R) do
		aggregate_reading = aggregate_reading + adc.read(0)
		--print("aggregate_reading ="  .. aggregate_reading)
        loop_ctr = loop_ctr + 1;
        -- wait one second (ish) before next reading
	    tmr.delay(500 * 1000) -- wait for half of a second before next read
	end
    -- turn moisture sensor off once done (to preserve battery)
    gpio.write(PIN_MOI, gpio.LOW)
    
    -- calculate average and print out
    disp:clearBuffer() -- start with clean buffer
    disp:setFont(u8g2.font_6x10_tf) -- set 6x10 font
    disp:drawStr(1, 1, "Soil Moisture")
    disp:drawStr(1,12, "..." .. tostring(aggregate_reading/MOIST_R))

	disp:sendBuffer() -- sent buffer to display
end

--[[
    INITIALISE - Begin
--]]  
-- set and init PCD8544 and Moist.Sensor GPIO to output 
gpio.mode(PIN_LCD, gpio.OUTPUT)
gpio.write(PIN_LCD, gpio.LOW)
gpio.mode(PIN_MOI, gpio.OUTPUT)
gpio.write(PIN_MOI, gpio.LOW)

-- Initialise PCD8544 module and show welcome screen
gpio.write(PIN_LCD, gpio.HIGH)
spi.setup(M_BUS, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
disp = u8g2.pcd8544_84x48(M_BUS, PIN_CS, PIN_DC, PIN_RES)

disp:setFontRefHeightExtendedText()
disp:setContrast(125)
disp:setFontPosTop()

-- start welcome screen
disp:clearBuffer() -- start with clean buffer
disp:setFont(u8g2.font_6x10_tf) -- set 6x10 font
disp:drawStr(1, 1, "Moisture")
disp:drawStr(1, 9, "Sensor V 1.0")
disp:drawStr(2, 17, "by SOTM")
disp:sendBuffer() -- sent buffer to display

--[[
    INITIALISE - End
--]]  

-- show moisture sensor data after 5 secs
--tmr.alarm(  0, 3000, tmr.ALARM_SINGLE, 
tmr.delay(3000 * 1000) -- wait for three seconds before sensor read
outputMoistureData()
-- wait for 2 minutes and then turn LCD off
tmr.delay(2 * 60 * 1000 * 1000)
gpio.write(PIN_LCD, gpio.LOW)
-- and done

Credits

SOTM
7 projects • 4 followers

Comments