69章:加速度センサADXL345とHMC5883Lコンパス使用低コスト回路

    作成2016.10.13

     加速度センサADXL345とHMC5883Lコンパス使用低コスト回路を検討してみました。

  1. 基板組込時に不可欠な部品と価格
      Arduino UNOでデバッグが完了した場合、基板組込に不可欠な部品は以下のとおりです。
    (1)AVRマイコンATMEGA328P-PU 1個 小計¥250
    (2)クリスタル(水晶発振子)16MHz 1個 小計¥30
    (3)コンデンサー 22pF  2個 小計¥20
     合計¥300と安価となります。


  2. AVRマイコンATMEGA328P-PUへのブートローダ書込みの必要性
     Arduino UNOでAVRマイコンATMEGA328P-PUにスケッチを書き込むには、あらかじめAVRマイコンATMEGA328P-PUへブートローダを書込む必要があります。
     あらかじめブートローダを書込み済みのAVRマイコンATMEGA328P-PUもあるそうですが、¥250のAVRマイコンATMEGA328P-PUには書き込まれていませんでした。
     書き込み方法の詳細は57章:AVRマイコンATMEGA328P-PUへのブートローダの書込み方法を参照ねがいます。


  3. 加速度センサADXL345とHMC5883Lコンパス使用低コスト回路図
     押しボタンスイッチを4個にしました。
     加速度センサADXL345とHMC5883Lコンパス使用低コスト回路図





  4. 万能基板組込回路外観
     万能基板組込回路外観を以下に示します。





  5. 「Adafrut ADXL345」ライブラリーのインストール
     64章:3軸加速度センサモジュール ADXL345(SPI/IIC)を参照願います。


  6. 「Adafruit_HMC5883_Unified」ライブラリーのインストール
     60章:HMC5883L 使用 3軸 デジタル・コンパス モジュール (3-5V 動作)を参照願います。


  7. Arduinoスケッチ
     Arduinoスケッチは以下となります。
    //ADXL345_HMC5883L_V1
    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_HMC5883_U.h>
    #include <Adafruit_ADXL345_U.h>
    
    #define LED_PIN 13
    static bool blinkState = false;
    #define SW1_PIN 8
    #define SW2_PIN 9
    #define SW3_PIN 10
    #define SW4_PIN 11
    
    Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
    Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
    
    void setup()
    {
      pinMode(LED_PIN, OUTPUT);
      pinMode(SW1_PIN, INPUT);pinMode(SW2_PIN, INPUT);
      pinMode(SW3_PIN, INPUT);pinMode(SW4_PIN, INPUT);
      
      Serial.begin(38400);
      if(!mag.begin()){while(1);}
      if(!accel.begin()) {while(1);}
      delay(500);
    }
    
    void loop()
    {
      float SX[6];
      int i,N=100;
      sensors_event_t event1; 
      accel.getEvent(&event1);
      sensors_event_t event2; 
      mag.getEvent(&event2);
    
      int SW1=digitalRead(SW1_PIN);int SW2=digitalRead(SW2_PIN);
      int SW3=digitalRead(SW3_PIN);int SW4=digitalRead(SW4_PIN);
    
      if (Serial.available() > 0)
      {
        int inByte = Serial.read();
        for(i=0;i<6;i++){SX[i]=0;}
        for(i=0;i<N;i++)
        {
          SX[0]+=event1.acceleration.x;
          SX[1]+=event1.acceleration.y;
          SX[2]+=event1.acceleration.z;
          SX[3]+=event2.magnetic.y;
          SX[4]+=event2.magnetic.x;
        }
        
        float Hx = 100*atan2(SX[0]/N, SX[2]/N);
        float Hy = 100*atan2(SX[1]/N, SX[2]/N);
        float Hz = 100*atan2(SX[3]/N, SX[4]/N);
    
        Serial.print(Hx); Serial.print(",");
        Serial.print(Hy); Serial.print(",");
        Serial.print(Hz); Serial.print(",");
        Serial.print(SW1); Serial.print(",");
        Serial.print(SW2); Serial.print(",");
        Serial.print(SW3); Serial.print(",");
        Serial.println(SW4);
    
        blinkState = !blinkState;// blink LED to indicate activity
        if(SW1==LOW){blinkState=HIGH;}
        digitalWrite(LED_PIN, blinkState);
      }
      delay(50);
    }
    


  8. Arduinoスケッチ_テキストファイル
     Arduinoスケッチ_テキストファイルは以下から参照できます。
    Arduinoスケッチ_テキストファイルにいく


    変更点
    (1)例題SerialCallResponseASCII方式のシリアル通信にしました。
    (2)HxとHyは加速度センサー、Hzはコンパスから求めています。
    (3)押しボタンスイッチ4個としました。。


  9. Processingのスケッチ
     Integration_ADXL345_HMC5883L.pdeのスケッチを以下に示します。
    //Integration_ADXL345_HMC5883L
    import processing.serial.*;
    Serial myPort;        // The serial port
    float My=0;
    float Mz=0;
    float Mx=0;
    float Py=0;
    float Pz=0;
    float Px=0;
    
    import controlP5.*;
    ControlP5 cp5;
    DropdownList d1;
    int mode;
    float scale;
    
    int gSW2=1;
    
    MyJet MyJet;//使用クラスの定義
    Yacht Yacht;
    Train Train;
    Engin Engin;
    BirdBox BirdBox;
    GuardRail GuardRail;
    SolarUnits SolarUnits;
    TrussStructure TrussStructure;
    
    void setup ()
    {
       size(1000, 800, P3D);
       println(Serial.list());
       myPort = new Serial(this, Serial.list()[1], 38400);
       myPort.bufferUntil('\n');   
    
       MyJet=new MyJet();//MyJetクラスのオブジェクトを生成
       Yacht=new Yacht();
       Train=new Train();
       Engin=new Engin();
       BirdBox=new BirdBox();
       GuardRail=new GuardRail();
       SolarUnits=new SolarUnits();
       TrussStructure=new TrussStructure();
       noStroke();
       
       cp5 = new ControlP5(this);
      
       cp5.addSlider("scale")
         .setPosition(200,0)
         .setSize(200,20)
         .setRange(0.1,2)
         .setColorLabel(color(0))
         .setValue(1.0);
         
        d1 = cp5.addDropdownList("List-d1")
              .setPosition(0, 0)
              .setSize(100,180)
              .setItemHeight(20)
              .setBarHeight(20)
              .addItem("My-Jet", 0)
              .addItem("Yacht", 1)
              .addItem("Train", 2)
              .addItem("Engin", 3)
              .addItem("Bird-Box", 4)
              .addItem("Guard-Rail", 5)
              .addItem("Solar-Units", 6)
              .addItem("Truss-Structure", 7);   
    }
     
    
    void draw ()
    {
       pushMatrix();
       background(0, 256, 256);
       lights();
       
       translate(width / 2, height / 2);
       //rotateY(map(mouseX, 0, width, -PI/1, PI/1));
       //rotateX(map(mouseY, 0, height, PI/1, -PI/1));
       translate(Px,Py,Pz);
       rotateX(Mx);
       rotateY(Mz);
       rotateZ(My);
       scale = cp5.getController("scale").getValue();
       mode=(int)cp5.getController("List-d1").getValue();
       
       
       
       scale(scale,scale,scale);
       switch(mode) 
        {
          case(0):MyJet.MyJet();break;
          case(1):Yacht.Yacht();break;
          case(2):Train.Train();;break;
          case(3):Engin.Engin();break;
          case(4):BirdBox.BirdBox();break;
          case(5):GuardRail.GuardRail();break;
          case(6):SolarUnits.SolarUnits();break;
          case(7):TrussStructure.TrussStructure();break;
        }
       popMatrix();
       
       if (myPort.available() <= 0){myPort.write("B");}
    }
     
    void controlEvent(ControlEvent theEvent)
    {
      if (theEvent.isController())
      {
        println(theEvent.getController()+"\t"+mode+"\t"+ scale);
      }
    }
    
    void serialEvent(Serial myPort)
    {
      float  r=0.5;
      String myString = myPort.readStringUntil('\n');
      myString = trim(myString);
      float sensors[] = float(split(myString, ','));
      for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) 
      {
         print(sensors[sensorNum] + "\t");
      }
      println();
      
      if(sensors[3]==1)
      {
        Mx=Mx*(1-r)+sensors[0]*r/100;//重力方向
        My=My*(1-r)+sensors[1]*r/100;//重力方向
        if(sensors[0]*sensors[0]+sensors[1]*sensors[1]<40*40)
        {
          Mz=Mz*(1-r)+(sensors[2]+100)*r/100;//磁力方向
        }
    
      }
      else
      {
        Px=Px*(1-r)+400*(sensors[0]/100)*r;//重力方向
        Py=Py*(1-r)+400*(sensors[1]/100)*r;//重力方向
        if(sensors[0]*sensors[0]+sensors[1]*sensors[1]<40*40)
        {
          Pz=Pz*(1-r)+400*((sensors[2]+100)/100)*r;//磁力方向
        }
      }   
      myPort.write("A");
      if(sensors[4]==0)
      {
        if(gSW2==1)
        {
          mode++;
          if(mode>7){mode=0;}
          cp5.getController("List-d1").setValue(mode);
          //d1.setValue(mode);
        }
        gSW2=0;
      }
      else
      {
        gSW2=1;
      }
      
      if(sensors[5]==0)
      {
        cp5.getController("scale").setValue(scale+0.01);
        delay(10);
      }
      
      if(sensors[6]==0)
      {
        cp5.getController("scale").setValue(scale-0.01);
        delay(10);
      }
     
    }
    


  10. 加速度センサADXL345とHMC5883Lコンパス使用低コスト回路ファイル
      ファイルは下記の「69-1.zip」ファイルをダウンロードしてください。
    [69-1.zip]をダウンロードする。

    解凍するとIntegration_ADXL345_HMC5883Lフォルダー内に
    (1)Integration_ADXL345_HMC5883L.pde
    (2)BirdBox.pde
    (3)Engin.pde
    (4)GuardRail.pde
    (5)My_OB.pde
    (6)MyJet.pde
    (7)SolarUnits.pde
    (8)Train.pde
    (9)TrussStructure.pde
    (9)Yacht.pde
     があります。 Integration_ADXL345_HMC5883L.pdeをダブルクリックすると起動します。




  11. 動作テスト
    (1)角度Mx、角度Myは重力方向から求めているため、ドリフトしません。
    (2)角度Mzはコンパスから求めていますが、安定性は良くありません。
    (3)回路基板の角度を変えると、 3Dサンプルの角度Mx、角度My、角度Mzが変化します。



    (4)押しボタンスイッチSW1を押すと角度を固定したまま、XYZ方向に移動します。



    (5)押しボタンスイッチSW2を押すと、3Dサンプルの画像が変化します。



    (6)押しボタンスイッチSW3を押すと表示倍率が大きくなります。



    (7)押しボタンスイッチSW4を押すと、表示倍率が小さくなります。





  12. 加速度センサADXL345とHMC5883Lコンパス使用低コスト回路)まとめ
    (1)角度Mx、角度Myは重力方向から求めているため、ドリフトしません。
    (2)角度Mzはコンパスから求めていますが、安定性は良くありません。
    (3)押しボタンスイッチを4個設置して、より複雑な動作ができるようにしました。
    (4)押しボタンスイッチSW1を押すと角度を固定したまま、XYZ方向に移動します。
    (5)押しボタンスイッチSW2を押すと、3Dサンプルの画像が変化します。
    (6)押しボタンスイッチSW3を押すと表示倍率が大きくなります。
    (7)押しボタンスイッチSW4を押すと、表示倍率が小さくなります。





トップページに戻る。