• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Deep sleep с пробуждением по кнопке

Beerukoff

New member
поставить шлюз типа ключевика двустороннего (например, мультиплексор или демультиплексор) подсоединить еспшку к флэхе через него.
Во время записи на флэху с помощью ключа отдельного гасить плэйер по команде с есп. Или, вернее, перед CRUD :) операциями гасить его - чтобы плэйер и еспшка не мешали друг другу во время работы с флэхой.
Закончили редактирование файлов с помощью есп - перещёлкиваем оба ключевика - отключаем есп от флэхи и поднимаем обратно плэйер.
С помощью Яндекса я, конечно, через некоторое время пойму, что именно вы предложили :)


Но для начала хочется все же научится правильно переходить в спящий режим (не обязательно DS) и выходить из него по нажатию кнопки.
 

Arthur

Active member
С помощью Яндекса я, конечно, через некоторое время пойму, что именно вы предложили :)


Но для начала хочется все же научится правильно переходить в спящий режим (не обязательно DS) и выходить из него по нажатию кнопки.
Тогда Google вам в помощь - SPIFFS.
 

Beerukoff

New member
Просто пока я до получения компонентов с Али читал разные статьи и форумы, мне казалось, что заснуть ЕСПшку несложно и это вполне себе штатный режим работы.
А вот сейчас во время написания кода никак не могу найти какой-то простой пример для видоизменения и использования
 

Arthur

Active member
Просто пока я до получения компонентов с Али читал разные статьи и форумы, мне казалось, что заснуть ЕСПшку несложно и это вполне себе штатный режим работы.
А вот сейчас во время написания кода никак не могу найти какой-то простой пример для видоизменения и использования
Не ясен тогда вопрос ваш - так вопрос в том, как проресетить корректно и подняться в нужное состояние? - или Я чего-то не понимаю и звучит вопрос как "Как сделать всё с нуля, покажите, пожалуйста, прошивки, код и схему?" :).
 

Beerukoff

New member
Сейчас не хватает только кода засыпания и просыпания.
Все остальное (пусть пока и по частям) я уже сделал (и схему, и код). Кнопка нажимается, музыка играет, лампочки мигают, веб сервер поднимается, громкость с андроид приложения регулируется
 

pvvx

Активный участник сообщества
А если не погружать в DS, а просто отключать все, что можно отключить (кроме канала контроля кнопки), то насколько меньше проработает устройство от батареек?
У вас снова - питание от АКБ или батареек. Это уже часть внешней схемы у модуля и вопрос не в сколько потребляет модуль, когда спит, а сколько жрет внешний стабилизатор и система пробуждения по кнопке.
Не забываем и про контроль разряда АКБ. В итого у вас, если по самому простому, 2 микросхемы и индикатор разряда (например при нажатии этой одной кнопки он быстро мигает в течении n секунд с замедлением - индикация разряда батареи).
Тут кто-то просил схему - получите и распишитесь. :)
tststst.gif
Все условия тут выполнены - контроль разряда с ADC(! :eek:), стабилизатор и использование 1-го порта двунаправленных DIO сигналов для передачи кодов кнопки к ESP и кода отключения от EPS.
Стабилизатор импульсный, с более менее КПД, можно махнуть и на другой - при рисовании схемы такой первый выпал - не выбирал.
Схема умещается между выводами ESP8266 :)
Номера ног у I/O PIC10 делаются по разводке, а не по схеме - потом перепрограмируете, а провода потом перепаивать сложнее :)
 
Последнее редактирование:

Arthur

