ArduinoでPWM制御
前回の記事で正弦波を作ったので、
それを使って、PWM制御でLEDを点滅させてみる。
use v5.14; use strict; use warnings; use Math::Trig qw( pi ); use constant PI => pi(); sub wav_sin { my $n = 256; return map { my $tmp = sin( ($_ / $n) * (2.0 * PI) ); if ( $tmp < .0 ) { int( ($tmp * (128.0 / 1.125)) - .5 ); } else { int( ($tmp * (128.0 / 1.125)) + .5 ); } } 0..($n - 1); } while ( <DATA> ) { if ( /{{wav_sin}}/ ) { my @wav = wav_sin(); while ( @wav ) { my $tmp = join( ' ', map { sprintf('%4d,', $_) } splice(@wav, 0, 8) ); chop $tmp if ( not @wav ); print ' ', $tmp, "\n"; } } else { print $_; } } __DATA__ // sin wave // +128.0 / 1.125 〜 -128.0 / 1.125 const static signed char wavSine[] = { {{wav_sin}} }; byte timer = 0; byte max = 0; byte i = 0; ISR ( TIMER0_COMPA_vect ) { if ( timer == 0 ) { short tmp = wavSine[ i & 0xFF ]; max = (byte)(tmp + 128); i++; } digitalWrite( 13, (timer < max) ? HIGH : LOW ); timer++; } void setup() { pinMode( 13, OUTPUT ); digitalWrite( 13, LOW ); TCCR0A = 0b00000010; // CTC TCCR0B = 0b00000010; // 1/8 OCR0A = 130; TIMSK0 = 0b00000010; sei(); } void loop() { // nop }
これを実行すると、こうなる。
// sin wave // +128.0 / 1.125 〜 -128.0 / 1.125 const static signed char wavSine[] = { 0, 3, 6, 8, 11, 14, 17, 19, 22, 25, 28, 30, 33, 36, 38, 41, 44, 46, 49, 51, 54, 56, 58, 61, 63, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 91, 93, 95, 96, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 110, 111, 112, 112, 113, 113, 113, 113, 114, 114, 114, 114, 114, 113, 113, 113, 113, 112, 112, 111, 110, 110, 109, 108, 107, 106, 105, 104, 103, 102, 100, 99, 98, 96, 95, 93, 91, 90, 88, 86, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66, 63, 61, 58, 56, 54, 51, 49, 46, 44, 41, 38, 36, 33, 30, 28, 25, 22, 19, 17, 14, 11, 8, 6, 3, 0, -3, -6, -8, -11, -14, -17, -19, -22, -25, -28, -30, -33, -36, -38, -41, -44, -46, -49, -51, -54, -56, -58, -61, -63, -66, -68, -70, -72, -74, -76, -78, -80, -82, -84, -86, -88, -90, -91, -93, -95, -96, -98, -99, -100, -102, -103, -104, -105, -106, -107, -108, -109, -110, -110, -111, -112, -112, -113, -113, -113, -113, -114, -114, -114, -114, -114, -113, -113, -113, -113, -112, -112, -111, -110, -110, -109, -108, -107, -106, -105, -104, -103, -102, -100, -99, -98, -96, -95, -93, -91, -90, -88, -86, -84, -82, -80, -78, -76, -74, -72, -70, -68, -66, -63, -61, -58, -56, -54, -51, -49, -46, -44, -41, -38, -36, -33, -30, -28, -25, -22, -19, -17, -14, -11, -8, -6, -3 }; byte timer = 0; byte max = 0; byte i = 0; ISR ( TIMER0_COMPA_vect ) { if ( timer == 0 ) { short tmp = wavSine[ i & 0xFF ]; max = (byte)(tmp + 128); i++; } digitalWrite( 13, (timer < max) ? HIGH : LOW ); timer++; } void setup() { pinMode( 13, OUTPUT ); digitalWrite( 13, LOW ); TCCR0A = 0b00000010; // CTC TCCR0B = 0b00000010; // 1/8 OCR0A = 130; TIMSK0 = 0b00000010; sei(); } void loop() { // nop }
でもって、これをArduinoに書き込むと、
PCがスリープしてるときのアレっぽい点滅をする。
(43行目のマスク処理は、ここを0x7F
とかにして試してた時のなごり。)
あと、Arduino IDEで書き込もうとしたら、
初めてMacが固まって、フリーズ画面になって、再起動したんだけど
フリーズなんて数年ぶりでビビった。
おしまい。
Leave a Comment