さくらのジャンク箱ロゴ

Sakura87がほぼ月刊でお届けするPCや電子工作と写真の備忘録てきなブログ @なんと20周年

Raspberry Pi 2 で複数桁の7セグLED制御(2) マルチスレッド化

この記事は9年ほど前に投稿されました。内容が古くなっている可能性がありますので更新日時にご注意ください。

IMG_4671

以前、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);
 
 }
総閲覧数:147 PV

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください