Arduino 製作基於OneNET平臺的繼電器控制(EDP協議)(二)

所需硬件

  • Arduino UNO
  • ESP8266-01S
  • 繼電器模塊

準備工作

首先在製作前,我們先通過Arduino IDE 燒錄一下ESP8266的程序,具體燒錄步驟在 https://blog.csdn.net/m0_37738838/article/details/83999561 中可以查看,有部分地方需要修改的
IP地址和端口號修改成OneNET EDP協議的IP地址和端口

IP: jjfaedp.hedevice.com
PORT: 876

燒錄完成後,看一下我們在程序中設置連接的WIFI是否連上,如果已連接上就沒問題。

接線

ESP8266 Arduino UNO
TX RX
RX TX
VCC 3.3V
GND GND
CH_PD 3.3V
繼電器 Arduino UNO
信號腳 D9
VCC 5V
GND GND

在這裏插入圖片描述

程序

edp.c程序下載鏈接: https://download.csdn.net/download/m0_37738838/10912961

演示效果

https://v.youku.com/v_show/id_XNDA3MjU4MDI3Mg==.html?spm=a2h3j.8428770.3416059.1

流程說明

#include <Wire.h>
#include<Arduino.h>
#include<math.h>
#include<SoftwareSerial.h>
#include"edp.c"
#include <Metro.h> 

#define JDQ 7 //設置繼電器模塊輸出引腳爲9號引腳

#define KEY  "2lSvvpOO4UBjuMwdQSN7jVVe36A="    //APIkey
#define ID   "513758691"                          //設備ID  fish_pond
#define PUSH_ID NULL
#define tem  "TEM"

//串口
#define _baudrate 115200 //波特率
#define _rxpin 2 
#define _txpin 3
#define WIFI_UART dbgSerial //數據傳送串口
#define DBG_UART Serial //調試打印串口
static int time_=3000;
Metro Write_metro = Metro(time_); 
SoftwareSerial dbgSerial( _rxpin, _txpin ); // 軟串口,調試打印
edp_pkt *pkt;
static int edp_connect = 0; //連接標識
bool read_package = true; //連接標識
void setup()
{
  char buf[100] = {0};
  int tmp;
  
  Serial.begin(9600);//設置通訊波特率爲9600
  pinMode(JDQ,OUTPUT); //繼電器
  
  WIFI_UART.begin( _baudrate );
  DBG_UART.begin( 9600 );
  WIFI_UART.setTimeout(3000);    //設置find超時時間
  delay(3000);
  DBG_UART.println("Hello World!");
  delay(2000);
}

void loop()
{
  bool trigger = false;
  edp_pkt rcv_pkt;
  unsigned char pkt_type;
  int i, tmp;
   /*EDP連接*/
  if (!edp_connect) {
    while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收緩存
    packetSend(packetConnect(ID, KEY)); //發送EDP連接包
    while (!WIFI_UART.available()); //等待EDP連接應答
    /*
    WIFI_UART.readBytes(buffer, length)從串口讀字符到一個緩衝區       
    buffer:用來存儲字節(char[]或byte[])的緩衝區
    length:讀取的字節數(int)
    */
    if ((tmp = WIFI_UART.readBytes(rcv_pkt.data, sizeof(rcv_pkt.data))) > 0) {  
      rcvDebug(rcv_pkt.data, tmp);//打印onenet下發的數據包
      if (rcv_pkt.data[0] == 0x20 && rcv_pkt.data[2] == 0x00 && rcv_pkt.data[3] == 0x00) {//onenet判斷下發的數據包是爲0x20 0x02 0x00 0x00 
        edp_connect = 1;
        DBG_UART.println("EDP connected.");//連接成功
      }
      else
        DBG_UART.println("EDP again connected."); //重新連接   
    }
    packetClear(&rcv_pkt);//數據包清理 初始化內存
 }
  
  read_package=true;

//解析平臺下發數據,這裏只關心edp控制命令
  while (WIFI_UART.available())
  {
   
    readEdpPkt(&rcv_pkt);
    if (isEdpPkt(&rcv_pkt))//判斷是否爲完整edp包
    {
      if(rcv_pkt.data[0] == 0x40){//斷開連接後,edp_connect歸零,重新連接
        edp_connect = 0;
        DBG_UART.println("waahaha");
      }
      read_package=false;
      pkt_type = rcv_pkt.data[0];
      switch (pkt_type)
      {
        case CMDREQ:
          char edp_command[50];
          char edp_cmd_id[40];
          long id_len, cmd_len, rm_len;
          memset(edp_command, 0, sizeof(edp_command));//EDP命令接收緩存數組
          memset(edp_cmd_id, 0, sizeof(edp_cmd_id));//EDP命令ID接收緩存數組
          edpCommandReqParse(&rcv_pkt,edp_cmd_id,edp_command,&rm_len,&id_len,&cmd_len);//解析edp命令
          DBG_UART.print("rm_len: ");
          DBG_UART.println(rm_len, DEC);
          delay(10);
          DBG_UART.print("id_len: ");
          DBG_UART.println(id_len, DEC);
          delay(10);
          DBG_UART.print("cmd_len: ");
          DBG_UART.println(cmd_len, DEC);
          delay(10);
          DBG_UART.print("id: ");
          DBG_UART.println(edp_cmd_id);
          delay(10);
          DBG_UART.print("cmd: ");
          DBG_UART.println(edp_command);
          delay(50);       
          if (atoi(edp_command) == 1)   //LED開關
          {
            digitalWrite(JDQ, LOW);
          }
          if (atoi(edp_command) == 0){
            digitalWrite(JDQ, HIGH);  
          }
           
          break;
        default:
          DBG_UART.print("unknown type: ");
          DBG_UART.println(pkt_type, HEX);
          break;
      }
    }
  }
 /*
  if(edp_connect==1){//判斷是否連接
    if(Write_metro.check()&&read_package)
    packetSend(packetDataSaveTrans(ID, tem,"25")); //將溫度的數據打包發送至onenet平臺
 }*/
 
  if (rcv_pkt.len > 0)
    packetClear(&rcv_pkt);
    delay(150);
}


/*
 * readEdpPkt
 * 從串口緩存中讀數據到接收緩存
 */
bool readEdpPkt(edp_pkt *p)
{
  int tmp;
  if ((tmp = WIFI_UART.readBytes(p->data + p->len, sizeof(p->data))) > 0 )
  {
    rcvDebug(p->data + p->len, tmp);
    p->len += tmp;
  }
  return true;
}
/*
   packetSend
   將待發數據發送至串口,並釋放到動態分配的內存
*/
void packetSend(edp_pkt* pkt)
{
  if (pkt != NULL)
  {
    WIFI_UART.write(pkt->data, pkt->len);    //串口發送
    WIFI_UART.flush();
    free(pkt);              //回收內存
  }
}

void rcvDebug(unsigned char *rcv, int len)
{
  int i;
  DBG_UART.print("rcv len: ");
  DBG_UART.println(len, DEC);
  for (i = 0; i < len; i++)
  {
    DBG_UART.print(rcv[i], HEX);
    DBG_UART.print(" ");
  }
  DBG_UART.println("");
}

在這裏插入圖片描述

重新連接

在這裏插入圖片描述

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章