Как проверить контроллер

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

Ничего удивительного, такое бывает, если часть пинов подгорело. Если их не использовать - работает устойчиво.
А корень проблемы, скорее всего, тоже в коде. Просто подгорает медленно.

Почему бы и не быть? Напишите, Валера, будете первопроходцем :wink:

так он уже написал. Отличный тестовый код - если контроллер зависает, значит “китайский”

Вовчик, я ленивый. Сначала на гитхабе попробую найти.

Такая шутка в голове крутится.

Даже доска начинает понимать о чем речь.

Пины сами не подгорают. Причина не в контроллере, а в коде или ошибочной схемотехнике.
Так что после того, как вы выложите код - надо будет показать еще и схему.

Ты смотри, он в приятели набивается :sweat_smile:

Да! все контроллеры разные однако:

#define Version 1.08

#define SIGRD 5

#include <avr/boot.h>
#include <ArduinoUniqueID.h>


typedef struct {
  byte sig[3];
  const char *desc;
} signatureType;

int foundSig = -1;
unsigned int tik = 0;
byte freq, count = 0;

volatile unsigned int int_tic;
volatile unsigned long tic;
bool readwdt = 0;
unsigned int n = 0;

void setWDT() {
  TCCR1B = 0; TCCR1A = 0; TCNT1 = 0;
  TIMSK1 = 1 << TOIE1;
  TCCR1B = 1 << CS10;
  WDTCSR = (1 << WDCE) | (1 << WDE); //установить биты WDCE WDE (что б разрешить запись в другие биты
  WDTCSR = (1 << WDIE) | (1 << WDP2) | (1 << WDP1); // разрешение прерывания + выдержка 1 секунда(55 страница даташита)
}

ISR (TIMER1_OVF_vect) { //прерывания счёта по переполнению uint
  int_tic++; //считать переполнения через 65536 тактов
}

void setup()
{
  Serial.begin(115200);
  Serial.print(F("\nSysInfo for Arduino version "));
  Serial.println(Version);
  Serial.println();

  //UniqueIDdump(Serial);
  Serial.print("UniqueID: ");
  for (size_t i = 0; i < UniqueIDsize; i++)
  {
    if (UniqueID[i] < 0x10)
      Serial.print("0");
    Serial.print(UniqueID[i], HEX);
    Serial.print(" ");
  }
  Serial.println();

  delay(1000);

  Frequency();
  Serial.println();
  Serial.print(F("F_CPU = "));
  Serial.println(F_CPU);

  Serial.print(F("Frequency = "));
  Serial.print(freq);
  Serial.println(F(" MHz"));
  Serial.println();

  CPU();
  Memory();
  Signature();
  VCC();
  Temperature();
  TestPins();
  int_tic = 0;
  readwdt = true;
  setWDT();
}

void loop() {}

void Frequency()
{
  byte fcpu;

  TCCR1A = 0;
  TCCR1B = 1 << CS10 | 1 << CS12; // clk/1024
  TCNT1 = 0;

  WDTCSR = (1 << WDCE) | (1 << WDE);
  WDTCSR = (1 << WDIE); // enable WDT delay 16ms

  while (count < 3) delay(1);

  WDTCSR = (1 << WDCE); // disable WDT

  if (tik <= 30) freq = 1;
  if ((tik > 30)  && (tik <= 100)) freq = 4;
  if ((tik > 100) && (tik <= 170)) freq = 8;
  if ((tik > 170) && (tik <= 240)) freq = 12;
  if ((tik > 240) && (tik <= 320)) freq = 16;
  if (tik > 320) freq = 20;

  fcpu = F_CPU / 1000000L;

  if ((fcpu == 16) && (freq == 8)) Serial.begin(19200);
}

ISR (WDT_vect) {
  if (!readwdt) {
    tik = TCNT1;
    count++;
    TCNT1 = 0;
  } else {
    if (n < 10) {
      n++;
      tic = ((uint32_t)int_tic << 16) | TCNT1 ; //подсчёт тиков
      Serial.print(" 1 Sec WDT= ");
      Serial.print( (float) tic * 625E-10 , 6 );
      ICR1 = 0; int_tic = 0; TCNT1 = 0;
      Serial.print(' ');
      Serial.println("Seconds");
    }
  }
}

