2016年2月27日 星期六

電流計的筆記


量電流方式有串聯方式非接觸式,一般非接觸式都是使用霍爾電流感應方式量測,但因為使用感應電流方式取得一定比率的電流再回推實際值,這會因為環境因素影響準確性,但非接觸式有個好處如其名稱一樣,我們不需要變更線路設計就能量測到電流。

SCT013
  • SCT013 for Arduino 電路
SCT013輸出是電流的方式,但Arduino Analog IN是量電壓方式,所以需要另外接電路將電流轉換成電壓,而且電流帶有正負電壓的正弦波,需將電壓位準提升至0V以上,上圖為連接的示意圖,等效圖如下:





Reference : http://cms.35g.tw/coding/arduino-using-sct013-measure-current/

Reference : https://openenergymonitor.org/emon/buildingblocks/ct-sensors-interface

2016年2月26日 星期五

OpenGL + adxl345 -> 藉由adxl345來轉動你的茶壺



用adxl345 sensor  可以讀出來  x, y, z  的加速度....

因為地球有重力加速度(垂直往下)....

如果你把adxl345 平放在桌上....你可以發現...x 和 y 軸的加速度為 0....然後z 軸大概為 1G 左右

由於會有些noise.....這個需要做一下校正....

但沒有校正也可以啦....



從參考網址2來看

我們可以得到   roll 和 pitch 的計算公式


    roll = (atan2(-fYg, fZg)*180.0)/M_PI;
    pitch = (atan2(fXg, sqrt(fYg*fYg + fZg*fZg))*180.0)/M_PI;

   那甚麼是roll 和 pitch 呢?

   請看reference 3 的網站...他有動畫...一看就知道.....

  原理是當你轉動你的adxl345 

  由於地球有重心引力.....sensor 的 x, y ,z 的加速度 會因為你的轉動而可得到不同的分量

  所以我們可以從adxl345所量測到的x,y,z 的加速度...反推回去 目前sensor 和地球座標的夾角...

  那有了 roll 和 pitch....也只是一堆數字.....看起來好像不夠酷....

  沒關係....我記得我有在arduino 看到一個例子....adxl345 結合  teaspot....

   那raspberry 也可以畫  teaspot壓....

  找了一下資料...

  發覺在下面的目錄有opengl 的例子....

   /opt/vc/src/hello_pi

剛好有 hello_teapot.....真是太lucky.....

打開  triangle.c 來看.... 找一下我要改的地方....

static void update_model(CUBE_STATE_T *state,double roll, double pitch)
{
   // update position
   state->rot_angle_x = inc_and_wrap_angle(state->rot_angle_x, state->rot_angle_x_inc);
   state->rot_angle_y = inc_and_wrap_angle(state->rot_angle_y, state->rot_angle_y_inc);
   state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc);
   state->distance    = inc_and_clip_distance(state->distance, state->distance_inc);

   glLoadIdentity();
   // move camera back to see the cube
   glTranslatef(0.f, 0.f, -state->distance);

   // Rotate model to new position
   glRotatef(state->rot_angle_x, 1.f, 0.f, 0.f);
   glRotatef(state->rot_angle_y, 0.f, 1.f, 0.f);
   glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f);
}


可以看出來...  他會一直去抓   x 和 y 和 z 的angle......   然後 inc 他....

 所以只要在這邊動點手腳.....把最後送到  glRotatef 的值換掉....應該可以了....

修改的code 大概如下 :


static void update_model(CUBE_STATE_T *state,double roll, double pitch)
{
   // update position
   state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc);
   state->distance    = inc_and_clip_distance(state->distance, state->distance_inc);

   glLoadIdentity();
   // move camera back to see the cube
   glTranslatef(0.f, 0.f, -state->distance);

   // Rotate model to new position
   glRotatef(roll, 1.f, 0.f, 0.f);
   glRotatef(pitch, 0.f, 1.f, 0.f);
   glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f);
}


