ATmega 168 (3,3V 8 MHz) рабочий скетч работает некорректно

leks
Offline
Зарегистрирован: 22.10.2017
// НОВОГОДНЯЯ МЕЛОДИЯ
int tonePin = 7; 
int minus = 6;
void setup()
{
pinMode(tonePin,OUTPUT);
pinMode(minus,OUTPUT);
digitalWrite(minus, LOW);
}


void midi() {
  const struct { 
    int freq, duration, dly; 
  } sounds[] = {
    {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750}, 
    {293, 225, 250}, {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, 
    {329, 450, 750}, {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250}, 
    {440, 225, 250}, {587, 450, 750}, {587, 225, 250}, {659, 225, 250}, {587, 225, 250}, 
    {523, 225, 250}, {440, 225, 250}, {493, 675, 750}, {293, 225, 250}, {293, 225, 250}, 
    {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750}, {293, 225, 250}, 
    {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {329, 450, 750}, 
    {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250}, {440, 225, 250}, 
    {587, 225, 250}, {587, 225, 250}, {587, 225, 250}, {587, 225, 250}, {659, 225, 250}, 
    {587, 225, 250}, {523, 225, 250}, {440, 225, 250}, {391, 450, 500}, {587, 450, 500}, 
    {493, 225, 250}, {493, 225, 250}, {493, 450, 500}, {493, 225, 250}, {493, 225, 250}, 
    {493, 450, 500}, {493, 225, 250}, {587, 225, 250}, {391, 337, 375}, {440, 112, 125}, 
    {493, 450, 1000}, {523, 225, 250}, {523, 225, 250}, {523, 337, 375}, {523, 112, 125}, 
    {523, 225, 250}, {493, 225, 250}, {493, 225, 250}, {493, 112, 125}, {493, 112, 125}, 
    {493, 225, 250}, {440, 225, 250}, {440, 225, 250}, {493, 225, 250}, {440, 450, 500}, 
    {587, 450, 500}, {493, 225, 250}//, {493, 225, 250}, {493, 450, 500}, {493, 225, 250}, //дальше не лезет ? в про мини 3,3 V (168)
    //{493, 225, 250}, {493, 450, 500}, {493, 225, 250}, {587, 225, 250}, {391, 337, 375}, 
   //{440, 112, 125}, {493, 450, 1000}, {523, 225, 250}, {523, 225, 250}, {523, 337, 375}, 
   //{523, 112, 125}, {523, 225, 250}, {493, 225, 250}, {493, 225, 250}, {493, 112, 125}, 
   // {493, 112, 125}, {587, 225, 250}, {587, 225, 250}, {523, 225, 250}, {440, 225, 250}, 
   // {391, 675, 750}
  };
  const uint8_t melodieLength = sizeof(sounds) / sizeof(sounds[0]);

  for (uint8_t i = 0; i < melodieLength; i++) {
    tone(tonePin, sounds[i].freq, sounds[i].duration);
    delay(sounds[i].dly);
  }
}

void loop()
{

midi();delay(5000);

}

 

leks
Offline
Зарегистрирован: 22.10.2017

Забавная история, здесь такой интересный скетч проскакивал (ребёнку вроде пытались помочь). Решил для тренировки в про мини залить. Как в исходнике - заработало с искажениями в двух местах мелодии. Пришлось подрезать массив примерно на четверть - заработало нормально. Почему возникла такая ситуация? Ведь пишет что в исходнике используется всего 62 процента динамической памяти (в приведённом варианте 48 проц.). 50 процентов почему то становятся критическими. Почему ?

PRC
Онлайн
Зарегистрирован: 03.02.2019

Попробуй так:

// НОВОГОДНЯЯ МЕЛОДИЯ
int tonePin = 7; 
int minus = 6;

const struct sound{ 
  int freq, duration, dly; 
  } sounds[] PROGMEM = {
    {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750}, 
    {293, 225, 250}, {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, 
    {329, 450, 750}, {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250}, 
    {440, 225, 250}, {587, 450, 750}, {587, 225, 250}, {659, 225, 250}, {587, 225, 250}, 
    {523, 225, 250}, {440, 225, 250}, {493, 675, 750}, {293, 225, 250}, {293, 225, 250}, 
    {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750}, {293, 225, 250}, 
    {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {329, 450, 750}, 
    {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250}, {440, 225, 250}, 
    {587, 225, 250}, {587, 225, 250}, {587, 225, 250}, {587, 225, 250}, {659, 225, 250}, 
    {587, 225, 250}, {523, 225, 250}, {440, 225, 250}, {391, 450, 500}, {587, 450, 500}, 
    {493, 225, 250}, {493, 225, 250}, {493, 450, 500}, {493, 225, 250}, {493, 225, 250}, 
    {493, 450, 500}, {493, 225, 250}, {587, 225, 250}, {391, 337, 375}, {440, 112, 125}, 
    {493, 450, 1000},{523, 225, 250}, {523, 225, 250}, {523, 337, 375}, {523, 112, 125}, 
    {523, 225, 250}, {493, 225, 250}, {493, 225, 250}, {493, 112, 125}, {493, 112, 125}, 
    {493, 225, 250}, {440, 225, 250}, {440, 225, 250}, {493, 225, 250}, {440, 450, 500}, 
    {587, 450, 500}, {493, 225, 250}, {493, 225, 250}, {493, 450, 500}, {493, 225, 250},
    {493, 225, 250}, {493, 450, 500}, {493, 225, 250}, {587, 225, 250}, {391, 337, 375}, 
    {440, 112, 125}, {493, 450, 1000},{523, 225, 250}, {523, 225, 250},{523, 337, 375}, 
    {523, 112, 125}, {523, 225, 250}, {493, 225, 250}, {493, 225, 250}, {493, 112, 125}, 
    {493, 112, 125}, {587, 225, 250}, {587, 225, 250}, {523, 225, 250}, {440, 225, 250}, 
    {391, 675, 750}
};
const uint8_t melodieLength = sizeof(sounds) / sizeof(sound);
sound SoundSRAM;
    
void setup()
{
pinMode(tonePin,OUTPUT);
pinMode(minus,OUTPUT);
digitalWrite(minus, LOW);
Serial.begin(9600);
}

void midi() {
  
  Serial.println(melodieLength);
  for (uint8_t i = 0; i < melodieLength; i++) {

    memcpy_P( &SoundSRAM, &sounds[i], sizeof(sound));
    
    Serial.print(i);Serial.print("=");
    Serial.print(SoundSRAM.freq);Serial.print(",");
    Serial.print(SoundSRAM.duration);Serial.print(",");
    Serial.print(SoundSRAM.dly);Serial.println();
    
    tone(tonePin, SoundSRAM.freq, SoundSRAM.duration);
    delay(SoundSRAM.dly);
  }
}

void loop()
{
  midi();delay(5000);
}

Мелодия тут полностью. На меге168:

Скетч использует 4694 байт (32%) памяти устройства. Всего доступно 14336 байт.
Глобальные переменные используют 215 байт (20%) динамической памяти, оставляя 809 байт для локальных переменных. Максимум: 1024 байт.
leks
Offline
Зарегистрирован: 22.10.2017

Ух ты! Заработала! Спасибо. Это массив из временной памяти ушёл в "постоянную"? Такое возможно если элементы массива при исполнении скетча не меняются?

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Массив из ROM не переходил в RAM. 

b707
Offline
Зарегистрирован: 26.05.2017

конечно, такое надо сразу класть в ПРОГМЕМ.

Но интересно, почему все-таки первый скетч не работал - вроде получается структура порядка 650 байт, ну еще сотня на локальные переменные - а на 168-й Атмеге целый килобайт памяти

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

"50 % становится критичным" наводит на мысль, что массив, который, как известно, в первом варианте копируется в стек при каждом вызове, также хранится в оперативной памяти. Т.е. до начала работы программы из ПРОГМЕМ копируется в ОЗУ, а потом при вызове еще и из основного объема ОЗУ в стек.

Тут недавно поднималась тема про то, как компилятор обходится с массивами констант, описанных внутри функции. Там, правда, была проблема с призводительностью в прерывании, но с точки зрения "как обмануть компилятор" тема интересна.

PRC
Онлайн
Зарегистрирован: 03.02.2019

Для эксперимента стоило вынести массив из функции и сделать его не константным. Тогда он должен будет передаваться по ссылке и копирования не будет.

leks
Offline
Зарегистрирован: 22.10.2017

PRC пишет:

Для эксперимента стоило вынести массив из функции и сделать его не константным. Тогда он должен будет передаваться по ссылке и копирования не будет.

// НОВОГОДНЯЯ МЕЛОДИЯ
int tonePin = 7; 
int minus = 6;
const struct { 
    int freq, duration, dly; 
  } sounds[] = {
    {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750}, 
    {293, 225, 250}, {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, 
    {329, 450, 750}, {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250}, 
    {440, 225, 250}, {587, 450, 750}, {587, 225, 250}, {659, 225, 250}, {587, 225, 250}, 
    {523, 225, 250}, {440, 225, 250}, {493, 675, 750}, {293, 225, 250}, {293, 225, 250}, 
    {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750}, {293, 225, 250}, 
    {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {329, 450, 750}, 
    {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250}, {440, 225, 250}, 
    {587, 225, 250}, {587, 225, 250}, {587, 225, 250}, {587, 225, 250}, {659, 225, 250}, 
    {587, 225, 250}, {523, 225, 250}, {440, 225, 250}, {391, 450, 500}, {587, 450, 500}, 
    {493, 225, 250}, {493, 225, 250}, {493, 450, 500}, {493, 225, 250}, {493, 225, 250}, 
    {493, 450, 500}, {493, 225, 250}, {587, 225, 250}, {391, 337, 375}, {440, 112, 125}, 
    {493, 450, 1000}, {523, 225, 250}, {523, 225, 250}, {523, 337, 375}, {523, 112, 125}, 
    {523, 225, 250}, {493, 225, 250}, {493, 225, 250}, {493, 112, 125}, {493, 112, 125}, 
    {493, 225, 250}, {440, 225, 250}, {440, 225, 250}, {493, 225, 250}, {440, 450, 500}, 
    {587, 450, 500}, {493, 225, 250}, {493, 225, 250}, {493, 450, 500}, {493, 225, 250}, 
    {493, 225, 250}, {493, 450, 500}, {493, 225, 250}, {587, 225, 250}, {391, 337, 375}, 
    {440, 112, 125}, {493, 450, 1000}, {523, 225, 250}, {523, 225, 250}, {523, 337, 375}, 
    {523, 112, 125}, {523, 225, 250}, {493, 225, 250}, {493, 225, 250}, {493, 112, 125}, 
    {493, 112, 125}, {587, 225, 250}, {587, 225, 250}, {523, 225, 250}, {440, 225, 250}, 
    {391, 675, 750}
  };
void setup()
{
pinMode(tonePin,OUTPUT);
pinMode(minus,OUTPUT);
digitalWrite(minus, LOW);
}


void midi() {
  
  const uint8_t melodieLength = sizeof(sounds) / sizeof(sounds[0]);
  for (uint8_t i = 0; i < melodieLength; i++) {
    tone(tonePin, sounds[i].freq, sounds[i].duration);
    delay(sounds[i].dly);
  }
}

void loop()
{

midi();delay(5000);

}

Вынес, теперь заработало без сбоев.