Перестает работать скетч после 5-10 минут работы. В чем может быть проблема? Скетч внутри
- Войдите на сайт для отправки комментариев
Вс, 21/06/2020 - 10:42
Здравствуйте. Весь код перечитываю - проблем не нахожу. Что может приводить к остановке работы? Mega 2560
// d - провернуть двигатель против часовой стрелки (по движению джойстика). // при этом varres_in увеличивается, а палка натягивается от себя. u - наоборот boolean oscill = false; boolean messages = false; boolean usemove = true; const int ffb_min = 22; // уровень сигнала ффб мин. const int ffb_max = 57; // уровень сигнала ффб макс. (33 - середина 25-33-55) const int varresMin = 560; // пружина от себя const int varresMax = 640; // пружина на себя const uint8_t ffbpin = A15; // сигнал ффб const uint8_t EN = A2; // № вывода Arduino к которому подключены входы драйвера L_EN и R_EN. Можно указать любой вывод Arduino поддерживающий ШИМ. const uint8_t L_PWM = A1; // № вывода Arduino к которому подключён вход драйвера L_PWM. Можно указать любой вывод Arduino, как цифровой, так и аналоговый. const uint8_t R_PWM = A0; // № вывода Arduino к которому подключён вход драйвера R_PWM. Можно указать любой вывод Arduino, как цифровой, так и аналоговый. const uint8_t varres_in = A4; // считывание резистора переменного. int varres_value; // значение емкости потенциометра (текущее положение) int ffb_current = (ffb_min + ffb_max) / 2; // среднее значение ффб за последний промежуток времени int ffb_percent = 50; // среднее значение ффб за последний промежуток времени int CurrentPosition = 0; int ToPosition = 50; int Array[4] = {30, 50, 70, 100}; unsigned long prev_millis = 0; volatile unsigned long start_time = 0; volatile long ffblength = 0; volatile int ffbcount = 0; void setup() { Serial.begin(9600); // Последовательное соединение pinMode(EN, OUTPUT); // EN как выход (выход Arduino, вход драйвера) pinMode(L_PWM, OUTPUT); // L_PWM как выход (выход Arduino, вход драйвера) pinMode(R_PWM, OUTPUT); // R_PWM как выход (выход Arduino, вход драйвера) pinMode(A3, OUTPUT); // Выход питания потенциометра позиции двигателя pinMode(A5, OUTPUT); // Выход питания позиции двигателя pinMode(13, OUTPUT); // Светодиод pinMode(varres_in, INPUT); // пин приема сигнала с потенциометра позиции двигателя pinMode(ffbpin, INPUT); // пин приема сигнала с FFB digitalWrite(A3, LOW); // Питание потенциометра позиции двигателя digitalWrite(A5, HIGH); // Питание потенциометра позиции двигателя prev_millis = millis(); attachInterrupt(0, rising, RISING); } void loop() { if (millis() >= prev_millis + 30) { detachInterrupt(0); ffb_current = ffblength / (ffbcount / 2); ffb_current = constrain(ffb_current, ffb_min, ffb_max); // Обработка сигнала FFB ffb_current = constrain(ffb_current, ffb_min, ffb_max); ffb_percent = map(ffb_current, ffb_min, ffb_max, 0, 100); if (usemove) { ToPosition = ffb_percent; if (ffb_percent <= 25) { ToPosition = map(ffb_percent, 0, 25, 0, Array[0]); } else if (ffb_percent <= 50) { ToPosition = map(ffb_percent, 26, 50, Array[0] + 1, Array[1]); } else if (ffb_percent <= 75) { ToPosition = map(ffb_percent, 51, 75, Array[1] + 1, Array[2]); } else { ToPosition = map(ffb_percent, 76, 100, Array[2] + 1, Array[3]); } ToPosition = constrain(ToPosition, 0, 100); } if (messages) { Serial.print(ffb_current); Serial.print(" - "); Serial.println(ToPosition); } prev_millis = millis(); ffblength = 0; ffbcount = 0; attachInterrupt(0, rising, RISING); } else { delay(5); } varres_value = analogRead(varres_in); Serial.println(varres_value); // Остановка при выходе за рамки if (varres_value <= varresMin - 10 || varres_value >= varresMax + 10) { //moveto(0, 255); if (messages) { Serial.print("error: "); Serial.println(varres_value); } //error(2); } // Перемещение на позицию if (usemove) { varres_value = constrain(varres_value, varresMin, varresMax); CurrentPosition = map(varres_value, varresMin, varresMax, 0, 100); if (CurrentPosition - 4 > ToPosition) { if (messages) { Serial.print("move min - "); Serial.print(CurrentPosition); Serial.print(" - "); Serial.println(ToPosition); } moveto(2, 255); } else if (CurrentPosition + 4 < ToPosition) { if (messages) { Serial.print("move max - "); Serial.print(CurrentPosition); Serial.print(" - "); Serial.println(ToPosition); } moveto(1, 255); } else { if (messages) { Serial.print("STOPPED: "); Serial.print(ToPosition); Serial.print(" - "); Serial.println(ffb_percent); } moveto(0, 255); } } // Перестановка по командам из COM while (Serial.available() > 0) { // messages = true; int incomingByte = Serial.read(); if (incomingByte >= 48 && incomingByte <= 57) { Serial.print("command move to - "); Serial.print(ToPosition); ToPosition = (incomingByte - 48) * 10; Serial.print(" - "); Serial.println(ToPosition); } else if (incomingByte == 100) { Serial.print("command move max - "); Serial.print(analogRead(varres_in)); moveto(1, 160); delay(60); moveto(0, 160); Serial.print(" - "); Serial.println(analogRead(varres_in)); } else if (incomingByte == 117) { Serial.print("command move min - "); Serial.print(analogRead(varres_in)); moveto(2, 160); delay(60); moveto(0, 160); Serial.print(" - "); Serial.println(analogRead(varres_in)); } else { Serial.print("command not found - "); Serial.print(incomingByte); } } // Вывод данных if (oscill) { // Осциллограф - значение FFB // Serial.write( 0xff ); // Serial.write( (ToPosition * 10 >> 8) & 0xff ); // Serial.write( ToPosition * 10 & 0xff ); // Осциллограф - сглаженное значение FFB //Serial.write( 0xff ); //Serial.write( (map(ffb_average, 300, 700, 0, 100) * 10 >> 8) & 0xff ); //Serial.write( map(ffb_average, 300, 700, 0, 100) * 10 & 0xff ); // тест //Serial.write( 0xff ); //Serial.write( (50 * 10 >> 8) & 0xff ); //Serial.write( 50 * 10 & 0xff ); // Осциллограф - Процент для двигателя //Serial.write( 0xff ); //Serial.write( ((CurrentPosition * 10) + 1000 >> 8) & 0xff ); //Serial.write( (CurrentPosition * 10) + 1000 & 0xff ); // Осциллограф - Текущее значение FFB //Serial.write( 0xff ); //Serial.write( ((map(constrain(ffb_average, ffb_min, ffb_max), ffb_min, ffb_max, 0, 100) * 10) >> 8) & 0xff ); //Serial.write( (map(constrain(ffb_average, ffb_min, ffb_max), ffb_min, ffb_max, 0, 100) * 10) & 0xff ); Serial.write( 0xff ); Serial.write( ((map(ffb_current, 10, 80, 0, 100) * 10) >> 8) & 0xff ); Serial.write( (map(ffb_current, 10, 80, 0, 100) * 10) & 0xff ); }; } void rising() { start_time = micros(); attachInterrupt(0, falling, FALLING); } void falling() { ffblength = micros() - start_time + ffblength; ffbcount++; attachInterrupt(0, rising, RISING); } // 1 - натянуть, 2 - ослабить пружины void moveto(byte mode, byte power) { if (mode == 1) { digitalWrite(L_PWM, 0 ); // Устанавливаем логический 0 на входе драйвера L_PWM, значит на выходе драйвера M- будет установлен потенциал S- digitalWrite(R_PWM, 255); // Устанавливаем логическую 1 на входе драйвера R_PWM, значит на выходе драйвера M+ будет установлен потенциал S+ analogWrite (EN, power ); // Устанавливаем 50% ШИМ на входах драйвера L_EN и R_EN, это скорость, можно установить от 0 (0%) до 255 (100%). } else if (mode == 2) { digitalWrite(L_PWM, 255); // Устанавливаем логическую 1 на входе драйвера L_PWM, значит на выходе драйвера M- будет установлен потенциал S+ digitalWrite(R_PWM, 0 ); // Устанавливаем логический 0 на входе драйвера R_PWM, значит на выходе драйвера M+ будет установлен потенциал S- analogWrite (EN, power ); // Устанавливаем ШИМ } else { digitalWrite(L_PWM, 0 );// Остановка и торможение digitalWrite(R_PWM, 0); analogWrite (EN, power); } } void error(int code) { detachInterrupt(0); while (true) { for (int i = 1; i <= code; i++) { digitalWrite(13, HIGH); delay(700); digitalWrite(13, LOW); delay(500); } delay(1500); } }
Как именно "перестает работать"? Зависает, сваливается в ошибку или еще как? На каком именно действии останавливается - всегда на одном или на разных?
Дополню
1. Reset на плате восстанавливает работоспособность меги.
2. Зависание происходит через несколько минут во время игры. В периоде ожидания (когда данные не меняются, цикл крутится вхолостую) зависания не происходит.
acces969, Вам же залаи вопрос "как именно и в каком месте останавливается".
У Вас там много вывода в монитор порта. Выложите протокол от начала и до зависания, это помогло б тому, кто захочет разбираться.
Сообщения ничего не дают = просто поток сообщений прекращается и все. Остановится может в любой момент. Последнее сообщение всегда "stopped ...".
Но вот что заметил - если закрыть окно монитора порта и вновь открыть его, то иногда мега "оживает" и начинает работать, в т.ч. отправлять сообщения. Но это не всегда
Поставьте скорость порта 115200.
Что я вижу из недоработок: переменные, меняющиеся в прерывании, объявлены volatile - это хорошо. Однако, вне прерывания, в loop - работа с ними идёт неатомарно. Думаю, в этом и причина странного поведения.
Что надо сделать:
1. Сейчас в loop:
Надо:
Надеюсь, мысль понятна ;)
Сообщения ничего не дают
Сообщения - они как бабы - одному дают, другому - нет. Тебе по-русски сказали: "это помогло б", но если ты лучше знаешь, кто кому и что даёт, то разбирайся сам.
Я бы проверил, не кончается ли свободная память - погуглите функцию FreeRAM, она даже тут на форуме пробегала. И проследите за числом. Она может как уменьшаться, если есть утечка, так и увеличиваться резко, что говорит о проблемах с работой с памятью.