C# 异步编程示例

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Threading;

 

namespace ConsoleApplication3

{


class
Program

{


static
void Main(string[] args)

{


Console.WriteLine($”主程序头,当前线程ID{Thread.CurrentThread.ManagedThreadId});

CallSayHiAysnc(“Jack”);


Console.WriteLine($”主程序尾,当前线程ID{Thread.CurrentThread.ManagedThreadId});


Console.ReadKey();

}

 


static
async
void CallSayHiAysnc(string name)

{


Console.WriteLine($”异步调用头,当前线程ID{Thread.CurrentThread.ManagedThreadId});


string result = await SayHiAsync(name);


Console.WriteLine($”异步调用尾,当前线程ID{Thread.CurrentThread.ManagedThreadId});


Console.WriteLine(result);

}


static
Task<string> SayHiAsync(string name)

{


return
Task.Run<string>(()=> { return SayHi(name); });

}


static
string SayHi(string name)

{


Thread.Sleep(10000);


Console.WriteLine($”SayHi已执行,当前线程ID{Thread.CurrentThread.ManagedThreadId});


return
$”Hi,{name};

}

 

}

}

结构化文本实现上升沿和下降沿指令

上升沿和下降沿指令是需要两个扫描周期检测的,另外需要一个点位存储上一次的扫描结果用于和本次扫描做对比。

西门子S7200的子程序中如果使用上升沿和下降沿程序,就只能调用一次,多次调用的话,上升沿和下降沿指令就会出现混乱。S71200使用带多重背景块的上升沿和下降沿指令的子程序就不存在这样的问题,因为背景数据块之间没有影响。

下面是梯形图的实现方式

然后我们写成结构化文本的模式;

横河PLC实现modbusrtu通讯

这里只介绍实现的思路

  1. 重点阅读名称H22-02E的帮助文档。
  2. 程序中会使用到间接寻址或偏移量寻址方式。
  3. CRC16校验采用小查表法易于实现。
  4. 接受数据失败,建议初始化数据接收缓冲区。

由于横河PLC没有更上层的指令,只能通过自由口通讯的模式实现。

串口设置部分:

设置参数包含906,907,908,909,912,913,918,其中912和913要设置为0,否则通信的会有问题,参见描述中的部分。

帮助中给的通讯参数设置程序:

帮助中给出的发送数据程序:

帮助中给出的接受数据程序:

 

CRC16 小查表法

#include
“stdafx.h”

 

static
unsigned
short crcTlb[] = { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,

0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 };

 

static
unsigned
short CalcCRC16(unsigned
short * pBuf, unsigned
int
length)

{

    unsigned
int i = 0, ch = 0;

    unsigned
int crc = 0xFFFF;

    for (i = 0; i < length; i++)

    {

        ch = pBuf[i];

        crc = crcTlb[(ch ^ crc) & 0x000F] ^ (crc >> 4);

        crc = crcTlb[((ch >> 4) ^ crc) & 0x000F] ^ (crc >> 4);

    }

    crc = (crc & 0x00FF) << 8 | (crc >> 8);

    return crc;

}

 

 

int main()

{

    unsigned
short ar[] = {0x01,0x03,0x00,0x56,0x00,0x09};

    unsigned
short crc16 = CalcCRC16(ar,6);

    printf(“%X\n”, crc16);


return 0;

}

 

运算符

意义

示例

对于每个位位置的结果(1=设定,0=清除)

    &    

位 AND

 x&y 

如果 x 和 y 都为 1,则得到 1;如果 x 或 y 任何一个为 0,或都为0,则得到 0

    |    

位 OR

 x|y 

如果 x 或 y 为 1,或都为 1,则得到 1;如果 x 和 y 都为 0,则得到 0

    ^    

位 XOR

 x^y 

如果 x 或 y 的值不同,则得到 1;如果两个值相同,则得到 0

    ~    

位 NOT(I的补码)

 ~x 

如果 x 为 0,则得到 1,如果 x 是 1,则得到 0

 

运算符

意义

示例

结果

<<

向左移位

x<<y

x 的每个位向左移动 y 个位

>>

