2016年9月12日 星期一

[Raspberry] 在Raspberry Pi 2 使用GPIO(三)

sudo –i    charge to root user  -->這樣就可root操作了嗎?

下載BCM2835套件,解壓縮後,進入資料夾
./configure   -->設定連結
make
sudo make check   -->編譯前檢查
sudo make install   -->編譯並進行安裝


程式:

#include <cstdlib>

#include <stdio.h>
#include <unistd.h>

#include <bcm2835.h>

#define PIN RPI_BPLUS_GPIO_J8_08

using namespace std;

int main(int argc, char** argv) {

    if(!bcm2835_init())
    {
        printf("err\r\n");
    }  
   
    bcm2835_gpio_fsel(PIN,BCM2835_GPIO_FSEL_OUTP);
   
    for(int i=1;i<10;i++)
    {
        bcm2835_gpio_write(PIN,HIGH);
        sleep(1);
        bcm2835_gpio_write(PIN,LOW);
        sleep(1);
    }
  
    return 0;
}


當編譯時,出現許多錯誤訊息
Undefined reference to bcm2835_init
Undefined reference to bcm2835_gpio_fsel ….

在NetBeans 視窗中,
選 Run -->Set Project Configuration -->Customize
在左邊選 Linker,右邊的 Libraries 點選加入(會出現 Debug-Libraries)
在右邊點選 Add Option 鈕(出現 Select Option)
選 checkbox Other Option ,輸入 “–lbcm2835”

跑程式,成功了!!





參考資料:

讓你的Raspberry Pi 透過 GPIO 閃爍 LED燈

Raspberry Pi –控制內建LED燈 PWR LED 和 ACT LED

Linux GPIO Driver Guide


RPi GPIO Code Samples

[How To Raspberry Pi] 使用C語言控制GPIO (安裝BCM2835套件)

Adding A Library To A NetBeans Project

[Raspberry] 在Raspberry Pi 2 使用GPIO(二)

程式:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>


using namespace std;


int pin=14;

void CloseExport()
{
    int fd;
    ssize_t byte_write;
    char buf[3];
   
    fd=open("/sys/class/gpio/unexport",O_WRONLY);
       
    if(fd==-1) printf("Failed to open unexport \r\n");
           
    byte_write=snprintf(buf,3,"%d",pin);
       
    if(write(fd,buf,byte_write)<0)   printf("Failed 1\r\n");
 
    close(fd);
}


int main(int argc, char** argv) {

    ssize_t byte_write0;

    int fd1;
   
    char buf0[3];
    fd1=open("/sys/class/gpio/export",O_WRONLY);
   
    if(fd1==-1) {  printf("failed to open export for writing\r\n");return -1;}
   
    byte_write0=snprintf(buf0,3,"%d",pin);
    if(write(fd1,buf0,byte_write0)<0)
    {
        close(fd1);
       
        printf("fail 0\r\n");    
   
        CloseExport();
   
        return-1;
       
    }
    close(fd1);

   
    int fd3;
    char buf1[35];
    snprintf(buf1,35,"/sys/class/gpio/gpio%d/direction",pin);
    fd3=open(buf1,O_WRONLY);
    if(fd3==-1)
    {  
        printf("failed to open gpio direction for writing\r\n");
       
        CloseExport();
     
        return-1;
    }
    if(write(fd3,"out",3)<0)
    {
        close(fd3);
       
        printf("Failed to set direction\r\n");
   
        CloseExport();
   
        return-1;
    }
    close(fd3);
   

    int fd5;
    char buf2[30];
   
    snprintf(buf2,30,"/sys/class/gpio/gpio%d/value",pin);
    fd5=open(buf2,O_WRONLY);
    if(fd5==-1)
    {
        printf("Failed to open gpio value for writing\r\n");
        CloseExport();
        return -1;
    }
   
    if(write(fd5,"1",1)<0)
    {
        close(fd5);
        printf("Failedto set 1");
        CloseExport();
        return -1;
    }
    close(fd5);

    sleep(1);
    printf("Success !!\r\n");
    CloseExport();
     
    return 0;
}

2016年9月11日 星期日

[Raspberry] 在Raspberry Pi 2 使用GPIO(一)

