快捷搜索:  汽车  科技

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)3)DHT22温度传感器2)Sigfox TD1208R项目需要的知识储备系统的硬件组成部分1)主控:STM32 L432开发板

疫情让很多人成为园艺大师,在家种上了蔬菜。如何科学规范的种植呢?今天分享的就是一套近乎0基础就可以实现的植物监测系统。

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)(1)

系统功能

监控包括:

  • 空气/土壤水分
  • 空气/土壤温度
  • 亮度(包括RGB 光线)

附加的功能:
还可以发送本地化信息,从而提供天气预报。为监控系统创建了一个Twitter帐户。使用 Sigfox 发送的每条消息也作为推文发送。

项目需要的知识储备

  • 微控制器编程
  • 如何阅读数据表并提取最重要的数据
  • I2C、SPI、UART、CRC 协议
  • 如何使用 Sigfox 发送数据(Sigfox 无线技术是低功耗广域网 (LPWAN) 技术):
  • 1)AT 命令
  • 2)每天可以发送多少条消息?
  • 3)如何构建消息?(JSON 语言)

系统的硬件组成部分

1)主控:STM32 L432开发板

2)Sigfox TD1208R

3)DHT22温度传感器

4)Seeed Studio Grove 湿度传感器

5)Adafruit TSL2561 照度传感器

6)Adafruit TCS34725 RGB 颜色传感器

7)Seeed Studio Grove DS18B20 温度传感器

8)Adafruit 单色 0.96" 128x64 OLED 图形显示器

9)USB Micro-B 连接器分线板

系统设计步骤

1. 对项目使用的所有引脚进行映射

2. 对微控制器 STM32 NUCLEO-L432KC 进行编程

  • 从传感器获取数据
  • 使用 Sigfox 转换发送数据
  • 在 OLED 屏幕上显示数据
  • 配置 Sigfox 模块不发送消息时微控制器的睡眠模式

3. 配置仪表板,将显示所有检索到的数据

  • 创建图表
  • 将数据保存在数据库中
  • 使用此数据显示天气预报
  • 配置 Twitter 和邮件
  • CSV 报告(每周、每月和每半年)
  • 如果有多个Sigfox模块,创建一个下拉列表以允许最终用户过滤数据以显示

使用哪些引脚?

项目有 5 个传感器可供使用,它们的连接通信方式不同。阅读 NUCLEO L432KC 的数据表可以对要使用的引脚进行分类。

下图为项目定义的映射:

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)(2)

点击可放大

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。

点击这里找小助理0元领取嵌入式物联网学习资料(头条)

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)(3)

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)(4)

软件代码编写

要使用的头文件:

#include "mbed.h" #include "DS18B20.h" #include "DHT.h" #include "TSL2561.h" #include "Adafruit_SSD1306.h" #include "WakeUp.h"

在mapping.h 文件中,根据需要注释/取消注释以下行:

// Uncomment line to enable the focused object/sensor : #define OLED_ACTIF #define SIGFOX_ACTIF #define I2C_ACTIF #define DEBUG_UART_ACTIF #define DHT_ACTIF #define GROVE_MOIST_ACTIF #define ONEWIRE_TEMP_ACTIF #define LUX_ACTIF #define RGB_ACTIF #define BATTERIE_ACTIF

对于高级用户,可以在此文件中修改其他参数,例如:

  • 传感器校准
  • 引脚分配
  • 测量精度
  • 计时

main初始化:

/********************************* Initialisation *********************************/ #ifdef BATTERIE_ACTIF float BATTERIE_MIN = 33; float BATTERIE_MAX = 42; #endif #ifdef OLED_ACTIF // Initialisation de l'écran OLED.fillRect(0 0 LARGEUR_OLED HAUTEUR_OLED BLACK); OLED.setTextCursor(0 10); OLED.printf("==================="); OLED.setTextCursor(0 20); OLED.printf(" PlantSigfox "); OLED.setTextCursor(0 30); OLED.printf(" Projet ei2i-4 "); OLED.setTextCursor(0 40); OLED.printf("Jeanne Anais Thomas"); OLED.setTextCursor(0 50); OLED.printf("==================="); OLED.display(); #endif #ifdef DEBUG_UART_ACTIF // Initialisation des communications UART pc.format(8 SerialBase::None 1); pc.baud(9600); #endif #ifdef SIGFOX_ACTIF Sigfox.format(8 SerialBase::None 1); Sigfox.baud(9600); #endif #ifdef ONEWIRE_TEMP_ACTIF // Initialisation du capteur de température while (!Temperature.initialize()); // on attend que le capteur soit initialisé avant de pouvoir effectuer des mesures #endif #ifdef RGB_ACTIF // Initialisation du TCS34725 rgb.init_RGB(); #endif // Attente de 5 secondes avant le démarrage du programme wait(5);

