ESP32 DevKitC прошивается, но не хочет выполнять никаких программ. Даже мигать LEDом

Каждый выбирает по себе женщину…
Кому-то повезло завоевать сердце Королевы…а кому-то иные достались…зависть плохое качество…

Ох… Всему учить надо! Еще в песне поёццо: “…добъёмся мы освобождения своею собственной рукой!”.

Маяковского по случаю цитировать, или эрудиции хватит?

https://rustih.ru/vladimir-mayakovskij-ej-onanisty-krichite-ura/

Я в матклассе учился. В школе 179. В 1981-83 годах. Ездил кажный день из Зелика на м.Площадь Свердлова :frowning:

84-86. Там же, у Романа. Возможно ты был среди тех, кому я листочки сдавал.

дело пахнет керосином…

(Только что прочел - совсем закрутился с этими микросхемами)
СУПЕР! В смысле у РОмана? Он нам тоже преподавал. Да-а, прекрасные там были учителя. Получается, что мы почти однокашники! :slight_smile: Это приятно!

да. у Сергея Григорьевича.

На свякий случай приведу текст своей программы для управления воспроизведением аудиофайлов с помощью 9 кнопок (4х2 + 1).
Систему собрал, но программа постоянно перезагружается - видимо ESP32 не хватает питания от кабеля microUSB, идущего от компьютера (что странно).
В системе еще присутствуют:
реле, МР3-плеер, дисплей (только светится - даже стандартные примеры из библиотеки не запускает), блок 8 кнопок 4х2, отдельная кнопка для отключения устройства, два сопротивления (для перехода от 5В к 3,3В), блок питания 5В (всего лишь на 600 мА - по ошибке купил маломощный). Блок питания могу поменять на зарядное устройство 2,5А 5В.
ТЕКСТ

#include <EEPROM.h>
// #include <driver/gpio.h>
//#include "driver/timer.h"
//static const uint8_t K3volDn = 9; //кнопка Тише
static const int K3volDn = 9; //кнопка Тише
static const int K7volUp = 7; //кнопка Громче
static const int K2trackPrev = 35; //кнопка Предыдущий трек
static const int K6trackNext = 8; //кнопка Следующий трек
static const int K1endTimeDn = 39; //кнопка Время до конца работы уменьшить на 30 мин
static const int K5endTimeUp = 11; //кнопка Время до конца работы увеличить на 30 мин
static const int K0defaultTimeDn = 36; //кнопка Время работы по умолч. уменьшить на 30 мин
static const int K4defaultTimeUp = 10; //кнопка Время дработы по умолч. увеличить на 30 мин
static const int Kswitch = 6; //кнопка Выключить/Включить (красного цвета)
static const int IRout = 23; //выход ИК-датчика
static const int Mp3BUSY = 34; // вкл-выкл MP3-плеер
static const int TXprogr = 17; //выход ESP32 = программируемый TX
static const int RXprogr= 16; //выход ESP32 = программируемый RX
unsigned long Time_Ms; // время (мс), прошедшее после запуска setup()
const int DisplayTimeout = 7000000;  //7000000мкс=7сек - время в мкс загорания экрана (использует таймер timerDisplay)
static const uint8_t RelayIN = GPIO_NUM_25; // вкл-выкл реле
// gpio_pad_select_gpio(RelayIN);
// gpio_set_direction(RelayIN, GPIO_MODE_OUTPUT);

hw_timer_t *timerDisplay = NULL;
hw_timer_t *timerFireplace = NULL;

unsigned long LastPressingTime = 0; // время (мс) последнего нажимания на какую-либо кнопку
unsigned int checksum;
byte highChk, lowChk;         // control command template
byte serialCom[10] = {0x7E,0xFF,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xEF};
// = start version length CMD feedback para[1, 2] checksum[high, low] end
byte buffer[10];

byte Volume; //громкость
byte Track; //номер трека
byte DefaultTime; //время выключения (ед.измер.=30 мин), по умолчанию задаваемое после включения камина
int EndTime; //время до конца работы (ед.измер.=1 мин)
int EditRow = (-1); //номер строки, редактируемой на экране дисплея

