Необъяснимая работа программы

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

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

Вот вариант скетча на 4 эффекта-генерации:

Спойлер
/////////////////////////////////////
// примеры для ws2812b
//Arduino UNO

#include "Adafruit_NeoPixel.h"

#define line_ 256 //число пикселей в ленте
uint8_t dataPin = 6;// вывод для подключения
Adafruit_NeoPixel strip = Adafruit_NeoPixel(line_, dataPin , NEO_GRB + NEO_KHZ800); // Создаем переменную strip для управления нашей лентой.

byte M = 2; //мощность свечения


const byte massiv_per3[32][8] PROGMEM = { {204, 187, 195, 180, 68, 51, 75, 60}, //1
  {203, 188, 196, 179, 67, 52, 76, 59}, //2
  {202, 189, 197, 178, 66, 53, 77, 58}, //3
  {205, 186, 194, 181, 69, 50, 74, 61}, //4
  {221, 170, 165, 210, 85, 34, 45, 90}, //5
  {171, 220, 164, 211, 84, 35, 44, 91}, //6
  {172, 219, 163, 212, 83, 36, 43, 92}, //7
  {218, 173, 213, 162, 82, 37, 93, 42}, //8
  {217, 174, 214, 161, 81, 38, 41, 94}, //9
  {190, 201, 198, 177, 65, 54, 57, 78}, //10
  {206, 185, 182, 193, 70, 49, 73, 62}, //11
  {222, 169, 166, 209, 86, 33, 89, 46}, //12
  {238, 153, 150, 225, 102, 17, 105, 30}, //13
  {237, 154, 149, 226, 101, 18, 29, 106}, //14
  {236, 155, 148, 227, 100, 19, 28, 107}, //15
  {235, 156, 147, 228, 99, 20, 27, 108}, //16
  {234, 157, 229, 146, 98, 21, 26, 109}, //17
  {233, 158, 230, 145, 97, 22, 25, 110}, //18
  {232, 159, 231, 144, 96, 23, 24, 111}, //19
  {216, 175, 215, 160, 80, 39, 40, 95}, //20
  {200, 191, 199, 176, 64, 55, 56, 79}, //21
  {184, 207, 183, 192, 48, 71, 72, 63}, //22
  {168, 223, 167, 208, 32, 87, 88, 47}, //23
  {239, 152, 151, 224, 16, 103, 104, 31}, //24
  {255, 136, 135, 240, 119, 0, 15, 120}, //25
  {254, 137, 241, 134, 1, 118, 121, 14}, //26
  {253, 138, 242, 133, 117, 2, 13, 122}, //27
  {252, 139, 243, 132, 116, 3, 12, 123}, //28
  {251, 140, 244, 131, 115, 4, 11, 124}, //29
  {250, 141, 245, 130, 114, 5, 10, 125}, //30
  {249, 142, 246, 129, 113, 6, 9, 126}, //31
  {248, 143, 247, 128, 112, 7, 8, 127} //32
};
byte massiv_kolzo3[32] = {1, 2, 2, 2, 0, 0, 0, 0, 6, 6, 5, 6, 0, 0, 0, 4, 5, 6, 7, 2, 0, 0, 0, 0, 6, 6, 5, 6, 0, 7, 7, 6}; // начальный набор цветов
const byte massiv_per[28][8]PROGMEM = { {248, 247, 128, 112, 7, 8, 127, 143}, //1
  {249, 246, 144, 96, 6, 9, 111, 159}, //2
  {250, 245, 160, 80, 5, 10, 95, 175}, //3
  {251, 244, 176, 64, 4, 11, 79, 191}, //4
  {252, 243, 192, 48, 3, 12, 63, 207}, //5
  {253, 242, 208, 32, 2, 13, 47, 223}, //6
  {254, 241, 224, 16, 1, 14, 31, 239}, //7
  {237, 226, 209, 33, 18, 29, 46, 222}, //8
  {236, 227, 193, 49, 19, 28, 62, 206}, //9
  {235, 228, 177, 65, 20, 27, 78, 190}, //10
  {234, 229, 161, 81, 21, 26, 94, 174}, //11
  {233, 230, 145, 97, 22, 25, 110, 158}, //12
  {232, 231, 129, 113, 23, 24, 126, 142}, //13
  {216, 215, 130, 114, 39, 40, 125, 141}, //14
  {217, 214, 146, 98, 38, 41, 109, 157}, //15
  {218, 213, 162, 82, 37, 42, 93, 173}, //16
  {219, 212, 178, 66, 36, 43, 77, 189}, //17
  {220, 211, 194, 50, 35, 44, 61, 205}, //18
  {203, 196, 179, 67, 52, 59, 76, 188}, //19
  {202, 197, 163, 83, 53, 58, 92, 172}, //20
  {201, 198, 147, 99, 54, 57, 108, 156}, //21
  {200, 199, 131, 115, 55, 56, 124, 140}, //22
  {184, 183, 132, 116, 71, 72, 123, 139}, //23
  {185, 182, 148, 100, 70, 73, 107, 155}, //24
  {186, 181, 164, 84, 69, 74, 91, 171}, //25
  {169, 166, 149, 101, 86, 89, 106, 154}, //26
  {168, 167, 133, 117, 87, 88, 122, 138}, //27
  {152, 151, 134, 118, 103, 104, 121, 137} //28
};
byte massiv_kolzo[28] = {1, 2, 2, 2, 0, 0, 0, 0, 6, 6, 5, 6, 0, 0, 0, 4, 5, 6, 7, 2, 0, 0, 0, 0, 6, 6, 5, 6}; // начальный набор цветов
const byte massiv_per2[4][64]PROGMEM = {{120, 121, 137, 153, 169, 168, 167, 166, 165, 164, 148, 132, 116, 100, 84, 68, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 93, 109, 125, 141, 157, 173, 189, 205, 221, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 208, 192, 176, 160, 144, 128, 112, 96, 80, 64, 48, 32, 16, 0}, //1
  {135, 134, 118, 102, 86, 87, 88, 89, 90, 91, 107, 123, 139, 155, 171, 187, 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, 178, 162, 146, 130, 114, 98, 82, 66, 50, 34, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239, 255}, //2
  {136, 152, 151, 150, 149, 133, 117, 101, 85, 69, 70, 71, 72, 73, 74, 75, 76, 92, 108, 124, 140, 156, 172, 188, 204, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 193, 177, 161, 145, 129, 113, 97, 81, 65, 49, 33, 17, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, //3
  {119, 103, 104, 105, 106, 122, 138, 154, 170, 186, 185, 184, 183, 182, 181, 180, 179, 163, 147, 131, 115, 99, 83, 67, 51, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 62, 78, 94, 110, 126, 142, 158, 174, 190, 206, 222, 238, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240}, //4

};
byte massiv_kolzo2[64] = {0, 0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 5, 5, 5, 5, 7, 7, 7, 7, 0, 0, 0, 0, 6, 6, 6, 6, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 0, 0, 0, 0}; // начальный набор цветов фрагмента
const byte massiv_per1[16][16]PROGMEM = {{207, 199, 71, 79, 251, 243, 115, 123, 184, 176, 48, 56, 140, 132, 4, 12}, //1
  {223, 215, 87, 95, 250, 242, 114, 122, 168, 160, 32, 40, 141, 133, 5, 13}, //2
  {206, 198, 70, 78, 235, 227, 99, 107, 185, 177, 49, 57, 156, 148, 20, 28}, //3
  {205, 197, 69, 77, 219, 211, 83, 91, 186, 178, 50, 58, 172, 164, 36, 44}, //4
  {222, 214, 86, 94, 234, 226, 98, 106, 169, 161, 33, 41, 157, 149, 21, 29}, //5
  {239, 231, 103, 111, 249, 241, 113, 121, 152, 144, 16, 24, 142, 134, 6, 14}, //6
  {255, 248, 119, 127, 247, 240, 112, 120, 136, 128, 0, 8, 143, 135, 7, 15}, //7
  {238, 230, 102, 110, 233, 225, 97, 105, 153, 145, 17, 25, 158, 150, 22, 30}, //8
  {221, 213, 85, 93, 218, 210, 82, 90, 170, 162, 34, 42, 173, 165, 37, 45}, //9
  {204, 196, 68, 76, 203, 195, 67, 75, 187, 179, 51, 59, 188, 180, 52, 60}, //10
  {220, 212, 84, 92, 202, 194, 66, 74, 171, 163, 35, 43, 189, 181, 53, 61}, //11
  {237, 229, 101, 109, 217, 209, 81, 89, 154, 146, 18, 26, 174, 166, 38, 46}, //12
  {254, 246, 118, 126, 232, 224, 96, 104, 137, 129, 1, 9, 159, 151, 23, 31}, //13
  {253, 245, 117, 125, 216, 208, 80, 88, 138, 130, 2, 10, 175, 167, 39, 47}, //14
  {236, 228, 100, 108, 201, 193, 65, 73, 155, 147, 19, 27, 190, 182, 54, 62}, //15
  {252, 244, 116, 124, 200, 192, 64, 72, 139, 131, 3, 11, 191, 183, 55, 63}, //16
};
byte massiv_kolzo1[16] = {2, 2, 2, 2, 0, 0, 0, 0, 6, 6, 5, 6, 0, 0, 0, 0}; // начальный набор цветов
long Y = 0; //
byte FL = 0; //
///RGB
void setup() {
  strip.begin();

}
void loop() {

  if (millis() - Y > 10000) {
    Y = millis();
    FL++;
    if (FL > 3) {
      FL = 0;
    }
  }
  if (FL == 0) {
    fun_1();
  }
  if (FL == 1) {
    fun_2();
  }
  if (FL == 2) {
    fun_3();
  }
  if (FL == 3) {
    fun_4();
  }

}
/////////////////////////////////////
void gruppa3(byte n, byte cv) {
  for (int in = 0; in < 8; in++) {
    strip.setPixelColor(pgm_read_byte(*massiv_per3 + 8 * n + in), (cv % 2)*M, ((cv / 2) % 2)*M , ((cv / 4) % 2)*M );
  }
  //strip.show();
}
/////////////////////////////////////
void kolzo3() {
  byte V = 0;
  for (int in = 0; in < 32; in++) {
    if (in != 0 && in != 31) {
      massiv_kolzo3[in] = massiv_kolzo3[in + 1];
    }
    if (in == 0) {
      V = massiv_kolzo3[in];
      massiv_kolzo3[0] = massiv_kolzo3[1];
    }
    if (in == 31) {
      massiv_kolzo3[in] = V;
    }
  }
}
/////////////////////////////////////
void fun_4() {
  for (int i = 0; i < 32; i++) {
    gruppa3(i, massiv_kolzo3[i]);
  }
  strip.show();
  delay(100);//быстрота смены узора
  kolzo3();
  if (millis() % 5 == 0) {
    massiv_kolzo3[0] = random(0, 8);
  }
  if (millis() % 5 == 1) {
    massiv_kolzo3[0] = 0;
  }
}
/////////////////////////////////////
void gruppa(byte n, byte cv) {
  for (int in = 0; in < 8; in++) {
    strip.setPixelColor(pgm_read_byte(*massiv_per + 8 * n + in), (cv % 2)*M, ((cv / 2) % 2)*M , ((cv / 4) % 2)*M );
  }
  //strip.show();
}
/////////////////////////////////////
void kolzo() {
  byte V = 0;
  for (int in = 0; in < 28; in++) {
    if (in != 0 && in != 27) {
      massiv_kolzo[in] = massiv_kolzo[in + 1];
    }
    if (in == 0) {
      V = massiv_kolzo[in];
      massiv_kolzo[0] = massiv_kolzo[1];
    }
    if (in == 27) {
      massiv_kolzo[in] = V;
    }
  }
}
/////////////////////////////////////
void fun_2() {
  for (int i = 0; i < 28; i++) {
    gruppa(i, massiv_kolzo[i]);
  }
  strip.show();
  delay(200);//быстрота смены узора
  kolzo();
  if (millis() % 5 == 0) {
    massiv_kolzo[0] = random(0, 8);
  }
  if (millis() % 5 == 1) {
    massiv_kolzo[0] = 0;
  }
}
////////////////////////////////////
void gruppa2(byte n, byte cv) {
  for (int in = 0; in < 4; in++) {
    strip.setPixelColor(pgm_read_byte(*massiv_per2 + 64 * in + n), (cv % 2)*M, ((cv / 2) % 2)*M , ((cv / 4) % 2)*M );
  }
  //strip.show();
}
/////////////////////////////////////
void kolzo2() {
  byte V = 0;
  for (int in = 0; in < 64; in++) {
    if (in != 0 && in != 63) {
      massiv_kolzo2[in] = massiv_kolzo2[in + 1];
    }
    if (in == 0) {
      V = massiv_kolzo2[in];
      massiv_kolzo2[0] = massiv_kolzo2[1];
    }
    if (in == 63) {
      massiv_kolzo2[in] = V;
    }
  }
}
/////////////////////////////////////
void fun_1() {
  for (int i = 0; i < 64; i++) {
    gruppa2(i, massiv_kolzo2[i]);
  }
  strip.show();
  delay(75);//быстрота смены узора
  kolzo2();
  if (millis() % 5 == 0) {
    massiv_kolzo2[0] = random(0, 8);
  }
  if (millis() % 5 == 1) {
    massiv_kolzo2[0] = 0;
  }
}
/////////////////////////////////////
void gruppa1(byte n, byte cv) {
  for (int in = 0; in < 16; in++) {
    strip.setPixelColor(pgm_read_byte(*massiv_per1 + 16 * n + in), (cv % 2)*M, ((cv / 2) % 2)*M , ((cv / 4) % 2)*M );
  }
  //strip.show();
}
/////////////////////////////////////
void kolzo1() {
  byte V = 0;
  for (int in = 0; in < 16; in++) {
    if (in != 0 && in != 15) {
      massiv_kolzo1[in] = massiv_kolzo1[in + 1];
    }
    if (in == 0) {
      V = massiv_kolzo1[in];
      massiv_kolzo1[0] = massiv_kolzo1[1];
    }
    if (in == 15) {
      massiv_kolzo1[in] = V;
    }
  }
}
/////////////////////////////////////
void fun_3() {
  for (int i = 0; i < 16; i++) {
    gruppa1(i, massiv_kolzo1[i]);
  }
  strip.show();
  delay(200);//быстрота смены узора
  kolzo1();
  if (millis() % 5 == 0) {
    massiv_kolzo1[0] = random(0, 8);
  }
  if (millis() % 5 == 1) {
    massiv_kolzo1[0] = 0;
  }
}
//////////////////////////////////////

может просто резервировать надо ? ну что бы предупреждали…)))

String inputString = "";         // Строка для хранения 256 принятых символов
String byteString = "";          // Строка для хранения байтов символа
bool stringComplete = false;     // Флаг завершения приема
int counter = 0;                 // Счетчик


void setup() {
Serial.begin(9600);           // Инициализация последовательного порта
inputString.reserve(256);     // Резервируем память для 256 символов
byteString.reserve(8);        // Резервируем память для 8 бит
}

Резервировать надо тогда уж явно на этапе компиляции в виде массива, например.

Что резервировать?

///////////// шкала по мотивам круговой подвижной
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);

int t=20;// пауза между считываниями потенциометра
float a=0.00;//
int dlina_1=95;
int dlina_2=85;
int dlina_3=65;

int N=12;// количество рисуемых на шкале чисел
extern uint8_t MediumNumbers[];
void setup()
{
 myOLED.begin();
 myOLED.invert(0);//инверсия цвета
 myOLED.setFont( MediumNumbers); 
}

void loop()
{
myOLED.clrScr(); // очищаем дисплей 

a=PI*map(analogRead(A0), 0,1023, 0, 192)/96;//считывание данных с потенциометра
//////
for(float i=a+PI/24;i<=2*PI+a+PI/24;i=i+PI/18){// рисуем штрихи-риски по кругу
myOLED.drawLine( 63+cos(i)*dlina_3, 100+sin(i)*dlina_3, 63+cos(i)*dlina_1, 100+sin(i)*dlina_1);//
}
//////
int n=N+1;
for(float i=a-PI/2;i<=3*PI/2+a;i=i+2*PI/N){// рисуем числа по рискам-штрихам поверх
n=n-1;
if(n<N){myOLED.printNumI(n,63+cos(i)*dlina_2 ,100+sin(i)*dlina_2 );}
}
//////
myOLED.drawCircle(63, 25, 24); //окружность - прицел рисуем
myOLED.drawCircle(63, 25, 23);

myOLED.update(); delay(t); 
}

