вопрос по памяти и не стабильной работе
- Войдите на сайт для отправки комментариев
Втр, 20/06/2017 - 12:11
Добрый день!
такой вопрос:
при компиляции кода выдается сообщение - Глобальные переменные используют 1805 байт (88%) динамической памяти, оставляя 243 байт для локальных переменных. Максимум: 2048 байт.
Недостаточно памяти, программа может работать нестабильно.
есть где то описание какой тип переменных сколько резервирует памяти, или я что-то не правильно понимаю и это зависит ни только от переменных?
подскажите пожалуйста
Добрый день!
такой вопрос:
при компиляции кода выдается сообщение - Глобальные переменные используют 1805 байт (88%)
Сколько памяти кушает простой тип Вы всегда можете узнать, напечатав его sizeof
// узнаём сколько памяти жрут переменные типов long и float Serial.print("long - "); Serial.println(sizeof(long)); Serial.print("float - "); Serial.println(sizeof(float));Что касается типа String, то он жрёт sizeof(String) + реальный размер строки.
Пробуйте, смотрите.
Пожалуйста, прочитайте в прикрепленной выше теме, как надо выкладывать код в форуме. Вы не заметили, что в других темах код выложен совсем по другому? Ваш код невозможно обсуждать.
Пока вижу это -
В массиве state у вас 4 элемента с индексами 0-3. Элемент state[4] находится за границей массива, не говоря уж о том, что вы присваиваете одному символу значение целой строки. С такой строкой у вас будут глюки даже при использовании памяти на 1%, я уж не говорю про 80
так правильно?
#include <SD.h> #include <SPI.h> #include <Ethernet.h> #include <stdio.h> #include <DS1302.h> #define SWITCH_TO_W5100 digitalWrite(4,HIGH); digitalWrite(10,LOW) #define SWITCH_TO_SD digitalWrite(10,HIGH); digitalWrite(4,LOW) #define ALL_OFF digitalWrite(10,HIGH); digitalWrite(4,HIGH) char state[4]="OFF"; File root; boolean newInfo = 0; byte server1[] = { 192,168,1,177 }; byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 }; byte ip[] = { 192, 168, 1, 177 }; //int num; char buf[29]; EthernetServer server(80); EthernetClient client; namespace { const int kCePin = 5; // Chip Enable const int kIoPin = 3; // Input/Output const int kSclkPin = 2; // Serial Clock DS1302 rtc(kCePin, kIoPin, kSclkPin); String dayAsString(const Time::Day day) { switch (day) { case Time::kSunday: return "Sunday"; case Time::kMonday: return "Monday"; case Time::kTuesday: return "Tuesday"; case Time::kWednesday: return "Wednesday"; case Time::kThursday: return "Thursday"; case Time::kFriday: return "Friday"; case Time::kSaturday: return "Saturday"; } return "(unknown day)"; } } void setup() { SWITCH_TO_W5100; pinMode(8, OUTPUT); pinMode(4, OUTPUT); pinMode(10, OUTPUT); Serial.begin(9600); Serial.println("Ethernet start"); Ethernet.begin(mac, ip); server.begin(); SWITCH_TO_SD; if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); printTime(); Serial.println(buf); ALL_OFF; } void loop() { EthernetClient client = server.available(); if(client){ //если запрос оканчивается пустой строкой boolean currentLineIsBlank = true; //ставим метку об окончании запроса (дословно: текущая линия чиста) while (client.connected()) { //пока есть соединение с клиентом if (client.available()) { //если клиент активен char c = client.read(); //считываем посылаемую информацию в переменную "с" if(newInfo && c == ' '){ //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке newInfo = 0; //то обнуляем переменную поступления новой информации } if(c == '$'){ //если переменная "с", несущая отправленный нам запрос, содержит символ $ //(все новые запросы) - "$" подразумевает разделение получаемой информации (символов) newInfo = 1; //то пришла новая информация, ставим метку новой информации в 1 Serial.println (newInfo); } if(newInfo == 1){ //если есть новая информация Serial.println(c); if(c == '1'){ //и "с" содержит 1 state[4] = "ON "; Serial.println(state); digitalWrite(8, HIGH); //то зажигаем светодиод readPage(buf); printTime(); Serial.println(buf); } if(c == '2'){ //если "с" содержит 2 state[4] = "OFF"; Serial.println(state); digitalWrite(8, LOW); //гасим светодиод readPage(buf); printTime(); Serial.println(buf); } } if (c == '\n') { //если "с" равен символу новой строки currentLineIsBlank = true; //то начинаем новую строку } else if (c != '\r') { //иначе, если "с" не равен символу возврата курсора на начало строки currentLineIsBlank = false; //то получаем символ на текущей строке } if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println("Refresh: 30"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.print("<title>My web Server</title>"); client.print("<H1>My web Server</H1>"); client.print("<a href=\"/$1\"><button>On</button></a>"); client.print("<a href=\"/$2\"><button>Off</button></a>"); // client.print("<img src=\ "http://upload-4249238ac8260d1ede4549359aadf4b1.commondatastorage.googleapis.com/iblock/34b/34b735f803df228d1d69a707b8d4dfa8.png" </a>"); client.println("<br />"); client.println("</html>"); break; } // Serial.println("http stop"); } } delay (10); client.stop (); } } void printTime() { // Get the current time and date from the chip. Time t = rtc.time(); // Name the day of the week. const String day = dayAsString(t.day); // Format the time and date and insert into the temporary buffer. snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec); // Print the formatted string to serial so we can see the time. // Serial.println(buf); return buf; } void readPage(char bufff[29]) { Serial.println("connecting..."); //конектимся к серверу по 80 порту if (client.connect(server1, 80)) Serial.println("connected"); client.stop(); printTime(); Serial.println(bufff); Serial.println("Disconnected"); root = SD.open("/"); printDirectory(root, 0, bufff); Serial.println("done!"); } void printDirectory(File dir, int numTabs, char buff[29]) { //SWITCH_TO_SD; root = SD.open("TEXTFILE.TXT", FILE_WRITE); if (root){ Serial.print("Осуществляется запись в файл"); printTime(); Serial.println(buff); root.print(state); root.print(" "); root.println(buff); Serial.print("WRITING COMPLETED"); root.close(); Serial.println(root); Serial.println("Файл успешно закрыт"); }else{ printTime(); Serial.println(buff); Serial.println("Ошибка при открытии файла"); } // delay (1); // num = num + 1; }Пока вижу это -
В массиве state у вас 4 элемента с индексами 0-3. Элемент state[4] находится за границей массива, не говоря уж о том, что вы присваиваете одному символу значение целой строки. С такой строкой у вас будут глюки даже при использовании памяти на 1%, я уж не говорю про 80
можно поподробнее?
у меня как раз была проблема с этим state я не могу понять как мне правильно объявить сьтроковую переменную и записывать в нее 2 варианта значений "ON" "OFF", на сасос деле мне даже не нужны переменные, я бы и напрямую писал в файл саму строчку, но мне ни как не удается записать в файл что-то путное, вместо времени туда попадает один какой-то не понятный символ а ON OFF вообще не пишется
так правильно?
Да, теперь верно.
По коду - в строках 80 и 89, как уже сказал выше, вы портите память, не принадлежащую массиву state. Это гарантированный источник глюков. Исправте это, потом будем смотреть дальше. Зачем вам вообще хранить ON или OFF в виде строк? - используйте переменные bool
[я не могу понять как мне правильно объявить сьтроковую переменную и записывать в нее 2 варианта значений "ON" "OFF"
Обьявляете вы правильно, а вот записываете значение неверно. Вам нужна функция strcpy
я попроавил, спасибо
только вот теперь опять проблемы с записью в файл
на сколько я тут вычитал так как SD карта и Ethernet используют одни и те же пины, вместе они работать не могут, вроде я нашел код который позволяет закрывать одно или другое для освобождения ресурсов, но он все равно как то не правильно работает, первая итерация осуществляет запись, а во время второй происходит ошибка при открытии файла, да и собственно записи в фал не попадают, может бы конструкция которую я использую не верна?
root.print(state); root.print(" "); root.println(buff);#include <SD.h> #include <SPI.h> #include <Ethernet.h> #include <stdio.h> #include <DS1302.h> #define SWITCH_TO_W5100 digitalWrite(4,HIGH); digitalWrite(10,LOW) #define SWITCH_TO_SD digitalWrite(10,HIGH); digitalWrite(4,LOW) #define ALL_OFF digitalWrite(10,HIGH); digitalWrite(4,HIGH) char state[4]="OFF"; File root; boolean newInfo = 0; byte server1[] = { 192,168,1,177 }; byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 }; byte ip[] = { 192, 168, 1, 177 }; char buf[29]; EthernetServer server(80); EthernetClient client; namespace { const int kCePin = 5; // Chip Enable const int kIoPin = 3; // Input/Output const int kSclkPin = 2; // Serial Clock DS1302 rtc(kCePin, kIoPin, kSclkPin); String dayAsString(const Time::Day day) { switch (day) { case Time::kSunday: return "Sunday"; case Time::kMonday: return "Monday"; case Time::kTuesday: return "Tuesday"; case Time::kWednesday: return "Wednesday"; case Time::kThursday: return "Thursday"; case Time::kFriday: return "Friday"; case Time::kSaturday: return "Saturday"; } return "(unknown day)"; } } void setup() { SWITCH_TO_W5100; pinMode(8, OUTPUT); pinMode(4, OUTPUT); pinMode(10, OUTPUT); Serial.begin(9600); Serial.println("Ethernet start"); Ethernet.begin(mac, ip); server.begin(); SWITCH_TO_SD; if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); printTime(); Serial.println(buf); ALL_OFF; } void loop() { EthernetClient client = server.available(); if(client){ //если запрос оканчивается пустой строкой boolean currentLineIsBlank = true; //ставим метку об окончании запроса (дословно: текущая линия чиста) while (client.connected()) { //пока есть соединение с клиентом if (client.available()) { //если клиент активен char c = client.read(); //считываем посылаемую информацию в переменную "с" if(newInfo && c == ' '){ //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке newInfo = 0; //то обнуляем переменную поступления новой информации } if(c == '$'){ //если переменная "с", несущая отправленный нам запрос, содержит символ $ //(все новые запросы) - "$" подразумевает разделение получаемой информации (символов) newInfo = 1; //то пришла новая информация, ставим метку новой информации в 1 Serial.println (newInfo); } if(newInfo == 1){ //если есть новая информация Serial.println(c); if(c == '1'){ //и "с" содержит 1 //state[4] = "ON "; strcpy(state , "ON"); Serial.println(state); digitalWrite(8, HIGH); //то зажигаем светодиод readPage(buf); printTime(); Serial.println(buf); } if(c == '2'){ //если "с" содержит 2 strcpy(state , "OFF"); Serial.println(state); digitalWrite(8, LOW); //гасим светодиод readPage(buf); printTime(); Serial.println(buf); } } if (c == '\n') { //если "с" равен символу новой строки currentLineIsBlank = true; //то начинаем новую строку } else if (c != '\r') { //иначе, если "с" не равен символу возврата курсора на начало строки currentLineIsBlank = false; //то получаем символ на текущей строке } if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println("Refresh: 30"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.print("<title>My web Server</title>"); client.print("<H1>My web Server</H1>"); client.print("<a href=\"/$1\"><button>On</button></a>"); client.print("<a href=\"/$2\"><button>Off</button></a>"); // client.print("<img src=\ "http://upload-4249238ac8260d1ede4549359aadf4b1.commondatastorage.googleapis.com/iblock/34b/34b735f803df228d1d69a707b8d4dfa8.png" </a>"); client.println("<br />"); client.println("</html>"); break; } // Serial.println("http stop"); } } delay (10); client.stop (); } } void printTime() { // Get the current time and date from the chip. Time t = rtc.time(); // Name the day of the week. const String day = dayAsString(t.day); // Format the time and date and insert into the temporary buffer. snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec); // Print the formatted string to serial so we can see the time. // Serial.println(buf); return buf; } void readPage(char bufff[29]) { Serial.println("connecting..."); //конектимся к серверу по 80 порту if (client.connect(server1, 80)) Serial.println("connected"); client.stop(); printTime(); Serial.println(bufff); Serial.println("Disconnected"); root = SD.open("/"); printDirectory(root, 0, bufff); Serial.println("done!"); } void printDirectory(File dir, int numTabs, char buff[29]) { //SWITCH_TO_SD; root = SD.open("TEXTFILE.TXT", FILE_WRITE); if (root){ Serial.print("Осуществляется запись в файл"); printTime(); Serial.println(buff); root.print(state); root.print(" "); root.println(buff); Serial.print("WRITING COMPLETED"); root.close(); Serial.println(root); Serial.println("Файл успешно закрыт"); }else{ printTime(); Serial.println(buff); Serial.println("Ошибка при открытии файла"); } }подскажите, пожалуйста, могу ли я использовать функцию в таком виде?
собственно оно так не работает, но имеет ли место такой смысл, вызовет ли такая запись исполнение функции?
void setup() { Serial.println(printTime()); } char printTime() { // Get the current time and date from the chip. Time t = rtc.time(); // Name the day of the week. const String day = dayAsString(t.day); // Format the time and date and insert into the temporary buffer. snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec); // Print the formatted string to serial so we can see the time. return buf; }Вообще-то функцию нужно определять до использования. Но благодаря котылю в некоторых версиях IDE сожрёт и так.
нет, это неверно. У вас возвращаемое значение функции printTime() - единичный символ(char), а вы возвращаете ссылку на массив...
Надо и функцию прописать соответсвенно - то есть char* printTime()
Если же вопрос, можно ли функцию вызывать внутри оператора Serial.println() - да, можно.
нет, это неверно. У вас возвращаемое значение функции printTime() - единичный символ(char), а вы возвращаете ссылку на массив...
Надо и функцию прописать соответсвенно - то есть char* printTime()
Если же вопрос, можно ли функцию вызывать внутри оператора Serial.println() - да, можно.
имеется виду char[29] printTime() ? или запись как-то иначе выглядет, а то у меня как раз проблема что возвращается один какой то не понятный символ вместо массива, а описания как такой массив объявить я не нашел
все понял, спасибо
заработал вывод даты, спасибо
#include <stdio.h> #include <DS1302.h> namespace { const int kCePin = 5; // Chip Enable const int kIoPin = 3; // Input/Output const int kSclkPin = 2; // Serial Clock DS1302 rtc(kCePin, kIoPin, kSclkPin); String dayAsString(const Time::Day day) { switch (day) { case Time::kSunday: return "Sunday"; case Time::kMonday: return "Monday"; case Time::kTuesday: return "Tuesday"; case Time::kWednesday: return "Wednesday"; case Time::kThursday: return "Thursday"; case Time::kFriday: return "Friday"; case Time::kSaturday: return "Saturday"; } return "(unknown day)"; } } char* printTime() { // Get the current time and date from the chip. Time t = rtc.time(); char buf[29]; const String day = dayAsString(t.day); // Format the time and date and insert into the temporary buffer. snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec); // Print the formatted string to serial so we can see the time. return buf; } void setup() { Serial.begin(9600); Serial.println(printTime()); } void loop() { // put your main code here, to run repeatedly: }вроде все в скетче поправил но вывод в терминал странный, может это быть связано с тем самым недостатком памяти?
#include <SD.h> #include <SPI.h> #include <Ethernet.h> #include <stdio.h> #include <DS1302.h> #define SWITCH_TO_W5100 digitalWrite(4,HIGH); digitalWrite(10,LOW) #define SWITCH_TO_SD digitalWrite(10,HIGH); digitalWrite(4,LOW) #define ALL_OFF digitalWrite(10,HIGH); digitalWrite(4,HIGH) char state[4]="OFF"; File root; boolean newInfo = 0; byte server1[] = { 192,168,1,177 }; byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 }; byte ip[] = { 192, 168, 1, 177 }; EthernetServer server(80); EthernetClient client; namespace { const int kCePin = 5; // Chip Enable const int kIoPin = 3; // Input/Output const int kSclkPin = 2; // Serial Clock DS1302 rtc(kCePin, kIoPin, kSclkPin); String dayAsString(const Time::Day day) { switch (day) { case Time::kSunday: return "Sunday"; case Time::kMonday: return "Monday"; case Time::kTuesday: return "Tuesday"; case Time::kWednesday: return "Wednesday"; case Time::kThursday: return "Thursday"; case Time::kFriday: return "Friday"; case Time::kSaturday: return "Saturday"; } return "(unknown day)"; } } char* printTime() { // Get the current time and date from the chip. Time t = rtc.time(); char buf[29]; // Name the day of the week. const String day = dayAsString(t.day); // Format the time and date and insert into the temporary buffer. snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec); // Print the formatted string to serial so we can see the time. //Serial.println(buf); return buf; } void setup() { SWITCH_TO_W5100; pinMode(8, OUTPUT); pinMode(4, OUTPUT); pinMode(10, OUTPUT); Serial.begin(9600); Serial.println("Ethernet start"); Ethernet.begin(mac, ip); server.begin(); SWITCH_TO_SD; if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); Serial.println(printTime()); ALL_OFF; } void loop() { EthernetClient client = server.available(); if(client){ //если запрос оканчивается пустой строкой boolean currentLineIsBlank = true; //ставим метку об окончании запроса (дословно: текущая линия чиста) while (client.connected()) { //пока есть соединение с клиентом if (client.available()) { //если клиент активен char c = client.read(); //считываем посылаемую информацию в переменную "с" if(newInfo && c == ' '){ //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке newInfo = 0; //то обнуляем переменную поступления новой информации } if(c == '$'){ //если переменная "с", несущая отправленный нам запрос, содержит символ $ //(все новые запросы) - "$" подразумевает разделение получаемой информации (символов) newInfo = 1; //то пришла новая информация, ставим метку новой информации в 1 Serial.println (newInfo); } if(newInfo == 1){ //если есть новая информация Serial.println(c); if(c == '1'){ //и "с" содержит 1 //state[4] = "ON "; strcpy(state , "ON"); Serial.println(state); digitalWrite(8, HIGH); //то зажигаем светодиод readPage(printTime()); Serial.println(printTime()); } if(c == '2'){ //если "с" содержит 2 strcpy(state , "OFF"); Serial.println(state); digitalWrite(8, LOW); //гасим светодиод readPage(printTime()); Serial.println(printTime()); } } if (c == '\n') { //если "с" равен символу новой строки currentLineIsBlank = true; //то начинаем новую строку } else if (c != '\r') { //иначе, если "с" не равен символу возврата курсора на начало строки currentLineIsBlank = false; //то получаем символ на текущей строке } if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println("Refresh: 30"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.print("<title>My web Server</title>"); client.print("<H1>My web Server</H1>"); client.print("<a href=\"/$1\"><button>On</button></a>"); client.print("<a href=\"/$2\"><button>Off</button></a>"); client.println("<br />"); client.println("</html>"); break; } // Serial.println("http stop"); } } delay (10); client.stop (); } } void readPage(char bufff[29]) { Serial.println("connecting..."); //конектимся к серверу по 80 порту if (client.connect(server1, 80)) Serial.println("connected"); client.stop(); Serial.println("Disconnected"); root = SD.open("/"); printDirectory(root, 0, printTime()); Serial.println("done!"); } void printDirectory(File dir, int numTabs, char buff[29]) { //SWITCH_TO_SD; root = SD.open("TEXTFILE.TXT", FILE_WRITE); if (root){ Serial.println("Осуществляется запись в файл"); root.print(state); root.print(" "); root.println(printTime()); Serial.print("WRITING COMPLETED"); root.close(); //Serial.println(root); Serial.println("Файл успешно закрыт"); }else{ Serial.println(printTime()); Serial.println("Ошибка при открытии файла"); } }можно попробовать загнать все константные строки в PROGMEM, для чего вместо
Serial.println("Ошибка при открытии файла");пишемSerial.println(F("Ошибка при открытии файла"));и так везде, где есть вывод в сериал не из переменных. Пропробуй.
вроде перестал подвисать, но вывод все равное не верный
т.е. то вывод что в setup получается нормальным а тот что из loop уже кривой какой-то
вобщем если вызывать функцию из serilaprint то вывод странный, а если предварительно присвоить значение функции переменной через strcpy то время выводится нормально, спасибо всем кто помог разобраться