「さ~ボード」プロジェクト(8)ー ATtiny版「さ~ボード2」の製作

ATtinyの準備ができたところでブレッドボードで試作してみます。部品点数が減って結線が楽になりました。

ところが、ファームウェアで新たな問題が発生しました。ATtinyコア用の開発環境を作るためライブラリをインストールしているのですが、もとからあるServoライブラリと競合するようでコンパイルが通らないのです。

やむを得ずServoライブラリを使わず、自前でPWMを生成することにします。以下のサイトを参考にさせて頂きました。
Arduinoでサーボモータをキュイキュイ動かす!


const int MSGEQ7_Reset = 2; // MSGEQ7_Resetピン
const int MSGEQ7_Strobe = 4; // MSGEQ7_Strobeピン
const int MSGEQ7_Out = 3; // MSGEQ7_Outputの入力ピン

const int 0msec = 600; // 0度のときのパルス幅msec
const int 180msec = 2350; // 180度のときのパルス幅 msec
int microSec = 0msec;
int microSec2 = 0msec;
int deg,deg2;

int MSGEQ7_[7];//バンド毎のMSGEQ7の出力値保存用
int val;//アナログ入力値
int angle1,angle2;//サーボ角

byte band = 6;

void setup() {

pinMode(MSGEQ7_Reset, OUTPUT);
pinMode(MSGEQ7_Strobe, OUTPUT);

//MSGEQ7初期化処理
digitalWrite(MSGEQ7_Strobe,LOW);
delay(1);
digitalWrite(MSGEQ7_Reset,HIGH);
delay(1);
digitalWrite(MSGEQ7_Strobe,HIGH);
delay(1);
digitalWrite(MSGEQ7_Strobe,LOW);
delay(1);
digitalWrite(MSGEQ7_Reset,LOW);
delay(5);
}

void loop() {
if (++band == 7) band = 0;//処理するバンドを0~6の間で反復

//データの平滑化(サーボの震え防止)
//入力値を同じバンドの前回の値と平均し、端数を切り捨てる
MSGEQ7_[band] = (analogRead(MSGEQ7_Out)+MSGEQ7_[band])/2;
val=MSGEQ7_[band] /100*100;
MSGEQ7_[band]=val;
//入力値をサーボ角にマッピング。値はテストして試行錯誤的に決める
angle1 =map(val,300, 900, 0, 180);
angle2 =map(val,300, 900, 180, 0);//片側の腕はサーボの向きが反対になるため、角度が反対になる

digitalWrite(MSGEQ7_Strobe,HIGH);
delayMicroseconds(18);
digitalWrite(MSGEQ7_Strobe,LOW);

switch (band){
case 0://MIDI#36 63Hz

break;

case 1://MIDI#52 160Hz

break;

case 2://MIDI#67 400Hz
break;

case 3://MIDI#84 1KHz
break;

case 4://2489
myServo(angle1,0);
break;

case 5://6271
myServo2(angle2,1);
break;

default:
break;
}

}

void myServo(int deg,int pinNo){
if ( deg >= 0 && deg <= 180 )
microSec = 0msec + deg / 180.0 * ( 180msec - 0msec );
if ( microSec >= 0msec ) {
digitalWrite( pinNo, HIGH );
delayMicroseconds( microSec ); // ON
digitalWrite( pinNo, LOW );
delayMicroseconds( 10000 ); // OFF(注1)
delayMicroseconds( 10000 - microSec ); // OFF
}
//パルス周期は50Hzだから20000μS待つ必要があるが、delayMicroseconds関数の仕様で16000μS位しか待てないので、2つに分けて処理する
}
void myServo2(int deg2,int pinNo2){
if ( deg2 >= 0 && deg2 <= 180 )
microSec2 = deg0msec + deg2 / 180.0 * ( deg180msec - deg0msec );
if ( microSec2 >= deg0msec ) {
digitalWrite( pinNo2, HIGH );
delayMicroseconds( microSec2 ); // ON
digitalWrite( pinNo2, LOW );
delayMicroseconds( 10000 ); // OFF
delayMicroseconds( 10000 - microSec ); // OFF
}
}

これもFusionPCBで基板にしました。