void CPU()
{
  Serial.print(F("CPU_IDE = "));

#if   defined(__AVR_ATmega328P__)
  Serial.println(F("ATmega328P"));
#elif defined(__AVR_ATmega328PB__)
  Serial.println(F("ATmega328PB"));
#elif defined(__AVR_ATmega328__)
  Serial.println(F("ATmega328"));
#elif defined(__AVR_ATmega48__)
  Serial.println(F("ATmega48"));
#elif defined(__AVR_ATmega48P__)
  Serial.println(F("ATmega48P"));
#elif defined(__AVR_ATmega88__)
  Serial.println(F("ATmega88"));
#elif defined(__AVR_ATmega88P__)
  Serial.println(F("ATmega88P"));
#elif defined(__AVR_ATmega168__)
  Serial.println(F("ATmega168"));
#elif defined(__AVR_ATmega168P__)
  Serial.println(F("ATmega168P"));
#elif defined(__AVR_ATmega164__)
  Serial.println(F("ATmega164"));
#elif defined(__AVR_ATmega164P__)
  Serial.println(F("ATmega164P"));
#elif defined(__AVR_ATmega324__)
  Serial.println(F("ATmega324"));
#elif defined(__AVR_ATmega324P__)
  Serial.println(F("ATmega324P"));
#elif defined(__AVR_ATmega644__)
  Serial.println(F("ATmega644"));
#elif defined(__AVR_ATmega644P__)
  Serial.println(F("ATmega644P"));
#elif defined(__AVR_ATmega1284__)
  Serial.println(F("ATmega1284"));
#elif defined(__AVR_ATmega1284P__)
  Serial.println(F("ATmega1284P"));
#elif defined(__AVR_ATmega640__)
  Serial.println(F("ATmega640"));
#elif defined(__AVR_ATmega1280__)
  Serial.println(F("ATmega1280"));
#elif defined(__AVR_ATmega1281__)
  Serial.println(F("ATmega1281"));
#elif defined(__AVR_ATmega2560__)
  Serial.println(F("ATmega2560"));
#elif defined(__AVR_ATmega2561__)
  Serial.println(F("ATmega2561"));
#elif defined(__AVR_ATmega8U2__)
  Serial.println(F("ATmega8U2"));
#elif defined(__AVR_ATmega16U2__)
  Serial.println(F("ATmega16U2"));
#elif defined(__AVR_ATmega32U2__)
  Serial.println(F("ATmega32U2"));
#elif defined(__AVR_ATmega16U4__)
  Serial.println(F("ATmega16U4"));
#elif defined(__AVR_ATmega32U4__)
  Serial.println(F("ATmega32U4"));
#elif defined(__AVR_AT90USB82__)
  Serial.println(F("AT90USB82"));
#elif defined(__AVR_AT90USB162__)
  Serial.println(F("AT90USB162"));
#elif defined(__AVR_ATtiny24__)
  Serial.println(F("ATtiny24"));
#elif defined(__AVR_ATtiny44__)
  Serial.println(F("ATtiny44"));
#elif defined(__AVR_ATtiny84__)
  Serial.println(F("ATtiny84"));
#elif defined(__AVR_ATtiny25__)
  Serial.println(F("ATtiny25"));
#elif defined(__AVR_ATtiny45__)
  Serial.println(F("ATtiny45"));
#elif defined(__AVR_ATtiny85__)
  Serial.println(F("ATtiny85"));
#elif defined(__AVR_ATtiny13__)
  Serial.println(F("ATtiny13"));
#elif defined(__AVR_ATtiny13A__)
  Serial.println(F("ATtiny13A"));
#elif defined(__AVR_ATtiny2313__)
  Serial.println(F("ATtiny2313"));
#elif defined(__AVR_ATtiny2313A__)
  Serial.println(F("ATtiny2313A"));
#elif defined(__AVR_ATtiny4313__)
  Serial.println(F("ATtiny4313"));
#elif defined(__AVR_ATmega8__)
  Serial.println(F("ATmega8"));
#elif defined(__AVR_ATmega8A__)
  Serial.println(F("ATmega8A"));
#else
  Serial.println(F("Unknown"));
#endif

  Serial.println();
}

void Memory()
{
  extern int __bss_end, *__brkval;
  int freeRam;

  Serial.print(F("Flash Memory = "));
  Serial.print(FLASHEND);
  Serial.println(F(" bytes"));

  if ((int)__brkval == 0)
    freeRam = ((int)&freeRam) - ((int)&__bss_end);
  else
    freeRam = ((int)&freeRam) - ((int)__brkval);

  Serial.print(F("Free RAM memory = "));
  Serial.print(freeRam);
  Serial.println(F(" bytes"));

  Serial.println();
}

void Signature()
{
  const signatureType signatures [] = {
    { { 0x1E, 0x95, 0x0F }, "ATmega328P",  },    //  0
    { { 0x1E, 0x92, 0x05 }, "ATmega48A",   },    //  1
    { { 0x1E, 0x92, 0x0A }, "ATmega48PA",  },    //  2
    { { 0x1E, 0x93, 0x0A }, "ATmega88A",   },    //  3
    { { 0x1E, 0x93, 0x0F }, "ATmega88PA",  },    //  4
    { { 0x1E, 0x94, 0x06 }, "ATmega168A",  },    //  5
    { { 0x1E, 0x94, 0x0B }, "ATmega168PA", },    //  6
    { { 0x1E, 0x95, 0x14 }, "ATmega328",   },    //  7
    { { 0x1E, 0x95, 0x16 }, "ATmega328PB", },    //  8
    { { 0x1E, 0x94, 0x0A }, "ATmega164P",  },    //  9
    { { 0x1E, 0x95, 0x08 }, "ATmega324P",  },    // 10
    { { 0x1E, 0x96, 0x0A }, "ATmega644P",  },    // 11
    { { 0x1E, 0x97, 0x05 }, "ATmega1284P", },    // 12
    { { 0x1E, 0x97, 0x06 }, "ATmega1284",  },    // 13
    { { 0x1E, 0x96, 0x08 }, "ATmega640",   },    // 14
    { { 0x1E, 0x97, 0x03 }, "ATmega1280",  },    // 15
    { { 0x1E, 0x97, 0x04 }, "ATmega1281",  },    // 16
    { { 0x1E, 0x98, 0x01 }, "ATmega2560",  },    // 17
    { { 0x1E, 0x98, 0x02 }, "ATmega2561",  },    // 18
    { { 0x1E, 0x93, 0x89 }, "ATmega8U2",   },    // 19
    { { 0x1E, 0x94, 0x89 }, "ATmega16U2",  },    // 20
    { { 0x1E, 0x95, 0x8A }, "ATmega32U2",  },    // 21
    { { 0x1E, 0x94, 0x88 }, "ATmega16U4",  },    // 22
    { { 0x1E, 0x95, 0x87 }, "ATmega32U4",  },    // 23
    { { 0x1E, 0x93, 0x82 }, "At90USB82",   },    // 24
    { { 0x1E, 0x94, 0x82 }, "At90USB162",  },    // 25
    { { 0x1E, 0x91, 0x0B }, "ATtiny24",    },    // 26
    { { 0x1E, 0x92, 0x07 }, "ATtiny44",    },    // 27
    { { 0x1E, 0x93, 0x0C }, "ATtiny84",    },    // 28
    { { 0x1E, 0x91, 0x08 }, "ATtiny25",    },    // 29
    { { 0x1E, 0x92, 0x06 }, "ATtiny45",    },    // 30
    { { 0x1E, 0x93, 0x0B }, "ATtiny85",    },    // 31
    { { 0x1E, 0x91, 0x0A }, "ATtiny2313A", },    // 32
    { { 0x1E, 0x92, 0x0D }, "ATtiny4313",  },    // 33
    { { 0x1E, 0x90, 0x07 }, "ATtiny13A",   },    // 34
    { { 0x1E, 0x93, 0x07 }, "ATmega8A",    }     // 35
  };

  int flashSize, NumSig = 36;
  byte sig[3], fuse;

  Serial.print(F("Signature = "));

  sig[0] = boot_signature_byte_get(0);
  if (sig[0] < 16) Serial.print("0");
  Serial.print(sig[0], HEX);
  Serial.print(" ");

  sig[1] = boot_signature_byte_get(2);
  if (sig[1] < 16) Serial.print("0");
  Serial.print(sig[1], HEX);
  Serial.print(" ");

  sig[2] = boot_signature_byte_get(4);
  if (sig[2] < 16) Serial.print("0");
  Serial.println(sig[2], HEX);

  Serial.print(F("Fuses (Low/High/Ext/Lock) = "));

  fuse = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS);
  if (fuse < 16) Serial.print("0");
  Serial.print(fuse, HEX);
  Serial.print(" ");

  fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
  if (fuse < 16) Serial.print("0");
  Serial.print(fuse, HEX);
  Serial.print(" ");

  fuse = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS);
  if (fuse < 16) Serial.print("0");
  Serial.print(fuse, HEX);
  Serial.print(" ");

  fuse = boot_lock_fuse_bits_get(GET_LOCK_BITS);
  if (fuse < 16) Serial.print("0");
  Serial.println(fuse, HEX);

  flashSize = 1 << (sig[1] & 0x0F);

  for (int j = 0; j < NumSig; j++)
  {
    if (memcmp(sig, signatures[j].sig, 3) == 0)
    {
      foundSig = j;
      Serial.print(F("Processor = "));
      Serial.println(signatures[j].desc);

      Serial.print(F("Flash memory size = "));
      Serial.print(flashSize, DEC);
      Serial.println(F(" kB"));
      break;
    }
  }

  if (foundSig < 0) Serial.println(F("Unrecogized signature"));

  Serial.println();
}

void VCC()
{
#define Vref 1100
  int mvVcc;

  if ((foundSig >= 0) && (foundSig <= 8)) {

    ADMUX = (1 << REFS0) | 0x0E;
    ADCSRB = 0;
    ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADSC) | 0x05;
    delay(1);
    mvVcc = (1023L * Vref) / ADC;

    Serial.print(F("VCC = "));
    Serial.print(mvVcc);
    Serial.println(F(" mV"));
    Serial.println();
  }

  if ((foundSig >= 14) && (foundSig <= 18)) {

    ADMUX = (1 << REFS0) | 0x1E;
    ADCSRB = 0;
    ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADSC) | 0x05;
    delay(1);
    mvVcc = (1023L * Vref) / ADC;

    Serial.print(F("VCC = "));
    Serial.print(mvVcc);
    Serial.println(F(" mV"));
    Serial.println();
  }

  if ((foundSig >= 22) && (foundSig <= 23)) {

    ADMUX = (1 << REFS0) | 0x1E;
    ADCSRB = 0;
    ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADSC) | 0x05;
    delay(1);
    mvVcc = (1023L * Vref) / ADC;

    Serial.print(F("VCC = "));
    Serial.print(mvVcc);
    Serial.println(F(" mV"));
    Serial.println();
  }

  if ((foundSig >= 29) && (foundSig <= 31)) {

    ADMUX = 0x0E;
    ADCSRB = 0;
    ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADSC) | 0x05;
    delay(1);
    mvVcc = (1023L * Vref) / ADC;

    Serial.print(F("VCC = "));
    Serial.print(mvVcc);
    Serial.println(F(" mV"));
    Serial.println();
  }
}

void Temperature()
{
  float temperature;

  if ((foundSig >= 0) && (foundSig <= 8)) {

    ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << MUX3);
    ADCSRA |= (1 << ADEN);
    delay(20);
    ADCSRA |= (1 << ADSC);
    delay(1);

    temperature = (ADC - 324.31) / 1.22;

    Serial.print(F("Internal Temperature = "));
    Serial.print(temperature, 1);
    Serial.println(F(" C"));
    Serial.println();
  }

  if ((foundSig >= 22) && (foundSig <= 23)) {

    ADMUX = (1 << REFS1) | (1 << REFS0) | 0x07;
    ADCSRB = 0x20;
    ADCSRA |= (1 << ADEN);
    delay(20);
    ADCSRA |= (1 << ADSC);
    delay(1);

    temperature = (ADC - 324.31) / 1.22;

    Serial.print(F("Internal Temperature = "));
    Serial.print(temperature, 1);
    Serial.println(F(" C"));
    Serial.println();
  }

  if ((foundSig >= 29) && (foundSig <= 31)) {

    ADMUX = (1 << REFS1) | 0x0F;
    ADCSRA |= (1 << ADEN);
    delay(20);
    ADCSRA |= (1 << ADSC);
    delay(1);

    temperature = (ADC - 324.31) / 1.22;

    Serial.print(F("Internal Temperature = "));
    Serial.print(temperature, 1);
    Serial.println(F(" C"));
    Serial.println();
  }
}