int main(){


.......


 struct acc_dat gdata;
  double alpha = 0.5f,roll,pitch,fXg = 0.0,fYg = 0.0,fZg = 0.0;

   while (!terminate)
   {
    gdata = getAxes(fd_adxl345, 1);
    // low pass filter ,  to remove noise
    fXg = gdata.x * alpha + (fXg * (1.0f - alpha));
    fYg = gdata.y * alpha + (fYg * (1.0f - alpha));
    fZg = gdata.z * alpha + (fZg * (1.0f - alpha));
    //Roll and Pitch Equations
    roll = (atan2(-fYg, fZg)*180.0)/M_PI;
    pitch = (atan2(fXg, sqrt(fYg*fYg + fZg*fZg))*180.0)/M_PI;

      update_model(state,roll,pitch);
      redraw_scene(state);
   }

}


新增一個  c 的 file   ->  adxl345.c

#include "./adxl345.h"


void enableMeasurement(char FD_ADDR)
{
     wiringPiI2CWriteReg8(FD_ADDR,POWER_CTL,MEASURE);
}

void setBandwidthRate(char FD_ADDR, int rate_flag)
{
     wiringPiI2CWriteReg8(FD_ADDR,BW_RATE,rate_flag);
}

void setRange(char FD_ADDR, int range_flag)
{
        int value;
        value = wiringPiI2CReadReg8(FD_ADDR, DATA_FORMAT);
        value &= ~0x0F;
        value |= range_flag;
        value |= 0x08;

//        printf("set range value : %d",value);
        wiringPiI2CWriteReg8(FD_ADDR, DATA_FORMAT, value);
}

struct acc_dat getAxes(char FD_ADDR, int gforce)
{
        double dx,dy,dz;
        struct acc_dat dat;
        int x,y,z;
        char bytes[6];
        bytes[0] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA);
        bytes[1] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+1);
        bytes[2] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+2);
        bytes[3] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+3);
        bytes[4] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+4);
        bytes[5] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+5);

        //printf("%d\n",bytes[0]);
        //printf("%d\n",bytes[1]);
        x = bytes[0] | (bytes[1] << 8);
        if(x & (1<<15))
            x = x - (1<<16);
        //printf("%d\n",x);

        y = bytes[2] | (bytes[3] << 8);
        if(y & (1<<15))
            y = y - (1<<16);

        z = bytes[4] | (bytes[5] << 8);
        if(z & (1<<15))
            z = z - (1<<16);

        dx = (double)x * SCALE_MULTIPLIER;
        dy = (double)y * SCALE_MULTIPLIER;
        dz = (double)z * SCALE_MULTIPLIER;

        if (gforce == 0)
        {
            dx = dx * EARTH_GRAVITY_MS2;
            dy = dy * EARTH_GRAVITY_MS2;
            dz = dz * EARTH_GRAVITY_MS2;
        }
        dat.x = (dx);
        dat.y = (dy);
        dat.z = (dz);


        return dat;
}

然後 adxl345.h  裡面大概就是一些定義...這裡我就不貼了....

然後修改Makefile

OBJS=triangle.o video.o models.o adxl345.o
BIN=hello_teapot.bin
LDFLAGS+=-lilclient
LDFLAGS+=-lwiringPi

include ../Makefile.include


然後就是編譯......

sudo ./make

執行 

sudo ./hello_teapot.bin

你就可以在你的螢幕看到一個  teaspot....然後轉動你的 adxl345....你就可以看到茶壺也會跟著轉


demo 的影片在下面的連結

demo video:    https://www.youtube.com/watch?v=O3V-0z6UWF0




note 1.   teaspot 所需要用的gpu-mem 比較大....請把gpu mem 設到128M....   sudo raspi-config -> Advanced option -> ....

note 2.   我有使用 wiringPi 的library....請先安裝 wiringPi  ....  http://wiringpi.com/


Reference 2 : http://blog.oscarliang.net/use-gy80-arduino-adxl345-accelerometer/

Reference 3 : http://howthingsfly.si.edu/flight-dynamics/roll-pitch-and-yaw

OpenGL on Raspberry





Reference : https://jan.newmarch.name/LinuxSound/Diversions/RaspberryPiOpenGL/

Raspberry Pi SPI and I2C Tutorial -> using wiringPi




Reference : https://learn.sparkfun.com/tutorials/raspberry-pi-spi-and-i2c-tutorial

using wiringpi to access adxl345 on raspberry



為了速度....所以把 python code 轉成  c code....

但可能bottle-neck 還是在i2c 的protocol 上面


