STM32采集风速仪+ESP8266显示OLED+阿里云上报

发布时间 2023-10-21 04:03:47作者: MKT-porter

 

 

 

 

 

ESP代码

#include <ESP8266WiFi.h>
 
static WiFiClient espClient;
#include <ArduinoJson.h>
 
#include <AliyunIoTSDK.h>
AliyunIoTSDK iot;
 
#define PRODUCT_KEY "hyyfW2KHpdG"
#define DEVICE_NAME "Node1"
#define DEVICE_SECRET "b8825507720f1566c5b0dc9b77bf8cf9"
#define REGION_ID "cn-shanghai"
 
#define WIFI_SSID "yaoyao"
#define WIFI_PASSWD "love123456"



#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);


//#include <SoftwareSerial.h>
//实例化软串口
//SoftwareSerial mySerial(D2, D1); // RX, TX
//分割结果
#define sleng 11 //数组大小
String split_result[sleng];//手动动态调整数组大小,保证数组可以满足容量

/*字符串分割
输入参数
String zifuchuan,  输入字符串
String fengefu,    分隔符号-可以是多个
String result[]    输出结果
     
*/
void Split(String zifuchuan,String fengefu,String result[])
 {
  int weizhi; //找查的位置
  String temps;//临时字符串
  int i=0;
  do
  {
      weizhi = zifuchuan.indexOf(fengefu);//找到位置
      if(weizhi != -1)//如果位置不为空
      {
          temps=zifuchuan.substring(0,weizhi);//打印取第一个字符
          zifuchuan = zifuchuan.substring(weizhi+fengefu.length(), zifuchuan.length());
          //分隔后只取后面一段内容 以方便后面找查
      }
      else
      {  //上面实在找不到了就把最后的 一个分割值赋值出来以免遗漏
         if(zifuchuan.length() > 0)
          temps=zifuchuan;
      }
     
      result[i++]=temps;
      //Serial.println(result[i-1]);//在这里执行分割出来的字符下面不然又清空了
      temps="";
   }
   while(weizhi >=0);
  }


void wifiInit(const char *ssid, const char *passphrase)
{
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, passphrase);
    WiFi.setAutoConnect (true);
    WiFi.setAutoReconnect (true);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.println("WiFi not Connect");
    }
    Serial.println("Connected to AP");
}
void powerCallback(JsonVariant p)
{
    int PowerSwitch = p["PowerSwitch"];
    if (PowerSwitch == 1)
    {
        //
    }
    else
    {
        //
    }
}

    /* 初始化 */
void setup() {
  
    
  Serial.begin(9600);
  while (!Serial) {
  }
     
  Serial.println("Goodnight moon!");
     
  //mySerial.begin(9600);

  wifiInit(WIFI_SSID, WIFI_PASSWD);
  AliyunIoTSDK::begin(espClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);
 
  // 绑定属性回调
  AliyunIoTSDK::bindData("PowerSwitch", powerCallback);

    
     // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }
  display.display();
  delay(500); // Pause for 2 seconds
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setRotation(0);

  
      
}


unsigned long lastMsMain = 0;
String wind_speed="0";
String wind_jibie="0";
String wind_alram="0";

String dgree_X="0";
String dgree_Y="0";
String dgree_Z="0";
String dgree_alram="0";
          
//  如果数据内容为字符串而非数字
/*
   SendMsg("wind_speed",wind_speed);
*/
void SendMsg_String(String s_send_id,String s_send_msg){

      char c_send_msg[s_send_msg.length()+1];
      char c_send_id[s_send_id.length()+1];
      s_send_msg.toCharArray(c_send_msg,s_send_msg.length()+1); 
      s_send_id.toCharArray(c_send_id,s_send_id.length()+1);             
      AliyunIoTSDK::send(c_send_id, c_send_msg);
  }