bool EditMode = false; //включен ли режим редактирования параметров (сразу после включения камина в сеть режим выключен)
bool IsFireplaceWork = true; //включен ли камин

int KeyNumber = 0; //KeyNumber - это номер нажатой кнопки: 1-8 для кнопок 2х4, 9 для красной кнопки. 
//=Значение KeyNumber = 0 означает, что нет нажатий, требующий выполнения (т.е. последняя нажатая кнопка уже "отработана" или "отрабатывается")

void setup() {
  Serial.begin(9600);
  Serial.println("Hi, world!");
  pinMode(RelayIN, OUTPUT);
  Time_Ms = millis();
  //запуск обработчика завершения трека
  // attachInterrupt(digitalPinToInterrupt(Mp3BUSY), TrackFinished, RISING);
   
  //запуск обработчиков 9 кнопок
  attachInterrupt(digitalPinToInterrupt(K3volDn), volDn, RISING);
  attachInterrupt(digitalPinToInterrupt(K7volUp), volUp, RISING);
  attachInterrupt(digitalPinToInterrupt(K2trackPrev), trackPrev, RISING);
  attachInterrupt(digitalPinToInterrupt(K6trackNext), trackNext, RISING);
  attachInterrupt(digitalPinToInterrupt(K1endTimeDn), endTimeDn, RISING);
  attachInterrupt(digitalPinToInterrupt(K5endTimeUp), endTimeUp, RISING);
  attachInterrupt(digitalPinToInterrupt(K0defaultTimeDn), defaultTimeDn, RISING);
  attachInterrupt(digitalPinToInterrupt(K4defaultTimeUp), defaultTimeUp, RISING);
  attachInterrupt(digitalPinToInterrupt(Kswitch), fireplaceSwitch, RISING);

  //запуск обработчика ИК-датчика
//  ???????????????
  // считывание сохраненных в энергонезависимой памяти значений громкости, номера трека и времени работы по умолчанию:
  EEPROM.begin(3);
  Volume = EEPROM.read(0);
  if (Volume==255) {EEPROM.write(0,10);}
  Track = EEPROM.read(1);
  if (Track==255) {EEPROM.write(1,1);}
  DefaultTime = EEPROM.read(2);
  if (DefaultTime==255) {EEPROM.write(2,10);}
  EEPROM.end();
 
  //запуск таймера отключения камина = timer 0
  timerFireplace = timerBegin(0, 80, true);          //timer 0, div 80 / 80 МГц = 1 мкс
  timerAttachInterrupt(timerFireplace, &SwitchOffFireplace, true);  //attach callback
  timerAlarmWrite(timerFireplace, 30*60000000*DefaultTime, false); //false = сработает один раз, без повторений
  // =обработчик сработает через DefaultTime*30 минут, т.к. 60000000 мкс = 1 минута, а ед.измер. в DefaultTime - 30 минут
  timerAlarmEnable(timerFireplace);                          //запускаем использование прерывания 
  
  //запуск таймера "отключения экрана" = timer 1
  timerDisplay = timerBegin(0, 80, true);                  //timer 0, div 80 / 80 МГц = 1 мкс
  timerAttachInterrupt(timerDisplay, &FinishEditMode, true);  //attach callback
  timerAlarmWrite(timerDisplay, DisplayTimeout, false); // сработает через DisplayTimeout=7000000 мкс = 7 сек; false = сработает один раз, без повторений
  //timerAlarmEnable(timer);                          //запускаем использование прерывания = включаем генерацию тревожных событий таймера


}


bool IsBounce(unsigned long RealTime, unsigned long LastTime) { // возвращает true, если дребезг кнопки или нажато сразу несколько кнопок 
  // если с предпоследнего нажатия кнопки прошло меньше 100 мс, то последнее нажатие - это или дребезг, или нажато неколько кнопок сразу:
  return((RealTime - LastTime) < 100); 
}

