1. 上一篇记录 openplc使用C语言文件读写驱动实现基本流程。
openPLC_Editor C语言编程 在mp157 arm板上调用io等使用记录_openplc c 编程-CSDN博客
2. 下面通过映射地址的方式控制io和读写驱动数据。
在runtime 环境的 hardware 硬件配置中 选择 python on Linux(PSM),这个可以通过python编程把openplc的地址和硬件控制结合起来。上层读写地址就能控制io。比如 QX0.0 写寄存器0或1 控制led灯开关。
3. python编程 地址映射
3.1 import psm ,导入psm库,可以读写内部地址。
qx00 = psm.get_var("QX0.0") 读取QX0.0的寄存器值,在openplc_editor中定义变量设置QX0.0 = 1,就可以qx00 = psm.get_var("QX0.0")读的值就是1。
psm.set_var("IX0.0", 1)给 IX0.0的寄存器赋值1,在openplc_editor中定义IX0.0的变量就可以读取。
3.2 在编辑框内默认代码有两个函数,update_inputs() 和 update_outputs()。
update_outputs() : 读取上层代码的输出变量,%QX0.0, %QW0之类的变量。比如
qx00 = psm.get_var("QX0.0") 判断QX0.0的值,=1 开灯, =0 关灯。
qx01 = psm.get_var("QX0.1")判断QX0.1的值,=1 gpio0置1,=0 gpio0置0。
qw00 = psm.get_var("QW0")读QW0的值,16位INT,设置DAC的输出值。
update_inputs() :设置上层代码的输入变量,%IX0.0,%IW0之类的变量。比如
psm.set_var("IX0.0", int(var_str)) 先读取gpio10的电平值,然后赋值给 %IX0.0 寄存器,上层代码读 %IX0.0就能 得到 gpio10的电平值。
psm.set_var("IW2", int(float(adc_value)*100)) 先读adc的采样值,float类型,*100变成int 赋值给 %IW2。上层代码就可以读 %IW2 得到adc的采样值。
4. python编程 驱动读写
还是跟C语言编程一样使用文件操作来读写驱动。如下 读写adc的驱动文件,获取采样值,换算成电压值。
5.完整代码,最好在notpad++之类的编辑器编好在复制过去。
#import all your libraries here
import psm
import time
import os
#global variables
cnt = 0
var_str = ""
def hardware_init():
#Insert your hardware initialization code in here
psm.start()
f_led = open('/sys/class/leds/user-led/trigger','w')
f_led.write("none")
f_led.close()
f_dac = open('/sys/bus/iio/devices/iio:device1/out_voltage1_powerdown','w')
f_dac.write("0")
f_dac.close()
if not os.path.exists('/sys/class/gpio/gpio0'):
f_io0 = open('/sys/class/gpio/export','w')
f_io0.write("0")
f_io0.close()
f_in0 = open('/sys/class/gpio/gpio0/direction','w')
f_in0.write("out")
f_in0.close()
if not os.path.exists('/sys/class/gpio/gpio10'):
f_io10 = open('/sys/class/gpio/export','w')
f_io10.write("10")
f_io10.close()
f_in10 = open('/sys/class/gpio/gpio10/direction','w')
f_in10.write("in")
f_in10.close()
def adc_read():
f_raw = open('/sys/bus/iio/devices/iio:device0/in_voltage19_raw','r')
f_raw.seek(0,0)
str_raw = f_raw.read()
f_raw.close()
f_scale = open('/sys/bus/iio/devices/iio:device0/in_voltage_scale','r')
f_scale.seek(0,0)
str_scale = f_scale.read()
f_scale.close()
return float(str_raw)*float(str_scale)/1000.0
def dac_set( set ):
if set >=0 and set <=4095:
f_dac = open('/sys/bus/iio/devices/iio:device1/out_voltage1_raw','w')
f_dac.write(str(set))
f_dac.close()
def update_inputs():
#place here your code to update inputs
global cnt
global var_str
cnt += 1
if (cnt == 2):
cnt = 0
f = open('/sys/class/gpio/gpio10/value','r')
var_str = f.read()
f.close()
psm.set_var("IX0.0", int(var_str))
#print(var_str)
adc_value = adc_read()
psm.set_var("IW2", int(float(adc_value)*100))
#print(int(float(adc_value)*100));
def update_outputs():
#place here your code to work on outputs
qx00 = psm.get_var("QX0.0")
if qx00 == True:
os.system("echo 1 > /sys/class/leds/user-led/brightness")
elif qx00 == False:
os.system("echo 0 > /sys/class/leds/user-led/brightness")
qx01 = psm.get_var("QX0.1")
if qx01 == True:
os.system("echo 1 > /sys/class/gpio/gpio0/value")
elif qx01 == False:
os.system("echo 0 > /sys/class/gpio/gpio0/value")
qw00 = psm.get_var("QW0")
if qw00 >=0 and qw00 <=4095:
dac_set(qw00)
if __name__ == "__main__":
hardware_init()
while (not psm.should_quit()):
update_inputs()
update_outputs()
time.sleep(0.1) #You can adjust the psm cycle time here
psm.stop()
5.在openplc_editer 上层代码 变量定义
6.代码读写测试
tcpGet 是 modbus %QW1 写地址,通过网络调试助手连接502端口就可以发送。
发送 “00 00 00 00 00 06 01 06 00 01 00 01” 设置 tcpGet 变量 = 1,
发送 “00 00 00 00 00 06 01 06 00 01 00 02” 设置 tcpGet 变量 = 2,
如果 tcpGet == 1,
ledSet :=1 点灯,
gpioSet :=1 设置gpio0置1,
dacSet :=1024 设置dac的值=1024,0.8V
gpioRead0 := gpioRead 读取gpio10的电平值。
adcRead0 := adcRead 读取adc的值
打印值。
发送 “00 00 00 00 00 06 01 06 00 01 00 01”,gpio10 =1,adc=0.82v
发送 “00 00 00 00 00 06 01 06 00 01 00 02” ,gpio10 =0,adc=2.47v