Низкая мощность для Nucleo F401RE Project: Demote Weather Datalogger

Эндрюмаг
Вт 20 ноября 2018 г., 19:11
Привет,
У меня есть проект с использованием Nucleo F401RE, это метеостанция, которая записывает данные на SD -карте каждые 20 минут. Он работает с использованием BME 280 (датчики температуры, влажности и давления) и HC-SR04 для глубины снега. Кроме того, у меня есть модуль SD -карты и DS3231 RTC.
Теперь моя проблема заключается в том, что мне нужно запустить этот проект на батареях почти один месяц (он будет установлен в высокой горе в течение зимнего периода), в настоящее время он содержится около 35 мА... Я видел много библиотек для низкой мощности, но я не мог заставить их работать. Любой может мне помочь?
Заранее большое спасибо!

Вот код текущего проекта (протестирован и работа на 100%): #include #include #include #include #include #include "Sodaq_DS3231.h" Adafruit_BME280 bme; #define SEALEVELPRESSURE_HPA (1013.25) const int TRIG_PIN = 5; const int ECHO_PIN = 6; File data; int meteoCount = 1; void setup() { pinMode(TRIG_PIN, OUTPUT); //dichiaro come output il pin trig pinMode(ECHO_PIN, INPUT); //dichiaro come input il pin echo bme.begin(0x76); pinMode(10, OUTPUT); SD.begin(4); data = SD.open("MetData.txt", FILE_WRITE); data.println("N:,Data e ora:,Temperatura:,U.R.:,Press.assoluta:,Altitudine:,Neve:"); data.close(); Wire.begin(); rtc.begin(); } uint32_t old_ts; void loop() { float temperatura = bme.readTemperature(); float neve, durata; //dichiaro la variabile neve e la variabile durata float cmPerMicrosecondi = 0.0331 + ( 0.000062 * temperatura); //calcolo i cm/ms del suono in base alla temperatura digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); //faccio un impulso di dieci microsecondi sul pin trig digitalWrite(TRIG_PIN, LOW); durata = pulseIn(ECHO_PIN, HIGH); //mi metto in ascolto sul pin eco e calcolo la durata dell'impulso neve = (durata*cmPerMicrosecondi/2.0); //calcolo la distanza con la formula durata*(cm/ms)/2, diviso due perchè il suo va, rimbalza contro un oggetto e ritorna, quindi compie due volte il tragitto float menoNeve = 200.0 - neve; delay(500); DateTime now = rtc.now(); //get the current date-time uint32_t ts = now.getEpoch(); if (old_ts == 0 || old_ts != ts) { old_ts = ts; data = SD.open("MetData.txt", FILE_WRITE); data.print(meteoCount); data.print(","); data.print(now.date(), DEC); data.print("/"); data.print(now.month(), DEC); data.print("/"); data.print(now.year(), DEC); data.print(" "); data.print(now.hour(), DEC); data.print(":"); data.print(now.minute(), DEC); data.print(":"); data.print(now.second(), DEC); data.print(","); data.print(temperatura); data.print(","); data.print(bme.readHumidity()); data.print(","); data.print(bme.readPressure() / 100.0F); data.print(","); data.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); data.print(","); data.print(menoNeve); data.println(""); data.close(); meteoCount++; delay(1200000); } }

Mrburnette
Вт 20 ноября 2018 г., 19:29
[Эндрюмаг - Вт 20 ноября 2018 г., 19:11] - Привет,
У меня есть проект с использованием Nucleo F401RE, это метеостанция, которая записывает данные на SD -карте каждые 20 минут. Он работает с использованием BME 280 (датчики температуры, влажности и давления) и HC-SR04 для глубины снега. Кроме того, у меня есть модуль SD -карты и DS3231 RTC.
Теперь моя проблема заключается в том, что мне нужно запустить этот проект на батареях почти один месяц (он будет установлен в высокой горе в течение зимнего периода), в настоящее время он содержится около 35 мА... Я видел много библиотек для низкой мощности, но я не мог заставить их работать.
...
Поскольку вы используете доску Nucleo, могу ли я предположить, что вы используете ядро ​​чиновника STM (на основе HAL)?

