Как хранить массив бит анимации

Нет, по ссылке выше

Упаковка битов в байт | Страница 2 | Амперка / Форум

Можно как-то так, думаю.

const uint8_t frameOnRam[] = {
  0b11010010, 0b00000000, 0b10011000, 0b00000001,
  0b00000011, 0b10000000, 0b00000000, 0b01100000,
  0b00000110, 0b00001100, 0b00000000, 0b00000000,
  0b00000000, 0b00000000, 0b00000000, 0b00000001,
  0b00000000, 0b00000000, 0b00000000, 0b00000001
};

const uint8_t frameOnProgmem[] PROGMEM = {
  0b10000011, 0b01010101, 0b10011000, 0b00000001,
  0b00000011, 0b10000000, 0b00000000, 0b01100000,
  0b00000110, 0b00001100, 0b00000000, 0b00000000,
  0b00000000, 0b00000000, 0b00000000, 0b00000001,
  0b00000000, 0b00000000, 0b00000000, 0b00000001
};

const uint8_t ledQuantity = 20;

class __FlashArrayHelper;
#define FA(array_name) (reinterpret_cast<const __FlashArrayHelper *>(array_name))

// RAM-placed data case
bool getBitOnPosition(uint16_t _position, const uint8_t* _data) {
  // No bounds checking here
  uint16_t offset = _position >> 3;
  uint8_t  bitNo = 7 - (_position - (offset << 3));
  uint8_t  dataByte = _data[offset];
  return ((dataByte >> bitNo) & 0x01);
}

// PROGMEM-placed data case
bool getBitOnPosition(uint16_t _position, const __FlashArrayHelper * _data) {
  uint16_t offset = _position >> 3;
  uint8_t  bitNo = 7 - (_position - (offset << 3));
  uint8_t  dataByte = pgm_read_byte_near(reinterpret_cast<const uint8_t*>(_data) + offset);
  return ((dataByte >> bitNo) & 0x01);
}


void setup() {
  Serial.begin(115200);
  Serial.println(F("Bit array access demo"));

  Serial.println(F("Take frames from RAM"));
  for (uint16_t frameOffset = 0; (sizeof(frameOnRam) * 8) > frameOffset; frameOffset += ledQuantity) {
    for (uint16_t ledNo = 0; ledQuantity > ledNo; ledNo++) {
      bool isLedOn = getBitOnPosition(frameOffset + ledNo, frameOnRam);
      Serial.print(isLedOn); Serial.print(' ');
    }
    Serial.println();
  }

  Serial.println(F("Take frames from PROGMEM"));
  for (uint16_t frameOffset = 0; (sizeof(frameOnProgmem) * 8) > frameOffset; frameOffset += ledQuantity) {
    for (uint16_t ledNo = 0; ledQuantity > ledNo; ledNo++) {
      bool isLedOn = getBitOnPosition(frameOffset + ledNo, FA(frameOnProgmem));
      Serial.print(isLedOn); Serial.print(' ');
    }
    Serial.println();
  }

}

void loop() {}

UPD: поддал оверлоада на PROGMEM

1 лайк

хм…
а почему не
uint8_t bitNo = 7 - (_position & 0x7);

Да в последнюю минуту понял, что надо бы перевернуть вывод, чтобы было по-человечески. Не стал уже там извращаться.

А, вопрос не про это. Такую кракозябру я делал, чтобы понятна была логика. Ну, я так полагаю, что она остаётся понятной: на 8 поделили, на 8 умножили. А там уже пусть иринка оптимизирует, как хочет.

Большое спасибо. Буду разбираться на выходных.

Тема самому интересна, поэтому решил добавить.
В моём примере из #19 описана простая функция, позволяющая записать любой бит в массив uint32_t. При этом биты нумеруются от младшего к старшему.
А в этом примере массив разбит на кадры(по 20 бит), и биты адресуются линейно, по порядку, начиная со старшего бита

Спойлер
uint32_t mass[4] = {0, 0, 0, 0};
#define CADRvolum 20

void write_mass(uint32_t *massiv, byte cadr, byte bitNum, bool Bit)
 {
   uint32_t fullBitNum = cadr * CADRvolum + bitNum;//полный номер бита в массиве
   bitWrite( *((massiv + fullBitNum/32)), 31 - (fullBitNum % 32), Bit);
 }


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

void loop() {
  static uint16_t cadre = 0;//счёт кадров, начиная с 0
  static byte bitNum = 0;// счёт номера бита в кадре, начиная с 0
  bool BITstat;
 
  bitNum % 2 ? BITstat = true : BITstat = false;//определяем чётные и нечётные биты
 
 write_mass(mass, cadre, bitNum, BITstat);//записываем в массив бит № bitNum  
 //в кадре № cadre
 for(byte ii = 0; ii < 4; ii++)
 {
  Serial.print(mass[ii], BIN);
  Serial.print(' ');
 }
 Serial.println();
 bitNum++;
 if(bitNum > CADRvolum - 1)//
 {
  bitNum = 0;
  cadre++;
 }
 if(cadre > 5)
 for(;;);
}
Спойлер

зачем?
К чему тут эти кадры, если биты все равно пишут в массив uint32_t подряд?
Бессмысленный какой-то пример…

Написал п мотивам #1. Видимо так удобнее.