查看gpio的物理地址:
cat /proc/iomem |grep  gpio | grep gpio
3f2000000=3f20000b3 : /soc/gpio@7e200000                         

程式:

#include <cstdlib>

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define BCM2708_PERI_BASE 0x3F000000  //0x20000000 --> Raspberry Pi的位址
#define GPIO_BASE (BCM2708_PERI_BASE +0x200000) /* GPIO controller*/
#define PAGE_SIZE  (4*1024)
#define BLOCK_SIZE (4*1024)

int mem_fd;
void *gpio_map;

//IO access
volatile unsigned *gpio;

//GPIO setup macros. Always use INP_GPIO(x) before using 
//OUT_GPIO(x) or SET_GPIO_ALT(x,y) 
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

#define GPIO_SET *(gpio+7)  //sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) //clears bits which are 1 ignores bits which are 0
#define GET_GPIO(g) (*(gpio+13)&(1<<g)) //0 if Low, (1<<g) if High
#define GPIO_PULL *(gpio+37) //pull up/pull down

using namespace std;

void setup_io()
{
    if((mem_fd = open("/dev/mem",O_RDWR|O_SYNC))<0)
    {
        printf("Can not open /dev/mem \n");
        exit(-1);
    }
    
    //map GPIO
    gpio_map=mmap(
            NULL,                   //anyadress inourspace will do
            BLOCK_SIZE,             //map length
            PROT_READ|PROT_WRITE,   //enable reading & writting to mappedmemory
            MAP_SHARED,             //shared with other processes
            mem_fd,                 //fileto map
            GPIO_BASE               //offset to GPIOperipheral
            );
    
    close(mem_fd);      //No need to keep mem_fd open after map
    
    if(gpio_map==MAP_FAILED){
        printf("mmap error %d\n",(int)gpio_map);    //errnoalso set
        exit(-1);
    }   
    gpio=(volatile unsigned*)gpio_map;
}


int main(int argc, char** argv) {

    //set up gpi pointer for direct register access
    setup_io();

    printf("step 1 ok\r\n");    
    
    //MustuseINP_GPIO before we can use OUT_GPIO
    INP_GPIO(14);
    OUT_GPIO(14);

    for(int j=0;j<10;j++)
    {
        GPIO_SET=1<<14;
        sleep(1);
        GPIO_CLR=1<<14;
        sleep(1);
    }
        
    return 0;
}



開始跑出現 can not open /dev/mem,就停下來了

進入 NetBeans IDE 8.1 視窗
選擇 Run --> Set Project Configuration -->Customize…
左邊選擇Run,在右邊Run Command,加入 sudo
“${OUTPUT_PATH}” --> sudo “${OUTPUT_PATH}”      
成功運行了 !!!


[Raspberry] 在Raspberry Pi 2 使用GPIO

原來在終端機上,這樣就可操控 GPIO:

操控 UART的TX(先把 UART disable了)
echo 14 > /sys/class/gpio/export  -->設定可控制
echo out > /sys/class/gpio/gpio14/direction  -->輸出腳
echo 1 > /sys/class/gpio/gpio14/value  -->輸出1
echo 0 > /sys/class/gpio/gpio14/value  -->輸出0
echo 14 > /sys/class/gpio/unexport  -->取消建立出的 node


使用 GPIO readall 可看到 IO 的輸出(IN or out/0 or 1)



使用 debugfs 來觀看目前的GPIO設定
sudo mount –t debugfs   debugfs /sys/kernel/debug
mount:debugfs is already mounted or /sys/kernel/debug busy
sudo cat /sys/kernel/debug/gpio
GPIOs 0-53 platform/3f2000000.gpio  pinctrl-bcm2835:
gpio-14 (      |sysfs  )  out    hi
gpio-35 (      |?     )   in    hi 

gpio-47  (     |?    )   out   lo

2016年9月9日 星期五

[Raspberry] 在Raspberry Pi 2 使用 UART

確認Pi 沒有主控台控制權,如果有,先關閉