Active member
У вас снова - питание от АКБ или батареек. Это уже часть внешней схемы у модуля и вопрос не в сколько потребляет модуль, когда спит, а сколько жрет внешний стабилизатор и система пробуждения по кнопке.
Не забываем и про контроль разряда АКБ. В итого у вас, если по самому простому, 2 микросхемы и индикатор разряда (например при нажатии этой одной кнопки он быстро мигает в течении n секунд с замедлением - индикация разряда батареи).
Тут кто-то просил схему - получите и распишитесь. :)
Посмотреть вложение 3800
Все условия тут выполнены - контроль разряда с ADC(! :eek:), стабилизатор и использование 1-го порта двунаправленных DIO сигналов для передачи кодов кнопки к ESP и кода отключения от EPS.
Стабилизатор импульсный, с более менее КПД, можно махнуть и на другой - при рисовании схемы такой первый выпал - не выбирал.
Схема умещается между выводами ESP8266 :)
Чот Вы загнули чутка, слишком далеко вперёд прыгнули, с контролем разряда и потреблением тока стабилизатором...
Мы пока что ещё с дип слип ещё не разобрались, какой контроль разряда... )
 

Beerukoff

New member
Я планировал запитать от двух АА батарей (в разбираемой игрушке так) напрямую. Насколько я понял пока батарейки довольно свежие все должно работать и так.

Мне просто хочется ограничиться использованием nodemcu, dfplayer и динамика, а все остальное уже есть в игрушке. Во всяком случае на бредборде все работает (правда пока с питанием от USB). Плюс находил в интернете статьи как ардуина может измерять питающее напряжение, чтобы понять остаток батареек. Если разберусь, тоже приделаю с выводом его через веб-сервер.

А потом, если батарейки будут садиться очень быстро, уже думать дальше
 
Последнее редактирование:

pvvx

Активный участник сообщества
Чот Вы загнули чутка, слишком далеко вперёд прыгнули, с контролем разряда и потреблением тока стабилизатором...
Мы пока что ещё с дип слип ещё не разобрались, какой контроль разряда... )
Ну такой простой - села или не батарейка. Как узнать то, если нет индикатора?
И так самый примитив нарисовал - концепцию. Можно взять с проц другой буквой - с немного большей программной памятью и на пару выводов, выкинуть второй чип, а поставить два мосфета - будет и контроль заряда АКБ и импульсный стабилизатор :)
Размеры то всё равно останутся почти те-же, типа 5x8 мм :) :) У нас же самая большая и главная деталь - кнопка, светодиод и динамик. Всё остальное - это второстепенные деталюшки и должны укладываться между основными :)
И не совсем понятно - если главные задачи у устройства - управление динамиком, то при чем тут deep_sleep и другие нюансы типа Arduino, SPIFFS и прочих никчемных решений для неё? Это обязательная нагрузочная часть решения задачи управления динамиком с автономным питанием? :eek: Типа потупим по тупиковым внедренным в мозх системам, не годящихся для решения данной задачи?
 
Последнее редактирование:

pvvx

Активный участник сообщества
Мне просто хочется ограничиться использованием nodemcu,
У NodeMCU проблемы с deep_sleep и RESET. Размер деталей и их кол-во для доработки NodeMCU до рабочего варианта, годящегося под описание, больше чем использование пустого модуля.
Но не исключаю, что эта переработка NodeMCU и есть главная задача в данном развлечении...
 

Arthur

Active member
"Зевнул и потянулся" - Скучно это всё, господа, скучно.
Интересно было бы в дальнейшем узнать, будет ли этот проект реализован и что получится...
У меня часто получается вот в таком стиле:
upload_2017-3-30_17-25-25.jpeg
 

pvvx

Активный участник сообщества
Уже реализовал. Кнопка включается на PB_1, в модуль заливаем немного модифицированную прошивку MP3. К питанию модуля подключаем любой современную импульсную микруху на дцать МГц со встроенным в корпус дросселем и остальными причендалами. Подключаем через сборку двух мосфет один динамик на один канал и второй для стерео - аналогично. Включаем, нажимаем кнопку - модуль стартует и поет песни с внешнего URL в формате MP3. Такая замена за 200 рупь Хиаоми MP3, но стерео. Жмыкаем кнопку ещё раз - переключается радиостанция. Давим кнопку дольше - модуль упал в deep_sleep. Модуль всего-то другой, на 30 руб дороже, но не надо думать о кнопке старта...
 

Arthur

Active member
Уже реализовал. Кнопка включается на PB_1, в модуль заливаем немного модифицированную прошивку MP3. К питанию модуля подключаем любой современную импульсную микруху на дцать МГц со встроенным в корпус дросселем и остальными причендалами. Подключаем через сборку двух мосфет один динамик на один канал и второй для стерео - аналогично. Включаем, нажимаем кнопку - модуль стартует и поет песни с внешнего URL в формате MP3. Такая замена за 200 рупь Хиаоми MP3, но стерео. Жмыкаем кнопку ещё раз - переключается радиостанция. Давим кнопку дольше - модуль упал в deep_sleep. Модуль всего-то другой, на 30 руб дороже, но не надо думать о кнопке старта...
Я про проект ТСа грил...
 

Beerukoff

New member
В итоге за 3 дня фонового изучения языка (читал статьи, форумы, искал подходящие примеры, понимал логику языка) сделал следующий скетч, который делает все из моего ТЗ, кроме перехода в энергоэкномичный режим (не обязательно deep sleep) по истечению определенного времени

Код, наверняка, не оптимальный, но во всяком случае он работает. Обратную связь по вывод инфы в монитор порта в конце уберу

Код:
#include <Arduino.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <ESP8266WiFi.h>

//Распиновка
int button = D0;
int MP3BusyPin = D1;
int MP3Com1 = D3;
int MP3Com2 = D4;
int led1 = D5;
int led2 = D6;
int led3 = D5;

//Параметры wi-fi сети
const char* ssid = "WiFiVillage";
const char* password = "***";

//Параметры для светодиодов
const byte totalLEDs = 3; // Number of LEDS used -- number <255 so use a byte or uint8_t
const byte ledPin[totalLEDs] = {led1,led2,led3}; //Pins assigned to those LEDS -- number <255 so use a byte or uint8_t
boolean ledState[totalLEDs] =   {0,0,0}; // What is the current LED state -- used a byte to store true/false as boolean since it is ON or OFF (0 or not 0)
unsigned int ledOn[totalLEDs] = {0,0,0}; // used to store ON times, using unsigned int to hold time up to 65535 ms) -- used INT (16 bits to store larger values
unsigned int ledOff[totalLEDs] ={0,0,0}; // used to store OFF times, using unsigned int to hold time up to 65535 ms) -- used INT (16 bits to store larger values
unsigned long previousMillis[totalLEDs] = {0,0,0}; // What time was the LED last tumned OFF -- Needs to store largest possible value (4 bytes used)
unsigned long currentMillis;

//Начальная громкость
int MP3Vol = 1;

WiFiServer server(80);
//Описание ответов вебсервера
int i;
char* Ans[]={"Volume +", "Volume -", "Play Next"};

SoftwareSerial mySoftwareSerial(MP3Com1, MP3Com2); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

static unsigned long timerMP3;