Если это так, библиотека с низким энергопотреблением должна работать: https: // github.com/stm32duino/arduino_c ... /проблемы/35

Луча

fpistm
Ср 21 ноября 2018 г. 8:01
Что -то подобное должно работать:
#include #include #include #include #include #include #include Adafruit_BME280 bme; #define SEALEVELPRESSURE_HPA (1013.25) const int TRIG_PIN = 5; const int ECHO_PIN = 6; File data; // Time in second between measure static uint32_t atime = 1200000; int meteoCount = 1; /* Get the rtc object */ STM32RTC& rtc = STM32RTC::getInstance(); void setup() { pinMode(TRIG_PIN, OUTPUT); //dichiaro come output il pin trig pinMode(ECHO_PIN, INPUT); //dichiaro come input il pin echo bme.begin(0x76); pinMode(10, OUTPUT); SD.begin(4); data = SD.open("MetData.txt", FILE_WRITE); data.println("N:,Data e ora:,Temperatura:,U.R.:,Press.assoluta:,Altitudine:,Neve:"); data.close(); Wire.begin(); // By default the LSI is selected as source. Use LSE for better accuracy rtc.setClockSource(STM32RTC::LSE_CLOCK); rtc.begin(); // Configure low power LowPower.begin(); LowPower.enableWakeupFrom(&rtc, alarmMatch, &atime); // Configure first alarm in 2 second then it will be done in the rtc callback rtc.setAlarmEpoch( rtc.getEpoch() + atime ); } void loop() { float temperatura = bme.readTemperature(); float neve, durata; //dichiaro la variabile neve e la variabile durata float cmPerMicrosecondi = 0.0331 + ( 0.000062 * temperatura); //calcolo i cm/ms del suono in base alla temperatura digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); //faccio un impulso di dieci microsecondi sul pin trig digitalWrite(TRIG_PIN, LOW); durata = pulseIn(ECHO_PIN, HIGH); //mi metto in ascolto sul pin eco e calcolo la durata dell'impulso neve = (durata * cmPerMicrosecondi / 2.0); //calcolo la distanza con la formula durata*(cm/ms)/2, diviso due perchè il suo va, rimbalza contro un oggetto e ritorna, quindi compie due volte il tragitto float menoNeve = 200.0 - neve; delay(500); data = SD.open("MetData.txt", FILE_WRITE); data.print(meteoCount++); data.print(","); data.print(rtc.getDay(), DEC); data.print("/"); data.print(rtc.getMonth(), DEC); data.print("/"); data.print(rtc.getYear(), DEC); data.print(" "); print2digits(rtc.getHours()); data.print(":"); print2digits(rtc.getMinutes()); data.print(":"); print2digits(rtc.getSeconds()); data.print(","); data.print(temperatura); data.print(","); data.print(bme.readHumidity()); data.print(","); data.print(bme.readPressure() / 100.0F); data.print(","); data.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); data.print(","); data.print(menoNeve); data.println(""); data.close(); LowPower.deepSleep(); } void print2digits(int number) { if (number < 10) { data.print("0"); // print a 0 before if the number is < than 10 } data.print(number); } void alarmMatch(void* data) { // This function will be called once on device wakeup // You can do some little operations here (like changing variables which will be used in the loop) // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context uint32_t sec = 1; if (data != NULL) { sec = *(uint32_t*)data; // Minimum is 1 second if (sec == 0) { sec = 1; } } rtc.setAlarmEpoch( rtc.getEpoch() + sec); }

Zoomx
Ср 21 ноября 2018 г., 9:06
@Andrewmag
Если вы используете китайские модули DS3231, прочитайте это
https: // thecavepearlproject.org/2014/05 ... от-ebay/
Он говорит, чтобы удалить некоторые компоненты для достижения низкой мощности в этом модуле, начиная с светодиода питания.
Cave Pearl Datalogger, который основан на Arduino, имеет много подсказков с низкой мощностью, потому что этот проект не является доказательством концепции, но используется с многих лет в отдаленных подводных пещерах.

