前回unitv2でWEBページを作成し、そこにカメラ画像を埋め込むといった内容をまとめました。↓
一応私がやろうとしている事の目的が「unitv2でサーボモーターを動かしたい」になっていまして、頭の中では
unitv2(webサーバー)→js→python(cgi)→i2cでサーボモータードライバ制御
を考えていたのですが、いきなり頓挫する事になりました。もうみなさんご承知の通り、unitv2のgrove端子はi2cが使えません。。
なんでも「uart」と呼ばれるシリアル通信しか使えないようです。(uartって有名みたいですが私は初耳でございました。。)で、色々調べた結果、uartでサーボ制御は出来ない事はないけども少々厄介そうでしたので、一旦ラズパイを挟み、そこからi2cでサーボモーターを制御する事にしました。。
unitv2(webサーバー)→js→python(cgi)→uart→ラズパイ→i2cでサーボモータードライバ制御
はっきり言って意味ないですけどね(-_-;)ならunitv2いらないだろという話ですから。。
しかし、無駄な事でもunitv2から始まり最終的にサーボモーターを動かすことに意義があるのです!そう思わんとやってられんのです!uartのお勉強にもなるしね!
ということで、今回は一先ず「unitv2~ラズパイゼロまでのuart通信」についてまとめてみようかと思います。
まあここまではなにかしらで用途はあるかとも思いますので、少しでも参考になればうれしいです。
目次
初めに
unitv2のuartの罠
私はたまたまTwitterにて確認できていたので良かったですが、どうやらunitv2のuartのtxとrxの表記がテレコになっているみたいですね(;^ω^)
普通は送信ー送信、受信ー受信に繋げないですよね、これは結構大きな罠ですよね。
ですので、unitv2の場合uartのtxとrxは同じ端子同士で繋げる必要があります。とても重要なポイントですね。
tx — rx
rx — tx
gnd — gnd
uartは上のような感じでGND1つに送信と受信専用の回線を持った通信になります。一見全二重通信に見えますが、これで半二重通信をしているようです。
それでは、unitv2とラズパイゼロの電源を入れて、お互いをgroveケーブル(5Vは繋げない)で接続しておきます。
続いて、プログラムを記述していきます。
javascript
main.js
index.htmlと同じ階層に作成します。CGIでpythonを動かしたいので、Ajaxを使います。
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 |
$(function(){ let motor = "STOP"; // 「前進」ボタンが押されたときのイベント処理 $('#forward').click(function(event) { if(motor == "STOP") { $(this).addClass('ledon'); change_motor('FOWARD'); } else if(motor == "FOWARD") { $(this).removeClass('ledon'); motor = "STOP"; change_motor('STOP'); } }); // 「後退」ボタンが押されたときのイベント処理 $('#backward').click(function(event) { if(motor == "STOP") { $(this).addClass('ledon'); change_motor('BACKWARD'); } else if(motor == "BACKWARD"){ $(this).removeClass('ledon'); motor = "STOP"; change_motor('STOP'); } }); // 「右」ボタンが押されたときのイベント処理 $('#right').click(function(event) { if(motor == "STOP") { $(this).addClass('ledon'); change_motor('RIGHT'); } else if(motor == "RIGHT") { $(this).removeClass('ledon'); motor = "STOP"; change_motor('STOP'); } }); // 「左」ボタンが押されたときのイベント処理 $('#left').click(function(event) { if(motor == "STOP") { $(this).addClass('ledon'); change_motor('LEFT'); } else if(motor == "LEFT") { $(this).removeClass('ledon'); motor = "STOP"; change_motor('STOP'); } }); // 関数:モーターを動かすマクロ呼び出し function change_motor(typee) { motor = typee; if(typee == "FOWARD") { // 前進 //w().callMacro('FW'); console.log(typee); $.ajax({ url: 'cgi-bin/recieve.py', type: 'post', data: {name: 'hhhhh' } }).done(function(data){ console.log(data); }); } else if(typee == "BACKWARD") { //w().callMacro('BK'); console.log(typee); $.ajax({ url: 'cgi-bin/recieve.py', type: 'post', data: {name: 'iiii' } }).done(function(data){ console.log(data); }); } else if(typee == "RIGHT") { //w().callMacro('RT'); console.log(typee); $.ajax({ url: 'cgi-bin/recieve.py', type: 'post', data: {name: 'jjjj' } }).done(function(data){ console.log(data); }); } else if(typee == "LEFT") { //w().callMacro('LT'); console.log(typee); $.ajax({ url: 'cgi-bin/recieve.py', type: 'post', data: {name: 'kkkk' } }).done(function(data){ console.log(data); }); } else if(typee == "STOP") { //w().callMacro('ST'); console.log(typee); $.ajax({ url: 'cgi-bin/recieve.py', type: 'post', data: {name: 'ssss' } }).done(function(data){ console.log(data); }); } } }); |
htmlのボタンをクリックすれば、押したボタンを判別する為に適当に割り振った文字列をCGI(recieve.py)にpostしています。
続いてpythonスクリプト。
python
recieve.py
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#!/usr/bin/python3 import serial import cgi import time form = cgi.FieldStorage() recieve = form.getvalue('name') moji= recieve + '\r\n' uart_grove = serial.Serial('/dev/ttyS1', 115200, timeout=0.5) uart_grove.write(moji.encode('utf-8')) |
index.htmlと同じ階層にcgi-binディレクトリを作成し、その配下にrecieve.pyを作成します。
先頭にCGIで起動するようにシェバンを記述しています。
postされてきた文字列を受け取り、ttyS1(unitv2のシリアルポート)へボーレート115200で送信(write)しています。
今回記述していませんが、ラズパイからのデータを受信したい場合はreadを使います。
続いて、ラズパイ側のプログラムを記述します。
ラズパイ側のプログラム
python
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 |
import time import serial data3 = 'abc' ser = serial.Serial('/dev/ttyS0', 115200, timeout = 0.5) while True: #コマンドの結果を受信 time.sleep(0.1) data = ser.readline() #区切り文字0x0Aまでのデータを受信 data2 = data.strip().decode('utf-8') print(data2) if data2 == 'hhhhh' or data2 == 'iiii' or data2 == 'kkkk' or data2 =='jjjj': data3 = data2 if data3 == 'hhhhh': print('ff') elif data3 == 'jjjj': print("lf") elif data3 == 'kkkk': print('bk') elif data3 == 'iiii': print('rt') if data2 == 'ssss': print('st') |
適当な場所にpythonファイルを作成します。
ttys0がラズパイのシリアルポートになります。
ここからwhileのループに入りますが、これはunitv2からのデータをいつでも受け取れる状態にするためです。つまり、ラズパイ側でこのpythonプログラムを走らせておけば、unitv2からのuart通信をいつでも受信できる状態になります。
readlineで、unitv2からuartで送られてきたデータを受け取っています。
while文の中では、指定した文字列を受信した場合にprintで表示を出すようにしています。つまり、これで文字が表示されれば、unitv2からラズパイまでのuart通信が問題なく出来ているという事になります。
それでは、この時点で動作をチェックしてみます。
動作チェック
unitv2のindex.htmlがある階層に移動し、そこでpython http.serverを立ち上げます。
python -m http.server 8000 –cgi
ラズパイのpythonプログラムを起動させておきます。
python3 pythonファイル名
あとは、unitv2のローカルIP:8000にアクセスすれば確認できます。↓
次回は、サーボモーターを動かす前にLチカしてみようかと思います。
動作チェックの項目において、
“ラズパイのpythonプログラムを起動させておきます。
python3 pythonファイル名”
のところで、やり方がちょっと分かりませんから、説明させていただけないですか?
よろしくお願いいたします。
ラズパイでターミナルを起動し、作成したプログラムファイルを下記のように指定してやればプログラムが走ります。
python3 pythonファイル名
ラズパイPicoを使っていますので、やり方は同じでしょうか?
管理人です
picoはosが入ってませんのでターミナル操作が出来ません。
当記事と同じ事は出来ませんね。