void TestPins()
{
#define FIRST_PIN 0
#define LAST_PIN 19

  Serial.println(F("Test of short circuit on GND or VCC:"));

  for (byte pin = FIRST_PIN; pin <= LAST_PIN; pin++)
  {
    if (pin < 10) Serial.print(F("Pin:  "));
    else Serial.print(F("Pin: "));
    Serial.print(pin);

    pinMode(pin, OUTPUT);
    digitalWrite(pin, 0);
    Serial.print(F("    Low: "));
    if (!digitalRead(pin)) Serial.print(F("Ok  "));
    else Serial.print(F("Fail"));

    digitalWrite(pin, 1);
    Serial.print(F("  High: "));
    if (digitalRead(pin)) Serial.print(F("Ok  "));
    else Serial.print(F("Fail"));

    pinMode(pin, INPUT_PULLUP);
    Serial.print(F("  Pull Up: "));
    if (digitalRead(pin)) Serial.print(F("Ok  "));
    else Serial.print(F("Fail"));

    Serial.println();
    pinMode(pin, INPUT);
  }

  Serial.println();
}

Ссылку на автора не даю, искать на старом форуме было в лом…
ЗЫ (с) уж извини друг PS по моему автор был (c) ARDUINEC

1 лайк

Спасибо. Примерно такой код и представлял.
П.С. И шутникам спасибо. Подняли настроение.

никто и не шутил

За все время работы с 2014 года с ардуино совместимыми контроллерами еще ни разу не слетал код с контроллера. Да и спалил их (насильно, в целях тестирования)- единицы. При правильном питании(!!!) и обвесе- это почти невозможно. Покупаю с китая самые дешевые МК AVR. Платы развожу сам. Первая ардуина Уно еще жива(не мк , а сама плата-больше как талисман).Но прошивка еще не слетела ни с одного устройства.
ТС попутал МК с процессорами ПК. Еще и бенчмарк ищет для МК.

2 лайка

Это Вы серьезно?
Вот у меня, например, один из контроллеров вместо логического нуля выдает 1.6 В. Вы уверены, что опубликованная программа сумеет выявить эту неисправность?
А между тем, наиболее часто встречающиеся неисправности контроллеров связаны именно с неисправностью входных/выходных цепей, а не с неисправностью АЛУ.
Опять же, большая часть информации берется из настроек компилятора в момент компиляции скетча. Т.е. что Вы зададите, именно то и получите.

Как напишите что-нибудь сложнее бегущей строки, так поговорим. Особенно управление индуктивной нагрузкой.

Интересно что вы имеете в виду. Слишком уж разные у людей представления о правильном питании.

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

Более чем. Что интересовало, про то и спросил. Аппаратные проблемы диагностируются мгновенно, особенно при заведомо рабочем коде.

П.С. Тут совсем рядом доказывали, что проблема может быть только в коде. Аппаратных проблем не существует, и компилятор не влияет. Как же так? Врали?

Ну судя по тому , что вы используя нано за 200р в проекте называете его “серьезным”, наши понятия о серьезном -разные. Какая индуктивная нагрузка вас “особенно” пугает?


Это работает с 2014 года . Одна из первых поделок.И работает 24/7. И условия не идеальные :температура ,влажность, все нагрузки индуктивные(от электроклапанов до пускателей и электромоторов).За эти года много такого сделано было (блоки управления). И ничего - прошивка еще не разу не слетела. Поначалу были сбросы -зависания(индуктивная нагрузка). А сейчас -все ок. Питание , фильтры по питанию и т.д.
Ну и расскажите мне про сложности еще что-нибудь.Про поливалку ,теряющую мозги, выключатель света в туалете, забывающий выключить свет вовремя и т.д? :slightly_smiling_face:
Если чо- моя работа справа вверху(платки). Остальное заказчик категорически запретил даже трогать.

А что, разве в итоге доказали, что был виноват компилятор?
Единственное, что доказано точно - что ТС наврал насчет того, что измерения зависят от числа Сериал принтов. Ну и заодно показал незнание элементарных вещей, типа назначения функции Пинмоде

Вы это озвучьте в любом пункте ремонта радиоаппаратуры.

Мне кажется, диагноз ясен.

2 лайка

Да да, а у ремонтера еще брат боксер, в мастерской в это время должен находится, который должен сразу мне в морду дать.

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

До доски не доходит, что если на одном компе копмилируется нормально, а на другом возникают баги, то что-то с компилятором?

Я так понимаю, примитивная релейная логика: вкл/выкл?

Про питание так и не ответили.