
通过温度,湿度和日照等不同变量跟踪生态系统演变的设备。 ![]() 硬件组件 Grove DHT22 空气温度+空气湿度传感器 × 2 Grove 101990019(DS18B20) 土壤温度传感器 × 2 重力SEN0193 土壤湿度传感器 × 2 Adafruit TSL2591 亮度传感器 × 2 ADA 1334(TCS34725) RGB传感器 × 2 细胞核 - L432KC STM32微控制器 × 1 BRKWS01 Kit Breakout Sigfox +天线 × 1 Accu Li-Ion 3,7 V 1050 mAh 电池 × 1 DFR0164 USB转换器 × 1 SOL2W 太阳能板 × 1 太阳能电池板应用的电池充电器 × 1 张力调节器/ MCP1252 / 3 × 1 手动工具和制造机器 烙铁(通用) 3D打印机(通用) mbed 手臂Mbed mbed 介绍 ![]() ![]() 我们开始这个项目的目标如下:设计一个自动装置,在安装太阳能电池板后跟随绿色屋顶的演变。 有了这个,我们可以研究生物多样性的演变和热岛的影响。 详细功能 监控包括管理: 空气/土壤湿度 空气/土壤温度 亮度(甚至RGB光线) 使用微控制器和传感器 先决条件 有知识 微控制器编程(C ++) 如何阅读数据表并提取最重要的数据 I2C,SPI,UART,CRC协议 如何使用Sigfox发送数据: 每天可以发送多少条消息? 如何构建消息?(SQL查询) 要遵循的步骤 1.根据用于解释数据的技术,对项目使用的所有引脚进行映射 2.对微控制器STM32 NUCLEO-L432KC进行编程 从传感器中检索数据 将数据转换为使用Sigfox发送 当Sigfox模块不发送消息时,配置微控制器的睡眠模式 3.按照本教程设置IoT Azure云平台:https ://github.com/aureleq/sigfox-azure-iothub 4.配置仪表板,其中将显示所有检索到的数据 创建图表 将数据保存在数据库中 代码说明: 使用的库 #include "mbed.h" #include "main.h" #include "DHT.h" #include "DS1820.h" #include "TSL2591.h" #include "TCS3472_I2C.h" #include "WakeUp.h" 连接: #defineDHT_INT_PIN D6 //Humidity and temperature #defineDHT_EXT_PIN D9 #defineI2C_INT_SDA D0 //I2C1 #defineI2C_INT_SCL D1 #defineI2C_EXT_SDA D12 //I2C3 #defineI2C_EXT_SCL A6 #defineSOIL_TEMP_INT_PIN A2 //Soil Temperature #defineSOIL_TEMP_EXT_PIN A4 #defineSOIL_MOISTURE_INT_PIN A1 //Ground Humidity #defineSOIL_MOISTURE_EXT_PIN A3 #defineSIGFOX_TX D5 #defineSIGFOX_RX D4 #defineINT_MEASURE 0 #defineEXT_MEASURE 1 #defineDELAY_SLEEP 60 // 1 min x 20 min DHT dht_int(DHT_INT_PIN, DHT: ![]() DHT dht_ext(DHT_EXT_PIN, DHT: ![]() I2C i2c_int(I2C_INT_SDA,I2C_INT_SCL); //SDA_1, SCL_1 I2C i2c_ext(I2C_EXT_SDA,I2C_EXT_SCL); //SDA_3, SCL_3 TCS3472_I2C rgb_int(I2C_INT_SDA,I2C_INT_SCL); // busI2C 1 TCS3472_I2C rgb_ext(I2C_EXT_SDA,I2C_EXT_SCL); // busI2C 3 TSL2591 lum_int(i2c_int, TSL2591_ADDR); TSL2591 lum_ext(i2c_ext, TSL2591_ADDR); DS1820 soil_temp_int(SOIL_TEMP_INT_PIN); // A2 DS1820 soil_temp_ext(SOIL_TEMP_EXT_PIN); // A4 DigitalOut drive_sigfox(DRIVE_SIGFOX); //DigitalOut drive_ext(DRIVE_EXT); //DigitalOut drive_int_1(DRIVE_INT_1); // DHT and 2 I2Cint //DigitalOut drive_int_2(DRIVE_INT_2); // 2 temp sol ethum du sol AnalogIn soil_hum_int(SOIL_MOISTURE_INT_PIN); // SEN0193- A1 AnalogIn soil_hum_ext(SOIL_MOISTURE_EXT_PIN); // SEN0193- A3 Serial sigfox(SIGFOX_TX, SIGFOX_RX); Serial pc(USBTX, USBRX); // UART 使用的变量: int err_int = 0; // verify DHT_int sample int err_ext = 0; // verify DHT_ext sample int x = 0; // used in air_temperature processing int y = 0; // used in soil_temperature processing int lum = 0; // used in ReducedLuminosity uint32_t dataSigfox1_int = 0; // 32 bit uint32_t dataSigfox2_int = 0; uint32_t dataSigfox1_ext = 0; // 32 bit uint32_t dataSigfox2_ext = 0; uint8_t air_temp_int_reduced = 0; // 8 bit (0.5°C step) uint8_t air_temp_ext_reduced = 0; // 8 bit (0.5°C step) uint8_t soil_temp_int_reduced = 0; // 8 bit (0.5 °C step) uint8_t soil_temp_ext_reduced = 0; // 8 bit (0.5 °C step) uint8_t air_hum_int_reduced = 0; // 8 bit (0 to 50% - 1% step) uint8_t air_hum_ext_reduced = 0; // 8 bit (0 to 50% - 1% step) uint8_t soil_hum_int_reduced = 0; // 8 bit (0 to 50% - 1% step) uint8_t soil_hum_ext_reduced = 0; uint8_t lum_int_reduced = 0; // 8 bit (0 to 255) uint8_t lum_ext_reduced = 0; uint8_t rgb_int_red = 0; // 8 bit (0 to 255) uint8_t rgb_int_blue = 0; uint8_t rgb_ext_red = 0; uint8_t rgb_ext_blue = 0; 使用的功能: 这些函数允许从传感器读取值并转换它们的值,以确保它可以存储在8位变量中。参数type告诉函数是否是内部测量。 uint8_t GetAirHumidityReduced(int type) uint8_t GetAirTempReduced(int type) uint8_t GetSoilTempReduced(int type) uint8_t GetSoilHumidityReduced(int type) uint8_t GetLuminosityReduced(int type) void printSensorValue_int() void printSensorValue_ext() 如何构建和发送Sigfox消息: 测量完成后,有效负载将根据所有值构建并发送到Sigfox网络: // Build SigfoxPayload Frame dataSigfox1_int = ((uint32_t)(air_temp_int_reduced)<< 24) | ((uint32_t)(soil_temp_int_reduced)<< 16) | ((uint32_t)(air_hum_int_reduced)<< 8) | ((uint32_t)(soil_hum_int_reduced)); dataSigfox2_int = ((uint32_t)(lum_int_reduced)<< 24) | ((uint32_t)(rgb_int_red)<< 16) | ((uint32_t)(rgb_int_blue)<< 8) | ((uint32_t)(INT_MEASURE)); dataSigfox1_ext = ((uint32_t)(air_temp_ext_reduced)<< 24) | ((uint32_t)(soil_temp_ext_reduced)<< 16) | ((uint32_t)(air_hum_ext_reduced)<< 8) | ((uint32_t)(soil_hum_ext_reduced)); dataSigfox2_ext = ((uint32_t)(lum_ext_reduced)<< 24) | ((uint32_t)(rgb_ext_red)<< 16) | ((uint32_t)(rgb_ext_blue)<< 8) | ((uint32_t)(EXT_MEASURE)); // Send PayloadFrame sigfox.printf("AT$SF=%08x%08x\r\n", dataSigfox1_int, dataSigfox2_int); pc.printf("AT$SF=%08x%08x\r\n", dataSigfox1_int, dataSigfox2_int); wait(10); sigfox.printf("AT$SF=%08x%08x\r\n", dataSigfox1_ext, dataSigfox2_ext); pc.printf("AT$SF=%08x%08x\r\n", dataSigfox1_ext, dataSigfox2_ext); 原理图 ![]() 代码 /* main.c Author : Ayoub SABRI, Ryan DANEKAS, AntoineACOLANT, Antoine SOMSAY Polytech Sorbonne - EISE 4 - 2018/19 */ /***************************** LIBRARIES ***********************************/ #include "mbed.h" #include "main.h" #include "DHT.h" #include "DS1820.h" #include "TSL2591.h" #include "TCS3472_I2C.h" #include "WakeUp.h" /**************************** CONNECTIONS **********************************/ DHT dht_int(DHT_INT_PIN,DHT: ![]() DHT dht_ext(DHT_EXT_PIN,DHT: ![]() I2C i2c_int(I2C_INT_SDA,I2C_INT_SCL); // SDA_1, SCL_1 I2C i2c_ext(I2C_EXT_SDA,I2C_EXT_SCL); // SDA_3, SCL_3 TCS3472_I2C rgb_int(I2C_INT_SDA,I2C_INT_SCL); // bus I2C 1 TCS3472_I2C rgb_ext(I2C_EXT_SDA,I2C_EXT_SCL); // bus I2C 3 TSL2591 lum_int(i2c_int, TSL2591_ADDR); TSL2591 lum_ext(i2c_ext, TSL2591_ADDR); DS1820 soil_temp_int(SOIL_TEMP_INT_PIN); // A2 DS1820 soil_temp_ext(SOIL_TEMP_EXT_PIN); // A4 AnalogIn soil_hum_int(SOIL_MOISTURE_INT_PIN); // SEN0193 - A1 AnalogIn soil_hum_ext(SOIL_MOISTURE_EXT_PIN); // SEN0193 - A3 Serial sigfox(SIGFOX_TX, SIGFOX_RX); Serial pc(USBTX, USBRX); // UART /**************************** VARIABLES ************************************/ int err_int = 0; // verify DHT_int sample int err_ext = 0; // verify DHT_ext sample int x = 0; // used in air_temperature processing int y = 0; // used in soil_temperature processing int lum = 0; // used in ReducedLuminosity uint32_t dataSigfox1_int = 0; // 32 bit uint32_t dataSigfox2_int = 0; uint32_t dataSigfox1_ext = 0; // 32 bit uint32_t dataSigfox2_ext = 0; uint8_t air_temp_int_reduced = 0; // 8 bit (0.5°C step) uint8_t air_temp_ext_reduced = 0; // 8 bit (0.5°C step) uint8_t soil_temp_int_reduced = 0; // 8 bit (0.5°C step) uint8_t soil_temp_ext_reduced = 0; // 8 bit (0.5°C step) uint8_t air_hum_int_reduced = 0; // 8 bit (0 to 50% - 1% step) uint8_t air_hum_ext_reduced = 0; // 8 bit (0 to 50% - 1% step) uint8_t soil_hum_int_reduced = 0; // 8 bit (0 to 50% - 1% step) uint8_t soil_hum_ext_reduced = 0; uint8_t lum_int_reduced = 0; // 8 bit (0 to 255) uint8_t lum_ext_reduced = 0; uint8_t rgb_int_red = 0; // 8 bit (0 to 255) uint8_t rgb_int_blue = 0; uint8_t rgb_ext_red = 0; uint8_t rgb_ext_blue = 0; /**************************** FUNCTIONS ************************************/ void mycallback(void){} uint8_t GetAirHumidityReduced(int type) { int air_humidity = 0; if(type == INT_MEASURE){ air_humidity = (int) dht_int.getHumidity(); } else if( type ==EXT_MEASURE){ air_humidity = (int) dht_ext.getHumidity(); } if(air_humidity % 2 != 0) { air_humidity ++; } return air_humidity / 2; } uint8_t GetAirTempReduced(int type) { int air_temperature = 0; if(type == INT_MEASURE){ air_temperature = (int) dht_int.getTemperature(DHT::CELCIUS) * 10; } else if( type ==EXT_MEASURE){ air_temperature = (int) dht_ext.getTemperature(DHT::CELCIUS) * 10; } x= air_temperature % 10; if((x > 2) && (x < 8)){ air_temperature = (air_temperature / 10)*10+5; } else{ if (x < 5) {air_temperature =(air_temperature/10)*10;} else {air_temperature =(air_temperature/10)*10+10;} } return(int)(air_temperature+300)/5; } uint8_t GetSoilTempReduced(int type) { int soil_temperature = 0; if(type == INT_MEASURE){ soil_temp_int.convertTemperature(true, DS1820::all_devices); if(soil_temp_int.unassignedProbe(SOIL_TEMP_INT_PIN))pc.printf("error"); soil_temperature = (int) soil_temp_int.temperature() * 10; } else if(type == EXT_MEASURE){ soil_temp_ext.convertTemperature(true, DS1820::all_devices); if(soil_temp_ext.unassignedProbe(SOIL_TEMP_EXT_PIN))pc.printf("error"); soil_temperature = (int) soil_temp_ext.temperature() * 10; } y= soil_temperature % 10; if((y > 2) && (y < 8)){ soil_temperature = (soil_temperature/10)*10+5; } else{ if (y < 5) {soil_temperature =(soil_temperature/10)*10;} else {soil_temperature =(soil_temperature/10)*10+10;} } return (soil_temperature+50)/5; } uint8_t GetSoilHumidityReduced(int type){ float Vm = 0.0; if(type == INT_MEASURE){ Vm = soil_hum_int; // read sensor voltage from ADC } else if(type == EXT_MEASURE){ Vm = soil_hum_ext; // read sesor voltage from ADC } float soil_humidity = (( 1.0 - Vm ) - 0.23) * 100.0 / 0.4; // 0 to 100% range return (uint8_t)soil_humidity / 2; } uint8_t GetLuminosityReduced(int type){ if(type == INT_MEASURE){ lum_int.getALS(); lum_int.calcLux(); lum = lum_int.lux; } else if(type == EXT_MEASURE){ lum_ext.getALS(); lum_ext.calcLux(); lum = lum_ext.lux; } return (int) (lum / 16); } void printSensorValue_int(){ pc.printf("AT$SF=%08x%08x\r\n", dataSigfox1_int, dataSigfox2_int); pc.printf("air temp int: %d %.2f\r\n", air_temp_int_reduced,dht_int.getTemperature(DHT::CELCIUS)); pc.printf("soil temp int: %d %.2f\r\n", soil_temp_int_reduced,soil_temp_int.temperature()); pc.printf("air hum int: %d %.2f\r\n", air_hum_int_reduced,dht_int.getHumidity()); pc.printf("soil hum int: %d %d\r\n", soil_hum_int_reduced,soil_hum_int_reduced * 2); pc.printf("lum int: %d %.2f\r\n", lum_int_reduced, lum_int.lux); pc.printf("rgb red int: %d\r\nrgb blue int: %d\r\n\n", rgb_int_red,rgb_int_blue); } void printSensorValue_ext() { pc.printf("AT$SF=%08x%08x\r\n", dataSigfox1_ext, dataSigfox2_ext); pc.printf("air temp ext: %d %.2f\r\n", air_temp_ext_reduced,dht_ext.getTemperature(DHT::CELCIUS)); pc.printf("soil temp ext: %d %.2f\r\n", soil_temp_ext_reduced,soil_temp_ext.temperature()); pc.printf("air hum ext: %d %.2f\r\n", air_hum_ext_reduced,dht_ext.getHumidity()); pc.printf("soil hum ext: %d %d\r\n", soil_hum_ext_reduced,soil_hum_ext_reduced * 2); pc.printf("lum ext: %d %.2f\r\n", lum_ext_reduced, lum_ext.lux); pc.printf("rgb red ext: %d\r\nrgb blue ext: %d\r\n\n", rgb_ext_red, rgb_ext_blue); } void init(){ rgb_int.enablePowerAndRGBC(); rgb_int.setIntegrationTime(100); rgb_ext.enablePowerAndRGBC(); rgb_ext.setIntegrationTime(100); lum_int.init(); lum_ext.init(); WakeUp::set_ms(DELAY_SLEEP * 1000); WakeUp::calibrate(); WakeUp::attach(&mycallback); } /******************************* MAIN **************************************/ int main() { // Initalization pc.format(8,SerialBase::None,1); pc.baud(9600); //sigfox.format(8,SerialBase::None,1); sigfox.baud(9600); while(1) { init(); wait_ms(10); //Air Humidity and Temperature err_int = dht_int.read(); err_ext = dht_ext.read(); if (err_int ==DHT::SUCCESS) { air_hum_int_reduced = GetAirHumidityReduced(INT_MEASURE); air_temp_int_reduced = GetAirTempReduced(INT_MEASURE); } if (err_ext ==DHT::SUCCESS) { air_hum_ext_reduced = GetAirHumidityReduced(EXT_MEASURE); air_temp_ext_reduced =GetAirTempReduced(EXT_MEASURE); } // rgb rgb_int_red = rgb_int.getRedData(); rgb_int_blue = rgb_int.getBlueData(); rgb_ext_red = rgb_ext.getRedData(); rgb_ext_blue = rgb_ext.getBlueData(); // soil temp soil_temp_int_reduced = GetSoilTempReduced(INT_MEASURE); soil_temp_ext_reduced = GetSoilTempReduced(EXT_MEASURE); // soil humidity soil_hum_int_reduced = GetSoilHumidityReduced(INT_MEASURE); soil_hum_ext_reduced = GetSoilHumidityReduced(EXT_MEASURE); //luminosity lum_int_reduced = GetLuminosityReduced(INT_MEASURE); lum_ext_reduced = GetLuminosityReduced(EXT_MEASURE); // Build Sigfox Payload Frame dataSigfox1_int =((uint32_t)(air_temp_int_reduced) << 24) | ((uint32_t)(soil_temp_int_reduced) << 16) | ((uint32_t)(air_hum_int_reduced) << 8) | ((uint32_t)(soil_hum_int_reduced)); dataSigfox2_int = ((uint32_t)(lum_int_reduced) << 24) | ((uint32_t)(rgb_int_red) << 16) | ((uint32_t)(rgb_int_blue) << 8) | ((uint32_t)(INT_MEASURE)); dataSigfox1_ext = ((uint32_t)(air_temp_ext_reduced) << 24) | ((uint32_t)(soil_temp_ext_reduced) << 16) | ((uint32_t)(air_hum_ext_reduced) << 8) | ((uint32_t)(soil_hum_ext_reduced)); dataSigfox2_ext = ((uint32_t)(lum_ext_reduced) << 24) | ((uint32_t)(rgb_ext_red) << 16) | ((uint32_t)(rgb_ext_blue) << 8) | ((uint32_t)(EXT_MEASURE)); // Send Payload Frame sigfox.printf("AT$SF=%08x%08x\r\n", dataSigfox1_int, dataSigfox2_int); pc.printf("AT$SF=%08x%08x\r\n", dataSigfox1_int, dataSigfox2_int); wait(10); sigfox.printf("AT$SF=%08x%08x\r\n", dataSigfox1_ext, dataSigfox2_ext); pc.printf("AT$SF=%08x%08x\r\n", dataSigfox1_ext, dataSigfox2_ext); // Display values //printSensorValue_int(); //printSensorValue_ext(); //wait_ms(100); // En veille pendant 20 min for(int i = 0; i < 20; ++i){ WakeUp::set_ms(DELAY_SLEEP * 1000); // 20 min wait_ms(10); deepsleep(); } } } |