とにかく小さくて安いのに、ほぼArduinoとして使える。
そしてズボンのコインポケットに入れて持ち歩けるので電車内hackに便利。

DigiSpark


ソースコードはここに置いておいた。
デジタル出力・アナログ出力・アナログ入力・Mac上のRubyとのUSB通信を試した。
https://github.com/shokai/digispark-study

「webサービスと連動したちょっとしたハードウェア」にはArduinoはオーバースペックだと思うので、DigiSparkちょうどいいと思う。





普通のArduinoとの違い

詳しくは digispark:tutorials:basics [Digistump Wiki]

多少制限はある。
  • IOピン数が6本、PCとUSB通信する場合は4本しか無い
  • プログラムを書き込めるメモリ領域が6Kbyteしかない
  • PCからは仮想シリアルポートではなくただのUSB-HID(ヒューマンインタフェースデバイス)として認識される

内部のソースコード読んだらすごかった。
DigiSparkはマイコン上のプログラムを工夫する事で部品点数を減らし、価格と基盤サイズを抑えている。

ここの一番下にある回路図を見ればわかるが、DigiSparkはATTiny85という安い8ピンマイコンと、抵抗・ダイオード・三端子レギュレータしか使っていない。部品点数が少なく基板も片面実装なので安い。

ATTiny85にはUSB機能は付いていないが、micronucleusというDigiSparkのファームウェアがArduinoブートローダとソフトウェアUSBを同時に実装しているから、たったこれだけの部品でArduinoになれる。

micronucleusはV-USBというUSB1.1のソフトウェア実装を取り込んでいる。

V-USBは、10年ぐらい前に流行った「12MHz以上のAVRマイコンならUSB-HIDになれる」というhackを綺麗に書きなおしてオープンソースで公開されているライブラリ。

実際に使う上で一番大きい違いは仮想シリアルポートではなくUSB-HIDとして使わなければならない所だけど、これはDigiSparkを単体で使う場合は関係ないし、PCと通信させて使う場合もRubyならdigiusbというgemを使えば普通のシリアルデバイスの様に使える。
digiusbの実装を見ると普通にlibusbを使っているだけなので、他の言語でもたぶんなんとかなるんじゃないかと思う。

誰かnode.jsのC拡張くわしい人、digiusb npm作ってください


購入

注文して1週間ぐらいで届いた。

Digispark USB Development Board – Digistump

日本円でも決済できる。
単体で9ドル、現時点で895円。
発送方法は色々選べるけど安いUSPS First Class Package Insuredの965円にした。14+ daysって書いてあったけど1週間ぐらいで来た。

最低でもこのUSB Development Boardだけあれば良いが、シールドなども色々あるのでまとめていろいろ買った。
DigiSparkをUSBポートに接続し、PC/Mac上のソフトで自作プログラムを書き込めば動くので特に別途マイコン書き込み器等は必要ない。

他に頼んだもの

Stackable Headersはシールドを2階建以上積むる時に使う。
Starter KitはUSB Development boardにRGB Shield KitPrototype Shield Kitが付いたもので、壊した時の為にもう一枚DigiSpark欲しかったから買った。バラで買うより100円安い。
Temperature Sensor Shieldは1-wireで温度が計れる。


ボードへのプログラムの書き込み

DigiSpark用のIDEを使う。

Arduino IDEはJavaで実装されていて、Mac/PC/Linuxで使える。それにDigiSparkへの書き込み機能とDigiSprak用のマイコン側のライブラリを追加したものがこれ。

タイトルバーにArduino IDEって書いてあるけど、[ツール]→[書込装置]にDigiSparkが追加されている。
また、スイッチサイエンスが作って本家Arduino IDEに取り込まれた日本語化も有効になっている。


とりあえず使う

プログラムの書き込みはArduinoと同じを押すだけ。
しかしボード上にリセットボタンが無いのでUSBポートを抜き差しする事で代替する。
Arduinoのファームウェアは電源が入ってから数秒はプログラム書き込み待ち状態になり、特にプログラムが送られてこない場合は今持っているプログラムを実行するようになっている。

基板上のLEDを点滅させる


基板上にテスト用のLEDがあるが、基盤のリビジョンによりpin0にあったりpin1にあったりする。とりあえず500ミリ秒ごとに両方点滅させた。

led_blink.ino
bool led_stat = false;

void setup(){
pinMode(0, true);
pinMode(1, true);
}

void loop(){
digitalWrite(0, led_stat);
digitalWrite(1, !led_stat);
led_stat = !led_stat;
delay(500);
}


LEDをぼんやり点滅させる

analogWriteを使った。なおanalogWriteにはpinModeの設定はいらない(arduino.cppが勝手にやってくれる)


led_fade.ino
void setup(){
}

void loop(){
for(char i = 0; i < 26; i++){
analogWrite(0, i*10);
analogWrite(1, i*10);
delay(20);
}
for(char i = 25; i > 0; i--){
analogWrite(0, i*10);
analogWrite(1, i*10);
delay(20);
}
}


Macと通信する

Rubyでやる場合、libusbのラッパーのdigiusb gemをインストールする
% brew install libusb
% gem install digiusb
digitermという実行コマンドも付いている。


アナログセンサーを読んでMacに送る

analogReadしてUSBでMacに送る

SerialライブラリのかわりにDigiUSB.hを使う。delayもDigiUSB.delayにしないと通信できなくなる。
adb_usb.ino
#include <DigiUSB.h>

void setup(){
DigiUSB.begin();
}

void loop(){
DigiUSB.println( analogRead(1) );
DigiUSB.delay(100);
}

なおLEDを点滅させながらanalogReadしたら値がブレまくるけど、キャパシタを入れれば大丈夫だと思う(まだ試してない)

digitermで見る


センサーつないでないけどanalogReadは取れてる。


Rubyで受信する

adc_usb.rb
require 'digiusb'

spark = DigiUSB.sparks.first

loop do
recv = spark.gets.strip
puts "analog value: #{recv}"
end

digiusb gemは普通にIOっぽく使えるので、serialport gemからの移行も楽だと思う。


Macから基盤上のLEDを点灯・消灯する

今度はMacからDigiSparkに命令を送る。

‘o’が来たら点灯、’x’が来たら消灯するプログラムを書いた
usb_led.ino
#include <DigiUSB.h>

void setup(){
pinMode(1, true);
DigiUSB.begin();
}

void loop(){
if(DigiUSB.available()){
char recv = DigiUSB.read();
switch(recv){
case 'o':
digitalWrite(1, true);
break;
case 'x':
digitalWrite(1, false);
break;
}
}
DigiUSB.delay(10);
}

digitermを起動して、oやxを入力しenterキーで送信で操作できる。


RubyからLED点灯・消灯命令を送る


1秒ごとに点灯消灯

usb_led.rb
require 'digiusb'

spark = DigiUSB.sparks.first

led_stat = false

loop do
puts led_stat
spark.write( led_stat ? 'o' : 'x' )
led_stat = !led_stat
sleep 1
end


このように簡単に使えるし、安いし、ズボンのコインポケットにピッタリはいるから電車内hackに便利。
arduino_firmataのdigispark版を作ろうと思う。けど6Kbyteのプログラムメモリに入れるために機能を削らないとならないかもしれない。
node用のdigiusb npmも欲しい。

あと、AndroidとArduinoを接続したりした時も思ったけど、もうUSB上で仮想シリアルポート使うのやめたほうがいいんじゃないかと思う。DigiSparkのようにUSB-HIDならドライバいらないし、libusb使えば自作プログラムとマイコンの通信も簡単だし、シリアル通信を115200bpsとかいう速度で読み書きするのもなんかおかしい気がする。