借助A2工业计算机和4G网络,设计智能喷淋系统,实现根据传感器数据定时控制喷淋的功能。

主要设计目标如下:

    • 控制大功率喷淋水泵开关
    • 接入多种传感器,温湿度、光照、土壤PH等
    • 接入物联网平台,采集数据、下发执行命令
    • 下发联动策略,由本地规则引擎执行
    • 接入星尘平台,监控设备健康状况
    • 支持OTA空中升级应用


电气图

采用工业级设备,大功率喷淋水泵,总电气接线图如下:

真实项目中,还需要电箱和开关电源,把这些东西都安装在电箱里面。

这里使用12v圆口电源,通过转接线给A2工控机的欧式端子供电,同时给继电器控制板和温湿度传感器供电。


继电器控制板使用工控机的COM1口,温湿度传感器使用工控机的COM2口,可以在程序中根据实际情况调整。


喷淋水泵功率较大,本身是圆口电源直接给水泵供电,我们让红线正极通过继电器控制,黑线附近直连。

同理,继电器控制板的另外3个继电器还可以控制其它设备,支持220v10A。

务必注意,不要搞混了工控机电源和喷淋水泵电源,接线错误可能损坏传感器(A2工控机有防护功能)。


上电测试

A2-4G自带4G全网通模块以及物联网卡(含1年流量)。

开箱后先给工控机上电测试,此时自动通过4G联网,可在星尘公网查看到该设备。

http://star.newlifex.com

工控机带有双网口,其中Ethernet1具有DHCP功能,接入网线即可联网。

网线和4G可以同时连接,优先使用以太网,以太网断开时自动切换到4G网络


为了取得较好网络质量,需要连接好4G天线,并把天线放置在高处。


连接设备

安装MobaXterm,接上网线后(不支持4G远程连接工控机),使用SSH连接工控机IP地址(可从路由器或星尘找到),默认账号密码都是feifan


工控机内部已安装好.NET3.1/5.0,新机器安装有.NET6.0


使用MobaXterm可以很方便的上传下载文件,左边有可视化目录,拖拽文件即可。


agent目录部署有星尘代理StarAgent,默认连接星尘公网 http://star.diyibox.com:6600 ,可以修改为自己的平台地址。

StarAgent设置为系统服务,随系统启动会自动运行。


flower目录部署有喷淋系统程序,并且由StarAgent守护,配置文件 ~/agent/Config/StarAgent.config。

因此,计算机启动时,StarAgent也会拉起喷淋系统程序,即使程序崩溃退出或者认为终止进程,StarAgent仍然会拉起程序(每分钟检查)。

<?xml version="1.0" encoding="utf-8"?>
<StarAgent>
  <!--调试开关。默认true-->
  <Debug>true</Debug>
  <!--证书-->
  <Code></Code>
  <!--密钥-->
  <Secret></Secret>
  <!--本地服务。默认udp://127.0.0.1:5500-->
  <LocalServer>udp://127.0.0.1:5500</LocalServer>
  <!--更新通道。默认Release-->
  <Channel>Release</Channel>
  <!--应用服务集合-->
  <Services>
    <ServiceInfo>
      <Name>flower</Name>
      <FileName>GirlFlower</FileName>
      <Arguments></Arguments>
      <WorkingDirectory>/home/feifan/flower/</WorkingDirectory>
      <AutoStart>true</AutoStart>
      <Retry>3</Retry>
      <AutoRestart>true</AutoRestart>
      <Singleton>false</Singleton>
    </ServiceInfo>
  </Services>
</StarAgent>


程序开发与上传

喷淋控制主要源码

using System;
using System.Threading;
using NewLife;
using NewLife.Log;
using NewLife.Threading;
using SmartOS_A2;
using Stardust;

namespace GirlFlower
{
    class Program
    {
        private static ITracer _tracer;
        private static TimerX _timer;
        private static TimerX _timer2;
        static void Main(string[] args)
        {
            XTrace.UseConsole();

            var star = new StarFactory(null, null, null);
            _tracer = star.Tracer;
            A2.Led.Tracer = star.Tracer;
            A2.Buzzer.Tracer = star.Tracer;
            A2.COM1.Tracer = star.Tracer;
            A2.COM2.Tracer = star.Tracer;

            // 闪灯,闪蜂鸣器
            var led = A2.Led;
            var buzzer = A2.Buzzer;
            for (var i = 0; i < 6; i++)
            {
                led.Write(i % 2 == 0);
                buzzer.Write(i % 2 == 0);
                Thread.Sleep(300);
            }

            var relay = new RelayControl { Modbus = A2.COM1 };
            relay.Write(0, false);

            //var timer = new TimerX(DoWork, relay, "*/5 * * * * *") { Async = true };
            _timer = new TimerX(DoControl, relay, "0 0 6-20/2 * * *") { Async = true };
            _timer.SetNext(5_000);

            var sensor = new TemperatureSensor { Modbus = A2.COM2 };
            _timer2 = new TimerX(DoCollect, sensor, 1_000, 10_000) { Async = true };

            Thread.Sleep(-1);
        }

        static void DoControl(Object state)
        {
            using var span = _tracer?.NewSpan("OpenControl");

            XTrace.WriteLine("开始控制!");
            var led = A2.Led;
            led.Write(true);

            var relay = state as RelayControl;
            relay.Write(0, true);
            Thread.Sleep(15_000);
            relay.Write(0, false);

            led.Write(false);
            XTrace.WriteLine("结束控制!");
        }

        static void DoCollect(Object state)
        {
            using var span = _tracer?.NewSpan("ReadData");

            var sensor = state as TemperatureSensor;

            // 读取温湿度
            var (temp, humi) = sensor.ReadValues();
            XTrace.WriteLine("传感器,温度:{0:n1}°C,湿度:{1:p1}", temp, humi);

            if (span != null) span.Tag = $"温度:{temp:n1}°C,湿度:{humi:p1}";
        }
    }
}

从代码中可以看到,喷淋系统启动时先让蜂鸣器鸣叫3次,并且闪灯,告知用户系统程序已启动。

然后配置继电器控制和温湿度采集,各自启动一个定时器。

继电器按照Cron表达式定时执行,启动5秒后临时增加一次执行;

温湿度采集是每10秒一次,借助星尘埋点,送到星尘监控平台。

http://star.newlifex.com/Monitors/appDayStat?appId=36

http://star.newlifex.com/trace?id=0a00000c16208351988313e84e048a

后面对接物联网平台后,传感器数据将直接送给平台。


程序发布为linux-arm,然后使用MobaXterm部署到工控机的flower目录下。

上图为部署所必要的文件。


切换到flower目录,给GirlFlower加执行权限 chmod +x GirlFlower

然后可以直接跑起来 sudo ./GirlFlower ,注意,控制串口需要管理员权限,因此这里需要sudo。

如果不想加执行权限,也可以用dotnet命令启动 sudo dotnet GirlFlower.dll


工控机上电后,让程序先跑一会,去星尘看看是否有正常的数据上报 http://star.newlifex.com/Monitors/appDayStat?appId=36

一切正常后,再做电器线路连接。


最后的最后,一定要注意安全,禁止带电接线!!!