主循环分为 3 个部分:

1 - 获取方法和数据处理:

为了使测量点更可靠,每个点对应于一段时间内的测量平均值(在 Mapping.h 中定义)。

/********************************* Mesure des ADC *********************************/ // On effectue une moyenne sur une quantité de relevés ( pour avoir une mesure fiable ) #if defined(GROVE_MOIST_ACTIF) || defined(BATTERIE_ACTIF) Niveau_Batterie = 0; HumidSol = 0; for (i=0; i < NB_MESURES; i ) { #ifdef BATTERIE_ACTIF // Batterie VBAT = 100 * Batterie; // Lecture de l'entrée ADC Niveau_Batterie = ((VBAT - BATTERIE_MIN) / (BATTERIE_MAX - BATTERIE_MIN)) * 100 ; #endif #ifdef GROVE_MOIST_ACTIF // Humidité du Sol (Grove) HumidSol = ((Capteur_Moisture - GROVE_MOIST_MIN) / (GROVE_MOIST_MAX - GROVE_MOIST_MIN)) * 100; #endif wait(TEMPS_MESURE); } #endif // Moyennage du résultat #ifdef GROVE_MOIST_ACTIF HumidSol /= NB_MESURES; #endif #ifdef BATTERIE_ACTIF Niveau_Batterie /= NB_MESURES; // Limitation de la batterie if (Niveau_Batterie >100) Niveau_Batterie = 100; // Si la batterie est déconnectée on doit le faire remarquer (code : 101) if (Niveau_Batterie < 0) Niveau_Batterie = 101; #endif /********************************* Température du sol (OneWIRE) *********************************/ #ifdef ONEWIRE_TEMP_ACTIF Temperature.setResolution(twelveBit); // Le choix de la résolution se fait avant le relevé des données TempSol = Temperature.readTemperature(); // relevé de données #endif /********************************* Température/Humidité Air (Grove) *********************************/ #ifdef DHT_ACTIF int err; wait(1); // wait 1 second for device stable status do { err = sensor.readData(); wait(1); } while (err != 0); if (err == 0) { TempAir = sensor.ReadTemperature(CELCIUS); HumidAir = sensor.ReadHumidity(); } #endif /********************************* Luminosité / RGB(Adafruit) *********************************/ #ifdef LUX_ACTIF Lumiere = COEF_LUX * lum.lux(); #endif #ifdef RGB_ACTIF rgb.GET_RGB(&Clear &Red &Green &Blue); #ifdef RGB_1_OCTET // On réduit la précision des données brutes en divisant par 256 pour n'avoir qu'un octet seulement Clear /= 256; Red /= 256; Green /= 256; Blue /= 256; #endif #endif

2 - 显示和发送数据:

数据显示在 OLED 屏幕上,并通过 Sigfox 模块作为帧发送到云端。

