精华内容
下载资源
问答
  • 多路延时开关控制器
    2021-04-11 01:18:45

    遥控器的按键A按下后,继电器1闭合,再按一次A,继电器1断开,依次循环。
    遥控器的按键B按下后,继电器2闭合,再按一次B,继电器2断开,依次循环。
    遥控器的按键C按下后,继电器3闭合,再按一次C,继电器3断开,依次循环。
    遥控器的按键D按下后,继电器4闭合,再按一次D,继电器4断开,依次循环。
    A.B.C.D口需要加10K的上拉电阻
    #include <reg52.h>
    void Init_Timer0(void);
    unsigned long time_20ms ;

    /------------------------------------------------
    uS延时函数,含有输入参数 unsigned char t,无返回值
    unsigned char 是定义无符号字符变量,其值的范围是
    0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
    长度如下 T=tx2+5 uS
    ------------------------------------------------
    /
    void DelayUs2x(unsigned char t);
    /------------------------------------------------
    uS延时函数,含有输入参数 unsigned char t,无返回值
    unsigned char 是定义无符号字符变量,其值的范围是
    0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
    长度如下 T=tx2+5 uS
    ------------------------------------------------
    /
    void DelayUs2x(unsigned char t)
    {
    while(–t);
    }
    /------------------------------------------------
    mS延时函数,含有输入参数 unsigned char t,无返回值
    unsigned char 是定义无符号字符变量,其值的范围是
    0~255 这里使用晶振12M,精确延时请使用汇编
    ------------------------------------------------
    /
    void DelayMs(unsigned char t);
    /------------------------------------------------
    mS延时函数,含有输入参数 unsigned char t,无返回值
    unsigned char 是定义无符号字符变量,其值的范围是
    0~255 这里使用晶振12M,精确延时请使用汇编
    ------------------------------------------------
    /
    void DelayMs(unsigned char t)
    {

    while(t–)
    {
    //大致延时1mS
    DelayUs2x(245);
    DelayUs2x(245);
    }
    }

    sbit Key315_A = P2^2;
    sbit Key315_B = P2^0;
    sbit Key315_C = P2^3;
    sbit Key315_D = P2^1;

    sbit relay1 = P1^0;
    sbit relay2 = P1^1;
    sbit relay3 = P1^2;
    sbit relay4 = P1^3;

    unsigned char rekey_a,rekey_b,rekey_c,rekey_d; //防止重复参数
    void main (void)
    {
    Init_Timer0(); //定时器0初始化
    DelayMs(10);
    while(1) //主循环
    {
    if(Key315_A == 1) //A按键按下 高电平有效
    {
    if(rekey_a == 0) //防止重复按下在这里插入图片描述

    		{
    			DelayMs(10);	//消除的抖动
    			if(Key315_A ==1)  //再次确认
    			{
    				rekey_a =1 ;		  //放重复
    			   	relay1 =!relay1 ;	  //继电器发转状态
    				DelayMs(30);
    			}
    		}
    	}
    	else
    	{rekey_a = 0;}		//防止重复
    
    	if(Key315_B == 1)		//B按键按下 高电平有效
    	{
    		if(rekey_b == 0)	//防止重复按下
    		{
    			DelayMs(10);	//消除的抖动
    			if(Key315_B ==1)  //再次确认
    			{
    				rekey_b =1 ;		  //放重复
    			   	relay2 =!relay2 ;	  //继电器发转状态
    				DelayMs(30);
    			}
    		}
    	}
    	else
    	{rekey_b = 0;}		//防止重复
    
    	if(Key315_C == 1)		//C按键按下 高电平有效
    	{
    		if(rekey_c == 0)	//防止重复按下
    		{
    			DelayMs(10);	//消除的抖动
    			if(Key315_C ==1)  //再次确认
    			{
    				rekey_c =1 ;		  //放重复
    			   	relay3 =!relay3 ;	  //继电器发转状态
    				DelayMs(30);
    			}
    		}
    	}
    	else
    	{rekey_c = 0;}		//防止重复
    
    	if(Key315_D == 1)		//D按键按下 高电平有效
    	{
    		if(rekey_d == 0)	//防止重复按下
    		{
    			DelayMs(10);	//消除的抖动
    			if(Key315_D ==1)  //再次确认
    			{
    				rekey_d =1 ;		  //放重复
    			   	relay4 =!relay4 ;	  //继电器发转状态
    				DelayMs(30);
    			}
    		}
    	}
    	else
    	{rekey_d = 0;}		//防止重复
    }
    

    }

    void Init_Timer0(void)
    {
    TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
    TH0=(65536-20000)/256; //重新赋值 20ms
    TL0=(65536-20000)%256;
    EA=1; //总中断打开
    ET0=1; //定时器中断打开
    TR0=1; //定时器开关打开
    }

    void Timer0_isr(void) interrupt 1
    {
    TH0=(65536-20000)/256; //重新赋值 20ms
    TL0=(65536-20000)%256;

    time_20ms++;
    

    }
    在这里插入图片描述

    更多相关内容
  • 通过互联网络TCP(pc机),远程控制继电器开关,和查询四温度DS18B20传感器的温度 下位机使用的是51单片机 淘宝上淘的TCP转串口模块,和四继电模块(底电平触发) 电路上有5个指示灯 分别为:电源指示...
  • 蜂鸣用一PNP 型三极管驱动,集电极(C极)通过蜂鸣线圈接5V电源,基极(B极) 是控制端,发射极(E 极)接地,当三极管C,B 极PN 结正偏时,PN结导通,即B极为低电 平时,三极管导通,蜂鸣发声,视频中有介绍...
  • 10 可以控制6路开关的通断输出 11 可以采集6路开关的状态 12 如何把读取的数据赋值给控件及各类处理 2019-1-20 发布说明最新功能 1、发命令控制某一路通断 2、一条命令控制12整体的状态通断 3、发命令控制某一路...
  • 8modbus RTU控制器说明书 产品介绍 本控制器带有8采集和8继电器输出,因灵活的使用方式被客户广泛的使用在各个行业及领域。同时带有二次开发协议,方便客户集成到自己的系统中。可以通过串口232发送MODBUS RTU...
  • 通过地址编码,在延时1秒许可的情况下,一个串口最多可以寻址、控制100块串口控制器,构成一个由4000个输出点的大系统。6、可提供串口通信协议以及VB通信源程序,赠送VB通过RS232串口操作控制器的演示程序或代为开发...
  • 是深圳市精敏数字机器有限公司自主研发的一种主要由电脑和工业级高可靠步进电机串口控制器实现的串口控制2步进(或伺服)电机运行的高可靠性高速数控系统,具有操作简便、抗干扰、性能稳定、功能强大、经济实用等...
  • 多路数据传送过程中,能够根据需要将其中任意一路选出来的电路,叫做数据选择,也称多路选择多路开关。在选择变量控制下,从多路数据输入中某一路数据送至输出端。对于一个具有 2^n 个输入和 1 个输出的多路...

    摘要:多路选择器是数据选择器的别称。在多路数据传送过程中,能够根据需要将其中任意一路选出来的电路,叫做数据选择器,也称多路选择器或多路开关。在选择变量控制下,从多路数据输入中某一路数据送至输出端。对于一个具有 2^n 个输入和 1 个输出的多路选择器,有 n 个选择变量。多路选择器也是 FPGA 内部的一个基本资源,主要用于内部信号的选通。简单的多路选择器还可以通过级联生成更大的多路选择器。

    一、使用的开发板

    正点原子新起点FPGA开发板

    LED灯硬件原理图
    流水灯实验管脚分配
    按键电路原理图
    触摸按键控制LED管脚分配图

    二、功能分析

    1、模块框图

    模块框图
    输入输出信号描述

    2、波形图绘制

    框图结构设计完毕后就可以实现该模块的具体功能了,也就是要找到输入和输出之间具体的映射关系。输入和输出满足信号与系统中输入与响应的关系。其中输入信号的名字用绿色表示,输出信号的名字用红色表示,任意模拟输入波形,画出输出信号的波形

    经分析得,当 sel 为低电平时,out 的输出波形和 in2 相同;当 sel 为高电平时,out 的输出波形和 in1 相同。根据分析的输入输出关系,我们列出如表格所示的真值表,然后再根据真值表的输入与输出的对应关系画出波形图。其波形图如图所示,图中蓝色的线代表有效信号。

    三、程序设计

    1、RTL代码的编写

    开始RTL代码的编写,RTL代码编写出的模块叫RTL模块(后文中也称功能模块、可综合模块)。之所以叫RTL代码是因为用Verilog HDL在Resistances Transistors Logic(寄存器传输级逻辑)来描述硬件电路,RTL代码能够综合出真实的电路以实现我们设计的功能,区别于不可综合的仿真代码。

    `timescale  1ns/1ns
    
    
    module  mux2_1 //模块的开头以“module”开始,然后是模块名“mux2_1”
    (
        input   wire    in1,    //输入端1,信号名后就是端口列表“();”(端口列表里面列举了该模块对外输入、输出信号的方式、类型、位宽、名字),该写法采用了Verilog-2001标准,这样更直观且实例化更方便,之前的Verilog-1995标准是将模块对外输入、输出信号的方式、类型、位宽都放到外面
        input   wire    in2,    //输入端2,当数据只有一位宽时位宽表示可以省略,且输入只能是wire型变量
        input   wire    sel,    //选择端,每行信号以“,”结束,最后一个后面不加“,”
    
        output  reg     out     //结果输出,输出可以是wire型变量也可以是reg型变量,如果输出在always块中被赋值(即在“<=”的左边)就要用reg型变量,如果输出在assign语句中被赋值(即在“=”的左边)就要用wire型变量
    );    //端口列表括号后有个“;”不要忘记
    
    //********************************************************************//
    //***************************** Main Code ****************************//
    //********************************************************************//
    //out:组合逻辑输出sel选择的结果
    always@(*)                  //“*”为通配符,表示只要if括号中的条件或赋值号右边的变量发生变化则立即执行下面的代码,“(*)”在此always中等价于“(sel, in1, in2)”写法
        if(sel == 1'b1)         //当“if...else...”中只有一个变量时不需要加“begin...end”,也显得整个代码更加简洁
            out = in1;          //always块中如果表达的是组合逻辑关系时使用“=”进行赋值,每句赋值以“;”结束
        else
            out = in2;
    
    /*
    //out:组合逻辑输出选择结果
    always@(*)
        case(sel)
            1'b1    : out = in1;
    
            1'b0    : out = in2;
    
            default : out = in1;    //如果sel不能列举出所有的情况一定要加default。此处sel只有两种情况,并且完全列举了,所以default可以省略
        endcase
    */
    
    /*
    out:组合逻辑输出选择结果
    assign out = (sel == 1'b1) ? in1 : in2; //此处使用的是条件运算符(三元运算符),当括号里面的条件成立时,执行"?”后面的结果;如果括号里面的条件不成立时,执行“:”后面的结果
    */
    
    endmodule  //模块的结尾以“endmodule”结束(每个模块只能有一组“module”和“endmodule”,所有的代码都要在它们中间编写)
    
    

    2、代码的分析和综合

    3、 查看RTL视图

    4、Testbench代码的编写

    //时间尺度、精度单位定义,决定“#(不可被综合,但在可综合代码中也可以写,只是会在仿真时表达效果,而综合时会自动被综合器优化掉)”
    //后面的数字表示的时间尺度和精度,具体表达含义为:“时间尺度/时间精度”。
    //为了以后编写方便我们将该句放在所有“.v”文件的开头,后面的代码示例将不再显示该句
    `timescale  1ns/1ns 
    /*testbench的格式和待测试RTL模块的格式相同,也是以“module”开始以“endmodule”结束,所有的代码都要在它们中间编写。
    不同的是在testbench中端口列表为空,因为testbench不对外进行信号的输入输出,
    只是自己产生激励信号提供给内部实例化待测RTL模块使用,所以端口列表中没有内容,
    只是列出“()”,当然也可以将“()”省略,括号后有个“;”不要忘记*/
    module  tb_mux2_1(); 
    
    
    //********************************************************************//
    //****************** Parameter and Internal Signal *******************//
    //********************************************************************//
    //reg   define
    //要在initial块和always块中被赋值的变量一定要是reg型
    //(在testbench中待测试RTL模块的输入永远是reg型变量)
    reg     in1;
    reg     in2;
    reg     sel;
    
    //wire  define
    //输出信号,我们直接观察,也不用在任何地方进行赋值,所以是wire型变量
    //(在testbench中待测试RTL模块的输出永远是wire型变量)
    wire    out;
    
    //********************************************************************//
    //***************************** Main Code ****************************//
    //********************************************************************//
    /*initial语句是不可以被综合的,一般只在testbench中表达而不在RTL代码中表达。,
    initial块中的语句上电后只执行一次,主要用于初始化仿真中要输入的信号,
    初始化值在没有特殊要求的情况下给0或1都可以。如果不赋初值,仿真时信号会显示为
    不定态(ModelSim中的波形显示红色)*/
    initial
        begin   //在仿真中begin...end块中的内容都是顺序执行的,在没有延时的情况下几乎没有差别,看上去是同时执行的,如果有延时才能表达的比较明了;而在rtl代码中begin...end相当于括号的作用,在同一个always块中给多个变量赋值的时候要加上
            in1 <= 1'b0;
            in2 <= 1'b0;
            sel <= 1'b0;
        end
    
    //in1:产生输入随机数,模拟输入端1的输入情况
    always #10 in1 <= {$random} % 2;    //取模求余数,产生非负随机数0、1,每隔10ns产生一次随机数
    
    //in2:产生输入随机数,模拟输入端2的输入情况
    always #10 in2 <= {$random} % 2;
    
    //sel:产生输入随机数,模拟选择端的输入情况
    always #10 sel <= {$random} % 2;
    
    //下面的语句是为了在ModelSim仿真中直接打印出来信息便于观察信号变化的状态,也可以不使用下面的语句而直接观察仿真出的波形
    //------------------------------------------------------------
    initial begin
        $timeformat(-9, 0, "ns", 6);    //设置显示的时间格式,此处表示的是(打印时间单位为纳秒,小数点后打印的小数位为0位,时间值后打印的字符串为“ns”,打印的最小数量字符为6个)
        $monitor("@time %t: in1=%b in2=%b sel=%b out=%b", $time, in1, in2, sel, out);   //只要监测的变量(时间、in1, in2, sel, out)发生变化,就会打印出相应的信息
    end
    //------------------------------------------------------------
    
    //********************************************************************//
    //**************************** Instantiate ***************************//
    //********************************************************************//
    //待测试RTL模块的实例化,相当于将待测试模块放到测试模块中,并将输入输出对应连接上,测试模块中产生激励信号给待测试模块的输入,以观察待测试模块的输出信号是否正确
    //------------- mux2_1_inst -------------
    mux2_1  mux2_1_inst
    (    
    //第一个是被实例化模块的名子,第二个是我们自己定义的在另一个模块中实例化后的名字。同一个模块可以在另一个模块中或不同的另外模块中被多次实例化,第一个名字相同,第二个名字不同
        .in1(in1),  //input     in1,前面的“in1”表示被实例化模块中的信号,后面的“in1”表示实例化该模块并要和这个模块的该信号相连接的信号(可以取名不同,一般取名相同,方便连接和观察),“.”可以理解为将这两个信号连接在一起
        .in2(in2),  //input     in2
        .sel(sel),  //input     sel
    
        .out(out)   //output    out
    );
    endmodule
    

    5、ModelSim仿真波形

    6、上板验证


    展开全文
  • ESP8266利用Bliker、小爱同学和本地按钮控制4路开关

    千次阅读 热门讨论 2021-10-08 13:39:01
    ESP8266利用Bliker、小爱同学和本地按钮控制4路开关 Blinker函数说明: Button.color("#FFFF00"); //设置app按键是纯黄色,16进制颜色码 Button.text("开"); //设置app按键注释“开” Button.icon("fal fa-power-...

    ESP8266利用Bliker、小爱同学和本地按钮控制4路开关


    Blinker函数说明:

    • Button.color("#FFFF00"); //设置app按键是纯黄色,16进制颜色码
    • Button.text("开"); //设置app按键注释“开”
    • Button.icon("fal fa-power-on");//按键图标。

    获取更多图标:https://fontawesome.com/v5.15/icons?d=gallery&p=2&c=arrows,design&m=free

    • Button.print("on");//调试器窗口打印信息
    • Blinker.vibrate(); //开启继电器时反馈,让手机震动

    配网使用注意事项

    • 如果是使用Smartconfig配网:

    请启用宏定义: #define BLINKER_ESP_SMARTCONFIG和Setup函数里面的,Blinker.begin(auth); //手机配网用这段
    注释掉:Setup函数里面的,Blinker.begin(auth, ssid, pswd);//代码配网用这段

    • 如果是使用直接写入的配网方式:

    注释掉宏定义: #define BLINKER_ESP_SMARTCONFIG和Setup函数里面的,Blinker.begin(auth); //手机配网用这段
    启用:Setup函数里面的,Blinker.begin(auth, ssid, pswd);//代码配网用这段

    实例代码

    本文采用代码直接写入wifi的方式配网。

    /* *****************************************************************  
     * 程序功能:blinker+小爱同学+本地按键(点触自复位)控制插座4路插孔/开关
     * 1.使用开发板:nodemcu-ESP8266(模块ESP-12F)
     * 2.程序功能1:使用Blinker 手机APP添加设备并绑定,通过Blinker APP或者小爱同学,
     *   远程控制开发板相连的继电器开关
     * 3.程序功能2:使用本地开关控制继电器开关,并反馈继电器状态到Blinker控制按钮
     * 4.例程文档:小爱类:https://www.diandeng.tech/doc/xiaoai
     *            SmartConfig自动配网:https://blog.csdn.net/u014091490/article/details/105178037
     *            Blinker心跳包:https://github.com/blinker-iot/blinker-doc/wiki/Blinker-Arduino-%E5%BA%93%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C
     * 5.程序参考:blinker库例程--blinker-library-master\examples\Blinker_MIOT\MIOT_MULTI_OUTLET
     * *****************************************************************/
    
    #define BLINKER_WIFI               //支持wifi
    //#define BLINKER_ESP_SMARTCONFIG    //Smartconfig或者手机微信扫码自动配网,代码配网请注释此条
    #define BLINKER_MIOT_MULTI_OUTLET  //支持多路插座,最多4个插孔
    #define BLINKER_PRINT Serial       //串口协议库
    #define BLINKER_WITHOUT_SSL        //blinker默认使用加密方式进行远程通信,但通信加密会消耗大量的RAM,如果您对通信安全性无要求
                         //可以添加宏BLINKER_WITHOUT_SSL用以获得更多可用RAM,BLINKER_WITHOUT_SSL目前仅可用于ESP8266,其他设备的RAM足以进行加密通信
     
    #include <Blinker.h>               //使用第三方Blinker库
    
    
    char auth[] = "7963c4b7e283";      //Blinker APP(连接小爱同学必须阿里云服务器)中获取到的Secret Key(密钥)
    //代码配网用这段
    char ssid[] = "MERCURY_D268G";                     //wifi名称
    char pswd[] = "pba5ayzk";              //wifi密码
     
    //定义继电器信号
    #define Relay_1 5         //定义继电器1信号接入GPIO5,D1
    #define Relay_2 4         //定义继电器2信号接入GPIO4,D2
    #define Relay_3 0         //定义继电器3信号接入GPIO0,D3
    #define Relay_4 2         //定义继电器4信号接入GPIO2,D4
    
    //定义本地开关信号
    #define KG_1 14         //定义开关1信号接入GPIO14,D5
    #define KG_2 12         //定义开关2信号接入GPIO12,D6
    #define KG_3 13         //定义开关3信号接入GPIO13,D7
    #define KG_4 3          //定义开关4信号接入GPIO3,RX(GPIO15/D8持续低电平,后更改为GPIO3/RX接口)
     
    // 新建Blinker软件组件对象
    BlinkerButton Button("MainSwitch");     //组件对象,要和APP组件中的“数据键名”一致,总开关
    BlinkerButton Button1("Switch1");       //组件对象,要和APP组件中的“数据键名”一致,开关1
    BlinkerButton Button2("Switch2");       //组件对象,要和APP组件中的“数据键名”一致,开关2
    BlinkerButton Button3("Switch3");       //组件对象,要和APP组件中的“数据键名”一致,开关3
    BlinkerButton Button4("Switch4");       //组件对象,要和APP组件中的“数据键名”一致,开关4
    BlinkerButton Button5("Refresh");       //APP端按钮状态刷新
    
    //定义插座状态,用于小爱同学状态反馈
    bool oState[5] = { false };
    #define OUTLET_ALL   0  //所有插孔
    #define OUTLET_NO_1  1  //插座插孔一
    #define OUTLET_NO_2  2  //插座插孔二
    #define OUTLET_NO_3  3  //插座插孔三
    #define OUTLET_NO_4  4  //插座插孔四
    
    //反馈继电器状态函数
    void RelayState(int num)
    {
      switch(num)
      {
        case 1:   //插座插孔一状态
            if(digitalRead(Relay_1)==LOW)
            {
              Button1.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
              Button1.text("插座1开");          //设置app按键注释“开”
              Button1.print("on");
              oState[1] = true;
            }
            else if(digitalRead(Relay_1==HIGH))
            {
              Button1.color("#808080");   //设置app按键是灰色,16进制颜色码
              Button1.text("插座1关");          //设置app按键注释“关”
              Button1.print("off");
              oState[1] = false;
            }
            break;
        case  2:
            if(digitalRead(Relay_2)==LOW)
            {
              Button2.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
              Button2.text("插座2开");          //设置app按键注释“开”
              Button2.print("on");
              oState[2] = true;
            }
            else if(digitalRead(Relay_2==HIGH))
            {
              Button2.color("#808080");   //设置app按键是灰色,16进制颜色码
              Button2.text("插座2关");          //设置app按键注释“关”
              Button2.print("off");
              oState[2] = false;
            }
            break;
        case  3:
            if(digitalRead(Relay_3)==LOW)
            {
              Button3.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
              Button3.text("插座3开");          //设置app按键注释“开”
              Button3.print("on");
              oState[3] = true;
            }
            else if(digitalRead(Relay_3==HIGH))
            {
              Button3.color("#808080");   //设置app按键是灰色,16进制颜色码
              Button3.text("插座3关");          //设置app按键注释“关”
              Button3.print("off");
              oState[3] = false;
            }
            break;
        case  4:
            if(digitalRead(Relay_4)==LOW)
            {
              Button4.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
              Button4.text("插座4开");          //设置app按键注释“开”
              Button4.print("on");
              oState[4] = true;
            }
            else if(digitalRead(Relay_4==HIGH))
            {
              Button4.color("#808080");   //设置app按键是灰色,16进制颜色码
              Button4.text("插座4关");          //设置app按键注释“关”
              Button4.print("off");
              oState[4] = false;
            }
            break;
            default:
                break;
      }
    }
     
    //小爱同学控制插座多个插孔
    void ctrl_multi_outlet(uint8_t num, uint8_t io_level)
    {
        switch (num)
            {
                case 0:  //所有插孔
                    digitalWrite(Relay_1, io_level);//控制继电器1
                    digitalWrite(Relay_2, io_level);//控制继电器2
                    digitalWrite(Relay_3, io_level);//控制继电器3
                    digitalWrite(Relay_4, io_level);//控制继电器4
                    break;
                case 1:  //插座插孔一
                    digitalWrite(Relay_1, io_level);//控制继电器1
                    break;
                case 2:  //插座插孔二
                    digitalWrite(Relay_2, io_level);//控制继电器2
                    break;
                case 3:  //插座插孔三
                    digitalWrite(Relay_3, io_level);//控制继电器3
                    break;
                case 4:  //插座插孔四
                    digitalWrite(Relay_4, io_level);//控制继电器4
                    break;
                default:
                    break;
            }
    }
     
    //小爱电源类回调,例如:“打开插座”、“打开插座插孔一”、“打开插座插孔二”
    void miotPowerState(const String & state, uint8_t num)
    {
        BLINKER_LOG("need set outlet: ", num, ", power state: ", state);
     
        if (state == BLINKER_CMD_ON) 
        {
            ctrl_multi_outlet(num, LOW);//打开继电器,num表示是多少路(继电器低电平出发)
            BlinkerMIOT.powerState("on", num);
            BlinkerMIOT.print();
            RelayState(num);
     
            oState[num] = true;
        }
       else if (state == BLINKER_CMD_OFF) 
        {
            ctrl_multi_outlet(num, HIGH);//关闭继电器,num表示是多少路
     
            BlinkerMIOT.powerState("off", num);
            BlinkerMIOT.print();
            RelayState(num);
     
            oState[num] = false;
        }
    }
    
    //小爱设备查询的回调函数,查询设备状态,例如:“插座插孔一状态”
    void miotQuery(int32_t queryCode,uint8_t num)
    {
        BLINKER_LOG("插孔",num,"状态",",codes:", queryCode);
    
        switch (num)
        {
             case 0 :
                BLINKER_LOG("状态:");
                BlinkerMIOT.powerState(oState[1] ? "on" : "off");
                BlinkerMIOT.powerState(oState[2] ? "on" : "off");
                BlinkerMIOT.powerState(oState[3] ? "on" : "off");
                BlinkerMIOT.powerState(oState[4] ? "on" : "off"); 
                BlinkerMIOT.print();
                break;
             case 1 :
                BLINKER_LOG("插孔1状态:");
                BlinkerMIOT.powerState(oState[1] ? "on" : "off");
                BlinkerMIOT.print();
                break;
             case 2 :
                BLINKER_LOG("插孔2状态:");
                BlinkerMIOT.powerState(oState[2] ? "on" : "off");
                BlinkerMIOT.print();
                break;
             case 3 :
                BLINKER_LOG("插孔3状态:");
                BlinkerMIOT.powerState(oState[3] ? "on" : "off");
                BlinkerMIOT.print();
                break;
             case 4 :
                BLINKER_LOG("插孔4状态:");
                BlinkerMIOT.powerState(oState[4] ? "on" : "off");
                BlinkerMIOT.print();
                break;
             default :
                BlinkerMIOT.powerState(oState[1] ? "on" : "off");
                BlinkerMIOT.powerState(oState[2] ? "on" : "off");
                BlinkerMIOT.powerState(oState[3] ? "on" : "off");
                BlinkerMIOT.powerState(oState[4] ? "on" : "off"); 
                BlinkerMIOT.print();
                break;
        }
     }
    
    // 在APP控制,按下MainSwitch按键即会执行该函数
    void button_callback(const String & state)
    {
        BLINKER_LOG("操作了MainSwitch: ", state);//APP中的Monitor控件打印的信息
        if (state=="on") 
        {
            ctrl_multi_outlet(OUTLET_ALL, LOW);//打开继电器--所有
            // 反馈继电器状态
            Button.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
            Button.text("开");          //设置app按键注释“开”
            Button.icon("fal fa-power-on");
            Button.print("on");
            Blinker.vibrate();  //开启继电器时反馈,让手机震动
        } else if(state=="off")
        {
            ctrl_multi_outlet(OUTLET_ALL, HIGH);//关闭继电器--所有
            // 反馈继电器状态
            Button.color("#808080");   //设置app按键是纯黄色,16进制颜色码
            Button.text("关");          //设置app按键注释“开”
            Button.icon("fal fa-power-off");
            Button.print("off");
        }
    }
     
    // 在APP控制,按下Switch1按键即会执行该函数--第1路开关
    void button1_callback(const String & state)
    {
        BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
        if (state=="on") 
        {
            ctrl_multi_outlet(OUTLET_NO_1, LOW);//打开继电器--第1路
            // 反馈继电器1状态
            RelayState(1);    //调用继电器反馈程序
        } else if(state=="off")
        {
            ctrl_multi_outlet(OUTLET_NO_1, HIGH);//关闭继电器--第1路
            // 反馈继电器状态
            RelayState(1);    //调用继电器反馈程序
        }
    }
     
    // 在APP控制,按下Switch2按键即会执行该函数--第2路开关
    void button2_callback(const String & state)
    {
        BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
        if (state=="on") 
        {
            ctrl_multi_outlet(OUTLET_NO_2, LOW);//打开继电器--第2路
            // 反馈继电器状态
            RelayState(2);    //调用继电器反馈程序
        } else if(state=="off")
        {
            ctrl_multi_outlet(OUTLET_NO_2, HIGH);//关闭继电器--第2路
            // 反馈继电器状态
            RelayState(2);    //调用继电器反馈程序
        }
    }
     
     // 在APP控制,按下Switch3按键即会执行该函数--第3路开关
     void button3_callback(const String & state)
    {
        BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
        if (state=="on") 
        {
            ctrl_multi_outlet(OUTLET_NO_3, LOW);//打开继电器--第3路
            // 反馈继电器状态
            RelayState(3);    //调用继电器反馈程序
        } else if(state=="off")
        {
            ctrl_multi_outlet(OUTLET_NO_3, HIGH);//关闭继电器--第3路
            // 反馈继电器状态
            RelayState(3);    //调用继电器反馈程序
        }
    }
    
    // 在APP控制,按下Switch4按键即会执行该函数--第4路开关 
     void button4_callback(const String & state)
    {
        BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
        if (state=="on") 
        {
            ctrl_multi_outlet(OUTLET_NO_4, LOW);//打开继电器--第4路
            // 反馈继电器状态
            RelayState(4);    //调用继电器反馈程序
        } else if(state=="off")
        {
            ctrl_multi_outlet(OUTLET_NO_4, HIGH);//关闭继电器--第4路
            // 反馈继电器状态
            RelayState(4);    //调用继电器反馈程序
        }
    }
    
    //APP端状态手动刷新按钮
    void button5_callback(const String & state)
    {
      for(int i=0;i<5;i++)
      {
        RelayState(i);
      }
    }
    
    //心跳包刷新状态
     void heartbeat()
     {
      for(int i=0;i<5;i++)
      {
        RelayState(i);
      }
     }
     
     //本地开关控制继电器程序
     void bdms()
     {
      if(digitalRead(KG_1)==LOW)
      {
        digitalWrite(Relay_1, !digitalRead(Relay_1));
        //反馈继电器1状态
        RelayState(1);    //调用继电器反馈程序
        Blinker.delay(1000);    //必须加延时,否则灯一直切换状态
      }
      if(digitalRead(KG_2)==LOW)
      {
        digitalWrite(Relay_2, !digitalRead(Relay_2));
        RelayState(2);    //调用继电器反馈程序
        Blinker.delay(1000); 
      }
      if(digitalRead(KG_3)==LOW)
      {
        digitalWrite(Relay_3, !digitalRead(Relay_3));
        RelayState(3);    //调用继电器反馈程序
        Blinker.delay(1000);
      }
     if(digitalRead(KG_4)==LOW)
      {
        digitalWrite(Relay_4, !digitalRead(Relay_4));
        RelayState(4);    //调用继电器反馈程序
        Blinker.delay(1000);
      }
     }
     
    void setup()
    {
        // 初始化串口,用于调试,后期可删除
        Serial.begin(115200);
        BLINKER_DEBUG.stream(Serial);
        BLINKER_DEBUG.debugAll();
        
        // 初始化有继电器的IO
        pinMode(Relay_1, OUTPUT);
        pinMode(Relay_2, OUTPUT);
        pinMode(Relay_3, OUTPUT);
        pinMode(Relay_4, OUTPUT);
        //初始化继电器初始状态
        digitalWrite(Relay_1, HIGH);       //继电器为低电平触发,初始化为HIGH
        digitalWrite(Relay_2, HIGH);
        digitalWrite(Relay_3, HIGH);
        digitalWrite(Relay_4, HIGH);
        //初始化本地按键状态
        pinMode(KG_1, INPUT_PULLUP);   //本地开关输入上拉
        pinMode(KG_2, INPUT_PULLUP);   //本地开关输入上拉
        pinMode(KG_3, INPUT_PULLUP);   //本地开关输入上拉
        pinMode(KG_4, INPUT_PULLUP);   //本地开关输入上拉
        
        //初始化blinker
       // Blinker.begin(auth);              //手机配网用这段
        Blinker.begin(auth, ssid, pswd);//代码配网用这段
        Button.attach(button_callback);   //绑定按键回调
        Button1.attach(button1_callback); //绑定按键回调
        Button2.attach(button2_callback); //绑定按键回调
        Button3.attach(button3_callback); //绑定按键回调
        Button4.attach(button4_callback); //绑定按键回调
        Button5.attach(button5_callback);
        
        //小爱同学注册回调
        BlinkerMIOT.attachPowerState(miotPowerState); //注册小爱电源回调
        BlinkerMIOT.attachQuery(miotQuery);           //小爱设备查询的回调函数
        
        //心跳包,初始化
        Blinker.attachHeartbeat(heartbeat);           //app定时向设备发送心跳包, 设备收到心跳包后会返回设备当前状态
    }
     
    void loop() 
    {
      bdms();           //本地开关模式
      Blinker.run();
    }
    

    设备接入联网后,手机APP操作界面

    在这里插入图片描述

    • 串口调试输出信息
      在这里插入图片描述
    展开全文
  • LabVIEW控制Arduino采集多路模拟量、数字量-单片机文档类资源 3、硬件环境 数据采集系统中的Arduino下位机部分采用Arduino Uno控制器,模拟量采用电位器分压来实现不同电压值,数字量采用拨动开关在5V和GND之间切换...

    目录

    1、项目概述

    2、项目架构

    3、硬件环境

    4、Arduino功能设计

    5、LabVIEW功能设计

    5.1、前面板设计

    5.2、程序框图设计


    1、项目概述

    数据采集,是指从传感器和其他待测设备的模拟和数字被测单元中自动采集信息的过程。能够实现数据采集功能的系统叫作数据采集系统。

    数据采集系统的任务,就是将传感器输出的信号转换成计算机能识别的信号并送入计算机进行处理,然后将处理得到的数据进行显示或打印,以便实现对某些物理量的监测,其中一些参数还会被计算机控制系统用于计算输出的控制量,以实现将某些物理量的控制在某一水平。

    Arduino控制器均具有模拟输入功能,Uno拥有6路模拟输入端口(A0到A5),每一路具有10位的分辨率(即输入有1024个不同值),默认输入信号范围为0到5V,并且可以通过AREF调整参考电压。

    2、项目架构

    采用Arduino Uno与LabVIEW来实现低成本上下位机数据采集系统,具有模拟量和数字量两种采集功能,可以满足低速、低成本的数据采集需求。其中,Arduino Uno作为下位机,负责A/D转换以及数据传输,LabVIEW编写的数据采集软件作为上位机,上下位机通过USB-TTL接口实现通信。如下图所示为多路数据采集系统框图。

    项目资源下载请参见:LabVIEW控制Arduino采集多路模拟量、数字量-单片机文档类资源

    3、硬件环境

    数据采集系统中的Arduino下位机部分采用Arduino Uno控制器,模拟量采用电位器分压来实现不同电压值,数字量采用拨动开关在5V和GND之间切换实现高电平与低电平。多路数据采集系统硬件连接如下图所示:

    ​4、Arduino功能设计

    Arduino下位机部分需要完成两个功能:数据采集和数据传输,Arduino Uno控制板通过USB-TTL电缆接收上位机发来的命令,完成相应的数据采集,并将采集的数据回传至LabVIEW上位机软件。

    数据采集分为模拟量采集和数字量采集两种,此处设置采集路数各为2路,分别采用Arduino Uno控制器上具有模拟量输入的管脚A0、A1和具有数字量输入的管脚2、3。

    Arduino Uno控制器负责读取LabVIEW上位机发来的采集命令,并采集相应的数据,通过串口发送回上位机LabVIEW软件。Arduino Uno控制器的程序代码如代码如下所示:

    #define A0_Command  0x10   //A0采集命令字
    #define A1_Command  0x11   //A1采集命令字
    #define D0_Command  0x20   //D0采集命令字
    #define D1_Command  0x21   //D1采集命令字
     
    byte comdata[3]={0};      //定义数组数据,存放串口接收数据
     
    int AD_Value=0;          //AD转换后的数字量
    float float_AD_Value;    //数字量换算成浮点电压量
    int D_Value=0;           //数字量测量的数据
     
    void receive_data(void);      //接受串口数据
    void test_do_data(void);         //测试串口数据是否正确,并更新数据
     
    void setup()
    {
      Serial.begin(9600);      
      pinMode(2, INPUT);
      pinMode(3, INPUT);
    }
    void loop()
    {
      while (Serial.available() > 0)   //不断检测串口是否有数据
       {
            receive_data();            //接受串口数据
            test_do_data();               //测试数据是否正确并更新标志位
       }
    }
    void receive_data(void)       
    {
       int i ;
       for(i=0;i<3;i++)
       {
          comdata[i] =Serial.read();
          //延时一会,让串口缓存准备好下一个字节,不延时可能会导致数据丢失,
           delay(2);
       }
    }
     
    void test_do_data(void)
    {
      if(comdata[0] == 0x55)            //0x55和0xAA均为判断是否为有效命令
       {
         if(comdata[1] == 0xAA)
         {
            switch(comdata[2])
              {   
                case A0_Command:   
                     AD_Value = analogRead(A0);                 //读取A0电压值
                     float_AD_Value=(float)AD_Value/1023*5.00;  //换算为浮点电压值
                     Serial.println(float_AD_Value,2);          //保留两位小数发送数据                       
                     break;
                case A1_Command:   
                     AD_Value = analogRead(A1);                 //读取A0电压值
                     float_AD_Value=(float)AD_Value/1023*5.00;  //换算为浮点电压值
                     Serial.println(float_AD_Value,2);          //保留两位小数发送数据                       
                     break;
                case D0_Command:   
                     D_Value = digitalRead(2);                  //读取D2数字量
                     Serial.println(D_Value);                  //发送数字量测量数据                    
                     break;
                case D1_Command:   
                     D_Value = digitalRead(3);                  //读取D2数字量
                     Serial.println(D_Value);                  //发送数字量测量数据                     
                     break;               
              }
           }
       }
    }

    5、LabVIEW功能设计

    LabVIEW上位机部分需要完成两个功能:向下位机发送命令帧和将数据显示在前面板上,Arduino Uno控制板通过串口接收上位机命令,完成相应的数据采集,并将数据回传至上位机。

    数据采集分为模拟量采集和数字量采集,设置采集路数各为2路,分别采用ArduinoUno上具有模拟量输入的管脚A0、A1和具有数字量输入的管脚2、3来实现。模拟量采用电位器分压来实现不同电压值,数字量采用拨动开关在5V和GND之间切换实现高电平与低电平。

    5.1、前面板设计

    LabVIEW前面板分为模拟量采集和数字量采集两个部分,模拟量采集部分主要针对模拟量输出的传感器,数字量采集部分主要针对数字量的输入。

    LabVIEW上位机前面板设计如下图所示:

    ​5.2、程序框图设计

    由于有2路模拟量和2路数字量,不同通道的模拟量或数字量的发送数据帧中,通道号不同,数字量与模拟量采集的发送数据帧中,命令号不同。发送数据帧中,具体的命令号和通道号可以自定义,此处模拟量通道0的采集命令为0x55AA10,模拟量通道1的采集命令为0x55AA11,数字量通道0的采集命令为0x55AA20,数字量通道1的采集命令为0x55AA21。

    LabVIEW上位机程序框图如下所示:

    Arduino Uno上的模拟输入拥有10位的分辨率,可以满足一般的数据采集的需求同时可以更改参考电压来提高最小分辨率。

    对于高精度的应用,需要外部扩展高分辨率的ADC(模数转换器)和高精度的电压基准源。

    对于连续数据采集的应用,可以采用LabVIEW Interface for Arduino函数库中的模拟采样库中的Get Finite Analog Sample函数节点来实现。

    对于远距离的数据采集的应用,可以采用RS-485总线、无线串口方式或网络方式实现。

    项目资源下载请参见:LabVIEW控制Arduino采集多路模拟量、数字量-单片机文档类资源

    展开全文
  • 1.下列元件中,开关电器有()。 A.组合开关 B.接触 C.行程开关 D.时间继电 2.下列元件中,主令电器有()。 A.熔断 B.按钮 C.刀开关 D.速度继电 3.熔断的作用是()。 A.控制行程 B.控制速度 C.短路...
  • 终于到了最关键的环节,也是最难的环节,如何求出开关级的传递函数? 也就是下图这一级。 哎,不得不说,太难了。。。 不过没办法,先前夸下海口,跟兄弟们说我要把环路搞清楚,现在搞不动也得搞啊。 ...
  • 多种延时电路

    2021-05-13 00:13:09
    关注+星标公众号,不错过精彩内容编排| strongerHuang微信公众号|嵌入式专栏众所周知,说到延时,很多人都会想到用软件件来实现,比如定时器之类的。今天就来说说用硬件来实现定...
  • 集成多路模拟开关的应用技巧

    万次阅读 2016-05-18 16:32:48
    集成多路模拟开关(以下简称多路开关)是自动数据采集、程控增益放大等重要技术领域的常用器件,其实际使用性能的优劣对系统的严谨和可靠性重要影响。 关于多路开关的应用技术,些文献上介绍有两点不足:一是对器件...
  • JZ18-4A 四轴联动可编程控制器, 集成了PLC 与运动控制器双重功能, 顺序执行 的编写方式,所见即所得,编程方便简易。本身控制器采用高性能 32 位 CPU,可四轴直 线插补和两轴圆弧插补,涵盖基本的运动控制及 PLC ...
  • 一款基于STC89C52单片机的手机WIFI控制4继电器的插座控制器设计。通过安装手机APP实现手机和设备的互联,只要手机发送相应的指令,继电器将会按照相关指令进行操作该设计极大的方便了人们对家用电器的使用,在现实...
  • 11.复杂需求可以采用RS485通信,电脑与控制器之间是一对的关系;通信距离最大可达1千米左右,每个控制器可以设定不同的地址,一台电脑最多可控制255个控制器;12.安装尺寸:本控制器采用一体化紧凑型设计,使用便利...
  • 对于好奇最近对于智能家居的控制买了个ESP8266套餐回来研究,用BLINKER实现4远程控制继电模块运行+温湿度感应。
  • 当输入端加电信号时发光发出光线,受光器接收光线之后就产生光电流,从输出端流出,从而实现了“电—光—电”控制。以光为媒介把输入端信号耦合到输出端的光电耦合,由于它具有体积小、寿命长、无触点,抗干扰...
  • 远程手机控制开关应用

    千次阅读 2019-04-08 09:31:37
    移动管家远程手机控制开关多路信号输入及多路控制输出接口,使用灵活方便! 手机控制电机启停,移动管家YD238-6,GSM远程手机控制设备开关:只要插入手机卡,接入电源(220V或380V、12V),无论何时何地通过手机...
  • 二、4【FPGA】简单的组合逻辑——设计多路选择
  • 手机APP物联网远程控制开关

    万次阅读 2020-09-10 21:17:29
    随着物联网技术应用到了楼宇自动化建设和工业现场控制之中,远程控制开关有着十分广阔的应用前景,因此物联网开关成为了智慧楼宇的核心组成部分。在工业4.0的推动下,这就要求普通的开关不仅只用于控制开关,还要对...
  • 科蒂斯 1230 控制器故障代码指示Led 灯 代码 故障原因Led 灯一直灭 没上电或者控制器损坏Led 灯一直亮 控制器或者芯片故障Led 灯 (0,1 ■ ¤) ...
  • Led灯代码故障原因Led灯一直火没上电或者控制器损坏Led灯一直亮控制器或者芯片故障Led灯(0,1■□)控制器正常工作,没有显示故障Led灯(1,2aaa)电机速度编码器或安全失效故障Led灯(1,3aaaa)电机过流或相线接错故障Led...
  • 这两款控制器同属高系列,功能强大,能满足多种场合的需求,支持直线插补、连续插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、位置锁存、同步跟随、虚拟轴设置、硬件比较输出、硬件定时器、运动中...
  • 华为CCA汽车域控制器

    2022-02-08 05:58:36
    华为CCA汽车域控制器 一、汽车E/E架构不断升级,华为CCA架构指引未来发展趋势。 1)ADAS功能升级导致算力需求提升。智能汽车时代,传统分布式ECU架构无法满足日益增长的算力需求,开始向“功能域”集中。 2)“软件...
  • 通过一段时间的arduino编程和ESP8266学习,参考示例程序等,完善了自己的一份小爱同学四开关控制的程序。 硬件部分:ESP8266 nodeMCU、4继电、4个按键开关、杜邦线若干 硬件介绍:4继电为低电平触发、4个...
  • 设备介绍 我们以普通电动开关阀为例,一般至少会有...因为在不同的工况下,对同一个阀门,要求的控制逻辑不尽相同,以我们从简单到复杂,来编写几个典型的范例。 案例1 简单粗暴型(适用于开关到位后能自行内部断...
  • Led灯代码故障原因Led灯一直灭没上电或者控制器损坏Led灯一直亮控制器或者芯片故障Led灯(0,1■¤)控制器正常工作,没有显示故障Led灯(1,2¤¤¤)电机速度编码器或安全失效故障Led灯(1,3¤¤¤¤)电机过流或相线接错...
  • 工作原理:我们控制的就是下面的那个开关,当下面的开关处于闭合状态时,带铁芯的线圈会输出对应的磁场,把衔铁吸附住,上面的电路就形成了闭合回路。具体工作原理详见此链接:继电工作原理3.接线:按照第三部分的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,832
精华内容 1,532
热门标签
关键字:

多路延时开关控制器