LoginSignup
6
9

More than 5 years have passed since last update.

C言語でpigpio.hを使う(raspberry pi-pigpio_if2.h)

Last updated at Posted at 2018-04-18

はじめに

pigpio.hはraspberry pi3のGPIOピンを使ってデバイスの制御をサポートします。
pigpio.hの利点や何が出来るのか等は先駆者の方々やリファレンスに書いてあるのでそちらを参照してください。
では、なぜ投稿するのか?
―pigpio.hを使っている方がほとんどpyhonを使っているのでC言語で作ったコードを投稿しとこうと、まぁメモ程度です。

・pigpio library
http://abyz.me.uk/rpi/pigpio/

pigpioライブラリの初期設定

※最近のバージョンだと最初から設定されています。

・インストール
sudo apt-get install pigpio

・サービスの設定
$ sudo vi /lib/systemd/system/pigpiod.service
[Unit]
Description=Gpio daemon
[Service]
ExecStart=/usr/bin/pigpiod -l
ExecStop=/bin/systemctl kill pigpiod
Type=forking
[Install]
WantedBy=multi-user.target

・サービスの起動
$ sudo systemctl start pigpiod  (起動)
$ sudo systemctl enable pigpiod (有効化)

pigpioを使う

・初期化
pi = pigpio_start(0, 0);
・解放
pigpio_stop(pi);

中身も書こうと思ったが種類が多いので下記に書いたコードを載せる
(面倒になったわけではな・・・)

サンプルコード

pigpio.hとpigpio.cppは自身で作ったヘッダーとクラス
pigpiod_if2.hはpigpioライブラリを使うためのヘッダー

pigpio.h

//--------------------------------------------------
// Pigpioヘッダファイル
// (CLCDは動作しません-残してる理由は個人的にあり)
//-------------------------------------------------

class Pigpio
{
private:
    int pi;
    //int clcd_i2c;
    int ina226_i2c; 
    void moterInit();           // pwm制御モータ
    void buttonInit();          // プッシュボタン
    void lightInit();           // 3色ledデバイス
    //void clcdInit();          // キャラクタディスプレイ
    void ina226Init();          // 電圧測定デバイス
public:
    Pigpio();
    ~Pigpio();
    void moterFreq(int gpio, int freq);                 // PWM周波数変更
    void moterMove(int num, int r_duty, int l_duty);    // モータ使用
    void moterIdol();                                   // モータ停止
    void buttonPush();                                  // ボタン押下
    void lightIndicator(int mode);                      // 3色表示灯点灯
    void lightFlashing(int mode);                       // 3色表示灯点滅
    void lightClear();                                  // 3色表示灯消灯
    //int clcdCheck();
    //void clcdPrint(char *str, int row, int col);
    //void clcdCursor(int n);
    //void clcdClear();
    //void clcdWrite(unsigned char rs, unsigned char data);
    float Voltage();                                    // 電圧測定
    void pigpioStop();                                  // 終了処理
};

pigpio.cpp

//--------------------------------------------------------
// pigpio_if2 を使用しているメソッドをまとめたクラス
//--------------------------------------------------------

#include "pigpio.h"                     // 作製したヘッダー
#include "pigpiod_if2.h"                // pigpioライブラリを使うためのヘッダー
#include <unistd.h>
#include <iostream>

// GPIOピン(番号は任意)
#define RIGHT_MOTER_CW  5
#define RIGHT_MOTER_CCW 13
#define RIGHT_MOTER_PWM 6
#define LEFT_MOTER_CW   20
#define LEFT_MOTER_CCW  19
#define LEFT_MOTER_PWM  21
#define PUSHBUTTON      22
#define GREEN           10
#define YELLO           11
#define RED             9

#define CLCD_ADDRS      0x50
#define INA226_ADDRS    0x40

#define RANGE           100
#define MOTOR_FREQ      10000   // 10kHz(周波数)

Pigpio::Pigpio()
{
    pi = pigpio_start(0, 0);
    moterInit();
    buttonInit();
    lightInit();
    //clcdInit();
    ina226Init();
}

Pigpio::~Pigpio()
{
    pigpioStop();
}

// 初期化--------------------------------------------------------
// モータ初期化
void Pigpio::moterInit()
{
    set_mode(pi, RIGHT_MOTER_CW, PI_OUTPUT);
    set_mode(pi, RIGHT_MOTER_CCW, PI_OUTPUT);
    set_mode(pi, RIGHT_MOTER_PWM, PI_OUTPUT);
    set_mode(pi, LEFT_MOTER_CW, PI_OUTPUT);
    set_mode(pi, LEFT_MOTER_CCW, PI_OUTPUT);
    set_mode(pi, LEFT_MOTER_PWM, PI_OUTPUT);

    set_PWM_range(pi, RIGHT_MOTER_PWM, RANGE);
    set_PWM_range(pi, LEFT_MOTER_PWM, RANGE);

    set_PWM_frequency(pi,RIGHT_MOTER_PWM,MOTOR_FREQ); // 周波数指定
    set_PWM_frequency(pi,LEFT_MOTER_PWM,MOTOR_FREQ);

    set_PWM_dutycycle(pi,RIGHT_MOTER_PWM,50); // デューティー比の指定
    set_PWM_dutycycle(pi,LEFT_MOTER_PWM,50);

    moterIdol();
}

// 3色表示灯初期化
void Pigpio::lightInit()
{
    set_mode(pi, GREEN, PI_OUTPUT);
    set_mode(pi, RED, PI_OUTPUT);
    set_mode(pi, YELLO, PI_OUTPUT);

    lightClear();
}

//ボタン
void Pigpio::buttonInit()
{
    set_mode(pi, PUSHBUTTON, PI_INPUT);
}

