6
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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
10
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
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?