viernes, 25 de agosto de 2023

Tesys T LTMR + Gambas3 + Modbus + V0.01

 Todavía falta codear mas funciones de MODBUS, versión 0.01




Tesys T LTMR + Gambas3 + Modbus + V0.01

' Gambas class file


Public DatoRegistro As String

Public DatoINT[256] As Integer



Public Sub Socket1_Closed()

  PictureBox8.Picture = Picture.Load("led_verde_off.png") 

  

End



Public Sub Socket1_Ready()

PictureBox8.Picture = Picture.Load("led_verde_on.png")

  

End


Public Function BIN_DEC(Binario As String, n As Integer) As Integer

  Dim L, i, e, Entero As Integer  

  

  e = 0   

   

  For i = n To 0 Step -1

    If Binario[i] = "1" Then

      Entero = Entero + 2 ^ e

    Endif

    e = e + 1

  Next

  

  Return Entero

End


Public Function DEC_BIN(Decimal As Integer) As String

  Dim i As Integer  

  Dim CadenaBit As String

    

  For i = 0 To 15

    If (Decimal % 2 == 1) Then 

     CadenaBit = CadenaBit & "1"

    Else 

     CadenaBit = CadenaBit & "0"

    End If     

    Decimal = Decimal / 2   

  Next  

  

  Return (Byte[].FromString(CadenaBit)).Reverse().ToString()

End


Function Leer_MDBUS_TCP(Registro As Integer) As String

  Dim i, l As Integer

  Dim Byte_LO As String

  Dim Byte_HI As String

  

  Escribir_MODBUS_TCP(0, 3, Registro, 1) 

  

  l = Len(DatoRegistro)

  

  For i = 0 To l 

    DatoINT[i] = Asc(DatoRegistro[i])

  Next


  'For i = 0 To l 

  '  Print i, DatoINT[i], DEC_BIN(DatoINT[i])

  'Next

  

  Byte_LO = Right$(DEC_BIN(DatoINT[10]), 8)

  Byte_HI = Right$(DEC_BIN(DatoINT[9]), 8)

  

  Return Byte_HI & Byte_LO        

End



Public Sub Escribir_MODBUS_TCP(Direccion As Integer, CodigoFuncion As Integer, DireccionRegistro As Integer, Dato As Integer)

Dim TRAMA As New Integer[256]

Dim DATO_TX As String

Dim BIN, HI, LO As String


'Identificador de la transaccion

TRAMA[0] = 0

TRAMA[1] = 0


'Identificador del protocolo 0 para modbus

TRAMA[2] = 0

TRAMA[3] = 0


'Numero de bytes en esta trama

TRAMA[4] = 0

TRAMA[5] = 6


'Direccion del dispositivo

TRAMA[6] = Direccion


'Codigo de funcion

TRAMA[7] = CodigoFuncion


'Direccion registro

BIN = DEC_BIN(DireccionRegistro)


HI = Mid$(BIN, 1, 8)

LO = Mid$(BIN, 9, 16)


TRAMA[8] = BIN_DEC(HI, 7)

TRAMA[9] = BIN_DEC(LO, 7)


'Datos del registro

BIN = DEC_BIN(Dato)

HI = Mid$(BIN, 1, 8)

LO = Mid$(BIN, 9, 16)


TRAMA[10] = BIN_DEC(HI, 7)

TRAMA[11] = BIN_DEC(LO, 7)


DATO_TX = Chr$(TRAMA[0]) & Chr$(TRAMA[1]) & Chr$(TRAMA[2]) & Chr$(TRAMA[3]) & Chr$(TRAMA[4]) & Chr$(TRAMA[5]) & Chr$(TRAMA[6]) & Chr$(TRAMA[7]) & Chr$(TRAMA[8]) & Chr$(TRAMA[9]) & Chr$(TRAMA[10]) & Chr$(TRAMA[11]) 

 

If (Socket1.Status = Net.Connected) Then 

  Write #Socket1, DATO_TX, Len(DATO_TX)  

Endif 


End


Public Sub Cerrar_Click()

 Escribir_MODBUS_TCP(0, 6, 704, 1)

  