Эндрюмаг
Ср 21 ноября 2018 г. 18:16
Большое спасибо всем! Да Я использую ядро ​​чиновника STM (на основе HAL) с успехом!
[fpistm - Ср 21 ноября 2018 г. 8:01] - Что -то подобное должно работать:
[...]
Примечание Я использовал RTC с доски.
Вы должны быть в состоянии установить батарею монетной ячейки на VBAT, удалив один солдатский мост
Видеть: https: // os.Mbed.com/users/gregeric/note ... N-STM32-N/

Для вашего варианта использования должно быть лучше для использования режима выключения, но я еще не реализую регистр RTC Back, чтобы восстановить время.
Большое спасибо за код и советы! К сожалению, это дает мне эту ошибку, что у меня была также, когда я пытался в прошлом, чтобы использовать библиотеку низкой мощности... Что я сделал неправильно?
Arduino:1.8.5 (Windows 7), Scheda:"Nucleo-64, Nucleo F401RE, STLink, Enabled with generic Serial, None, Smallest (-Os default)" In file included from C:\Users\Andrea\Documents\Arduino\libraries\STM32LowPower-master\src/STM32LowPower.h:49:0, from C:\Users\Andrea\Desktop\DATI ANDREA\ardUINO\sketch_nov21a\sketch_nov21a.ino:6: C:\Users\Andrea\Documents\Arduino\libraries\STM32RTC-master\src/STM32RTC.h:66:10: error: 'HOUR_AM' was not declared in this scope AM = HOUR_AM, ^~~~~~~ C:\Users\Andrea\Documents\Arduino\libraries\STM32RTC-master\src/STM32RTC.h:67:10: error: 'HOUR_PM' was not declared in this scope PM = HOUR_PM ^~~~~~~ exit status 1 Errore durante la compilazione per la scheda Nucleo-64.

fpistm
Ср 21 ноября 2018 г., 19:10
У вас не было последней версии библиотек. Пожалуйста, удалите STM32RTC и Lowerower, затем установите их спасибо менеджеру библиотеки,
Лучше использовать официальные релизы вместо Zip

Эндрюмаг
Ср 21 ноября 2018 г., 19:39
Хорошо. Удалили их обоих и переустановили STM32Duino RTC 1.0.2 версия и STM32Duino Low Power 1.0.1 версия
К сожалению, ничего не изменилось... та же ошибка!

fpistm
Ср 21 ноября 2018 г., 20:18
Да, я просто думаю, что ты не на последнем ядре 1.4.0. Вот почему вы получаете эту ошибку.

Эндрюмаг
Чт 22 ноября 2018 г., 10:00 утра
Хорошо, спасибо, как я могу обновить ядро ​​до 1.4.0?

fpistm
Чт 22 ноября 2018 13:08
Спасибо менеджеру «Доски» в файле JSON.
Видеть:
https: // github.com/stm32duino/arduino_c ... NG-начало

Эндрюмаг
Пт 23 ноября 2018 г., 21:48
Хорошо, спасибо. Код успешно заряжается, даже если, к сожалению, он не работает правильно, потому что он делает только одно измерение, а затем ничего более (возможно, он не просыпается от глубокого сна?)
Я также заметил, что ваш код больше не использует RTC DS3231... Из-за того, что у меня нет резервной батареи для RTC доски Nucleo, невозможно использовать DS3231 вместо бортовой RTC, чтобы разбудить доску с низкой мощности? Может быть, с внешней сигнализацией от DS3231?
заранее спасибо

Zoomx
Пн 26 ноября 2018 г., 10:25
Я считаю, что это возможно в Arduino, но код должен быть изменен.
MCU Shold засыпает и пробуждается, когда линия, соединенная с падением DS3231.
К сожалению, я не могу написать код для этого.

Mrburnette
Пн 26 ноября 2018 г. 13:07
Проверьте контроллер камеры Энди:

https: // www.STM32duino.com/viewtopic.PHP?t = 658