安裝wiringPi 請參考這篇  安裝wiringPi

wiringPi 使用I2C 請參考這篇wiringPi use i2c

 compile 的指令如下:

 gcc -Wall -o adxl345 main.cpp adxl345.cpp -lwiringPi
 sudo ./adxl345 

sample code 如下:
main.cpp
=======================
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPiI2C.h>
#include <string.h>
#include "./adxl345.h"


int main (void)
{
int fd_adxl345 ;
struct  acc_dat  gdata ;
 fd_adxl345 = wiringPiI2CSetup(0x53);
  //printf("%d",fd_adxl345);

  ADXL345 adxl345(fd_adxl345);
  gdata = adxl345.getAxes(true);

  printf("x : %f g\n",gdata.x);
  printf("y : %f g\n",gdata.y);
  printf("z : %f g\n",gdata.z);
}

=======================


adxl345.h
==============================
#ifndef  __ADXL345
#define __ADXL345

#include <wiringPiI2C.h>
#include <math.h>
#include <stdio.h>

#define EARTH_GRAVITY_MS2    9.80665
#define SCALE_MULTIPLIER     0.004

#define DATA_FORMAT          0x31
#define BW_RATE              0x2C
#define POWER_CTL            0x2D

#define BW_RATE_1600HZ       0x0F
#define BW_RATE_800HZ        0x0E
#define BW_RATE_400HZ        0x0D
#define BW_RATE_200HZ        0x0C
#define BW_RATE_100HZ        0x0B
#define BW_RATE_50HZ         0x0A
#define BW_RATE_25HZ         0x09

#define RANGE_2G             0x00
#define RANGE_4G             0x01
#define RANGE_8G             0x02
#define RANGE_16G            0x03

#define MEASURE              0x08
#define AXES_DATA            0x32


struct acc_dat{
        double x;
        double y;
        double z;
};

class ADXL345{

public:
    int FD_ADDR;
    ADXL345(int addr);
    void enableMeasurement();
    void setBandwidthRate(int rate_flag);
    void setRange(int range_flag);
    //struct acc_dat getAxes(bool gforce = false);
    struct acc_dat getAxes(bool gforce);
};

#endif
================================================
adxl345.cpp

#include "./adxl345.h"

ADXL345::ADXL345(int addr)
{
    FD_ADDR = addr;
    setBandwidthRate(BW_RATE_100HZ);
    setRange(RANGE_2G);
    enableMeasurement();

}
void ADXL345::enableMeasurement()
{
     wiringPiI2CWriteReg8(FD_ADDR,POWER_CTL,MEASURE);
}

void ADXL345::setBandwidthRate(int rate_flag)
{
     //printf("%d",rate_flag);
     wiringPiI2CWriteReg8(FD_ADDR,BW_RATE,rate_flag);
}

void ADXL345::setRange(int range_flag)
{
        int value;
        value = wiringPiI2CReadReg8(FD_ADDR, DATA_FORMAT);
        value &= ~0x0F;
        value |= range_flag;
        value |= 0x08;

//        printf("set range value : %d",value);
        wiringPiI2CWriteReg8(FD_ADDR, DATA_FORMAT, value);
}

struct acc_dat ADXL345::getAxes(bool gforce = false)
{
        double dx,dy,dz;
        struct acc_dat dat;
        int x,y,z;
        char bytes[6];
        bytes[0] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA);
        bytes[1] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+1);
        bytes[2] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+2);
        bytes[3] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+3);
        bytes[4] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+4);
        bytes[5] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+5);

        //printf("%d\n",bytes[0]);
        //printf("%d\n",bytes[1]);
        x = bytes[0] | (bytes[1] << 8);
        if(x & (1<<15))
            x = x - (1<<16);
        //printf("%d\n",x);

        y = bytes[2] | (bytes[3] << 8);
        if(y & (1<<15))
            y = y - (1<<16);

        z = bytes[4] | (bytes[5] << 8);
        if(z & (1<<15))
            z = z - (1<<16);

        dx = (double)x * SCALE_MULTIPLIER;
        dy = (double)y * SCALE_MULTIPLIER;
        dz = (double)z * SCALE_MULTIPLIER;

        if (gforce == false)
        {
            dx = dx * EARTH_GRAVITY_MS2;
            dy = dy * EARTH_GRAVITY_MS2;
            dz = dz * EARTH_GRAVITY_MS2;
        }
        dat.x = (dx);
        dat.y = (dy);
        dat.z = (dz);

        return dat;
}
=============================================

