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