pi@raspberrypi:~ $ dmesg | grep tty
[    0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=1024 bcm2708_fb.fbheight=768 bcm2709.boardrev=0xa21041 bcm2709.serial=0xf1ba6d8 smsc95xx.macaddr=B8:27:EB:1B:A6:D8 bcm2708_fb.fbswap=1 bcm2709.uart_clock=48000000 bcm2709.disk_led_gpio=47 bcm2709.disk_led_active_low=0 vc_mem.mem_base=0x3dc00000 vc_mem.mem_size=0x3f000000  dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
[    0.001532] console [tty1] enabled
[    0.093340] 3f201000.uart: ttyAMA0 at MMIO 0x3f201000 (irq = 87, base_baud = 0) is a PL011 rev2
[    0.596998] console [ttyAMA0] enabled
[    4.446432] systemd[1]: Expecting device dev-ttyAMA0.device...
[    5.297264] systemd[1]: Starting system-serial\x2dgetty.slice.
[    5.319043] systemd[1]: Created slice system-serial\x2dgetty.slice.
pi@raspberrypi:~ $

關閉方式:
Sudo raspi-config
選 9 Advanced Options
選 A7 Serial  Enable/Disable shell and kernel messages on the serial connection ,關閉他 

Reboot後, dmesg | grep tty

pi@raspberrypi:~ $ dmesg | grep tty
[    0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=1024 bcm2708_fb.fbheight=768 bcm2709.boardrev=0xa21041 bcm2709.serial=0xf1ba6d8 smsc95xx.macaddr=B8:27:EB:1B:A6:D8 bcm2708_fb.fbswap=1 bcm2709.uart_clock=48000000 bcm2709.disk_led_gpio=47 bcm2709.disk_led_active_low=0 vc_mem.mem_base=0x3dc00000 vc_mem.mem_size=0x3f000000  dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
[    0.001516] console [tty1] enabled
pi@raspberrypi:~ $

關閉了

去查看 /dev/ttyAMA0 不見了(網路上的範例都是用這個PORT勒 !!!)
參考資料,第一二篇有寫了一大推解決方法……..太難了,看無


進入視窗,左上角 Menu -> Preferences -> Raspberry Pi Configuration ->Interfaces -> Serial --> Enable

Sudo apt-get install minicom  安裝軟體
sudo minicom –b 9600 –o –D /dev/ttyAMA0
切換至新視窗後,按鍵盤的Key,確認在示波器有看到輸出信號

gpio readall -- >check state of all pin
gpio mode 15 ALTO -->第8pin改成 ALTO state



程式:

Sudo chmod a+rw /dev/ttyAMA0  -->如果沒權限,就無法open port

#include <cstdlib>

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

using namespace std;

int main(int argc, char** argv) {
    //setup UART
    int uart_filestream=-1;
    uart_filestream=open("/dev/ttyAMA0",O_RDWR | O_NOCTTY | O_NDELAY);
    if(uart_filestream==-1)
    {
        printf("Unable to Open UART \r\n ");
        return 0;
    }
   
    //Configure UART
    struct termios options;
    tcgetattr(uart_filestream,&options);
    options.c_cflag=B9600 | CS8 | CLOCAL | CREAD;
    options.c_iflag=IGNPAR;
    options.c_oflag=0;
    options.c_lflag=0;
    tcflush(uart_filestream,TCIFLUSH);
    tcsetattr(uart_filestream,TCSANOW,&options);
   
    //Transmitting
    unsigned char tx_buf[10];
    unsigned char *p_buffer;  
    p_buffer=&tx_buf[0];
    *p_buffer++='O';
    *p_buffer++='I';
    *p_buffer++='A';
    if(uart_filestream !=-1)
    {
        int count=write(uart_filestream,&tx_buf[0],(p_buffer-&tx_buf[0]));
        if(count<0)
            printf("TX error \r\n");
    }
    
    close(uart_filestream);
    printf("finish\r\n");
    return 0;
}




參考資料:

Raspberry Raspbian turning off the UART functioning as a serial console


Serial(UART) communication on Raspberry Pi 2

Raspberry Pi 釋放主控台序列埠(GPIO14,GPIO15)

Using the UART (C語言)



[Raspberry] 在Raspberry Pi 2 使用 I2C

網路上找到的,Raspberry Pi2 Model B 40 Pin GPIO接腳圖,其中:GPIO3為 I2C SDA1,GPIO5 為 I2C SCL1,GPIO9為 GND

找到的資料有提及:
電流輸出的限制:每個接腳輸出最大為16mA,全部接腳同時最大輸出為50mA
GPIO為3.3V準位




pi@raspberrypi:~ $ lsmod   (檢查系統所載入的module)
Module                  Size  Used by
….
i2c_bcm2708             4834     0
…
i2c_dev                 5859     0


pi@raspberrypi:~ $ sudo  i2cdetect  –l  (列舉出系統上的I2C裝置)
i2c-1   i2c          3f804000.i2c   I2C adapter


pi@raspberrypi:~ $ sudo  i2cdetect  -y  1  (列出可用的slave address)
    0 1 2 3 4 5 6 7 8 9 a b c d e f
00:      -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- 14 -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- 55 -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                        


 pi@raspberrypi:~ $ sudo i2cget -y 1 0x55 0x2c   (讀取SOC low bte)
0x31
pi@raspberrypi:~ $ sudo i2cget -y 1 0x55 0x2d   (讀取SOC high bte)
0x00


pi@raspberrypi:~ $ sudo i2cdump -y 1 0x55
No size specified (using byte-data access)
        0 1   2   3   4  5  6  7  8    9 a    b   c  d    e  f
00: 00 00 00 00 ff 7f a6 0b 2a 0f c0 01 34 05 9f 0a    .....???*???4???
10: 34 05 9f 0a 00 00 ff ff 00 00 00 00 ff ff 00 00    4???............
20: ff ff 79 04 00 00 ff ff a6 0b 00 00 31 00 64 00    ..y?....??..1.d.
30: 00 00 34 05 00 00 00 00 00 00 00 00 be 0a 78 94    ..4?........??x?
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00    ........ .......
70: 00 00 c3 0b 00 00 55 00 00 00 00 00 00 00 00 00    ..??..U.........
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX


安裝 libi2c-dev (sudo apt-get install libi2c-dev)
有安裝就可使用 i2c_smbus_read_word_data 等眾多function,不然只有簡單 read/write 可用
如果有用 python,安裝 python-smbus


C的程式如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

using namespace std;

/*
*
*/
int main(int argc, char** argv) {
int file_i2c;
int length;
unsigned char buffer[100]={0};
char *filename=(char *)"/dev/i2c-1";    

//open the bus
if((file_i2c=open(filename,O_RDWR))<0)
{
    printf("Failed to openthei2c bus\n\r");
    return 0;
}
else
    printf("open /dev/i2c-1 ok!\r\n");

//setup slave address
int addr=0x55;
if(ioctl(file_i2c,I2C_SLAVE,addr)<0)
{
    printf("Failed to acquire bus acess and/or talk toslave");
    return 0;
}
else
    printf("setup slaveaddress to 0x55 ok!\r\n");


length=2;
if(read(file_i2c,buffer,length)!=length)  //not useful
{
    printf("Failed to read  from i2c bus\r\n");
    return 0;
}
else
    printf("Data read:%x %x\r\n",buffer[0],buffer[1]);


int dat;
dat=i2c_smbus_read_word_data(file_i2c,0x3e);
 if(dat<0)
 {
     printf("read failed\r\n");
 }
 else
 {
     printf("Data read:%lx \r\n",dat);
 }

printf("finish\n\r");  

close(file_i2c);

return 0;
}





不錯的參考資料
(1)   安裝編譯C/C++
[How To Raspberry Pi] 安裝 GCC
Raspberry Pi:在Pi 2與 Raspbian 上安裝NetBeansIDE,撰寫Java與C++ 程式

(2)安裝/啟動 I2C driver
I2C Installation for Raspberry Pi – Step by Step Guide
讓你的Raspberry Pi透過I2C讀取EEPROM

(3)參考文章:
Raspberry Pi:如何更新Raspbian
Raspberry Pi:Raspbian套件列表
Raspberry Pi安裝中文環境
http://yehnan.blogspot.tw/2012/08/raspberry-pi.html 
黑傑克的筆記
I2C Drivers, Part I
Interfacing an I2C GPIO expander(MCP23017) to the Raspberry Pu using C++(i2Cdev)
Using the I2C interface