2016年2月25日 星期四

安裝其他的web browser



Firefox


介紹

Iceweasel是一個網路瀏覽器,是Mozilla Firefox瀏覽器的Debian再發布版。<取自WIKI>

安裝步驟



$ sudo apt-get install iceweasel 

Chromium

介紹

Chromium 是一款由Google 所主導的輕量瀏覽器,為Google發展自家的瀏覽器Google Chrome而開啟的計畫,所以Chromium相當於Google Chrome的工程版或稱實驗版

安裝步驟

$ sudo apt-get install chromium
如果遇過error,請先嘗試以下動作
$ sudo apt-get update
reference : http://hengxiuxu.blogspot.tw/2014/09/raspberry-pi.html

unrar 強化版



Raspberry Pi 樹莓派 強化版的解rar工具 unrar-nonfree

相信大家在下載東西的時候有遇過xxx.part1.rar, xxx.part2.rar, ......這種東西吧,而Raspberry本身的unrar對這東西又很無力......,因此筆者打算裝上unrar-nonfree版本

1. 刪除unrar-free (2014年的Raspbian預設沒有安裝,因此不用再刪除)
sudo apt-get remove unrar-free
2. 修改apt的source list
sudo vi /etc/apt/sources.list
# Source repository to add deb-src http://archive.raspbian.org/raspbian wheezy main contrib non-free rpi
3. 更新apt資料庫
sudo apt-get update
4. 準備unrar-nonfree的資料夾,我們準備要從原始碼建置他
mkdir unrar-nonfree pi@ShiunPiSnd ~ $ cd unrar-nonfree
5. 安裝相依套件
sudo apt-get build-dep unrar-nonfree
6. 下載unrar-nonfree的原始碼並建置成deb檔
sudo apt-get source -b unrar-nonfree
7. 安裝unrar-nonfree的deb套件
sudo dpkg -i unrar*.deb
8. 接著只要解壓縮part1就可以解開全部part了,另外要輸入密碼也沒有問題~
unrar x xxx.part1.rar
Reference : http://alenshiun.blogspot.tw/2014/05/raspberry-pi-rar-unrar-nonfree.html

2016年2月24日 星期三

wiringpi to access i2c



Before you can use the I2C interface, you may need to use the gpio utility to load the I2C drivers into the kernel:
gpio load i2c

如果訊息如下:  要去  把   device-tree 的功能關掉....




sudo raspi-config  ->Advance options ->  Device tree disable  and I2C enable

sudo reboot

再輸入一次  ...看看能不能用
gpio load i2c

如果訊息如下....就代表可以


他抓到的 裝置為   /dev/i2c-1


如果要確定i2c 的裝置有沒有連上去...可以打

i2cdetect -y 1
可以看到i2c 的 device number


可以看到目前i2c 的裝置號碼為 0x53.....(AXDL345)


gpio load i2c 1000
will set the baud rate to 1000Kbps – ie. 1,000,000 bps. (K here is times 1000)


sample code 如下:  以   grove rgb lcd 為例子
==================================================

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPiI2C.h>   // 要多加這個函式庫
#include <string.h>


class rgb_lcd {
     public:
     rgb_lcd(int fd_rgb, int fd_text);
      int FD_RGB_ADDR ;
      int FD_TEXT_ADDR ;
      void setRGB(int r,int g,int b);
      void textCommand(int cmd);
      void setText(char* text);
};

rgb_lcd::rgb_lcd(int fd_rgb, int fd_text)
{
    FD_RGB_ADDR = fd_rgb;
    FD_TEXT_ADDR = fd_text;
}

void rgb_lcd::setRGB(int r ,int g ,int b)
{
      wiringPiI2CWriteReg8(FD_RGB_ADDR,0,0);
      wiringPiI2CWriteReg8(FD_RGB_ADDR,1,0);
      wiringPiI2CWriteReg8(FD_RGB_ADDR,0x08,0xaa);
      wiringPiI2CWriteReg8(FD_RGB_ADDR,4,r);
      wiringPiI2CWriteReg8(FD_RGB_ADDR,3,g);
      wiringPiI2CWriteReg8(FD_RGB_ADDR,2,b);
}