void StartEditMode() {  //вместо ARDUINO_ISR_ATTR можно IRAM_ATTR  ВРЕМ УБРАЛ!!!!!!!!!!!!!!!!!!!!!!
  EEPROM.begin(3);
  // восстановление значений громкости, номера трека и времени работы по умолчанию
  Volume = EEPROM.read(0);
  Track = EEPROM.read(1);
  DefaultTime = EEPROM.read(2);
  EEPROM.end();
  SwitchDisplay(true);
  EditMode = true;  
}

void FinishEditMode() {  //вместо ARDUINO_ISR_ATTR можно IRAM_ATTR
  EEPROM.begin(3);
  // восстановление значений громкости, номера трека и времени работы по умолчанию
  if (Volume != EEPROM.read(0)) { EEPROM.write(0, Volume); }
  if (Track != EEPROM.read(1)) { EEPROM.write(1, Track); }
  if (DefaultTime != EEPROM.read(2)) { EEPROM.write(2, DefaultTime); }
  EEPROM.end();
  SwitchDisplay(false);
  EditMode = false;
  timerStop(timerDisplay); //остановка счетчика таймера
  EditRow = (-1);
}

void SwitchDisplay(bool TurnOn) { //если TurnOn=true, то экран включается, а если TurnOn=false, то экран выключается
//выключить экран ?????????????
}

void RefreshDisplay(int Row, int OldRow) { //обновляет изображение строки Row (0,1,2) на экране дисплея, с учетом, что перед этим обновлялась строка OldRow
//обновить строку Row ?????????????
//ЗАГЛУШКА
  Serial.print("Громкость: ");
  Serial.println(Volume);
  Serial.print("Трек: ");
  Serial.println(Track);
  Serial.print("Отключится через (мин): ");
  Serial.println(EndTime);
  Serial.print("Время раб.по умолч. (час): ");
  Serial.println(DefaultTime/2);
}

int ButtonPressing(int Key)
{
  if(!IsFireplaceWork) { return(0); }
  LastPressingTime = millis(); //обновляем время последнего нажатия
  timerRestart(timerDisplay);  //перезапуск счетчика времени таймера погашения дисплея
  if(!EditMode) { StartEditMode(); } //"если экран погашен, то включить его" (запустить режим редактирования)

  //если дребезг кнопки или нажато сразу несколько кнопок - считаем, что кнопка не нажата и ничего не делаем
  if(IsBounce(millis(), LastPressingTime)) { return(0); } 
  //иначе возвращаем нажатую клавишу 
  else { return(Key); }
}

void loop() {
  if(KeyNumber==1) 
  { 
    cmd(0x05, 0);           // уменьшить громкость на 1 
    Volume = cmd(0x43, 0);  // получить величину громкости, установленную плеером в рез-те вып-я команды = get volume value
    RefreshDisplay(0, EditRow);
    EditRow = 0;
  }
  else if(KeyNumber==2)  
  {
    cmd(0x04, 0);           // увеличить громкость на 1 = increase volume
    Volume = cmd(0x43, 0);  // получить величину громкости, установленную плеером в рез-те вып-я команды = get volume value
    RefreshDisplay(0, EditRow);
    EditRow = 0;
  }
  else if(KeyNumber==3)  
  {
    cmd(0x02, 0);          // предыдущий трек
    Track = cmd(0x4C, 0);  // получить номер трека
    RefreshDisplay(1, EditRow);
    EditRow = 1;
  }
  else if(KeyNumber==4)  
  {
    cmd(0x01, 0);          // следующий трек
    Track = cmd(0x4C, 0);  // получить номер трека
    RefreshDisplay(1, EditRow);
    EditRow = 1;
  }
  else if(KeyNumber==5)  
  {
    if (EndTime > 30) 
    { 
      EndTime = EndTime - 30; 
      RefreshDisplay(2, EditRow);
      EditRow = 2;
    }
  }
  else if(KeyNumber==6)  
  {
    if (EndTime < 2160) 
    { //время работы можно увеличить, если оно не превышает 36 часов
      EndTime = EndTime + 30; 
      RefreshDisplay(2, EditRow);
      EditRow = 2;
    }
  }
  else if(KeyNumber==7)  
  {
    if (DefaultTime > 1) 
    { //время работы по умолчанию можно уменьшить, если оно больше получаса (=1/2)
      DefaultTime = DefaultTime - 1; 
      RefreshDisplay(3, EditRow);
      EditRow = 3;
    }
  }
  else if(KeyNumber==8)  
  {
    if (DefaultTime < 72) //время работы по умолчанию можно увеличить, если оно не превышает 36 часов (=72/2)
    { 
      DefaultTime = DefaultTime + 1; 
      RefreshDisplay(3, EditRow);
      EditRow = 3;
    }
  }
  else if(KeyNumber==9)  
  {
    if (IsFireplaceWork) 
    { 
      FinishEditMode();
      digitalWrite(RelayIN, LOW); 
    } 
    else  //БЫЛО { gpio_set_level(RelayIN, 1); };
    { digitalWrite(RelayIN, HIGH); };

    IsFireplaceWork = !IsFireplaceWork;
  }
  
  
  KeyNumber==0;
  
}


