Open Source
    Microcontroller
    Automatic Control
    Coding Notes

2014年5月29日 星期四

利用Processing 顯示 Arduino 加速規模組姿態

清晨7:56 Posted by Unknown , , 1 comment



加速規,用來量測加速度的裝置,但也因為重力恆向下,也可以拿來測量重力於其他方向的分量,進而推算得到物體目前的姿態。

本篇文章主要討論如何從三軸加速規擷取訊號到Arduino,並透過序列傳輸將三軸的分量傳至電腦由Processing接收,並將物體姿態繪出顯示於螢幕。




Arduino ADXL345 三軸重力加速模組 




本篇範例所使用的 Arduino ADXL345 三軸重力加速模組 (數位輸出) Datasheet 。


我們有兩種方法能讓Arduino與加速度模組溝通,分別是SPI 跟 I2C ,文章使用 I2C 通訊作為範例,主要因為Arduino 提供非常方便的 library 供我們使用。


我們可以在Arduino 的 Wire Library 說明頁中看到 Uno 的腳位是  A4 (SDA),  A5 (SCL),因此加速度模組與Arduino 的連接也非常的簡單。


ADXL345 的VCC 接到 Arduino 的 3.3V ,GND 接到 Arduino 的 GND,SDA 接到 Arduino 的 A4,SCL 接到 Arduino 的 A5,這樣接線就完成了。



Arduino 與加速度感測器的連接


硬體準備就緒後,就進入軟體部分。


首先下載 Arduino 的 Wire Library,解壓縮後放到 arduino 的Library資料夾中。


接著下載 ADXL345 的 Arduino Library 。若不想用別人的程式碼可以可以照著 ADXL345 的 Datasheet 自己試著寫,但在此我們先用別人寫好的來修改,畢竟我們的目的是在Processing 上顯示出姿態。


在 ADXL345 的 Datasheet 第10頁中解釋了如何透過I2C跟 ADXL345 溝通,也因此可以看到 Library 的前段是在配置記憶體位置,為了避免記憶體衝突。


為了將資料傳至Processing(注意:鮑率要對應),我們必須修改一小段程式碼,請將 readAccel() 的副程式改寫成如下:

void readAccel() {

  uint8_t howManyBytesToRead = 6;

  readFrom( DATAX0, howManyBytesToRead, _buff); //read the acceleration data from the ADXL345



  // each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!

  // thus we are converting both bytes in to one int

  int x = (((int)_buff[1]) << 8) | _buff[0];  

  int y = (((int)_buff[3]) << 8) | _buff[2];

  int z = (((int)_buff[5]) << 8) | _buff[4];




    Serial.write('X');

    Serial.write(_buff[1]);

    Serial.write(_buff[0]);

    Serial.write(_buff[3]);

    Serial.write(_buff[2]);

    Serial.write(_buff[5]);

    Serial.write(_buff[4]);



}

因為 Serial 是一個 byte 一個 byte 傳送,因此我們在Arduino 讀取到的高位元與低位元的值就直接傳至 Processing 再處理,不用再多做一個步驟,並加上一個 'X' 當做起始字元。

接下來就是Processing 的程式碼(再次提醒:鮑率要對應!):

import processing.serial.*;



Serial serial;

int[] invalue=new int[6];

int[] Val=new int[3];



float G=250;

float xacc;

float yacc;

float zacc;



void setup(){

  size(600,300,P3D);

  fill(0, 102, 153);

  println(Serial.list());

  serial=new Serial(this,Serial.list()[3],9600);

  println("Start!");



}



void draw(){

  if(serial.available()>20){

      if(serial.read()=='X'){

        int sign = 1;

        invalue[1]=serial.read();

        invalue[0]=serial.read();

        invalue[3]=serial.read();

        invalue[2]=serial.read();

        invalue[5]=serial.read();

        invalue[4]=serial.read();

          if( invalue[1]>>7 == 1 ) {

             invalue[1]= 255 - invalue[1];

             invalue[0] = 256 - invalue[0];

             sign = -1;

          } else {

            sign = 1;

          }Val[0] = sign * ( invalue[1] << 8 | invalue[0] );

          if( invalue[3]>>7 == 1 ) {

             invalue[3]= 255 - invalue[3];

             invalue[2] = 256 - invalue[2];

             sign = -1;

          } else {

            sign = 1;

          }Val[1] = sign * ( invalue[3] << 8 | invalue[2] );

          if( invalue[5]>>7 == 1 ) {

             invalue[5]= 255 - invalue[5];

             invalue[4] = 256 - invalue[4];

             sign = -1;

          } else {

            sign = 1;

          }Val[2] = sign * ( invalue[5] << 8 | invalue[4] );

          println(Val);

          background(0);

          textSize(20);

          translate(width/2, height/2);

          text("z-acc:"+Val[2],-250,-100);

          text("x-acc:"+Val[0],-250,-80);

          text("y-acc="+Val[1],-250,-60);



          rotateX(asin(Val[1]/G));  //xacc

          rotateZ(asin(-Val[0]/G));   //Yacc

 

          box(100,20,100);

        }

     }

    }

注意到程式碼紅、藍、綠的地方,這裡我們要對接收到的高低位元資料做處理,ADXL345 傳過來的資料要合併這裡整理出一個規則:
如果值為正,則不改變,但如果值為負,則全部的0變為1;全部的1變為0。

也就是說若值為 256,則高低位元分別是 00000001 00000000;

而值為 -256,則高低位元是 11111110 11111111;
也因此有了上面的處理步驟。


得到資料後,便透過重力在個座標的分量來計算出現在加速規的姿態,這步驟需要一點空間概念,不過並不難,思考一下應該可以得到跟筆者一樣的答案。

以上就是如何利用Processing 顯示 Arduino 加速規模組姿態。




1 則留言:

  1. Casino - MapyRO
    Casino - The place for all your casino games, from live 과천 출장안마 dealers, to the latest bingo, slots 목포 출장마사지 and 강원도 출장안마 poker to the 양주 출장샵 biggest prizes!‎Casino · ‎Casino · ‎Cash games · ‎Promotions 영천 출장안마

    回覆刪除