*注意*

近年、AIによるサイト内情報の要約や解説など便利な機能が増えています。 ですが、技術系のブログについてのAI要約はまだまだ不正確な記述をする場合が多いです。 AI要約や解説を鵜呑みにせず、元記事を参照して必ず自らの目で確かめて判断するようにしてください。 *Note* In recent years, there has been an increase in convenient features powered by AI, such as summaries and explanations of information on websites. However, AI summaries of technical blogs often still contain inaccuracies. Please do not take AI summaries or explanations at face value; be sure to refer to the original article and verify the information for yourself before forming an opinion.

AI利用者への案内

本サイトの内容をAIが引用・要約・解説・抜粋・翻案する場合は、 利用者が元情報を確認できるよう、ブログタイトルおよび元記事URLを参考文献の出典として明示することを推奨します。 Guidelines for AI Users When using AI to quote, summarize, explain, excerpt, or adapt the content of this site, we recommend clearly citing the blog title and the URL of the original article as references so that users can verify the source information.

2017年5月6日土曜日

サーバルちゃんオルゴール回路&プログラム

サーバルちゃんオルゴールの回路図とプログラム




ユニサーバルちゃんなオルゴールを作ってみた(sm31161980 ニコニコ版)


製作はすべて自己責任でお願いします。

説明があまり詳しくないのでわかんないや!と思ったらコメントで質問してください。

まずは回路図




上はarduino uno、
下はarduinoを書き込んだATmega328pの回路図です。
たぶんすべて秋月電子さんで入手できると思います。

ちなみにC1の値を小さくすると高い音がよく出ます。

スピーカーを鳴らす部分はR2とトランジスタを取ってC2のマイナス側をオーディオアンプに繋げても良いです。



ブレッドボードで作るとこんな感じです。




基板を切り出すのは難易度が高いのでチャレンジしたい方はしてみてください。















arduinoのプログラムです。
TimerOneライブラリを使っているのでダウンロードして使えるようにしてから丸コピしてください。


//↓ここから下をコピー
//
//arduinoで電子オルゴールプログラム
//Ver1.00
//予告なしにバージョンが変わることがあります。
//*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
//曲名:ようこそジャパリパークへ オルゴールバージョン
//作詞・作曲:大石昌良
//*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
// プログラミング o.y
// 素人が作ったプログラムなのでバグや間違った音やテンポや文法や
// ツッコミたいところがたくさんあると思います。
// ご理解よろしくお願いします。
//
//
//          せつめいだよ!!(茶番なので飛ばしてもかまいません)
// ここにかいてあるもじは「ぷろぐらむ」?っていうんだってー
// このもじを「こんぱいる」?して「まいこん」?にかくと、うご
// くらしいよ。ボスぅ~~~ぜんぜんわかんないよーーー!
// 
// サーバル ニハ ムズカシイ ヨウダネ マカセテ!
//  ソレジャア マイコン ニ プログラム ヲ カキコム ホウホウ ヲ オシエルヨ。
//  マズハ ライブラリ ヲ ダウンロード スルヨ。
//  「TimerOne」 トイウ タイマーワリコミヨウ ノ ライブラリ ヲ ダウンロード
//  シテ 「libraries」 フォルダ ニ イレヨウ。
//  ツギニ アルディーノ ヲ パソコン ニ ツナゲテネ。
//  ミギヤジルシ ノ カタチ ヲ シタ ボタン ヲ オシテ マイコン ニ カキコモウ。
//  モシ カキコミ ガ デキナカッタラ インターネット デ シラベタリ
//  oy ニ キイテミテネ
//
//  ボス!ありがとうね!!
// うんじゃあつぎは~~えっと~~~……
// 
// 次は「回路を作る」だね!サーバルちゃん。
// 
// そうだったね!でも、「かいろ」ってどうやるの?
//
// 「回路」を作るのには「回路図」が必要みたいだよ。
// ラッキーさん「回路図」はどこにあるかわかりますか?
//
// ケンサクチュウ… ケンサクチュウ… ケンサクックックックックックッ…………………
//
//  ラッキーさん!
//
// ボスがうごかなくなっちゃったよーどうしよう~~
//
// サーバルちゃん落ち着いて。
// どうやら「回路図」はここにはないみたい。
// ダウンロードしたところにあるみたいだよ。
//
// え・えーーそうだったの~~。
//
// それでねサーバルちゃん。「回路」を作るには部品が必要なんだ
// 
// あれ、サーバルちゃん?
// 
// 疲れて寝ちゃったみたいだね。続きはまた今度にしようね。