void rgb_lcd::textCommand(int cmd)
{
    wiringPiI2CWriteReg8 (FD_TEXT_ADDR, 0x80, cmd) ;
}

void rgb_lcd::setText(char *text)
{
        textCommand(0x01); // clear display
        delay(50);
        textCommand(0x08 | 0x04); // display on, no cursor
        textCommand(0x28);// 2 lines
        delay(50);
        int count = 0;
        int row = 0;
        //for c in text:
        int lens = strlen(text);
        for(int i =0;i< lens;i++)
        {
            char c = text[i];
            if ( (c == '\n') || (count == 16))
            {
               count = 0;
               row += 1;
               if (row == 2)
                  break;
               textCommand(0xc0);
               if(c == '\n')
                  continue;
            }
            count++;
            wiringPiI2CWriteReg8(FD_TEXT_ADDR,0x40,c);
        }
}


int main (void)
{
  int  fd_rgb, fd_text;
  int DISPLAY_RGB_ADDR = 0x62;
  int DISPLAY_TEXT_ADDR = 0x3e;
  fd_rgb  = wiringPiI2CSetup(DISPLAY_RGB_ADDR);
  fd_text = wiringPiI2CSetup(DISPLAY_TEXT_ADDR);

  if(fd_rgb==-1){
       printf("I2C setup error");
      return 0;}

  if(fd_text==-1){
       printf("I2C setup error");
       return 0;  }

 rgb_lcd  lcd(fd_rgb,fd_text);
  lcd.setRGB(128,128,128);
  lcd.setText("Hello world");
}


Reference : http://wiringpi.com/reference/i2c-library/

2016年2月23日 星期二

using wiringPi to implement ultrasonic function



有關於wiringPi 的安裝和執行  請參考這篇   wiringPi

然後我發覺我超音波做不出來的原因是因為我理解錯誤....

參考timing diagram



重點是要去數  第三列的pulse為高電位的時間......


int ultrasonic_read(_pin){
        unsigned int  start_time,end_time,duraction;
        pinMode (_pin, OUTPUT) ;
        digitalWrite (_pin, LOW) ;
        delayMicroseconds(3);
        digitalWrite (_pin, HIGH) ;
        delayMicroseconds(11);
        digitalWrite (_pin, LOW);
        pinMode (_pin, INPUT) ;
        while(digitalRead(_pin)==LOW)
            delayMicroseconds(1);
        start_time = micros();
        while(digitalRead(_pin)==HIGH)
            delayMicroseconds(1);
        end_time = micros();
        if(start_time > end_time)
           duraction = (unsigned int)4294967295 - end_time + start_time;
        else
           duraction = end_time - start_time;
        return (0.17 * duraction);
}

把跑出來的資料plot 出來....結果就像下圖一樣




wiringPi in raspberry



安裝

sudo apt-get install git-core
sudo apt-get update
sudo apt-get upgrade
git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
cd wiringPi
./build

pin  圖:
   wiringPi  定義的腳位和RPI的腳位不一樣...舉個例子....

GPIO14 (Txd) ->  wiringPi  15

所以這裡要特別注意





  • Pins 171819 and 20: (BCM_GPIO 28, 29, 30 and 31) These are additional GPIO pins on the Rev. 2 board.

sample code:

#include <wiringPi.h>
int main (void)
{
  int pin_num = 0;
  wiringPiSetup () ;
  pinMode (pin_num, OUTPUT) ;
  for (;;)
  {
    digitalWrite (pin_num, HIGH) ; delay (500) ;
    digitalWrite (pin_num,  LOW) ; delay (500) ;
  }
  return 0 ;
}
 then to compile and run, you would enter:
gcc -Wall -o blink blink.c -lwiringPi
sudo ./blink

如果線有接對....應該會亮了....

Reference : http://wiringpi.com/

2016年2月21日 星期日

show chinese font on raspberry


1.
sudo apt-get -y install ttf-wqy-zenhei

2.

sudo apt-get -y install ttf-wqy-microhei

3.

sudo apt-get -y install fonts-arphic-ukai

4.

sudo apt-get -y install ttf-arphic-uming

