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~1ZRGB通道1代表RGB,通道号支持1~Z
21~2ZVID通道2代表VID,通道号支持1~Z
31~3ZDIG通道3代表DIG,通道号支持1~Z
41~4ZSTR通道4代表STR,通道号支持1~Z
51~5ZNET通道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口连接外网,自动更新系统时间

五、调试与常用技巧

(一)调试工具

  1. beep(次数):通过蜂鸣器发声判断程序执行节点
  2. print(内容):打印变量值、执行状态等调试信息
  3. printhex(数据):查看16进制数据传输是否正确

(二)常用技巧

  1. 中文/特殊字符处理:HTTP请求、URL参数需用str.EncodeURL编码
  2. 长连接优化:TCP长连接避免反复连接断开,提升通信速度
  3. 变量复用:全局变量可在多程序间共享数据,减少重复赋值
  4. 容错处理:长连接中添加断开检测(如res="$Close$"),避免程序卡死
  5. 代码助手:使用系统自带的代码助手功能,输入关键字(如"串口")自动生成代码,无需记忆函数格式

六、注意事项

  1. 本编程说明仅适用于SimFAS中控系统V7.0+默认引擎,基础模式支持自动容错(语法参数错误会尝试修复并运行)
  2. 若需复杂逻辑(如if内嵌、or/and逻辑、完整C/C++/Java风格语法),请切换至专家模式
  3. 红外控制、投影机控制等功能需确保设备已正确配对(红外学习、IP/密码正确)
  4. 网络通信需确保中控与目标设备网络互通,防火墙未拦截对应端口
  5. 日志记录依赖外网时间同步,否则日志时间可能不准确
  6. 变量长度不可超过8字符,否则会导致语法错误