Grüße an alle Habr-Leser! Der heutige Artikel befasst sich mit einem Temperatur-, Feuchtigkeits- und Atmosphärendrucksensor mit langer Batterielebensdauer. Der Sensor arbeitet mit dem Mikrocontroller nRF52832 (
Datenblatt ). Um Temperatur, Luftfeuchtigkeit und Luftdruck zu erhalten, wurde das
Datenblatt BME280 Sensor -
verwendet . Der Sensor wird mit CR2430 / CR2450 / CR2477-Batterien betrieben. Der Verbrauch im Übertragungsmodus beträgt 8 mA, im Schlafmodus 5 mA. Also über die Bestellung.
Dies ist ein Arduino-Projekt, das Programm ist in der Arduino-IDE geschrieben. Die Adafruit Industries-Bibliothek wird zum Betreiben des
BME280-Sensors -
Github-Sensoren | verwendet
Github BME280 . Für die Arbeit mit nRF52832-Karten verwendete die Ardeino IDE das Sandeep Mistry-Projekt -
github . Die Datenübertragung zum Controller des Smart House erfolgt nach dem Mysensors-Protokoll - Github-
Boards |
Protokoll | Bibliothek .
Die Sensorplatine wurde im Diptrace-Programm entwickelt. Die Abmessungen der Platine betragen 36,8 mm x 25 mm.

Liste der verwendeten Komponenten- C1 - cap0603 100nF
- C2 - cap0603 100nF
- R1 - res0603 332
- R2 - res0603 85b
- R3 - res0603 113
- R4 - res0603 912
- R5 - res0603 113
- R6 - res0603 512
- R7 - res0603 512
- RGBL1 - led0805 rgb
- SWD - PPHF 2x3 6p 1,27 mm
- U1 - YJ-16048 nRF52832
- U2 - BME280
- ANSCHLUSS - Taktschalter KLS7-TS5401
- RESET - Uhrentaste KLS7-TS5401
- Batteriehalter KW-BS-2450-2-SMT
- Schalter Dsc0012
Die Gebühr wurde über
jlcpcb.com bestellt - $ 2 für 5 Stück in jeder Farbe.

