ラズパイ4 シリアル通信7セグLED表示

7セグメント LED表示

 今回は、Strawberry Linux社の 7セグメントLED表示器にシリアル通信で表示内容(アスキーコード)を送信し、連続的に表示を切り替える処理を確認します。
 この表示器選定理由は、数字認識の最終目的である表示器とサイズ・桁数等が近いこと。コネクタ,LED等を除き、おおよそはんだ付けが完了していることなどです。
 ラズパイはGPIOピン経由でシリアル通信出来るのだと思いますが、今回は同じく Strawberry Linux社 の 「FT232RX」 USBシリアル変換モジュールを使用して、USBポートを介して通信を行っています。これは、Windows PC からも使用できる様にするためです。
 次の写真が表示器(右)とシリアル変換モジュール(左)です。シリアル変換モジュールのUSBポートから、ラズパイ、もしくはパソコンにUSBケーブルで接続します。表示器と変換モジュール間接続は、手持ちピンソケット(2X5)を使いました。配線は表示器説明書に記載されているので省略します。

ラズパイとUSB接続

 Windowと接続する時は、ドライバーを別途ダウンロードし、インストールする必要がありましたが、Rasbian では不要の様です。接続前後に “ lsusb ” コマンドで接続状況を確認すると、接続後に赤枠部が追加されていることを確認しました。

 “/dev/ttyUSB0” も追加されています。これを、python でシリアルポートを開く時のポート番号として使用します。

 “ sudo apt-get install python-serial ” コマンドでシリアル通信ライブラリをインストールします。既に入っているとのことです。いつインストールしたのか記憶にありませんが・・・?

プログラム(python)

 次の python プログラムは表示器を全点灯/全消灯を数回繰り返した後、表示内容変更を数回行うものです。数字,ドット,一部のアルファベットが表示可能です。
 先ほど確認したポート番号 “/dev/ttyUSB0” を指定し、 シリアル通信ポートを開いています。(行番5)

import serial
import time

# シリアルポートを開く
ser = serial.Serial("/dev/ttyUSB0",9600)

# 点滅表示
num = 0
while num < 11 :
    if num % 2 == 1 :
        ser.write(b"8.8.8.8.8.8.8.8.\r")
    else :
        ser.write(b"\r")
    num += 1
    time.sleep(0.5)

# 数字変更処理
num = 0
while num < 11 :
    chr_cnt = 0
    while chr_cnt < 8 :
        dsp_n = (chr_cnt + num) % 10
        ser.write(bytes(str(dsp_n),'UTF-8'))
        chr_cnt += 1
    ser.write(b"\r")
    num += 1
    time.sleep(0.5)

# シリアルポート閉じる
ser.close
print("Program END")

 表示状況(動画)です。

  

Windows FT232RX ドライバー

 Windowsパソコンで「FT232RX」を使う場合、ドライバーがなく、利用できないことがありました。記憶に基づいて、その場合の設定方法を記載します。
 下記より、私の場合Win64ドライバーをダウンロードします。
 https://www.ftdichip.com/Drivers/VCP.htm

 対象デバイスを右クリック。「ドライバー更新」選択。

 コンピューターを参照しドライバー検索を選択します。
 フォルダー選択ダイアログが表示されるので、ドライバーダウンロード先のフォルダーを選択し、インストールします。

 

Windows の python で動かす 

 Windowsのpython で動かす方法を確認しています。
 既にWindowsパソコンに python はインストール済みなので、シリアル通信用ライブラリをインストールします。Windows コマンドプロンプトから、次の様に打込みインストールします。
 “python -m pip install pyserial”

 プログラムは同じですが、シリアルポートを開く際の指定ポート番号は異なります。下記は私の環境の場合です。

# シリアルポートを開く ※ポート番号は利用環境による
ser = serial.Serial("COM5",9600)

 私が参考させて頂いたサイトによるのですが、ラズパイでは apt-get を使い、Windows では pip を使ったので、少し違いを確認しました。 pipは、pythonモジュールリポジトリのPyPIから直接ダウンロード・インストールされるとのこと。一方、apt-getは、Ubuntuリポジトリからダウンロード・インストールされるとのことです。とりあえず、今回の利用目的に対してはどちらでも問題なさそうです。

 尚、ポート番号はデバイスマネージャーを開き、下記の通り確認することが出来ます。

Windows の C# で動かす 

 Windows Visual Studio C# でもプログラム作成しています。
 素人プログラマーで基礎が無いので、“アスキーコードをバイト型でシリアル通信する”といってもよく判りません。ということで、下記にプログラムを記載しておきます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SerComTest
{
    public partial class Form1 : Form
    {
        int flick_cnt;
        int flk_T_cnt;
        public Form1()
        {
            InitializeComponent();

            serialPort1.PortName = "COM5" ;                         // COMポート指定
            serialPort1.BaudRate = 9600 ;                           // 通信速度 9600 bps
            serialPort1.Parity = System.IO.Ports.Parity.None ;      // パリィティ無
            serialPort1.DataBits = 8 ;                              // データ長 8ビット
            serialPort1.StopBits = System.IO.Ports.StopBits.One ;   // ストップビット1ビット
            serialPort1.NewLine = "\r";                             // ReadLine,WriteLine末尾判定

            serialPort1.ReadTimeout = 1000 ;                        // 受信制限時間(msec)
            serialPort1.WriteTimeout = 1000 ;                       // 送信制限時間(msec)
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            flick_cnt = 0;
            flk_T_cnt = 0;
            timer1.Interval = 500;
            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
           
            if (flk_T_cnt < 21) 
            {   // 点滅表示
                if (flk_T_cnt % 2 == 0) { 
                    string res = disp_string(""); 
                }
                else { 
                    string res = disp_string("8.8.8.8.8.8.8.8."); 
                }

                flk_T_cnt += 1 ;
            } 
            else 
            {   // 切換表示
                string dsp_chr = "" ;

                for (int i = 0; i < 8; i++ ) {
                    int dsp_flk = (i + flick_cnt) % 10 ;
                    dsp_chr = dsp_chr + dsp_flk.ToString() ;
                }

                string res = disp_string(dsp_chr);

                flick_cnt += 1 ;

                // プログラム終了
                if (flick_cnt > 10) {
                    timer1.Enabled = false;
                    this.Close();
                    Application.Exit();
                }
            }
        }

        private string disp_string(string g_str) {
            string dsp_str = g_str;

            byte[] snd_data = new byte[ dsp_str.Length + 2 ]; 
            snd_data[0] = 0x15 ;                                    // [NAK,NegativeAcknowledge(否定応答)]
            snd_data[ dsp_str.Length + 1 ] = 0x0d ;                 // [CR,Carriage Return(復帰)]

            for (int i = 0; i < dsp_str.Length; i++)
            {
                string str_tmp = dsp_str.Substring(i, 1);
                char chr_tmp = Convert.ToChar(str_tmp);
                snd_data[i+1] = (byte)chr_tmp;
            }

            serialPort1.Open();
            serialPort1.Write(snd_data, 0 , snd_data.Length);
            serialPort1.Close();

            return g_str;
        }
    }
} 

  

まとめ

 シリアルコマンドによる7セグメント表示について、ラズパイ4(python),Win10(python),Win10(C#) と3方式について確認しました。