/* 主函数 */
void loop() {
  AliyunIoTSDK::loop();
      //接收串口消息mySerial
  if (Serial.available()){
      String split_input =Serial.readStringUntil(';');
      //Serial.println(split_input);
    
      //分割解析
      Split(split_input,"-",split_result);//分割调用
          
      Serial.println("--------new data--------");
      //打印消息 检查是否为空
       for(int i=0;i<sleng;i++)
          {
            if(split_result[i]!="")
            {
             //Serial.println(String(i)+"-"+split_result[i]);
            }
            else
            {
              split_result[i]="0";
             }
          }

           wind_speed=split_result[0];
           wind_jibie=split_result[1];
           wind_alram=split_result[7];

           dgree_X=split_result[3];
           dgree_Y=split_result[5];
           dgree_Z=split_result[6];
           dgree_alram=split_result[8];

          display.clearDisplay();
          display.setCursor(0, 0);
        
          display.print("wind speed:");
          display.println(split_result[0]);
          
          display.print("wind level:");
          display.println(split_result[1]);

            
          display.print("wind waring:");
          display.println(split_result[7]);
          
          display.print("angle x:");
          display.println(split_result[3]);
          display.print("angle y:");
          display.println(split_result[5]);
          display.print("angle z:");
          display.println(split_result[6]);

          
          display.print("angle waring:");
          display.println(split_result[8]);
          
          display.display();
          delay(100);


          
           String msg=String("")+"{"
                     +"\"wind_speed\":"+String(split_result[0])+","
                     +"\"wind_jibie\":"+String(split_result[1])+","
                     +"\"wind_alram\":"+String(split_result[7])+","
                     
                     +"\"dgree_X\":"+String(split_result[3])+","
                     +"\"dgree_Y\":"+String(split_result[5])+","
                     +"\"dgree_Z\":"+String(split_result[6])+","
                     +"\"dgree_alram\":"+String(split_result[8])
                     +"}";
           Serial.println(msg); 

        
  }


       if (millis() - lastMsMain >= 3000){
            lastMsMain = millis();
         
            AliyunIoTSDK::send("wind_speed", wind_speed.toFloat());
            AliyunIoTSDK::send("wind_jibie", int(wind_jibie.toInt()));
            AliyunIoTSDK::send("wind_alram", int(wind_alram.toInt()));

            AliyunIoTSDK::send("dgree_X", dgree_X.toFloat());
            AliyunIoTSDK::send("dgree_Y", dgree_Y.toFloat());
            AliyunIoTSDK::send("dgree_Z", dgree_Z.toFloat());
            AliyunIoTSDK::send("dgree_alram", int(dgree_alram.toInt()));
            //  SendMsg("报警状态","报警信息");
            
       }



     
}

  

 

STM32

 

 

#include <Adafruit_MPU6050.h>
//#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
 
 

 
 
int PIN_LEDR = PA12;
int PIN_LEDG = PB5;

int PIN_alram = PB8;
 
 
Adafruit_MPU6050 mpu;
//Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

bool buttonState = 0;


float dx_list[10]={0,0,0,0,0,0,0,0,0,0};
float dy_list[10]={0,0,0,0,0,0,0,0,0,0};
float dz_list[10]={0,0,0,0,0,0,0,0,0,0};
int idex=0;

#define ESP_Serial3 Serial3
#define mySerial Serial2
// 查询一次
byte  Msg_getdata[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xC4,0x0B};
char RecData[9]={0};

// 风速 m/s
float fengsu[1]={0.0};
// 风速等级
int dnegji[1]={0};

            
//==============校验==============
uint16_t modbus_crc16( char *data, uint8_t length) {
  uint16_t crc = 0xFFFF;  
  for (uint8_t i = 0; i < length; i++) {
    crc ^= data[i];
    for (uint8_t j = 8; j > 0; j--) 
    {
      if (crc & 0x0001) 
      {
        crc = (crc >> 1) ^ 0xA001;
      } else 
      {
        crc >>= 1;
      }
    }
  }
  return crc;
}

