Sparkfun Pro-Micro зависает при загрузке

Я читал несколько сообщений о том, как сбросить настройки sparkfun pro-micro, когда он зависает во время загрузки, и, кажется, это работает, чтобы вернуть его в состояние, когда я могу снова загрузить новый код. Тем не менее, я здесь, чтобы спросите, возможно ли, что что-то в моем коде вызывает эту проблему? Причина, по которой я подозреваю, что это мой код, заключается в том, что я пробовал:

  • Разные профессиональные микро
  • Другой USB-кабель
  • Загружена последняя версия IDE
  • Загружен последний пакет плат AVR
  • Пытался вернуться к более старому пакету плат AVR, как было предложено в другом посте.

Не уверен, что это совпадение, но когда я загружаю простой блинк-скетч, у меня нет никаких проблем, но как только я загружаю свой код (ниже), он зависает при загрузке. .. Я могу заставить его в конечном итоге загрузиться после многих попыток, используя трюк сброса во время загрузки, но он кажется нестабильным. Я говорю нестабильный, потому что иногда он выводит запрошенные значения, а иногда ничего не выводит...

int clampVal = 0;

void setup() {
  Serial.begin(115200);
}


void ClampReading()
{
    const int numRead = 400; //количество калибровочных значений, которое мы усредним
    double vals[numRead];      // показания с аналогового входа
    int readIndex2 = 0;                 // индекс текущего показания
    double total2 = 0;                  // промежуточный итог
    int calibration2 = 0;               // калибровочный инкремент

    for (int thisReading2 = 0; thisReading2 < numRead; thisReading2++) {
    vals[thisReading2] = 0;
    }
    while(calibration2<numRead)
    {
      int rawClamp = analogRead(A0);
      total2 = total2 - vals[readIndex2];
      vals[readIndex2] = rawClamp;
      total2 = total2 + vals[readIndex2];
      readIndex2 = readIndex2 + 1;
      if (readIndex2 >= numRead) {
        readIndex2 = 0;
     }
      clampVal = total2 / numRead;
      calibration2++;
    }

}  


void loop() {
 ClampReading();
 Serial.println(clampVal);
}

ИЗМЕНИТЬ: После сброса и загрузки ПУСТОГО скетча я могу без проблем загрузить пустой скетч. Я сделал это 5 раз подряд без проблем. Затем попытался загрузить приведенный выше код один раз, и это сработало... но затем попытался загрузить второй раз и снова застрял в загрузке... это должен быть код, но я не могу определить, что это такое.

, 👍0


1 ответ


Лучший ответ:

2

У Uno Mega и других устройств есть отдельный MCU (u3), который содержит загрузчик и отвечает за USB-соединение и управление виртуальным последовательным портом. Micros (а также Leonardos и Esploras) имеют встроенную поддержку USB в основной MCU (u4). Поэтому, если ваша программа делает что-то, что нарушает USB-часть MCU, связь также прерывается. Это происходит, например, если вы отключите прерывания.

Единственное, что может вызвать проблемы в вашей программе, — это последовательное соединение. Пример мигания не имеет последовательного вывода.

Если вы добавите Serial.begin(115200) и Serial.println("Hello") в пример с мерцанием, я предполагаю, что проблема также возникает.

Среда IDE устанавливает соединение для программирования путем подключения к выбранному COM-порту на скорости 1200 бод. Загрузчик распознает это, выполняет автоматический сброс и открывает второй (порт программирования), после чего IDE получает доступ к этому порту и использует его для связи с загрузчиком. В UNO этим занимается отдельный MCU, а в Micro за это отвечает главный процессор.

Возможно, будет лучше, если вы добавите временную задержку перед Serial.begin(). Тогда у вас будет больше времени для запуска программатора.

Есть также трюк, чтобы увеличить время, когда вы можете начать программирование после сброса, до 8 секунд. https://forum.arduino.cc/index.php?topic=224416.msg1643210#msg1643210

И еще одна подсказка:

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

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

Моя прог. имеет меньший объем памяти, потому что я сохраняю целочисленные значения из аналогового ввода в целочисленный массив. Вы использовали двойной массив.

Вы также сделали много ненужных вычислений после считывания аналогового значения. Это может замедлить чтение. Возможно, поэтому вы пропустили некоторые значения, которые ожидали увидеть.

//количество калибровочных значений, которое мы усредним
const int valueCount = 400; 
const int calibCount =   0; 

void setup() 
{ 
  Serial.begin(115200); 
}

void loop() 
{
  // показания с аналогового входа
  int vals[ valueCount ]; 

  for (int idx = 0; idx < valueCount + calibCount; idx++) 
  {
    int rawValue = analogRead( A0 );
    if ( idx >= calibCount )
    {
      vals[ idx - calibCount ] = rawValue;
    }
  }

  double total = (double) 0.0;

  for (int idx = 0; idx < valueCount; idx++) 
  {
    total += (double) vals[ idx ];
  }

  Serial.println( total / valueCount );
}
,

Спасибо @peter Paul Kiefer за очень подробное объяснение! Когда я вернусь к своему микро позже, я попробую ваши предложения и код, скрестив пальцы, это работает!, @MattG

Это, кажется, сделало свое дело. Я установил задержку в 500 мс между последовательными отпечатками, и теперь он загружается многократно. Спасибо за помощь!, @MattG