2016年2月20日 星期六

在Raspberry 上面使用GPS module


好一陣子沒有在玩 Raspberry Pi 了,由於網友詢問這類問題剛好手上有GPS模組所以找了空檔寫了這篇希望能有所幫助。
一般GPS大概都是透過非同步式串列介面(UART)作為訊號傳遞連結,模組與Raspberry Pi連結就是透過高低電位的TTL方式使用UART介面來傳遞,通常運用到模組上的RX,TX 兩條訊號線及VCC/GND (這裡的VCC是供電給GPS模組使用的)。
模組上你可能會看到還有VBAT這是外接電池使用或者每家開發商會有不同的定義其他腳位,這個部分就得要看所買到的GPS模組Datasheet了。

至於GPS模組中還要注意的是協議部分,常見的GPS模組內建協議包括NMEA-0183、 SiRF binary、RTCM SC-104等格式,這些協議格是可以透過AT命令進行切換,本篇文章則以常見的NMEA為主,好處是讀取道的資訊是一般的明碼,我們取來應用比較方便。


實作Raspberry Pi 整合 GPS 模組有兩種方式,一種是透過TTL方式直接跟IO接腳的第8腳UART TX及第10腳UART RX連結(方案一),另外就是GPS模組透過 USB to TTL Adapter Cable連接到Raspberry Pi 的 USB上面(方案二)。詳細接線圖如下:

注意  (usb2TTL)TX -> 對方的RX...
         (usb2TTL)RX -> 對方的TX...

USB2TTL 的綠色為TX...
                   白色為RX...



1. Python
在寫程式的前置動作必須先安裝 python 的 serial 函式庫,執行下列指令:
sudo apt-get install python-serial

接著用編輯器編輯一個檔案名稱為 gps.py 的程式,其內容如下:
import serial

def getdata(port):
# open the serial port
    port.open()
# check that the port is open
    if port.isOpen():
# read 16 lines
        line = []
        for i in range(1,16):
            line.append(port.readline())
# close the serial port
    port.close()
# discard the first line (sometimes it contains rubbish, so just always discard it)
    del line[0]
# return the list of lines
    return line

def outputdata(data):
# print the list of lines
    for i in range(0,len(data)):
        print data[i]

def initialise():
# initialise serial port settings
    Port = serial.Serial()
    Port.baudrate = 9600              //鮑率(Baud Rate)
    Port.port = '/dev/ttyAMA0'       //如接USB的話改成dev/ttyUSB0
    Port.xonxoff = 1
# return the port as an object we can use
    return Port

# main program starts here
sPort = initialise()
data = getdata(sPort)
outputdata(data)
# end

執行結果:
使用指令:
sudo python gps.py
結果如下:



接下來就是要研究這些資訊室做甚麼的.....

This is the raw GPS "NMEA sentence" output from the GPS module. There are a few different kinds of NMEA sentences, the most common ones people use are the $GPRMC (Global Positioning Recommended Minimum Coordinates or something like that) and the $GPGGA sentences. These two provide the time, date, latitude, longitude, altitude, estimated land speed, and fix type. Fix type indicates whether the GPS has locked onto the satellite data and received enough data to determine the location (2D fix) or location+altitude (3D fix).

For more details about NMEA sentences and what data they contain, check out this site


Something that starts with $GPRMC like:
Copy Code
  1. $GPRMC,194509.000,A,4042.6142,N,07400.4168,W,2.03,221.11,160412,,,A*77
This line is called the RMC (Recommended Minimum) sentence and has pretty much all of the most useful data. Each chunk of data is separated by a comma.
The first part 194509.000 is the current time GMT (Greenwich Mean Time). The first two numbers 19 indicate the hour (1900h, otherwise known as 7pm) the next two are the minute, the next two are the seconds and finally the milliseconds. So the time when this screenshot was taken is 7:45 pm and 9 seconds. The GPS does not know what time zone you are in, or about "daylight savings" so you will have to do the calculation to turn GMT into your timezone

