0

moxaでバイオメタルを動かした

バイオメタルをmoxaで動かすために0V~3V程度を出せる回路とプログラムを作った。

色々試した結果、最終的にPCからシリアル通信でmoxaのanalogWrite(PWM出力)を制御できるようにして、analogWriteをトランジスタ(2SC1815)に突っ込む。トランジスタは三端子レギュレータ7805から得た5Vを出すが、トランジスタを通る事で3.7V程度に落ちて、バイオメタルにちょうど良い電圧になった。

バイオメタルは「3Vで駆動」と書いてあったけど3.7Vでも大丈夫だった。5Vそのまま入れると変な臭いがしてきてヤバイ(すぐ止めました)

AVRマイコンのGPIO出力は3Vだけど40mAと電流が足りなかった。
バイオメタルを動かすには200mA程度必要で、秋月の3.3Vの三端子レギュレータを使っても動いたけどマイコンから制御するためにトランジスタをかますと2V程度に落ちてしまうので5V電源でやったらちょうど良くなった。アクチュエータ系は試行錯誤が必要だなー



パソコンでアナログ値を制御している動画


回路。基盤で隠れて見えないけど、moxaの左下のGNDはブレッドボードのGNDと接続されている
moxaでバイオメタル動かす
moxaでバイオメタル動かす


今回のtalkticコード
xtel technical information > learning> Analog Read & Writeを参考にした

serialInit(9600);
pinMode(1,true);
pinMode(0,true);
power = 0.0;

function onSerialReceive(){ // シリアル受信イベント
    while(serialAvailable()){ // 受信データがある時
        var recvData = serialRead(); // 読み出し
        power = recvData*0.01;
        analogWrite(0, power);
        analogWrite(1, power)
        serialSend(recvData); // 受信した文字列をそのままエコーする
    }
}

while(true){
}

0

PCなしで、moxaで音を出す

xtel technical information > learning> Sound Writeより

moxaとスピーカを直結させて、soundWrite(ピン番号, 周波数)関数を使うと音が出せる





センサと組み合わせるとインタラクティブに音階を変えられる。CdSという明度センサを使っている

0

moxaでセンサーネットワーク

xtelのmoxaを使う。

moxaのzigbee無線で距離を測るから距離情報を削って、少しフォーマットを変えただけだが
たくさんあるセンサ付きノードの状態を、zigbee無線で一カ所に集めるのが簡単にできる。
8ビットマイコンなのにclassが作れて(厳密にはJavaScript互換なのでクラスではないが)文字列が可変長でString.splitなども使えてArrayもあるので、こういう無線通信プロトコルは簡単に作れる

Read more

0

moxa – 明るさと振動をシリアル通信で送る

CdSと振動スイッチを使った。
xtel基盤のDigitalReadAnalog Readのページが大変参考になりました。


このサイズのCdSだと、330ΩをGNDにつないで分圧したら丁度良くなった。
DSCF4111


まずブレッドボードで回路を組んでみた
DSCF4114


それからはんだづけ
明るさ、振動


プログラム。
連続でシリアル通信するとPCが大変なので、1秒ぐらいのインターバルを取る。
明るさはアナログ値なのでその時間内の平均を取った。
振動も、一度でも振動センサが反応したらshaked:trueになるようにして、serialSendでまとめて送った。

serialInit(9600);
pinMode(0, true); // 振動センサ

function loop(){
    
    var an = 0;
    var shaked = false;
    var loopTime = 1000;
    for(var i = 0; i < loopTime; i++){
        an += analogRead(0); // 明るさ
        if(!digitalRead(0)) shaked = true;
    }
    an = an/loopTime;
    serialSend("light:"+an+",shake:"+shaked+"¥r¥n");
    
    sleep(1);
}


function sleep(count){
    for(var i = 0; i < count*10; i++){
    }
}

while(true){
    loop();
}



PCでシリアル通信受信したところ
振動と明るさ

0

moxaのzigbee無線で距離を測る

zigbee無線で距離を測った。

moxaの無線は出力を変える事ができる。これを利用して、サンプルプログラムの中にあった距離が近づいたらLEDが点灯する奴を改造し、
・複数nodeをID識別
・距離の計測の高速化
を行った。

1つのanchorと複数のnodeとの間の距離を取る。たくさんプログラムを書きこむ羽目になるのでUSBハブが無いと大変。
DSCF2544

