непонятное зависание программы через минуту
- Войдите на сайт для отправки комментариев
Пнд, 27/04/2015 - 06:23
Сделал радиоуправляемую платформу, на про мини ардуине.
Примерно через минуту машинка зависает, не принимает моманды управления и на дисплее видно как начинают прорисоывваться пиксели очень медленно.
Прием написан по прерыванию в формате пакетов старлайн, для помехозащищенности.
отключил дисплей, также зависает. Уже хочу на пике переделать, не могу найти причину...
//#include <Adafruit_GFX.h> // Core graphics library //#include <Adafruit_ST7735.h> // Hardware-specific library //#include <SPI.h>x_position #include <avr/wdt.h> //#define sclk 13 //#define mosi 11 #define cs 10 #define dc 9 #define rst 8 // you can also connect this to the Arduino reset #define RX 2 #define D1 3 // Направление вращение двигателя 1 #define M1 5 // ШИМ вывод для управления двигателем 1 #define D2 7 // Направление вращение двигателя 2 #define M2 6 // ШИМ вывод для управления двигателем 2 #define forward 0 //направлене движения в перед #define back 1 //напрвление движения назад //bool direction = 0; // Текущее направление вращения int value; // Текущее значение ШИМ int left_motor; //скорость левого мотора int riht_motor; //скорость правого мотора int left_motor_temp; // int riht_motor_temp; // int x_position; // int y_position; // bool left_napravlenie; //напрвление вращения bool riht_napravlenie; //напрвление вращения bool flag_stop_motor; //флаг гстановки двигателей по истечении 250 млсек unsigned char flag_datacar; //флаг прилета новых данных //Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst); volatile byte level=255; volatile unsigned long last, len; byte p_level; unsigned long p_len, p_len_prev; volatile unsigned char str[2]; //для вывода на дисплей unsigned char sernom[4] = {0x12, 0x34, 0x56, 0x78}; //серийник машинки unsigned char datacar[4]; //данные прилетевших пакетов для управления машинкой //datacar[0] - данные скорости левой стороны //datacar[1] - данные скорости правой стороны volatile unsigned int tcnt2; //для таймера2 volatile char count; //для подсчета переполнений таймера2 volatile unsigned int time_no_comand; //для измерения милисекунд с момента прилета команды volatile unsigned int time; volatile bool flag_time; volatile struct { volatile unsigned char state; unsigned char data[3], dat_bit; } came; struct { byte state; unsigned long TE; byte pre_count, data[8], dat_bit; } keeloq; struct { byte state; byte pre_count, data[8], dat_bit; } starline; void setbit(byte *data, byte n) { data[n/8]|=1<<(7-n%8); } #define KL_MIN_PRE_COUNT 4 #define KL_MAX_TE 500 #define KL_MIN_TE 300 #define KL_MAX_BITS 64 void process_keeloq() { switch(keeloq.state) { case 0: if(p_level) break; keeloq.state=1; keeloq.pre_count=0; break; case 1: //pre+hdr if(p_len>=KL_MIN_TE && p_len<=KL_MAX_TE) keeloq.pre_count++; else if(!p_level && p_len>=KL_MIN_TE*10 && p_len<=KL_MAX_TE*10 && keeloq.pre_count>=KL_MIN_PRE_COUNT) { keeloq.TE=p_len/10; keeloq.state=2; keeloq.dat_bit=0; keeloq.data[0]=0x00; keeloq.data[1]=0x00; keeloq.data[2]=0x00; keeloq.data[3]=0x00; keeloq.data[4]=0x00; keeloq.data[5]=0x00; keeloq.data[6]=0x00; keeloq.data[7]=0x00; } else { keeloq.state=0; break; } break; case 2: //dat if(!p_level) break; if(p_len<keeloq.TE/2 || p_len>keeloq.TE*3) { keeloq.state=0; break; } if(p_len<=keeloq.TE+keeloq.TE/2) setbit(keeloq.data, keeloq.dat_bit); if(++keeloq.dat_bit==KL_MAX_BITS) keeloq.state=100; break; } } #define SL_MIN_PRE_COUNT 4 #define SL_MAX_PRE 1150 #define SL_MIN_PRE 850 #define SL_MAX_ZERO 350 #define SL_MIN_ZERO 100 #define SL_MAX_ONE 700 #define SL_MIN_ONE 400 #define SL_MIN_BITS 16 #define SL_MAX_BITS 64 void process_starline() { byte b; switch(starline.state) { case 0: if(p_level) break; starline.state=1; starline.pre_count=0; break; case 1: //pre if(p_len>=SL_MIN_PRE && p_len<=SL_MAX_PRE) starline.pre_count++; else if(p_len<SL_MIN_PRE && starline.pre_count>=SL_MIN_PRE_COUNT) { starline.state=2; starline.dat_bit=0; starline.data[0]=0x00; starline.data[1]=0x00; starline.data[2]=0x00; starline.data[3]=0x00; starline.data[4]=0x00; starline.data[5]=0x00; starline.data[6]=0x00; starline.data[7]=0x00; } else { starline.state=0; break; } break; case 2: //dat if(p_level) break; if(p_len_prev>=SL_MIN_ONE && p_len_prev<=SL_MAX_ONE && p_len>=SL_MIN_ONE && p_len<=SL_MAX_ONE) b=0; else if(p_len_prev>=SL_MIN_ZERO && p_len_prev<=SL_MAX_ZERO && p_len>=SL_MIN_ZERO && p_len<=SL_MAX_ZERO) b=1; else { //if(starline.dat_bit>=SL_MIN_BITS) starline.state=100; // else starline.state=0; break; } if(b) setbit(starline.data, starline.dat_bit); if(++starline.dat_bit==SL_MAX_BITS) starline.state=100; break; } } /* void dump_hex(byte *buf, byte bits) { byte a; for(a=0; a<(bits+7)/8; a++) { if(buf[a]<=0x0f) Serial.print('0'); Serial.print(buf[a], HEX); Serial.print(" "); } Serial.println(""); } */ void rx_int() { if(level!=255) return; len=micros()-last; last=micros(); if(digitalRead(RX)==HIGH) level=0; else level=1; } void setup() { attachInterrupt(0, rx_int, CHANGE); // tft.initR(INITR_REDTAB); //Serial.begin(115200); //while(!Serial); // Serial.begin(57600); pinMode(D1, OUTPUT); pinMode(D2, OUTPUT); wdt_enable(WDTO_250MS); /* tft.invertDisplay(false); tft.fillScreen(ST7735_BLACK); tft.setCursor(0, 0); tft.setTextColor(ST7735_BLUE); tft.setTextSize(1); tft.println(" SUPERCAR "); tft.setCursor(0, 10); tft.setTextColor(ST7735_WHITE); tft.println(" ARDUINO PRO MINI"); tft.setCursor(0, 20); tft.println(" ATMEGA328A"); tft.setTextColor(ST7735_RED); tft.setCursor(0, 150); tft.print(" V bat = 6.25 v "); */ //wdt_enable(WDTO_1S); //включаем ватч дог с периодом 1000 мсек //interrupts(); } byte a; void loop() { wdt_reset(); /* if((millis() - time)>500) { time = millis(); flag_time = !flag_time; if(flag_time) { tft.setCursor(0, 150); tft.print(" V bat = 6.25 v "); } else tft.fillRect(0, 150, 130, 8, ST7735_BLACK); } */ //если более секунды нет команд - отключаем двигатели if(!flag_stop_motor & (millis() - time_no_comand) > 1000) { flag_stop_motor = 1; left_motor = 0; riht_motor = 0; analogWrite(M1, 0x00); // выключаем моторы, если нет команд с пульта более 250 миллисекунд analogWrite(M2, 0x00); digitalWrite(D1, forward); // Задаем направление вращения digitalWrite(D2, forward); /* tft.fillRect(0, 110, 130, 8, ST7735_BLACK); tft.setTextColor(ST7735_GREEN); tft.setCursor(0, 110); tft.print(left_napravlenie); tft.print(" "); tft.print("LEFT "); tft.print(left_motor); // wdt_reset(); tft.fillRect(0, 130, 130, 8, ST7735_BLACK); tft.setTextColor(ST7735_GREEN); tft.setCursor(0, 130); tft.print(riht_napravlenie); tft.print(" "); tft.print("RIHT "); tft.print(riht_motor); */ } //---------------------------------------------------------------------- if(flag_datacar) { time_no_comand = millis(); //засекаем время после прилета команды flag_stop_motor = 0; //сброс флага остановки двигателей /* tft.fillRect(0, 70, 130, 8, ST7735_BLACK); tft.setTextColor(ST7735_GREEN); tft.setCursor(0, 70); tft.print(" PRIEM KOMAND "); */ wdt_reset(); x_position = (starline.data[4]*256 + starline.data[5]); //значение 0-1024 y_position = (starline.data[6]*256 + starline.data[7]); //значение 0-1024 /* tft.fillRect(0, 60, 130, 8, ST7735_BLACK); tft.setTextColor(ST7735_GREEN); tft.setCursor(0, 60); tft.print("X_pos "); tft.print(x_position); tft.print(" Y_pos "); tft.print(y_position); */ // if(x_position > 517) // { left_motor_temp = y_position + ((x_position - 512)/2); riht_motor_temp = y_position - ((x_position - 512)/2); // } // else if(x_position < 507) // { // left_motor_temp = y_position - (x_position - 512); // riht_motor_temp = y_position + (x_position - 512); // } // else // { // left_motor_temp = y_position; // riht_motor_temp = y_position; // } if(left_motor_temp > 1023) left_motor_temp = 1021; if(left_motor_temp < 1) left_motor_temp = 3; if(riht_motor_temp > 1023) riht_motor_temp = 1021; if(riht_motor_temp < 1) riht_motor_temp = 3; left_motor = (abs(left_motor_temp - 512))/2; riht_motor = (abs(riht_motor_temp - 512))/2; if(left_motor_temp > 512) { left_napravlenie = 1; left_motor = 255 - left_motor; } else { left_napravlenie = 0; } if(riht_motor_temp > 512) { riht_napravlenie = 1; riht_motor = 255 - riht_motor; } else { riht_napravlenie = 0; } wdt_reset(); /* tft.fillRect(0, 110, 130, 8, ST7735_BLACK); tft.setTextColor(ST7735_GREEN); tft.setCursor(0, 110); tft.print(left_napravlenie); tft.print(" "); tft.print("LEFT "); tft.print(left_motor); // wdt_reset(); tft.fillRect(0, 130, 130, 8, ST7735_BLACK); tft.setTextColor(ST7735_GREEN); tft.setCursor(0, 130); tft.print(riht_napravlenie); tft.print(" "); tft.print("RIHT "); tft.print(riht_motor); // wdt_reset(); */ digitalWrite(D1, left_napravlenie); // Задаем направление вращения digitalWrite(D2, riht_napravlenie); analogWrite(M1, left_motor); // Задаем скорость вращения analogWrite(M2, riht_motor); flag_datacar = 0; wdt_reset(); } if(level!=255) { // noInterrupts(); p_level=level; p_len=len; len=0; level=255; // interrupts(); wdt_reset(); process_keeloq(); process_starline(); p_len_prev=p_len; } /* if(keeloq.state==100) { //Serial.print("KEELOQ: "); //dump_hex(keeloq.data, 64); tft.setCursor(0, 40); tft.setTextColor(ST7735_RED); tft.fillRect(0, 40, 130, 8, ST7735_BLACK); tft.println(" KEELOG "); tft.fillRect(0, 50, 130, 8, ST7735_BLACK); // wdt_reset(); tft.setCursor(0, 50); for(a=0; a<8; a++) { if(a==0) tft.print(" "); if(a==4) tft.print(" "); //if(a==7) tft.print(" "); tft.print(keeloq.data[a], HEX); } // wdt_reset(); keeloq.state=0; } */ if(starline.state==100) { // Serial.print("STARLINE["); // Serial.print(starline.dat_bit); // Serial.print("]: "); // dump_hex(starline.data, starline.dat_bit); /* tft.setCursor(0, 40); tft.setTextColor(ST7735_BLUE); tft.fillRect(0, 40, 130, 8, ST7735_BLACK); tft.print(" STARLINE "); tft.fillRect(0, 50, 130, 8, ST7735_BLACK); wdt_reset(); tft.setCursor(0, 50); //tft.setTextColor(ST7735_BLUE); for(a=0; a<8; a++) { if(a==0) tft.print(" "); if(a==4) tft.print(" "); tft.print(starline.data[a], HEX); } */ if((starline.data[0]==sernom[0])&&(starline.data[1]==sernom[1])&&(starline.data[2]==sernom[2])&&(starline.data[3]==sernom[3])) flag_datacar = 1; //прилетели новые данные, нужно обработать starline.state=0; } }
сторожевой таймер не работает, не понял почему.
Виснет судя по всему через 65 секунд :) 52, 53 строка не мала ли u_int для хранения миллис() ?
Спасибо, исправил на
unsigned
long
Хотел уже на 18F2520 камне переделать машинку, давно лежит, забросил в дальний угол.
Круто... Как вы это читаете и находите... Это же так много букав :(
Круто... Как вы это читаете и находите... Это же так много букав :(
Букав не много,
есть проэкт со 8000 строк кода, правда на хай теке.
Опытный ардуинщик по названию темы уже знает несколько вариантов возможных ошибок. Для этого нужно хорошо знать компилятор.
brokly, да, жуть. Не полез бы в эту портянку, но я по началу ардуино-изучения сам наступил на эти грабли, поэтому увидев у Т.С., что "зависает через минуту" осталось только проверить в какие переменные он кладёт millis()
Логично ! Круто! Прямо поиском int в тексе ! И смотреть что он объявляет. Не читая текста.....
Опытный ардуинщик по названию темы уже знает несколько вариантов возможных ошибок. Для этого нужно хорошо знать компилятор.
Гм... Я и не знал, что можно классифицироваться ардуинщик или нет :)