void setup()
{
  pinMode(button, OUTPUT);
  pinMode(MP3BusyPin, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  mySoftwareSerial.begin(9600);
  Serial.begin(115200);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(MP3Vol);  //Set volume value. From 0 to 30
  myDFPlayer.next();  //Play the first mp3
  timerMP3 = millis();

// Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");
  // Print the IP address
  Serial.println(WiFi.localIP());

  //Настройка светодиодов
  for (byte currentLED=0; currentLED<totalLEDs; ++currentLED)
  {
    pinMode(ledPin[currentLED], OUTPUT); //initilize all used LED pins as outputs
    digitalWrite(ledPin[currentLED], LOW); //Turn LEDs off to start
  }

}

void loop()
{

if(digitalRead(button) == HIGH && digitalRead(MP3BusyPin) == HIGH)
{
PlayMP3:
Serial.println("play MP3");
myDFPlayer.next ();
timerMP3 = millis();

//delayplay = 0;
}

//Раздел выбора следующего MP3 при нажатии на кнопку во время проигрывания текущего
if (millis() - timerMP3 > 2000 && digitalRead(button) == HIGH && digitalRead(MP3BusyPin) == LOW)
  {
      myDFPlayer.next();
      timerMP3 = millis();
  }


//Раздел мигания светодиодами во время проигрывания MP3
if(digitalRead(MP3BusyPin) == LOW)
{

  currentMillis = millis();           // Get the current time

  for (byte currentLED=0; currentLED<totalLEDs; ++currentLED)
{
  if (currentMillis - previousMillis[currentLED] > (ledState[currentLED] ? ledOff[currentLED]:ledOn[currentLED])){   // using a conditional operator
    digitalWrite(ledPin[currentLED], ledState[currentLED] = !ledState[currentLED]);    // Flip the state and output it
 
    (ledState[currentLED] == 0) ? ledOn[currentLED]=random(400, 800) : ledOff[currentLED]=random(800, 1400);
   
    previousMillis[currentLED] = currentMillis;  // reset the blinker time
   }
}
}

//Выключение светодиодов при тишине
if(digitalRead(MP3BusyPin) == HIGH && digitalRead(button) == LOW)
{
  for (byte currentLED=0; currentLED<totalLEDs; ++currentLED)
  {
    digitalWrite(ledPin[currentLED], LOW); //Turn LEDs off to start
  }
}

//  if (myDFPlayer.available()) {
//    printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
//  }
//}





  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();

   // Match the request
  if (req.indexOf("/BeerukoffaMusicBox/1") != -1)
  {
    i=0;
    MP3Vol++;
    myDFPlayer.volume (MP3Vol);
  }
  else if (req.indexOf("/BeerukoffaMusicBox/0") != -1)
  {
    i=1;
    MP3Vol--;
    myDFPlayer.volume (MP3Vol);
  }
  else if (req.indexOf("/BeerukoffaMusicBox/2") != -1)
  {
    i=2;
    myDFPlayer.next ();
  }
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }
  Serial.println(Ans[i]);
  client.flush();

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\ ";
  s += Ans[i];
  s += "</html>\n";
  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

}


void printDetail(uint8_t type, int value){
  switch (type) {
  case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

Звук регулируется таким приложением на телефоне

Все соединено на бредборде, питается пока от USB и ждет второго (железячного) этапа.

Теперь разбираюсь с засыпанием устройства по таймеру неактивности
 

pvvx

Активный участник сообщества
кроме перехода в энергоэкномичный режим (не обязательно deep sleep) по истечению определенного времени
Ну нету у ESP8266 возможности засыпания с просыпанием по кнопке с его SDK от Espressif, который и используется в Arduino. Надо что-нибудь довешивать.
Теперь разбираюсь с засыпанием устройства по таймеру неактивности
Команда system_deep_sleep_set_option() и system_deep_sleep() в SDK работают. Сложностей там вроде нет, кроме времени исполнения (времени от подачи команды до отключения - он потупит не менее 0.1 сек и отключиться).
Ошибка в system_deep_sleep() во всех последних SDK, ставящая неправильный флаг для следующего просыпания вам не помешает. (Ошибка связана с тем, что по последующему просыпанию система считает, что перезагрузилась по причине "протектед", а не по "deep_sleep" и соответственно будет полностью инициализировать WiFi, а не как это описано в документации. Причина в неправильном коде процедуры в iram переключения процессора в deep_sleep и аппаратно отключив flash он по ret в ней успевает возвращаться в коды flash, а там уже неопределенный код... и успевает сработать "протектед", записывая в RTC память причину перезагрузки по ошибке... Т.е. ошибка плавающая - успеет или не успеет нарваться в отключенном "кэш" на кривую инструкцию. На 160 MHz - успевает всегда...).
 
Последнее редактирование:

Beerukoff

New member
Значит буду просто wifi вырубать и смотреть сколько в таком случае от батарек работать будет.
 

Сергей_Ф

Moderator
Команда форума
Beerukoff, на nodeMCU WiFi вырубать бессмысленно. Линейный стабилизатор все равно будет жрать батарею.
 

pvvx

Активный участник сообщества
Посмотрите команды SDK wifi_fpm...()
В Arduino их реализации не видел.
 
Сверху Снизу