/********************************* Affichage OLED *********************************/ #ifdef OLED_ACTIF // OLED Reset OLED.fillRect(0 0 LARGEUR_OLED HAUTEUR_OLED BLACK); line = 0; // Sol : #if defined(GROVE_MOIST_ACTIF) && defined(ONEWIRE_TEMP_ACTIF) OLED.setTextCursor(0 line); OLED.printf("Sol = %d \tC // %d \t/\t" (int)TempSol (int)HumidSol); line =10; #endif // Air : #ifdef DHT_ACTIF OLED.setTextCursor(0 line); OLED.printf("Air = %d \tC // %d \t/\t" (int)TempAir (int)HumidAir); line =10; #endif // Intensité lumineuse #if defined(LUX_ACTIF) && defined(I2C_ACTIF) OLED.setTextCursor(0 line); OLED.printf("Light = %d" (int)Lumiere); OLED.setTextCursor(110 line); OLED.printf("Lux"); line =10; #endif // Couleurs RGB #if defined(RGB_ACTIF) && defined(I2C_ACTIF) OLED.setTextCursor(0 line); OLED.printf("RGB = %d/%d/%d" Red Green Blue); line =10; OLED.setTextCursor(0 line); OLED.printf("Clear = %d" Clear); line =10; #endif // Batterie #ifdef BATTERIE_ACTIF OLED.setTextCursor(0 line); if (((int)Niveau_Batterie >= 0) && ((int)Niveau_Batterie <= 100)) { OLED.printf("Batterie : %d" (int)Niveau_Batterie); OLED.setTextCursor(110 line); OLED.printf("\t/\t"); } else { OLED.printf("Prise Secteur"); } #endif // Display OLED.display(); #endif /**************************************************************************** Envoi des données via le module Sigfox (dépend du format des données) *****************************************************************************/ #ifdef SIGFOX_ACTIF #if defined(RGB_2_OCTET) && !defined(RGB_1_OCTET) // trame 1 : [T°Air Hum Air T°Sol Hum Sol Lumiere Batterie] Sigfox.printf("AT$SS=x x x x x x \r\n" (int)TempAir (int)HumidAir (int)TempSol (int)HumidSol (int)Lumiere (int)Niveau_Batterie); // trame 2 : [Clear Red Green Blue] Sigfox.printf("AT$SS=x x x x \r\n" Clear Red Green Blue); #endif #if defined(RGB_1_OCTET) && !defined(RGB_2_OCTET) // trame : [T°Air Hum Air T°Sol Hum Sol Lumiere Batterie Clear Red Green Blue] Sigfox.printf("AT$SS=x x x x x x x x x x \r\n" (int)TempAir (int)HumidAir (int)TempSol (int)HumidSol (int)Lumiere (int)Niveau_Batterie Clear Red Green Blue); #endif #endif // Envoi des données sur le debug UART (optionnel) #ifdef DEBUG_UART_ACTIF #if defined(RGB_2_OCTET) && !defined(RGB_1_OCTET) // trame 1 : [T°Air Hum Air T°Sol Hum Sol Lumiere Batterie] pc.printf("AT$SS=x x x x x x \r\n" (int)TempAir (int)HumidAir (int)TempSol (int)HumidSol (int)Lumiere (int)Niveau_Batterie); // trame 2 : [Clear Red Green Blue] pc.printf("AT$SS=x x x x \r\n" Clear Red Green Blue); #endif #if defined(RGB_1_OCTET) && !defined(RGB_2_OCTET) // trame : [T°Air Hum Air T°Sol Hum Sol Lumiere Batterie Clear Red Green Blue] pc.printf("AT$SS=x x x x x x x x x x \r\n" (int)TempAir (int)HumidAir (int)TempSol (int)HumidSol (int)Lumiere (int)Niveau_Batterie Clear Red Green Blue); #endif #endif

3 - 待机:

微控制器进入待机模式以限制其空闲时间的消耗:

/********************************* Mise en veille de l'appareil *********************************/ #if defined(OLED_ACTIF) && defined(OLED_VEILLE) // Test : éteindre l'écran au bout d'un temps donné wait (DUREE_AFFICHAGE); OLED.fillRect(0 0 LARGEUR_OLED HAUTEUR_OLED BLACK); OLED.display(); WakeUp::set_ms((TEMPS_RELEVE-DUREE_AFFICHAGE)* 1000); deepsleep(); #else WakeUp::set_ms(TEMPS_RELEVE * 1000); deepsleep(); #endif

注意:整个代码依赖于 Mapping.h 文件中的配置

PCB焊接

硬件组件接线整体示意图:

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)(5)

太阳能电池的制作:

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)(6)

外壳及封装:

stm32室内环境监测系统程序(项目分享DIYSTM32植物监测系统)(7)

此项目来自hackster.io,制作者是Team PlantSigfox EI2I4: Thomas Broussard Jeanne Baumier Anaïs Auberval

END

转载自:达尔闻说

文章来源于项目分享| DIY STM32植物监测系统,园艺大师指日可待

原文链接:https://mp.weixin.qq.com/s/5D1ZhbEw27goCkPp4u0ALQ

猜您喜欢: