资讯详情

基于机智云平台的温湿度和光照强度获取

本设计采用esp8266烧写机智云固件。esp8266与stm32通信,然后stm32可以通过esp8266与机智云服务器进行数据交互,而机智云服务器可以与机智云进行数据交互app因此,数据交互stm32通过esp8266可以和机智云一起使用app数据交互。stm32作为MCU与传感器进行数据交互,得到传感器采集的数值,所以完成的是传感器和app数据交互。由于本实验增加了光强采集,因此增加了三色RGB灯外设。通过机智云app可以调节RGB为了模拟光强的变化。如下图所示: 在这里插入图片描述 另外,用机智云app调节RGB光强的数据流如下图所示:

一、传感器测试

设计利用STM32CubeMX开发、代码设计过程分为模块,编写测试用例验证各模块的功能,包括oled模块,按键模块,dht光敏电阻模块11模块,rgb模块。 1、oled模块 ①接线:

Stm32 oled
3.3V VCC
GND GND
PB13 D0
PB15 D1
PB4 RES
PB3 DC
GND CS

②代码编写: 本次设计中oled采用硬件SPI2驱动,STM32CubeMX如下图所示: 利用STM32CubeMX生成的SPI主要代码如上所示。SPI进一步编写代码oled.c和oled.h文件。 oled.c包装以下函数: 测试函数:

int main(void) { 
             HAL_Init();     SystemClock_Config();     MX_GPIO_Init();     MX_SPI2_Init();     OLED_Init();     OLED_ShowString(0, 0, "wait for set esp8266,press key1 to set esp8266 with AIRLINK_MODE"); } 

③试验用例实验结果: 从上图可以看出,oled能正确显示模块的显示函数。 2、按键模块 ①接线: KEY_R0接地,KEY_L0和KEY_L可用于检测按键状态。 相应的引脚为:

KEY_R0 PC11(用单片机输出低电平)
KEY_L0 PC10
KEY_L1 PB5

②代码编写: STM32CubeMX设计如下: PC11设置为输出模式,PC10和PB5设置为输入模式。 Key.c包装以下函数:

void key_init(void) { 
            HAL_GPIO_WritePin(KEY_COM_GND_GPIO_Port, KEY_COM_GND_Pin, GPIO_PIN_RESET); }  void Test_key(void) { 
            if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_SET { 
          OLED_ShowString(0,0,"key1_up"); } else { 
          OLED_ShowString(0,0,"key1_down"); } if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin)==GPIO_PIN_SET) { 
          OLED_ShowString(0,10,"key2_up"); } else { 
          OLED_ShowString(0,10,"key2_down"); } OLED_Refresh_Gram(); } 

测试用例:

int main(void)
{ 
        
   MX_GPIO_Init();
   key_init();
   while(1)
   { 
        
      Test_key();
   }
}

③测试用例实验结果: 由图中可以看出,按键一被按下时显示key1_down和key2_up,与理论相符。 3、dht11模块 ①接线:

Stm32 Dht11
3.3V VCC
GND GND
PB0 DAT

②代码编写: 由于dht11的数据引脚有时需要作为输入,有时需要作为输出,所以不在STM32CubeMX设置。 Dht11.c主要封装了以下函数: 这里的us延时并没有使用定时器来产生,而是用系统时钟来实现:

void delay_us(uint32_t us)
{ 
        
    uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
    while (delay--)
   { 
        
      ;
   }
}

测试用例:

int main(void)
{ 
        
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_SPI2_Init();
  OLED_Init();
  while(1)
  { 
        
      Test_dht11();
   }

void Test_dht11(void)
{ 
        
   char txt[16];
   while(1)
   { 
        
      DHT11_Read_Data(&humidity_integer,&humidity_decimal,&temperature_integer,&temperature_decimal);
      sprintf(txt, "temp:%d.%d", temperature_integer,temperature_decimal);
      OLED_ShowString(0,0,txt);
      sprintf(txt, "humi:%d.%d", humidity_integer,humidity_decimal);
      OLED_ShowString(0,10,txt);
      OLED_Refresh_Gram();
   }
}

③测试用例实验结果: 由上图可以看出,温度为23.3℃,湿度为53.0%,湿度的小数为0,与理论相符。 4、光敏电阻模块 ①接线:

Stm32 5506
3.3V VCC
GND GND
PA0 AO

②代码编写: STM32CubeMX设置ADC1的IN0如下: Stm32Rct6的ADC是12位的,这里没有更改的选项,则ADC读取的最大值是2^12=4096。 这里采样时间Sampling Time选择1.5个周期。ADC采样时间 = (采样周期+12.5周期)* 1/ADC时钟频率,这里ADC采样时间=(1.5+12.5)*1/12 = 1.167us。 light_check5506.c主要封装以下函数:

void light_check5506_init(void)
{ 
        
   HAL_ADCEx_Calibration_Start(&hadc1);
   HAL_Delay(200);
}

uint32_t light_check5506_getinitvalue(void)
{ 
        
   HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1,50);//ÏÞʱ50ms
   return HAL_ADC_GetValue(&hadc1);
}

uint32_t light_check5506_get0to100value(void)
{ 
        
   //°µ-->ÁÁ£º0~100
   uint32_t value;
   value=light_check5506_getinitvalue();
   value=4096-value;//ÔʼÊý¾ÝÊÇÔ½°µÊý¾ÝÔ½´ó
   value=(value*100/4096);//»¯Îª0~100µÄÊý,±ØÐëÏȳËÒÔ100ÔÙ³ý£¬ÒòΪȫ²¿ÊÇÕûÊý
   return value;
}

void Test_5506(void)
{ 
        
   uint32_t value;
   char txt[16];
   while(1)
   { 
        
      value=light_check5506_get0to100value();
      sprintf(txt, "light(0-100):%d", value);  
      OLED_ShowString(0,0,txt);
      OLED_Refresh_Gram();
   }
}

测试用例:

main(void)
{ 
        
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_SPI2_Init();
    MX_ADC1_Init();
    OLED_Init();
    light_check5506_init();
    while(1)`
    { 
        
        Test_5506();
    }
}

③测试用例实验结果: 将ADC读取的值归一化到0~100后光照强度的数值为18。 5、rgb模块 ①接线:

Stm32 rgb
GND GND
PC6 R
PC7 G
PC8 B

②代码编写: STM32CubeMX设置TIM8的三个通道如下: 计数周期Counter Period设置为255,这是为了便于查找RGB颜色表进行颜色设置,占空比Pulse设置为50% Rgb.c封装了以下函数:

void rgb_init(void)
{ 
        
   HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
   HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_2);
   HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
}
void Test_rgb(void)
{ 
        
    rgb_setpwm(10.0,100.0,200.0);
}
void rgb_setpwm(uint8_t pwm_r,uint8_t pwm_g,uint8_t pwm_b)
{ 
        
   __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1,pwm_r);
   __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2,pwm_g);
   __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_3,pwm_b);

}

测试用例:

main(void)
{ 
        
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_SPI2_Init();
    MX_TIM8_Init();
    rgb_init();
    OLED_Init();
    while(1)`
    { 
        
       Test_rgb();    
}
}

③测试用例实验结果: 由上图可知RGB灯被点亮。

二、通过esp8266实现数据上传和数据回传

在进行数据上传与数据回传之前,首先进行用于打印数据的串口1的设置和用于stm32与esp8266通信的串口2。 串口1: 串口1设置PA9和PA10分别作为TX和RX,波特率为115200,不使能中断。 串口2:

串口2设置PA2和PA3分别作为TX和RX,波特率为9600,使能中断。 (一)数据上传------温湿度数据、关照强度数据 ①主要代码

void userHandle(void)
{ 
        
    DHT11_Read_Data( & humidity_integer, & humidity_decimal, & temperature_integer, & temperature_decimal);
    currentDataPoint.valuehumidity = humidity_integer; 
    currentDataPoint.valueLight_intensity = light_check5506_get0to100value(); 
    currentDataPoint.valueDHT11 = temperature_integer + 0.1 * temperature_decimal; 
}

在userHandle(void)中添加温湿度数据的采集以及光照强度的读取。userHandle()是main函数中while循环的内容。 由左图可以看出,userHandle对于用户来说是最顶层的,数据在userHandle中采集,依次经过gizCheckReport判断是否上报当前状态的数据、gizDataPoints2ReportData完成用户区数据到上报型数据的转换、gizReportData将转换后的上报数据通过串口发送给 WiFi 模块。 ②设计结果: 首先确保esp8266和手机都已经连接到同一个网络,这里用电脑作为这个网络。 由上图可知手机和esp8266已经连接上了电脑。机智云app连接上esp8266后得到上传来的数据: Oled上的数据是stm32收集的,右边图的数据是app通过esp8266收到的,两者一致,说明数据交互是正确的。 (二)数据回传------RGB三数值 ①主要代码

int8_t gizwitsEventProcess(eventInfo_t * info, uint8_t * gizdata, uint32_t len)
{ 
        
    uint8_t i = 0;
    dataPoint_t * dataPointPtr = (dataPoint_t *)gizdata;
    moduleStatusInfo_t * wifiData = (moduleStatusInfo_t *)gizdata;
    protocolTime_t * ptime = (protocolTime_t *) gizdata;
    # if MODULE_TYPE
    gprsInfo_t * gprsInfoData = (gprsInfo_t *)gizdata;
    # else
    moduleInfo_t * ptModuleInfo = (moduleInfo_t *) gizdata;
    # endif
    if ((NULL == info) || (NULL == gizdata))
    { 
        
        return -1;
    }
    for (i=0; i < info->num; i++)
    { 
        
        switch(info->event[i])
        { 
        
            case EVENT_LED_R:
                currentDataPoint.valueLED_R = dataPointPtr->valueLED_R;
                GIZWITS_LOG("Evt:EVENT_LED_R %d\n", currentDataPoint.valueLED_R);
                rgb_setpwm(currentDataPoint.valueLED_R, currentDataPoint.valueLED_G, currentDataPoint.valueLED_B);
                break;
            case EVENT_LED_G:
                currentDataPoint.valueLED_G = dataPointPtr->valueLED_G;
                GIZWITS_LOG("Evt:EVENT_LED_G %d\n", currentDataPoint.valueLED_G);
                rgb_setpwm(currentDataPoint.valueLED_R, currentDataPoint.valueLED_G, currentDataPoint.valueLED_B);
                break;
            case EVENT_LED_B:
                currentDataPoint.valueLED_B = dataPointPtr->valueLED_B;
                GIZWITS_LOG("Evt:EVENT_LED_B %d\n", currentDataPoint.valueLED_B);
                rgb_setpwm(currentDataPoint.valueLED_R, currentDataPoint.valueLED_G, currentDataPoint.valueLED_B);
                break;
        }
    }
}

在gizwitsEventProcess中的EVENT_LED_R、EVENT_LED_G、EVENT_LED_B分别添加对对RGB三个PWM的赋值,赋值之后使其立即生效。 protocolIssuedProcess被 gizwitsHandle 调用,接收来自云端或 app端下发的相关协议数据。ACTION_CONTROL_DEVICE进行“控制型协议”的相关处理,gizDataPoint2Event根据协议生成“控制型事件”,并进行相应数据类型的转化转换,gizwitsEventProcess是位于数据回传过程中的最底层,根据已生成的“控制型事件”进行相应处理。 ②设计结果: 首先确保esp8266和手机都已经连接到同一个网络,这里用电脑作为这个网络。 由上图可知手机和esp8266已经连接上了电脑。机智云app设置RGB三个PWM数值,得到oled上的数据为: 由上图可知,右图为app设置的三个PWM数值,左图再oled上为同样的数值,说明数据交互正确。

三、总结与体会

①通过这次设计接触了STM32CubeMX这个软件,相比与之前的标准库,STM32CubeMX生成的Hal库不仅封装度更高,而且更有利于开发者进行快速开发,而且在本次实验中机智云生成的代码也是基于Hal库的,这说明以后对于stm32来说,会越来越趋向于Hal开发。 ②官网永远是对解决问题的最好地方,机智云的官方文档给了我极大帮助。 ③esp8266的烧录对于供电要求十分苛刻,导致多次烧录都失败了,所以我在制pcb的时候加上了esp8266的烧录接口,以及GPIO的接地开关,还有复位电路。 ④stmRct6板的供电十分差,由于我刚开始只是接了ST-LINK进行供电,导致dht11和oled一起使用时dht11的VCC口只有2.6V,进而使得dht11通信一直不成功,这也说明了一切先从电源管理开始,确保供电没问题再查找软件问题。

附录

1、PCB扩展板 PCB工程链接: 链接:https://pan.baidu.com/s/1mASqMcT1FdAu_I2DBkxMeg 提取码:xydq

2、代码 链接:https://pan.baidu.com/s/1fQRfchWXtGXmWRjT9O1fTw 提取码:jaam

标签: 300pa2pa传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台