Здравствуйте, подскажите что делаю не правильно, хочу отправить МК в сон, он уходит в сон, выходит только если нажать кнопку reset и снова в сон, так вот мне нужно чтоб он сам выходил из сна в заданное время и отсылал данные. в режиме сна МК+nrf24l01+ds18b20 расходует 5.2мА а если нажать кнопку то 18 мА. пин 2 подключен IRQ Код (C++): #include <OneWire.h> #include <DallasTemperature.h> #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <LowPower.h> #define ONE_WIRE_BUS 3 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature DS18B20(&oneWire); RF24 radio(9, 10); // Настройки uint64_t transmitter_addr = 0xAABBCCDD11LL; float max_voltage = 4.25; float min_voltage = 2.75; float R1 = 9.8; // Изменить! (Значение в кОм) float R2 = 1.0; // Изменить! (Значение в кОм) // Настройки int data; float temp[2]; float vin; float vbat; volatile bool rx_flag; void setup(){ DS18B20.begin(); radio.begin(); radio.setChannel(5); radio.setDataRate(RF24_250KBPS); radio.setPALevel(RF24_PA_HIGH); radio.openWritingPipe(0xAABBCCDD00LL); radio.openReadingPipe(1, transmitter_addr); radio.startListening(); analogReference(INTERNAL); } void loop(){ attachInterrupt(0, radio_check, FALLING); LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); detachInterrupt(0); radio.powerUp(); if(rx_flag){ DS18B20.requestTemperatures(); temp[0] = DS18B20.getTempCByIndex(0); vin = (analogRead(A0) * 1.1) / 1023; vbat = vin / (R2/(R1 + R2)); temp[1] = ((vbat - min_voltage) / (max_voltage - min_voltage)) * 100; radio.read(&data, sizeof(data)); if(data == 0){ radio.stopListening(); delay(100); radio.write(&temp, sizeof(temp)); radio.startListening(); } rx_flag = false; radio.powerDown(); } } void radio_check(){ bool tx, fail, rx; radio.whatHappened(tx, fail, rx); rx_flag = rx; }
для этого нужно задействовать ватчдог таймер А в вашем коде есть "сон навсегда", (SLEEP_FOREVER) а условия пробуждения по таймеру - нет. И еще - если МК потребляет в режиме сна 5 мА - это никакой не сон. Вы на чем это проверяете? - Если на готовой плате ардуино - это бессмысленно, надо сначала удалить с платы все лишнее - регулятор напряжения. чип UART и светодиоды - потому что все это потребляет в десятки раз больше, чем сам контроллер.
Не обязательно. ISP программатор при пытке установить связь с блоком внутрисхемного программирования держит ресет на нуле. В МК при этом никакой код не исполняется. Сон какой? Их там три. В любом случае читать даташит на МК на предмет того, что способно вывести МК из любого сна. У меня МК в рабочем режиме столько не жрет. Это если nRF24 сидит в дипслип. Но лучше его нафик выключить - он во сне до 1 мкА жрет. Это абсолютно позорное значение на фоне того же SiLabs, который во сне жрет в 20 раз меньше - 50нА.
32 кГц откуда? При ресете заводится тот осциллятор, который указан во фьюзах. По умолчанию RC на 8МГц. Если это дуня, то внешний на 8 или 16.
Написано что? Какой осциллятор запускается? Так в AVR вариантов не очень много. Точнее он один. Прескалер не сбрасывается по ресету. Но сбрасывается по подаче напряжения. Вернее туда записывается значение, определенное фьюзом. Всё это описано в даташите. Не понимаю, что я написал не так в предыдущем сообщении? В глубокий сон вообще пофигу с какой частоты уходить - в deep sleep не работает ровным счетом ничего - майн клок равен нулю герц. ОЗУ только там как-то сохраняется. Там важнее правильно ноги включить (или выключить), чтобы наводки не переключали входные транзисторы в триггере Шмитта. АЦП не забыть рубануть - его аналоговые цепи не подвластны тактированию. Не нужен BOD - заглушить программно или фьюзом. Ну и вачдог. Но у него свой асинхронный осциллятор. В уголочке сопит потихоньку))
Мне сразу подумалось, что речь про часовой кварц. Будет время - проверю. Только 328 надо найти. Или на тиньке посмотрю. Почему? Где что не так даташит описал? Только считать надо не ток, а энергию. А она кратна количеству переключений комплементарной пары. А количество переключений зависит от количества вычислений. А ну ещё кварц молотит на 8МГц. Из этих 8МГц ты предлагаешь 1 такт использовать на пользу, 249 вхолостую. Зачем? Опускать частоту необходимо только в одном случае - если того требует напряжение питания. В таких случаях я МК читаю на паразитном питании. Т.е. пин Vcc никуда не подключен. Хотя бы понимаешь, живой МК или нет.
В даташите на PB в регистре CLKPR напротив битов, отвечающих за коэффициент деления прескалера, указано X напротив RESET. В даташите на P стоит пометка "See bit descriptions". Как я считаю, даташит на PB более точен в описании: reset не сбрасывает эти биты. В обоих даташитах указано, что
Ещё есть нюанс: если работает АЦП, а мы тупо ждем его результат. Пусть вся периферия и заглушена (регистром PRR), но ЦПУ, FLASH тактируется. И вот здесь имеет смысл играться не прескалером АЦП, а прескалером осциллятора, чтобы за время измерения АЦП все остальные получили как можно меньше тактов. Экономия незначительная, но всё же.
А что я должен увидеть-то? Невозможность прошивки проца? Какое-то чудо с прескалером? Слет осциллятора?
готовая плата, подключен по +- по UART, после удаления одного светодиода потребляет в режиме сна 0.18 мА в режиме измерения 7мА, это нормально или можно измерение еще снизить? к плате подключено nrf24l01 и ds18b20 работает по таймеру, просыпается каждые 10 сек измеряет и уходит в сон, + с 3 пин взял на nrf24l01 он включается по нужде только
Не знаю, у меня голый МК (просто микросхема ATmega328P) + усиленный NRF (который с усилителем и антенной) + ds18b20 в режиме сна около 5 микроампер, т.е. 0,005mA