fpistm
Пн 26 ноября 2018 г., 13:09
Да, как уже упоминалось, я удаляю использование внешнего RTC и предоставляю способ добавить батарею ячейки монеты.
В любом случае, можно использовать внешний и использовать один из булавок Syswkup, чтобы разбудить доску от сна, для F401: PA0. attachInterruptWakeup()

Эндрюмаг
Пн 26 ноября 2018 г., 19:41
Спасибо
Я выложил новый код... На этот раз, используя ток «Время глубокого сна», упав с 35 до 26.
Неплохо, но я думаю, что должно быть возможно сделать больше, удалив светодиоды (или отключив их? Является ли это возможным? Я говорю о LD1 E LD3) Я надеюсь сэкономить еще несколько ма...
Кто -нибудь знает, возможно ли отключить ток на датчики (VCC), пока доска в глубоком соном? Это определенно дало бы мне гораздо меньше отходов питания!

Обновленный код (протестирован): #include #include #include #include #include #include "Sodaq_DS3231.h" #include "STM32LowPower.h" Adafruit_BME280 bme; #define SEALEVELPRESSURE_HPA (1013.25) const int TRIG_PIN = 5; const int ECHO_PIN = 6; File data; int meteoCount = 1; void setup() { pinMode(TRIG_PIN, OUTPUT); //dichiaro come output il pin trig pinMode(ECHO_PIN, INPUT); //dichiaro come input il pin echo bme.begin(0x76); pinMode(10, OUTPUT); SD.begin(4); data = SD.open("MetData.txt", FILE_WRITE); data.println("N:,Data e ora:,Temperatura:,U.R.:,Press.assoluta:,Altitudine:,Neve:"); data.close(); Wire.begin(); rtc.begin(); LowPower.begin(); } uint32_t old_ts; void loop() { float temperatura = bme.readTemperature(); float neve, durata; //dichiaro la variabile neve e la variabile durata float cmPerMicrosecondi = 0.0331 + ( 0.000062 * temperatura); //calcolo i cm/ms del suono in base alla temperatura digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); //faccio un impulso di dieci microsecondi sul pin trig digitalWrite(TRIG_PIN, LOW); durata = pulseIn(ECHO_PIN, HIGH); //mi metto in ascolto sul pin eco e calcolo la durata dell'impulso neve = (durata*cmPerMicrosecondi/2.0); //calcolo la distanza con la formula durata*(cm/ms)/2, diviso due perchè il suo va, rimbalza contro un oggetto e ritorna, quindi compie due volte il tragitto float menoNeve = 200.0 - neve; delay(500); DateTime now = rtc.now(); //get the current date-time uint32_t ts = now.getEpoch(); if (old_ts == 0 || old_ts != ts) { old_ts = ts; data = SD.open("MetData.txt", FILE_WRITE); data.print(meteoCount); data.print(","); data.print(now.date(), DEC); data.print("/"); data.print(now.month(), DEC); data.print("/"); data.print(now.year(), DEC); data.print(" "); data.print(now.hour(), DEC); data.print(":"); data.print(now.minute(), DEC); data.print(":"); data.print(now.second(), DEC); data.print(","); data.print(temperatura); data.print(","); data.print(bme.readHumidity()); data.print(","); data.print(bme.readPressure() / 100.0F); data.print(","); data.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); data.print(","); data.print(menoNeve); data.println(""); data.close(); meteoCount++; digitalWrite(LED_BUILTIN, LOW); LowPower.deepSleep(1200000); } }

Zoomx
Вт 27 ноября 2018 г. 8:40
[Эндрюмаг - Пн 26 ноября 2018 г., 19:41] - Кто -нибудь знает, возможно ли отключить ток на датчики (VCC), пока доска в глубоком соном? Это определенно дало бы мне гораздо меньше отходов питания!
Это зависит от датчиков!
Если вы используете BME280, возможно, это возможно привлечь его из штифта или использовать функцию Power Down.

fpistm
Вт 27 ноября 2018 г. 8:55 утра
Библиотека низкой мощности обрабатывает режим питания MCU. Пользователь также должен обрабатывать все подключенные периферийные устройства, чтобы получить наилучшую низкую мощность.
Больше, если вы используете Stlink, он потребляет также некоторые текущие.

