Ошибка во время выполнения скетча.

katon
Offline
Зарегистрирован: 06.11.2017

Здравствуйте, мой скетч не выполняется, а точнее просто замораживается. Есть следующий код

#include <QList.h>
#include "QList.cpp" 

#include <TimerOne.h>

volatile QList <byte> mySignal;

// This example uses the timer interrupt to blink an LED
// and also demonstrates how to share a variable between
// the interrupt and the main program.


void setup(void)
{
  pinMode(LED_BUILTIN, OUTPUT);
  //Timer1.initialize(100000);// в микросекундах
  Timer1.initialize(300000);// в микросекундах
  Timer1.attachInterrupt(blinkLED); // blinkLED to run every 0.10 seconds
  Serial.begin(9600);
}


// The interrupt will blink the LED, and keep
// track of how many times it has blinked.
int ledState = LOW;
volatile unsigned long blinkCount = 0; // use volatile for shared variables

void blinkLED(void)
{
  if (ledState == LOW) {
    ledState = HIGH;
    blinkCount = blinkCount + 1;  // increase when LED turns on
  } else {
    ledState = LOW;
  }
  digitalWrite(LED_BUILTIN, ledState);
  addItemSignal();
}


// The main program will print the blink count
// to the Arduino Serial Monitor
void loop(void)
{
  QList <byte> signalCopy;  // holds a copy of the mySignal

  // to read a variable which the interrupt code writes, we
  // must temporarily disable interrupts, to be sure it will
  // not change while we are reading.  To minimize the time
  // with interrupts off, just quickly make a copy, and then
  // use the copy while allowing the interrupt to keep working.

  //int m1=millis();
  noInterrupts();
  // тут прочитать стек
  int signalSize=mySignal.size();
  for (int i=0;i<signalSize;i++){
    signalCopy.push_back(mySignal.get(i));
  }
  interrupts();
   //int m2=millis();
  //Serial.println(m2-m1);
  
 /*
  for (int i=0;i<signalSize;i++){
    //Serial.print(signalCopy.get(signalSize-i-1));
    Serial.print(signalCopy.get(i));
    Serial.print(" ");
  }
  */
  Serial.println();
  
  //тут будет DTW
  noInterrupts();
  Serial.print("num - ");
  Serial.print(signalCopy.size());
  interrupts();
  int disctance=DTWrun(signalCopy,signalCopy);
  noInterrupts();
  Serial.print(" distance ");
   Serial.print(disctance);
    Serial.println();
interrupts();

}
void addItemSignal(){
  int curSig=analogRead(A0);
  if(curSig>255){
    curSig=255;
  }
  Serial.println("aaa");
  //Serial.println(mySignal.size());
  if (mySignal.size()>5){
    mySignal.pop_back();
  }
  mySignal.push_front((byte)curSig);
}

int DTWrun( QList <byte> v, QList <byte>  w ) {
  int cost;
  int mGamma [v.size()+1][w.size()+1];
  for( int i = 1; i <= w.size(); i++ ) {
    mGamma[0][i] = 0;
  }
  for( int i = 1; i <= v.size(); i++ ) {
    mGamma[i][0] = 0;
  }
  mGamma[0][0] = 0;
  
  for( int i = 1; i <= v.size(); i++ ) {
    for( int j = 1; j <= w.size(); j++ ) {
    //  cost = abs( v[i] - w[j] ) * abs( v[i] - w[j] );
      if( v.get(i - 1) == w.get(j - 1) ) {
        cost = 0;
      }
      else {
        cost = 1;
      }
      mGamma[i][j] = cost + min( mGamma[i-1][j], min(mGamma[i][j-1], mGamma[i-1][j-1]) );
    }
  }
  return 10;
}


Вывод:

num - 0 distance 10
 
num - 0 distance 10
 
num - 0 distance 10
 
num - 0 distance 10
 
num - 0aaa
 distance 10
 
num - 1 distance 10
 
num - 1aaa
 distance :⸮⸮
 
num - 2aa
 
 
-----

Ошибка происходить на 78 строчке. После этого перестают работать прерывания (не мигает светодиод, не добывляются новые элементы в список). Если убрать блок кода на 78 строке, все работает как часы. Во время. Стоит отметить что скетч крашится после того как в списке появляется первый элемент. Что я делаю не так?

Плата: Arduino Nano, процессор: ATmega 328P

sadman41
Offline
Зарегистрирован: 19.10.2016

Возможно, что у вашего QList нет деструктора, освобождающего память. Или вы его не вызываете. Поэтому, скорее всего на каждом лупе вы резервируете память при создании экземпляра QList и через несколько раундов она просто заканчивается, начинается запись в случайные ячейки, что приводит к аварийной ситуации.

Самое простое, думаю, сделать этот экземпляр глобальным и чистить его при заходе в луп, если это необходимо. 

Как - не спрашивайте, я такой библиотеки даже и не знаю.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Судя по второй строке. Библиотека еще тем "гением" написана

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Слава тебе, Господи, адекватный новичок появился! :)))

давайте, по порядку.

1. Удалите вторую строку. Если библиотека установлена правильно, оно и без неё должно работать.

2. Дайте ссылку на бибилотеку потому. что не видя её я не уверен в дальнейшем

3. например, скорее всего (но не видя библиотеки, трудно утверждать наверное), в строке 78 Вы теряете свой список. Вы передаёте два списка по значению. Если у них нет специального конструктора, то создаются новые экземпляры с теми же указателями и в памяти начинается каша.

Пока Вы мне не дали ссылки на библиотеку, попробуйте просто в строке 99 вместо

int DTWrun( QList <byte> v, QList <byte>  w ) {

написать

int DTWrun( QList <byte>  & v, QList <byte>  & w ) {

и скажите мне поменялось что-то или нет. Должно поменяться.

И ещё, возьмите вот в этой теме программу memory Explorer (там есть примеры использования) и с её помощью последите за памятью. Может чего интересного увидите.

Как всё это сделаете. выложите свежий скетч и описание как он себя ведёт (ну и ссылку на библиотеку не забудьте).

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

и вот тут должно вешаца

079   noInterrupts();
080   Serial.print(" distance ");
081    Serial.print(disctance);
082     Serial.println();
 

аптамуш, хардсериал по прерываниям работает, а оне тут запрещаюца.