The second part is the 'status code', if it is a V that means the data is Void (invalid). If it is an A that means its Active (the GPS could get a lock/fix)
The next 4 pieces of data are the geolocation data. According to the GPS, my location is 4042.6142,N (Latitude 40 degrees, 42.6142 decimal minutes North) & 07400.4168,W. (Longitude 74 degrees, 0.4168 decimal minutes West) To look at this location in Google maps, type +40° 42.6142', -74° 00.4168' into the google maps search box . Unfortunately gmaps requires you to use +/- instead of NSWE notation. N and E are positive, S and W are negative.

People often get confused because the GPS is working but is "5 miles off" - this is because they are not parsing the lat/long data correctly. Despite appearances, the geolocation data is NOT in decimal degrees. It is in degrees and minutes in the following format: Latitude: DDMM.MMMM (The first two characters are the degrees.) Longitude: DDDMM.MMMM (The first three characters are the degrees.)
The next data is the ground speed in knots. We're going 2.03 knots
After that is the tracking angle, this is meant to approximate what 'compass' direction we're heading at based on our past travel
The one after that is 160412 which is the current date (this sentence was first 'grabbed' on 16th of April, 2012).
Finally there is the *XX data which is used as a data transfer checksum
Once you get a fix using your GPS module, verify your location with google maps (or some other mapping software). Remember that GPS is often only accurate to 5-10 meters and worse if you're indoors or surrounded by tall buildings.

Reference : http://cheng-min-i-taiwan.blogspot.tw/2014/03/raspberry-pi-gps.html

Reference : https://github.com/mcauser/Raspberry-Pi-ITead-Studio-GPS-NEO-6M

Reference : https://learn.adafruit.com/adafruit-ultimate-gps-hat-for-raspberry-pi/pi-setup

2016年2月19日 星期五

在Raspberry 上面使用ADXL345



Step 1: Setting up the Raspberry pi for the ADXL 345

ADXL 345 pin out 圖

 RPI GPIO 圖

The ADXL345 supports both I2C and SPI connections, I used I2C, which requires some configuration on the Pi:
使用I2C 來連線.....

Use the GPIO diagram above to help with the wiring
GND - GND 
3V - 3V3
SDA - SDA
SCL - SCL
check 一下系統有沒有把I2C關掉

Add the I2C modules to the Pi's configuration:
sudo nano /etc/modules
Then add the following lines:
i2c-bcm2708
i2c-dev
Remove I2C from the blacklist:
sudo nano /etc/modprobe.d/fbdev-blacklist.conf
Change this:
blacklist i2c-bcm2708
To this:
#blacklist i2c-bcm2708
Reboot to make the changes:
sudo reboot

Step 2: Installing the Stuff


You will need to install smbus:
sudo apt-get install python-smbus i2c-tools git-core
Now test the ADXL345 is found on the I2C bus by running:
sudo i2cdetect -y 1

看的出來address 0x53的地方有device....

如果沒有看到0x53...代表你線接錯了...或是i2c關掉了

Now download from
不太會使用gitcore.....  所以我從網頁右上角有個 Download Zip..... 按下... 然後用ftp 傳到RPI...


cd adxl345-python-master
Then write:
sudo python example.py
If you get 0.000G for all axis then something probably isn't set up correctly.

看一下  example.py
from adxl345 import ADXL345

adxl345 = ADXL345()

axes = adxl345.getAxes(True)
print "ADXL345 on address 0x%x:" % (adxl345.address)
print "   x = %.3fG" % ( axes['x'] )
print "   y = %.3fG" % ( axes['y'] )
print "   z = %.3fG" % ( axes['z'] )

解釋如下 :



#import the adxl345 module
import adxl345
#create ADXL345 object 
accel = adxl345.ADXL345()
#get axes as g 
axes = accel.getAxes(True) 
# to get axes as ms^2 use  
axes = accel.getAxes(False)
#put the axes into variables 
x = axes['x'] 
y = axes['y'] 
z = axes['z']
#print axes 
print x 
print y 
print z
Change the program for fun!
The default range is 2g which means that the maximum G the ADXL345 can measure is 2.048, but at a high degree of sensitivity.
You can change the sensitivity of the ADXL345 by using the .setRange() method of the class.

這邊還有另外一個sample code

Firstly download their file from:
From there download the User manual(Super Kit for Pi) and the Code and Frizting(Super kit for Pi)

會看到兩個code ...


也是可以參考一下......  

Reference : http://www.instructables.com/id/how-to-use-the-ADXL345-on-Raspberry-pi/