Вот библиотека нормальная. Сразу написано 51 процент динамической памяти занят. Откуда? Буфер экрана…и сразу это не забывается :slight_smile:

что за напасть такая на форуме второй день, секунды с миллисекундами путают и тут

1 лайк

Для проверки, иногда просто “подкинуть” код на “Мегу”(если есть конечно))).

А зачем? На Меге покажет настоящий объём занятой оперативной памяти?
… Почему у одного автора библиотека корректная, а у других нет?
…Мегу никогда не хотел и нет потому.

Ели на Нано не работает, а на Меге работает - скорее дело в памяти.
Примитивный тест.

Вша библиотека (<Adafruit_NeoPixel.h>) тоже вполне себе умеет сообщать о проблемах, просто кто б её сообщения ещё слушал. Ну, вот что Вам мешало в самом начале программы, прямо в setup, поставить проверку (средствами самой библиотеки) всё ли там у неё в порядке? Лень? Ну, вот и получите. Поставили бы – сэкономили бы кучу времени и нервов.

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

1 лайк

С другой стороны, может теперь запомню уже :slight_smile:

1 лайк

Знаете хоть как проверять?

Нет конечно.

Прямо у себя в setup (ещё до strip.begin()) можете написать

if (! strip.getPixels()) {
    Serial.println("Хреново!");
    while(true);
}
3 лайка

Всё равно мне непонятно, почему данные по буферу пикселей не выносятся в итоги компиляции? Как только автор скетча указал число пикселей так сразу известен размер используемой памяти.

Буфер статический или динамический?

Параметр указывающий размер - это параметр функции (конструктора). Если сможете в синтаксисе c/c++ проинициализировать статический массив опираясь на значение параметра функции, я у вас поучусь.

С шаблонами может быть иначе.

В вашем коде размер ленты передается в создаваемый обьект не на этапе компиляции, а во время выполнения, при инициализации глобальных переменных.

Возможно компилятор в if не верно компилит код, где нет else. Тут даже scanf не чисто работает.

Почитал тут :slight_smile: Ещё больше запутался.

По моему пониманию:
статический - размер фиксирован и известен, элементы не меняются.
динамический - размер известен, фиксирован - элементы меняются поочерёдно-поштучно (зачем какой то дубликат?, с уничтожением исходника. )
наверное возможен динамический с открытым-переменным размером в заданных границах.
… с многомерными понятно уже давно, они одномерные.

Или в языке нельзя указать размер массива тыкая в переменную, даже зная, что её значение будет однозначно задано?