本帖最后由 点点&木木 于 2019-4-12 11:28 编辑 . p* z! O/ S9 D, H* U# \ 介绍 我们是Polytech Sorbonne的3名学生,专门研究EI2I(电子和计算机科学) 我们项目的目标是创建一个由多个传感器组成的模块,以帮助来自其他专业(AGRAL:农业食品行业)的学生进行种植园的后续工作。 微控制器在屏幕上实时显示传感器发送的温度(空气和土壤),湿度(空气和土壤),光度等信息。同时,它可通过LPWAN网络Sigfox将数据发送到在线服务器Ubidots。 & g7 I& s% t7 P9 W2 H$ S4 d ( V/ R' ^+ @9 b 硬件组件 DHT22温度传感器 × 1 STMicroelectronics STM32 MCU Nucleo-32板 × 1 TSL2561 - Lux传感器 × 1 TCS34725 - RGB传感器 × 1 SSD1306 OLED - 屏幕 × 1 SigFox × 1 DFRobot土壤水分 × 1 模温探头 × 1 Li-Pro Rider Pro × 1 Accu Li-Ion 3,7 V 1050 mAh × 1 太阳能板 × 1 ; ^* } r" T- n# d7 O6 m 1)使用传感器 · 1. DHT22 - 空气传感器的温度和湿度 DHT 22 3 A" h8 n* Q4 r6 r DHT22温度和湿度传感器通过串行端口与微控制器通信。传感器经过校准,不需要使用任何其他组件。 电源:3.3至6 Vdc 测量范围: - 温度:-40至+ 80°C - 湿度:0至100%RH 精确: - 温度:±0.5°C - 湿度:±2%RH - P. ~" B4 O$ y 为了使用这个传感器,我们使用了Mbed中的预定义功能 · DHT22.h /*5 g' C9 B0 M: `1 T- f* DHT Library for Digital-output Humidity and Temperature sensors3 Y" l+ @" O: c- F2 O *" _4 C, G" F: a9 B * Works with DHT11, DHT21, DHT221 X7 M- v$ N+ N& {) v0 i" s * SEN11301P, Grove - Temperature&Humidity Sensor (Seeed Studio)) ]2 P3 f4 s4 Q3 A9 D& T; Y * SEN51035P, Grove - Temperature&Humidity Sensor Pro (Seeed Studio) * AM2302 , temperature-humidity sensor * RHT01,RHT02, RHT03 , Humidity and Temperature Sensor (Sparkfun)/ ~4 W( _* {' I1 D ** X8 V6 D: c# M3 J% G8 Q* @ * Copyright (C) Wim De Roeve6 y# ? S" p/ z3 [ * based on DHT22 sensor library by HO WING KIT * Arduino DHT11 library * * Permission is hereby granted, free of charge, to any person obtaining a copy& M! h1 h! {- G0 W, \: j/ E( m * of this software and associated documnetation files (the "Software"), to deal2 k2 c* E+ o# @$ ?4 e* ~ * in the Software without restriction, including without limitation the rights; N. m$ |% k( \9 {" Y! n1 M * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell% k8 N5 \1 x- S * copies of the Software, and to permit persons to whom the Software is * furished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in, f8 y2 f& l9 F w * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,3 t" a" o( e: j# \! D2 D/ l6 F * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE/ m6 o. Y' v1 Q4 c+ ^# p * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,8 D$ R( h Q" ` * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN m G8 b3 N2 A$ t+ w: d8 e H * THE SOFTWARE. */4 E+ e9 V' H' n; S& D, p" ] #ifndef MBED_DHT_H& a* u/ J9 a5 B. O #define MBED_DHT_H #include "mbed.h" typedef enum eType eType;8 A' N8 `- J1 {' r4 ?6 k! ` enum eType {, d4 f4 o' C3 i, U+ @( _ DHT11 = 11,$ C* F4 }7 H8 `5 P/ t- }7 x2 [ SEN11301P = 11, RHT01 = 11,& F) _# F2 Y' I; C DHT22 = 22, AM2302 = 22,0 s( e( t1 C B3 t SEN51035P = 22,8 Y: l: B0 c @$ O! V3 X RHT02 = 22, RHT03 = 22 ^, f8 ^# U' a% V7 m; i* W! D }; ^+ c0 k R8 e% R typedef enum eError eError; enum eError {6 B. y/ y- d, Y0 r+ O5 z ERROR_NONE = 0,5 n" F# i6 n2 L/ q BUS_BUSY, ERROR_NOT_PRESENT,$ U* W$ f' C# R7 F3 s3 P% E ERROR_ACK_TOO_LONG, ERROR_SYNC_TIMEOUT, ERROR_DATA_TIMEOUT, ERROR_CHECKSUM,, r0 @/ p) j7 M q& m" w% N ERROR_NO_PATIENCE; M$ n3 w k0 U) t };1 H! E \/ P# @; v typedef enum eScale eScale;' D6 L1 g7 d h5 ?* z1 A" E enum eScale { CELCIUS = 0, FARENHEIT,- p A7 R* G) I9 E& {* k! M: M0 q KELVIN }; class DHT { public:! C0 P0 [; R* t0 d7 A DHT(PinName pin, eType DHTtype); ~DHT(); eError readData(void);. [ K$ r7 j# m" k8 t4 ` float ReadHumidity(void); : N% b( N7 P* B# W# z float ReadTemperature(eScale const Scale);6 ^7 T! e; `( @5 t0 ? float CalcdewPoint(float const celsius, float const humidity);- m c, M$ y$ {+ i5 e float CalcdewPointFast(float const celsius, float const humidity);3 ]- [8 z( O% i, _4 n private:4 H E) o! _% m3 k: F* F2 \ time_t _lastReadTime;' M) I% D- n8 } s7 e, s float _lastTemperature;% Q5 @" @0 p) A r2 I6 u& o float _lastHumidity; PinName _pin;! {3 O$ v& @0 g3 w6 X/ ^ bool _firsttime;4 B( ~) x3 J# c/ U( ? eType _DHTtype; uint8_t DHT_data[5];7 R# ?6 ] J, `* G4 N; {/ {$ ^6 x float CalcTemperature(); d; q& S6 j; s0 ` float CalcHumidity(); float ConvertCelciustoFarenheit(float const); float ConvertCelciustoKelvin(float const);- E8 Y G% P/ S8 C eError stall(DigitalInOut &io, int const level, int const max_time);$ Q4 d) r/ }( V6 e% C }; #endif DHT22.cpp #include "DHT22.h"# T# \& }3 `" B, j6 P d DHT22:HT22(PinName pin) {" F h8 D d4 d6 N* g _data_pin = pin;3 ?# F# K v* }& D }+ _8 p7 u: [" E6 ?" p: ~1 a int DHT22::getTemperature() {, x. v; C! i% x: _6 `- i2 y( i return _temperature;9 o' h: w9 Y5 c9 I$ t; o } int DHT22::getHumidity() { return _humidity; }# ^9 ^2 B: `7 i# G/ w1 e* V! \0 m bool DHT22::sample() {9 {; c7 X w1 c2 V7 ` DigitalInOut DHT22(_data_pin);+ [$ \; S2 O, j9 _; H int dht22_dat [5];% B! M d8 w/ e! a DHT22.output();) }: B3 G) o" Q* Z/ q( e DHT22.write(0);: X8 T. e; N0 T1 ^: V$ { wait_ms(18); DHT22.write(1); DHT22.input();2 Y7 f( H( C: e4 m wait_us(40); wait_us(80);" b) Q* b( [/ @8 X I. h" W# A! w4 G int i,j,result=0;4 t/ c/ d5 y9 p5 a, \+ ~$ C% V for (i=0; i<5; i++) { result=0;9 G$ i5 i* ]6 C9 u' h$ E. n for (j=0; j<8; j++) { while (DHT22);. y: t+ }+ V; [6 t+ u5 X while (!DHT22);* [7 ~, [, H( o: C% p wait_us(50); int p;8 J: ?/ M" [5 R/ V( ~1 G( _0 m p=DHT22;" E- f" m; @+ w6 Q u p=p <<(7-j); result=result|p; }+ w: G* u" E4 O, p dht22_dat = result; } int dht22_check_sum;2 G5 E, \8 g0 E% W dht22_check_sum=dht22_dat[0]+dht22_dat[1]+dht22_dat[2]+dht22_dat[3];/ {3 H& t% T7 \5 ~" E8 \ A/ i dht22_check_sum= dht22_check_sum%256;/ V1 S0 M1 d1 K) C- b if (dht22_check_sum==dht22_dat[4]) { _humidity=dht22_dat[0]*256+dht22_dat[1];9 u/ Y) n4 b# d) `7 ^( n _temperature=dht22_dat[2]*256+dht22_dat[3];7 B$ C; T" I' ]1 O3 ^* D0 H: o return true; } return false;0 J J: x, v+ m D) | } 首先,您需要定义传感器所连接的引脚。 + V) v8 j5 B+ }( n/ T 现在您可以使用传感器的功能。 #ifdef MesureDHT22void mesuresDHT22(){ CaptDHT.readData(); TemperatureAir = CaptDHT.ReadTemperature(CELCIUS); HumiditeAir = CaptDHT.ReadHumidity();}#endif2.亮度传感器 TSL2561 5 V* @' d) K& D- v \ 基于TSL2561的亮度传感器,可测量0.1至40000 Lux的亮度。它与微控制器通信。 电源:2.7至3.6 VDC TSL2561.h /** mbed library program * Luminosity sensor -- LIGHT-TO-DIGITAL CONVERTER (light intensity to a digital signal output)& K8 P; C+ e% `6 K9 R: T) L K0 l * TSL2561 by Texas Advanced Optoelectronic Solutions Inc. *6 @9 W+ A" s2 i/ y- ?( J 3 j, R( N4 v( o+ h" w4 o1 _3 r( h #ifndef TSL2561_H #define TSL2561_H #include "mbed.h"" f$ A3 {! C6 U( a$ B // Luminosity sensor, TSL2561. G: X1 a9 Z# O! k' Y // Address b7=0,b6=1,b5=1,b4=1,b3=0,b2=0,b1=1, b0=R/W #define TSL2561_ADDRESS_GND (0x29 << 1)/ u; Y8 s3 R# w2 A2 b& K: E5 U' j #define TSL2561_ADDRESS_FLOAT (0x39 << 1)+ ^ ?- k, @7 e! y, o# c# |1 A #define TSL2561_ADDRESS_VDD (0x49 << 1) ////////////// Registers //////////////////////////////////6 M4 f7 E! w3 e) x U) e6 _: E, [- S // Register definition( J9 H# e G0 |4 P: X" X4 } #define TSL2561_CONTROL 0x00 #define TSL2561_TIMING 0x01) a) E" f/ h! M/ I) U8 a #define TSL2561_THRESHLOWLOW 0x02 #define TSL2561_THRESHHIGHLOW 0x04- ]6 D" S# b2 N" b9 v. O #define TSL2561_INTERRUPT 0x06 #define TSL2561_CRC 0x08$ ?- V1 G: a' ^! D; ~0 U #define TSL2561_ID 0x0A# h/ Z/ ~1 R! _8 C) E4 g9 A #define TSL2561_DATA0LOW 0x0C #define TSL2561_DATA0HIGH 0x0D5 e5 z. [* s5 `6 g3 G* E #define TSL2561_DATA1LOW 0x0E #define TSL2561_DATA1HIGH 0x0F ////////////// TIMING PARAMETER /////////////////////////// #define TIMING_GAIN_1 (0UL << 4) #define TIMING_GAIN_16 (1UL << 4)0 x8 S! T+ V0 l, M( f( Z; \ #define TIMING_TIME_13R7 (0x0)" H5 \- v0 _5 n( u0 |3 y* J2 g ]6 C #define TIMING_TIME_101 (0x1). v4 J& X7 {- s, l #define TIMING_TIME_402 (0x2)' a$ n: E3 `" t# i+ ^# S5 l! f #define TIMING_TIME_MANU (0x3)3 F w* E) ~4 `8 f- v5 \8 I& G #define TIMING_DEFAULT (TIMING_GAIN_1 + TIMING_TIME_402) ////////////// ID /////////////////////////////////////////* t7 z7 y% W# q #define I_AM_TSL2561 0x50 #define REG_NO_MASK 0x0F ////////////// COMMAND //////////////////////////////////// #define CMD_CMDMODE (1UL << 7) #define CMD_CLEAR (1UL << 6) #define CMD_WORD (1UL << 5)2 g$ u$ m' j3 w/ E #define CMD_BLOCK (1UL << 4)3 a; _; F0 N) b# e3 A #define CMD_SINGLE (CMD_CMDMODE)% o$ j( J0 |* ~2 y" h" A- l% J #define CMD_MULTI (CMD_CMDMODE + CMD_WORD) /** Interface for Luminosity sensor, TSL2561 * @code * #include "mbed.h", c! k5 c" t8 e) ~ * #include "TSL2561.h" * * // I2C Communication0 W1 ]# [ f. M9 z" }% y * TSL2561 lum(dp5,dp27); // TSL2561 SDA, SCL * // If you connected I2C line not only this device but also other devices,& A+ }* S2 w3 c# d$ @7 L$ }# Q * // you need to declare following method. * I2C i2c(dp5,dp27); // SDA, SCL7 O6 U/ D3 Y5 c0 O3 F * TSL2561 lum(i2c); // TSL2561 SDA, SCL (Data available every 400mSec) * * int main() {;- F! T$ p9 h6 G9 N * while(true){4 h7 L; S: {4 _" S9 x- h( w * printf("Illuminance: %+7.2f [Lux]\r\n", lum.lux());7 V" T4 H# ]# B! W+ g' x * wait(1.0); * }# s4 F5 Q* f6 I8 g, S2 a * } * @endcode */ class TSL2561. U3 C. x2 J- Y( A { public: /** Configure data pin * @param data SDA and SCL pins TSL2561(PinName p_sda, PinName p_scl);+ R! y3 g6 s4 A% C, u3 a: a2 G- X TSL2561(PinName p_sda, PinName p_scl, uint8_t addr);/ g( R4 t0 j# ?' J u2 m, P) A$ Y' v /** Configure data pin (with other devices on I2C line) * @param I2C previous definition */ TSL2561(I2C& p_i2c); TSL2561(I2C& p_i2c, uint8_t addr);5 Y: y( O/ d- C, O& C- |5 y /** Get approximates the human eye response * in the commonly used Illuminance unit of Lux * @param none * @return Lux8 {4 ^8 w. r9 W& H4 p& A */9 I' |! p; g" b float lux(void); /** Set timing register * @param timing parameter& d! U, B O( ?, I# X6 } * @return timing read data; O. g. I U. i) q [1 l# z3 u */ uint8_t set_timing_reg(uint8_t parameter); /** Read timing register * @param timing parameter * @return timing read data. m/ _" |9 b3 n6 L* a0 T* I. f$ Z */3 O1 m( h, p* s; c% Y5 Y uint8_t read_timing_reg(void); /** Set I2C clock frequency * @param freq.9 O8 K+ F! U$ l0 N- A * @return none */% Q. p2 z. Z+ ~ void frequency(int hz);" C' f7 K# q' i /** check Device ID number * @param none * @return TSL2561 = 1, others 02 _( t* D- q/ ` */& b: U2 r6 h, v8 S8 F) z3 N9 C uint8_t who_am_i(void);& Z- Y$ n1 q+ i /** Read ID and Revision Number * @param none" T( ?4 P, x( Z1 n$ d) u * @return ID + REVNO */ uint16_t read_ID(void); /** Power Up/Down * @param none * @return none m4 r5 o% L" K! _( i6 k4 @9 s */ void power_up(void); void power_down(void);) u5 D6 O4 g: H protected:3 i* H" n, p0 G/ D5 E x I2C *_i2c_p; I2C &_i2c; void init(void); private:9 a0 I# X/ r2 t3 k bool TSL2561Initialised; uint8_t TSL2561_addr;+ z. T, g9 y9 T1 g uint8_t dt[4]; uint32_t ch0;1 t: V! `+ }6 w' A, ]+ t6 p uint32_t ch1;. ?3 W. c9 k) y1 @) m int8_t gain;$ X# v5 l$ @ o0 s( s uint8_t id_number;( A1 b/ X9 A" V" k% w% F double integ_time; };" ~( ^. a6 R. O, i1 |/ j- E #endif // TSL2561_H TSL2561.cpp /*1 ]7 I- }# O/ G! M* mbed library program: r& K# i! t6 P- b0 I* x * Luminosity sensor -- LIGHT-TO-DIGITAL CONVERTER (light intensity to a digital signal output)& W2 `: }( d$ |5 K$ a& C& Y$ f# s+ z * TSL2561 by Texas Advanced Optoelectronic Solutions Inc.( y+ O! i F3 \ *2 U0 O& _3 R; V& k * Created: Feburary 21st, 2015& n4 s$ q( ]; N! I * Revised: August 23rd, 20170 N" L8 u$ t4 c( c9 l: t */ Q& X! Q3 T* e #include "TSL2561.h" TSL2561::TSL2561 (PinName p_sda, PinName p_scl); X$ `' U' m7 ~& D$ q: F : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) { TSL2561_addr = TSL2561_ADDRESS_GND; init();} ^+ |- n4 }# o3 Z$ P! | TSL2561::TSL2561 (PinName p_sda, PinName p_scl, uint8_t addr)# e3 a! H" \5 c' w* j : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) {1 A! H4 h1 F0 @4 z$ `8 W4 N TSL2561_addr = addr; A6 o# [: d; s$ K init();! }9 X* {7 N6 @/ {/ v: M# K } TSL2561::TSL2561 (I2C& p_i2c)' |/ k, h7 k- z3 O( E : _i2c(p_i2c)1 v) O% W$ N! h; [ {9 T& s$ U% m8 x. g, ?2 Z ^ TSL2561_addr = TSL2561_ADDRESS_GND; init(); } TSL2561::TSL2561 (I2C& p_i2c, uint8_t addr)) a8 f" y& b% a7 N3 N7 I. O : _i2c(p_i2c) { TSL2561_addr = addr;0 Z2 B4 m( q) s7 x7 { init();8 q3 a& [9 A; _! O% B } /////////////// Read Lux from sensor ////////////////////// /*# ]$ [" K1 C0 D3 q* U5 ^. U+ U9 c/ J For 0 < CH1/CH0 < 0.50 Lux = 0.0304 x CH0-0.062 x CH0 x ((CH1/CH0)1.4)+ }) R, X! V) V0 N# s+ R: t For 0.50 < CH1/CH0 < 0.61 Lux = 0.0224 x CH0-0.031 x CH1 For 0.61 < CH1/CH0 < 0.80 Lux = 0.0128 x CH0-0.0153 x CH1 For 0.80 < CH1/CH0 < 1.30 Lux = 0.00146 x CH0-0.00112x CH1 For CH1/CH0 > 1.30 Lux = 0/ [9 m+ }8 L+ e */( H. A0 M6 @# J. v float TSL2561::lux()( D; Q, j5 K. F { double lux0, lux1; double ratio; double dlux; dt[0] = CMD_MULTI + TSL2561_DATA0LOW; _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);1 x( L# |) { b# o$ \( J! w2 t, g _i2c.read(TSL2561_addr, (char *)dt, 2, false);! x* |/ }& d+ r$ x7 C3 [" W ch0 = dt[1] << 8 | dt[0]; dt[0] = CMD_MULTI + TSL2561_DATA1LOW;7 J5 ^! y+ P- V' i) |/ [ _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);% s/ N9 ]) D0 a3 U. n9 E: x _i2c.read(TSL2561_addr, (char *)dt, 2, false); ch1 = dt[1] << 8 | dt[0];( I# c" L, [2 G, { if (ch0 == 0xFFFF) { S! M' k8 l6 } F; T; w return 2500.0; } lux0 = (double)ch0;$ P: }) B- @1 j) {* k6 S lux1 = (double)ch1; ratio = lux1 / lux0; read_timing_reg(); lux0 *= (402.0/integ_time); lux1 *= (402.0/integ_time);6 y3 W( y/ N! @* C lux0 /= gain;' V4 ^5 I! `0 v% B lux1 /= gain;( r J& r- M: `+ b if (ratio <= 0.5) { dlux = 0.03040 * lux0 - 0.06200 * lux0 * pow(ratio,1.4);- s Z( I. g2 c3 u& ] } else if (ratio <= 0.61) { dlux = 0.02240 * lux0 - 0.03100 * lux1;" o. C$ C# m) j+ N: U } else if (ratio <= 0.80) {5 O# X8 m. L. r! M u) u dlux = 0.01280 * lux0 - 0.01530 * lux1;( p& p; F$ T& o* d. E. h* X# x* v } else if (ratio <= 1.30) { dlux = 0.00146 * lux0 - 0.00112 * lux1; } else {; h! h2 K0 I, B8 y! P dlux = 0; } return (float)dlux;6 m5 l0 N& W- `7 J } /////////////// Initialize ////////////////////////////////1 i5 G6 C8 Z& H void TSL2561::init()$ o. [4 E$ w9 v { _i2c.frequency(100000); power_up();' p% N5 w9 c- s9 q2 h set_timing_reg(TIMING_DEFAULT); }2 C* B2 o+ l: {, p, D/ H+ N) I /////////////// Timing Register ///////////////////////////! D' z; g9 z B2 H+ C/ e5 Z& I uint8_t TSL2561::set_timing_reg(uint8_t parameter) {$ M: }% K: Y$ ]8 A. w! C, Z& b- { dt[0] = CMD_SINGLE + TSL2561_TIMING; dt[1] = parameter;/ S" n3 N% _6 O8 U _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);1 U# R& e3 |1 V. ] R dt[0] = CMD_SINGLE + TSL2561_TIMING;1 c) H1 @6 Z6 F _i2c.write((int)TSL2561_addr, (char *)dt, 1, true); _i2c.read(TSL2561_addr, (char *)dt, 1, false);" O i7 w t1 ` return dt[0]; }0 Z$ Q3 \5 u# r( `! M" { uint8_t TSL2561::read_timing_reg(void)5 E( e- V$ D! M8 R$ N, F {5 R6 O/ v1 j$ [" w9 H uint8_t i; dt[0] = CMD_SINGLE + TSL2561_TIMING;: E' P s) o# w, R; f+ s3 d _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);7 w6 t, t1 h; q/ ~8 D _i2c.read(TSL2561_addr, (char *)dt, 1, false);+ {- m0 w+ L4 [: h+ c if (dt[0] & TIMING_GAIN_16){" m: e- } f0 n gain = 16; } else { r, c! [5 n. _7 E+ O( C gain = 1; }( k8 i. E& S5 p# U }" ^% y6 S: V1 N3 Z/ y+ n- R. { i = dt[0] & 0x3; switch (i) { case 0:6 B) K1 f. K1 y, m# n6 d! D integ_time = 13.7;. [: L# X0 G% b1 r) X$ K: S& w break; case 1: integ_time = 101.0; break; case 2: integ_time = 402.0; break; default:- J8 `8 i6 j- Z integ_time = 0; break; } return dt[0];}( E$ J8 N4 J% G9 M2 k/ Q0 | /////////////// ID ////////////////////////////////////////+ ?1 N1 {! K/ G# L; A uint16_t TSL2561::read_ID()* I1 m% ~3 _( I% h/ d {; e/ p$ H3 @& b7 Y) Y6 K dt[0] = CMD_SINGLE + TSL2561_ID;% ]: _# j: x! _4 ]7 {. l8 ] _i2c.write((int)TSL2561_addr, (char *)dt, 1, true); _i2c.read(TSL2561_addr, (char *)dt, 2, false);! _4 t6 \: G. [- w3 s id_number = dt[0] << 8 | dt[1];( {' h$ y5 `- ~ return id_number; } uint8_t TSL2561::who_am_i()9 Z$ \* z, P* Y, ~& H { read_ID(); if ((id_number >> 4) == I_AM_TSL2561) {. q* ]% I3 t# [0 |6 N4 p' A return 1; } else {, R8 v* H- J2 p4 G* B: x return 0; }# l5 j5 D8 b' E' P+ e4 H2 n& L } /////////////// Power ON/OFF //////////////////////////////$ j3 s7 C+ v7 y- C" l0 G9 k void TSL2561::power_up()! s8 W1 @) F' {5 | { dt[0] = CMD_SINGLE + TSL2561_CONTROL; dt[1] = 3; _i2c.write((int)TSL2561_addr, (char *)dt, 2, false); } void TSL2561::power_down()# \- L& x& F* z0 g* S {' a4 C" X; c- x$ r& _) Z6 ?& v: p1 r dt[0] = CMD_SINGLE + TSL2561_CONTROL;- ^1 q9 ~3 |% k- b5 K3 ?0 P/ D dt[1] = 0; _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);! [3 V( k# @' z; b" e }" w) s1 x( A" { /////////////// I2C Freq. /////////////////////////////////2 ~( i: t4 A7 r1 i void TSL2561::frequency(int hz) {& w! [/ g. q! y0 d9 g _i2c.frequency(hz);9 ~5 E( ?+ V9 d$ H3 u2 o# X ` } 3 T/ v0 \9 r* o. w( M# a 对于此传感器,您需要选择用于营养和I2C的引脚(SCA,SDL) 3. RGB传感器 TCS34725 / k4 o# A( ^- G; f( c$ ], a 该模块用于检测光源或对象的颜色。它基于TCS34725传感器,通过I2C端口进行通信。传感器用于检测RGB颜色和白色。 电源:3.3至5 Vdc I2C协议 { CaptRGB.getRawData(&Red, &Green, &Blue, &Clear); & \ U0 x: N# N: k2 o( {- V uint32_t Sum = Clear; RedValue = Red; RedValue /= Sum; 1 n, E) ?+ K* @7 g& j8 s GreenValue = Green; GreenValue /= Sum; BlueValue = Blue; BlueValue /= Sum; RedValue *= 256; GreenValue *= 256; BlueValue *= 256;}#endif 4.地面温度 温度探针 温度探头是一种精确的防水温度传感器,工作温度范围为-40℃至105℃。 与其他温度传感器不同,它可以精确地报告温度,并且不需要任何其他组件。 5.地面湿度 传感器土壤水分 我们的土壤湿度传感器通过电容式传感测量土壤水分,而不像其他传感器那样测量电阻传感 该模块包括一个板载稳压器,工作电压范围为3.3~5.5V。 // Mesure de l'humidité du sol#ifdef MesureHumiditeSolvoid mesureHumiditeCSMS() { . l2 J/ l \ a/ t- s& Z float a = -0.005312; . V8 j" E/ q1 l$ r& Y float b = 0.92265; 2 Z ^+ c5 C7 K7 j* _ float SommeMesures = 0; for(int i = 0; i < NombreDeMesures; i++) { HumiditeSol = CSMS.read(); HumiditeSol = (1/a)*(HumiditeSol-b); ( @, H3 _& i6 l7 e: s4 \ if (HumiditeSol < 0) HumiditeSol = 0; if (HumiditeSol > 100) HumiditeSol = 100; SommeMesures += HumiditeSol; wait_ms(DelaiEntreMesures); } SommeMesures /= NombreDeMesures; & t6 C- z. A# g- Y* A6 I8 s: S+ ] HumiditeSol = SommeMesures; }; }+ p3 h x" l$ u" p' v" z #endif 6. STM32 Nucleo-32 L432KC STM32 Nucleo-32 L432KC 所有传感器都连接到此卡,如下所示。 1)守则 为了开发这个的项目,我们使用了Mbed编译器,这是一个互联网上的软件,允许我们在任何计算机上工作,非常有用,在家里就可以完成项目。 Mbed编译器 我们开发了一个非常结构化的代码,以便能够非常轻松地进行调试。使用了一些#define和#ifdef,因此您可以通过仅在头文件上注释一行来轻松关闭传感器,该头文件包含许多全局变量,例如引脚名称,其中连接传感器以快速更改它。 Mbed的优势在于每个传感器都有许多的库。 程序将记录每个传感器的值,然后将它们显示在LCD屏幕上,并使用Sigfox发送这些记录以便稍后显示。 Mapping.h #ifndef __MAPPING_H__#define __MAPPING_H__ // Commenter pour désactiver certaines mesures ou fonctions #define MesureDHT22 #define MesureIntensiteLumineuse //I2C #define MesureRGB //I2C: h: r" P" n6 z6 w- Z! }: X9 \, E #define MesureTemperatureSol #define MesureHumiditeSol #define AffichageOLED #define Debug //#define SigfoxActif% }* s* n P4 Y o //#define DeepSleepEnable //Moyenne de mesures+ j" A2 g! k% z' i$ P" ~* u #define NombreDeMesures 100 e7 B' `+ \( Y% [" U& Z #define DelaiEntreMesures 25 // exprimé en ms; M/ \1 s8 v9 u* w( q& D; J, s //Luxmètre #define COEF_TSL 10% I1 ]. J" v' e g! m( L //CSMS (Humidite du sol)( @7 `3 W) D8 R0 B' \8 \ #define pinCSMS A04 [; t( O1 J+ V7 k- ^ //DS1820 (Temperature du sol) #define pinDS1820 D12 //DHT22 (Temperature et humidite de l'air)7 k. Y- V/ b. t H5 h- w #define pinDHT22 D9 //PA_8& W6 C, F9 S, h3 ` #define modeleDHT AM2302 //I2C1 [$ f/ f9 D$ `% @. s9 i #define pinSDA D0 #define pinSCL D1 //Sigfox/ n [. E* q3 x8 T #define SigfoxTX D5 #define SigfoxRX D4- b" ~6 x% o" L; k; T/ y O8 B2 { /*#define SigfoxTX A7 #define SigfoxRX A2*/ #define DelaiEnvoi 30 //Délai entre 2 envois en secondes //Deep Sleep7 v/ l/ b" M% x3 Y #define DureeDeepSleep 3000 //Duree en secondes //Ecran OLED #define pinCS D6 #define pinRS D3. c/ p# t' W! N" K: h } #define pinDC A5 #define pinCLK A4' c- |' Z+ Y. f. ~7 M #define pinDATA D2& c. m Y2 _ b# {9 I' ] #endif5 B% A ~! U% R) y% f! s Main.cpp #include "mbed.h" #include "mapping.h" #include "ssd1306.h"2 |. e" a! Q! v) k) e1 K #include "standard_font.h"" G8 o' F) W F #include "bold_font.h" #include "DHT.h" #include "TSL2561.h" #include "Adafruit_TCS34725.h" #include "DS1820.h" #include "WakeUp.h" " S# @2 H/ p0 [ F- k /************************************ * Declaration des objets ***********************************/ #ifdef SigfoxActif+ T" f. I1 _$ N. {- i9 p% A1 e Serial Sigfox(SigfoxTX, SigfoxRX);' W& @# B) O9 @* X2 y5 S #endif #ifdef AffichageOLED K w) {/ `! i- Q SSD1306 oled(pinCS, pinRS, pinDC, pinCLK, pinDATA);% x* H. ]0 ?% {1 M, d' ^% p #endif* e/ n- a6 L& k j+ q #if defined(MesureIntensiteLumineuse) || defined(MesureRGB). i/ Q, w+ j% n+ F* i4 S, y I2C i2c(pinSDA, pinSCL); #endif #ifdef MesureIntensiteLumineuse3 f6 v" W$ }4 d0 V; ] q7 e6 } TSL2561 Lumiere(i2c,TSL2561_ADDRESS_FLOAT);: m) z1 i6 F, h8 Q. w4 e #endif #ifdef MesureRGB Adafruit_TCS34725 CaptRGB(&i2c, TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);1 O/ e: Q9 D- t# y7 [. @" U #endif #ifdef MesureDHT22 DHT CaptDHT(pinDHT22, modeleDHT);$ A% ]8 L; w) m #endif #ifdef MesureTemperatureSol DS1820 TemperatureSonde(pinDS1820);' F$ E' `+ S, ]+ t #endif" f. k/ |9 O; ~3 e0 A X$ g! @ #ifdef MesureHumiditeSol AnalogIn CSMS(pinCSMS);; \. r4 C2 R8 j3 K6 f \! P3 r #endif DigitalOut myled(LED1);9 ^+ c1 E+ S/ E7 z #ifdef Debug Serial pc(USBTX,USBRX); #endif+ j9 Z! b( T8 R! N/ b! F /* #ifdef DeepSleepEnable/ R, E; F0 J2 T) ]0 N7 q0 d WakeUp ModeVeille; ModeVeille.calibrate(); #endif */ /************************************8 E* ^) Y3 L" Y; a9 Z/ G * Declaration des variables globales+ g9 { X: y2 g9 ^3 O" X( s$ T ************************************/& N$ h' F. n. z: T int TemperatureAir, HumiditeAir; int RGB;# Z3 t ?. y/ b6 K5 W$ |9 @" A9 y float Lux;1 ^$ q1 {. l- d3 I* T: I float TemperatureSol;9 r6 O. ^9 D( w# e) b float HumiditeSol;; Z9 l9 K" q1 o5 _6 ~4 N; j3 o float RedValue, GreenValue, BlueValue;7 _/ E o. [3 O' G uint16_t Clear, Red, Green, Blue; /************************************ * Fonctions de mesures ou affichage ***********************************/ // Fonction permettant l'affichage des mesures sur l'ecran/ y2 ~' X7 R/ D/ g+ w3 w) ~' ^ #ifdef AffichageOLED) X/ q; L ^6 R6 n void affichageOLED(){7 g( i1 G% J/ k. ^2 w, s% S oled.clear(); oled.set_font(bold_font, 8); oled.printf("rojet AGRAL\r\n");5 N8 H- @4 y- y% O8 K( f oled.printf("\r\n");3 s$ y0 M# @9 Q. r9 S oled.set_font(standard_font, 6); #ifdef MesureDHT229 n# c4 c9 R1 w- E& \, R9 J: Y/ E oled.printf("Tempe Air : %d\r\n", TemperatureAir);* T0 e9 ^8 r0 |4 \9 h0 L3 r* r) g oled.printf("Humidite : %d %%\r\n", HumiditeAir);: C9 @# X ^' L2 r& A4 r2 D* _( I #endif( ^7 Q( A- Z/ x; o6 j #ifdef MesureIntensiteLumineuse oled.printf("Lux : %.0f lux\r\n", Lux);9 A; G- c6 t7 L0 Q# U #endif #ifdef MesureRGB oled.printf("RGB : %d %d %d\r\n", int(RedValue),int(GreenValue),int(BlueValue)); #endif #ifdef MesureTemperatureSol- s% Y. v8 x4 Y" s oled.printf("Temp Sol : %3.0f\r\n", TemperatureSol); #endif #ifdef MesureHumiditeSol oled.printf("Hum Sol : %.0f %%\r\n", HumiditeSol); #endif0 g/ s+ y' h6 `( S3 I oled.update(); }0 P b! _4 Q" N( U #endif3 X8 l$ M. o# a3 C4 S #ifdef Debug& A0 C' ?2 |) ]6 R+ V' P @# C; p void debugPrintf(void){! ^2 R8 P* s7 ?. l7 @3 X( E #ifdef MesureDHT22; S- M2 i5 G: `; v) T pc.printf("Temperature : %d\r\n", TemperatureAir); pc.printf("Humidite : %d %%\r\n", HumiditeAir);* o1 I8 j% v# o2 Y; C4 @0 N/ I #endif #ifdef MesureTemperatureSol pc.printf("Temp Sol : %3.0f\r\n", TemperatureSol); #endif #ifdef MesureHumiditeSol pc.printf("Hum Sol : %.0f %%\r\n", HumiditeSol); #endif' M( z- r. }9 M1 ]5 L/ q #ifdef MesureIntensiteLumineuse2 y! }+ u+ b1 h1 K3 h% { pc.printf("Lux : %.0f lux\r\n", Lux);. b) U3 W/ x6 \0 v+ _; x2 p #endif #ifdef MesureRGB pc.printf("RGB : %d %d %d\r\n", int(RedValue),int(GreenValue),int(BlueValue));) L& n! @( m3 V+ `, l3 W #endif #ifdef SigfoxActif pc.printf("\r\n"); pc.printf("AT$SF=%02x%02x%04x%02x%02x%02x%02x%02x\n\r", (int)TemperatureAir, (int)HumiditeAir, (int)Lux, (int)TemperatureSol, (int)HumiditeSol, (int)RedValue, (int)GreenValue, (int)BlueValue);! z% [4 b$ t t% X) u8 \ pc.printf("\r\n"); #endif& r1 C" B& O8 x1 T+ o) z pc.printf("---------------------------------------------------\r\n"); } #endif+ J1 ~9 g9 `+ p' J // Mesure de la température et de l'humidité de l'air# m. i5 L# i: n #ifdef MesureDHT225 V: k: d0 a6 S void mesuresDHT22(){ CaptDHT.readData(); TemperatureAir = CaptDHT.ReadTemperature(CELCIUS);* Y* B2 i1 n1 `& H8 L HumiditeAir = CaptDHT.ReadHumidity(); } #endif // Mesure du spectre de la lumière; N% O* m/ Q0 Y# J: t- D #ifdef MesureRGB6 z+ M A8 s3 b$ x4 b void mesureRGB(){4 m9 w" u) @2 j CaptRGB.getRawData(&Red, &Green, &Blue, &Clear); uint32_t Sum = Clear;$ B7 P# M0 i) ^+ F" E RedValue = Red; RedValue /= Sum; GreenValue = Green; GreenValue /= Sum; BlueValue = Blue; BlueValue /= Sum;6 y% Y. o/ K/ _3 p1 W3 ~2 Q RedValue *= 256; GreenValue *= 256; BlueValue *= 256;4 c' F% n L5 r, q8 ~9 z }0 S! M# I6 o; ~: R! G) _% k #endif // Mesure de l'intensité lumineuse en Lux! v, }! B7 t) x- f* G3 p$ l #ifdef MesureIntensiteLumineuse' [9 G# _4 R2 T# e( d* Y1 i9 `/ f" T void MesureLux(){) C/ p0 ]( u" J% J ? //int i;; f; m4 Z$ j" }" o+ I! K Lux = 0; for(int i = 0; i < NombreDeMesures; i++){6 K! q$ `3 x( l, W Lux += COEF_TSL*Lumiere.lux();8 O( S M" y3 X' | wait_ms(DelaiEntreMesures); } Lux /= NombreDeMesures;1 B$ x7 D" w' O8 R5 `, \0 b! i } #endif // Mesure de la temperature du sol #ifdef MesureTemperatureSol void mesureTemperatureSonde(){" U/ u9 |' W9 ?8 E y- X6 ~9 L1 O TemperatureSonde.convertTemperature(true, DS1820::all_devices);# U t; P" b; U" M$ s5 \- f c) f TemperatureSol = TemperatureSonde.temperature();% ]' k! j$ I6 [! l } #endif // Mesure de l'humidité du sol #ifdef MesureHumiditeSol void mesureHumiditeCSMS(){6 A1 u% }8 \; j' J float a = -0.005312;3 L8 r7 \2 w; D, m+ v, u& ? float b = 0.92265;; R; u0 u2 V2 |. l( `9 n float SommeMesures = 0; for(int i = 0; i < NombreDeMesures; i++){, v. K7 A! Q8 Q* l+ P3 `" X HumiditeSol = CSMS.read();( E1 i _* F/ y$ ~; f: f HumiditeSol = (1/a)*(HumiditeSol-b);4 |5 P2 |$ I- O4 G( P: S: Q# _ if (HumiditeSol < 0)4 J' k1 E5 ^; b" @( J HumiditeSol = 0;' l$ Z. Z& N5 {% l0 a& s! _* V" ]" _ if (HumiditeSol > 100) HumiditeSol = 100;0 a* ]' y+ a) Q, c$ l `8 A' d U SommeMesures += HumiditeSol; wait_ms(DelaiEntreMesures);5 [9 ~: s3 v2 F3 d5 l; o3 h }2 e$ J$ X% x+ P6 V8 v6 @. G# D SommeMesures /= NombreDeMesures;+ ?6 u1 v) n2 Z/ } HumiditeSol = SommeMesures; }8 d! ~& |2 M6 U i6 L1 g #endif6 i! @$ J' y7 _, @ void ClignotementLED(int duree){7 J6 p+ J' U+ v: q+ J& w myled = !myled; wait_ms(duree); myled = !myled;8 X& w$ h/ [1 f N wait_ms(duree);* e X k% C, `$ M myled = !myled;% k& ~' H/ h8 _$ f wait_ms(duree); myled = !myled; wait_ms(duree); } b/ \# Z/ d" B& m8 [9 A/ A #ifdef AffichageOLED/ O2 F/ h/ E8 S( N4 _, T void eteindreEcran(){ oled.clear(); }) A+ j5 f, y& b! @( d/ W #endif /*********************************** * Fonction main. e% z7 c6 N9 P: F, w ************************************/ int main()$ j/ ]( e4 |3 i& m4 |7 s" b" i8 v {8 N, s. u5 y+ [/ v i0 q& x // Initialisation de l'écran #ifdef AffichageOLED oled.initialise(); oled.set_contrast(255);% m2 D* g; z; {# D1 e0 ` oled.clear(); #endif while (1)" x/ A' K9 j+ i O4 S S( l9 ~. p1 I { #ifdef MesureDHT22 mesuresDHT22(); #endif #ifdef MesureIntensiteLumineuse MesureLux(); #endif7 Y+ C2 ~! g' W7 e9 D, C3 G3 X$ } #ifdef MesureRGB3 F) Q9 Z g2 v4 U mesureRGB();3 W& m, ?, F" t- n' G# g! K #endif' s: r. k3 m3 S* r #ifdef MesureTemperatureSol% r# m/ ~- Q1 w1 r mesureTemperatureSonde();' ?: c% R' \8 F; I8 [8 B #endif #ifdef MesureHumiditeSol mesureHumiditeCSMS(); #endif8 G6 n( T# N0 P- ]9 t$ x #ifdef AffichageOLED affichageOLED(); #endif #ifdef SigfoxActif; F( N; \/ M3 A" ~9 u5 s+ n5 ` Sigfox.printf("AT$SF=");9 d% E& r" j a0 L. O8 _ //Sigfox.printf("15290107141f675e47");0 T- h. f# I- x/ W1 p //Sigfox.printf("65"); //Sigfox.printf("%02x%02x%04x%02x%02x%02x%02x%02x", (int)TemperatureAir, (int)HumiditeAir, (int)Lux, (int)TemperatureSol, (int)HumiditeSol, (int)RedValue, (int)GreenValue, (int)BlueValue); Sigfox.printf("%02x%02x%04x%02x", (int)TemperatureAir, (int)HumiditeAir, (int)Lux, (int)HumiditeSol);0 \- L# N. P0 r0 ^( p Sigfox.printf("\n\r");2 i$ Q- W# i- v( _+ p* t ClignotementLED(40); //On indique quand un message est envoyé par Sigfox #endif; W8 ? F5 v& T! Z #ifdef Debug debugPrintf(); #endif #ifdef SigfoxActif5 N$ W/ s1 b1 l- [$ Y6 l5 M wait(DelaiEnvoi); #endif 0 w: q+ P, |& r2 L #ifdef DeepSleepEnable wait(2);' G- ^3 M/ @: v eteindreEcran(); ClignotementLED(40); //ModeVeille.set(DureeDeepSleep);' f4 z: @3 S+ }- ]* e WakeUp::set_ms(30000);# g" d% m) B% I& y6 {6 A deepsleep(); #endif # N! \4 U3 ?. d$ e //NVIC_SystemReset(); }% R b; N) e |; O& ~% E$ K4 W2 n }5 w8 V, [7 j8 r$ P8 z3 R 2)Ubidots Ubidots是一种物联网平台,通过易于使用的界面,可以开发和部署互联网连接的应用程序和解决方案。借助REST API,Cloud Plateform能够接收和处理HTTP请求。 变量 变量对应于封装到JSON字符串中的数据。变量必须与传感器的数据具有相同的名称,以便很好地分析数据。因此,我们创建了与传感器数据一样多的变量。 Ubidots的变量 3)图形界面 为了开发我们的项目,我们使用Ubidots教育云数据库,该数据库收集来自Sigfox的所有传感器数据。对Json脚本的所有值都会被自动检测到,然后我们只需要放置一些小部件并告诉哪些数据与之相关。 我们在Ubidots项目的仪表板 4)印刷板 最后,我们选择了EASYEDA来创建我们的PCB.EASYEDA也是一个在线共享工具,每个成员都可以编辑项目以及任何使其成为私有或公共的计算机。完成shematic后,软件将生成一个PCB,您必须找到将传感器引脚连接到电路板上引脚的正确方法。 我们项目的电路板示意图 原理图 E* I8 g5 s+ q. M, OPCB 8 J! F$ O* J, k1 w$ D! C |