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

Проблема с созданием точки доступа

DMENUX

New member
Очень странная ситуация, но когда я создаю точку доступа в методе setup, а в методе loop постоянно вывожу текст на дисплей - то точка доступа или исчезает или к ней невозможно подключиться. Если после создания точки доступа в методе setup вывести что-то на дисплей, а в методе loop убрать весь код для вывода текста на дисплей - то точка доступа будет работать без проблем, но мне необходимо выводить постоянно обновляющиеся данные. Для работы с дисплеем использую библиотеку iarduino_OLED_txt, т.к с ее помощью можно легко вывести русский текст на дисплей.
 

CodeNameHawk

Moderator
Команда форума
Код в лооп должен выполнятся "быстро", примерно так, вошли в лооп, нарисовали, отработали логику и вышли из лооп.
 

DMENUX

New member
вот мой код loop:
C++:
void loop()
{
  if (getBatteryPercentage() >= 1)
  {
    webServer.handleClient();
    //displayMenuOptions(getMenuOptions());
    //displayCursor(5, getCurrentCursorYCoord());
    //displayScrollBar(115, getCurrentScrollBarYCoord());

    if (mainMenuConfigured == true)
    {
      drawString(20, 7, "Charge: " + String(getBatteryPercentage()) + "% ");  
    }

    if (apInfoMenuConfigured == true)
    {
      drawString(20, 3, "Devices: " + String(WiFi.softAPgetStationNum()) + " ");
    }

    if (systemMenuConfigured == true)
    {
      drawString(20, 1, String(getBatteryVoltage(), 2) + "V");
      drawString(20, 2, String((float)ESP.getFreeHeap() / 1024, 2) + "(kb)");
      drawString(20, 3, getWorkingTimeStr());
    }

    if (curMenuOptions.size() > 0)
    {
      if (upButtonIsPress())
      {
        cursorYCoord--;
        if (curMenuOptions.size() > maxMenuOptionsOnScreen)
        {
          if (cursorYCoord < 0)
          {
            if (menuOffset > 0)
            {
              menuOffset--;
              cursorYCoord = 0;
            }
            else
            {
              menuOffset = curMenuOptions.size() - maxMenuOptionsOnScreen;
              cursorYCoord = (int)maxMenuOptionsOnScreen - 1;
            }
          }
          else if ((size_t)cursorYCoord + menuOffset > ((size_t)curMenuOptions.size() - 1))
          {
            menuOffset = 0;
            cursorYCoord = 0;
          }
          else if (cursorYCoord > (int)maxMenuOptionsOnScreen - 1)
          {
            menuOffset++;
            cursorYCoord = (int)maxMenuOptionsOnScreen - 1;
          }
        }
        else
        {
          if (cursorYCoord < 0)
          {
            cursorYCoord = curMenuOptions.size() - 1;
          }
          else if ((size_t)cursorYCoord > ((size_t)curMenuOptions.size() - 1))
          {
            cursorYCoord = 0;
          }
        }
      }

      if (downButtonIsPress())
      {
        cursorYCoord++;
        if (curMenuOptions.size() > maxMenuOptionsOnScreen)
        {
          if (cursorYCoord < 0)
          {
            if (menuOffset > 0)
            {
              menuOffset--;
              cursorYCoord = 0;
            }
            else
            {
              menuOffset = curMenuOptions.size() - maxMenuOptionsOnScreen;
              cursorYCoord = (int)maxMenuOptionsOnScreen - 1;
            }
          }
          else if ((size_t)cursorYCoord + menuOffset > ((size_t)curMenuOptions.size() - 1))
          {
            menuOffset = 0;
            cursorYCoord = 0;
          }
          else if (cursorYCoord > (int)maxMenuOptionsOnScreen - 1)
          {
            menuOffset++;
            cursorYCoord = (int)maxMenuOptionsOnScreen - 1;
          }
        }
        else
        {
          if (cursorYCoord < 0)
          {
            cursorYCoord = curMenuOptions.size() - 1;
          }
          else if ((size_t)cursorYCoord > ((size_t)curMenuOptions.size() - 1))
          {
            cursorYCoord = 0;
          }
        }
      }

      if (selectButtonIsPress() || selectButtonIsHold())
      {
        if (curMenuOptions.size() > maxMenuOptionsOnScreen)
        {
          curMenuOptions[cursorYCoord + menuOffset].optionFunc();
        }
        else
        {
          curMenuOptions[cursorYCoord].optionFunc();
        }
      }
    }
  }
  else
  {
    webServer.stop();
    WiFi.disconnect(true);
    WiFi.softAPdisconnect(true);

    clearDisplay();
    drawString(20, 3, "Need charging");
    while (true)
    {
      millisDelay(200);
      if (getBatteryPercentage() >= 5)
      {
        configureMainMenu();
        break;
      }
      yield();
    }

    createAccessPoint(apSsid, apPassword);
    startWebServer();
  }
}
 

