2013年5月13日月曜日

アクリルLEDパネルお試し

とあるイベントでアクリルLEDパネルの展示&作成をやってたのを見て、自分もやってみたくなったので挑戦してみました。

とりあえず雰囲気を掴むため、出来るだけあり合わせの道具で。
アクリル板だけ東急ハンズで買ってきました。
  • 削る道具: ダイソールーター
  • 光る仕組み: Arduino + フルカラーLED (OSTA5131A)
  • アクリル板: 透明 2mm厚
  • パネルの固定: 洗濯バサミ:)
パネルの作成はシンプルに
  1. 紙に絵を下書き
  2. アクリル板を紙に乗せて下絵をペンでトレース
  3. アクリル板に書いた線をなぞってルーターで軽く削る
削る作業だけは集中力が要求されますが、あとは適当。

完成したパネルをLEDの上に垂直に立てて置いただけですが、ちゃんとLEDパネルっぽくなりました。
LEDひとつだと光量が足りないかも?とか、ちゃんと絵が光るのかな?とか不安でしたが杞憂だったみたい。

お手軽でなおかつ面白い。
道具を揃えてパネル台も含めてきちんと作るのもいいかなー。

シンプルな絵ということで、Minecraftで人気のCreeperさんにご登場願いました:)

2013年1月14日月曜日

one-liner時報

終日一人で自宅に引き篭っていると、時間の感覚が無くなってアレな感じです。
最近、職場で時報が鳴るようになったら時間が分かりやすくてよかったので、自宅でも導入してみました。

その辺で公開されているソフトを使ってもいいのですが、折角なので自前で。

サウンドの再生自体は.NETでお手軽にできるので、PowerShellから一発。
(New-Object Media.SoundPlayer("C:\time-signal\signal.wav")).PlaySync()
これをタスクスケジューラで毎時59分56秒とかに実行するよう登録すると、一応時報になります。

ですがこのままではタスク実行時にコマンドプロンプトウィンドウが表示されてちょっと残念。

こういうときはWshShellオブジェクトからRun
第2引数IntWindowStyleを0にすればウィンドウは表示されません。

こんな.vbsファイルをタスクスケジューラに登録すれば目的達成。
CreateObject("WScript.Shell").Run "powershell (New-Object Media.SoundPlayer(\""C:\time-signal\signal.wav\"")).PlaySync()",0
one-linerといいつつ .vbsファイルをタスクスケジューラから呼ぶという邪道な感じになってしまいました。

サウンドデータは好きなものを.WAV形式で調達すれば良いです。

2013年1月4日金曜日

P/Invokeの規定の呼び出し規約

自前のunmanagedなdllを、.NETなアプリケーションからP/Invokeで使おうとした際に  pInvokeStackImbalance で躓いたメモです。
環境は Visual Studio 2010 / .NET Framework 4.0

unmanaged DLL 側はC++でこんな感じ。
extern "C" {
 __declspec(dllexport) bool
 ReadValue(wchar_t* buffer, unsigned int bufferLength) {
  wcscpy_s(buffer, bufferLength, L"hogehoge");
  return true;
 }
}
それをこんなC#コードで呼び出すと、デバッグ実行時に pInvokeStackImbalance で怒られます。
[DllImport("foo.dll", CharSet = CharSet.Unicode)]
public static extern bool ReadValue(StringBuilder buffer, uint bufferLength);
MSDN: DllImportAttribute.CallingConvention フィールド によると
DllImportAttribute.CallingConvention の規定値は Winapi。
これはプラットフォーム標準の呼び出し規約を使用することを示す。Windows なら StdCall。
よくP/InvokeされるWin32APIの場合はすべてStdCallなので規定値でOKですね。

というわけで今回は次ように呼び出し規約をきちんと指定してあげないといけない。
[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern bool ReadValue(
    StringBuilder buffer, uint bufferLength);
ちなみにこのエラーを検出している MDA (Managed Debugging Assistant) は、.NET Framework 3.5 では規定値で無効になっているらしいです。