Demo entry 6623899

no

   

Submitted by anonymous on Jun 11, 2017 at 19:02
Language: C. Code size: 8.5 kB.

#include <aJSON.h>
//=============  此处必须修改============
String DEVICEID = "2287"; // 你的设备ID=======
String APIKEY = "4d666f8f4"; // 设备密码==
String INPUTID = "2194"; //接口ID1==============
String INPUTID2 = "2245"; //接口ID2==============
String INPUTID3 = "2246"; //接口ID3==============
String INPUTID4 = "2247"; //接口ID4==============
//=======================================
unsigned long lastCheckInTime = 0; //记录上次报到时间
unsigned long lastUpdateTime = 0;//记录上次上传数据时间
const unsigned long postingInterval = 40000; // 每隔40秒向服务器报到一次
const unsigned long updateInterval = 5000; // 数据上传间隔时间5秒
String inputString = "";//串口读取到的内容
boolean stringComplete = false;//串口是否读取完毕
boolean CONNECT = true; //连接状态
boolean isCheckIn = false; //是否已经登录服务器
char* parseJson(char *jsonString);//定义aJson字符串

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 16, 2);
unsigned int PM1 = 0;
unsigned int PM2 = 0;
unsigned int PM10 = 0;
unsigned int HOCO = 0;
unsigned char gState_1 = 0;//通信模块
unsigned char RecieveData_1[50] = {0x00};//接收缓存
unsigned short Lib_1 = 0;//接收指针
unsigned char SerialBusy_1 = 0; //串口处理忙标志
unsigned char OperationFlag_1 = 0; //一帧数据串口接收完标志
unsigned char checkingflag = 0;
void setup()
{
  Serial.begin(9600);//串口0用来打印调试记录
  Serial1.begin(115200);//串口1 用来和ESP8266通信
  lcd.begin();//初始化液晶
  lcd.backlight();//初始化液晶背光灯
  Serial2.begin(9600);//串口2用来和气体传感器通信
  delay(2000);
}
void loop()
{
  //if (millis() - lastCheckInTime > postingInterval ) {
  //Serial.println("begin check in");
  //checkIn();
  //}
  if ((millis() - lastUpdateTime > updateInterval)) {//如果间隔时间超过5000毫秒
    update4(DEVICEID, INPUTID, HOCO, INPUTID2, PM2, INPUTID3, PM10, INPUTID4, PM1);//则开始向服务器上传数据
    checkingflag++;
    if (checkingflag > 8)//8*5秒=40秒,40秒向服务器报道一次
    {
      checkingflag = 0;
      Serial.println("begin check in");
      checkIn();//向服务器报道
    }
  }
  serialEvent1();//执行一次串口1中断服务程序
  if (stringComplete) {//ESP8266模块向单片机串口1发送了一帧完整的数据,解析它,在我们的程序应用中,服务器并不需要向下发送指令,这段函数主要用来解析服务器向单片机发送的指令
    inputString.trim();
    //Serial.println(inputString);
    if (inputString == "CLOSED") {
      Serial1.println("connect closed!");
      CONNECT = false;
      isCheckIn = false;
    } else {
      int len = inputString.length() + 1;
      if (inputString.startsWith("{") && inputString.endsWith("}")) {
        char jsonString[len];
        inputString.toCharArray(jsonString, len);
        aJsonObject *msg = aJson.parse(jsonString);
        processMessage(msg);//处理接收到的Json数据
        aJson.deleteItem(msg);
      }
    }
    inputString = "";
    stringComplete = false;
  }
  if (OperationFlag_1)//解析通信模块的指令
  {
    unsigned int sumcheck = 0;
    unsigned char sumcheckHigh = 0x00;
    unsigned char suncheckLow = 0x00;
    sumcheck = SUMCheck(RecieveData_1, 38);//计算求和值
    sumcheckHigh = sumcheck >> 8;
    suncheckLow = sumcheck;
    if (RecieveData_1[38] == sumcheckHigh && RecieveData_1[39] == suncheckLow)//看是否校验成功
    {
      PM1 = RecieveData_1[4] * 256 + RecieveData_1[5];//根据使用说明书中的通信协议,计算出PM1、PM2.5、PM10、甲醛的浓度
      PM2 = RecieveData_1[6] * 256 + RecieveData_1[7];
      PM10 = RecieveData_1[8] * 256 + RecieveData_1[9];
      HOCO = RecieveData_1[28] * 256 + RecieveData_1[29];
      FormatDisplay(PM1, PM2, PM10, HOCO);
    }
    //一帧数据解析完毕后,进行清空缓冲区
    OperationFlag_1 = 0;
    SerialBusy_1 = 0;
    gState_1 = 0;
    Lib_1 = 0;
    for (unsigned short i = 0; i < 50; i++)
    {
      RecieveData_1[i] = 0;
    }
  }


}
void FormatDisplay(unsigned int pm1, unsigned int pm2, unsigned int pm10, unsigned int hoco)//格式化显示4个参数,如果不格式化显示的话,就容易引起一些预料不到的错误
{
  lcd.setCursor(0, 0);
  lcd.print("1=");
  if (pm1 < 10)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(pm1);
  }
  else if (pm1 < 100)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(pm1);
  }
  else if (pm1 < 1000)
  {
    lcd.print(' ');
    lcd.print(pm1);
  }
  else
  {
    lcd.print(pm1);
  }
  lcd.setCursor(10, 0);
  lcd.print("2=");
  if (pm2 < 10)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(pm2);
  }
  else if (pm2 < 100)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(pm2);
  }
  else if (pm2 < 1000)
  {
    lcd.print(' ');
    lcd.print(pm2);
  }
  else
  {
    lcd.print(pm2);
  }
  lcd.setCursor(0, 1);
  lcd.print("3=");
  if (pm10 < 10)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(pm10);
  }
  else if (pm10 < 100)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(pm10);
  }
  else if (pm10 < 1000)
  {
    lcd.print(' ');
    lcd.print(pm10);
  }
  else
  {
    lcd.print(pm10);
  }
  lcd.setCursor(10, 1);
  lcd.print("4=");
  if (hoco < 10)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(hoco);
  }
  else if (hoco < 100)
  {
    lcd.print(' ');
    lcd.print(' ');
    lcd.print(hoco);
  }
  else if (hoco < 1000)
  {
    lcd.print(' ');
    lcd.print(hoco);
  }
  else
  {
    lcd.print(hoco);
  }
}
void serialEvent2()
{
  unsigned char inChar = Serial2.read();
  if (SerialBusy_1)
  {
    return ;
  }
  switch (gState_1)
  {
    case 0x00:
      {
        if (inChar == 0x42)
        {
          gState_1 = 0x01;
          Lib_1 = 0;
          RecieveData_1[0] = inChar;
        }
        else
        {
          Lib_1 = 0;
          gState_1 = 0x00;
        }
        break;
      }
    case 0x01:
      {
        if (inChar == 0x4D)
        {
          RecieveData_1[1] = inChar;
          gState_1 = 0x02;
          Lib_1 = 1;
        }
        else
        {
          Lib_1 = 0;
          gState_1 = 0x00;
        }
        break;
      }
    case 0x02:
      {
        RecieveData_1[++Lib_1] = inChar;
        if (Lib_1 > 38)
        {
          SerialBusy_1 = 1;
          OperationFlag_1 = 1;
        }
      }
  }
}

