<jupyter_start><jupyter_text>Excitación del módulo  multivariable SIEMENS del PCJICEn el laboratorio de automática del Politécnico Colombiano <NAME> se encuentra un módulo multivariable que está controlado con un PLC  SIEMENS. Por esta razón, se utiliza el módulo `SNAP7` para interactuar con el PLC desde el notebook.Para instalar `SNAP7`:- Use la instrucción ~~~!pip install python-snap7==0.5~~~- Descargue la librería completa de [https://sourceforge.net/projects/snap7/files/1.2.1/](https://sourceforge.net/projects/snap7/files/1.2.1/)- Copie `snap7.dll` y `snap7.lib` a su carpeta `System32`.  1. Establezca conexión con el PLC.El PLC tiene configurada la dirección IP **192.168.0.1**. Este funcionará como un servidor al cuál debe conectar su PC configurándole una dirección estática dentro de la subred del PLC.  Su dirección puede ser **192.168.0.2**, por ejemplo. Una vez su equipo haya establecido comunicación con el PLC, establezca conexión desde el notebook con las siguientes instrucciones.<jupyter_code>#Conexión con el PLC
plc = c.Client()
IP_PLC = '192.168.0.1'
try:
    plc.connect(IP_PLC,0,1)
    print("Conectado")
except:
    print("Algo no funcionó")<jupyter_output>Conectado<jupyter_text>2. Identifique actuadores y sensores.Con `SNAP7` puede manipular los actuadores del sistema y capturar los datos de los sensores. Se han construido algunas funciones para facilitar la interacción con el PLC. Tenga en cuenta la siguiente información, que le orientará en cómo se ha conectado el sistema al PLC.|Elemento   |  Punto  ||-----------|---------|| Presión 	|    IW96 || Flujo		|    IW98 || Nivel		|   IW100 || Run Bomba	|    Q0.5 || Bomba		|    QW80 || Válvula H20 |  QW96 |<jupyter_code>#ESCRIBIR SALIDA BOOLEANA
def escr_sal_bool(byte, bit, valor):
    lectura = plc.ab_read(byte, bit)
    set_bool(lectura, byte, bit, valor)
    plc.ab_write(0, lectura)
#escr_sal_bool(0,1,1)

#ESCRIBIR SALIDA ENTERO
def escr_sal_ent(byte,valor):
    lectura = plc.read_area(areas['PA'], 0, byte, 2) #PA: salidas, 0: bloque de datos, dirección, # bytes.
    # print(lectura)
    set_int(lectura, 0, valor)  # se da formato al valor deseado, en este caso entero
    plc.write_area(areas['PA'], 0, byte, lectura)  # Escribe en la dirección definida
#escr_sal_ent(90,9000)

#LEER MARCA ENTERA
def leer_ent_ent(byte):
    leer = plc.read_area(areas['PE'],0,byte,2) #PE: entradas, 0: bloque de datos, dirección, # bytes.
    leer_ent = get_int(leer,0) #Comando get_int(_bytearray, byte_index)
    return leer_ent

def AbrirValvulaQW96(valvulap):
    # Abre la valvula en QW96 a un porcentaje determinado
    valvula = ((7800 / 71.5) * (valvulap - 7.4)) + 6200
    escr_sal_ent(96,valvula)
    

def BombaQW80(motobombaHz):
    #Poner bomba en 60Hz salida QW80
    motobomba = motobombaHz * (22118 / 60) + 5530
    escr_sal_ent(80,motobomba)

def leerNivelPLCIW100():
    nivelplc = leer_ent_ent(100)
    nivelcm = ((60 / 15105) * (nivelplc - 10125)) + 20
    # print(nivelplc, nivelcm)
    return nivelcm

def leerPresionPLCIW96():
    presionplc = leer_ent_ent(96)
    # 0.64 5679
    # 0.4  5623
    mp = (0.64-0.4)/(5679-5623)
    presion =  mp* presionplc - mp *5623+0.4
    # print(presionplc, presion)
    return presion


def leerFlujoPLCIW98():
    flujoplc = leer_ent_ent(98)
    # 4.67 8773 
    # 16.52  16957 
    mf = (4.67-16.52)/(8773-16957)
    flujo =  mf* flujoplc - mf *16957+16.52
    # print(flujoplc, flujo)
    return flujo

def leerNada():
    return np.random.rand(1)[0]<jupyter_output><empty_output><jupyter_text>3. Inicie el experimento.El módulo multivariable tiene:- 2 actuadores:    - Motobomba    - Válvula- 3 sensores:    - Flujo    - Presión    - Nivel3.1 Escoja una variable como salida y un actuador para su experimento.3.2 Ponga un punto de operación para el otro actuador.**Establecer un punto para la bomba**~~~BombaQW80(60)~~~**Establecer un punto para la válvula**~~~AbrirValvulaQW96(100)~~~<jupyter_code>escr_sal_bool(0,5,1) #Habilitar RUN motobomba
# Complete para establecer un punto de operación
BombaQW80(20)
AbrirValvulaQW96(100)<jupyter_output>bytearray(b']\x99')
bytearray(b'\x15\x10')<jupyter_text>5. Defina la entrada del sistemaEsta vez se configura una entrada en forma de un escalón.\begin{equation}U(t) = \begin{cases} V_0 & \forall t t_0 \end{cases}\end{equation}Defina:- Tiempo de muestreo $t_m$- Duración para el experimento $t_f$- Valor inicial para el actuador $V_0$- Valor final para el actuador $V_f$ **Lista de tiempos $t$**<jupyter_code>tm = 1
tf = 500.0
t = np.linspace(0.0 ,tf, round(tf/tm) + 1)<jupyter_output><empty_output><jupyter_text>**Señal de entrada $U(t)$**<jupyter_code>t0 = 30
v0 = 20
vf = 60
U = np.where(t>=t0,vf,v0)<jupyter_output><empty_output><jupyter_text>**Gráfica de la señal**<jupyter_code>plt.plot(t,U)<jupyter_output><empty_output><jupyter_text>6. Realice el experimento y guardeEntregue los valores definidos para $U(t)$ en el actuador cada $t_m$ segundos, lea el sensor apropiado para su caso y guarde la información necesaria. Para esto puede crear un archivo `csv` a partir de un **dataframe**.Para leer los sensores se han definido las siguientes funciones:~~~leerNivelPLCIW100()leerPresionPLCIW96()leerFlujoPLCIW98()~~~<jupyter_code>Y = []
print('Para abortar el experimento presione ESPACIO')
abortado = False
for idt,ti in enumerate(t):
    Entrada = U[idt]
    # Poner el valor en el actuador
    #AbrirValvulaQW96(Entrada)
    BombaQW80(Entrada)
    Y.append(leerPresionPLCIW96())
    if keyboard.is_pressed(' '):
        print('Abortando el experimento a los ' + 
              str(ti) +' segundos')
        abortado = True
        escr_sal_bool(0,5,0)
        BombaQW80(5)
        AbrirValvulaQW96(0)
        
        break
    time.sleep(tm)
    
if abortado:
    Y = Y + [np.nan]*(len(U)-len(Y))
d = {'Tiempo': t, 'Entrada': U, 'Salida': Y}

df = pd.DataFrame(data=d)
df.head()
escr_sal_bool(0,5,0)
AbrirValvulaQW96(0)

# Gráfica de entrada y salida
plt.plot(df["Tiempo"],df["Entrada"],
         df["Tiempo"],10*df["Salida"])
# Guarda datos
archivo = "Datos/sebastianmartinezospina.csv"
df.to_csv(archivo, index=False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1206307917411803, 'fraction_numerical': 0.05007315883596163, 'mean_word_length': 4.1610738255033555, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 29, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 3, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '571377', 'license': 'MIT', 'n_tokens_mistral': 2666, 'n_tokens_neox': 2441, 'n_words': 614, 'path': 'CapturaDatosPLC_Siemens.ipynb', 'repo_name': 'pierrediazp/Control', 'size': '6164'}