作成日時:2015年06月20日 20時46分25秒
更新日時:2020年05月19日 08時43分03秒
この記事は9年ほど前に投稿されました。内容が古くなっている可能性がありますので更新日時にご注意ください。
以前、Raspberry Pi 2 で複数桁の7セグLED制御 を実行しましたが、この処理はメイン処理系でLED表示を無限ループさせていました。しかし、これでは7セグLEDを表示している場合に他の処理ができなかったり、逆に他の処理をしている際にLEDの表示が止まるという感じで少々不便でしたね。
そこで今回はそのLED表示部分をマルチスレッド化して別処理にしてみたいと思います。
注意
上記の記事の応用編なのでその記事を先に読んでください。
なお、最後のソースコードのGPIOポートは当方の事情によりLEDの接続ポートが変わっております。ご注意ください。
なお、この記事では作成した実機通りのピン配列にしていますが。後になってGPIOの「8・9」番ポートに何かが接続されていると、Raspberry Piが起動しない(シリアル通信をしようとして失敗する?)という現象が発生しましたので。LED_1・LED_2は別のポートを使ったほうがいいかもしれません。(2つずらして10・11・12を使えば問題ありません。)
接続
元記事の通りですが、今回GPIOポートを変更しました。
変更前
// LEDポート設定(GPIO.x)
#define LED_A 29
#define LED_B 28
#define LED_C 27
#define LED_D 26
#define LED_E 25
#define LED_F 24
#define LED_G 23
#define LED_P 22
#define LED_1 1 // 1桁目
#define LED_2 2 // 2桁目
#define LED_3 3 // 3桁目
変更後
// LEDポート設定(GPIO.x)
#define LED_A 0
#define LED_B 1
#define LED_C 2
#define LED_D 3
#define LED_E 4
#define LED_F 5
#define LED_G 6
#define LED_P 7
#define LED_1 8
#define LED_2 9
#define LED_3 10
変更理由
この配列だと、LED表示制御に digitalWriteByteコマンドが利用できるためです。
(使ってませんが。)
コーディング
まずは必要なライブラリをインクルードします。
#include <pthread.h> // マルチスレッド化
次に、マルチスレッド化する命令を抜き出します。
今回は数字を表示するための命令を抜き出しました。
void* LED_SND(void* args){
for(;;){
int n=num,n1=0,n2=0,n3=0;
n3 = (n%10);n/=10;
n2 = (n%10);n/=10;
n1 = (n%10);n/=10;
if (num < 100) n1=17;
if (num < 10 ) n2=17;
LED_SET(n1,0,1);
delay(2);
LED_SET(n2,0,2);
delay(2);
LED_SET(n3,1,3);
delay(2);
}}
※この関数は実際に使用する前に記述しないとエラーになります。
void main(){ hogehoge関数でスレッドを作成 }
void hogehoge(){ 何らかの処理 }
↑コンパイルエラーが出る
↓正しい記述方法
void hogehoge(){ 何らかの処理 }
void main(){ hogehoge関数でスレッドを作成 }
num変数をグローバル変数として定義します。(関数外にint num;を記述するだけ)
#define LED_3 10
int num; ←例えばこんなかんじに
void* LED_SND(void* args){ ←変数
main変数にて上記関数をスレッド化
pthread_t led_th;
pthread_create(&led_th,NULL,LED_SND,(void *)NULL);
これで後はnum変数の数値を変えるだけでLEDの表示が変更され、LEDを表示していてもメイン処理がLED表示に邪魔されなくなりました。
以下、numを1000まで順に表示していくコードを貼り付けておきます。
#include <stdio.h>
#include <wiringPi.h>
#include <stdlib.h>
#include <pthread.h> // マルチスレッド化
// LEDポート設定(GPIO.x)
#define LED_A 0
#define LED_B 1
#define LED_C 2
#define LED_D 3
#define LED_E 4
#define LED_F 5
#define LED_G 6
#define LED_P 7
#define LED_1 8
#define LED_2 9
#define LED_3 10
int num;
void* LED_SND(void* args){
for(;;){
int n=num,n1=0,n2=0,n3=0;
n3 = (n%10);n/=10;
n2 = (n%10);n/=10;
n1 = (n%10);n/=10;
if (num < 100) n1=17;
if (num < 10 ) n2=17;
LED_SET(n1,0,1);
delay(2);
LED_SET(n2,0,2);
delay(2);
LED_SET(n3,1,3);
delay(2);
}
}
int main(void){
wiringPiSetup();
pinMode(LED_A,OUTPUT);
pinMode(LED_B,OUTPUT);
pinMode(LED_C,OUTPUT);
pinMode(LED_D,OUTPUT);
pinMode(LED_E,OUTPUT);
pinMode(LED_F,OUTPUT);
pinMode(LED_G,OUTPUT);
pinMode(LED_P,OUTPUT);
pinMode(LED_1,OUTPUT);
pinMode(LED_2,OUTPUT);
pinMode(LED_3,OUTPUT);
LED_SET(3,0,1);
delay(200);
LED_SET(9,0,2);
delay(200);
LED_SET(6,0,3);
delay(200);
LED_SET(8,0,1);
delay(200);
LED_SET(7,0,2);
delay(1000);
pthread_t led_th;
pthread_create(&led_th,NULL,LED_SND,(void *)NULL);
time_t timer;struct tm *local;struct tm *utc;
for(;;){
num++;
delay(300);
if(num==1000)num=0;
}
}
int LED_SET(int num,int dot,int keta){
// セグメント定義
int seg[18][7] ={{1,1,1,1,1,1,0}, // 0
{0,1,1,0,0,0,0}, // 1
{1,1,0,1,1,0,1}, // 2
{1,1,1,1,0,0,1}, // 3
{0,1,1,0,0,1,1}, // 4
{1,0,1,1,0,1,1}, // 5
{1,0,1,1,1,1,1}, // 6
{1,1,1,0,0,0,0}, // 7
{1,1,1,1,1,1,1}, // 8
{1,1,1,1,0,1,1}, // 9
{1,1,1,0,1,1,1}, // A
{0,0,1,1,1,1,1}, // B(b)
{0,0,0,1,1,0,1}, // C(c)
{0,1,1,1,1,0,1}, // D(d)
{1,0,0,1,1,1,1}, // E
{1,0,0,0,1,1,1}, // F
{0,0,0,0,0,0,1}, // -
{0,0,0,0,0,0,0}};// Blank
digitalWrite(LED_1,0);
digitalWrite(LED_2,0);
digitalWrite(LED_3,0);
if(keta==1){digitalWrite(LED_1,1);}
if(keta==2){digitalWrite(LED_2,1);}
if(keta==3){digitalWrite(LED_3,1);}
digitalWrite(LED_A,seg[num][0]);
digitalWrite(LED_B,seg[num][1]);
digitalWrite(LED_C,seg[num][2]);
digitalWrite(LED_D,seg[num][3]);
digitalWrite(LED_E,seg[num][4]);
digitalWrite(LED_F,seg[num][5]);
digitalWrite(LED_G,seg[num][6]);
digitalWrite(LED_P,dot);
}