unsigned int SUMCheck(unsigned char *message, unsigned short len)//该函数计算求和,形参*message是数组首地址,形参len是数组长度,计算传递过来的数组值的和
{
  unsigned int temp = 0x00;
  for (unsigned short i = 0; i < len; i++)
  {
    temp += (*(message + i));
  }
  return temp;
}
void checkIn()//该函数主要的目的就是向服务器按时报道,如果不能按时向服务器报道,服务器就会认为设备离线,所以要固定时间间隔向服务器上报一次 
{
  if (!CONNECT) {//如果认为设备没有连接网络,则发AT指令,让ESP8266复位
    Serial1.print("+++");
    delay(500);
    Serial1.print("\r\n");
    delay(1000);
    Serial1.print("AT+RST\r\n");
    delay(6000);
    CONNECT = true;
    //lastCheckInTime == 0;
    Serial.println("check in fail");
  }
  else {//如果认为设备连接了网络,则向服务器发送贝壳网规定的协议
    Serial1.print("{\"M\":\"checkin\",\"ID\":\"");
    Serial1.print(DEVICEID);
    Serial1.print("\",\"K\":\"");
    Serial1.print(APIKEY);
    Serial1.print("\"}\r\n");
    Serial.println("check in success");
  }
  lastCheckInTime = millis();
}
void processMessage(aJsonObject *msg) {
  aJsonObject* method = aJson.getObjectItem(msg, "M");
  aJsonObject* content = aJson.getObjectItem(msg, "C");
  aJsonObject* client_id = aJson.getObjectItem(msg, "ID");
  //char* st = aJson.print(msg);
  if (!method) {
    return;
  }
  //Serial.println(st);
  //free(st);
  String M = method->valuestring;
  if (M == "checkinok") {
    isCheckIn = true;
  }
}
void update1(String did, String inputid, float value) {//向服务更新一个数据接口的数据
  Serial1.print("{\"M\":\"update\",\"ID\":\"");
  Serial1.print(did);
  Serial1.print("\",\"V\":{\"");
  Serial1.print(inputid);
  Serial1.print("\":\"");
  Serial1.print(value);
  Serial1.println("\"}}");
  //lastCheckInTime = millis();
  lastUpdateTime = millis();
  Serial.println("begin upload");
}
void serialEvent1() {//串口1中断服务函数,ESP8266接到硬件串口1上了,所以调用这个串口中断
  while (Serial1.available()) {
    char inChar = (char)Serial1.read();
    Serial.print(inChar);
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}
//同时上传4个接口数据调用此函数
void update4(String did, String inputid1, float value1, String inputid2, float value2, String inputid3, float value3, String inputid4, float value4) {
  Serial1.print("{\"M\":\"update\",\"ID\":\"");
  Serial1.print(did);
  Serial1.print("\",\"V\":{\"");
  Serial1.print(inputid1);
  Serial1.print("\":\"");
  Serial1.print(value1);
  Serial1.print("\",\"");
  Serial1.print(inputid2);
  Serial1.print("\":\"");
  Serial1.print(value2);
  Serial1.print("\",\"");
  Serial1.print(inputid3);
  Serial1.print("\":\"");
  Serial1.print(value3);
  Serial1.print("\",\"");
  Serial1.print(inputid4);
  Serial1.print("\":\"");
  Serial1.print(value4);
  Serial1.println("\"}}");
  lastCheckInTime = millis();
  lastUpdateTime = millis();
  Serial.println("begin upload");
}

This snippet took 0.02 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).