Загрузка данных


const byte PIN_CS  = 10;
const byte PIN_CLK = 13;
const byte PIN_DIN = 11;

void sendByte(byte value) {
  for (int bit = 7; bit >= 0; bit--) {
    digitalWrite(PIN_CLK, LOW);
    digitalWrite(PIN_DIN, (value >> bit) & 1);
    digitalWrite(PIN_CLK, HIGH);
  }
}

void writeRegister(byte address, byte value) {
  digitalWrite(PIN_CS, LOW);
  sendByte(address);
  sendByte(value);
  digitalWrite(PIN_CS, HIGH);
}

void drawRing(float radius) {
  // Центр матрицы находится между пикселями: (3.5, 3.5).
  // Пиксель включается, если он близок к окружности заданного радиуса.
  for (byte row = 0; row < 8; row++) {
    byte pixels = 0;

    for (byte column = 0; column < 8; column++) {
      float dx = column - 3.5;
      float dy = row - 3.5;
      float distance = sqrt(dx * dx + dy * dy);

      if (fabs(distance - radius) < 0.45) {
        pixels |= (0x01 << column);
      }
    }

    // Для этой ориентации младший бит соответствует левому столбцу.
    writeRegister(row + 1, pixels);
  }
}

void setup() {
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_CLK, OUTPUT);
  pinMode(PIN_DIN, OUTPUT);

  digitalWrite(PIN_CS, HIGH);
  digitalWrite(PIN_CLK, LOW);

  writeRegister(0x0F, 0x00); // display test off
  writeRegister(0x0C, 0x01); // normal operation
  writeRegister(0x0B, 0x07); // scan all 8 rows
  writeRegister(0x09, 0x00); // no decode
  writeRegister(0x0A, 0x08); // brightness

  drawRing(0.8);
}

void loop() {
  // Кольцо постепенно растёт от центра к краям.
  for (float radius = 0.8; radius <= 4.8; radius += 0.15) {
    drawRing(radius);
    delay(70);
  }

  // Затем плавно уменьшается обратно.
  for (float radius = 4.8; radius >= 0.8; radius -= 0.15) {
    drawRing(radius);
    delay(70);
  }
}