Somsak Lima
Published

7 in 1 Sensor with LoRaWAN RS485 Modbus

NPK Sensor, PH, EC, Moisture, Temperature Sensor RS485 Modbus

IntermediateFull instructions provided6,091
7 in 1 Sensor with LoRaWAN RS485 Modbus

Things used in this project

Hardware components

ESP32 Development board HW-573
×1
7 in 1 NPK, PH, EC, Temp, Humid Soil Sensor
×1
MAXIIOT DL7612-AS923-TH with Antenna and PCB Adapter
×1
Automatic Switch RS485 TO TLL 232 Converter 5V Version
×1
OLED white 0.96 inch 128X64
×1
Breadboard Size 16.5X5.5x1 cm.
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian
Chirpstack
Influxdb
Grafana
Modbus Library for MicroPython
OLED SSD1306.py
thonny MicroPython IDE
RS485ControlV21.exe

Story

Read more

Schematics

ESP32 RS485

Code

7 in 1 Soil Sensor RS485 Modbus

MicroPython
7 in 1 Soil Sensor RS485 Modbus
Modbus lib https://github.com/techbase123/micropython-modbus
# By Somsak Lima and Itti  Srisumalai 
import machine
import ssd1306
from ssd1306 import SSD1306_I2C
import ure
import binascii
import time, ubinascii
from machine import UART, Pin, SoftI2C, ADC
from struct import unpack
from cayennelpp import CayenneLPP
from time import sleep
from micropython import const
from struct import *
import utime as time
import _thread # for multi-threading

from uModBusSerial import uModBusSerial
modbus= uModBusSerial (1, baudrate=4800, pins=(32, 33))

pinScl      = 22  
pinSda      = 18  
addrOled    = 60  #0x3c
hSize       = 64  
wSize       = 128 
oledIsConnected = False

stop = False
LED_GPIO = const(2)  
led = machine.Pin( LED_GPIO, mode=machine.Pin.OUT ) 
led = Pin(2, Pin.OUT)
relay1 = Pin(12, Pin.OUT)

i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000) 
# Scan i2c bus and check if  OLED display are connected
print('Scan i2c bus...')
devices = i2c.scan()
if len(devices) == 0:
  print("No i2c device !")
else:
  print('i2c devices found:',len(devices))
  for device in devices: 
    if device == addrOled:
      oledIsConnected = True
    print(device)

uart = UART(2, 115200, timeout=300)
rstr=""
def sendATcommand(ATcommand):
    print("Command: {0}\r\n".format(ATcommand))
    print(ATcommand)
    uart.write("{0}\r\n".format(ATcommand))
    rstr=uart.read().decode('utf-8')
    print(rstr)
    return (rstr)

def check_downlink(led):
    global stop
    rstr=""
    while not stop:
        rstr=sendATcommand ('AT+NMGR')
        print("--Downlink Message--: {0}\r\n".format(rstr))
        time.sleep(5)
        if "NNMI" in rstr:
        #if "NMGR" in rstr:
            if "040064ff" in rstr:   # BABk/w== 
                print("Command1 Detected: On LED  =============>")
                relay1.value(1)
                time.sleep(5)

            elif "040000ff" in rstr:  # BAAA/w==
                print("Command1 Detected: Off LED  =============>")
                relay1.value(0)
                time.sleep(5)
            else:
                print("No Known Command Detect")

sendATcommand ('AT')
sendATcommand ('AT+INFO')
sendATcommand ('AT+APPEUI')
sendATcommand ('AT+DEVEUI')
sendATcommand ('AT+APPKEY')
sendATcommand ('AT+NCONFIG')
sendATcommand ('AT+CHSET')

###LOOP OTAA
sendATcommand('AT+NRB')
time.sleep(20.0)
rstr = sendATcommand("AT+CGATT")
tryno=1
while rstr != "+CGATT:1":
    rstr = sendATcommand("AT+CGATT")
    print("Respond String")
    print(rstr)
    if rstr.startswith("+CGATT:1"):
        print("*******OTAA OK*******")
        break
    print("Retry OTAA Continue")
    a=1234560
    b=str(tryno)
    print(b[-1:])
    if b[-1:]=="0":
       print("YES")
       sendATcommand('AT+NRB')
    else:
       print("NO")
    tryno=tryno+1

    time.sleep(20.0)