// CRC16 校验
//  char senddata[6] = {0x30,0x31,0x00,0x00,0x00,0x02};
//  数据   数据长度(不包含校验码本身)
//  uint16_t crc = modbus_crc16(senddata, sizeof(senddata));
//
//  //CRC16: 0xB, 0xC4
//  uint16_t crc_H= (crc & 0xFF00) >> 8;
//  uint16_t crc_L= (crc & 0x00FF);
//  
//  Serial.print("CRC16: 0x");
//  Serial.print(crc_H, HEX);
//  Serial.print(", 0x");
//  Serial.println(crc_L, HEX);
/*
0~9  48~57 30~39H
A~Z 65~90 41~5AH
a~z 97~122  61~7AH
空格  32  20H
*/



void ReadSpeed(float *fengsu, int *dnegji){
  
   mySerial.write(Msg_getdata,sizeof(Msg_getdata)) ;
     
   while(1){
    
      if(mySerial.available()>0)//判断串口是否有数据可读
      {
        delay(50);
        for(int i=0;i<9;i++)
        {
           RecData[i]=mySerial.read();
           //Serial.print(i);  Serial.print(" - ");Serial.println(RecData[i]);
        }
       

          // 地址 功能码 数据长度 风速寄存器0高 风速寄存器0低 风级寄存器1高 风级寄存器1低 CRC16低校验码 CRC16高校验码 
          // 01 03 00 00 24 00 03 FA 39 
          uint16_t crc = modbus_crc16(RecData, sizeof(RecData)-2);// 最后两位是校验码
        
          //CRC16: 0xB, 0xC4
          uint16_t crc_H= (crc & 0xFF00) >> 8;
          uint16_t crc_L= (crc & 0x00FF);

          uint16_t crc_L_rec=RecData[7];
          uint16_t crc_H_rec=RecData[8];
          
          if(crc_L_rec=crc_L && crc_H_rec==crc_H)
          {
           
             fengsu[0]=(RecData[4])/10.0;
             dnegji[0] =(RecData[6]);
  
            //String showms=" 风速: " + String(fengsu)+"m/s 等级:"+String(dnegji);
            
            //Serial.println(showms);
            break;
          }
          else{

            fengsu[0]=0.1;
            dnegji[0]=0;
            
            Serial.println("校验失败......");            
            Serial.print("接收的CRC16: 0x");
            Serial.print(crc_L, HEX);
            Serial.print(", 0x");
            Serial.print(crc_H, HEX);


            Serial.print("  计算的CRC16: ");
            Serial.print(crc_L_rec, HEX);
            Serial.print(", 0x");
            Serial.println(crc_H_rec, HEX);
            break;
            }
      }

    
      delay(20);

   }

  
  }


float MPU_x_y_z[3]={0};
void ReadMPU(float *MPU_x_y_z_){
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
    float d_x= acos(a.acceleration.x/9.8)/3.14*180-90;
  float d_y= acos(a.acceleration.y/9.8)/3.14*180-90;
  float d_z= acos(a.acceleration.z/9.8)/3.14*180;

  if (idex<10){
    dx_list[idex]=d_x;
    dy_list[idex]=d_y;
    dz_list[idex]=d_z;
    idex=idex+1;
    
  }
  else{
    idex=0;
    dx_list[idex]=d_x;
    dy_list[idex]=d_y;
    dz_list[idex]=d_z;
    idex=idex+1;
    }


  float d_x_j=0;
  float d_y_j=0;
  float d_z_j=0;

    for(int i=0;i<10;i++)
    {
      d_x_j=d_x_j+dx_list[i];
      d_y_j=d_y_j+dy_list[i];
      d_z_j=d_z_j+dz_list[i];
      
    }

      d_x_j=d_x_j/10.0;
      d_y_j=d_y_j/10.0;
      d_z_j=d_z_j/10.0;

      MPU_x_y_z_[0]=d_x_j;
       MPU_x_y_z_[1]=d_y_j;
        MPU_x_y_z_[2]=d_z_j;
   
}
void setup()
{
  Serial.begin(9600);
  mySerial.begin(4800);
  ESP_Serial3.begin(9600);

  
  pinMode(PIN_LEDR, OUTPUT);
  pinMode(PIN_LEDG, OUTPUT);
  
  digitalWrite(PIN_LEDR, LOW);
  digitalWrite(PIN_LEDG, LOW);
     
  pinMode(PIN_alram, OUTPUT);
  digitalWrite(PIN_alram, HIGH);

   
  if (!mpu.begin()) {
    Serial.println("Sensor init failed");
    while (1)
      yield();
  }
//  Serial.println("Found a MPU-6050 sensor");
//   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
//  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
//    Serial.println(F("SSD1306 allocation failed"));
//    for (;;)
//      ; // Don't proceed, loop forever
//  }
//  display.display();
//  delay(500); // Pause for 2 seconds
// display.setTextSize(1);
// display.setTextColor(WHITE);
// display.setRotation(0);

 
}

