UNO R4 ライブラリ使わずにNeoPixel を使ってみる。 [Arduino]
ライブラリ使わずに NeoPixel を使ってみる。
素直にライブラリ使えばいいじゃん、っていう話なんですけど。
83.3nsという100ナノセカンドオーダーでI/Oポートレジスタの操作ができることを利用して、NeoPixelの制御信号を作ってみました。
素直にライブラリ使えばいいじゃん、っていう話なんですけど。
83.3nsという100ナノセカンドオーダーでI/Oポートレジスタの操作ができることを利用して、NeoPixelの制御信号を作ってみました。
// UNO R4 minima NeoPixel test
inline void PH() { R_PORT1->POSR = bit(11); } // D13(UNO R4 minima P111) HIGH (83.3ns)
inline void PL() { R_PORT1->PORR = bit(11); } // D13(UNO R4 minima P111) LOW (83.3ns)
inline void T0() { PH(); PH(); PH(); PH(); PL(); PL(); PL(); PL(); PL(); PL(); PL(); PL(); }
inline void T1() { PH(); PH(); PH(); PH(); T0(); }
#define NUMPIXELS (12)
uint8_t pixels[NUMPIXELS * 3]; // GRBGRBGRB...
void setup() {
R_PORT1->PODR |= bit(11); // D13(UNO R4 minima P111) pinMode OUTPUT
}
void loop() {
for (uint8_t i = 0; i < NUMPIXELS; i++) {
for (uint8_t c = 0; c < 6; c++) {
pixels[ ((NUMPIXELS + i - c) * 3 + 2) % (NUMPIXELS * 3) ] = 31 >> c;
}
neoPixelShow();
delay(100);
}
}
void neoPixelShow() {
for(uint8_t i = 0; i < NUMPIXELS * 3; i++) {
for(uint8_t bm = 0b10000000; bm; bm >>= 1) {
noInterrupts();
if (pixels[i] & bm) T1(); else T0();
interrupts();
}
}
}
UNO R4 digitalWrite と I/Oポートレジスタ [Arduino]
UNO R4 で digitalWrite() の代わりに、I/Oポートレジスタを制御することで高速化できるということは、各所で報告されております。
digitalWriteFast with UNO R4 - UNO R4 _ UNO R4 Minima - Arduino Forum
https://forum.arduino.cc/t/digitalwritefast-with-uno-r4/1145206
digitalWrite() と I/Oポートレジスタの制御でどのくらい時間が違うのかですが、
HIGH, LOW 1000回ループと、HIGH, LOW, HIGH, LOW 1000回ループの差分でfor()ループの影響を除去してHIGH, LOW 1000回分だけとして、これを2で割って、digitalWrite() 1回分にかかる速度を調べてみました。ただ、割り込みなどがあるので、その時々で結構まちまちの値が出ました。
だいたい、
digitalWrite(LED_BUILTIN, HIGH); や
digitalWrite(LED_BUILTIN, LOW);
で 700 ns ちょっと。
R_PORT1->POSR = bit(11); や
R_PORT1->PORR = bit(11);
で 83 ns ちょっと。
UNO R4が48MHzということは、CPU 1cycleあたり、20.8333 nsくらい。
83.333nsだと、4 cyclesに相当するのかな?
ポート操作は速いけど、UNO R4は、「MINIMA」と「WIFI」でも一部ポートが違うので注意。
digitalWriteFast with UNO R4 - UNO R4 _ UNO R4 Minima - Arduino Forum
https://forum.arduino.cc/t/digitalwritefast-with-uno-r4/1145206
digitalWrite() と I/Oポートレジスタの制御でどのくらい時間が違うのかですが、
HIGH, LOW 1000回ループと、HIGH, LOW, HIGH, LOW 1000回ループの差分でfor()ループの影響を除去してHIGH, LOW 1000回分だけとして、これを2で割って、digitalWrite() 1回分にかかる速度を調べてみました。ただ、割り込みなどがあるので、その時々で結構まちまちの値が出ました。
だいたい、
digitalWrite(LED_BUILTIN, HIGH); や
digitalWrite(LED_BUILTIN, LOW);
で 700 ns ちょっと。
R_PORT1->POSR = bit(11); や
R_PORT1->PORR = bit(11);
で 83 ns ちょっと。
UNO R4が48MHzということは、CPU 1cycleあたり、20.8333 nsくらい。
83.333nsだと、4 cyclesに相当するのかな?
ポート操作は速いけど、UNO R4は、「MINIMA」と「WIFI」でも一部ポートが違うので注意。
タグ:Uno R4