Официальный сайт компании Arduino по адресу arduino.cc
Батарейный радио датчик температуры на pro mini + nrf24
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
В качестве освоения режимов потребления МК решил сделать датчик на nrf24. Также этот датчик позволет мне мониторить проблемные участи дома с выводом информации на головной блок (http://arduino.ru/forum/proekty/udalennyi-monitoring-za-datchikami-na-ma...)
1. Выбор элементной базы.
В качестве контроллера решил использовать pro mini 3.3 вольта 8 мГц. Сама плата была доработана по "классике" (в сети по этому много инфо) . Аппаратная доработка свелась к трем вещам - 1. Удаление светодиода по питанию, 2. Удаление входного стабилизатора, 3 Удаление светодиода на 13 ноге. Обычно 3 пункт не описан, но в моем случае используется SPI и удалить для уменьшения потребления все таки нужно.
Тонкости.
Для программирования pro mini я использую конвертор usb uart на ft232. На плате был установлен переключатель 3.3-5 вольт но он только управлял уровнем выходов-входов ft232. Т.к. ft232 имеет встроенный стабилизатор на 3.3 (50мА) я доработал плату (один разрез и один провод кинуть) и теперь при положении 3.3 вольта на pro mini подается питание 3.3 от стабилизатора . ft232. Зачем ,???????? А затем, что бы nrf24 правильно запитать при отладке.
Выбор датчика.
Использовал ВМ180 т.к. хотел посмотреть как работает датчик давления. Особенность - питание на датчик снимается с 10 ноги контроллера для уменьшение энергопотребления. Т.е. для активации датчика надо записать на 10 ногу 1 и инициализировать датчик. Не факт что это правильное решение. Плюсом такого решения является что в выключенном состянии датчик ничего не потребляет, минусом что увеличивается время в режиме "работа". Это вопрос требует дальнейшего изучения. Что более энергетически эффективно.
nrf24 - все соединено по классике. Была только одна проблема. Вначале я поставил плату nrf24 с усилителем. При отладке (питание от ft232) все было хоорошо, при питании от батареи приходилось уменьшать мощность до уровня LOW иначе данны не уходили. Я не верю что батаейка не может отдать необходимый ток, Причина в ином - но в чем не разобрался, Поменял плату на "без усилителя" там можно рабоать на максимальной мощности. Может кто подскажет?
Элемент питания. выбор пал на литиевый элемент на основе Li-SOCl2 (литий-тионилхлорида) с напряжением 3.6 воьлта размером 1/2 АА. Емкость обещают 1200 мА ч.
Сразу решил что буду ставить только одну батарейку для простоты монтожа и уменьшения габаритов - т.е это дало диапазон напряжений 3-4 вольта - литевый элемент. Размер 1/2 АА получился при компоновке устройства.
2. Программа
Использовал библиотеки для работы с датчиком и управления режимами потребления контроллера. Здесь все стандартно.
Программа проста и не затейлева.
WDT таймер настроен на 8 секунд он будит МК. Каждое 9 просыпание считывается датчик и копится сумма показаний. Каждое 9*4 просыпание данные передаются в головной блок. 8*9*4=288 секунд около 5 минут.
НО есть единственная тонкость с которой я бился целый вечер. При уходе в режим power_down потребление оставалось на уровне 1.2 мА что не приемлемо. Долго копался, решения на русскоговорящих форумах не нашел, на англ. есть намеки типа копайте ноги SPI. Я выяснил что виновата связка SPI+nrf24. Через выходы течет ток и он влиеет на потребление Решене:
Выключение
// Выключение чипа nrf24 radio.powerDown(); // выключаем чип но это не все!!! SPI.end(); // выключаем SPI PullUp(B,5); // slk - сделать входом и подтянуть к 3.3 вольтам PullUp(B,3); // mosi - сделать входом и подтянуть к 3.3 вольтам
Включение
// Включение чипа nrf24 SetOutput(B,5); // slk - выход сделать SetOutput(B,3); // mosi - выход сделать SPI.begin(); // старт spi заново radio.powerUp();
После этого потребление стало 42 мкА, что совпадает с расчетами (13-15 nrf24 20-25-pro mini).
В режиме сна на батарейке 1200 мА проработает около 28 000 часов (я понимаю что это теория но цифры внушают -))).
Есть еще режим работы там потребелние колеблится от 4 до 20 мА, но время такого режима мкс. А передатчик (20 мА) активируется вообще раз в 5 минут.
Так что работать должна я думаю миниум 1 год.
3. Конструктив.
Традиционно корпус напечатан на 3Д принтере (нижняя часть сделана одной деталью). Очень удобно, все отверстия сразу сделаны, только заусецы счистить и можно использовать.
Батарейка приклеена внутри термоклеем, Провода припаяны (использована кислота для уменьшения времени нагрева, не забыть промыть). Все элемены соеденены проводом . С nrf24 снят разъем (автоматизированный отсос с паяльникм - вещь!!!!). Плата МК и nrf24 склеены между собой термоклеем (сторонами где нет деталей). Выключатель поставлен для того чобы вообще не менять батарейку. Когда не используешь - выключи.
Получилось компактно и просто.
4. Косяки
Периодически теряется связь с датчиком, Выснил что проблема в датчике. Включение выключение датчика помогает. Пока не разобрался. Может чтото отваливается в power_down, надо выяснить.
Для увеличения дальности надо ставить модуль nrf24 с внешней антенной
Конструктивная критика как всегда приветствуется.-))
Исходники файл temp_sensor.ino:
/* SFE_BMP180 library example sketch Hardware connections: - (GND) to GND + (VDD) to 3.3V (WARNING: do not connect + to 5V or the sensor will be damaged!) You will also need to connect the I2C pins (SCL and SDA) to your Arduino. The pins are different on different Arduinos: Any Arduino pins labeled: SDA SCL Uno, Redboard, Pro: A4 A5 Mega2560, Due: 20 21 Leonardo: 2 3 */ #include <SFE_BMP180.h> #include <Wire.h> #include "LowPower.h" #include <SPI.h> #include "nRF24L01.h" // Беcпроводной модуль надо использовать библиотеку http://tmrh20.github.io/RF24 #include "RF24.h" // Беcпроводной модуль используются не стандартные функции https://github.com/TMRh20 // - ОПЦИИ ------------------------------- //#define DEBUG // Отладочную информацию в ком порт посылает //#define DEMO // Признак демонстрации - данные с датчиков генерятся рандом #define VERSION_DATA "301115" // Дата текущей версии в формате ДДММГГ #define VERSION "0.15" // Текущая версия прошивки #define ID 0x31 // уникально Идентификатор устройства (тип) - старшие 4 бита, вторые (младшие) 4 бита серийный номер устройства #define LABEL "BM-180" // Название блока #define NRF24_CHANEL 100 // Номер канала nrf24 // Ноги куда подключаем переферию #define PIN_CE 7 // nrf24 ce #define PIN_CSN 6 // nrf24 csn // Макросы для работы с портами скорость и место #define SetOutput(port,bit) DDR ## port |= _BV(bit) #define SetInput(port,bit) DDR ## port &= ~_BV(bit) #define SetBit(port,bit) PORT ## port |= _BV(bit) #define ClearBit(port,bit) PORT ## port &= ~_BV(bit) #define WritePort(port,bit,value) PORT ## port = (PORT ## port & ~_BV(bit)) | ((value & 1) << bit) #define ReadPort(port,bit) (PIN ## port >> bit) & 1 #define PullUp(port,bit) { SetInput(port,bit); SetBit(port,bit); } #define Release(port,bit) { SetInput(port,bit); ClearBit(port,bit); } // - ВРЕМЕНА --------------------------------------- #ifdef DEMO // Для демо все быстрее #define TIME_WDT SLEEP_2S // Период сторожевого таймера #define TIME_SCAN_SENSOR 2 // Время опроса датчиков в 8 секундных интервалах (сторожевого таймера) #define TIME_SEND_SENSOR 4 // Время посылки данных (равно усреднению) #else #define TIME_WDT SLEEP_8S // Период сторожевого таймера #define TIME_SCAN_SENSOR 9 // Время опроса датчиков в 8 секундных интервалах (сторожевого таймера) #define TIME_SEND_SENSOR 4 // Время посылки данных (равно усреднению) 288 секунд почти пять минут #endif // АЦП ---------------------------------------- const long ConstADC=1126400; // Калибровка встроенного АЦП (встроенный ИОН) по умолчанию 1126400 // Переменные которые сохраняются в памяти без инициализации int S8_tick __attribute__((section(".noinit"))); // число 8 секундных интервалов с последнего измерения //int scan_tick __attribute__((section(".noinit"))); // счетчик измерений (опроса датчика) unsigned long tt __attribute__((section(".noinit"))); // Время пришедшее от головного блока если 0 то время не приходило // Пакет передаваемый, используется также для хранения УСРЕДНЕННЫХ результатов. struct type_packet_0x30_NRF24 // Версия 1.1!! адаптация для stm32 Структура передаваемого пакета 32 байта - 32 максимум { byte id=ID; // Идентификатор типа устройства - старшие 4 бита, вторые (младшие) 4 бита серийный номер устройства byte error=0; // Ошибка блока, пока резерв uint16_t Vcc; // Напряжение батареи Милливольты!!!!! int16_t Temp; // Температура датчика сотые градуса uint16_t relH; // Относительная влажность датчика сотые % uint16_t absH; // Абсолютная влажность датчика сотые грамма на куб uint16_t P; // Давление милибары uint16_t count=0; // Циклический счетчик пакетов 2 байта хватит на долго - около 3000 часов char ver[5] = VERSION; // Версия прошивки не более 4 байт + "0" символ char note[13] = LABEL; // Примечание не более 12 байт + "0" байт Русские буквы в два раза меньше т.к. UTF-8 } packet_0x30 __attribute__((section(".noinit"))); struct type_sensors // структура для усреднения измерений { int16_t num; // Число накопленных образцов int32_t Vcc=0; // Напряжение батареи Милливольты!!!!! int32_t Temp=0; // Температура датчика сотые градуса int32_t relH=0; // Относительная влажность датчика сотые % int32_t absH=0; // Абсолютная влажность датчика сотые грамма на куб int32_t P=0; // Давление резерв } sensor __attribute__((section(".noinit"))); SFE_BMP180 pressure; // датчик BMP180 RF24 radio(PIN_CE, PIN_CSN); // определение управляющих ног #define ALTITUDE 1655.0 // Altitude of SparkFun's HQ in Boulder, CO. in meters void setup() { int volt=0; S8_tick=0; tt=0; reset_sum(); // 1. Проверка питания мигание светодиода показывает напряжение батареи volt=readVcc(); /* if (volt>3300) LedBlink(4, 40); else if (volt>3000) LedBlink(3, 40); else if (volt>2700) LedBlink(2, 40); else if (volt>2400) LedBlink(1, 40); */ #ifdef DEBUG Serial.begin(115200); Serial.print(F("\n\n1. Version: ")); Serial.print(F(VERSION)); Serial.print(F(" ")); Serial.println(F(VERSION_DATA)); Serial.print(F("2. Battery voltage: ")); Serial.println(((float)volt)/1000.0,2); Serial.print(F("3. NRF24 init . . . ")); Serial.flush(); # endif // 2.Инициализация радиомодудя char buf[10]; if (setRadio()==true) // радио проинициализировано удачно { #ifdef DEBUG Serial.println(F("OK")); // внимание функция read_register сделана в библиотеке публичной sprintf(buf,"%02x",radio.read_register(CONFIG)); Serial.print(F(" 3.1 Register CONFIG: 0x")); Serial.println(buf); sprintf(buf,"%02x",radio.read_register(SETUP_AW)); Serial.print(F(" 3.2 Register SETUP_AW: 0x")); Serial.println(buf); sprintf(buf,"%02x",radio.read_register(SETUP_RETR));Serial.print(F(" 3.3 Register SETUP_RETR: 0x")); Serial.println(buf); sprintf(buf,"%02x",radio.read_register(RF_CH)); Serial.print(F(" 3.4 Register RF_CH: 0x")); Serial.println(buf); sprintf(buf,"%02x",radio.read_register(RF_SETUP)); Serial.print(F(" 3.5 Register RF_SETUP: 0x")); Serial.println(buf); sprintf(buf,"%02x",radio.read_register(NRF_STATUS));Serial.print(F(" 3.6 Register NRF_STATUS: 0x")); Serial.println(buf); #endif radio.powerDown(); // Выключить радиомодуль } else // радио не работает { #ifdef DEBUG Serial.println(F("FAIL")); #endif } // 3. Инициализация сенсора pinMode(10, OUTPUT); digitalWrite(10, HIGH); delay(10); if (pressure.begin()) { #ifdef DEBUG Serial.println(F("4. BMP180 init OK\n")); Serial.flush(); #endif } else { #ifdef DEBUG Serial.print(F("4. BMP180 init FAIL, error:")); Serial.println(pressure.getError()); Serial.print(F("\n")); Serial.flush(); #endif } digitalWrite(10, LOW); pinMode(10, INPUT); // Ошибки датчика ВМР180 связанные с чтением шины i2c // 0 = Success // 1 = Data too long to fit in transmit buffer // 2 = Received NACK on transmit of address // 3 = Received NACK on transmit of data // 4 = Other error packet_0x30.error=pressure.getError()-'0'; // Ошибка в виде символа переводим в число // Для проверки связи сразу посылаем пакет measurement(); packet_0x30.Vcc=sensor.Vcc; packet_0x30.Temp=sensor.Temp; packet_0x30.relH=sensor.relH; packet_0x30.absH=sensor.absH; packet_0x30.P=sensor.P/10; reset_sum(); sendRadio(); // Послать даннные } void loop() { if (S8_tick>=TIME_SCAN_SENSOR-1) // Пора опрашивать датчик { #ifdef DEBUG Serial.print(F("PowerUp and scan sensor")); // Serial.flush(); #endif S8_tick=0; // сюда вставить функцию измерения и накопления суммы measurement(); } else { #ifdef DEBUG Serial.println(F("PowerUp")); Serial.flush(); #endif S8_tick++; } if (sensor.num>=TIME_SEND_SENSOR) // Пора посылать данные { // Усреднение packet_0x30.Vcc=sensor.Vcc/TIME_SEND_SENSOR; packet_0x30.Temp=sensor.Temp/TIME_SEND_SENSOR; packet_0x30.relH=sensor.relH/TIME_SEND_SENSOR; packet_0x30.absH=sensor.absH/TIME_SEND_SENSOR; packet_0x30.P=(sensor.P/TIME_SEND_SENSOR)/10; reset_sum(); sendRadio(); // Послать даннные } LowPower.powerDown(TIME_WDT, ADC_OFF, BOD_OFF); // СПАТЬ } // Чтение напряжения питания ---------------------------------------------- long readVcc() { long result; // Read 1.1V reference against AVcc ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Convert while (bit_is_set(ADCSRA,ADSC)); result = ADCL; result |= ADCH<<8; result = ConstADC / result; // Back-calculate AVcc in mV return result; } // Установка радиомодуля bool setRadio(void) { // if (radio.begin()==false) return false; // Если модуль не стартует то выходим radio.begin(); radio.setDataRate(RF24_250KBPS); // выбор скорости RF24_250KBPS RF24_1MBPS RF24_2MBPS radio.setPALevel(RF24_PA_MAX); // выходная мощность передатчика RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, radio.setChannel(NRF24_CHANEL); // тут установка канала radio.setCRCLength(RF24_CRC_16); // использовать контрольную сумму в 16 бит radio.setAutoAck(true); // выключить аппаратное потверждение // radio.enableDynamicPayloads(); // разрешить Dynamic Payloads radio.enableAckPayload(); // Разрешить ответ приемника AckPayload radio.setRetries(50,10); // Количество пауза и количество повторов // Рекомендуют первые 2-4 байта адреса устанавливать в E7 или 18 он проще детектируется чипом radio.openWritingPipe(0xE7E7E7E7E1LL); // передатчик radio.openReadingPipe(1,0xE7E7E7E7D2LL); // приемник radio.startListening(); radio.powerDown(); return true; } // Посылка пакета bool sendRadio(void) { bool send_packet_ok=false; // Включение чипа nrf24 SetOutput(B,5); // slk - выход сделать SetOutput(B,3); // mosi - выход сделать SPI.begin(); // старт spi заново radio.powerUp(); radio.stopListening(); // Остановить приемник перейти в режим передачи delay(2); // дать время на переключение cli(); radio.writeBlocking(&packet_0x30,sizeof(packet_0x30),200); // Writes 1 payload to the buffers send_packet_ok=radio.txStandBy(); if ( radio.isAckPayloadAvailable() ) // Ждем получения -- основной блок передает текущее время radio.read(&tt,sizeof(tt)); //... и имеем переменную tt с временем от приемника. sei(); #ifdef DEBUG if (send_packet_ok==true) { Serial.println(F("Packet sending ++++++++++")); LedBlink(1, 10);} else Serial.println(F("Packet NOT sending -----------")); Serial.flush(); #endif // Выключение чипа nrf24 radio.powerDown(); // выключаем чип но это не все!!! SPI.end(); // выключаем SPI PullUp(B,5); // slk - сделать входом и подтянуть к 3.3 вольтам PullUp(B,3); // mosi - сделать входом и подтянуть к 3.3 вольтам packet_0x30.count++; // при переполнении сам сбросится } // Помигать светодиодом на 5 ноге N раз длительность t мсек void LedBlink(int n, int t) { int i; SetOutput(D,5); // 5 ногу на вывод WritePort(D,5,LOW); // Погасить светодиод for(i=1;i<=n;i++) { WritePort(D,5,HIGH); // зажечь светодиод delay(t); WritePort(D,5,LOW); // Погасить светодиод if ((n>1)&&(i<n)) delay(500); // если один раз или последний раз то задержка не нужна } SetInput(D,5); // 5 ногу на вход } void reset_sum(void) // Сброс счетчиков накоплений { sensor.num=0; sensor.Vcc=0; sensor.Temp=0; sensor.relH=0; sensor.absH=0; sensor.P=0; } // Измерение датчика bool measurement(void) { char status; double T,P,p0,a; packet_0x30.error=0; pinMode(10, OUTPUT); digitalWrite(10, HIGH); delay(10); pressure.begin(); status = pressure.startTemperature(); if (status != 0) { delay(status); status = pressure.getTemperature(T); packet_0x30.error=pressure.getError(); // Запомнить ошибку if (status != 0) { #ifdef DEBUG Serial.print(F(" Temperature: ")); Serial.print(T,2); #endif status = pressure.startPressure(3); if (status != 0) { delay(status); status = pressure.getPressure(P,T); packet_0x30.error=packet_0x30.error+8*(pressure.getError()); // Запомнить ошибку if (status != 0) {; #ifdef DEBUG Serial.print(F(" C absolute pressure: ")); Serial.print(P,2); Serial.println(F(" mb")); Serial.flush(); #endif } else {; #ifdef DEBUG Serial.println("error retrieving pressure measurement\n"); #endif } } else {; #ifdef DEBUG Serial.println("error starting pressure measurement\n"); #endif } } else {; #ifdef DEBUG Serial.println("error retrieving temperature measurement\n"); #endif } } else {; #ifdef DEBUG Serial.println("error starting temperature measurement\n"); #endif } digitalWrite(10, LOW); pinMode(10, INPUT); if (packet_0x30.error==0) // Если нет ошибок усредняем { sensor.num++; sensor.Vcc=sensor.Vcc+readVcc(); sensor.Temp=sensor.Temp+T*100; sensor.P=sensor.P+P*10; } }
Фото для понимания конструктива
Уф много букв.....
Кто дочитал до конца Молодец -))
Зачем толстый кондер сверху?
Электролит, по питанию... Акумулятор понравился, компактный
yucan, "nrf24 - все соединено по классике" Это как? Я прочёл, но так и не понял как вы запитали NRF24. И вполне возможно, что "Периодически теряется связь с датчиком, Выснил что проблема в датчике. Включение выключение датчика помогает." есть как раз следствие неправильного подключения.
pav2000, спасибо, интересно.
> это дало диапазон напряжений 3-4 вольта
Уточните в даташите. По-моему, для nrf24l01+ максимальное допустимое напряжение питания 3.6 В. Вы рискуете давая 4.
yucan, "nrf24 - все соединено по классике" Это как? Я прочёл, но так и не понял как вы запитали NRF24. И вполне возможно, что "Периодически теряется связь с датчиком, Выснил что проблема в датчике. Включение выключение датчика помогает." есть как раз следствие неправильного подключения.
Это пишет автор темы...
yucan, да проглядел)
pav2000, я использую следующий способ определения наличия радио модуля и вам предлагаю заменить 254 строку на
return radio.getChannel() == NRF24_CHANEL;
хотя, лучше это проверить раньше, сразу после setChannel
По питанию nrf24.
Питание nrf24 соеденино с Vcc и с "+" батареи напрямую. По питанию стоит кондесатор 470 мкф. Сейчас напряжение питания 3.54 вольта и находится в допустимых приделах. Надо еще керамику припаять на плату nrf24 1-2 мкф для спокойствия. Хотя может и здесь проблема т.е. 3.6 "китайские" могут быть меньше 3.54 "европейским"
Дипапазон 3-4 вольта был мною установлен только при ВЫБОРЕ батарии, т.е я решил не брать 1.5 вольта, 6 вольт. И выбрал батарею с напряжеинем (максимальным) 3.6 вольта помня об nrf24.
Сейчас моя идея о потери связи связана с тем что nrf24 не успевает просыпаться а я уже шлю команды. Поставил (увеличил) задержку - пока блок работает без сбоев более 20 часов.
Спасибо конечно "return radio.getChannel() == NRF24_CHANEL;" .
Но вставлять ее тогда надо не в функцию SetRadio которая устанавливает настройки nrf24 и вызавается один раз при старте (вероятность что будет все ОК приближается к 100%). Ставить ее на в SendRadio - функцию отправки пакета и делать механизм повтороной (например до 5 раз) отправки (возможно и инициализации nrf24) пакета.
О . . . Пока писал пришла шикарно-богатая идея. В ЕЕПРОМ писать лог ошибок что бы потом разобраться что происходит. Тем более часики есть. Обязательно прикручу.
И все таки смысл установки кондера на аккумулятор от меня как-то ускользает, видимо, по причине глубины мысли. Батарея, в определенном смысле, сама является офигенным конденсатором и добавлять еще один маленький -- это, как приделать к автомобилю еще одно маленькое колесико сбоку, с целью улучшения ходовых качеств.
И все таки смысл установки кондера на аккумулятор от меня как-то ускользает, видимо, по причине глубины мысли. Батарея, в определенном смысле, сама является офигенным конденсатором и добавлять еще один маленький -- это, как приделать к автомобилю еще одно маленькое колесико сбоку, с целью улучшения ходовых качеств.
Все примерно так, но есть нюансы. Есть еще внутреннее сопротивление источника. Оно влияет на выходное напряжение.
Сначала конденсатора вообще не было, и стояла плата nrf24 с усилителем. Передача вообще не работала. При этом при питании от ft232 с его внутреннем источником в 50 мА было все ок. Почему так для меня загадка.
Добавление конденсатора и уменьшение выходной мощности решили (уровень low) проблему. При замене на радиомодуль без усилителя я конденсатор оставил (при этом уровень мощности установлен максимальный).
Nrf24 очень требовательна к питанию.
Это похоже на шаманство но без него не работало.
Может без него не корректно сброс работает? Я не знаю.
По поводу Nrf24 и той или иной неработоспособности, в одном из форумов очень неплохо обсуждается и проблема остаётся.
http://forum.mysensors.org/topic/1664/which-are-the-best-nrf24l01-module...
Конденсатор по питанию ставят для подавления помех, сглаживания пульсаций и для "размазывания" короткоимульсного характера потребления значительных токов. Это не все случаи, но наиболее частые. В вашей ситуации батарея 14250 имеет рабочий ток на порядок (в десять раз) превышающий максимальный ток потребления NRF24L01 и при этом ее внутреннее сопротивление настолько мало, что она будет самым замечательным образом гасить все самые мощные помехи, пришедшие снаружи.
Кондер имел бы смысл, если бы устройство работало у вас от часовой батарейки, которая не в состоянии обеспечивать рабочих токов для передатчика. Тогда, кондер бы заряжался в промежутках между работой передатчика и отдавал большие токи, когда в них возникала потребность. На вашей схеме в таком режиме он не будет работать, скорее всего, никогда.
На фото как раз "часовая" батарея, из опыта емкостей по питанию очень часто не хватает в связи с неправельным расчетом или их усыханием.
Читаем мануал от ROBITON ER14250 в подразделе MAIN APPLICATION:
- Utility mettering
- Alarms and security devices
- Memory back-up
- Tracking systems
- Automotive electronics
- Professional electronics
Вы видите здесь "часы" ? Я нет. Зато часы указаны в батарейках серии, скажем, CRxxxx. Вы уже начинаете догадываться, что должно называться часовой батарейкой?
Какое "усыхание" у литиевой батареи ? Очнитесь.
Конденсатор по питанию ставят для подавления помех, сглаживания пульсаций и для "размазывания" короткоимульсного характера потребления значительных токов. Это не все случаи, но наиболее частые. В вашей ситуации батарея 14250 имеет рабочий ток на порядок (в десять раз) превышающий максимальный ток потребления NRF24L01 и при этом ее внутреннее сопротивление настолько мало, что она будет самым замечательным образом гасить все самые мощные помехи, пришедшие снаружи.
Полностью согласен. НО без кондесатора nrf24 с усилителем (ток до 100 ма) отказывалась работать. Я тоже думал в начале что все ок уж батарейка справится с током.
Как это объяснить. Установка кондесатора и уменьшение выходной мощности исправили это дело.
Это конкретный случай.
Возможно батарейка не соответвует заявленным параметрам.
Какое "усыхание" у литиевой батареи ? Очнитесь.
Часть даташита с токами религия не позволила прочитать?
CR2032 в разы более устойчива к импульсным нагрузкам, 20 мА 15 с против 50 мА 0,1 с у ER14250.
Сохнут электролиты.
Доработал код.
1. Увеличил время включения nrf24. После этого потерь связи почти нет, но еще изучаю этот вопрос.
2. Поставил механизм записи ошибок в еепром и возможность их вывода в последовательный порт. Внимание в режиме отладки необходимо для запуска блока подать команду в последовательный порт, без этого он будет ждать команду.
Для ловли ошибок надо сначала загрузить прошивку с опцией // #define DEBUG. Прошика будет работать и накапливать ошибки. Для просмотра раскоментировать // #define DEBUG и по последовательному порту можно будет посмотреть накопленные ошибки.
Правильное время лога выставляется ТОЛЬКО при связи с головным блоком.
Я вам могу задать тот же вопрос.
Вот даташит по часовым батарейкам Panasonic. Если мне не изменяет зрение, то рекомендованный ток потребления там указан в 200 микроампер и никаких имульсных значений не приводится вовсе. Зато есть график, на котором дается падение выдаваемого напряжения в зависимости от нагрузки. Так нагрузив батарейку током 2.5ма, напряжение упадет до 2.7в. Как-то я не очень разделяю ваш оптимизм насчет 20ма в течение 15с.
Вот даташит по часовым батарейкам Panasonic. Если мне не изменяет зрение, то рекомендованный ток потребления там указан в 200 микроампер и никаких имульсных значений не приводится вовсе. Зато есть график, на котором дается падение выдаваемого напряжения в зависимости от нагрузки. Так нагрузив батарейку током 2.5ма, напряжение упадет до 2.7в. Как-то я не очень разделяю ваш оптимизм насчет 20ма в течение 15с.
Этот режим используется в пультах д.у., даташиты с его описанием находятся по строке поиска "CR2032 pulse load" форум крив и не позволяет ничего вставить.
Подобрал времена, включения nrf24, теперь связь не теряется. Проверял трое суток, все ок.
Для увеличения дальности припаял кусок провода (83 мм) к печатной антенне (гуглил инет). Дальность возрасла где то в два раза. Теперь уверенный прием по всей квартире.
Последняя версия исходника:
Фото блока с "антенной"
Прием данных на удаленный блок
Очень интересная тема, собираюсь делать сеть регистраторов, типа метиостанция, питание будет сетевое с резервированием банками 18650 и передачей на ПК для анализа.
Хорошая тема, для себя тоже многое найду.
Хотел бы по поводу питания. Этот робитон, есть мнение, не справляется с токами включения. По самому робитону даташита не нашёл, сайт их висит, тот что давал человек выше в этой теме, на аналог - http://www.evebattery.ru/datas/menu/eve/er14250_eve.pdf - 15мА - максимальный! продолжительный ток. При это задуманный производителем нормальный ток отдачи таких батареек - 2 мА.
То есть 100мА (нрф с усилителем) она никак не вытягивает, 20мА (обычная нрф) - с трудом. Потому и понадобились вам чуднЫе конденсаторы и пляски с пролжительностями включения и тд.
pav2000, учитесь кроме кода и схемы рисовать, а то моветон получается какой то..
pav2000, времени прошло прилично со дня создания. Мне интересно сколько батарейка прожила? год хотя бы выдержала?
:) Примерно в то же время, создания топика, делал себе термометр на улицу. Сначала было на 27МГц, плохо было, не дальнобойно, не всё доходило и тп. Сделал на nrf, заработало сразу, передавало данные каждые 4 минуты, использовал 2ААА батарейки, через полгода батарейки сели, поставил новые - сразу сели, потом обнаружился паучёк умерший на плате датчика, а тк питание датчику я не снимал, он и начал жрать. Тогда переделал датчик, ну в смысле больше прошивку, полёт нормальный пока, напряжение на батарейках упало за месяц на 0.04v с учетом, что на улице мороз был.
Ну температура разная - всё в разное время делалось.
Ну и кривой но простой и рабочий код. Эх, спойлеров тут нет.
Можно выложить #include "LowPower.h"?
Нашел!
udavst, не могли бы Вы выложить и скетч серверной части?
Там в скетче очень много написано уже, больше 40КБ, а вот старую версию от тех-же часов, которые принимали с этого датчика и передавали дальше на базу - пожалуйста.
подпишусь