■しくみ
徐々に電波強度を上げていくと、「最も弱い出力で受信できた時」を距離とする事ができる。
電波強度は、無線通信のデータ本文に数値として含めておいて、受信側で文字列をparseして読み出す。

moxaはマイコン上でECMAScriptが使えるので、Stringを分解したり、Object型インスタンスに何でも突っ込んだり、配列に溜めたりするのが楽に出来るので通信プロトコルを作るのが楽だった。


■nodeのプログラム
徐々に電波強度を上げながらanchorに無線を送り続ける
node/source.js

var radio = new Object();
radio.id = 2; // id:2以降がnode
radio.group = 7;

var time = 1;
var power_borders = new Array();
power_borders = [1,2,3,4,11,12,13,30,31]; // 距離の境目リスト


function loop() {
       dist_send();
}

function dist_send(){
    for(p in power_borders){ // power
        radioInit(0xDEAD, radio.id, radio.group, p);
        message = "power:"+p+",time:"+time;
        radioSend(0xFFFF, message);
        sleep(1);
    }
    time++;
}

function sleep(count){
    for(var i = 0; i < count*10; i++){
    }
}

while(true){
    loop();
}


■プロトコル
powerを1から徐々に上げながら送信する。

“power:2,time:15”
“power:3,time:15”
“power:4,time:15”

という風にtimeという変数も合わせて送る事で、1セット分の無線送信試行を表している。

■距離の境目
実際にはpowerと無線の飛距離は正比例していなくて、簡単に調べた所
・power 4ぐらい → 4メートル以内ぐらい
・power 10前後 → 5~15メートルぐらい
・power 20前後 → 15~30メートルぐらい
・power 30前後 → それ以上
となっていた。なので、その境目あたりを重点的に送信するために

power_borders = [1,2,3,4,11,12,13,30,31]; // 距離の境目リスト

を使った。こうすると1から最大31まで全powerを試す必要が無くなり、3倍ぐらい速くなっても精度はあまり落ちない。


■anchorのプログラム
nodeからの最低出力で受信できた時のpowerを本文から取り出し、nodeのID毎に配列に保存しておく。
anchor/source.js

var radio = new Object();
radio.id = 1; // nodeはid:2以降
radio.group = 7;

var dist = new Object();
dist.lastTime = 0;
dist.lastPower = 0;

nodes = new Array(16);
nodes_init(nodes);

serialInit(9600);
radioInit(0xDEAD, radio.id, radio.group, 31);

function loop(){
}

function onRadioReceive(seq,id,pan,data,rss) {
    if(id < 2) return; // nodeからではない時
    commands = data.split(",");
    for(c in commands){
        tmp = c.split(":");
        if(tmp[0] == "power") distance = tmp[1];
        if(tmp[0] == "time") time = tmp[1];
    }
    
      if(nodes[id].lastTime != time){ // 新しいデータの時
          nodes[id].distance = distance;
          // nodeのidと距離を出力
          serialSend("id:"+id+",distance:"+distance+",time:"+time+"¥r¥n");
      }
      nodes[id].lastTime = time;
}

function nodes_init(nodes){
    for(i = 1; i < nodes.length; i++){
        var node = new Object();
        node.lastTime = 0;
        node.distance = 0;
        node.id = i;
        nodes[i] = node;
    }
}

function sleep(count){
    for(var i = 0; i < count*10; i++){
    }
}

while(true){
    loop();
}


■無線データの受信と解析
onRadioReceive(seq,id,pan,data,rss) という関数を宣言すると無線を受信できる。
こういうデータが来るので

“power:3,time:15”

splitで : と , を分けて、nodeオブジェクトに保存する。

    commands = data.split(",");
    for(c in commands){
        tmp = c.split(":");
        if(tmp[0] == "power") distance = tmp[1];
        if(tmp[0] == "time") time = tmp[1];
    }
    

また、引数 id に送信元のIDが入っているので、あわせて保存しておく。

■シリアルポートに出力
今回はanchorからパソコンにシリアル通信で出力した。

id:2,distance:10,time:18\r\n
id:6,distance:3,time:11\r\n
id:7,distance:13,time:7\r\n

こんな感じの文字列がきて、anchorとnodeの間の距離、IDがわかる。

距離計測、ついでにボタン状態も
ちなみに、node側でさらにボタンの押下状態なんかも付けられる。