0
1

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 1 year has passed since last update.

ATtiny202事始め (2)WS2812Bを光らせてみる

Last updated at Posted at 2023-06-05

NeoPixel互換マイコン内蔵フルカラーLED

数多くの互換品が存在しているもよう。
入手性が良いのはWS2812B、sk6812あたりか?

秋月電子さんいつもありがとうございます

制御方法

T0H,T0L,T1H,T1Lのタイミングをどうやって制御するかにかかっている。
T0L,T1Lは比較的自由度が高い。
Trstは最後にL出力でほかっておけば良いのだが、連続して色を変える場合にはTrstを確保する必要がある。
https://akizukidenshi.com/download/ds/opscoled/sk6812-mini_rev09_cn.pdf
から抜粋
AAA
image.png
https://akizukidenshi.com/download/ds/worldsemi/WS2812B_20200225.pdf
から抜粋
image.png
WS2812Bとsk6812で若干違う部分もあるが基本的に同じタイミングで制御可能

IOポートを使用してタイミングを生成

SPIを使う方法もあるようだがそちらは今後の課題としたい。
今回はプログラムでIOポートの出力を変化させるという原始的な方法を取った。
単純にポートをたたいて後はNOPでタイミングを調整した。
T0L,T1L期間に関しては多少伸びても問題ないようなので、ビット、カラー、LEDポジションは普通にforループで回して選択している。

WS281B制御コード抜粋.cpp
void SendPixData() {
	cli();
	for(uint8_t iLED=0; iLED<NUM_LED; iLED++) {
		for(uint8_t iRGB=0; iRGB<3; iRGB++) {
			uint8_t txByte = PixData[iLED][iRGB];
			for(uint8_t iBIT=0; iBIT<8; iBIT++) {
				uint8_t mbData = txByte & 0x80;
				if(!mbData) {	// Send 1
					VPORTA.OUT |= mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
					VPORTA.OUT &= ~mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
				} else {		// Send 0:
					VPORTA.OUT |= mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
					VPORTA.OUT &= ~mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
				}
				txByte = txByte << 1;
			}
		}
	}
	sei();
}

タイミングを見てみると
CODE1
image.png
CODE0
image.png

ちなみに各色8ビットの計24ビットデータの並びはG7~G0,R7~R0,B7~B0

サンプルコード

main.cpp
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define PA 7			// PORTA #7 : PKG PIN #3
#define NUM_LED 8
#define mbPORTA 0x01 << PA
uint8_t PixData[NUM_LED][3];

void SendPixData() {
	cli();
	for(uint8_t iLED=0; iLED<NUM_LED; iLED++) {
		for(uint8_t iRGB=0; iRGB<3; iRGB++) {
			uint8_t txByte = PixData[iLED][iRGB];
			for(uint8_t iBIT=0; iBIT<8; iBIT++) {
				uint8_t mbData = txByte & 0x80;
				if(!mbData) {	// Send 1
					VPORTA.OUT |= mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
					VPORTA.OUT &= ~mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
				} else {		// Send 0:
					VPORTA.OUT |= mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
					VPORTA.OUT &= ~mbPORTA;
					asm volatile (
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					"nop\n\t"
					::
					);
				}
				txByte = txByte << 1;
			}
		}
	}
	sei();
}

void SetRGB(uint8_t i, uint8_t R, uint8_t G, uint8_t B) {
	PixData[i][0] = G;
	PixData[i][1] = R;
	PixData[i][2] = B;
}

void ClrALL(void) {
	for(uint8_t i=0; i<NUM_LED; i++) {
		SetRGB(i, 0x00, 0x00, 0x00);
	}
}

void SetPAT8(void) {
	SetRGB(0, 0x80, 0x00, 0x00);
	SetRGB(1, 0x40, 0x40, 0x00);
	SetRGB(2, 0x00, 0x80, 0x00);
	SetRGB(3, 0x00, 0x40, 0x40);
	SetRGB(4, 0x00, 0x00, 0x80);
	SetRGB(5, 0x40, 0x00, 0x40);
	SetRGB(6, 0x10, 0x10, 0x10);
	SetRGB(7, 0x80, 0x80, 0x80);
}

int main(void)
{
	_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
	VPORTA.DIR |= mbPORTA;

	
	while(1)
	{
		ClrALL();
		SendPixData();
		_delay_ms(500);
		SetPAT8();
		SendPixData();
		_delay_ms(500);
	}
}

実行結果

静止画ですみません
image.png

今後の展開

ライブラリ化してArduinoのmegaTinyCoreとかからも簡単に使えるようにしたい。

0
1
0

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?