0

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?

0 Answers0