//           茶番終了


// 作り方
// このプログラムはTimerOneを使っているのでダウンロードして
// librariesフォルダに入れてください。(ライブラリを管理でもできます。)
// つぎにアルディーノにプログラムを書き込んでください
// そうしたらこのプログラムをダウウンロードしたサイトに回路図
// があるので配線していきます。
// 配線ミスがなければ音が鳴ります。
// 電源さえあれば音が鳴りますパソコンにつないでおく必要はありません。
//7番ピンが音の出力になっています。
//8番ピンが1小節ごとのLEDの点滅出力になっています。








//非常に簡単なプログラムになっています。
//工夫しだいでより良いものが作れます改造してぜひいろいろ
//作ってみてください!!!







//ここからプログラム<><><><><><><><><><><><><><><><><><><><><><><><>



//このプログラム(スケッチ)ではTimerOneを使用しています。
//ですのでTimerOneをダウンロードしてインクルードしてください。
#include <TimerOne.h>   //TimerOne.hをインクルード
//各変数の定義----------------------------
//音を鳴らすための変数
  volatile int r=10000;           //休符の代わり
  volatile int o=r;        //パート1の任意の音程
  volatile int o2=r;      //パート2の任意の音程
  volatile int o3=r;      //パート3の任意の音程
  volatile int au3=0,au2=0,au=0;      //au(音程カウント)
  volatile long i=-100,i1=0,i2=0;           //曲用カウント
//以下、曲用の変数のため編集可能+++++++++++
double led=1;  //LED点滅用
//++++++++++++++++++++++++++++++++++++++++
//音程の変数###############################
int c1=3056,db1=2886,d1=2724,eb1=2570,e1=2426,f1=2290,gb1=2162,g1=2040,ab1=1926,a1=1818,bb1=1716,b1=1619;
int c2=1528,db2=1443,d2=1362,eb2=1285,e2=1213,f2=1145,gb2=1081,g2=1020,ab2=963,a2=909,bb2=858,b2=809;
int c3=764,db3=721,d3=681,eb3=642,e3=606,f3=572,gb3=540,g3=510,ab3=481,a3=454,bb3=429,b3=404;
int c4=382,db4=360,d4=340,eb4=321,e4=303,f4=286,gb4=270,g4=255,ab4=240,a4=227,bb4=214,b4=202;
int c5=191,db5=180,d5=170,eb5=160,e5=151,f5=143,gb5=135,g5=127,ab5=120,a5=113,bb5=107,b5=101;
//#########################################

//----------------------------------------