向右移位

x>>y

x 的每个位向右移动 y 个位

Codesys或TwinCAT采用指针获取输入输出M存储区或其它连续存储区变量给数组赋值

VAR

a0 AT%M*:REAL:=0.0;

a1 AT%M*:REAL:=0.1;

a2 AT%M*:REAL:=0.2;

a3 AT%M*:REAL:=0.3;

a4 AT%M*:REAL:=0.4;

i:int:=0;

ar:array[0..4] of real;

b:bool;

pr:pointer to real;

r_trig1:R_TRIG;

END_VAR

r_trig1(clk:=b);

if r_trig1.q  then

b:=0;

for i:=0 to 4 do

pr:=adr(a0)+sizeof(a0)*i;

ar[i]:=pr^;

end_for

end_if;

 

C# 运行环境问题处理

同事的电脑运行程序,莫名其妙的闪退。

增加以下代码查找原因。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

using System.Windows.Forms;

 

namespace WindowsFormsApplication6

{


static
class
Program

{


///
<summary>


///
应用程序的主入口点。


///
</summary>

[STAThread]


static
void Main()

{


AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;


Application.EnableVisualStyles();


Application.SetCompatibleTextRenderingDefault(false);


Application.Run(new
Form1());

}

 


private
static
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)

{


MessageBox.Show(e.ExceptionObject.ToString());

}

}

}

 

 

 

和泉PLC的子程序、宏、脚本的使用

子程序

这里的子程序和我们常规理解的子程序不一样,这里的子程序更像是一个大程序被分成几个小块而已。

使用方式如下:

首先编写子程序,注意子程序的编号

这里调用指令需要填写子程序的编号

 

这里的宏反而更像子程序,但也缺少了临时变量的概念。

调用宏

 

脚本

这里的脚本支持类C语言

编写脚本

调用脚本

注意:这是使用的第二天,不能保证我的练习是正确的。

和泉MicroSmart系列PLC使用初体验之网页组态

今天使用了一下和泉公司提供的MicroSmart系列的PLC,型号为FC6A-D16P1CEE。

外观是这个样子,如下图:

编程软件分享如下:

链接:https://pan.baidu.com/s/16KY2VHZmjsroRHOL71QBXg

提取码:60pe

整体来说很日系风格,熟悉三菱的PLC上手难度不大。

下面演示网页编程,感觉比较有特色

写个简单的程序代码如下:

添加网页并关联变量

设置PLC的web服务器

下载程序。

可以用网页访问PLC了。

Eplan 绘制接触器的方式

我们先在图纸中添加一个电机,然后选择插入符号,如下图所示选择接触器主触点。

把主触点放到第一个电机的连接点上,鼠标左键不要松手,然后向右拖动,会自动生成第二个主触点,重复第二个主触点的操作步骤,生成第三个主触点,然后松开鼠标左键。如下图所示:

双击元件,修改接触器符号和连接点代号。

添加其它元器件后,绘制接触器线圈和触点。

添加线圈后,修改线圈的符号为KM1,辅助触点也修改为KM1。

按F5键,重新绘制图面。

S71200 频率的测量

最近要测量电机的转速,永磁同步电机加装了霍尔传感器,霍尔传感器输出采用共阳极解法,脉冲的测量采用S71200。

PLC编写程序如下

设置采样的输入点

启用高速计数器

设置计数类型和频率测量周期

设置采用点

设置IO地址

新建数据块和变量

Frequency的值为测量频率,此值与ID1000相同。

EnHSC为计数器启动使能。

EnPeriod为新的采样周期使能。

NewPeriod为新的采样周期。

 

编写程序

使能EnHSC,计时器开始测量频率。

S71200 上升沿与下降沿指令示例

大约是20015年,第一次使用施耐德的一款中型PLCM340,发现里面有很多上升沿和下降沿检测指令,这次使用西门子S71200做一个总结,仅以上升沿指令为例。

本质上,所有的上升沿检测指令都需要一个变量或者和存储单元来保存要检测变量的上一次扫描状态,本次的扫描状态和上次的扫描状态做对比,判断是不是上升沿指令。

