让榨汁机定时工作(C#+PLC)

买了自加热的榨汁机每天补充营养是件好事,但是为此早起一个小时却划不来。如果为了节省时间,早上用微波炉加热昨晚做好的豆汁,口感却不怎么好。怎么办?买定时加热的榨汁机,估计价钱会很高,不过市面上好像也没有带这种功能的。

正好这段时间对硬件比较感兴趣,所以抽时间用西门子PLC224实现了该功能(一个PLC一两千元,用PLC控制好像有点高射炮打蚊子--大材小用,建议最好用单片机或.Net Micro Framework实现,这样成本会很低)。

基本思路:

1、由于PLC外部没有显示和控制接口,所以需要在PC机上编写一个程序,用来设定定时时间和间隔。此外由于PLC的时钟精度较低,长时间运行偏差较大,所以还得提供一个校时功能。

2、PLC程序相对比较简单,只要用当前时间和设定时间进行比较,时间到,则Q0.0输出信号,由此驱动继电器工作,过了时间间隔,则停止输出。

3、PC和PLC通信部分,由于PLC原生支持PPI协议,可以采用我以前编写的西门子PPI控件进行访问。当然也可以采用Modbus Rtu模式进行通信,不过需要PLC程序添加Modbus Rtu Slave库,这样增大了PLC程序空间,由于Modbus协议为公开协议,可以在PC上自行编写Modbus Rtu读写程序,不过也可以采用我编写的Modbus Rtu控件进行通信控制。

实际接线图如下:
  
   PLC程序如下(语句表)

TITLE=榨汁机控制程序|[叶帆工作室]http://blog.csdn.net/yefanqiu

Network 1 

// 初始化

LD     SM0.1

MOVB   16#55, VB101                //复位初始状态

Network 2 

// 设定日期

LDB=   VB100, 16#AA

MOVB   16#55, VB100

//VB110 年 VB111 月 VB112 日 VB113 时 VB114 分 VB115 秒 VB117 星期

TODW   VB110                       //设置时钟

Network 3 

// 读取日期(1s刷新一次)

LD     SM
0.5

EU

TODR   VB120                       //读取时钟

Network 4 

// 判断是否开始输出

LDB=   16#55, VB101                //没有输出

AB=    VB123, VB130                //时

AB=    VB124, VB131                //分

AB=    VB125, VB132                //秒

EU

S      Q0.0, 1                     //Q0.0输出

MOVB   16#AA, VB101                //置位状态

Network 5 

// 判断是否停止输出

LDB=   16#AA, VB101                //没有输出

AB=    VB123, VB140                //时

AB=    VB124, VB141                //分

AB=    VB125, VB142                //秒

EU

R      Q0.0, 1                     //Q0.0输出

MOVB   16#55, VB101                //复位状态

  PC程序运行后的界面:

  相关代码如下:

using System;

using System.
Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Text.RegularExpressions;

namespace PPI_Test

{

    public partial class frmMain : Form

    {

        public frmMain()

        {

            InitializeComponent();

        }

private void frmMain_Load(object sender, EventArgs e)

        {

            //"×××公司"    '已注册的公司名称

            axS7_PPI1.InitRegCompany("叶帆测试");            

            axS7_PPI1.bps = PPIV2.PPIBps.mb9600;

            axS7_PPI1.CheckOut = PPIV2.PPICheckOut.mbEven;    

            if (axS7_PPI1.OpenPort(1, 2, 1024, 512) != 0)

            {

                MessageBox.Show("打开串口失败!");

            }

        }

private void frmMain_FormClosed(object sender, FormClosedEventArgs e)

        {

            axS7_PPI1.ClosePort();

        }

        

        /// 

        /// 登录

        /// 

        /// 

        /// 

        private void btnLogin_Click(object sender, EventArgs e)

        {

            if (axS7_PPI1.PlcLogin(byte.Parse(txtFixAddr.Text)) == 0)

            {

                txtFixAddr.BackColor = Color.Green;

            }

            else

            {

                txtFixAddr.BackColor = Color.Red;

            }

        }

//运行

        private void btnRun_Click(object sender, EventArgs e)

        {

            int intAddr = int.Parse(txtFixAddr.Text);

long lngRet = axS7_PPI1.PlcRun(intAddr);

            if (lngRet == 0)

            {

                MessageBox.Show("开始运行!");

            }

            else if (lngRet == 4)

            {

                MessageBox.Show("PLC拨码
开关在停止位置!");

            }

            else

            {

                MessageBox.Show("操作失败!");

            }

        }

//停止

        private void btnStop_Click(object sender, EventArgs e)

        {

            int intAddr = int.Parse(txtFixAddr.Text);

            long lngRet = axS7_PPI1.PlcStop(intAddr);

            if (lngRet == 0)

            {

                MessageBox.Show("停止运行!");

            }

            else

            {

                MessageBox.Show("操作失败!");

            }

        }

//读取日期

        private void btnGetDate_Click(object sender, EventArgs e)

        {

            int intAddr = int.Parse(txtFixAddr.Text);

            object vData = new object();

if (axS7_PPI1.ReadData(120, ref vData, 6, PPIV2.PPILEN.PPI_B,

         PPIV2.PPITYPE.PPI_V, intAddr) == 0)

            {

                Int32[] intData = (Int32[])vData;

                lblDate.Text ="20"+ intData[0].ToString("X2") + "-" +

       intData[1].ToString("X2") + "-" + intData[2].ToString("X2") + " " +

                           intData[3].ToString("X2") + ":" + intData[4].ToString("X2")

          + ":" + intData[5].ToString("X2");

            }

            else

            {

                lblDate.Text = "读日期错!";

            }

        }

        private void btnSetDate_Click(object sender, EventArgs e)

        {

            int intAddr = int

时间: 2024-10-28 12:46:48

让榨汁机定时工作(C#+PLC)的相关文章

艾伟_转载:让榨汁机定时工作(C#+PLC)

买了自加热的榨汁机每天补充营养是件好事,但是为此早起一个小时却划不来.如果为了节省时间,早上用微波炉加热昨晚做好的豆汁,口感却不怎么好.怎么办?买定时加热的榨汁机,估计价钱会很高,不过市面上好像也没有带这种功能的. 正好这段时间对硬件比较感兴趣,所以抽时间用西门子PLC224实现了该功能(一个PLC一两千元,用PLC控制好像有点高射炮打蚊子--大材小用,建议最好用单片机或.Net Micro Framework实现,这样成本会很低). 基本思路: 1.由于PLC外部没有显示和控制接口,所以需要在

利用 WSH 作定时工作流程

定时 一个很常见的 ASP 问题 : "如何定时工作流程执行网页?", 之所以会问这个问题大部分是因为管理员可能会利用一个 ASP 网页来作数据库维护的动作, 如备份...等, 在 Windows NT 平台有一个方法可以做工作流程, 那就是 AT 指令 + Schedule 服务, 但很可惜的是你并没有法度在命令列 (Command-Line) 执行 ASP 网页 当然你可以在命令列执行 IE 并告诉它要求执行的网页, 例如: c:\program files\internet ex

巧用Win7切换壁纸功能 定时工作提醒

很多朋友都非常喜欢Win7系统中可以自动切换壁纸的个性主题:多张美丽的壁纸在Win7桌面上定时切换,就像自动播放的幻灯片一样,酷炫又养眼.其实Win7主题切换壁纸 的酷炫功能不仅可以给我们美丽个性的系统界面,还能用来帮忙碌白领们在天天凝视显示器的工作中大致掌握时间 . 在写字间工作的白领们时间观念都超强,除了设定好的时间表事件提醒,很多公司人也很习惯在半点或者整点有一个定时提醒.如果用定时器之类的软件,频繁弹出的窗口多少有点影响工作.如果我们利用Win7主题的壁纸定时切换功能,既不会有弹出干扰,

定时工作思路设计?

问题描述 现在想用两个定时器,Timer1用于创建表,Timer2用于向表中添加数据,我想在晚上21:00向数据库中创建一个新表以当天日期作表名,并开始向表中添加数据,到第二天早上7:00停止,现在问题是:这个程序21点后每小时都创建一个表,想用在这段时间内判断表是否存在,但是过了0点后,day就加1到了下一天,这是该如何判断?请教这个问题怎么解决?PrivateSubTimer1_Tick(ByValsenderAsObject,ByValeAsSystem.EventArgs)Handles

nginx日志定时切割脚本的一些例子

每天自动nginx日志切割脚本  代码如下 复制代码 [bash] #!/bin/bash #先把日期赋值到变量,因为是在第二天0点后执行,所以日期应该获取前一天的,如20120903 todaydate=`date –date='yesterday' "+%Y%m%d"` #把网站的子目录日志枚举一下 for site in `ls -l /home/log/ | grep -v "^d" |awk '{print $NF}'` #移动昨天的日志到新的位置,重命名

【LINUX学习】例行命令的建立

例行命令就是那些需要定期执行的命令或者某个脚本.在linux中一般使用at 和contable服务来实现. 下面就简要的介绍一下两个的大概使用方法 at :此服务仅仅执行一次,之后就从linux中取消 先查看一下at服务的状态 [root@localhost test]# service atd status atd (pid 2222) 正在运行... 停止服务 [root@localhost test]# service atd stop 停止 atd:[确定]  启动服务 [root@lo

一个安全Web服务器的安装(3)

web|web服务|web服务器|安全 这样就会保证Apache.Scanlogd和SuSE防火墙在计算机启动时自动执行.现在我们继续配置本地防火墙,将/etc/rc.config.d/firewall.rc.config(个别变量的细节描述在这个文件中可以找到)文件中的对应行改成下面的形式: FW_DEV_WORLD="eth0" # query no. 2 FW_SERVICES_EXTERNAL_TCP="www https" # query no. 9 FW

在MYSQL中如何使用API

    5.2 选择API    本节介绍根据各种类型的应用程序选择A P I的方法,比较C.DBI 和PHP API 的能力,并给出它们相对的优点和缺点,并指出什么时候应选择哪一个.    首先应该指出,笔者不认为任一种语言优于其他语言.尽管笔者的确有自己的喜好,但还是统统使用它们.您也会有自己的喜好,像我的评论家一样.一个评论家会感觉应该强调C 对MySQL编程的重要性,应将这种重要性上升到更重要的程度,而另一个评论家会认为C编程相当困难,应放褂盟∧Φ比ê獗窘谥刑致鄣恼庑┮蛩兀贸鲎约

C++指针探讨(三)成员函数指针

C语言的指针相当的灵活方便,但也相当容易出错.许多C语言初学者,甚至C语言老鸟都很容易栽倒在C语言的指针下.但不可否认的是,指针在C语言中的位置极其重要,也许可以偏激一点的来说:没有指针的C程序不是真正的C程序. 然而C++的指针却常常给我一种束手束脚的感觉.C++比C语言有更严格的静态类型,更加强调类型安全,强调编译时检查.因此,对于C语言中最容易错用的指针,更是不能放过:C++的指针被分成数据指针,数据成员指针,函数指针,成员函数指针,而且不能随便相互转换.而且这些指针的声明格式都不一样: