Как сделать переменную, объявленную внутри функции(цикла) глобальной?
- Войдите на сайт для отправки комментариев
Всем привет! Я использую код для отправки сообщений Telegram боту, совместимый с библиотекой "Universal Telegram Bot" и платой ESP32. Я инициализирую объект определяющий Telegram бот в void setup(), после того как я прочитываю токен Telegram бота, название WiFi сети и её пароль из файловой системы SPIFFS, а затем сохраняю эти данные в переменные. Если объявить этот объект внутри void setup(), сразу после того как мы прочитали нужные для отправки сообщений Telegram боту данные, то этот объект будет локальным, и его не получится использовать в других циклах. Я хотел бы узнать, как сделать его глобальным? PS: мой код может показаться для вас непонятным, поэтому если у вас возникнут вопросы, то задавайте их) Также, для проверки этого скетча вам понадобится немного ознакомится с SPIFFS. Буду рад вашим подсказкам)
#include <WiFi.h> #include <WiFiClientSecure.h> #include "SPIFFS.h" #include <UniversalTelegramBot.h> #include <ArduinoJson.h> String network_name = ""; String network_pass = ""; String telegram_bot = ""; String my_settings = "-"; int settings_length; int first_hash; int second_hash; int third_hash; int Bot_mtbs = 1000; long Bot_lasttime; WiFiClientSecure client; void setup() { Serial.begin(115200); if(!SPIFFS.begin(true)){ Serial.println("Ошибка при монтировании SPIFFS :("); return; } else { Serial.println("Монтирование SPIFFS прошло успешно!"); } File settings = SPIFFS.open("/Settings.txt"); if (!settings) { Serial.println("Не удалось открыть файл с настройками для чтения :("); return; } else { Serial.println("Файл с настройками успешно открыт для чтения!"); } Serial.print("Содержимое файла: "); while (settings.available()) { my_settings = settings.readString(); Serial.println(my_settings); settings_length = my_settings.length(); first_hash = my_settings.indexOf('#'); second_hash = my_settings.indexOf('#', first_hash + 1); third_hash = my_settings.indexOf('#', second_hash + 1); network_name = my_settings.substring(0, first_hash); network_pass = my_settings.substring(first_hash + 1, second_hash); telegram_bot = my_settings.substring(second_hash + 1, third_hash); flash_onoff = my_settings.substring(third_hash + 1, settings_length); Serial.print("Название WiFi сети: "); Serial.println(network_name); Serial.print("Пароль WiFi сети: "); Serial.println(network_pass); Serial.print("Токен Telegram бота: "); Serial.println(telegram_bot); Serial.print("Включение вспышки: "); Serial.println(flash_onoff); } settings.close(); Serial.println("Файл с настройками закрыт!"); if (my_settings != "-") { Serial.println("Режим WiFi сети запущен!"); Serial.print("Подключаемся к WiFi сети: "); Serial.println(network_name); WiFi.mode(WIFI_STA); WiFi.begin((const char*)network_name.c_str(), (const char*)network_pass.c_str()); while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.println("Подключились к WiFi сети!"); Serial.print("IP адрес платы ESP32 CAM: "); Serial.println(WiFi.localIP()); UniversalTelegramBot bot(telegram_bot, client); } } void loop() { bot.longPoll = 1; if (millis() > Bot_lasttime + Bot_mtbs) { int numNewMessages = bot.getUpdates(bot.last_message_received + 1); while (numNewMessages) { Serial.println("Получен ответ от Telegram пользователя!"); handleNewMessages(numNewMessages); numNewMessages = bot.getUpdates(bot.last_message_received + 1); } Bot_lasttime = millis(); } } void handleNewMessages(int numNewMessages) { for (int i = 0; i < numNewMessages; i++) { String chat_id = String(bot.messages[i].chat_id); String text = bot.messages[i].text; String from_name = bot.messages[i].from_name; if (from_name == "") from_name = "Гость"; if (text == "/start") { bot.sendMessage(chat_id, "Telegram бот запущен!", "Markdown"); } } }
В показанном мной коде, строки 55 и 60 лишние. Я взял этот скетч из моего другого, более сложного скетча
Надо этот объект заранее объявить глобальным.
В данном случае, нужно объявить этот объект после того как мы прочитали данные из SPIFFS памяти. Я пытался объявить этот объект после void setup(), но тогда этот код не работал, плата не подключалась к Telegram боту
Чем обусловлена такая последовательность объявлений?
Я пытался объявить этот объект после void setup(),
Надо объявить до setup()
Это обусловлено тем, что команду "UniversalTelegramBot bot(telegram_bot, client);" нужно объявить после того как в переменную "telegram_bot" мы сохраним токен Telegram бота
Про вот такие операторы ( https://docs.microsoft.com/ru-ru/cpp/cpp/new-and-delete-operators?view=m... ) чего нибудь знаете ?
Только, что узнал) Сейчас почитаю вашу статью
Насколько я понял, операторы new и delete нужны для выделения памяти. Вот только, как это можно применить в моём случае?
Мир Ардуинщиков, память для всех глобальных объектов выделяется ДО первого исполняемого оператора вне зависимости от места объявления в программе. Что именно Вы подразумеваете под "что команду "UniversalTelegramBot bot(telegram_bot, client);" нужно объявить после того как в переменную "telegram_bot" мы сохраним токен..."?
Обычно если размер некоторого неизвестного на момент старта программы элемента известен, этот объект объявляется обычным образом. Если примерно известен - можно объявить с максимальным размером. Если неизвестен даже ориентировочно, но заведомо влезает в ОЗУ, вместо объекта объявляется указатель на него, а память выделяется уже после того, как размер станет известным. Если же размер объекта может превышать объем свободного ОЗУ, объект не читается в память целиком, а разбирается на отдельные элементы по мере поступления.
Про вот такие операторы ( https://docs.microsoft.com/ru-ru/cpp/cpp/new-and-delete-operators?view=m... ) чего нибудь знаете ?
ты уже для микрософта доки пописываешь? )))
Про вот такие операторы ( https://docs.microsoft.com/ru-ru/cpp/cpp/new-and-delete-operators?view=m... ) чего нибудь знаете ?
Правильно - мелкомягкие это зло!