Какую ошибку я допускаю?
- Войдите на сайт для отправки комментариев
Всем добрый день.
Не первый раз сталкиваюсь с такой ситуацией - из разных кусков кода или работающих примеров собираю свой проект и компилятор стопорится на обьявленной функции void (что то там).
То есть, в работающем примере все компилируется без замечаний - когда переношу работающий код в свой проект - компилятор спотыкается с ругательством "*** was not declared in this scope".
Я не раз уже в справочниках читал как обьявлять функцию, вроде же все так в коде. Но итог один - в примере функция работает нормально - при переносе в мой проект ругается.
Явно что то упускаю.
#define ANALOG_PIN A0 #define CLOSE_WIN_FACTOR 10 // 1/X for narrowing window each side int winHi = 0, winLo = 1024; // store histeresis limits here int dataCur; // temporary storage of current data boolean ledState, ledStateOld; // current logic state float wattage = 0; // store current wattage float wattage_min = 0; float wattage_day = 0; float wattage_month = 0; int windowLo = 0; // bottom line of scale window in Wt int windowHi = 1000; // top line of scale window in Wt unsigned long previousMillis=0; int min_count = 0; float min_power = 0; void setup() { ESP.wdtDisable(); Serial.begin(9600); Serial.println("start"); initWindow(); // вызов функции вычисления значения порогов вкл и выкл состояния светодиода } void loop() { unsigned long currentMillis = millis(); dataCur = analogRead(ANALOG_PIN); // запоминаем значение на сенсоре findAnalogWindow(dataCur); // расширяем окно, если значение выходит за его пределы ledStateOld = ledState; // сохраняем в буфер старое значение уровня сенсора checkLogic(dataCur); // оцениваем состояние сенсора и сохраняем его значение в ledState // if (ledState == !ledStateOld) { // ИНДикатор только что изменил своё состояние // } if (ledStateOld && !ledState) { // ИНДикатор только что загорелся Serial.println("o"); } if (!ledStateOld && ledState) { // ИНДикатор только что погас Serial.println("*"); closeAnalogWindow(); // ужимаем пороги окна сенсора, чтобы они хронически не росли. min_count++; } if ((currentMillis - previousMillis) == 60000) { Serial.print("blink #="); Serial.println(min_count); Serial.print("min_power="); min_power = min_count*0.3125; Serial.println(min_power); previousMillis = currentMillis; min_count = 0; } ESP.wdtFeed(); } void initWindow() { unsigned long startTimer = millis() + 5000; while (millis() < startTimer) { dataCur = analogRead(ANALOG_PIN); findAnalogWindow(dataCur); } } void findAnalogWindow(int analogData) { if (analogData > winHi) winHi = analogData; // запомнить значение как верхнее, если оно выше него if (analogData < winLo) winLo = analogData; // запомнить значение как нижнее, если оно ниже него } void closeAnalogWindow() { if (winLo < winHi - 30) { int winDif = (winHi - winLo) ; // вычисляем ширину окна winHi = winHi - (winDif / CLOSE_WIN_FACTOR); // вычитаем 1/10 ширины из верхнего порога winLo = winLo + (winDif / CLOSE_WIN_FACTOR); // прибавляем 1/10 ширины к нижнему порогу } } void checkLogic(int analogData) { if (winLo < winHi - 5) { int percCur = map(analogData, winLo, winHi, 0, 99); // переводим значение в проценты от шкалы if (percCur <= 33) ledState = 0; if (percCur >= 66) ledState = 1; } }
Переношу весь код в свой проект - компиляцию не проходит - стопорится на первой же функции "initWindow()"
#include <ThingSpeak.h> #include <FS.h> #include <ESP8266WiFi.h> #include <ArduinoJson.h> #include <ESP8266WebServer.h> #include <DNSServer.h> #include <WiFiManager.h> const int PIN_LED = 4; // поменять на другой пин const char* CONFIG_FILE = "/config.json"; int led = LOW; // этой переменной устанавливаем состояние светодиода long previousMillis2 = 0; // храним время последнего переключения светодиода long interval = 500; // интервал между включение/выключением светодиода unsigned long starttime1=0; int temp = 5; bool initialConfig = false; // Indicates whether ESP has WiFi credentials saved from previous session // Default configuration values char thingspeakApiKey[17] = ""; // Function Prototypes bool readConfigFile(); bool writeConfigFile(); unsigned long myChannelNumber; // Thingspeak channel ID here int fieldStart = 1; int updatePeriod = 120; int status = WL_IDLE_STATUS; WiFiClient client; #define ANALOG_PIN A0 #define CLOSE_WIN_FACTOR 10 // 1/X for narrowing window each side int winHi = 0, winLo = 1024; // store histeresis limits here int dataCur; // temporary storage of current data boolean ledState, ledStateOld; // current logic state float wattage = 0; // store current wattage float wattage_min = 0; float wattage_day = 0; float wattage_month = 0; int windowLo = 0; // bottom line of scale window in Wt int windowHi = 1000; // top line of scale window in Wt unsigned long previousMillis = 0; int min_count = 0; float min_power = 0; void setup() { ESP.wdtDisable(); Serial.begin(115200); Serial.println("\n Starting"); pinMode(PIN_LED, OUTPUT); bool result = SPIFFS.begin(); // Mount the filesystem Serial.println("SPIFFS opened: " + result); if (!readConfigFile()) { Serial.println("Failed to read configuration file, using default values"); } WiFi.printDiag(Serial); //Remove this line if you do not want to see WiFi password printed if (WiFi.SSID() == "") { Serial.println("We haven't got any access point credentials, so get them now"); initialConfig = true; } else { digitalWrite(PIN_LED, HIGH); // Turn LED off as we are not in configuration mode. WiFi.mode(WIFI_STA); // Force to station mode because if device was switched off while in access point mode it will start up next time in access point mode. unsigned long startedAt = millis(); Serial.print("After waiting "); int connRes = WiFi.waitForConnectResult(); float waited = (millis()- startedAt); Serial.print(waited/1000); Serial.print(" secs in setup() connection result is "); Serial.println(connRes); } if (WiFi.status()!=WL_CONNECTED){ Serial.println("Failed to connect, finishing setup anyway"); } else{ Serial.print("Local ip: "); Serial.println(WiFi.localIP()); } Serial.println("Configuration portal requested"); digitalWrite(PIN_LED, LOW); WiFiManagerParameter p_thingspeakApiKey("thingspeakapikey", "Введіть ключ сервера статистики:", thingspeakApiKey, 17); WiFiManager wifiManager; // Initialize WiFIManager wifiManager.setTimeout(180); if (!wifiManager.startConfigPortal()) { Serial.println("Not connected to WiFi but continuing anyway."); } else { Serial.println("Connected...yeey :)"); // If you get here you have connected to the WiFi } wifiManager.addParameter(&p_thingspeakApiKey); // Getting posted form values and overriding local variables parameters // Config file is written regardless the connection state strcpy(thingspeakApiKey, p_thingspeakApiKey.getValue()); writeConfigFile(); // Writing JSON config file to flash for next boot digitalWrite(PIN_LED, HIGH); // Turn LED off as we are not in configuration mode. delay(5000); initWindow(); // вызов функции вычисления значения порогов вкл и выкл состояния светодиода } void loop() { unsigned long currentMillis = millis(); // is configuration portal requested? if (WiFi.status()!=WL_CONNECTED){ if(currentMillis - previousMillis2 > interval) { previousMillis2 = currentMillis; // сохраняем время последнего переключения // если светодиод не горит, то зажигаем, и наоборот if (led == LOW) led = HIGH; else led = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(PIN_LED, led); } } else{ digitalWrite(PIN_LED, HIGH); } dataCur = analogRead(ANALOG_PIN); // запоминаем значение на сенсоре findAnalogWindow(dataCur); // расширяем окно, если значение выходит за его пределы ledStateOld = ledState; // сохраняем в буфер старое значение уровня сенсора checkLogic(dataCur); // оцениваем состояние сенсора и сохраняем его значение в ledState // if (ledState == !ledStateOld) { // ИНДикатор только что изменил своё состояние // } if (ledStateOld && !ledState) { // ИНДикатор только что загорелся Serial.println("o"); } if (!ledStateOld && ledState) { // ИНДикатор только что погас Serial.println("*"); closeAnalogWindow(); // ужимаем пороги окна сенсора, чтобы они хронически не росли. min_count++; } if ((currentMillis - previousMillis) == 60000) { Serial.print("blink #="); Serial.println(min_count); Serial.print("min_power="); min_power = min_count*0.3125; Serial.println(min_power); previousMillis = currentMillis; min_count = 0; } ESP.wdtFeed(); if (currentMillis >= (starttime1 + 180000)) { starttime1 = currentMillis; ThingSpeak.setField(fieldStart,temp); ThingSpeak.writeFields(myChannelNumber, thingspeakApiKey); //Write fields to Thingspeak, comment this line out if you wish to test without uploading data. Serial.println("Data sent to ThinkSpeak"); } } bool readConfigFile() { // this opens the config file in read-mode File f = SPIFFS.open(CONFIG_FILE, "r"); if (!f) { Serial.println("Configuration file not found"); return false; } else { // we could open the file size_t size = f.size(); // Allocate a buffer to store contents of the file. std::unique_ptr<char[]> buf(new char[size]); // Read and store file contents in buf f.readBytes(buf.get(), size); // Closing file f.close(); DynamicJsonBuffer jsonBuffer; // Parse JSON string JsonObject& json = jsonBuffer.parseObject(buf.get()); // Test if parsing succeeds. if (!json.success()) { Serial.println("JSON parseObject() failed"); return false; } json.printTo(Serial); // Parse all config file parameters, override // local config variables with parsed values if (json.containsKey("thingspeakApiKey")) { strcpy(thingspeakApiKey, json["thingspeakApiKey"]); } } Serial.println("\nConfig file was successfully parsed"); return true; } bool writeConfigFile() { Serial.println("Saving config file"); DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.createObject(); // JSONify local configuration parameters json["thingspeakApiKey"] = thingspeakApiKey; // Open file for writing File f = SPIFFS.open(CONFIG_FILE, "w"); if (!f) { Serial.println("Failed to open config file for writing"); return false; } json.prettyPrintTo(Serial); // Write data to file and close it json.printTo(f); f.close(); Serial.println("\nConfig file was successfully saved"); return true; } void initWindow() { unsigned long startTimer = millis() + 5000; while (millis() < startTimer) { dataCur = analogRead(ANALOG_PIN); findAnalogWindow(dataCur); } } void findAnalogWindow(int analogData) { if (analogData > winHi) winHi = analogData; // запомнить значение как верхнее, если оно выше него if (analogData < winLo) winLo = analogData; // запомнить значение как нижнее, если оно ниже него } void closeAnalogWindow() { if (winLo < winHi - 30) { int winDif = (winHi - winLo) ; // вычисляем ширину окна winHi = winHi - (winDif / CLOSE_WIN_FACTOR); // вычитаем 1/10 ширины из верхнего порога winLo = winLo + (winDif / CLOSE_WIN_FACTOR); // прибавляем 1/10 ширины к нижнему порогу } } void checkLogic(int analogData) { if (winLo < winHi - 5) { int percCur = map(analogData, winLo, winHi, 0, 99); // переводим значение в проценты от шкалы if (percCur <= 33) ledState = 0; if (percCur >= 66) ledState = 1; } }
Спасибо за подсказку.
Правильно объявлять функцию ДО её использования. Перенесите Ваши функции наверх.
я не вьехал в структуру происходящего в функции
спасибо за помощь
И вы уверены, что нигде с фигурными скобками не накосячили?
народ выручайте. не могу понять что не так.
Aduino pro micro M590. суть проблемы в следующем. если отправлять запрос баланса mySerial.println("ATD#100#;")
из функции void loop() то все отлично, приходит OK далее ответ с балансом. Либо через терминал командой money или bal тоже все отлично. Но если отправляю эту комманду из своей функции т.е шлю СМС Money то ERROR и соответственно ничего не приходит.
По поводу команды, то пробовал и так mySerial.println("AT+CUSD=1,\"#100#\"");
Свою функцию вывел из-за разрастания основного тела команды.
Свою функцию вывел из-за разрастания основного тела команды.
что-то я не нашел в коде отдельной функции для баланса.
И непонятно. зачем после команды ATD#100# посылать в модем кучу мусора из сериала? - вот наверно на все эти "money" и 'balance' и приходит ЕГГОГ
smsadmin() полностью была в loop'е после 216.
Для баланса нет. Есть обработчик СМС команд в smsadmin()
какая строка?
smsadmin() полностью была в loop'е после 216.
Для баланса нет. Есть обработчик СМС команд в smsadmin()
Каких-либо явных ошибок в коде не вижу. Но это скорее плохая новость для вас. чем хорошая. Если бы была явная ошибка - был бы шанс отделаться малой кровью. А так, похоже, программу надо кардинально переписывать.
Проблемы скорее всего обьясняются нехваткой памяти, с которой (с памятью) вы образаетесь очень неэкономно. У вас в программе изначально большое количество строк - как констант, так и переменных класса String. И вы даже не пытаетесь уменьшить занимаемый ими обьем памяти- например положить во флеш, или избавиться от многократных сравнений строк в разном регистре. Вместо этого вы добавляете новую функцию, копируя в нее длинную строку val по значению! - это как выстрелить самому себе в ногу.
Что надо сделать в первую очередь
1. - во все функции smsadmin() smsunknown(). в которые передается длинное входящее СМС - его надо передавать по ссылке, а не копировать по значению
2. Все строковые константы уберите во флешпамять
3. Прежде чем искать во входящей строке подстроки, переведите все в верхний или нижний регистр - тогда не нужно будет искать отдельно "Money" "MONEY" b "money". Или воспользуйтесь функциями поиска подстрок без учета регистра.
4. Избавьтесь от переменных типа String (рекомендация)
Спасибо.
Тоже думал о памяти НО компилятор не ругается.
По поводу строковых констант это временно для отладки.
Можно еще "разжевать" по поводу первого пункта. Имееться ввиду *использовать указатель?
Нарооооооооооооооооооод.
ну давайте РЕПУ почешем.
Убрал все что можно.
даже так
Я вам написал. что происходит. Вы хоть один из пунктов. что я перечислил - пытались поправить? Пока не исправите - какой смысл вам что-то еще советовать?
Сейчас не поленился. подсчитал - у вас одни строковые константы в кавычках уже отжирают около 650 байтов оперативки! - треть всей доступной памяти!
все пункты выполнил
кроме 4
все пункты выполнил
кроме 4
пункт 1 - не выполнен
пункт 2 - процентов на 10%, не больше
пункт 3 - сделано совсем не то. что я писал... ну фиг с вами
пункт 4 - 0%
Я не пойму - вы как двоечник на экзамене, пытаетесь у учителя "выпросить" тройку? - да фиг с вами, не делайте совсем...
Избавился от ДВУХ строк
Неужели ТАК СЛОЖНО каждую строку завернуть в F(), и не тупить?
еще один умник
По поводу первого пункта я ЗАДАЛ ВОПРОС
НО вроде сам себе
еще один умник
давай-давай - обидься на нас и уйди. Зачем тебе выслушивать ехидные замечания каких-то умников? - Сделай все сам.
По поводу первого пункта я ЗАДАЛ ВОПРОС
НО вроде сам себе
самому себе задавать вопросы полезно, но не всегда продуктивно. Проще было пойти в гугль и написать что-нибудь типа "передача по ссылке vs передача по значению"
ты думаешь мы тут только и ждем, кому лекцию по Си прочитать?
я думаю если "Учитель" не может обьяснить то он сам плохо понимает.
А зачем вы здесь
к чему был это коментарий.
я думаю если "Учитель" не может обьяснить то он сам плохо понимает.
Вполне возможно, даже наверняка, что я многие аспекты языка знаю нетвердо. Однако у меня хватает смекалки, чтобы найти недостающее в гугле и разобраться в конкретном вопросе максимум за час-полтора, а не отвисать на форуме днями. выпрашивая ответы на вопросы, которые отлично разобраны в учебнике.
А зачем вы здесь
Такая специальная группа, доставлять удовольствие неофитам. И форум исключительно для этого придумали.
Ну, что то пока плохо получается. Удовольствия 0
А зачем вы здесь
Такая специальная группа, доставлять удовольствие неофитам. И форум исключительно для этого придумали.
+5
Глобальные переменные используют 1003 байт (48%) динамической памяти, оставляя 1045 байт для локальных переменных.
Думаю проблема не связана с памятью.
засунул в ФЛЭШ все что можно.
засунул в ФЛЭШ все что можно.
наверняка вранье.... как и раньше, про "выполненные все 4 пункта"
Было 1200 байт занято, я насчитал более 600 байт строк - значит после "всовывания во флеш всего" должно остаться примерно 600 байт занятых, а не 1000.
Ну и главное - п.1
ну вам виднее
ну так и есть - строки 165, 166, 167 и тд...
А вот эти вообще круть - 292, 296, 300, 304 - в одних этих сразу 100 байт
Все, надоело. Я тебе указал, ЧТО надо поправить. Это, без ложной скромности, самая ценная помощь. А КАК это сделать - ищи сам. Для этого есть учебники и интернет.
сколько еще мне памяти почистить????
На, болезный, поработал за тебя корректором:
Спасибо за 100 байт. НО вопрос ОСТАЛСЯ.
Не туда копаем.
По поводу НАХЕР. строка 161 и 184.
если их убрать то ответы приходят с ошибками.
По поводу НАХЕР. строка 161 и 184.
если их убрать то ответы приходят с ошибками.
потому что строки из Сериала собираешь неправильно. Нужно ждать конца строки, а не просто перерыва в 3 мс, как у тебя в коде.
Я так и не понял - п.1 ты победил или нет? Какой сейчас размер скетча и памяти? Главный вопрос решился?
По поводу НАХЕР. строка 161 и 184.
если их убрать то ответы приходят с ошибками.
Там это реально нахер, т.к. смысла ждать в delay, когда в приёмном буфере уже есть данные - онанизм. Если при комментировании этих строчек работает неправильно - проблема не в этих строчках, а в другом месте. Да там весь код - одна большая проблема, если честно.
По поводу НАХЕР. строка 161 и 184.
если их убрать то ответы приходят с ошибками.
потому что строки из Сериала собираешь неправильно. Нужно ждать конца строки, а не просто перерыва в 3 мс, как у тебя в коде.
Я так и не понял - п.1 ты победил или нет? Какой сейчас размер скетча и памяти? Главный вопрос решился?
Сильно не вникал, но сразу бросается в глаза indexOf, она регистрозависимая. Лучше подстраховаться и сделать toLowerCase() toUpperCase().
Пишите что через терминал все работает, а из вашей функции нет и при этом при использовании через терминал вы баланс через дозвон используете (ATD) а из "своей функции" через USSD команды. Может надо в этой стороне покопать.
У меня, например, МТС на USSD вообще через раз отвечает, приходит сообщение об ошибке а потом через пару минут смс с балансом.
З.Ы. Ну это так мысли не больше.
Сильно не вникал, но сразу бросается в глаза indexOf, она регистрозависимая. Лучше подстраховаться и сделать toLowerCase() toUpperCase().
Пишите что через терминал все работает, а из вашей функции нет и при этом при использовании через терминал вы баланс через дозвон используете (ATD) а из "своей функции" через USSD команды. Может надо в этой стороне покопать.
У меня, например, МТС на USSD вообще через раз отвечает, приходит сообщение об ошибке а потом через пару минут смс с балансом.
З.Ы. Ну это так мысли не больше.
indexOf согласен исправляю.
Пробовал и так "ATD#100#;" и так "AT+CUSD=1,\"#100#\"" В любом случае если командой balance вызывать из терминала все проходит и ни разу ошибки не было. А через СМС никак. Причем через СМС программа доходит до
нужного куска кода. А в ответ ERROR
Т.е. в сериале вы видите "MONEY TRUE" и следом "ERROR" именно "ERROR" а не "E R R O R"?
Т.е. в сериале вы видите "MONEY TRUE" и следом "ERROR" именно "ERROR" а не "E R R O R"?
ТТ
Вообще сей гаджет с сентября работает в гараже, можно сказать в экстриме. температура в гараже -15. ни разу электроника и софт не дали сбоя. Хотя и СПАМИЛИ СМСками и тд. Просто решил добавить Функцию "узнать баланс" . НУУУУ очень нужна.
А лога с терминала нет? Посмотреть что выдает если запрашивать баланс через смс. А то то что вы говорите с кодом не сходится.