В вашем случае, если вы сохранили внешний RTC. Я советую использовать Shutdown () и AttactIntterupt на PA0 (Syswkup Pin).
Затем запрограммируйте DS3231, чтобы создать прерывание каждый период, который вы хотите.

Эндрюмаг
Вт 27 ноября 2018 г., 19:58
Только что попробовал с этим (пытаясь отменить VCC датчиков по контактам 9 и 2), но это не работает: значения датчиков появились в файле TXT «NAN»...
#include #include #include #include #include #include "Sodaq_DS3231.h" #include "STM32LowPower.h" Adafruit_BME280 bme; #define SEALEVELPRESSURE_HPA (1013.25) const int TRIG_PIN = 5; const int ECHO_PIN = 6; int nevePin = 9; int bmePin = 2; File data; int meteoCount = 1; void setup() { pinMode(TRIG_PIN, OUTPUT); //dichiaro come output il pin trig pinMode(ECHO_PIN, INPUT); //dichiaro come input il pin echo bme.begin(0x76); pinMode(10, OUTPUT); SD.begin(4); pinMode(bmePin, OUTPUT); pinMode(nevePin, OUTPUT); data = SD.open("MetData.txt", FILE_WRITE); data.println("N:,Data e ora:,Temperatura:,U.R.:,Press.assoluta:,Altitudine:,Neve:"); data.close(); Wire.begin(); rtc.begin(); LowPower.begin(); } uint32_t old_ts; void loop() { digitalWrite(nevePin, HIGH); digitalWrite(bmePin, HIGH); float temperatura = bme.readTemperature(); float neve, durata; //dichiaro la variabile neve e la variabile durata float cmPerMicrosecondi = 0.0331 + ( 0.000062 * temperatura); //calcolo i cm/ms del suono in base alla temperatura digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); //faccio un impulso di dieci microsecondi sul pin trig digitalWrite(TRIG_PIN, LOW); durata = pulseIn(ECHO_PIN, HIGH); //mi metto in ascolto sul pin eco e calcolo la durata dell'impulso neve = (durata*cmPerMicrosecondi/2.0); //calcolo la distanza con la formula durata*(cm/ms)/2, diviso due perchè il suo va, rimbalza contro un oggetto e ritorna, quindi compie due volte il tragitto float menoNeve = 200.0 - neve; delay(500); DateTime now = rtc.now(); //get the current date-time uint32_t ts = now.getEpoch(); if (old_ts == 0 || old_ts != ts) { old_ts = ts; data = SD.open("MetData.txt", FILE_WRITE); data.print(meteoCount); data.print(","); data.print(now.date(), DEC); data.print("/"); data.print(now.month(), DEC); data.print("/"); data.print(now.year(), DEC); data.print(" "); data.print(now.hour(), DEC); data.print(":"); data.print(now.minute(), DEC); data.print(":"); data.print(now.second(), DEC); data.print(","); data.print(temperatura); data.print(","); data.print(bme.readHumidity()); data.print(","); data.print(bme.readPressure() / 100.0F); data.print(","); data.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); data.print(","); data.print(menoNeve); data.println(""); data.close(); meteoCount++; digitalWrite(LED_BUILTIN, LOW); digitalWrite(nevePin, LOW); digitalWrite(bmePin, LOW); LowPower.deepSleep(1200000); } }

Zoomx
Ср 28 ноября 2018 г. 8:07
Удалить все светодиоды, которые вам не нужно.
Потребление энергии DS3231 кажется слишком высоким, вы удалили диод, используемый для перезарядки батареи?
Если нуклео работает от USB, возможно, есть питания от LDO.

Вы используете HCSR-04 для измерения высоты снега?
[fpistm - Вт 27 ноября 2018 г. 8:55] - В вашем случае, если вы сохранили внешний RTC. Я советую использовать Shutdown () и AttactIntterupt на PA0 (Syswkup Pin).
Затем запрограммируйте DS3231, чтобы создать прерывание каждый период, который вы хотите.
DS3231 имеет линейную тревогу, которая обычно высока, а при стрельбе тревоги он снижается.
Как и на Arduino Uno, вы должны поместить MCU в глубокий сон и настроить PIN -код (2 и 3 на Arduino Uno, PA0 на STM32, как предложено FPISTM), чтобы разбудить MCU, когда линия переходит от высокого до низкого уровня.

