0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ESP32用のマイコン内蔵RGB LED WS2813Bドライバの製作

Last updated at Posted at 2020-12-08

ESP32-WROOM-32Dでマイコン内蔵RGB LED WS2813Bを駆動するためにこのプログラムを作りました。ハードウェアタイマ割込みハンドラとして記述していますので、メインの処理を(ほとんど)邪魔することなくLEDをドライブできます。作者はSDカードからwavデータを読み出し再生するプログラムに本LEDドライバを組み込んで動作確認しました。

開発環境はVisual Studio Code + PlatformIOです。
RGB_LEDで定義している定数値がGPIOピン番号(任意)です。
CPUクロックについては、board_build.f_cpu = 240000000L に最適化してありますのでCPUクロック80MHzなどの場合は、LED_WAITの定義値を小さくしてみてください。

main.cpp
# define RGB_LED     (27)

const unsigned int ledMask[24] = {
  0b000000000000000000000001,
  0b000000000000000000000010,
  0b000000000000000000000100,
  0b000000000000000000001000,
  0b000000000000000000010000,
  0b000000000000000000100000,
  0b000000000000000001000000,
  0b000000000000000010000000,
  0b000000000000000100000000,
  0b000000000000001000000000,
  0b000000000000010000000000,
  0b000000000000100000000000,
  0b000000000001000000000000,
  0b000000000010000000000000,
  0b000000000100000000000000,
  0b000000001000000000000000,
  0b000000010000000000000000,
  0b000000100000000000000000,
  0b000001000000000000000000,
  0b000010000000000000000000,
  0b000100000000000000000000,
  0b001000000000000000000000,
  0b010000000000000000000000,
  0b100000000000000000000000,
};

// cnt == 1 : 0.08us @ 240MHz
void ledWait(unsigned int cnt) {
  volatile int timeWaster;
  for(int i = 0; i < cnt; i++) {
    timeWaster += i;
  }
}

# define LED_WAIT  (5)
// data sender for WS2813B
void IRAM_ATTR send24bits(unsigned int dat) {
  // reset
  //digitalWrite(RGB_LED, 0); ledWait(500);
  for(int i = sizeof(ledMask) / sizeof(unsigned int) - 1; i >= 0; i--) {
    if((dat & ledMask[i])) {
      // send '1'
      digitalWrite(RGB_LED, 1); ledWait(LED_WAIT << 2);   // 'H' about 0.8us
      digitalWrite(RGB_LED, 0); ledWait(LED_WAIT);        // 'L' about 0.4us
    } else {
      // send '0'
      digitalWrite(RGB_LED, 1); ledWait(LED_WAIT);
      digitalWrite(RGB_LED, 0); ledWait(LED_WAIT << 2);
    }
  }
}

使用例を以下に示します。

main.cpp
hw_timer_t *timerLed = NULL;

const unsigned int ledPattern[] = {
  0b000000000000000011111111,
  0b000000001111111100000000,
  0b111111110000000000000000,
};

void IRAM_ATTR ledOut() {
  static int idx = 0;
  send24bits(ledPattern[idx]);
  ++idx %= 3;
}

void setup(void) {
  pinMode(RGB_LED, OUTPUT);

  timerLed = timerBegin(2, 16, true);
  timerAttachInterrupt(timerLed, ledOut, true);
  timerAlarmWrite(timerLed, 300000, true);
  timerAlarmEnable(timerLed);
}

void loop() {

}
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?