// clcd初期化 (hyoujisarenai)
/*
void Pigpio::clcdInit(){
    clcd_i2c = i2c_open(pi, 1, CLCD_ADDRS, 0);
    clcdWrite(0x00, 0x01);
    clcdWrite(0x00, 0x38);
    clcdWrite(0x00, 0x0c);
    clcdWrite(0x00, 0x06);
}
*/

// INA226初期化
void Pigpio::ina226Init(){
    ina226_i2c = i2c_open(pi, 1, INA226_ADDRS, 0);
    i2c_write_word_data(pi, ina226_i2c, 0x0, 0x4EDF);
    i2c_write_word_data(pi, ina226_i2c, 0x5, 0x0A00);
}

// モータ----------------------------------------------------------
// PWM周波数変更
void Pigpio::moterFreq(int gpio, int freq)
{
    set_PWM_frequency(pi,gpio,freq);
}

// モータ使用
void Pigpio::moterMove(int num, int r_duty, int l_duty)
{
    set_PWM_dutycycle(pi,RIGHT_MOTER_PWM,r_duty);
    set_PWM_dutycycle(pi,LEFT_MOTER_PWM,l_duty);

    switch(num){
        case 1:     // 前進
            gpio_write(pi,RIGHT_MOTER_CW,1);
            gpio_write(pi,RIGHT_MOTER_CCW,0);
            gpio_write(pi,LEFT_MOTER_CW,1);
            gpio_write(pi,LEFT_MOTER_CCW,0);
            break;
        case 2:     // 後退
            gpio_write(pi,RIGHT_MOTER_CW,0);
            gpio_write(pi,RIGHT_MOTER_CCW,1);
            gpio_write(pi,LEFT_MOTER_CW,0);
            gpio_write(pi,LEFT_MOTER_CCW,1);
            break;
        case 3:     // 右回転
            gpio_write(pi,RIGHT_MOTER_CW,1);
            gpio_write(pi,RIGHT_MOTER_CCW,0);
            gpio_write(pi,LEFT_MOTER_CW,0);
            gpio_write(pi,LEFT_MOTER_CCW,1);
            break;
        case 4:     // 左回転
            gpio_write(pi,RIGHT_MOTER_CW,0);
            gpio_write(pi,RIGHT_MOTER_CCW,1);
            gpio_write(pi,LEFT_MOTER_CW,1);
            gpio_write(pi,LEFT_MOTER_CCW,0);
            break;
        default:
            break;
    }
}

// モータ停止
void Pigpio::moterIdol()
{
    gpio_write(pi,RIGHT_MOTER_CW,0);
    gpio_write(pi,RIGHT_MOTER_CCW,0);
    gpio_write(pi,LEFT_MOTER_CW,0);
    gpio_write(pi,LEFT_MOTER_CCW,0);
}

// Button-----------------------------------------------------------
void Pigpio::buttonEnd()
{
    if(gpio_read(pi, PUSHBUTTON) != 1){
        // 処理
    }
}

// 3色表示灯-----------------------------------------------------------
void Pigpio::lightIndicator(int mode)
{
    lightClear();
    int coler = (mode==0)? GREEN : (mode==1||mode==2)? YELLO : RED;
    gpio_write(pi, coler, PI_ON);
}

void Pigpio::lightFlashing(int mode)
{
    int coler = (mode==0)? GREEN : (mode==1||mode==2)? YELLO : RED;
    if(gpio_read(pi,coler)) gpio_write(pi, coler, PI_OFF);
    else gpio_write(pi,coler, PI_ON);
}

void Pigpio::lightClear()
{
    gpio_write(pi, GREEN, PI_OFF);
    gpio_write(pi, RED, PI_OFF);
    gpio_write(pi, YELLO, PI_OFF);
}

// CLCD (ACM1602NI-FLW-FBW)--------------------------------------------
// 動作しない.
/*
int Pigpio::clcdCheck(){
    return clcd_i2c;
}

void Pigpio::clcdPrint(char *str, int row, int col){
    int char_cnt = 0;
    int place[2] = {0x00, 0x40};
    if(col > 16) col = 16;

    if(clcd_i2c < 0){
        clcdCursor(place[row] + col);
        while(char_cnt < 16 && str[char_cnt]){
            clcdWrite(0x80, str[char_cnt]);
            char_cnt++;
        }
    }
}

void Pigpio::clcdCursor(int n){
    clcdWrite(0x00, 0x80 | n);
}

void Pigpio::clcdClear(){
    clcdWrite(0x00, 0x01);
}

void Pigpio::clcdWrite(unsigned char rs, unsigned char data){
    usleep(20);
    i2c_write_byte_data(pi, clcd_i2c, rs, data);
}
*/

// INA226--------------------------------------------------------------

// 電圧測定
float Pigpio::Voltage()
{
    unsigned short data_vol = 0;
    double voltage = 0.0;
    float per = 0.0;
    if(ina226_i2c < 0) return -1;

    const double maxVoltage = 27.16f;
    data_vol = i2c_read_word_data(pi, ina226_i2c, 0x2);
    data_vol = (data_vol >> 8) | (data_vol << 8);
    voltage = data_vol * 1.25f;

    return voltage;
}

// 終了処理------------------------------------------------------------
void Pigpio::pigpioStop(){
    moterIdol();
    i2c_close(pi, ina226_i2c);
    //i2c_close(pi, clcd_i2c);
    pigpio_stop(pi);
}

おわりに

完全に個人メモです(笑)
使ったデバイスの名称とか載せてないし、細かいところも書いてないので質問があれば足していきます、、、
しばらく組み込み系からは離れるます(raspberry4が出たら趣味では触りそう)

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9