SimFAS 中控系统基础模式编程说明(适用于V7.0+引擎)
一、编程基础规范
(一)备注规则
使用双连字符 -- 标记单行备注,备注内容仅在当前行有效,不会被执行。
示例:-- 这是一条备注,本行后续内容不执行
(二)字符串表示
- 单行字符串:使用双引号
"..."包裹,示例:"hello SimFAS" - 多行/特殊字符字符串:使用反引号
`...`包裹(键盘左上角按键),支持包含引号、换行等特殊格式,示例:
data=`[{"action":"play",
{"file":"1.mp4",
}] `(三)变量规则
1. 命名规范
| 变量类型 | 命名规则 | 访问范围 | 生命周期 |
|---|---|---|---|
| 局部变量 | 字母开头,可后续跟字母/数字,长度≤8字符 | 当前程序 | 程序执行完毕后释放 |
| 全局变量 | 下划线 _ 开头,后续跟字母/数字,长度≤8字符 | 所有程序 | 程序执行完毕后保留值 |
2. 变量赋值示例
a=10; -- 整数赋值
b=-5; -- 负数赋值(负号与数字无空格)
c=0xff; -- 16进制赋值
_abc=1; -- 全局变量赋值
ip="192.168.2.194"; -- 字符串赋值
port=8899; -- 整数赋值
port2=port; -- 变量间赋值二、核心功能模块编程指南
(一)串口通信
支持 com1-com8 共8个串口,核心用于设备串口指令交互,常用ASCII或16进制数据传输。
1. 串口配置
函数格式:comX.set(波特率, 数据位, 校验位, 停止位)
- 波特率:支持9600、2400、4800、19200、38400等常见值
- 数据位:8(默认)、5、6、7
- 校验位:"n"(无校验,默认)、"o"(奇校验)、"e"(偶校验)
- 停止位:1(默认)、1.5、2
示例:com1.set(9600,8,"n",1); -- 配置com1为9600波特率、8数据位、无校验、1停止位
2. 数据发送
- ASCII数据发送:
comX.send("字符串")
示例:com1.send("hello"); -- 向com1发送ASCII字符串"hello" - 16进制数据发送(控制指令常用):
comX.sendhex("16进制字符串")
示例:com1.sendhex("00 01 02 03"); -- 向com1发送16进制数据
(二)网络通信(TCP/UDP/HTTP)
1. TCP通信
支持短连接、长连接及数据收发,适用于设备网络指令交互。
(1)基础TCP发送
- ASCII数据发送:
tcp.send(IP, 端口, "数据")
示例:tcp.send("192.168.2.100",6688,"hello"); -- 向目标IP端口发送ASCII数据后断开 - 16进制数据发送:
tcp.sendhex(IP, 端口, "16进制数据")
示例:tcp.sendhex("192.168.2.100",6688,"01 0B 00 0D 0A"); - 带超时配置发送:
ret=tcp.send(IP, 端口, "数据", 发送等待时间ms, 连接超时时间s)
示例:ret=tcp.send("192.168.2.100",6688,"hello",1000,2); -- 连接超时2秒,发送后等待1秒断开,ret记录发送字节数
(2)TCP收发一体
- ASCII收发:
res=tcp.sendrcv(IP, 端口, "发送数据")
示例:res=tcp.sendrcv("192.168.2.100",6688,"chk"); -- res存储服务器返回数据 - 16进制收发:
res=tcp.sendhexrcv(IP, 端口, "16进制发送数据")
示例:res=tcp.sendhexrcv("192.168.2.100",6688,"010203");
(3)高级TCP长连接(带错误处理)
sock=tcp.new(); -- 创建TCP客户端
ret=tcp.connect(sock, "192.168.2.194",7788,2); -- 连接服务器,2秒超时
if (ret) then
tcp.sendto(sock,"hello kitty"); -- 发送数据
end
while (ret) do -- 循环接收数据
res=tcp.recv(sock,3000); -- 3秒无数据则退出接收
if (res="$Close$") then -- 检测到断开指令
print("服务器连接断开!");
break(); -- 退出循环
end
if (res) then -- 收到数据时打印
print("收到TCP数据:",res);
end
end
tcp.close(sock); -- 关闭客户端
print("TCP客户端退出");2. UDP通信
无连接通信,适用于广播、短数据传输场景。
基础发送:
udp.send("192.168.2.100",6699,"hello"); -- ASCII数据发送 udp.sendhex("192.168.2.100",6699,"01 0B 00 0D 0A"); -- 16进制数据发送收发一体:
res=udp.sendrcv(ip,port,data,localPort,waitTimeS); -- ASCII收发 res=udp.sendhexrcv(ip,port,data,localPort,waitTimeS); -- 16进制收发参数说明:
localPort(本地端口,可选)、waitTimeS(接收等待时间,秒)
3. HTTP客户端
支持GET/POST请求,适用于与Web服务器数据交互。
GET请求:
http.get("http://www.simfas.com/get/"); -- 基础GET请求 -- 带中文/特殊字符参数的GET请求(需URL编码) Req=str.EncodeURL("hello=你好"); -- 编码中文参数 url=str.cat("http://www.simfas.com/get/?", Req); -- 拼接URL res=http.get(url); -- 发送编码后的GET请求,res存储返回数据- POST请求:
http.post("URL", "表单数据")
示例:http.post("http://www.simfas.com/post/","a=1;b=2"); -- 提交表单数据a=1、b=2
(三)电脑控制(SimCTRL)
通过网络控制安装SimCTRL软件的电脑,支持唤醒、关机、重启等操作。
| 功能 | 函数格式 | 示例 |
|---|---|---|
| 网络唤醒 | pc.wakeup(广播IP, MAC地址) | pc.wakeup("192.168.2.255","01:03:0A:F2:DD:08"); |
| 关机(按ID) | pc.shutdown("设备ID") | pc.shutdown("001"); -- 关闭ID为001的电脑 |
| 关机(按IP) | pc.shutdown("*","S","IP地址") | pc.shutdown("*","S","192.168.2.101"); |
| 重启 | pc.reboot("设备ID") | pc.reboot("001"); |
| 发送按键 | pc.SendKey("设备ID","按键码") | pc.SendKey("001","31"); -- 发送按键指令 |
| 打开文件 | pc.open("设备ID","文件路径") | pc.open("001","d:\\abc.txt"); |
| 关闭软件 | pc.close("设备ID","exe文件名") | pc.close("001","abc.exe"); |
(四)红外控制
支持 ir1-ir8 共8个红外通道,需先通过"我的程序-红外学习"功能录入遥控器按键。
核心函数:irX.send("已学习的按键名称")
示例:ir1.send("按键A"); -- 通过红外通道1发送"按键A"指令
(五)触摸屏控制
用于修改触摸屏平板(SimAPP)的UI元素,支持文字、透明度、页面切换等操作。
| 功能 | 函数格式 | 示例 |
|---|---|---|
| 修改按钮文字+透明度 | touch.send("控件名称","文字内容",透明度) | touch.send("abc","系统已打开",80); |
| 预存UI更新(批量发送) | touch.sendPre("控件名称","文字内容",透明度) | touch.sendPre("abc","系统已打开",80); |
| 临时显示(不保存) | touch.SendOnce("控件名称","文字内容",透明度) | touch.SendOnce("tips","灯光已打开",80); |
| 删除控件内容 | touch.remove("控件名称") | touch.remove("abc"); |
| 禁用按钮 | touch.disable("控件名称") | touch.disable("abc"); |
| 启用按钮 | touch.enable("控件名称") | touch.enable("abc"); |
| 切换页面 | touch.open("页面文件名") | touch.open("next.ui"); |
| 语音提示 | touch.speak("语音内容") | touch.speak("你好,系统正在打开"); |
(六)投影机控制(Pjlink)
通过Pjlink协议控制投影机,支持开关、通道切换、状态查询等。
1. 基础控制
- 开机:
pjlink.on(IP地址, 密码)示例:pjlink.on("192.168.2.196",""); -- 无密码开机 - 关机:
pjlink.off(IP地址, 密码) - 切换输入通道:
pjlink.input(IP地址, 通道码, 密码)
示例:pjlink.input("192.168.2.196","11",""); -- 切换到RGB 1通道
2. 通道码说明
| 通道码 | 含义 | 说明 |
|---|---|---|
| 11~1Z | RGB通道 | 1代表RGB,通道号支持1~Z |
| 21~2Z | VID通道 | 2代表VID,通道号支持1~Z |
| 31~3Z | DIG通道 | 3代表DIG,通道号支持1~Z |
| 41~4Z | STR通道 | 4代表STR,通道号支持1~Z |
| 51~5Z | NET通道 | 5代表NET,通道号支持1~Z |
3. 状态查询与高级控制
- 状态查询:
res=pjlink.get(IP地址, 查询ID, 密码)
示例:res=pjlink.get("192.168.2.196",2,""); -- 查询电源状态(查询ID=2) - 高级设置:
pjlink.set(IP地址, 设置ID, 密码)
示例:pjlink.set("192.168.2.196",12,""); -- 设置音量+(设置ID=12) - 自定义协议发送:
pjlink.send(IP地址, 端口, 自定义数据, 密码)
4. 常用查询/设置ID对照表
| ID值 | 功能说明 |
|---|---|
| 2 | 查询电源状态 |
| 3 | 查询投影机名称 |
| 4 | 查询投影机型号 |
| 6 | 查询当前输入通道 |
| 7 | 查询投影机状态 |
| 10 | 设置FREZ ON(画面冻结开) |
| 11 | 设置FREZ OFF(画面冻结关) |
| 12 | 设置SVOL +(扬声器音量+) |
| 13 | 设置SVOL -(扬声器音量-) |
| 14 | 设置MVOL +(麦克风音量+) |
| 15 | 设置MVOL -(麦克风音量-) |
(七)系统常用函数
| 函数 | 功能说明 | 示例 |
|---|---|---|
sleep(秒数) | 延时(秒) | sleep(1); -- 延时1秒 |
msleep(毫秒数) | 延时(毫秒) | msleep(500); -- 延时500毫秒 |
usleep(微秒数) | 延时(微秒) | usleep(100); -- 延时100微秒 |
beep(次数) | 蜂鸣器发声 | beep(10); -- 蜂鸣器响10次 |
print(内容1,内容2...) | 打印调试信息 | print("IP地址:",ip); |
printhex(变量) | 打印16进制调试信息 | printhex(data); -- 以16进制显示data |
call("任务文件名") | 新建线程运行任务(不等待) | call("abc.tsk"); |
call_in("任务文件名") | 当前线程运行任务(等待完成) | call_in("abc.tsk"); |
time.Limit(小时数) | 限制程序运行(开机超时时不执行后续代码) | time.Limit(1000); -- 开机超1000小时不执行 |
exitIfr("提示") | 程序已运行则退出后续代码 | exitIfr("程序已经运行"); |
break(); | 退出循环/当前程序 | break(); -- 退出while循环 |
sys.uptime() | 获取系统启动时间(秒) | ret=sys.uptime(); |
sys.now() | 获取系统当前时间 | res=sys.now(); |
log.save("日志内容") | 记录用户操作日志 | log.save("用户打开了196号投影机"); |
relay.set(通道, 开关值) | 控制中控8路继电器(1-8通道,0=关/1=开) | relay.set(1,1); -- 打开1号继电器 |
return(); | 退出当前程序 | return(); |
三、逻辑控制与数学运算
(一)逻辑判断(if语句)
1. 语法规则
- 支持比较符:
>(大于)、<(小于)、=(等于)、~(不等于) - 支持
else分支,不支持if内嵌if,不支持or/and逻辑(需完整功能请用专家模式) - 逻辑表达式必须用括号包裹
- 无比较符时,变量非0则条件成立
2. 示例
a=10;
if (a>0) then -- 比较判断
print("a大于0");
end
if (a) then -- 无比较符(a非0则成立)
print("a不等于0");
else
print("a等于0或变量不存在");
end
s="hello";
if (s="hello") then -- 字符串比较
print("字符串相等");
end
c=str.contain(s,"llo"); -- 调用字符串函数判断
if (c) then
print("字符串包含'llo'");
end(二)循环控制(while语句)
1. 语法规则
- 支持比较符与
if-else内嵌 - 不支持
while内嵌if以外的循环 - 支持
break();退出循环(必须带括号) - 逻辑表达式必须用括号包裹
2. 示例
a=0;
while (a<10) do -- 循环条件:a小于10
if (a>5) then
print("a大于5的值是:",a);
else
print(a);
end
a++; -- a自增1
end(三)数学运算
| 运算类型 | 语法 | 示例 | 结果 |
|---|---|---|---|
| 自增 | 变量++ | a=5;a++; | a=6 |
| 自减 | 变量~~ | a=5;a~~; | a=4 |
| 取反(0↔1切换) | 变量!! | a=0;a!!; | a=1 |
| 加法 | math.add(数1,数2,...) | math.add(1,2,5) | 8 |
| 减法 | math.take(被减数,减数) | math.take(10,3) | 7 |
| 乘法 | math.times(乘数1,乘数2) | math.times(4,5) | 20 |
| 除法(整数) | math.div(被除数,除数) | math.div(10,3) | 3 |
| 除法(小数) | math.divf(被除数,除数) | math.divf(10,3) | 3.333... |
| 最大值 | math.max(数1,数2,...) | math.max(2,7,5) | 7 |
| 最小值 | math.min(数1,数2,...) | math.min(2,7,5) | 2 |
| 绝对值 | math.abs(数值) | math.abs(-10) | 10 |
(四)字符串函数
| 函数 | 功能说明 | 示例 | 结果 |
|---|---|---|---|
str.cmp(字符串1,字符串2) | 比较两个字符串是否相等 | str.cmp("abc","abc") | true |
str.contain(字符串,子串) | 判断字符串是否包含子串 | str.contain("hello","llo") | true |
str.new(长度) | 申请指定字节长度的字符串 | str.new(64) | 生成64字节空字符串 |
str.cat(字符串1,字符串2,...) | 拼接多个字符串 | str.cat("a","b","c") | "abc" |
str.len(字符串) | 获取字符串长度 | str.len("hello") | 5 |
str.tochar(16进制/整数) | 转换为字符型 | str.tochar("31 32") | "12" |
str.getChar(字符串,索引) | 获取第n个字符(左1为第1位) | str.getChar("abcde",4) | "d" |
str.sub(字符串,起始位,长度) | 截取字符串 | str.sub("192.168.2.1",2,4) | "92." |
str.md5(字符串) | MD5加密 | str.md5("123456") | MD5加密结果 |
str.sprintf(格式,参数1,...) | 格式化字符串(最多3个参数) | str.sprintf("ip=%s",ip) | "ip=192.168.2.194" |
str.Before(字符串,分隔符) | 截取分隔符前的内容 | str.Before("a=1;b=2",";") | "a=1" |
str.After(字符串,分隔符) | 截取分隔符后的内容 | str.After("a=1;b=2",";") | "b=2" |
str.EncodeURL(字符串) | URL编码(处理中文/空格) | str.EncodeURL("hello=你好") | 编码后的字符串 |
str.indexof(字符串,字符) | 获取字符在字符串中的位置 | str.indexof("192.168.2.1","9") | 2 |
str.getBit(整数,位数) | 获取整数第n位(右1为第1位,0/1) | str.getBit(0xf0,4) | 对应位值 |
str.setChar(字符串,索引,值) | 设置字符串第n位字符 | str.setChar("abc",2,0xf1) | 第2位设为0xf1 |
(五)校验与协议函数
| 函数 | 功能说明 | 示例 | |
|---|---|---|---|
crc16.toint(数据) | 计算CRC16校验(返回整数) | ret=crc16.toint(data); | CRC16整数结果 |
crc16.tochar(数据) | 计算CRC16校验(返回2字节字符) | res=crc16.tochar(data); | 2字节CRC16字符 |
modbus.new(指令,设备ID,寄存器地址,值) | 生成Modbus RTU协议数据 | res=modbus.new(6,1,0x0001,10); | Modbus协议数据 |
四、程序调用与日志记录
(一)程序调用
1. 内部程序调用
- 异步调用(新建线程):
call("任务文件名.tsk");
特点:不等待被调用程序完成,直接执行后续代码 - 同步调用(当前线程):
call_in("任务文件名.tsk");
特点:等待被调用程序执行完毕后,再继续执行后续代码
2. 跨设备/带参数调用
中控间、SimAPP与中控可通过TCP协议调用程序,支持带参数传递:
- 调用格式:
任务文件名.tsk?参数1=值&参数2=值 参数会被中控直接执行,配合
if语句可实现多功能复用:
示例:-- 调用指令:77206615.tsk?a=1&b=20 if (a=1) then print("执行a=1的功能"); end if (a=2) then print("执行a=2的功能"); end
(二)日志记录
1. 日志生成
使用log.save("日志内容");函数记录操作,需在程序末尾添加:
示例:
pjlink.on("192.168.2.196",""); -- 打开投影机
log.save("用户打开了196号投影机"); -- 记录日志2. 日志查询
管理人员通过中控管理界面→我的程序→帮助→用户日志Log查询,支持查看最新日志、更早日志、系统日志。
3. 日志存储规则
- 滚动保存,最早记录会被覆盖
- 存储容量:128KB-256KB动态调整
- 可存储记录数:5000-16000条左右
- 时间同步:需中控WAN口连接外网,自动更新系统时间
五、调试与常用技巧
(一)调试工具
beep(次数):通过蜂鸣器发声判断程序执行节点print(内容):打印变量值、执行状态等调试信息printhex(数据):查看16进制数据传输是否正确
(二)常用技巧
- 中文/特殊字符处理:HTTP请求、URL参数需用
str.EncodeURL编码 - 长连接优化:TCP长连接避免反复连接断开,提升通信速度
- 变量复用:全局变量可在多程序间共享数据,减少重复赋值
- 容错处理:长连接中添加断开检测(如
res="$Close$"),避免程序卡死 - 代码助手:使用系统自带的代码助手功能,输入关键字(如"串口")自动生成代码,无需记忆函数格式
六、注意事项
- 本编程说明仅适用于SimFAS中控系统V7.0+默认引擎,基础模式支持自动容错(语法参数错误会尝试修复并运行)
- 若需复杂逻辑(如
if内嵌、or/and逻辑、完整C/C++/Java风格语法),请切换至专家模式 - 红外控制、投影机控制等功能需确保设备已正确配对(红外学习、IP/密码正确)
- 网络通信需确保中控与目标设备网络互通,防火墙未拦截对应端口
- 日志记录依赖外网时间同步,否则日志时间可能不准确
- 变量长度不可超过8字符,否则会导致语法错误
最后一次更新于2025-12-15



0 条评论