Да как так-то??? (цикл уходит за пределы)
- Войдите на сайт для отправки комментариев
Вс, 13/12/2015 - 20:53
Картинка скажет сама за себя. У кого не отображается - замечу, что банальный цикл выходит за пределы. Неведомым мне образом. Соответственно вся обработка данных (а там структуры и массивы) уходит в левые области памяти, контроллер уходит в ребут.

Может банально не хватать ОЗУ, например. Это всего лишь предположение.
А как это можно узнать?
просто не очень охота переносить все на MEGA. Я хотел в итоге программу перенести на NANO, а ее вставить в плату с исполнительными устройствами. Да и мега дороже. Да и зря чтоли я мучался с оптимизацией или рисованием ;)
Памяти в MEGA не на много больше...
Да и по программной памяти укладываюсь с запасом: провел кое-какие оптимизации. Привожу код целиком, за исключением слегка модифицированных UTFT_buttons
#define YP A2 #define XM A1 #define YM 6 #define XP 7 #define TS_MAXX 92 #define TS_MINX 936 #define TS_MAXY 135 #define TS_MINY 900 // Последним параметром указывается сопротивление между X+ и X- // Для данных дисплеев 300 подойдет // От PhOSTU: я сомневаюсь в правильности этого коммента // Сила нажатия на дисплей // От PhOSTU: и этого тоже) #define MINPRESSURE 10 #define MAXPRESSURE 1000 #define ONE_WIRE_BUS 12 #define TEMPERATURE_PRECISION 9 //------------------------------------ #include <avr/pgmspace.h> #include "TouchScreen.h" #include <UTFT.h> #include "buttons.h" #include <OneWire.h> #include <DallasTemperature.h> extern uint8_t Sinclair_S[]; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); UTFT myGLCD(31,A2,A1,A3,A4); UTFT_Buttons myButtons(&myGLCD, &ts); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature mySensors(&oneWire); #define SENSCOUNT 8 #define ACC_OUT 0 #define RD_IN 1 #define RD_OUT 2 #define HT_IN 3 #define HT_MID 4 #define AIR_IN 5 #define AIR_OUT 6 #define OUTDOOR 7 //структура для хранения данных о датчиках #define DATASIZE 10 // количество хранимых отсчетов #define DATAPERIOD 1000 // период отсчетов //структура для датчиков typedef struct { char* name; // имя DeviceAddress addr; //адрес int x; //координата Х int y; //координата Y byte data[DATASIZE];//история отсчетов } tSensor; tSensor sensor[]= { {"ACC_OUT",{ 0x28, 0xFF, 0x79, 0xF6, 0x01, 0x15, 0x02, 0xAA },12,2 ,{0}}, {"RD_IN", { 0x28, 0xFF, 0x79, 0xF6, 0x01, 0x15, 0x02, 0xAA },39,30,{0}}, {"RD_OUT", { 0x28, 0xFF, 0x4B, 0xF5, 0x01, 0x15, 0x02, 0x25 },15,30,{0}}, {"HT_IN", { 0x28, 0xFF, 0x4B, 0xF5, 0x01, 0x15, 0x02, 0x25 },41,2 ,{0}}, {"HT_MID", { 0x28, 0xFF, 0x4B, 0xF5, 0x01, 0x15, 0x02, 0x25 },47,16,{0}}, {"AIR_IN", { 0x28, 0xFF, 0x79, 0xF6, 0x01, 0x15, 0x02, 0xAA },15,35,{0}}, {"AIR_OUT",{ 0x28, 0xFF, 0x79, 0xF6, 0x01, 0x15, 0x02, 0xAA },39,35,{0}}, {"OUTDOOR",{ 0x08, 0xFF, 0x79, 0xF6, 0x01, 0x15, 0x02, 0xAA },56,2 ,{0}}, }; // int sensPosX[SENSCOUNT]= {12, 39, 15, 41, 47, 15, 39, 56}; // int sensPosY[SENSCOUNT]= {2, 30, 30, 2, 16, 35, 35 ,2}; #define acc_out 0 #define rd_in 1 #define rd_out 2 #define ht_in 3 #define ht_mid 4 #define air_in 5 #define air_out 6 #define outdoor 7 byte bMain =1; byte bSensors = 2; int pressed_button; //------------------------------------ #define BOXSIZE 40 // Размер кнопки выбора цвета #define PENRADIUS 1 // Радиус круга для рисования int top = 5; int left= 10; float s=6; //************************************ //ставим цвета #define COL_C1 31 #define COL_C2 10265 //синий ниже #define COL_C3 14357 //синий ниже #define COL_C4 22544 //сине-красный #define COL_C5 28684 //сине-красный #define COL_C6 38917 //красный #define COL_C7 47104 //темно-красный #define COL_C8 63488 //ткрасный #define COL_GREEN 1504 //зеленый void drawFLine(int x1, int y1, int x2, int y2, word col) { myGLCD.setColor(col); myGLCD.drawLine(x1,y1,x2,y2); myGLCD.drawLine(x1+1,y1,x2+1,y2); myGLCD.drawLine(x1,y1+1,x2,y2+1); myGLCD.drawLine(x1+1,y1+1,x2+1,y2+1); } int h(int val) { int res = (int) val * s + left; return res; } int v(int val) { int res = (int) val * s + top; return res; } word setWColor(byte r, byte g, byte b) { word fch=((r&248)|g>>5); word fcl=((g&28)<<3|b>>3); return (fch<<8) | fcl; } void gPrintLn(const char* text, word color,int x, int y) { static int line =0; #define line_step 10 myGLCD.setColor(color); myGLCD.print(text, x, y+(line*line_step)); line++; } void checkSensor(int n, int x, int y) { char buf[30]; delay(200); if (!mySensors.isConnected(sensor[n].addr)) { myGLCD.setColor(VGA_YELLOW); sprintf(buf, "Unable to find address for %s", sensor[n].name); //myGLCD.print(buf, x, y+(line*line_step)); myGLCD.print(buf, x, y); } else { mySensors.setResolution(sensor[n].addr, TEMPERATURE_PRECISION); myGLCD.setColor(VGA_GREEN); int tempC =(int) mySensors.getTempC(sensor[n].addr); sprintf(buf, "Temperature for %s is %i *C", sensor[n].name, tempC); myGLCD.print(buf, x, y*n); myGLCD.printNumI (y, 310,n*10); } } void setup(void) { Serial.begin(9600); myGLCD.InitLCD(); myGLCD.setFont(Sinclair_S); myButtons.setTextFont(Sinclair_S); pinMode(13, OUTPUT); myGLCD.clrScr(); myGLCD.setColor(VGA_WHITE); myGLCD.print("System init", CENTER, 1); myGLCD.setColor(VGA_RED); myGLCD.print ("Init temperature sensors...", 10, 20); delay(100); mySensors.requestTemperatures(); Serial.println("requestTemperatures"); //обрабатываем все датчики поочереди //for(i=0; i<SENSCOUNT; i++) for (int i=0; i<=2; i++) { Serial.print("i= "); Serial.println(i); myGLCD.setColor(VGA_LIME); myGLCD.printNumI (i, 340,i*10); //checkSensor(i,10,i*5+20); } myGLCD.setColor(VGA_RED); myGLCD.print ("Init temperature sensors...", 10, 200); delay(3000); drawMainScreen(); } void drawMainScreen() { myButtons.deleteAllButtons(); myGLCD.clrScr(); // Устанавливаем текущий цвет myGLCD.setColor(VGA_WHITE); myGLCD.print("System control", CENTER, 1); //вот так вот определяем картинку для экономии памяти #define Rect 1 #define RRect 2 #define FLine 3 #define Circle 4//бочка трубы Радиатор камин типа насос byte img_type[] PROGMEM = {RRect,Rect, Rect, Rect, Rect, RRect, Rect, FLine, FLine, FLine, FLine, FLine, FLine, FLine, FLine, FLine, FLine, FLine, Rect, Rect, Rect, Rect, Rect, Rect, Rect, Rect, Circle, FLine, FLine, FLine, FLine }; int img_x1[] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 10, 44, 37, 17, 10, 35, 10, 44, 48, 45, 48, 20, 33, 22, 22, 22, 22, 42, 42, 27, 27, 27, 26, 26 }; int img_y1[] PROGMEM = {3, 8, 10, 13, 16, 22, 19, 4, 12, 4, 4, 29, 29, 4, 4, 6, 8, 10, 28, 28, 29, 31, 33, 35, 20, 23, 4, 3, 5, 3, 5}; int img_x2[] PROGMEM = {10, 10, 10, 10, 10, 10, 10, 44, 44, 37, 17, 20, 43, 44, 48, 45, 48, 44, 22, 35, 33, 33, 33, 33, 49, 49, 10, 28, 28, 27, 27 }; int img_y2[] PROGMEM = {10, 10, 13, 16, 19, 31, 23, 4, 20, 29, 29, 29, 29, 4, 6, 8, 10, 12, 37, 37, 30, 32, 34, 36, 23, 30, 0, 4, 4, 4, 4 }; word img_col[] PROGMEM = {COL_C1,COL_C2,COL_C3, COL_C4, COL_C5, COL_C7, COL_C6, COL_C1, COL_C6, COL_C5, COL_C6, COL_C7, COL_C8, COL_C1, COL_C2, COL_C3, COL_C4, COL_C5, COL_C7, COL_C8, VGA_GRAY,VGA_GRAY, VGA_GRAY,VGA_GRAY, COL_C7, COL_C8, COL_GREEN, VGA_BLACK, VGA_BLACK, VGA_BLACK,VGA_BLACK }; for (byte i=0; i<32; i++) { if(img_type[i]==Rect) { myGLCD.setColor (img_col[i]); myGLCD.fillRect(h(img_x1[i]),v(img_y1[i]),h(img_x2[i]),v(img_y2[i])); } if(img_type[i]==RRect) { myGLCD.setColor (img_col[i]); myGLCD.fillRoundRect(h(img_x1[i]),v(img_y1[i]),h(img_x2[i]),v(img_y2[i])); } if(img_type[i]==FLine) { drawFLine(h(img_x1[i]),v(img_y1[i]),h(img_x2[i]),v(img_y2[i]),img_col[i]); } if(img_type[i]==Circle) { myGLCD.setColor (img_col[i]); myGLCD.fillCircle(h(img_x1[i]),v(img_y1[i]),img_x2[i]); } //myGLCD.printNumI (i, 320, 10); //delay(300); } myButtons.deleteAllButtons(); boolean default_colors = true; myGLCD.setColor(VGA_WHITE); myButtons.deleteAllButtons(); myButtons.addButton( 310, 200, 70, 25, "Sensors", bSensors); myButtons.drawButtons(); } //печатаем состояние датчиков на экране void sensorPrint(byte n) { // предыдущее время сохранения данных static long lastTime=0; long curtime=millis(); int tempC=0; //получаем адрес по идентификатору tempC =(int) mySensors.getTempC(sensor[n].addr); if(tempC <= 0) myGLCD.setColor(VGA_BLUE); if(tempC==-127) myGLCD.setColor(VGA_GRAY); if(tempC <= 40 && tempC > 0) myGLCD.setColor(VGA_GREEN); if(tempC <= 60 && tempC > 40) myGLCD.setColor(VGA_LIME); if(tempC <= 80 && tempC > 60) myGLCD.setColor(VGA_YELLOW); if(tempC > 80 ) myGLCD.setColor(VGA_RED); //раз в минуту сохраняем данные Serial.print("lastTime= "); Serial.print(lastTime); Serial.print(" curtime= "); Serial.println(curtime); if(curtime-lastTime > DATAPERIOD ) { lastTime=millis(); //byte i=0; //сдвигаем все нафиг на одну позицию for (byte i=DATASIZE-1; i>=0; i--) { Serial.print("di="); Serial.print(i); Serial.print(" data="); Serial.println(sensor[n].data[i]); sensor[n].data[i+1]=sensor[n].data[i]; myGLCD.printNumI (sensor[n].data[i+1], 300, 0); } sensor[n].data[0]=tempC; } myGLCD.printNumI (tempC, h(sensor[n].x), v(sensor[n].y)); } //рисуем цветной график заданного размера void drawGraph(byte n, int x, int y, byte h, byte count) { byte i; if(count > DATASIZE-1) count = DATASIZE-1; for (i=0; i<count; i++) { int tempC=sensor[n].data[i]; //если меньше нуля - не показываем ибо пофиг. if(tempC<=0) tempC=0; myGLCD.setColor(100+tempC,255-tempC,0); myGLCD.drawLine(x+count-i,y+h,x+count-i,y+h-i/100*h); myGLCD.printNumI (tempC, 20*i,30); } } void drawTemp() { //int tempC=0; mySensors.requestTemperatures(); //обрабатываем все датчики поочереди for(int i=0; i<SENSCOUNT; i++) sensorPrint(i); // drawGraph(acc_out, 100, 10, 50, 30); } void drawSensorsScreen() { myGLCD.clrScr(); myGLCD.setColor(VGA_WHITE); myGLCD.print("Sensors control", CENTER, 1); boolean default_colors = true; myButtons.deleteAllButtons(); //выход в основной экран myButtons.addButton( 330, 200, 60, 25, "Return", bMain); myButtons.drawButtons(); } void loop(void) { pressed_button = myButtons.checkButtons(); drawTemp(); myGLCD.setColor(VGA_GREEN); myGLCD.printNumI (pressed_button, 320, 0); if(pressed_button==bMain) drawMainScreen(); if(pressed_button==bSensors) drawSensorsScreen(); delay(100); }Строка 149, длина буфера 30 байт. Строка формата, 27 байт длиной, плюс имя сенсора, ещё 7 байт, уже 34. Остальное даже не смотрел, с такими плюхами выполнение кода непредсказуемо.
Круто! Спасибо большое!
Я неопытный в сях приплюснутых, делаю тупые ошибки. последние 10..15 лет программировал на интерпретируемых языках, с нечеткой типизацией.
Подскажите, пожалуйста, есть ли методы анализа сколько памяти используется?
Не сочтите за наглость, не могли бы Вы проконсультировать по поводу этой функции?
//печатаем состояние датчиков на экране void sensorPrint(byte n) { // предыдущее время сохранения данных static long lastTime=0; long curtime=millis(); Serial.print("lastTime= "); Serial.print(lastTime); Serial.print(" curtime= "); Serial.println(curtime); int tempC=0; //получаем адрес по идентификатору tempC =(int) mySensors.getTempC(sensor[n].addr); if(tempC <= 0) myGLCD.setColor(VGA_BLUE); if(tempC==-127) myGLCD.setColor(VGA_GRAY); if(tempC <= 40 && tempC > 0) myGLCD.setColor(VGA_GREEN); if(tempC <= 60 && tempC > 40) myGLCD.setColor(VGA_LIME); if(tempC <= 80 && tempC > 60) myGLCD.setColor(VGA_YELLOW); if(tempC > 80 ) myGLCD.setColor(VGA_RED); //раз в минуту сохраняем данные if(curtime-lastTime > DATAPERIOD ) { lastTime=millis(); //byte i=0; //сдвигаем все нафиг на одну позицию for (byte i=DATASIZE-1; i>=0; i--) { Serial.print("di="); Serial.print(i); Serial.print(" data="); Serial.println(sensor[n].data[i]); sensor[n].data[i+1]=sensor[n].data[i]; myGLCD.printNumI (sensor[n].data[i+1], 300, 0); } sensor[n].data[0]=tempC; } myGLCD.printNumI (tempC, h(sensor[n].x), v(sensor[n].y)); }Если включить блок кода после комментария "раз в минуту сохраняем данные" то после вызова этой фунции ничего не работает. Сама функция - тоже, в последовательный порт не уходят сообщения, которые определены в начале функции. Подозреваю что дело в размере массива данных sensor[n].data[]: сейчас он определяется тупо так:
{"OUTDOOR",{ 0x08, 0xFF, 0x79, 0xF6, 0x01, 0x15, 0x02, 0xAA },56,2 ,{0,0,0,0,0,0,0,0,0,0}},//улица
Большое спасибо!
Ну там вообщетто новые IDE после компилляции пишут про память.
32 строка,, byte - беззнаковые, значит условие i >= 0 выполняется всегда, цикл бесконечный.
kisoft, спасибо! Но не помогло. Исполнение не доходит до этого участка кода вообще
У вас lastTime инициализируется в теле функции. Нужно сделать ее глобальной.
Если включить блок кода после комментария "раз в минуту сохраняем данные" то после вызова этой фунции ничего не работает. Сама функция - тоже, в последовательный порт не уходят сообщения, которые определены в начале функции. Подозреваю что дело в размере массива данных sensor[n].data[]: сейчас он определяется тупо так:
{"OUTDOOR",{ 0x08, 0xFF, 0x79, 0xF6, 0x01, 0x15, 0x02, 0xAA },56,2 ,{0,0,0,0,0,0,0,0,0,0}},//улица
Большое спасибо!
Функция millis возвращает значение не того типа, которое Вы определили переменной curtime.
Подскажите, пожалуйста, есть ли методы анализа сколько памяти используется?
http://andybrown.me.uk/2011/01/01/debugging-avr-dynamic-memory-allocation/
ЕвгенийП, спасибо, попробую!
Вот что получилось:
Сейчас смотрю где память можно подрезать. Хотя бы до 1 тыс. отсчетов увеличить.
Еще пытаюсь решить проблему с мерцанием и фиговым качеством изображения. Особенно это видно когда рисуешь много линий. Например, графики те же. По экрану мерцают вертикальные линии хаотично...
Ну, не знаю, как мерцает, а в статике красиво выглядит
Товарищи, имейте в виду что библиотека UTFT_Buttons с ходу отжирает около 500 байт ОЗУ. Ибо там одни классы и все в оперативке