下图是西门子S71200中的上升沿指令和下下降沿指令。

一下程序段都是实现,检测上升沿,让整数加一的功能。

 

 

 

 

 

 

 

 

 

 

 

 

 

总结一下:

好像也没什么可总结的,我也不知道这么多指令有什么本质的区别或者应用场合,我应用最后一个上升沿指令较多。

S71200指令修改PLC的IP地址

S71200指令修改PLC的IP地址。

以太网口部分设置如下:

程序如下:

需要讲解一下指令中的Conf_Data参数。

帮助文档中描述如下,我们只看我们用到的部分。

根据上面参数的描述,我们新建变量如下:

展开后

执行代码

可以看到修改后的IP地址

台达文本屏TP04入门

台达官网下载文本屏编程软件,安装后的图标是这个样子。如下

打开软件

文件->新建

设置如下

然后点击确定,保存到一个你能找的到的地方

添加一个数值显示

设置如下

注意:这里的地址是从40000开始

设置下载地址

设置通讯串口

点击人机写入

需要长按文本屏上的Esc按键

总体来说,组态是很简单的。

繁易触摸屏清除报警历史数据

  1. 触摸屏重新上电之前,手指按住触摸屏界面,上电后,快速选择进入设置界面。
  2. 选择”工程管理”输入密码”888888″,进入界面。

  1. 选择”数据清除”,再选择”清除历史事件”即可。

  1. 然后再选择”高级设置”,选择”重启”,系统进入程序界面。

 

 

PLC 结构化文本语言

数据类型

基本数据类型

类型

关键字

位数

范围

初始值

布尔

BOOL

1

1或0

0

短整数

SINT

8

-27~27-1

 

整型

INT

     

双整型

DINT

     

长整型

LINT

     

无符号短整型

USINT

     

无符号整型

UINT

     

无符号双整型

UDINT

     

无符号长整型

DLINT

     

实数

REAL

     

长实数

LREAL

     

时间

TIME

   

T#0S

日期

DATE

   

D#0001-01-01

时刻

TOD

   

TOD#00:00:00

日期和时刻

TD

   

DT#0001-01-01 00:00:00

变长度单字节字符串

STRING

     

变长度双字节字符串

WSTRING

     

8位位串

BYTE

     

16位位串

WORD

     

32位位串

DWORD

     

64位位串

LWORD

     
         

 

衍生数据类型

类型

示例

说明

常量

TYPE

PI:REAL:=3.1415927;

END_TYPE

 

枚举

TYPE

Color:(RED,BLUE,GREEN);

END_TYPE

 

子范围

TYPE

AI:INT(0..32000);

END_TYPE

 

数组

TYPE

ARR1:ARRAY[1..100] OF INT;

ARR1:ARRAY[1..100] OF COLOR;

END_TYPE

 

结构体

TYPE

Fvalue:

STRUCT

MAX:INT;

MIN:INT;

END_STRUCT

END_TYPE

 

 

 

结构化文本语言

条件执行

IF _condition_ THEN

// Statement section IF

;

END_IF;

条件分支

IF _condition_ THEN

// Statement section IF

;

ELSE

// Statement section ELSE

;

END_IF;

条件多分支

IF _condition_ THEN

// Statement section IF

;

ELSIF _condition_ THEN

// Statement section ELSIF

;

ELSE

// Statement section ELSE

;

END_IF;

多分支选择

CASE _variable_name_ OF

1: // Statement section case 1

;

2..4: // Statement section case 2 to 4

;

ELSE // Statement section ELSE

;

END_CASE;

计数循环

FOR _counter_ := _start_count_ TO _end_count_ DO

// Statement section FOR

;

END_FOR;

按步宽计数循环

FOR _counter_ := _start_count_ TO _end_count_ BY _count_step_ DO

// Statement section FOR

;

END_FOR;

条件满足循环

WHILE _condition_ DO

// Statement section WHILE

;

END_WHILE;

条件不满足循环

REPEAT

// Statement section REPEAT

;

UNTIL _condition_ END_REPEAT;

终止当前循环

CONTINUE;

退出循环

RETURN;