Как сделать переменную, объявленную внутри функции(цикла) глобальной?
- Войдите на сайт для отправки комментариев
Всем привет! Я использую код для отправки сообщений 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... ) чего нибудь знаете ?
Правильно - мелкомягкие это зло!