Link zum Archiv mit Gerber-DateienDer Sensor arbeitet gemäß dem Mysensors-Protokoll. Das Hinzufügen eines Geräts zum Mysensors-Netzwerk ist einfach. Schauen wir uns das Beispiel dieses Sensors an. Ich werde die Erklärung des BME280-Sensorcodes weglassen. Bei der Arbeit mit dem Mysensors-Netzwerk ändert sich nichts.
#define MY_DEBUG // #define MY_RADIO_NRF5_ESB // ( rfm69, rfm95, nrf24l01, nrf51-52) #define MY_RF24_PA_LEVEL (NRF5_PA_MAX) // #define MY_DISABLED_SERIAL // #define MY_PASSIVE_NODE // ( mysensors), PASSIVE , , , #define MY_NODE_ID 1 // #define MY_PARENT_NODE_ID 0 // //#define MY_PARENT_NODE_IS_STATIC // PARENT_NODE //#define MY_TRANSPORT_UPLINK_CHECK_DISABLED // #include <MySensors.h> // - MySensors #define TEMP_CHILD_ID 0 // #define HUM_CHILD_ID 1 // #define BARO_CHILD_ID 2 // #define CHILD_ID_VOLT 254 // MyMessage voltMsg(CHILD_ID_VOLT, V_VOLTAGE); // MyMessage temperatureMsg(TEMP_CHILD_ID, V_TEMP); // MyMessage humidityMsg(HUM_CHILD_ID, V_HUM); // MyMessage pressureMsg(BARO_CHILD_ID, V_PRESSURE); //
Präsentation von Sensoren und Sensoren in der Steuerung eines Smart Homes:
sendSketchInfo("BME280 Sensor", "1.0"); // , present(CHILD_ID_VOLT, S_MULTIMETER, "Battery"); // , , present(TEMP_CHILD_ID, S_TEMP, "TEMPERATURE [C or F]"); // , , present(HUM_CHILD_ID, S_HUM, "HUMIDITY [%]"); // , , present(BARO_CHILD_ID, S_BARO, "PRESSURE [hPa or mmHg]"); // , ,
Datenübertragung zum Smart Home Controller:
send(voltMsg.set(batteryVoltage)); // mW sendBatteryLevel(currentBatteryPercent); // % send(temperatureMsg.set(temperature, 1)); // , 1 send(humidityMsg.set(humidity, 0)); // , 0 send(pressureMsg.set(pressure, 0)); // , 0
Arduino-Programmcode #include <Wire.h> #include <SPI.h> #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> //#define MY_DEBUG #define MY_RADIO_NRF5_ESB #define MY_RF24_PA_LEVEL (NRF5_PA_MAX) #define MY_DISABLED_SERIAL #define MY_PASSIVE_NODE #define MY_NODE_ID 1 #define MY_PARENT_NODE_ID 0 //#define MY_PARENT_NODE_IS_STATIC //#define MY_TRANSPORT_UPLINK_CHECK_DISABLED #include <MySensors.h> bool sleep_flag; bool metric = true; bool last_sent_value; uint16_t currentBatteryPercent; uint16_t lastBatteryPercent = 1000; uint16_t battery_vcc_min = 2150; uint16_t battery_vcc_max = 2950; uint16_t batteryVoltage; uint16_t battery_alert_level = 25; uint32_t default_sleep_time = 60000; uint32_t SLEEP_TIME; uint32_t newmillisforbatt; uint32_t battsendinterval = 3600000; float tempThreshold = 0.5; float humThreshold = 5; float presThreshold = 1; float pres_mmThreshold = 1; float temperature; float pressure; float pressure_mm; float humidity; float lastTemperature = -1; float lastHumidity = -1; float lastPressure = -1; float lastPressure_mm = -1; #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; #define TEMP_CHILD_ID 0 #define HUM_CHILD_ID 1 #define BARO_CHILD_ID 2 #define CHILD_ID_VOLT 254 MyMessage voltMsg(CHILD_ID_VOLT, V_VOLTAGE); MyMessage temperatureMsg(TEMP_CHILD_ID, V_TEMP); MyMessage humidityMsg(HUM_CHILD_ID, V_HUM); MyMessage pressureMsg(BARO_CHILD_ID, V_PRESSURE); void preHwInit() { pinMode(21, INPUT); pinMode(25, OUTPUT); digitalWrite(25, HIGH); pinMode(26, OUTPUT); digitalWrite(26, HIGH); pinMode(27, OUTPUT); digitalWrite(27, HIGH); } void before() { NRF_POWER->DCDCEN = 1; NRF_NFCT->TASKS_DISABLE = 1; NRF_NVMC->CONFIG = 1; NRF_UICR->NFCPINS = 0; NRF_NVMC->CONFIG = 0; if (NRF_SAADC->ENABLE) { NRF_SAADC->TASKS_STOP = 1; while (NRF_SAADC->EVENTS_STOPPED) {} NRF_SAADC->ENABLE = 0; while (NRF_SAADC->ENABLE) {} } pinMode(BLUE_LED, OUTPUT); pinMode(RED_LED, OUTPUT); digitalWrite(BLUE_LED, HIGH); digitalWrite(RED_LED, HIGH); digitalWrite(27, LOW); } void setup() { digitalWrite(27, HIGH); bme_initAsleep(); wait(100); sendBatteryStatus(); wait(100); } void presentation() { sendSketchInfo("EFEKTA BME280 Sensor", "1.2"); present(CHILD_ID_VOLT, S_MULTIMETER, "Battery"); present(TEMP_CHILD_ID, S_TEMP, "TEMPERATURE [C or F]"); present(HUM_CHILD_ID, S_HUM, "HUMIDITY [%]"); present(BARO_CHILD_ID, S_BARO, "PRESSURE [hPa or mmHg]"); } void loop() { wait(10); bme.takeForcedMeasurement(); wait(100); sendData(); if (millis() - newmillisforbatt >= battsendinterval) { sleep_flag = 1; sendBatteryStatus(); } if (sleep_flag == 0) { sleep(SLEEP_TIME); sleep_flag = 1; } } void blinky(uint8_t pulses, uint8_t repit, uint8_t ledColor) { for (int x = 0; x < repit; x++) { if (x > 0) { sleep(500); } for (int i = 0; i < pulses; i++) { if (i > 0) { sleep(100); } digitalWrite(ledColor, LOW); wait(20); digitalWrite(ledColor, HIGH); } } } void sendBatteryStatus() { wait(20); batteryVoltage = hwCPUVoltage(); wait(2); if (batteryVoltage > battery_vcc_max) { currentBatteryPercent = 100; } else if (batteryVoltage < battery_vcc_min) { currentBatteryPercent = 0; } else { if (lastBatteryPercent == 1000) { currentBatteryPercent = (100 * (batteryVoltage - battery_vcc_min)) / (battery_vcc_max - battery_vcc_min) + 5; } else { currentBatteryPercent = (100 * (batteryVoltage - battery_vcc_min)) / (battery_vcc_max - battery_vcc_min) - 5; } } sendBatteryLevel(currentBatteryPercent); wait(100); if (lastBatteryPercent < battery_alert_level) { blinky(3, 1, RED_LED); } else { blinky((last_sent_value == true ? 2 : 1), 1, BLUE_LED); } sleep_flag = 0; newmillisforbatt = millis(); } void sendData() { temperature = bme.readTemperature(); wait(20); humidity = bme.readHumidity(); wait(20); pressure = bme.readPressure() / 100.0F; if (!metric) { temperature = temperature * 9.0 / 5.0 + 32.0; } else { pressure = pressure * 0.75006375541921; } CORE_DEBUG(PSTR("MY_TEMPERATURE: %d\n"), (int)temperature); CORE_DEBUG(PSTR("MY_HUMIDITY: %d\n"), (int)humidity); CORE_DEBUG(PSTR("MY_PRESSURE: %d\n"), (int)pressure); if (abs(temperature - lastTemperature) >= tempThreshold) { send(temperatureMsg.set(temperature, 1)); lastTemperature = temperature; sleep(1000); } if (abs(humidity - lastHumidity) >= humThreshold) { send(humidityMsg.set(humidity, 0)); lastHumidity = humidity; sleep(1000); } if (abs(pressure - lastPressure) >= presThreshold) { send(pressureMsg.set(pressure, 0)); lastPressure = pressure; sleep(1000); } sleep_flag = 0; } void bme_initAsleep() { if (! bme.begin(&Wire)) { while (1); } bme.setSampling(Adafruit_BME280::MODE_FORCED, Adafruit_BME280::SAMPLING_X1, // temperature Adafruit_BME280::SAMPLING_X1, // pressure Adafruit_BME280::SAMPLING_X1, // humidity Adafruit_BME280::FILTER_OFF ); wait(1000); }
Das Gehäuse für den Sensor wurde im 3D-Editor entwickelt:

Es wurde auf einem ANYCUBIC FOTON 3D-Drucker gedruckt, es wurde weißes Harz des gleichen Herstellers verwendet, die Schichtdicke wurde auf Medium - 50 Mikrometer gewählt. Die Druckzeit für Gehäuse und Umschlag beträgt 3 Stunden.



Das MySensors-Netzwerk, in dem der Sensor arbeitet, kommuniziert mit dem System des Smart Home von Magordomo. Der im Maysensors Majordomo-Modul registrierte Sensor sieht folgendermaßen aus:


Für diejenigen, die das Gleiche für sich selbst tun möchten, bietet der Artikel Links zu allem, was Sie brauchen.
Ein Ort, an dem Sie immer gerne allen helfen, die sich mit
MYSENSORS vertraut machen
möchten (Installation von Boards, Arbeit mit nRF5-Mikrocontrollern in der Arduino IDE-Umgebung, Tipps zur Arbeit mit dem mysensors-Protokoll -
@mysensors_rus