End

Public Sub Socket1_Error()

 Select Case Socket1.Status

 Case Net.CannotCreateSocket

 Message.Error("El sistema no permite crear un socket")

 Case Net.HostNotFound

 Message.Error("Host no encontrado")

 Case Net.ConnectionRefused

 Message.Error("No es posible conectar. La solicitud fue rechazada")

 Case Net.CannotRead

 Message.Error("Error leyendo datos")

 Case Net.CannotWrite

 Message.Error("Error escribiendo datos")

 End Select

End


Public Sub Abrir_Click()


  Escribir_MODBUS_TCP(0, 6, 704, 0)


End


Public Sub Conectar_Click()

Socket1.Host = TextBox1.Text

Socket1.Port = Val(TextBox2.Text)

Socket1.Connect()


 


End


Public Sub Timer1_Timer()

Dim BITs As String

Dim Entero As Integer


If (Socket1.Status = Net.Connected) Then 

  BITs = Leer_MDBUS_TCP(459) 

  Print BITs 

   

   If BITs[3] = "1" Then   

     PictureBox3.Picture = Picture.Load("contactor_close.png")    

   Else If BITs[3] = "0" Then 

     PictureBox3.Picture = Picture.Load("contactor_open.png")    

   Endif

   

    If BITs[2] = "1" Or BITs[14] = "1" Then   

     PictureBox2.Picture = Picture.Load("Interruptor_close.png")    

   Else If BITs[2] = "0" Or BITs[14] = "0" Then 

     PictureBox2.Picture = Picture.Load("Interruptor_open.svg.png")    

   Endif

Endif  



End


Public Sub O2_Click()


  Escribir_MODBUS_TCP(0, 6, 704, 2)


End


Public Sub Reset_Click()


  Escribir_MODBUS_TCP(0, 6, 704, 8)


End


Public Sub Socket1_Read()

  

 Read #Socket1, DatoRegistro, Lof(Socket1)  


End



Public Sub Form_Open()

 Timer1.Enabled = True


End


martes, 8 de agosto de 2023

Tesys T LTMR + pymodbus + Tkinter

 Observen que al darle al boton ON 0 cambiamos de estado la salida O1 del  Tesys T, de esta manera podemos probar nuestro LTMR en forma remota. Recuerden el I6 en estado alto para remoto.







Tesys T LTMR + pymodbus + Tkinter

from Tkinter import *

import os
import MySQLdb
from pymodbus.client.sync import ModbusTcpClient

#-------------------------------------------------------

#-------------------------------------------------------
def decbin(numero):
  cadenabin = ""	
  for i in range(1,17):  
    resultado = numero / 2
    resto = numero % 2
    if resto == 0:
      cadenabin = cadenabin + "0"
    else:
      cadenabin = cadenabin + "1"
		
    numero=resultado

  return cadenabin

def FUNC_OFF_a():
    cliente.write_register(704, 0b0000000000000000)

def FUNC_ON_a():
    cliente.write_register(704, 0b0000000000000001)

def FUNC_WRITE():
    dato = entrada.get()
    print dato
    dato = int(dato)
    cliente.write_register(652,dato)

def FUNC_ON_b():
    cliente.write_register(704, 0b0000000000000010)

def FUNC_Reset():
    cliente.write_register(704, 0b0000000000001000)

def FUNC_Kill():
    print ("Cuidado !")
    cliente.write_register(705, 0b0000000000011111)


def FUNC_Estado():
    estado = cliente.read_holding_registers(455,1)
    datos = estado.registers[0]
    print("-------------------------------------")
    print ("Registro 455")
    #print datos
    print decbin(datos)
    if (datos & 1): print ("Sistema listo")
    if (datos & 2): print ("Sistema activado")
    if (datos & 4): print ("Sistema fallo")
    if (datos & 8): print ("Sistema advertencia")
    if (datos & 16): print ("Sistema disparo")
    if (datos & 32): print ("Reinicio de fallo autorizado")
    if (datos & 64): print ("Controlador potencia\n")

    print("-------------------------------------")
    estado = cliente.read_holding_registers(457,1)
    datos = estado.registers[0]
    print ("Registro 457")
    #print datos
    print decbin(datos)

    if (datos & 1): print ("E1 Start")
    if (datos & 2): print ("E2 Close O2")
    if (datos & 4): print ("E3 Free")
    if (datos & 8): print ("E4 Stop O1 O2")
    if (datos & 16): print ("E5 Reset")
    if (datos & 32): print ("E6 L/R")





#    VENT_Estados = Tk()
#    VENT_Estados.title("LTMR Tesys T - Estados -")
#    VENT_Estados.minsize(300,200)

#    texto = Label(VENT_Estados, text="Estado LTMR")
#    texto.pack()
    



#-------------------------------------------------------
cliente = ModbusTcpClient('192.168.4.169','502')
cliente.connect()

#-------------------------------------------------------
# MAIN LOOP

VENTANA = Tk()
VENTANA.title("LTMR Tesys T")
VENTANA.minsize(250,200)


texto = Label(VENTANA, text="Comandos LTMR")
texto.pack()

ON_Img = PhotoImage(file="ON.png")
imagen = ON_Img.subsample(10,10)

ON_a = Button(VENTANA, text="ON 0", width=8, height=1, command=FUNC_ON_a, bg="green")
ON_a.pack()


OFF_a = Button(VENTANA, text="OFF 0", width=8, height=1, command=FUNC_OFF_a)
OFF_a.pack()


ON_b = Button(VENTANA, text="ON 1", width=8, height=1, command=FUNC_ON_b, bg="green")
ON_b.pack()


#---------------------------------------------------------------------------
entrada = StringVar()
corriente = Entry(VENTANA, width=10, textvariable=entrada)
corriente.pack()


OFF_b = Button(VENTANA, text="WRITE", width=8, height=1, command=FUNC_WRITE)
OFF_b.pack()
#---------------------------------------------------------------------------

RESET = Button(VENTANA, text="Reset", width=8, height=1, command=FUNC_Reset)
RESET.pack()

ESTADO = Button(VENTANA, text="Estado", width=8, height=1, command=FUNC_Estado)
ESTADO.pack()


KILL = Button(VENTANA, text="Kill", width=8, height=1, bg="red", command=FUNC_Kill)
KILL.pack()


VENTANA.mainloop()
cliente.close()

jueves, 14 de julio de 2022

lunes, 8 de noviembre de 2021

Linux - error con avrdude con libusb

El problema surgio al ejecutar  avrdude  -v

avrdude: symbol lookup error: /lib/x86_64-linux-gnu/libhidapi-libusb.so.0: undefined symbol: libusb_handle_events_completed

solucionamos de la siguiente manera, en la consola

export LD_LIBRARY_PATH="/lib/x86_64-linux-gnu/"


domingo, 7 de febrero de 2021

PLC M340 - Problemas con el FBD ADD - suma numeros reales

El inconveniente surgió cuando al corregir el valor del contador, el mismo sufría un desplazamiento, se atrasaba o se adelantaba. 

Tenemos un caudalimetro de gas, el cual produce un pulso cada tantas vueltas indicando un cambio en el primer decimal.

Observamos que justo en la foto esta por cambiar el primer decimal y a la vez el caudalimetro produciría un pulso, el cual va un pin de entrada de una ER.

 
 
En la imagen tenemos varios FBD, donde  ADD esta seteado de la siguiente manera:

VOL_CONS_CALENTADOR = VOL_CONS_CALENTADOR + 0,1  por cada pulso.

Al simular observamos lo siguiente:

 

Vemos que al simular un par de pulsos la suma paso a tener varios decimales, en la siguiente imagen vamos a poder apreciar el desplazamiento que ocurre.

La solución fue la siguiente, tomando en cuenta de no modificar el tipo de dato esperado en el scada.

AUX = AUX + 1.0  por cada pulso.

VOL_CONS_CALENTADOR = AUX / 10.0

En la simulación observamos que los decimales extras ya no estan "presentes", al dar 23 pulsos.



lunes, 25 de mayo de 2020

PLC M580 en modo STOP PLCDiagCom

Comparto la siguiente experiencia con un PLC M580 por algún motivo paso a modo STOP, al no tener el software UnityPro y su proyecto encontré una solución en el siguiente link. https://www.se.com/es/es/faqs/FA150522/ .
Donde use VirtualBox para poder correr la aplicación, el cual usa modbus y codigos de funciones de Schneider Electric (code 90), podemos observar mas en las siguientes capturas de pantalla. https://www.tenable.com/plugins/nessus/97436


lunes, 18 de mayo de 2020

Gambas3 cliente MODBUS RTU - Fase en desarrollo

' Gambas class file

Public ADU[254] As Integer
Public Nregistros As Integer
Public Nbytes As Integer
Public BYTES[1024] As Integer

' Conectar al puerto serie

Public Sub Button2_Click()

  SerialPort1.PortName = TextBox1.Text
  SerialPort1.Speed = TextBox2.Text  
  SerialPort1.Open()  
  
  TextBox6.text = "Puerto : " & SerialPort1.PortName & " Configuracion : " &  
  SerialPort1.Speed & "," & SerialPort1.Parity & "," & SerialPort1.DataBits & "," & SerialPort1.StopBits
  
  Button1.Enabled = True
  Button4.Enabled = True
  Button2.Enabled = False

End

' Desconectar del puerto serie
Public Sub Button4_Click()

  SerialPort1.Close()
  TextArea1.text = TextArea1.text & SerialPort1.Status
  
  Button4.Enabled = False
  Button2.Enabled = True
End

' Salir de la aplicacion

Public Sub Button3_Click()
  SerialPort1.Close()
  Quit
End

Public Sub Button5_Click()
  TextArea3.Clear()
  TextArea1.Clear()
End

' Envio de la consulta modbus
Public Sub Button1_Click()
  Dim DireccionHI As Integer
  Dim DireccionLO As Integer
  Dim DatoHI As Integer
  Dim DatoLO As Integer
  Dim ID As Integer
  Dim Funcion As Integer  
  Dim CRCLO, CRCHI, i As Integer
  Dim CRC As String
   
  Nbytes = 0
  TextArea2.text = TextArea2.text & "\n"
   
  'ID
  ADU[0] = TextBox3.text
  
  'Funcion
  ADU[1] = ComboBox1.Index + 1
  
  'Direccion HI
  ADU[2] = 0
  
  'Direccion LO
  ADU[3] = SpinBox1.Text
  
  'Numero de registros/DATO HI
  If ((ComboBox1.Index + 1) = 5) Or ((ComboBox1.Index + 1) = 6) Then
    ADU[4] = TextBox5.Text
  Else
    ADU[4] = 0
  Endif
  
  'Numero de registros/DATO LO
  If ((ComboBox1.Index + 1) = 5) Or ((ComboBox1.Index + 1) = 6) Then
     ADU[5] = TextBox4.Text
  Else  
     ADU[5] = SpinBox2.Text
  Endif
  
  Nregistros = SpinBox2.Text
  
  CRC = Hex(CRC16(5))
  
  If Len(CRC) < 4 Then
    ADU[6] = HEX_DEC(Right$(CRC, 2))
    ADU[7] = HEX_DEC(Left$(CRC, 1))    
  Else
    ADU[6] = HEX_DEC(Right$(CRC, 2))
    ADU[7] = HEX_DEC(Left$(CRC, 2))    
  Endif
  
  For i = 0 To 1
    TextArea1.Text = TextArea1.text & i & ":" & ADU[i] & "  "    
  Next
  TextArea1.Text = TextArea1.text & "\n"
  
  For i = 2 To 7
    TextArea3.Text = TextArea3.text & i & ":" & ADU[i] & "  "    
  Next
  TextArea3.Text = TextArea3.text & "\n"
  
    
  For i = 0 To 7
    Write #SerialPort1, Chr$(ADU[i])
  Next
End


Function CRC16(n As Integer) As Integer
  Dim i, pos As Integer 
  Dim CRC As Integer
  CRC = 65535 
  
  For pos = 0 To n
    CRC = CRC Xor ADU[pos]    
    For i = 0 To 7
      If ((CRC And 1) <> 0) Then
        CRC = Lsr(CRC, 1)
        CRC = CRC Xor 40961
      Else
        CRC = Lsr(CRC, 1)  
      Endif    
    Next
  Next
  
 Return CRC
End

Function HEX_DEC(aux As String) As Integer
  Dim a, b, c, l As Integer
  Dim d As String
  c = 0

  l = Len(aux)
  For a = 1 To l
    d = Mid$(aux, a, 1)
    Select Case d
      Case "A"
        b = 10
      Case "B"
        b = 11
      Case "C"
        b = 12
      Case "D"
        b = 13
      Case "E"
        b = 14
      Case "F"
        b = 15
      Case Else
        b = CInt(d)
    End Select   
   
    c = c + (b * 16 ^ (l - a))    
   
  Next    
  Return c
End

'Recepcion de datos seriales 
Public Sub SerialPort1_Read()
  Dim DATO_BYTE As String
      
  Read #SerialPort1, DATO_BYTE, 1  
    
  TextArea2.text = TextArea2.text & Nbytes & ":" & Hex(Asc(DATO_BYTE)) & "  "   
  
  Nbytes = Nbytes + 1
   
 End


Public Sub Button6_Click()
  TextArea2.Clear()

End

Public Sub Form_Open()

  Nbytes = 0
  
End

Public Sub Button7_Click()

  TextArea2.text = TextArea2.text & "\n"

End

 
 

miércoles, 6 de mayo de 2020

App Inventor Arduino MLX90614 - Prueba

#include <Wire.h>;
#include <Adafruit_MLX90614.h>;
 
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

String inputString = "";       
bool stringComplete = false; 

//-----------------------------------------------
//                 CONFIGURACION
//-----------------------------------------------
void setup() {

  inputString.reserve(32);
  Serial.begin(9600); 
  mlx.begin();  
}

//-----------------------------------------------
//                  MAIN
//-----------------------------------------------
void loop() {  
  
  if (stringComplete) {
    if(inputString.substring(0,2)=="MT"){
      
     Serial.print(mlx.readAmbientTempC()); 
     Serial.print("/"); 
     Serial.print(mlx.readObjectTempC());
  } 

    
    inputString = "";
    stringComplete = false;
  }  
}

//-----------------------------------------------
void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}
//----------------------------------------------- 
 
 

lunes, 23 de marzo de 2020

Sistema de observacion de seguridad

Programa creado con App Inventor para facilitar hacer observaciones al personal durante la realizacion de alguna tarea, fase a prueba.

Link de descarga:
sos.apk

lunes, 22 de julio de 2019

Planilla de recorrida Wartsila 18V50 SG v0.1

Planillas creadas para realizar la ronda de operaciones, estado en prueba.

Planilla de recorrida Lectura del fuelle

viernes, 7 de diciembre de 2018

pymodbus TCP cliente mysql tabla - ejemplo

Enscript Output
 Crear primero la BD llamada MODBUS_SCADA

 CREATE TABLE  ReadCoils (
     idReadCoils INT NOT NULL AUTO_INCREMENT,
     CO1    CHARACTER,
     CO2    CHARACTER,
     CO3    CHARACTER,
     CO4    CHARACTER,    
     CO5    CHARACTER,
     CO6    CHARACTER,
     CO7    CHARACTER,
     CO8    CHARACTER, 
     PRIMARY KEY (idReadCoils)
 ) ENGINE=InnoDB;

 CREATE TABLE ReadDiscreteInput (
     idReadDiscreteInput INT NOT NULL AUTO_INCREMENT,
     DI1    CHARACTER,
     DI2    CHARACTER,
     DI3    CHARACTER,
     DI4    CHARACTER,    
     DI5    CHARACTER,
     DI6    CHARACTER,
     DI7    CHARACTER,
     DI8    CHARACTER, 
     PRIMARY KEY (idReadDiscreteInput)
 ) ENGINE=InnoDB;

 CREATE TABLE ReadHoldingRegisters (
     idReadHoldingRegisters INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
     HR1    INT,
     HR2    INT,
     HR3    INT,
     HR4    INT,
     HR5    INT,
     HR6    INT,
     HR7    INT,
     HR8    INT
 ) ENGINE=InnoDB;

 CREATE TABLE ReadInputRegisters (
     idReadInputRegisters INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
     IR1    INT,
     IR2    INT,
     IR3    INT,
     IR4    INT,
     IR5    INT,
     IR6    INT,
     IR7    INT,
     IR8    INT
 ) ENGINE=InnoDB;





Generated by GNU Enscript 1.6.5.90.

pymodbus TCP cliente mysql - ejemplo

Enscript Output
import os
import MySQLdb
from pymodbus.client.sync import ModbusTcpClient

cliente = ModbusTcpClient('127.0.0.1','5020')
#---------------------------------------------------------------------------# 
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

Dispositivo = 1
#---------------------------------------------------------------------------#
def CONSULTA_SQL(COMANDO, DISPOSITIVO, a, b, c, d, e, f, g, h): 
  coneccion = MySQLdb.connect("localhost","root","holanena69","MODBUS_SCADA")
  BD = coneccion.cursor()

  if COMANDO == 1:
    BD.execute("""INSERT INTO ReadCoils (CO1, CO2, CO3, CO4, CO5, CO6, CO7, CO8) VALUES (%c, %c, %c, %c, %c, %c, %c, %c)""",(a, b, c, d, e, f, g, h))

  elif COMANDO == 2:
    BD.execute("""INSERT INTO ReadDiscreteInput (DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8) VALUES (%c, %c, %c, %c, %c, %c, %c, %c)""",(a, b, c, d, e, f, g, h))

  elif COMANDO == 3:
    BD.execute("""INSERT INTO ReadHoldingRegisters (HR1, HR2, HR3, HR4, HR5, HR6, HR7, HR8) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)""",(a, b, c, d, e, f, g, h))

  elif COMANDO == 4:  
    BD.execute("""INSERT INTO  ReadInputRegisters (IR1, IR2, IR3, IR4, IR5, IR6, IR7, IR8) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)""",(a, b, c, d, e, f, g, h))

  coneccion.commit() 

  BD.close()
  coneccion.close()

#---------------------------------------------------------------------------#    
os.system('clear')

print "Read Coils"
request = cliente.read_coils(0x0,0x8,unit=Dispositivo)
print request.bits[0]
print request.bits[1]
print request.bits[2]
print request.bits[3]
print request.bits[4]
print request.bits[5]
print request.bits[6]
print request.bits[7]

CONSULTA_SQL(1,0,request.bits[0], request.bits[1], request.bits[2], request.bits[3], request.bits[4], request.bits[5], request.bits[6], request.bits[7])


print "Read Discrete Input"
request = cliente.read_discrete_inputs(0x0,0x8,unit=Dispositivo)
print request.bits[0]
print request.bits[1]
print request.bits[2]
print request.bits[3]
print request.bits[4]
print request.bits[5]
print request.bits[6]
print request.bits[7]
CONSULTA_SQL(2,0,request.bits[0], request.bits[1], request.bits[2], request.bits[3], request.bits[4], request.bits[5], request.bits[6], request.bits[7])


print "Read Holding Registers"
request = cliente.read_holding_registers(0x0,0x7,unit=Dispositivo)
print request.registers
print type(request.registers[0])

CONSULTA_SQL(3,0,request.registers[0], request.registers[1], request.registers[2], request.registers[3], request.registers[4], request.registers[5], request.registers[6], 9)



print "Read Input Registers"
request = cliente.read_input_registers(0x0,0x7,unit=Dispositivo)
print request.registers
CONSULTA_SQL(4,0,request.registers[0], request.registers[1], request.registers[2], request.registers[3], request.registers[4], request.registers[5], request.registers[6], 9)



cliente.close()






Generated by GNU Enscript 1.6.5.90.

IRC

#freenode->#usljujuy

Seguidores

Eventos n_n

Tira Ecol Nano,Bilo y Luca