print("Join Success")
###END LOOP OTAA

time.sleep(5.0)

_thread.start_new_thread(check_downlink, (led,))

cnt = 1

slave_addr=0x01
starting_address=0x00
register_quantity=9
signed=True

while True:
    print( "\r\n\r\nPacket No #{}".format( cnt ) )

    register_value = modbus.read_holding_registers(slave_addr, starting_address, register_quantity, signed)

    print('Holding register value: ' + ' '.join('{:d}'.format(x) for x in register_value))
    print('')
    print('')
    print ('Temp           :',register_value[1]/10,' C')
    print ('Moisture       :',register_value[0]/10,' %')
    print ('Conductivity   :',register_value[2],' us/cm')
    print ('PH             :',register_value[3]/10,' PH')
    print ('Nitrogen (N)   :',register_value[4],' mg/kg,mg/L')
    print ('Phosphorus (P) :',register_value[5],' mg/kg,mg/L')
    print ('Potassium (K)  :',register_value[6],' mg/kg,mg/L')
    print ('Salinity       :',register_value[7],' ppt')
    print ('TDS            :',register_value[8],' mg/L')
    if oledIsConnected:
      oled=ssd1306.SSD1306_I2C(128,64,i2c)
      oled.fill(0)
         
      oled.text("PH "+str(register_value[3]/10), 0, 0)
      oled.text("N "+str(register_value[4]), 0, 10)
      oled.text("P "+str(register_value[5]), 0, 20)
      oled.text("K "+str(register_value[6]), 0, 30)
      oled.text("Temp "+str(register_value[1]/10), 50, 0)
      oled.text("Mois "+str(register_value[0]/10), 50, 10)
      oled.text("Cond "+str(register_value[2]), 50, 20)
      oled.show()
    
    c = CayenneLPP()
    c.addTemperature(2, register_value[1]/10) 
    c.addRelativeHumidity(3, register_value[0]/10) 
    c.addLuminosity(4, register_value[4])
    c.addLuminosity(5, register_value[5])
    c.addLuminosity(6, register_value[6])
    c.addAnalogInput(7, register_value[2])
    c.addAnalogInput(8, register_value[3]/10)
    c.addAnalogInput(9, register_value[7])
    c.addAnalogInput(10, register_value[8])
  
    b = (ubinascii.hexlify(c.getBuffer()))
    print('************    Sending Data Status   **************')
    led.value(1)
    ATresp=sendATcommand("AT+NMGS={0},{1}".format(int(len(b)/2),(b.decode('utf-8'))))
    print('********Finish Sending & Receiving Data Status******')
    led.value(0)
    cnt = cnt + 1
    time.sleep(20.0)

7 in 1 Soil Sensor RS485 Modbus

MicroPython
Read values and display on screen
# By Somsak Lima and Itti  Srisumalai 
#https://github.com/techbase123/micropython-modbus
from machine import UART
import time
from time import sleep
from uModBusSerial import uModBusSerial
modbus= uModBusSerial (1, baudrate=4800, pins=(32, 33))

slave_addr=0x01
starting_address=0x00
register_quantity=9
signed=True
register_value = modbus.read_holding_registers(slave_addr, starting_address, register_quantity, signed)

print('Holding register value: ' + ' '.join('{:d}'.format(x) for x in register_value))
print('')
print('')
print ('Moisture       :',register_value[0]/10,' %')
print ('Temp           :',register_value[1]/10,' C')
print ('Conductivity   :',register_value[2],' us/cm')
print ('PH             :',register_value[3]/10,' PH')
print ('Nitrogen (N)   :',register_value[4],' mg/kg,mg/L')
print ('Phosphorus (P) :',register_value[5],' mg/kg,mg/L')
print ('Potassium (K)  :',register_value[6],' mg/kg,mg/L')
print ('Salinity       :',register_value[7],' ')
print ('TDS            :',register_value[8],' ')

Credits

Somsak Lima
1 project • 2 followers
Contact

Comments

Please log in or sign up to comment.