SFC デザイン言語WS(電子工作)第6回「PCとの連携・音」
-
Upload
makoto-hirahara -
Category
Technology
-
view
308 -
download
6
Transcript of SFC デザイン言語WS(電子工作)第6回「PCとの連携・音」
2
今日の内容
• Processingと連携する。
• Unity 3Dと連携する。
• Ethernetにつなぐ
• tone関数
• PCM Audio Library
• WaveShield
• コンデンサマイク
4
Processing
http://processing.org/
Processing(プロセッシング)は、
Javaをベースに描画機能に特化した開
発環境。
開発者のCasey Reas と Benjamin Fry
はMITメディアラボ ジョン前田の元で
学び、Design By Numbers から着想
を得た。
6
Firmata
Firmata(フェルマータ)はSerial通信の汎用的なプロトコル。
Arduinoにファームウェアを入れておけば、Processingをはじめ
openFrameworksやPureDataなどから値を読み取ったり出力ができる。
FirmataFarmWare
Processing openFrameworksPd Unity3D
7
Firmata
Arduinoでピンの状態を調べるのと同じように、Processingから情報を取得で
きる。
pinMode( 0, INPUT );
digitalRead( 0 )
analogRead( 0 )
arduino.pinMode( 0, Arduino.INPUT );
arduino.digalRead( 0 )
arduino.analogRead( 0 )
12
ライブラリ
http://playground.arduino.cc/interfacing/processing
下記のサイトから、
ProcessingでArduinoを使うための
ライブラリをダウンロード。
13
ライブラリのインストール
ダウンロードしたファイルを解凍して、以下のフォルダにコピー
Mac
書類\Processing\libraries
Win
C:\Documents and Settings\ *** \My Documents\Processing\libraries
14
サンプルスケッチ
Processingを再起動。
[ファイル]-[Examples]を選択。
Java Examplesというウィンドウが開
く。
[Contributed Libraries]-[Arduino]-
[arduino_input]を選択。
18
インプットサンプルスケッチ
import processing.serial.*;
import cc.arduino.*;
Arduino arduino;
color off = color(4, 79, 111);
color on = color(84, 145, 158);
シリアル通信のライブラリと
Arduinoライブラリを読み込む。
Arduinoにアクセスするための
オブジェクトを宣言。
19
インプットサンプルスケッチ
void setup() {
size(470, 280);
println(Arduino.list());
// arduino = new Arduino(this, Arduino.list()[0], 57600);
arduino = new Arduino(this, "/dev/tty.usbmodem1411", 57600);
for (int i = 0; i <= 13; i++)
arduino.pinMode(i, Arduino.INPUT);
}
Arduinoにアクセスするためのオブジェクト
を生成。デバイス名と通信速度を設定。
arduinoオブジェクトの
pinModeメソッドを実行。指
定したピンを入力に使うか、出
力に使うかを設定する。
20
インプットサンプルスケッチvoid draw() {
background(off);
stroke(on);
for (int i = 0; i <= 13; i++) {
if (arduino.digitalRead(i) == Arduino.HIGH)
fill(on);
else
fill(off);
rect(420 - i * 30, 30, 20, 20);
}
noFill();
for (int i = 0; i <= 5; i++) {
ellipse(280 + i * 30, 240, arduino.analogRead(i) / 16, arduino.analogRead(i) / 16);
}
}
Arduinoの中でプログラムする時と同
じように、digitalReadでそれぞれの
ピンにアクセスできる。
analogReadも使える。
21
アウトプットサンプルスケッチ
[Contributed Libraries]-[Arduino]-[arduino_output]を実行。
ウィンドウの矩形をクリックすると、LEDが点灯する。
13 011
22
アウトプットサンプルスケッチvoid mousePressed()
{
int pin = (450 - mouseX) / 30;
// Toggle the pin corresponding to the clicked square.
if (values[pin] == Arduino.LOW) {
arduino.digitalWrite(pin, Arduino.HIGH);
values[pin] = Arduino.HIGH;
} else {
arduino.digitalWrite(pin, Arduino.LOW);
values[pin] = Arduino.LOW;
}
}
digitalWriteで、ピンのHigh,Lowを
コントロールできる。
24
PWMサンプルスケッチ
void draw() {
background(constrain(mouseX / 2, 0, 255));
arduino.analogWrite(9, constrain(mouseX / 2, 0, 255));
arduino.analogWrite(11, constrain(255 - mouseX / 2, 0, 255));
}
analogWriteで、256段階の出力をコントロールできる。
27
サンプルスケッチimport processing.serial.*;
import cc.arduino.*;
Arduino arduino;
…
void setup() {
arduino = new Arduino(this, Arduino.list()[5], 57600);
…
}
void draw () {
ps.setEmitter(arduino.analogRead(0),mouseY);
…
}
シリアル通信のライブラリとArduinoライブラリを取り込む。
Arduinoにアクセスするためのオブジェクトを宣言。
Arduinoにアクセスするためのオブジェク
トを生成。デバイス名と通信速度を設定。
必要な箇所で、Arduinoオブジェクトにアクセスして使う使う。
29
Unity3D
Unity3DはUnity Technologies社が提
供しているゲームエンジン。
クロスプラットフォーム、物理エンジ
ン、アニメーションなど高度な機能を
備えながら安価(機能を限定したバー
ジョンは無料)に利用できる事から、
企業・個人共に利用が広がっている。 http://japan.unity3d.com/
30
UNIDUINO
Unity3DとArduinoを連動するプラグイ
ン。Asset Storeで販売している。
Asset Storeとは
3Dモデル、シェーダー、エフェクトな
ど、Unityで使える素材を販売している
マーケット。http://u3d.as/4oP
32
インストール
下記のページにアクセス
https://www.assetstore.unity3d.com/jp/#!/
content/6804
Buyボタンをクリックして、アカウン
ト、クレジットカード情報を入力。
33
サンプル
ダウンロードが終わったら、新規プロ
ジェクトを作ってから、インポート。
Projectパネル
Asset/Uniduino/UniduinoTestPanel/
UniduinoTestPanel を読み込む。
34
サンプル
初回のみシリアルポートを利用するプ
ラグインのインストールが必要。
終わったらUnity3Dを再起動し、
UniduinoTestPanelを読み込み直す。
デジタル0~13, アナログ0~5 の状態
が確認できる。
35
サンプル2
Projectパネル
Asset/Uniduino/Tutorials/
Analog Read/AnalogRead を読み込む。
可変抵抗の操作で、3Dオブジェクトを回転
できる。
44
Ethernet Shield
ArduinoをLANにつなぐためのシール
ド。
TCPやUDP,HTTPなどのプロトコルで
通信することができる。
https://www.switch-science.com/catalog/2270/
47
サンプルスケッチ#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
char ReplyBuffer[] = "acknowledged";
EthernetUDP Udp;
ライブラリの読み込み
48
サンプルスケッチ#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
char ReplyBuffer[] = "acknowledged";
EthernetUDP Udp;
このEtherShieldのMACアドレス, IPアドレ
ス, ポート番号を指定。
49
サンプルスケッチ#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
char ReplyBuffer[] = "acknowledged";
EthernetUDP Udp;
受信したUDPメッセージを入れるバッファ。
返信するメッセージ
UDP通信するオブジェクトを宣言
50
サンプルスケッチ
void setup() {
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
}
最初に設定したMACアドレスと
IPアドレスで通信開始
51
サンプルスケッチvoid loop() {
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
UDPの受信サイズを確認。
何かデータを受け取っていれば、処理を進める
UDPの送り主のIPアドレスを取得
52
サンプルスケッチvoid loop() {
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
UDPの送り主のIPアドレスを10進数でSerialに出力
53
サンプルスケッチvoid loop() {
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
UDPの受信内容を読み込み
UDPの送り主のIPアドレス、
ポート番号に向けて、パケッ
トを用意。
54
サンプルスケッチvoid loop() {
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
先ほど用意した返信用メッセー
ジ “acknowledged”を送信。
56
発音デバイスの種類
ブザー
発振回路が内蔵されていて、電源を入
れるだけで特定の高さの音が鳴る。
http://akizukidenshi.com/
catalog/g/gP-04572/
http://akizukidenshi.com/
catalog/g/gP-00160/
圧電スピーカー
高音のビープ音の再生に向く。
サンプリングした音には向かない。
http://akizukidenshi.com/
catalog/g/gP-04120/
http://akizukidenshi.com/
catalog/g/gP-01251/
57
発音デバイスの種類
8Ωスピーカー
広い音域、大きな音量を鳴らせる。外形が大きいほど、音量も大きい。
8Ω 0.5W http://www.sengoku.co.jp/mod/
sgk_cart/detail.php?code=5A4R-
N8H5
8Ω 1W http://www.sengoku.co.jp/mod/
sgk_cart/detail.php?code=5A4R-
N8H5
http://akizukidenshi.com/catalog/c/cspk/秋月のスピーカー
59
音がなる仕組み
可聴域の周波数(20Hzから2万Hz(20kHz))でスピーカーをon/offすると、振
動板が空気を振るわせ、音として聞こえる。
void loop() {
digitalWrite(13, HIGH);
delay(5);
digitalWrite(13, LOW);
delay(5);
}
0.01秒周期でHigh/Lowが繰り返される。
周波数100Hz
62
tone関数
tone( ピン番号, 周波数, 継続時間 );
アウトプットピンから指定した周波数のパルスを出す事ができる。
例:
tone( 13, 440, 1000 );
13番ピンに圧電スピーカーをつなぐと440Hzの音が1秒間鳴る。
tone( 13, NOTE_A4, 1200 );
あらかじめ定義しておけば、音階で指定する事もできる。
65
サンプルスケッチ#include "pitches.h"
int melody[] = { NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
int noteDurations[] = { 4, 8, 8, 4,4,4,4,4 };
void setup() {
for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000/noteDurations[thisNote];
tone(8, melody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(8);
}
}
音階と周波数の定義ファイルを読み込む。
スケッチファイル(.ino)と同じフォルダに入れる。
66
サンプルスケッチ#include "pitches.h"
int melody[] = { NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
int noteDurations[] = { 4, 8, 8, 4,4,4,4,4 };
void setup() {
for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000/noteDurations[thisNote];
tone(8, melody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(8);
}
}
メロディーのデータ
音の長さのデータ
67
サンプルスケッチ#include "pitches.h"
int melody[] = { NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
int noteDurations[] = { 4, 8, 8, 4,4,4,4,4 };
void setup() {
for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000/noteDurations[thisNote];
tone(8, melody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(8);
}
}
メロディの個数分、繰り返す。
68
サンプルスケッチ#include "pitches.h"
int melody[] = { NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
int noteDurations[] = { 4, 8, 8, 4,4,4,4,4 };
void setup() {
for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000/noteDurations[thisNote];
tone(8, melody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(8);
}
}
noteDurationsに登録したデータ
から、音の長さを計算。
noteDurations[0] = 4
1000/4 = 250ms
melodyに登録した音階を、計算した長さ
で鳴らす。
melody[0] -> NOTE_C4 -> 262Hz
69
サンプルスケッチ#include "pitches.h"
int melody[] = { NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
int noteDurations[] = { 4, 8, 8, 4,4,4,4,4 };
void setup() {
for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000/noteDurations[thisNote];
tone(8, melody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(8);
}
}
noteDurationsに登録したデータ
から、音の長さを計算。
noteDurations[0] = 4
1000/4 = 250ms
音が鳴り終わるまで処理を止める。
71
PCM Audio
音楽や録音した音を、文字列に変換
し、Arduinoに書き込んで再生する。
圧電スピーカーでは、音が割れて聞
き取りにくいので、8Ωのスピーカー
を使う。
http://playground.arduino.cc/Code/PCMAudio
8-bit, 8000 Hz audio playback on a PC speaker.
72
再生時間
Arduinoのプログラム領域に書き込むため、合計で最大3秒程度。
Arduinoに書き込みをした時に表示される最大容量が上限。
Uno R3の場合32kB。
Arduino Due の場合、
512kB ≒ 50秒
76
サンプルスケッチ(PCM.ino)
#include "PCMData.h"
int ledPin = 13;
int speakerPin = 11;
// Can be either 3 or 11, two PWM outputs connected to Timer 2
volatile uint16_t sample;
byte lastSample;
音声データを読み込む
スピーカーを繋ぐPINを選択。
内臓ハードを使うため3Pinまたは 11Pinのみ。
77
サンプルスケッチ
void stopPlayback(){ ~ }
ISR(TIMER1_COMPA_vect) { ~ }
void startPlayback() { ~ }
停止する関数
8000Hzで呼び出される処理。
サンプリングデータを一つずつ
とり出す。
再生する関数
78
サンプルスケッチ
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
startPlayback();
}
void loop()
{
while (true);
}
再生開始
何もせずにくりかえす。
79
録音した音声を変換する
1.波形編集ソフト「Audacity」で音声データを作成。
Audacity : http://audacity.sourceforge.net/download/
2.Processingのスケッチ「PCMDataConverter」でヘッダファイルに変換。
PCMDataConverter : 授業ページよりダウンロード
3.Arduinoに書き込み
86
録音した音声を変換する
7.
PCMDataConverter.pde を
Processingで実行。
音声データをテキストデータに変換す
る。
Macではフォルダ名に日本語が含まれ
ていると正しく実行できない。
88
増幅回路
オーディオアンプICを使って信号を増幅する。
LM386
http://akizukidenshi.com/catalog/
g/gI-01295/
91
コンデンサ
一時的に電気を溜める部品。ノイズを吸収したり、信号を取り出したり、様々
な用途がある。
容量 電気を溜められる量。単位はF(ファラッド)
耐圧 耐えられる電圧。
電解コンデンサ 積層セラミックコンデンサ
足が長い方が
プラス
白いラインの
方がマイナス極性無し
92
部品表
オーディオアンプIC LM386http://akizukidenshi.com/catalog/g/gI-01295/
ダイナミックスピーカー 8Ω56mmΦhttp://akizukidenshi.com/catalog/g/gP-05411/
電解コンデンサー220μF25V85℃(ルビコンPK)http://akizukidenshi.com/catalog/g/gP-03179/
積層セラミックコンデンサー 0.047μF50Vhttp://akizukidenshi.com/catalog/g/gP-05250/
カーボン抵抗(炭素皮膜抵抗) 1/4W10Ω (100本入)http://akizukidenshi.com/catalog/g/gR-25100/
可変抵抗 10kΩ
93
2つの音を交互に再生すサンプル
1:サンプルをダウンロード(PCM_multi)
2:展開してできたファイル(PCM_multi.ino)をArduinoに書き込む。
3:13番ピンに繋いだスイッチを押す度に、「わん」と「にゃー」と鳴く。
http://youtu.be/bT3n2EWlEJk
95
Wave Shield
SDカードに保存した.wavファイル
を再生できるシールド。
https://learn.adafruit.com/adafruit-wave-shield-
audio-shield-for-arduino
96
Wave Shield
https://www.switch-science.com/catalog/1139/ http://www.galileo-7.com/?pid=14733131
97
基板の組み立て
パーツと基板の状態で届くので、
公式サイトの[Make it!!]を読んで、
自分でハンダ付けする。
写真付きで詳しく説明されているので、
慎重に作業すれば制作できる。
ICがソケットではなく直づけなので、
方向を間違わないように気をつける。
SDカードスロットはやや細かい。https://learn.adafruit.com/adafruit-wave-shield-
audio-shield-for-arduino/make-it
100
1:音声ファイルの準備
1.
Audacityを起動し、既存の音声ファ
イルを読み込むか、録音する。
メニュー > [エフェクト] > [増幅]
で、音量を調整しておく。
2.
トラックのプルダウンメニューから
[ステレオトラックを分離] を選択。
2つのチャンネルに分割される。
105
1:音声ファイルの準備
7.
[ファイル] - [書き出し] を選択。
Formatを以下の通りに設定する。
WAV (Microsoft)16bit PCM 符号あり
SDカードに保存。
SDカードをWaveShieldのスロットに
入れる。
106
2:ライブラリのインストール
1.
以下からライブラリをダウンロード
https://code.google.com/p/wavehc/downloads/list
107
2:ライブラリのインストール2.
解答したフォルダの WaveHC を
User \ 書類 \ Arduino \ libraries へコピー。
Windowsの場合は、
My Documents \ Arduino \ libraries \
108
2:ライブラリのインストール
1.
Arduinoのソフトを再起動し、
[ファイル] - [スケッチの例]
- [WaveHC] - [daphc] を選択。
Arduinoに書き込む。
ライブラリーが認識されない場合は、環境設
定の「スケッチブックの保存場所」を確認し、
その中にライブラリーを入れる。
110
サンプルスケッチ#include <WaveHC.h>
#include <WaveUtil.h>
SdReader card;
FatVolume vol;
FatReader root;
FatReader file;
WaveHC wave;
#define error(msg) error_P(PSTR(msg))
void setup() {
if (!card.init()) {
error("Card init. failed!");
}
if (!vol.init(card)) {
error("No partition!");
}
if (!root.openRoot(vol)) {
error("Couldn't open dir");
}
playfile(“music.wav” ); }
void loop(){
}
ファイル名を指定して再生。
113
エレクトレット・コンデンサ・マイク (ECM)
音の強弱によって電気を貯める能力が変わるデバイス。
一定の電圧をかけ、充電・放電によって出力電圧が変化する。
端子に極性(+/-)があるので、データシートを確認する。
+-
116
高感度マイクアンプキット
増幅回路があらかじめハンダ付けされていて扱いやすい。
http://akizukidenshi.com/catalog/g/gK-05757/
119
サンプルスケッチ
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0);// 入力を読み取る
sensorValue -= 512;// -512~+511 に整形
sensorValue = abs(sensorValue);// 絶対値に変換
sensorValue = sensorValue/25;// 0~20に変換
for ( int i=0; i<sensorValue; i++ ){
Serial.print("[]");// 改行せず[]を出力
}
Serial.println("");// 改行
delay(5);// ちょっと待つ
}
Mic_Sample
https://youtu.be/qS5IYENyicE
121
インプットとアウトプットを組み合わせる
第7回(5/22)はこれまで紹介した部品を組み合わせて「音を出す物」を作り
ます。授業資料(第5回センサー・第6回駆動部品・第7回PC、音)を参考に、
必要な部品を各自準備してきてください。
・光センサ(Cds)
・振動センサ(ピエゾ素子)
・温度センサー(LM35)
・タッチセンサ(静電容量)
・距離センサ
・タッチポジションセンサ
・感圧センサ
・曲げセンサ
・傾斜スイッチ
・加速度センサ
・カラーセンサ
・人感センサ
・マイク
・LED
・フルカラーLED
・DCモータ
・ソレノイド
・サーボモーター
・SSR
・tone
・PCM
・WaveShield
・Processing
・Unity 3D