三菱 PLC 编程入门 3

目录

上一篇文章《三菱 PLC 编程入门 2》实现了跑马灯的例子。但是代码的灵活性不高。本文换一种实现,使得代码更容易测试和维护。

微信扫码查看视频

微信扫码查看视频

先分析问题。要实现跑马灯,就是对每个灯,做开和关的操作。即,何时开,何时关。

我们把这个操作抽象成一个独立的功能(函数块)。

LightOnOff

功能说明

  • onTimeoffTime 时段内,输出 True

参数说明

  • IN: bool类型,功能开关,True – 功能生效;False – 计时器重置
  • onTime: time类型,打开时间
  • offTime: time类型,关闭时间
  • Q: bool 类型,输出

功能实现

// 函数块:LightOnOff
// 实现
IF NOT IN THEN
	// 重置计时器
	setOn(IN := FALSE);  // TON(延时开)实例 
	setOff(IN := FALSE);  // TP(持续开)实例
	RETURN;
END_IF;

IF Q = FALSE THEN
	// 如果灯灭,就延时打开
	setOn(IN := TRUE, PT := onTime, Q := Q);
	setOff(IN := FALSE); // 重置 TP(后续可以关灯)
	ELSE
	// 如果灯亮,就延时关闭
	duration := offTime - onTime;
	setOff(IN := TRUE, PT := duration, Q := Q); 
	setON(IN := FALSE); // 重置 TON(后续可以开灯)
END_IF;

为了方便调用,把这个函数块做个封装。

LightsOF

功能说明

  • 输入灯的「编号」,实现对应的开关操作;
  • 通过调用 LightOnOff 实现对应的操作。

参数说明

  • id: int类型,灯的编号 0 到 7
  • IN: bool类型,输入
  • onTime: time类型,打开时间
  • offTime: time类型,关闭时间
  • Q: bool 类型,输出

功能实现

// 函数块:LightsOF
// 实现
CASE id OF
	// LightOnOff 实例
	0: LightOnOff0(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
	1: LightOnOff1(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
	2: LightOnOff2(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
	3: LightOnOff3(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
	4: LightOnOff4(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
	5: LightOnOff5(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
	6: LightOnOff6(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
	7: LightOnOff7(IN := IN, onTime := onTime, offTime := OffTime, Q := Q);
END_CASE;

这么做的好处是,在主程序中可以用 FOR 语句,用遍历的方式对灯操作。

接下来计算灯的打开和关闭时间,即可实现跑马灯的逻辑。

// 延迟时间,单位:ms
iDelay := 500;
// 灯数
iNum := 8;

// 跑马灯效果:依次亮灯、依次灭灯
FOR ii := 0 TO iNum DO
	// 灯 ii 的打开时间
	onTime := INT_TO_TIME(iDelay * (ii + 1)); 
  // 灯 ii 的关闭时间
	offTime := INT_TO_TIME(iDelay * (2 * iNum - ii)); 
  // 操作生效
  // opLightsOF 是 LightsOF 的实例
  // Lights 是数组,代表灯的状态(赋值给 Y 即可实现灯的开和关)
	opLightsOF(id := ii, IN := TRUE, onTime := onTime, offTime := offTime, Q := lights[ii]);
END_FOR;

注意,上面代码只实现了跑马灯的逻辑。倒数第二行 opLightsOF 输出到 lights,它是一个数组,代表灯的状态。

接下来需要把 Lights 输出到 Y,即可实现跑马灯的效果。

我们把输出部分也独立成一个函数块。

InitLights

// 函数块:InitLights
// 实现
// lights 是数组(已声明)
Y0 := lights[0]; 
Y1 := lights[1];
Y2 := lights[2];
Y3 := lights[3];
Y4 := lights[4];
Y5 := lights[5];
Y6 := lights[6];
Y7 := lights[7];

别忘了重置计时器。

// 重置计时器
// resetter 是 TON 的实例
// isReset 是重置标签,TRUE - 执行重置,FALSE - 不执行重置
// 保证每个周期(iDelay * iNum * 2 毫秒)重置一次状态
resetter(IN := TRUE, PT := INT_TO_TIME(iDelay * iNum * 2), Q := isReset);
IF isReset THEN
	// 重置 resetter 自身
	resetter(IN := FALSE);
	FOR ii := 0 TO iNum DO
  	// 重置每个灯的计时器
  	// opLightsOF 是 LightOF 的实例
		opLightsOF(id := ii, IN := FALSE);
	END_FOR;
END_IF;

完整的主程序如下。

// 配置 Configuration
// 延迟时间,单位:ms
iDelay := 500;
// 灯数
iNum := 8;

// 实现 Implementation
// 初始化
// runInitLights 是 InitLights 的实例
runInitLights(lights := lights); 

// 跑马灯效果
FOR ii := 0 TO iNum DO
	// 灯 ii 的打开时间
	onTime := INT_TO_TIME(iDelay * (ii + 1)); 
  // 灯 ii 的关闭时间
	offTime := INT_TO_TIME(iDelay * (2 * iNum - ii)); 
  // 操作生效
  // opLightsOF 是 LightsOF 的实例
  // Lights 是数组,输出到 Y 
	opLightsOF(id := ii, IN := TRUE, onTime := onTime, offTime := offTime, Q := lights[ii]);
END_FOR;

// 重置计时器
// resetter 是 TON 的实例
// isReset 是重置标签,TRUE - 执行重置,FALSE - 不执行重置
// 保证每个周期(iDelay * iNum * 2 毫秒)重置一次状态
resetter(IN := TRUE, PT := INT_TO_TIME(iDelay * iNum * 2), Q := isReset);
IF isReset THEN
	// 重置 resetter 自身
	resetter(IN := FALSE);
	FOR ii := 0 TO iNum DO
  	// 重置每个灯的计时器
  	// opLightsOF 是 LightOF 的实例
		opLightsOF(id := ii, IN := FALSE);
	END_FOR;
END_IF;

最后,做个总结。程序可分为三个模块:

  • 初始化:作用是绑定输出,对应函数块 InitLights
  • 开关操作:实现定时开和定时关的逻辑,对应函数块 LightsOnOffLightOF,其中前者是功能实现,后者是对前者的封装。
  • 主程序:实现完整功能,它调用上述两个模块。

模块化就是解耦,有两个好处:一是提升开发效率,可以多人一起开发;二是方便测试和维护,各模块独立测试。

标签 :

相关文章

三菱 PLC 编程入门 1

PLC 全称是 Programmable Logic Controller,即可编程逻辑控制器。主要用于工业设备控制,比如电梯、传送带、机械臂等等。

更多

三菱 PLC 编程入门 2

上一篇文章《三菱 PLC 编程入门 1》 介绍了 PLC 编程的基本知识。本文实现一个跑马灯的小例子。

更多