コーディング不要のSigmaDSPを試食する
Analog DevicesのドメインスペシフィックDSPの試食
去年末に偶然発見したSigmaDSP
SigmaDSP プロセッサ | DSP&MCU | アナログ・デバイセズ
SigmaDSPにはいくつか世代や種類があるようですが、今回目を付けたのがADAU1701。(同一性能&パッケージで温度のみ車載グレードはADAU1401A)
24bitのAD/DAが入ってるだけで凄いのにDSP入りでコーディングが不要。ついでにポテンショメータなどの用途向けに8bitの補助的ADCもついてる。
SigmaDSP自身はプログラム格納フラッシュを持たずI2C/SPI経由でパラメータやブートプログラムをDSPに流し込む仕組みで、外部マイコンやPC等から書き込みが可能。
一部のデバイスは外部I2C EEPROMからブートすることも可能。最新のADAU1452はSPI EEPROMも使えるみたいですね。
擬似差動入力や、低消費電力、低ノイズ向けデバイスもありますが、すべての機能が搭載されているわけではないのでアプリケーションに応じて選択するのが良いと思います。まず手始めに一通りの機能がそろってるADAU1701/1401Aをつかってその後、アプリケーションに応じてデバイスを選択すると良いと思います。たとえば低ノイズが要求される場面でADAU1781をAD/DA+デジタルフィルタ代わりに使ってADAU1445をI2SでつなげてGPIO拡張や追加の演算をさせると、低ノイズで高速な制御系が要求される場面で役立つのではないかなと思います。
ただ、外部にSDカードをつなげたりUARTでprintfしたりといった「汎用マイコン」としての機能はまったくないので、結局外部にコプロセッサとしてのI2C/SPI通信が可能なマイコンが必要となるかも。*1
GUI開発環境から外部マイコン用にヘッダファイルも生成してくれるので、それをつかってArduinoとかmbedからSigmaDSPをコンフィグするのもいいかもしれない。
また、SigmaDSPのAD変換結果をリードしたり、DA変換器にデータを流し込んだりするのにI2SかTDMインターフェースを持ってるマイコンがあると便利なはず。
最近流行りのドメインスペシフィック開発(特定用途向け限定開発)の流れを汲んでいて、プロパティドリブンとなっている。
たとえば、1kHzの正弦波を出したければ、Toneのアイコンを配置して1000と入力するだけで完成。(Toneのプロパティは周波数)
開発環境をそろえる
- 開発はSigmaStudio。現在はXPとVistaと7のみ対応しているらしい*2。ダウンロードはフリー。
- デバッガはUSBi。USBiの実態はUSB to I2Cマスタのドングルなので、SigmaStudioが生成したhexをSigmaDSPに流し込める自前のI2C環境があるなら、必須ではない。
でもUSBiがあると、GUIで制御パラメータを変更したときにリアルタイムに結果を確認できるといった恩恵を享受できるので、あるに越したことはないです。(Digikeyで1万円とちょっと)
海外だとArduinoとVSでSigmaDSP書き込み環境を構築している作例も見ることができる。このソフトはダウンロードできるので興味のあるArduino使いの方はDLして試してみてもいいと思います。(紹介ビデオのリンクはこちらA Universal Through-Hole Audio DSP Board Based on the ADAU1701 [130232-I] | Elektor Labs)
なお、USBiはこんな外観。小さい。
2x5ピンのフラットケーブルもついてくる。なおこの基板のメインはCypress FX2LP (CY7C68053)で回路図は公開されている。
- ターゲット
開発ボードもあるんですが、部品が山盛り載ってて自分の試したいアプリケーションで使うには大改造が必要な感じだったので最初はバラックで組むことにしました。うまくいったらPSoC4+ADAU1701基板起こしますかね。
ADAU1701をサンプルでADIからゲット。
- データシートなど資料
ADIのチップは頭から足の先まで末恐ろしい挙動をする悪魔のデバイスなのでマニュアルにのっているデータだけではなく各方面の資料を調べて総合的に判断した方が良さげです。
ADAU1701で調べたのは以下の資料
- データシート:http://www.analog.com/static/imported-files/data_sheets/ADAU1701.pdf
- 純正評価ボード:http://www.analog.com/static/imported-files/eval_boards/EVAL-ADAU1701MINIZ.pdf
- SigmaDSPのGPIOの使い方とか:http://www.analog.com/static/imported-files/application_notes/AN-951.pdf
- SigmaStudio Wiki:SigmaStudio and SigmaDSP Documentation [Analog Devices Wiki]
試食用ハードを用意
大体使い方がわかってきたところで、バラック組みをしてみました。ほぼADAU1701データシートのp.49『SELF-BOOT MODE』の通りに組み上げましたが、公式評価ボードを参考にし、DSPのWPピンを10kでプルアップ、I2C EEPROMのWPをGNDに落としています。(こうしないとEEPROMからブートしない)
ぐちゃっ
ソフト
とりあえず、DSPで正弦波を作ってDACから出力しようと思います。
2014年4月8日現在、SigmaStudio 3.9が最新版です。Beta 3.10.3もありますが、自分の環境だとUSBiが時々見えなくなる現象が起きたので使用を控えました。
(メニュー)File -> New Project
を選択します。Tree ToolBoxからUSBi, ADAU1701, E2Promを選び、ひとつずつ隣のHardware Configurationタブにドラッグし、下図のように結線します。
次にHardware ConfigurationタブからSchematicタブに移動します。
ここでも同様にTree ToolBoxから機能パーツを選択します。
(IC 1)ADAU1701のツリーから以下のパーツを探して、Schematicタブにドラッグしてきます。
- Basic DSP -> Logic -> Invert -> Signal Invert
- Basic DSP -> Arithmetic Operations -> Signal Add
- Sources -> DC -> DC Input Entry
- Sources -> Oscillators -> Sine tone
あと、DACを2つ使うので、
- IO -> Output -> Output (を2つドラッグしてくる)
加えて信号分岐用にTree ToolBoxの上層のSchematic Design -> T Connection をドラッグしてくる。
下図のようになるはず。
これを以下の図のように配線する。
Tone1には100(Hz)、DCには0、Output1,2はそれぞれDAC0,DAC1をプルダウンから選択する。inv1にチェックを入れるのを忘れずに。
これで完成したので、リンクとコンパイルを行う。メニュー下のアイコン一覧から、Link Projectアイコンをクリックする。
ポップアップウィンドウでエラーがないことを確認したら、このウィンドウを閉じる。万が一エラーが出たら未結線のコネクションがないかもう一度確認する。
次に隣のアイコンのLink Compile Connectをクリックする。
もしこのときUSBiが接続されていない旨のエラーが出た場合(下図のエラー)
USBiを使ってない場合はそのままOKを押して次へ。
もし使っている場合はUSBiの接続や、ドライバがこけていないか確認する。
(USBiユーザのみ)次にそのまた隣のアイコン、Link Compile Downloadをクリックする。こうすると、ボードとの接続が開始され、Schematicタブでプロパティ変更を行うと瞬時に結果が反映される。DAC0,DAC1はADAU1701の46,45番ピンにアサインされているので、オシロのプローブを当たると下図のようになるはず。DAC1はSignal Invertを挿入しているのでDAC0の信号を反転した波形が出力されているはず。
なお、下図のようにバイアスを与えてみる(DCのプロパティに1を代入)と
半波整流回路を通した後のような波形が得られる。
※ EEPROMに書き込みたい場合は以上の手順を踏んだ後、Hardware Configurationタブに戻り、ADAU1701のアイコン上で右クリック→ Write Latest Compilation to E2PROMを選択する。これで、SigmaDSPが起動後、SELFBOOT端子がHighになっていればI2C EEPROMからパラメータをロードしてDSPを起動することができる。
PhoneGapからiOSデバイスのハードウェアボリュームを制御する
前回の続きになります。
有線でiOSデバイスに信号を送るのに手っ取り早い方法は、音声信号にデコードした情報をマイク入力で送るか、リモコンで情報を送る方法だと思います。
あとは送信された音声データや音量レベルをデコードするアプリを書けば良いのです。
HTML5にはmedia要素にvolumechangeイベント、またWeb Audio APIにもAudioGainNode.gain.valueが存在し、音量の調整・読み込みが出来るのですが、試したところ音源の音量を調整・検出するのみでハードウェアボリュームとは連動しませんでした(って、当たり前か…)
参考:Getting Started with Web Audio API - HTML5 Rocks
なのでPhoneGapでもHTML+JSのみでは無理でObjective-Cでネイティブプラグインコードを書いてやる必要があります。*1
プラグインの導入
iOSネイティブプラグインの作り方:PhoneGap API Documentation
読んでてクッソめんどくさいなとおもって諦めかけてたところこんなものを発見
devgeeks/VolumeSlider · GitHub
コードを見るとMPVolumeViewクラスがラッピングされている事が分かります。
このプラグインを自分のプロジェクトに導入します。ターミナル.appで自分のプロジェクトディレクトリに移動し、
phonegap local plugin add https://github.com/devgeeks/VolumeSlider.git
これで、プラグインを追加した際のxmlの設定など、煩雑な事を全部やってくれます。
あとは適宜必要なコードを追加するだけです。
ボリュームコントロールするコードの追記
VolumeSliderプラグインはスライダを初期化、UIに表示、非表示する機能のみなので、ハードウェアボリュームの値を読む、制御するObj-Cコードを追記します。
- 音量レベルのリード例
float value = [[MPMusicPlayerController applicationMusicPlayer] volume];
valueは0(最小)~1(最大音量)の範囲になります。
- 音量レベルの指定例
[MPMusicPlayerController applicationMusicPlayer].volume = 0.5f;
以上をふまえてプロジェクトの/Plugins の中にVolumeSlider.mにコードを追記しました。
なおディレクトリ階層は前回のプロジェクトの続きに作っているので以下の様に見えています。
//VolumeSlider.mに追記 - (void)getVolumeSlider:(CDVInvokedUrlCommand *)command { NSArray* arguments = [command arguments]; self.callbackId = command.callbackId; NSString *resultType = [arguments objectAtIndex:0]; float value = [[MPMusicPlayerController applicationMusicPlayer] volume]; // return value for example CDVPluginResult *result; if ( [resultType isEqualToString:@"level"] ) { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:value]; [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; } else { [MPMusicPlayerController applicationMusicPlayer].volume = 0.5f; result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Changed!"]; [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; } }
//VolumeSlider.hに追記 - (void)getVolumeSlider:(CDVInvokedUrlCommand *)command;
次に上記ネイティブ関数をコールするexec()関数をJSで記述します。exec()関数は以下の文法になります
exec( resultHandler, errorHandler, native_class, native_function, [resultType]);
PhoneGapは上記の関数によってネイティブコードをコールします。
exec()関数は、resultHandler、errorHandler、呼び出すネイティブクラス(native_class)、ネイティブ関数への参照(native_function)、ネイティブコードに渡されるパラメーターの配列([resultType])をネイティブ関数へ引き渡します。
先ほど書いたObj-Cのコード(VolumeSlider.m / .h)はexec関数からコールされる関数です。今回のコードではJSからネイティブへ"level"という文字列とともにコールされた場合はresultHandlerにボリュームレベルを戻り値としてコールバックしています。
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:value]; // valueには音量レベルが代入されている [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
また、それ以外の文字列ならば、ボリュームレベルを0.5にして"Changed!"という文字列を戻り値としてerrorHandlerをコールバックしています。
[MPMusicPlayerController applicationMusicPlayer].volume = 0.5f; result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Changed!"]; [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- JSの修正
/www配下のVolumeSlider.jsを探します。
VolumeSlider.jsに以下を追記します。
module.exports = { //中略 , // <-前の関数のあとにカンマを付けるのを忘れずに getVolumeSlider : function (success,fail,resultType) { return exec(success, fail, "VolumeSlider","getVolumeSlider",[resultType]); } };
次に、index.htmlのscriptにハンドラを記述します
</script> var volumeSlider = null; var volLevel = null; // 中略 volumeSlider = window.plugins.volumeSlider; // 中略 function getVolume() { volumeSlider.getVolumeSlider(VSLevelHandler, VSControlHandler, "level" ); return volLevel; } function resetVolume() { volumeSlider.getVolumeSlider(VSLevelHandler, VSControlHandler, "reset" ); } function VSLevelHandler (result) { volLevel = result; } function VSControlHandler (error) { document.getElementById("res").innerHTML = "result=" + error; } </script>
index.html全文
そして前回の記事で作ったプロジェクトに追記したindex.html全文です
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <style> .btn { font-family: Arial, Helvetica, sans-serif; font-size: 28px; color: #fff; padding: 12px 18px; background: #8893da; background: -webkit-gradient( linear, left top, left bottom, from(#8893da), to(#344c77) ); border-radius: 10px; -webkit-box-shadow: 12px 12px 12px rgba(000, 000, 000, 0.3), inset 0px 0px 0px rgba(255, 255, 255, 0); text-shadow: 10px 10px 10px rgba(000, 000, 000, 1), } </style> <script type="text/javascript" charset="utf-8" src="phonegap.js"></script> <script type="text/javascript" charset="utf-8"> var rec = null; var src = null; var volumeSlider = null; var volLevel = null; var timerID = null; document.addEventListener("deviceready", init(), false); function init(){ src = "test.wav"; } function startRec(){ rec = new Media(src, // success callback function() { console.log("Audio Success"); }, // error callback function(err) { console.log("Audio Error: "+ err.code); }); // Record audio rec.startRecord(); document.getElementById("stat").innerHTML = "recording..."; } function stopRec(){ rec.stopRecord(); document.getElementById("stat").innerHTML = "stop recording"; } function playRec(){ volumeSlider = window.plugins.volumeSlider; volumeSlider.createVolumeSlider(10,350,300,30); volumeSlider.showVolumeSlider(); rec.play(); document.getElementById("stat").innerHTML = "play..."; resetVolume(); // 音量は0.5fにリセット timerID = setInterval(intervalGetVolume,300); } function intervalGetVolume(){ getVolume(); document.getElementById("res").innerHTML = "vol=" + volLevel; } function playStop(){ rec.stop(); clearInterval(timerID); document.getElementById("stat").innerHTML = "stop playing"; } function getVolume() { volumeSlider.getVolumeSlider(VSLevelHandler, VSControlHandler, "level" ); return volLevel; } function resetVolume() { volumeSlider.getVolumeSlider(VSLevelHandler, VSControlHandler, "reset" ); } function VSLevelHandler (result) { volLevel = result; } function VSControlHandler (error) { document.getElementById("res").innerHTML = "result=" + error; } </script> </head> <body> <h1>Using Media APIs</h1> <div> <button class="btn" onclick="startRec()">REC</button> <button class="btn" onclick="stopRec()">STOP REC</button> <button class="btn" onclick="playRec()">PLY</button> <button class="btn" onclick="playStop()">STOP PLAY</button> </div> <div id="stat"></div> <div id="res"></div> </body> </html>
- 使い方
立ち上がったら、とりあえずRECを押して数秒間録音します(10秒くらい)。そのあとSTOP RECで止めます。
PLYを押して再生します。音源の再生が終わるまで、リモコンや側面ボリュームボタンを押すとそれに応じてボリュームスライダが変化し、音量レベルを数値で表示します。
おしまい。
*1:ちなみにPhoneGapにはvolumedown/volumeupイベントがありますが、これはblackberryのみ対応です http://docs.phonegap.com/en/3.3.0/cordova_events_events.md.html#volumeupbutton
エナジーハーベストPLDボードRODSZEPTA進捗状況(その3) :通常電力版MOZPENTAを作った
ハード開発環境の分離
前回の結果をうけて、エナジーハーベスト電源側とCPLD側の開発を別々に進める事にしたわけですが、MAX V 1270LEの144ピンTQFPパッケージ(5M1270ZT144)が手に入ったため、このデバイスで基板を起こしました。
RODSZEPTA(ラセタ)と区別するのにMOZPENTA(モズペンタ)と名付けています。意味は不明です。
もろもろを実装
USBコネクタの近くにある56ピンのSSOPパッケージはFX2LPです。USB-Blasterのフリをする悪い奴です。(ぉ
ixo.de USB JTAG podのコードを、この基板用にピンアサインを変更してFX2LPにプログラムしています。
ixo.de USB JTAG pod
認識成功
Lチカ
PhoneGap 3.3.0でiOS開発する
PhoneGapとは
HTML5+CSS+JavaScriptのみでさまざまなスマートフォンプラットフォーム、例えばAndroid、iOS、Windows Phone7/8、BlackBerryに対応できるフレームワークです。
なんでこんなもん使おうと思ったのか
html5で本来ネイティブアプリケーションでないと操作が難しかった、ファイル、カメラ、GPS、近接センサ、電池残量検出といった機能を実装できる様になってきました。
もし、ブラウザで完結できるようなアプリであれば、わざわざXcodeをつかう開発しなくていいので、ブログやプレゼンでjsのコードだけ貼付けておけば手軽に試してもらえるかな、と思った訳です。
具体的にはマイクで音声信号を広い、デコードした内容に応じて結果をスピーカから音声で返すモデムの実装です。(一時期流行ったAudio Hi-Jackです)
でも、現実はそんなに甘くなく
ブラウザ経由でマイクからの音声を取得するのにgetUserMedia() APIを使いますが、これは2014年1月現在iOS Safariでは対応していないわけです。
というわけで、(Xcodeで開発しなきゃならないのは仕方ないですが)マイクの取得=ネイティブ or それに準ずる環境、それ以外=HTML5 + JSで実行する事になります。このような理由からPhoneGapを使いました。
導入まで
導入方法が書いてある書籍やブログに当たったんですが、3.3.0ではかなり変わっちゃったみたいで少し苦労しました。
以下はそのメモ。
まずPhoneGap本家サイト:
PhoneGap | Home
※ Xcodeの導入、iOSデバイスのプロビジョニング関連は完了しているものとする。またnode.jsは導入済みのものとする
本体のインストール
$ sudo npm install -g phonegap
作りたいアプリケーションをCompany Identifierとともに指定します。自分の場合はVoiceCoderと言う名前で、Identifierはcom.lynxeyed.voicecoderとしました。
$ phonegap create voicecoder com.lynxeyed.voicecoder "VoiceCoder"
ディレクトリに移動
$ cd voicecoder/
使用するプラグインを導入します。今回はMedia API、Media Capture APIを使うのでこちらを導入しました
$ phonegap plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-media.git $ phonegap plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture.git
iOS用にビルドします。
$ phonegap build ios
すると、XCode用プロジェクトが、[アプリケーション名]/platform/ios/ 配下に作成されます。
とりあえず、このプロジェクトファイルをダブルクリックして、Xcodeを起動します。
実行します。
実機を指定している場合はiOSデバイス本体、そうでない場合はシミュレータが立ち上がって
こんな感じになれば動作確認は終了です
とりあえずマイクから録音できるか確認する
Audio Hi-Jackネタではマイクが使えないといけないので、ここだけ確認します。
使うのはPhoneGapのMedia APIです。
以下のサイトのコードをほぼそのまま使っています。が、3.3.0ではiOS、AndroidでMedia APIの呼び出すメソッドの差異は無い模様なので修正しました。
ASCII.jp:JavaScriptで作れるiPhone用ボイスレコーダー (1/5)|古籏一浩のJavaScriptラボ
画面はこんな感じ。
以下を/www配下のindex.htmlに記述します。iOS以外でも動作するはずですがwebkit系のブラウザ以外ではスタイルが崩れるはずなので各自修正を。
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <style> .btn { font-family: Arial, Helvetica, sans-serif; font-size: 28px; color: #fff; padding: 12px 18px; background: #8893da; background: -webkit-gradient( linear, left top, left bottom, from(#8893da), to(#344c77) ); border-radius: 10px; -webkit-box-shadow: 12px 12px 12px rgba(000, 000, 000, 0.3), inset 0px 0px 0px rgba(255, 255, 255, 0); text-shadow: 10px 10px 10px rgba(000, 000, 000, 1), } </style> <script type="text/javascript" charset="utf-8" src="phonegap.js"></script> <script type="text/javascript" charset="utf-8"> var rec = null; var src = null; document.addEventListener("deviceready", init(), false); function init(){ src = "test.wav"; } function startRec(){ rec = new Media(src, // success callback function() { console.log("Audio Success"); }, // error callback function(err) { console.log("Audio Error: "+ err.code); }); // Record audio rec.startRecord(); document.getElementById("stat").innerHTML = "recording..."; } function stopRec(){ rec.stopRecord(); document.getElementById("stat").innerHTML = "stop recording"; } function playRec(){ rec.play(); document.getElementById("stat").innerHTML = "play..."; } function playStop(){ rec.stop(); document.getElementById("stat").innerHTML = "stop playing"; } </script> </head> <body> <h1>Using Media APIs</h1> <div> <button class="btn" onclick="startRec()">REC</button> <button class="btn" onclick="stopRec()">STOP REC</button> <button class="btn" onclick="playRec()">PLY</button> <button class="btn" onclick="playStop()">STOP PLAY</button> </div> <div id="stat"></div> </body> </html>
エナジーハーベストPLDボードRODSZEPTA進捗状況(その2)
デバイステストが終了
RODSZEPTAにはエナジーハーベスト用電源管理ICにLTC3330を試験的に採用しています。
LTC3588-1と基本的構造は同じですが、バックブーストDCDCとLDOの2電源を内蔵しているところが異なります。また取得できる電流が少し減っているようです。
詳しくは LTC3330 - 環境発電(エナジーハーベスト)バッテリ寿命延長回路を内蔵したナノパワー昇降圧DC/DCコンバータ - Linear Technology
この電源ICの内蔵LDOからMAX Vのコア電源1.8V、その他IO電源をDCDCから取得しようと計画していました。
下の写真は加速劣化試験後のRODSZEPTA
また振動発電を主なオルタネイティブ電圧源としてしているので、耐圧が低めの電気二重層コンデンサでも発電支援をしてくれるスーパーキャパシタバランサの特性も測定していました。
結果はほぼデータシート通りでしたので特筆する所は無いのですが、2電源欲しい場合、LTC3588-1に小電力タイプLDOを併用したときと比べてエネルギー損失にあまり差がないにもかかわらず、コストが倍近くかかることや、実装面積比の優位性が無いことなどがあり今回、LTC3330は一旦採用を見送りLTC3588-1を使ってみようと思います。
なお、一次電池によるバックアップはLTC3588-1でも可能です。
というわけで
LTC3588-1を試すのに便利なモジュールを買いました
秋月の環境発電モジュール
圧電環境発電(エナジーハーベスト)電源IC LTC3588−1: 半導体 秋月電子通商 電子部品 ネット通販
これに、MAXVのコア電源1.8VはマイクロチップのMCP1801
http://ww1.microchip.com/downloads/en/DeviceDoc/22051c.pdf
を使おうと思います。
省電力イメージセンサボードを作る
事の発端
今年の初めに友人と天王寺ミオで、
こんな↓ラジコンにラインスキャン乗せて映像撮ったら面白そうだねという会話
でも大容量Li-PO電池もたないといけないかも、ついでに重くなるから出力上げないと、という話をしてたときに、
「振動で発電すれば電池要らないんじゃね?」
ということになり、作ってみるかと。
その後、雑事に忙殺されてなかなか暇が取れませんでしたが思い出したように作ってみました。振動のみで発電するのは難しいことが分かったので、一次電池との組み合わせにしました
ボード外形
・エナジーハーベストイメージセンサ制御ボード "RODSZEPTA (ラセタ)"
プロセッサ:NXP LPC800シリーズ
コプロ:Altera MAX V CPLD 5M570ZT
「勝手にAltera30周年記念祭り」と称してのAlteraデバイスの採用ですが、Avalon-MM MasterBridgeと外部マイコンの組み合わせは仕事でも重宝しています。今回もこれを前提にシステムを設計しています。
イメージセンサと振動発電用ピエゾフィルムは交換可能なように別基板でマウントする方式です。
イメージセンサ、コプロは必要なときだけ起動し、撮影が終わったら省電力モードに。
プロセッサはタイマで必要なときに起床します。
基板おもて面
基板うら面(表面からの透過)
試作は2層、デバッグ終わり次第4層の基板で製作する予定です。
週明けに発注すれば、年明けには来るかな?