目的:
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
と同じ画面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | <? 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 > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <? 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 制御)
) に置き換えたものとなる。
プログラムを以下に示す。
プログラムを以下に示す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #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 件のコメント:
コメントを投稿