« Outlookアドインの改良?版 | トップページ | Raspberry piでLazarusを使ってIoT »

2017.02.05

Raspberry piでC#を使ってIoT

「Outlookアドインを作成する」の記事でRaspberry piでIoTの実験うんぬんの話をしていましたが、さわりをまとめてみます。
Raspberry piにmonoをインストールして.NET環境を整えて、テストプログラムはVisual stdio 2015 communityで行って作成した実行ファイルをRaspberry piに転送して実行します。

Windows7上の実行状況
Win7screen

上記の実行ファイルをそのままRaspberry piで実行
Raspiscreen

といった感じです。
RaspberryのIO入力を処理するため、Windows上では基本動作の確認だけを行い、問題がないようであればRaspberry piにフォルダー毎コピーして動作テストを行っています。

このテストプログラムはADコンバータMPC3208の8チェンネルデータをタイマー時間毎に読み込んでMQTTブローカーにデータを流します。

#それにしてもRaspberry piでの処理時間が遅いこと・・・私の環境ではデータ読み込みサイクルが最短で200ms弱ですので、とてもリアルタイム入力とは言えません・・・

using System;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;
using uPLibrary.Networking.M2Mqtt; // MQTTパッケージ (NuGet)
using uPLibrary.Networking.M2Mqtt.Messages;
using Raspberry.IO.GeneralPurpose; // GPIOアクセス用パッケージ
using Raspberry.IO.Components.Converters.Mcp3208; // ADC MCP3208用パッケージ
using Raspberry.IO;
 
 
namespace Publisher
{
    public partial class Mainform : Form
    {
        private MqttClient Client; // MQTTオブジェクト
        const ConnectorPin adcClock = ConnectorPin.P1Pin23; // MCP3208制御用定数宣言
        const ConnectorPin adcMiso = ConnectorPin.P1Pin21;
        const ConnectorPin adcMosi = ConnectorPin.P1Pin19;
        const ConnectorPin adcCs = ConnectorPin.P1Pin24;
        private GpioConnectionDriver driver;
        private Mcp3208SpiConnection adcConnection;
        private Mcp3208Channel chan1, chan2, chan3, chan4, chan5, chan6, chan7, chan8;
        private bool Mcp3208 = false;
        private DateTime PrevDT;
 
        public Mainform()
        {
            InitializeComponent();
        }
 
        private void Mainform_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (Client != null)
            {
                Client.Disconnect();
                Client = null;
            }
            if (Mcp3208)
            {
                adcConnection.Close();
                adcConnection = null;
                driver = null;
            }
        }
 
        //チャンネルステータスの変更
        private void ON1_CheckedChanged(object sender, EventArgs e)
        {
            if (Stop_btn.Enabled) 
            {
                timer1.Enabled = CH1.Checked | CH2.Checked | CH3.Checked | CH4.Checked
                               | CH5.Checked | CH6.Checked | CH7.Checked | CH8.Checked;
            }
        }
 
        // ADC MCP3208からのデータ読み込み
        private string ReadMCP3208(Mcp3208Channel Ch)
        {
            AnalogValue p;
            decimal points;
            p = adcConnection.Read(Ch);
            // 一旦128bit精度の実数値にして、それを文字列に変換する
            points = p.Value;
            return points.ToString();
        }
        // インターバルタイマー割り込み
        private void timer1_Tick(object sender, EventArgs e)
        {
            string dat, data;
            DateTime dt;
            TimeSpan tgap;
            double mgap;
 
            // 今回読み出し時間と、前回読み出し時からの経過時間をミリ秒で取得する
            dt = DateTime.Now;
            tgap = dt - PrevDT;
            mgap = tgap.Seconds * 1000 + tgap.Milliseconds;
            PrevDT = dt;
            // 読み出し年月日時間, 経過時間, CH1, CH2, CH3, Ch4, CH5. CH6. CH7, CH8
            // のフォーマットで読み出しデータを文字列化していく
            data = dt.ToString("yyyy/MM/dd hh:mm:ss.fff") + "," + mgap.ToString() + ",";
            if (CH1.Checked)
            {
                dat = ReadMCP3208(chan1);
                Data1.Text = dat;
                data += dat;
            }
            data += ","; // カンマ区切り
            if (CH2.Checked)
            {
                dat = ReadMCP3208(chan2);
                Data2.Text = dat;
                data += dat;
            }
            // 以下CH8まで続く
            // :
            // 作成した8チャンネル分のデータ文字列をPublishする
            Client.Publish(Topic.Text, Encoding.UTF8.GetBytes(data), MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false);
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {   // MCP3208ドライバを作成し接続する
                driver = new GpioConnectionDriver();        // GPIOドライバーオブジェクト
                adcConnection = new Mcp3208SpiConnection(   // MCP3208オブジェクト
                                    driver.Out(adcClock),
                                    driver.Out(adcCs),
                                    driver.In(adcMiso),
                                    driver.Out(adcMosi));
                chan1 = Mcp3208Channel.Channel0; // 8チャンネル分
                chan2 = Mcp3208Channel.Channel1;
                chan3 = Mcp3208Channel.Channel2;
                chan4 = Mcp3208Channel.Channel3;
                chan5 = Mcp3208Channel.Channel4;
                chan6 = Mcp3208Channel.Channel5;
                chan7 = Mcp3208Channel.Channel6;
                chan8 = Mcp3208Channel.Channel7;
                Mcp3208 = true;
            }
            catch
            {
                MessageBox.Show("Cannot open the SPI.", "Error", MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return;
            }
 
            // MQTTクライアントを作成
            Client = new MqttClient(BrokerIP.Text);
            string clientId = Guid.NewGuid().ToString();
            try
            {
                Client.Connect(clientId);
                timer1.Enabled = CH1.Checked | CH2.Checked | CH3.Checked | CH4.Checked
                               | CH5.Checked | CH6.Checked | CH7.Checked | CH8.Checked;
                Start_btn.Enabled = false;
                Stop_btn.Enabled = true;
            }
            catch
            {
                MessageBox.Show("Cannot connect to MQTT Broker.", "Error", MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
            PrevDT = DateTime.Now;
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                timer1.Enabled = false;
                Client.Disconnect();
                Client = null;
                driver = null;
                adcConnection.Close();
                adcConnection = null;
                Status.Text = "Status: OFF";
                Start_btn.Enabled = true;
                Stop_btn.Enabled = false;
            }
            catch
            {
                ;
            }
        }
    }
}

|

« Outlookアドインの改良?版 | トップページ | Raspberry piでLazarusを使ってIoT »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: Raspberry piでC#を使ってIoT:

« Outlookアドインの改良?版 | トップページ | Raspberry piでLazarusを使ってIoT »