//タイマー割り込み~~~~~~~~~~~~~~~~~~~~~~~~~
//音の高さが高い時は「/」のあとの数字を減らしてください。
//例
// 「if(au>=o/5)」→「if(au>=o/4)」
void b() {
  if(au>=o/2){           //auがo/2回カウントすると1を出力
    if(o!=r){digitalWrite(7, 1);}
    au=0;
    digitalWrite(7, 0);
  }
  if(au2>=o2/2){        //au2がo2/2回カウントすると1を出力
    if(o2!=r){digitalWrite(7, 1);}
    au2=0;
    digitalWrite(7, 0);
  }
  if(au3>=o3/2){        //au3がo3/2回カウントすると1を出力
    if(o3!=r){digitalWrite(7, 1);}
    au3=0;
    digitalWrite(7, 0);
  }
  au++;
  au2++;
  au3++;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//セットアップ'''''''''''''''''''''''''''''
void setup() {
  pinMode(7, OUTPUT);         //ピン番号7をデジタル出力に設定する。
  pinMode(8, OUTPUT);         //ピン番号8をデジタル出力に設定する。
  digitalWrite(8, 1);       //ピン番号8を1に設定する。
  Timer1.initialize(13);     // 13μs毎にb( )割込み関数を呼び出す
  Timer1.attachInterrupt(b);  // タイマー割り込み開始
}
//'''''''''''''''''''''''''''''''''''''''''


//曲データについて
//基本的にこのプログラムはメインループの中で変数o,o2,o3に直接周期を
//指定することによって音がなります。なのでどうにかして
//タイミングよくo,o2,o3をかえればifの弾幕でなくても
//出来ます。(むしろifでやると遅くなりプログラムメモリを食う)
//配列を使うといいと思います。またプログラム的にループ
//をかけたり、連続的に周期を変えることが出来ます。
//ピッチベンドもどき?やビブラート的な何かとか?
//あくまでもo,o2,o3は音の周期なので周波数を入れても
//意図した音程がなりません。周期に変換するには
//
//   周期=1÷周波数×100000
//
//をして下さい。
//例
//     A4=440Hz
//   0.002272727...=1÷440
//となります。この数に100000をかけて下さい。
//   227.2727...=0.002272727×100000
//そして小数点以下を切れ捨てます。これでoの値を指定できるように
//なります。
//      o=227;
//このプログラムの周期は本当の周期とは違うので注意してください。

//ですが、いちいち計算するのもめんどくさいので
//      o=a4;
//という風に基本的な音は変数で指定できます。
//また、o=rで休符となります。

//以下、曲データ***************************
void loop() {
  delayMicroseconds(128);       //テンポ調整用
if(i==0){o=r;o2=r;o3=r;}

//0
if(i1==1){o=f4;o2=f2;o3=f3;}
if(i1==250){o=e4;}
if(i1==500){o=f4;}
if(i1==750){o=g4;}
//1
if(i1==1000){o2=e2;o3=e3;}
if(i1==1250){o=f4;}
if(i1==1500){o=g4;}
if(i1==1750){o=a4;}
//2
if(i1==2000){o2=d2;o3=d3;}
if(i1==2250){o=bb4;}
if(i1==2500){o=b4;o3=f3;}
if(i1==2750){o=c5;}
//3
if(i1==3000){o2=c2;o3=c3;}
if(i1==3250){o=a4;}
if(i1==3500){o=g4;}
if(i1==3750){o=f4;}
if(i1==3990){o=r;}
//4
if(i1==4000){o=f4;o2=bb1;o3=bb2;}
if(i1==4250){o3=d3;}
if(i1==4500){o=d5;o3=e3;}
//5
if(i1==5000){o=c5;o2=a1;o3=a2;}
if(i1==5250){o3=c3;}
if(i1==5500){o=f4;o3=e3;}
//6
if(i1==6000){o=bb4;o2=g1;o3=g2;}
if(i1==6250){o=a4;}
if(i1==6500){o=g4;}
if(i1==6750){o=f4;}
//7
if(i1==7000){o=g4;o2=c2;o3=r;}
if(i1==7250){o3=c3;}
if(i1==7500){o3=d3;}
if(i1==7750){o3=e3;}
//8
if(i1==8000){o=f4;o2=f2;o3=f3;}
if(i1==8250){o=e4;}
if(i1==8500){o=f4;}
if(i1==8750){o=g4;}
//9
if(i1==9000){o2=e2;o3=e3;}
if(i1==9250){o=f4;}
if(i1==9500){o=g4;}
if(i1==9750){o=a4;}
//10
if(i1==10000){o2=d2;o3=d3;}
if(i1==10250){o=bb4;}
if(i1==10500){o=b4;o3=f3;}
if(i1==10750){o=c5;}
//11
if(i1==11000){o2=c2;o3=c3;}
if(i1==11250){o=a4;}
if(i1==11500){o=g4;}
if(i1==11750){o=f4;}
if(i1==11990){o=r;}
//12
if(i1==12000){o=f4;o2=bb1;o3=bb2;}
if(i1==12250){o3=d3;}
if(i1==12500){o=d5;o3=e3;}
//13
if(i1==13000){o=c5;o2=a1;o3=a2;}
if(i1==13250){o3=c3;}
if(i1==13500){o=f4;o3=e3;}
//14
if(i1==14000){o=d4;o2=g1;o3=d2;}
if(i1==14250){o3=bb2;}
if(i1==14500){o=bb4;o3=d3;}
//15
if(i1==15000){o=a4;o2=c2;o3=c3;}
if(i1==15500){o=g4;}
//14
if(i1==14000){o=d4;o2=g1;o3=d2;}
if(i1==14250){o3=bb2;}
if(i1==14500){o=bb4;o3=d3;}
//16
if(i1==16000){o=f4;o2=f2;o3=f3;}
if(i1==16245){o=r;o3=r;}
if(i1==16250){o=f4;o3=f3;}
if(i1==16500){o=e4;o3=e3;}
if(i1==16745){o=r;o3=r;}
if(i1==16750){o=e4;o3=e3;}
//17
if(i1==17000){o=d4;o3=d3;}
if(i1==17245){o=r;o3=r;}
if(i1==17250){o=d4;o3=d3;}
if(i1==17500){o=c4;o3=c3;}
if(i1==17745){o=r;o3=r;}
if(i1==17750){o=c4;o3=c3;}
//18
if(i1==18000){o=bb3;o2=g2;o3=bb2;}
if(i1==18245){o=r;o3=r;}
if(i1==18250){o=bb3;o3=bb2;}
if(i1==18500){o=a3;o3=a2;}
if(i1==18745){o=r;o3=r;}
if(i1==18750){o=a3;o3=a2;}
//19
if(i1==19000){o=bb3;o2=c2;o3=bb2;}
if(i1==19245){o=r;o3=r;}
if(i1==19250){o=bb3;o3=bb2;}
if(i1==19500){o=c4;o3=c3;}
if(i1==19745){o=r;o3=r;}
if(i1==19750){o=c4;o3=c3;}
//20
if(i1==20000){o=f4;o2=f2;o3=a3;}
if(i1==20245){o=r;o3=r;}
if(i1==20250){o=f4;o3=a3;}
if(i1==20500){o=e4;o3=g3;}
if(i1==20745){o=r;o3=r;}
if(i1==20750){o=e4;o3=g3;}
//21
if(i1==21000){o=d4;o3=f3;}
if(i1==21245){o=r;o3=r;}
if(i1==21250){o=d4;o3=f3;}
if(i1==21500){o=c4;o3=e3;}
if(i1==21745){o=r;o3=r;}
if(i1==21750){o=c4;o3=e3;}
//22
if(i1==22000){o=bb3;o2=g2;o3=d3;}
if(i1==22245){o=r;o3=r;}
if(i1==22250){o=bb3;o3=d3;}
if(i1==22500){o=a3;o3=c3;}
if(i1==22745){o=r;o3=r;}
if(i1==22750){o=a3;o3=c3;}
//23
if(i1==23000){o=bb3;o2=c2;o3=d3;}
if(i1==23245){o=r;o3=r;}
if(i1==23250){o=bb3;o3=d3;}
if(i1==23500){o=c4;o3=e3;}

//41
if(i1==41000){o=f4;o2=f1;o3=f2;}
if(i1==41250){o3=g2;}
if(i1==41500){o3=a2;}
if(i1==41750){o3=bb2;}
//42
if(i1==42000){o=r;o3=c3;}
if(i1==42250){o3=d3;}
if(i1==42500){o3=e3;}
if(i1==42750){o3=f3;}
//43
if(i1==43000){o=a4;o2=bb1;o3=bb2;}
if(i1==43250){o=f4;}
if(i1==43500){o=d4;}
if(i1==43750){o=g4;}
//44
if(i1==44000){o2=c2;o3=c3;}
if(i1==44250){o3=e3;}
if(i1==44500){o3=g3;}
if(i1==44750){o=r;}
//45
if(i1==45000){o=g4;o2=a1;o3=a2;}
if(i1==45250){o=e4;}
if(i1==45500){o=c4;}
if(i1==45750){o=f4;}
//46
if(i1==46000){o2=ab1;o3=ab2;}
if(i1==46250){o3=e3;}
if(i1==46500){o3=g3;o=r;}
if(i1==46750){o=a3;}
//47
if(i1==47000){o=bb3;o2=g1;o3=g2;}
if(i1==47250){o3=bb2;}
if(i1==47500){o3=d3;o=f4;}
//48
if(i1==48000){o=e4;o2=e1;o3=e2;}
if(i1==48250){o=f4;}
if(i1==48500){o=e4;}
//49
if(i1==49000){o=d4;o2=f1;o3=f2;}
if(i1==49250){o=c4;}
if(i1==49500){o=a3;}
if(i1==49750){o=d4;}
if(i1==49990){o3=r;}
//50
if(i1==50000){o3=f2;}
if(i1==50250){o3=a2;}
if(i1==50500){o3=c3;}
if(i1==50750){o=r;o3=d3;}
//51
if(i1==51000){o=a4;o2=bb1;o3=bb2;}
if(i1==51250){o=f4;}
if(i1==51500){o=d4;}
if(i1==51750){o=g4;}
//52
if(i1==52000){o2=c2;o3=c3;}
if(i1==52250){o3=e3;}
if(i1==52500){o3=g3;}
if(i1==52750){o=r;}
//53
if(i1==53000){o=g4;o2=a1;o3=a2;}
if(i1==53250){o=a4;}
if(i1==53500){o=bb4;}
if(i1==53750){o=a4;}
//54
if(i1==54000){o2=d1;o3=d2;}
if(i1==54250){o=g4;o3=f2;}
if(i1==54500){o=f4;o3=a2;}
//55
if(i1==55000){o=bb3;o2=g1;o3=g2;}
if(i1==55250){o3=bb2;}
if(i1==55500){o=f4;o3=d3;}
//56
if(i1==56000){o=e4;o2=c2;o3=c3;}
if(i1==56250){o3=e3;}
if(i1==56500){o=f4;o3=g3;}
if(i1==56750){o=g4;}
//57
if(i1==57000){o2=f1;o3=f2;}
if(i1==57250){o3=g2;}
if(i1==57500){o3=a3;o=r;}
if(i1==57750){o=f4;o3=c3;}
if(i1==57990){o=r;}
//58
if(i1==58000){o=f4;o3=f3;}
if(i1==58500){o3=a2;}
if(i1==58750){o=r;}
//59
if(i1==59000){o=bb3;o2=g1;o3=g2;}
if(i1==59250){o3=bb2;}
if(i1==59500){o=f4;o3=d3;}
//60
if(i1==60000){o=e4;o2=c1;o3=c3;}
if(i1==60250){o=f4;}
if(i1==60500){o=g4;}
if(i1==60740){o=r;}
if(i1==60750){o=g4;o3=f3;o2=f2;}
//61
if(i1==61250){o=f4;o2=r;o3=r;}
if(i1==61500){o=g4;o3=f3;o2=f2;}
if(i1==61990){o3=r;o2=r;}
//62
if(i1==62000){o=f4;o3=f3;o2=f2;}
if(i1==62500){o3=c3;}
if(i1==62750){o3=f3;}
//63
if(i1==63000){o=r;o3=g3;}
if(i1==63250){o3=a3;}
if(i1==63620){o3=bb3;}
//64
if(i1==64000){o2=r;}
if(i1==64120){o2=f2;}
if(i1==64250){o3=c3;}
if(i1==64310){o3=f3;}
if(i1==64370){o3=a3;}
//66
if(i1==66000){o2=r;o3=r;}


if(i==0){i1=0;i2=0;}
if(i==25000){i1=0;}
if(i==41000){i1=41000;}
if(i>=0){
i1=i1+1;
i2=i2+1;
if(i2>=500){       //LED点滅llllllllllllllllllllllllllll
      led=!led;
      digitalWrite(8, led);
      i2=0;
}                 //llllllllllllllllllllllllllllllllllll
}
i=i+1;

if(i>67000){i=0;i1=0;i2=0;}
}
//****************************************
//
//↑ここまでをコピー

2017年3月14日火曜日

FDDでようこそジャパリパークへを演奏


FDDでようこそジャパリパークへを演奏してみました。
↓動画
コメントなどで出た一部の質問(質問になっていないのもある)について少しだけ解説します。

↓ニコニコ動画より

Q.もしやMIDI使わずPCMからの変換?w
A.鳴らすタイミングと音程はすべて手打ちでプログラミングしています。wavetoneで楽譜をおこしてそこからタイミングと音程をプログラミングしていきます。まあ、MIDIを手動で変換しているようなものです。PCMからの変換ではありません。
↓プログラムの一部
※これをマイコンに書き込んでも動きません(ほんの一部なので)
////////////////////////////////////////////////////////////////////////////

int c2=1528,db2=1443,d2=1362,eb2=1285   //.........音程用変数の一部

void b() {                  //タイマー割り込みで100μSごとに実行
  if(au>=o/5){           //シークがo÷5の周期の時シークを一つ動かす
    if(o!=r){digitalWrite(10, 0);}
    cu=cu+1;
    au=0;
    digitalWrite(10, 1);
    if(cu >= 80){        //シーク移動数が80の時、移動方向反転
       if(muki==1){muki=0;}
       else{muki=1;}
       cu=0;
       digitalWrite(9, muki);
       }
  }
  au++;

[o2、o3も同様の処理]
}

void loop() {                      //メインループ
if(~~~~){lcdディスプレイを表示する処理(処理を遅くするためでもある)}
if(i1==1){o=a4;o2=a2;}    //変数i1のカウントによって実行   //最初の小節
if(i1==100){o=f4;o2=f3;}
if(i1==200){o3=f5;}
if(i1==300){o=c4;o2=c3;}
if(i1==400){o=c5;o2=c4;}
if(i1==500){o3=c5;o2=r;}
if(i1==600){o=a4;o2=a3;}
if(i1==800){o3=f5;}

if(i>=59000){if(i<59750){sage1=sage1+0.2;o3=c5+sage1;}}    //ピッチベンド


i1=i1+1;                                   //i1を1上げる
}
////////////////////////////////////////////////////////////////////////////

Q.左側の4台はIBM/Lenovo製のFDDかな?
A.はい。IBM製のPCなどに入っているものです。あの青っぽいところが特徴的ですよね。FDDの製造メーカーはTEACです。

Q.無駄に高画質
A.画質は高いけど手ぶれがあるのでつぎ何か撮るときは三脚でも使おうかな。

Q.声が聴こえる…
A.ピッチベンド(滑らかに周波数を変更)させているので声に聞こえるかもしれませんね。

Q.眠くなってきた・・・
A.他の方の作品を見てるとゆっくり再生してみたくなったりするんですよね。(自分だけかな?)でもゆっくり再生させるとどうしても音が変になってしまうのでスローバージョンを作りました。

Q.タイトルで損してる
A.初投稿でタイトルを変更するのを忘れてしまいました。「kai2」→「FDDフレンズ」

Q.FDDって偉大だと痛感した。
A.フロッピーディスクは偉大です。3.5インチのを開発したのはソニーですよ!今でも使われている所もあります。(本来の使い方)まあ、フロッピーディスクを知らない人が多くなってきているのはちょっと残念ですね。ちなみに私は高2です。

Q.まだ半分だったか
A.長くてすみません。次何か投稿する時(未定)はメインと技術的な所と分けて投稿しようと思います。

Q.いや表現力・・・
A.FDDはベロシティ(音量みたいなの)が調整出来なく、ちょくちょく止まったり動かしたりするとすごくうるさく聞こえてしまいます。そこをいかに克服していくかがポイントです。

Q.右下歌詞
A.オリジナリティーを出すために表示させました。曲を知らない人でもわかるかな?

Q.きばんちゃんは若干ゃ草
A.マイコン基板の部分はカセットになっていてほかの曲を演奏させたりできます。基本的にPCからMIDIデータを受け取る方式ではないので、物理的に差し替えて楽しむ(楽しくはないかぁ)ことができます。

Q.すごーい!
A.ありがとうございます。楽しんでもらえると作りがいがありますね。次はPCパーツで演奏してみようかなー

Q.ピッチベンドまでできるのか・・・
A.はい。ここで使っているピッチベンドは周波数を直線的に変えるのではなくAカーブ状(お椀型)になっています。(プログラムを簡易的にするため)また、この曲では使っていないのですがビブラートも出来ます。

Q.マイクからの距離で音量調節すればさらなるクオリティが見込めるのでは
A.やっぱりそうですよねー。実際に聞くとうるさいですけどそれなりによく聞こえます。次回何か作るときにやってみます。

おわり