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で基板にしました。