DMENUX

New member
вот код drawString():
C++:
void drawString(uint8_t x, uint8_t y, String text)
{
  display.print(text.c_str(), x, y);
}
 

DMENUX

New member
если закоментить эти строчки - то точка доступа будет работать
C++:
if (mainMenuConfigured == true)
{
  drawString(20, 7, "Charge: " + String(getBatteryPercentage()) + "% ");
}

if (apInfoMenuConfigured == true)
{
  drawString(20, 3, "Devices: " + String(WiFi.softAPgetStationNum()) + " ");
}

if (systemMenuConfigured == true)
{
  drawString(20, 1, String(getBatteryVoltage(), 2) + "V");
  drawString(20, 2, String((float)ESP.getFreeHeap() / 1024, 2) + "(kb)");
  drawString(20, 3, getWorkingTimeStr());
}
 

DMENUX

New member
и проблема тут не в частом считывании аналогового пина, считывание происходит раз в 3 секунды.
вот код для получения приблизительного уровня заряда батареии:
C++:
float getBatteryVoltage()
{
  if (firstAnalogReadCompleted == false)
  {
    float voltage = (analogRead(batteryPin) * maxVoltage) / 1023.0;
    lastBatteryVoltage = voltage;
    batteryMillis = millis();
    firstAnalogReadCompleted = true;
    return voltage;
  }
  else if (millis() - batteryMillis >= 3000)
  {
    float voltage = (analogRead(batteryPin) * maxVoltage) / 1023.0;
    lastBatteryVoltage = voltage;
    batteryMillis = millis();
    return voltage;
  }
  else
  {
    return lastBatteryVoltage;
  }
}

int getBatteryPercentage()
{
  float volt = getBatteryVoltage();
  int percents = (int)roundf((volt - minVoltage) / (maxVoltage - minVoltage) * 100);
  if (percents > 100)
  {
    percents = 100;
  }
  else if (percents < 0)
  {
    percents = 0;
  }
  return percents;
}
 

CodeNameHawk

Moderator
Команда форума
Проблема в том, что в коде нет коментов.
По идее должен выполняться всегда, пока запущен веб сервер.
И самое очевидное займитесь отладкой, проверьте что сколько времени занимает, включите отладку сети в ардуиноиде.
 

esp340

Active member
Для работы с дисплеем использую библиотеку iarduino_OLED_txt,
вот код drawString():
C++:
void drawString(uint8_t x, uint8_t y, String text)
{
  display.print(text.c_str(), x, y);
}
Выбрось эти стринги и возьми нормальныеую трусы библиотеку http://arduino.ru/forum/proekty/aso...lya-oled-displeya-128kh64-s-kirillitsei-utf-8
 

DMENUX

New member
Выбрось эти стринги и возьми нормальныеую трусы библиотеку http://arduino.ru/forum/proekty/aso...lya-oled-displeya-128kh64-s-kirillitsei-utf-8
переход на эту библиотеку не помог решить проблему, однако эта библиотека куда лучше написана чем iarduino_OLED_txt и в целом она мне больше понравилась, так что я останусь на ней
 

DMENUX

New member
Как вы это определяете?
Точка доступа даже не появляется в списке активных wifi сетей, т.к ей что-то сильно мешает. Я бы мог предположить, что слишком частая отправка данных на дисплей каким-то образом мешает работе точки доступа, как и слишком частое считывания аналогового пина, но если сделать считывания пина раз в три секунды - не проблема, то с отправкой данных на дисплей так не прокатит. Не стоит так сильно замедлять дисплей. Я понимаю, что можно использовать куда меньшую задержку и для считывания пина и для отправки данных на дисплей, но если для дисплея требуется задержка больше 20мс - то это совершено не вариант.
Когда я пишу "задержка" я имею ввиду это:
C++:
unsigned long prevMillis = 0;
bool firstAnalogReadCompleted = false;

void t()
{
  if (firstAnalogReadCompleted == false)
  {
    // analogRead();
    prevMillis = millis();
    firstAnalogReadCompleted = true;
  }
  else if (millis() - prevMillis >= 3000)
  {
    // analogRead();
    prevMillis = millis();
  }
}
 

CodeNameHawk

Moderator
Команда форума
как и слишком частое считывания аналогового пина,
Была информация, что "частая" работа с аналоговым входом мешает работе есп, но у вас в тестовом скетче нет работы с ним, а вывод на экран должен работать.
 

DMENUX

New member
Была информация, что "частая" работа с аналоговым входом мешает работе есп, но у вас в тестовом скетче нет работы с ним, а вывод на экран должен работать.
Верно, в тестовом скетче нет работы с аналоговым входом. Я привел его как возможную аналогию проблемы с дисплеем. То есть как слишком частое считывание A0 мешает есп, так возможно слишком частая передача данных по i2c мешает работе esp
 
Сверху Снизу