目的:
WEB画面から raspberry pi に 接続した LED の PWM制御による 調光 を行う。
php から Cプログラム へ メッセージキュー を使用したプロセス間通信を使用する。
環境/構成:
環境/構成は、
WEB から LED ON/OFF
と同じ。
プロセス間通信については、WEB から LED ON/OFF ( php - C言語 間通信 ) を参照。
PWM制御については、C言語で LED 調光 (PWM 制御) を参照。
phpファイル(WEB画面):
WEB画面は、ESP32/arduino:LED調光_スライダーで明るさを調整
、2
と同じ画面。
<?php $QKEY = 1111; $QUEUE = msg_get_queue($QKEY, 0666); session_start() ; if ($_SESSION['led_val'] == NULL ) $_SESSION['led_val'] = 0 ; if ($_GET['led_v'] != NULL) { $_SESSION['led_val'] = $_GET['led_v'] ; msg_send($QUEUE, "1111", "set_ledval " . $_SESSION['led_val'] . "\0" , FALSE) ; } if ($_GET['led_s'] != NULL) { $_SESSION['led_val'] = $_GET['led_v'] ; msg_send($QUEUE, "1111", "set_ledval " . $_SESSION['led_val'] . "\0" , FALSE) ; } if ($_GET['on'] == "ON") { $_SESSION['led_val'] = "255" ; msg_send($QUEUE, "1111", "led_on\0" , FALSE) ; } if ($_GET['off'] == "OFF") { $_SESSION['led_val'] = "0" ; msg_send($QUEUE, "1111", "led_off\0" , FALSE) ; } $led_brightness = $_SESSION['led_val'] ; ?> <!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'> <style>input.button {margin:8px;width:100px;} input.button2 {margin-left:8px; width:40px;} input.text {margin-left:8px; width:25px;} input.slid {width:230px;} div {font-size:16pt;text-align:center;width:250px;border:solid 4px #93ff93;} </style> <title>Color LED Controller</title></head> <body> <div><p>LED ON/OFF</p> <form method='get' style='text-align:left' > <span style='padding-left:15pt; font-size:8pt ;text-align:left'> LED brightness (0-255)</span> <input class='text' type='text' name='led_v' id='led_v' value=<?=$led_brightness?> > <input class='button2' type='submit' name='set' value='SET'> </form> <form name='slidform' method='get' style='text-align:left'> <input class='slid' type='range' name='led_s' value=<?=$led_brightness?> min='0' max='255' step='1' onchange='setval(this.value)' oninput='setval(this.value)' > </form> <form method='get'> <input class='button' type='submit' name='on' value='ON'><input class='button' type='submit' name='off' value='OFF'><br> </form> </div> <script> function setval(ledval){ var xhr = new XMLHttpRequest(); xhr.open('get', 'pwm_resp.php?slid='+ledval ); xhr.timeout = 1000 ; xhr.setRequestHeader('Cache-Control', 'no-cache'); xhr.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhr.responseType = 'document' ; xhr.onreadystatechange = function() { if( (xhr.readyState == 4) && (xhr.status == 200) ) { document.getElementById('led_v').value = xhr.response.getElementById('output1').innerHTML; } } xhr.ontimeout = function(e) { xhr.abort() ; } xhr.send(); } </script> </body> </html>
<?php $led_brightness = $_GET['slid'] ; $QKEY = 1111; $QUEUE = msg_get_queue($QKEY, 0666); msg_send($QUEUE, "1111", "set_slidval " . $led_brightness . "\0" , FALSE) ; ?> <!DOCTYPE html><html lang='ja'> <head> <title>Color LED Controller</title></head> <body> <output id='output1'> <?=$led_brightness?> </output> </body> </html>
処理の流れ:
- php 本体では、各 GET 要求を受けたとき、メッセージキューに LED 操作のコマンドを送信する。また、HTML 中の変数($led_brightness) に値を設定する。
- HTML中の変数($led_brightness) は、php のショートタグ( <?=*** ?> ) を使用して値に置き換える。
- スライダー操作時は、javascript で XHRを使用して 値を XHRレスポンス用 php に送信する。
- XHR レスポンス用 php では、送信された値を受け、メッセージキューに LED 操作のコマンドを送信し、受信した値をそのままレスポンスとして返す。ここでは、HTML(テキスト) でレスポンスを返している。
各処理の内容については、上述の参照ページを参照。
Cプログラム(LED調光):
Cプログラムは、
WEB から LED ON/OFF ( php - C言語 間通信 )
の LED ON, OFF を PWM制御 (
C言語で LED 調光 (PWM 制御)
) に置き換えたものとなる。
プログラムを以下に示す。
プログラムを以下に示す。
#include <wiringPi.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <termios.h> #include <fcntl.h> // ***************************************************************************** // * 定義等 * // ***************************************************************************** // メッセージキュー 用 定義 ---------------------------------------------------- #define BUFFSIZE 256 // バッファサイズ #define QKEY (key_t)1111 // メッセージキューの key // struct msgbuf{ // メッセージの構造体 long int type; // type は long int であること。 char data[BUFFSIZE]; // }; // // // LED ON/OFF 用 定義 ---------------------------------------------------------- #define led_pin 12 // LED を接続する GPIO # // // ***************************************************************************** // * キーイベントの取得 * // ***************************************************************************** // int kbhit(void) { // struct termios oldt, newt; // int ch; // int oldf; // // tcgetattr(STDIN_FILENO, &oldt); // newt = oldt; // newt.c_lflag &= ~(ICANON | ECHO); // tcsetattr(STDIN_FILENO, TCSANOW, &newt); // oldf = fcntl(STDIN_FILENO, F_GETFL, 0); // fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); // // ch = getchar(); // // tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // fcntl(STDIN_FILENO, F_SETFL, oldf); // // if (ch != EOF) { // ungetc(ch, stdin); // return 1; // } // // return 0; // } // // // ***************************************************************************** // * メイン 関数 * // ***************************************************************************** int main() { // int msqid; // メッセージキュー ID struct msgbuf message; // メッセージ long int read_type = 0 ; // リードするメッセージタイプ char c ; // 1文字入力用 char buf[128] ; // キーボード入力用のバッファ int p_buf = 0 ; // 入力位置 char *cmd ; // コマンド用バッファ char *prm1 ; // パラメータ1用バッファ int val = 0 ; // 設定値 // // メッセージキューの作成,取得 ----------------------------------------------- // 誰でも読み書き可能なキューを作成して、ID を取得する -- errno = 0; // if( ( // msqid = msgget(QKEY, 0666 | IPC_CREAT) // 0666:アクセス許可パラメータ ) == -1 ) { // perror("msgget failure"); // 作成失敗時の処理 exit(EXIT_FAILURE); // } // // // wiringpi の設定 ----------------------------------------------------------- wiringPiSetupGpio() ; // pinMode (led_pin, PWM_OUTPUT) ; // LED 調光 pwmSetMode(PWM_MODE_MS) ; // PWM モード設定 pwmSetClock(40) ; // PWM 分周比設定(レンジ当たりのクロック数) pwmSetRange(255) ; // PWM 分解能設定(1周期当たりのレンジ数) // // メッセージを受信して LED の ON/OFF を行う --------------------------------- while(1){ errno = 0 ; // if (!(msgrcv( msqid, &message, BUFFSIZE, // メッセージの受信 read_type, IPC_NOWAIT) == -1) // ) // { // メッセージ受信時の処理 // メッセージをコマンドとパラメータに分割 -// cmd = strtok(message.data, " ") ; // 最初の文字列(" "まで) をコマンド prm1 = strtok(NULL, " ") ; // 次の文字列を パラメータ1 printf("command : %s %s\n",cmd,prm1); // 表示 // if (strcmp(cmd,"led_on") == 0) { // LED ON pwmWrite(led_pin, 256) ; // LED 調光値設定(ON : 256) } // if (strcmp(cmd,"led_off") == 0) { // LED OFF pwmWrite(led_pin, 0 ) ; // LED 調光値設定(OFF : 0) } // if (strcmp(cmd,"set_ledval") == 0) { // LED 調光値設定 val = atoi (prm1) ; // パラメータ1 を数値に変換 pwmWrite(led_pin, val) ; // LED 調光値設定 } // if (strcmp(cmd,"set_slidval") == 0) { // LED スライダー値設定 val = atoi (prm1) ; // パラメータ1 を数値に変換 pwmWrite(led_pin, val) ; // LED 調光値設定 } // }else{ // 受信失敗時 if (errno != ENOMSG) { // メッセージ無し以外は終了 printf("msgrcv : errno = %x\n",errno) ; // break ; // } // } // // キーイベントを取得し、入力文字列が "exit" ならループを終了する。---------- if (kbhit()) { // c = getchar() ; // 入力された文字を表示 printf("%c",c) ; // if ( c == '\n' ) { // リターン入力時 if ( strcmp(buf,"exit") == 0 ) { // "exit" を入力ならループ終了 break ; // } else { // "exit" でなければ、先頭に戻る p_buf = 0 ; // buf[p_buf] = '\0' ; // } // } else { // リターンでなければ、 if (p_buf == 255) p_buf = 0 ; // バッファサイズを超える時は先頭へ buf[p_buf] = c ; // バッファに入力文字を追加 buf[p_buf + 1] = '\0' ; // p_buf++ ; // 入力位置を +1 } // } // } // // // メッセージキューを削除して終了 ---------------------------------------------- errno = 0; // if(msgctl(msqid, IPC_RMID, NULL) == -1){ // perror("msgctl failure"); // exit(EXIT_FAILURE); // } // // exit(EXIT_SUCCESS); // // } // // //
メッセージキューに送信されたコマンドに従い、LED の値 を設定する。
本プログラムを sudo 付きで実行し、WEB から 上述のphp(html) を開いて 操作すると、スライダーに応じて LED の明るさが変わる。
端末から "exit(rtn)" を入力すると プログラムは停止する。
0 件のコメント:
コメントを投稿