bool alram_speed_dgree[2]={0};
unsigned long currentMicros = 0;
unsigned long previousMicros = 0;

 
void loop()
{

   delay(100);
   
   ReadSpeed(fengsu,dnegji);

 
   ReadMPU(MPU_x_y_z);
  

   currentMicros = micros();

  if (currentMicros - previousMicros >= 3000*1000) {
     previousMicros = currentMicros;


     String showms=" 风速: " + String(fengsu[0])+"m/s 等级:"+String(dnegji[0]);
     Serial.println(showms);
  
     if(dnegji[0]>=3){
        alram_speed_dgree[0]=1;
        Serial.println("风速过大报警");
      }
     else{
        alram_speed_dgree[0]=0;
        Serial.println("风速正常");
      }

     String showms_mpu=" 角度x: " + String(MPU_x_y_z[0])+"  y:"+String(MPU_x_y_z[1])+"  z:"+String(MPU_x_y_z[2]);
     Serial.println(showms_mpu);
  
     if(abs(MPU_x_y_z[0])>=65 || abs(MPU_x_y_z[1])>=65){
        alram_speed_dgree[1]=1;
        Serial.println("倾斜角过大报警");
      }
     else{
        alram_speed_dgree[1]=0;
        Serial.println("倾斜角正常");
      }

      if (alram_speed_dgree[0]==1 || alram_speed_dgree[1]==1 ) {
          digitalWrite(PIN_LEDR, LOW);
          digitalWrite(PIN_LEDG, HIGH);
          digitalWrite(PIN_alram, LOW);
           
      } else {
          digitalWrite(PIN_LEDR, HIGH);
          digitalWrite(PIN_LEDG, LOW);
          digitalWrite(PIN_alram, HIGH);
      }
String(fengsu[0])+"m/s 等级:"+String(dnegji[0]);

    String msg_esp=String()
                    + String(fengsu[0])+"-"
                    + String(dnegji[0])+"-"
                    + String(MPU_x_y_z[0])+"-"
                    + String(MPU_x_y_z[1])+"-"
                    + String(MPU_x_y_z[2])+"-"
                    + String(alram_speed_dgree[0])+"-"
                    + String(alram_speed_dgree[1])+"-"
                    +";";
    ESP_Serial3.print(msg_esp);
  }
  
   



//    display.clearDisplay();
//    display.setCursor(0, 0);
//  
//    display.print("speed:");
//    display.println(fengsu[0], 1);
//    
//    display.print("level:");
//    display.println(dnegji[0], 1);
//      
//    display.print("x:");
//    display.println(MPU_x_y_z[0], 1);
//    display.print("y:");
//    display.println(MPU_x_y_z[1], 1);
//    display.print("z:");
//    display.println(MPU_x_y_z[2], 1);
//    
//    display.display();
//    delay(100);
  
}