void volDn() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(1); }
}

void volUp() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(2); }
}

void trackPrev() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(3); }
}

void trackNext() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(4); }
}
  
void endTimeDn() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(5); }
}

void endTimeUp() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(6); }
}

void defaultTimeDn() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(7); }
}

void defaultTimeUp() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(8); }
}

void fireplaceSwitch() {
  if(KeyNumber==0) { KeyNumber = ButtonPressing(9); }
}


void SwitchOffFireplace() {  //вместо ARDUINO_ISR_ATTR можно IRAM_ATTR 
  if(IsFireplaceWork)
  {  
    FinishEditMode();
    // gpio_set_level(RelayIN, 0); 
    digitalWrite(RelayIN, LOW); 
  }
  IsFireplaceWork = false;
}


IRAM_ATTR void TrackFinished()         // ISR
{
  cmd(0x03, Track);
}

byte cmd(byte CMD, byte param2)     // command function
{
  //delay(100);           // delay to debounce button = задержка для устранения дребезга кнопки
/* Контрольная сумма – это отрицательная сумма всех компонентов без начального и конечного битов. Контрольная сумма форматируется как старший и младший байты: */
  checksum = -(0xFF + 0x06 + CMD + 0x00 + 0x00 + param2); // build checksum
  highChk = highByte(checksum);     // split checksum into
  lowChk = lowByte(checksum);       //  high byte and low bytes
  serialCom[3] = CMD;
  serialCom[6] = param2;        // command components
  serialCom[7] = highChk;
  serialCom[8] = lowChk;        // transmit command to MP3
/*в setup() serialCom было присвоено: serialCom[10] = {0x7E,0xFF,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xEF}; = start version length CMD feedback para[1, 2] checksum[high, low] end  */
  for (int i=0; i<10; i++) Serial2.write(serialCom[i]); 
  
  delay(100);           // receive command from MP3
  for (int i=0; i<10; i++) buffer[i] = Serial2.read(); 
  //delay(100);
  return(buffer[6]);
}

Подключен еще ИК-датчк и имеется ИК-пульт управления, но я пока с ними не разбирался. Просто “занял” контакты в ESP32, чтобы не забыть, что эти контакты уже заняты.
Все собрано на двух макетных платах: вся система кроме МР3-плеера на плате 10х16 и МР3-плеер на плате 5х8 см
Вообще программа странно себя ведет. Для тестирования я вставил команду Serial.println(“Hi, world!”);
так ESP32 печатает Hi, world! в мониторе, но перед этим печатает 19 произвольных, меняющихся от раза к разу символов (там могут быть разрывы страниц и т.п., в общем цифровой мусор, который система воспринимает как символы ASCII )

тут есть личные сообщения.

Могу убрать, если нужно

это напишу открыто.
цитированная строка не соответствует матшкольнику! .Сорри, если обидел. Даже бывшему.

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