fpistm
Ср 28 ноября 2018 г., 16:14
Ее пример, как использовать внешний пробуждение
https: // github.com/stm32duino/stm32lowp ... вверх.INO#L32

Я видел в примере библиотеки DS, как настроить тревогу, поэтому вы сможете настроить тревогу и пробуждение спасибо PA0.
И использовать Shutdown () вместо DeepSleep () (без аргументов, когда вы будется, благодаря внешнему тревоге RTC)

Эндрюмаг
Ср 28 ноября 2018 г. 18:15
[fpistm - Ср 28 ноября 2018 г., 16:14] - Ее пример, как использовать внешний пробуждение
https: // github.com/stm32duino/stm32lowp ... вверх.INO#L32

Я видел в примере библиотеки DS, как настроить тревогу, поэтому вы сможете настроить тревогу и пробуждение спасибо PA0.
И использовать Shutdown () вместо DeepSleep () (без аргументов, когда вы будется, благодаря внешнему тревоге RTC)
В библиотеке Sodaqds3231 RTC я нашел это Exmple: //Interrupts for Battery management/saving using MCU power down mode. /INT from DS3231 is connected to INT0 of MCU. #include #include #include "Sodaq_DS3231.h" static uint8_t prevSecond=0; void setup () { /*Initialize INT0 for accepting interrupts */ PORTD |= 0x04; DDRD &=~ 0x04; Serial.begin(57600); Wire.begin(); rtc.begin(); attachInterrupt(0, INT0_ISR, FALLING); //Enable Interrupt rtc.enableInterrupts(EveryMinute); //interrupt at EverySecond, EveryMinute, EveryHour // or this //rtc.enableInterrupts(18,4,0); // interrupt at (h,m,s) } void loop () { DateTime now = rtc.now(); //get the current date-time if((now.second()) != prevSecond ) { //print only when there is a change in seconds Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.date(), DEC); Serial.print(' '); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(' '); } prevSecond = now.second(); rtc.clearINTStatus(); } //Interrupt service routine for external interrupt on INT0 pin conntected to /INT void INT0_ISR() { //Keep this as short as possible. Possibly avoid using function calls Serial.println(" External Interrupt detected "); }

Zoomx
Чт 29 ноября 2018 г. 10:45 утра
[Эндрюмаг - Ср 28 ноября 2018 г. 18:15] -
Как я могу настроить PIN -код PA0? У вас есть пример?
Может, этот?
https: // github.com/stm32duino/stm32lowp ... Проснуться.Ино

Как я вижу, то же самое на arduino uno, разные булавки и разные функции, но другие вещи одинаковы.

Эндрюмаг
SAT 8 декабря 2018 г. 9:29 утра
Всем привет,
Я сделал несколько тестов, но я не смог правильно установить пробуждение доски через DS3231 ... В результате у меня есть, что доска не ложится спать и продолжает работать на 21 мА... Любой может мне помочь?
Я уверен, что это проблема кодирования, и моя, вероятно, совершенно неверна. Единственное, что я смог установить, - это тревога на DS3231 (даже то, что я хотел его каждые 20 минут, но кажется, что это возможно только каждый час), но часть кода для отправки спать и пробуждения доски - это доска наверное неверно... Есть ли пример для кода пробуждения?

Zoomx
Пн 10 декабря 2018 г., 10:22
Вы проверили тот, который я связал раньше?

На DS3231 просыпаться каждые 20 минут, вам следует использовать пробуждение с минутным матчем и установить новую тревогу, добавив 20 минут. Насколько я помню (это утро понедельника!) Этот чип не имеет тревоги в фиксированном интервале времени, поэтому будильник каждый час выполняется с использованием Minate Match, так как этот матч происходит только один раз в час.