I wrote an application in Micropython for ESP32 to read the MODBUS TCP registers of a photovoltaic inverter, the MODBUS RTU registers of PZEM 004T sensors, read and write some data obtained in the Firebase Realtime database. It turns out that after some time running, a very small Buffer error appears. Another problem occurs when the inverter is turned off at night and the MODBUS slave address becomes unavailable. The code is unstable, crashes all the time even using "try: and except: The complete code is below:
import network
import time
from umodbus.tcp import TCP as ModbusTCPMaster
from umodbus.serial import Serial as ModbusRTUMaster
from lcd_i2c import LCD
from machine import I2C, Pin
import ujson as json
import urequests as requests
host_status= True
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
FREQ = 800000
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=FREQ)
lcd = LCD(addr=I2C_ADDR, cols=I2C_NUM_COLS, rows=I2C_NUM_ROWS, i2c=i2c)
lcd.begin()
lcd.clear()
lcd.backlight()
pzem1 = ModbusRTUMaster(
pins=(12,14),
uart_id=1
)
pzem2 = ModbusRTUMaster(
pins=(17,16),
uart_id=2
)
SSID = "my SSID"
PSWD="My Passwd"
Modbus_slave_IP = "192.168.0.130"
wifi = network.WLAN(network.STA_IF)
if wifi.isconnected():
wifi.disconnect()
wifi.active(False)
time.sleep(2)
wifi.active(True)
debug_status = False
lcd.set_cursor(col=0, row=0)
lcd.print("Conectando WiFi ")
col_curs=0
carac="."
while not wifi.isconnected():
lcd.set_cursor(col=col_curs, row=1)
lcd.print(carac)
try:
wifi.connect(SSID,PSWD)
except Exception as wif_err:
lcd.set_cursor(col=col_curs, row=1)
lcd.print(carac)
col_curs = col_curs + 1
if ((col_curs>15) and (carac == ".")):
col_curs=0
carac = "o"
if (col_curs>15 and (carac =="o")):
col_curs=0
carac = "."
time.sleep(0.1)
try:
host = ModbusTCPMaster( slave_ip=Modbus_slave_IP, slave_port=502,timeout=5)
except Exception:
host_status = False
pass
LocalIP = wifi.ifconfig()[0]
Gateway = wifi.ifconfig()[2]
lcd.clear()
lcd.set_cursor(col=0, row=0)
lcd.print("WiFi CONECTADO " )
lcd.set_cursor(col=0, row=1)
lcd.print(LocalIP)
time.sleep(2)
lcd.clear()
first_time_code_run = True
def pzem_get():
try:
register_value_pzem_1 = pzem1.read_input_registers(
slave_addr=1,
starting_addr=0,
register_qty=9,
signed=False)
energ_pzem1 = str(register_value_pzem_1[5])+str(register_value_pzem_1[6])
energ_pzem1_value = int(energ_pzem1)
#print('pzem1',register_value_pzem_1)
register_value_pzem_2 = pzem2.read_input_registers(
slave_addr=2,
starting_addr=0,
register_qty=9,
signed=False)
energ_pzem2 = str(register_value_pzem_2[5])+str(register_value_pzem_2[6])
energ_pzem2_value = int(energ_pzem2)
#print('pzem2',register_value_pzem_2)
energ_pzem_total = (energ_pzem1_value + energ_pzem2_value)/10
except Exception as med_err:
energ_pzem_total = 0
pass
return energ_pzem_total
def initial_data():
inverter_data = modbus_get(1 ,0 ,51)
# energia consumida
e_ger = int(str(inverter_data[49])+str(inverter_data[50]))/100
# hora atualizada
if (inverter_data[3]<10):
hora_s="0"+str(inverter_data[3])
else:
hora_s= str(inverter_data[3])
if (inverter_data[4]<10):
minuto_s="0"+str(inverter_data[4])
else:
minuto_s=str(inverter_data[4])
hora_at = hora_s+":"+minuto_s
# data atualizada
if (inverter_data[2]<10):
dia_s="0"+str(inverter_data[2])
else:
dia_s= str(inverter_data[2])
if (inverter_data[1]<10):
mes_s="0"+str(inverter_data[1])
else:
mes_s=str(inverter_data[1])
data_at = dia_s+"-"+mes_s+"-"+str(inverter_data[0])
e_cons = round((pzem_get()/1000),2)
e_inj = round((e_ger - e_cons),2)
return data_at, hora_at, e_ger, e_cons, e_inj
def modbus_get(slave_id, reg_init, reg_size):
register_value = [0]*reg_size
try:
if (host_status):
register_value = host.read_input_registers(
slave_addr=slave_id,
starting_addr=reg_init,
register_qty=reg_size,
signed=False)
time.sleep(1)
except Exception as mod_err:
if (mod_err == "name 'host' isn't defined"):
print("Dispositivo MODBUS indisponível")
pass
return register_value
def get_db(_cliente, _id_usina, _mod_inv_NS, _dia_db):
res_db = [0]*6
try:
res_db = requests.get(url=f'https://monitoramento-solar-d85e5-default-rtdb.firebaseio.com/{_cliente}/{_id_usina}/{_mod_inv_NS}/{_dia_db}/.json?print=pretty')
except Exception as get_db_err:
res_db = [0]*6
pass
return res_db.json()
def get_comando(_cliente, _id_usina, _mod_inv_NS, _dia_db):
try:
res_com = requests.get(url=f'https://monitoramento-solar-d85e5-default-rtdb.firebaseio.com/{_cliente}/{_id_usina}/{_mod_inv_NS}/{_dia_db}/.json?print=pretty')
ret_res_com = res_com[0]
print(ret_res_com)
except OSError as get_com_err:
pass
return ret_res_com.json()
def put_db(_cliente, _id_usina, _mod_inv_NS, _dia_db, _dados):
if debug_status:
print()
print("Dados enviados:", json.dumps(_dados))
try:
res = requests.put(url=f'https://monitoramento-solar-d85e5-default-rtdb.firebaseio.com/{_cliente}/{_id_usina}/{_mod_inv_NS}/{_dia_db}/.json?print=pretty', data=json.dumps(_dados))
except Exception as put_db_err:
print("Erro na função put_db - ",put_db_err)
time.sleep(3)
def monit_command():
swap_command_value(cliente, id_usina, mod_inv_NS, dia_db, dados)
time.sleep(1)
def swap_command_value(_cliente, _id_usina, _mod_inv_NS, _dia_db,_dados):
global first_time_code_run
import ujson as json
import urequests as requests
try:
com=get_db(_cliente, _id_usina, _mod_inv_NS, _dia_db)
com_rec = com['Comando']
except Exception as get_com_err:
com_rec =0
pass
if (com_rec ==1 or first_time_code_run ):
first_time_code_run=False
inverter_data = modbus_get(1 ,0 ,51)
#print(inverter_data)
data_inv = initial_data()
_dia_db = data_inv[0]
_dados['Hora'] = data_inv[1]
_dados['Energia gerada'] = data_inv[2]
_dados['Energia consumida'] = data_inv[3]
_dados['Energia injetada'] = data_inv[4]
_dados['Comando'] = 0
lcd.set_cursor(col=0, row=0)
lcd.print(f'C:{data_inv[3]} G:{data_inv[2]}')
lcd.set_cursor(col=0, row=1)
lcd.print(f'I:{data_inv[4]} H:{data_inv[1]}')
try:
res = requests.put(url=f'https://monitoramento-solar-d85e5-default-rtdb.firebaseio.com/{_cliente}/{_id_usina}/{_mod_inv_NS}/{_dia_db}/.json?print=pretty', data=json.dumps(_dados))
except Exception as swap_command_value_err:
print("Erro na função swap_command_value -",swap_command_value_err)
if debug_status:
print("Command Field is 0")
time.sleep(2)
else:
pass
cliente = "Client Name"
cliente = cliente.replace(" ","_")
id_usina = "UFV001"
id_usina = id_usina.replace(" ","_")
mod_inv_NS = "Ingeteam 1play 3TL NS 000000000000"
mod_inv_NS = mod_inv_NS.replace(" ","_")
data_path = initial_data()
dia_db = data_path[0]
hora_db = data_path[1]
energia_g = data_path[2]
energia_c = data_path[3]
energia_i = data_path[4]
dados = {"Comando":0,
"Hora": hora_db,
"Energia gerada": energia_g,
"Energia consumida": energia_c,
"Energia injetada":energia_i
}
#print(dados)
#print(initial_data())
while True:
monit_command()
time.sleep(1)
How can I eliminate these errors?