概要
しばらく検討出来なくなりますので、途中ですが状況を投稿しておきます。少し時間が経つと、何がどこにあるかもすっかり忘れてしまいますので、とりあえず自分用の手がかりとして残しておきます。
下の図はRS232C通信でとあるデバイスを使って、データを取得しているフォーム(C#)状態です。正確に受信できていないケースもありますが、いつか修正したいと思います。
後半にはARDUINOでの取得例について記載します。
プログラム(C#)
未来の自分の為にプログラムを残します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace UTR_S201_COM_TEST01
{
public partial class Form1 : Form
{
string[] ports;
public string strReceive;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
ports = SerialPort.GetPortNames();
for (int ii = 0; ii < ports.GetLength(0); ii++) {
comboBox1.Items.Add(ports[ii]);
}
comboBox1.SelectedIndex = ports.GetLength(0) - 1;
if (serialPort1.IsOpen) { serialPort1.Close(); }
button2.BackColor = Color.Silver;
}
// COMポート開く
private void button2_Click(object sender, EventArgs e) {
string p_name = comboBox1.Text.Trim();
com_open(p_name);
}
//com_open
private void com_open(string p_name) {
if (serialPort1.IsOpen) {
serialPort1.Close();
button2.BackColor = Color.Silver;
return;
}
serialPort1.PortName = p_name;
serialPort1.BaudRate = 115200; //, //変調回数(1秒あたり)
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8; // 1変調あたりのbit数
serialPort1.StopBits = StopBits.One;
serialPort1.NewLine = "\r";
serialPort1.ReadTimeout = 1000;
serialPort1.WriteTimeout = 1000;
//serialPort1.Handshake = Handshake.None;
//serialPort1.DtrEnable = false;
//serialPort1.RtsEnable = false;
//serialPort1.DataReceived += serialPort_DataReceived; // データ受信イベント
serialPort1.Open();
button2.BackColor = Color.Yellow;
}
// フォーム閉じる
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
if (serialPort1.IsOpen) { serialPort1.Close(); }
}
// データ送信ボタン
private void button1_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen) {
MessageBox.Show("ポートが閉じています。", "ポート閉");
return;
}
int cmd_n = int.Parse(textBox2.Text.Trim());
SerialPort_DataSend(cmd_n);
cmd_n ++ ;
if (cmd_n > 5) {
cmd_n = 0;
}
this.textBox2.Text = cmd_n.ToString();
}
// データ送信
private void SerialPort_DataSend(int cmd_no) {
byte[] s_Data = std.S201_CMD[cmd_no];
int byt_l = s_Data.Length;
int chk_e = s_Data[byt_l - 1];
int cmd_sum = 0;
if (chk_e != 3) { return; }
byte[] tr_dt = new byte[byt_l + 2];
for (int ii = 0; ii < byt_l; ii++) {
tr_dt[ii] = s_Data[ii];
cmd_sum += s_Data[ii];
}
tr_dt[byt_l] = (byte)(0xFF & cmd_sum);
tr_dt[byt_l + 1] = 0x0d;
serialPort1.Write(tr_dt, 0, byt_l + 2);
}
// ■■■ 参考1によるデータ受信 ■■■
// シリアルポート データ受信イベント
// [ com_open ] 内で定義必要 → serialPort1.DataReceived += serialPort_DataReceived;
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e){
SerialPort seriPort = (SerialPort)sender;
int readByteS = seriPort.BytesToRead; // 受信データ長取得
if (readByteS > 0) {
byte[] buff = new byte[readByteS];
seriPort.Read(buff,0,readByteS);
strReceive = "";
for (int i = 0; i < buff.Length; i++) {
strReceive += string.Format("{0:X2}", buff[i]) ;
strReceive += " " ;
}
strReceive = strReceive.Trim() ;
serialPort1.DiscardInBuffer(); // 入力バッファークリア
if (this.InvokeRequired) {
this.Invoke(new Action(this.UpdateText));
} else {
this.textBox1.Text += strReceive + Environment.NewLine;
}
}
}
// 受信データ表示
private void UpdateText() {
textBox1.AppendText(strReceive);
string l_str = strReceive.Substring(strReceive.Length - 2);
if (l_str == "0D") { textBox1.AppendText(Environment.NewLine); }
}
// ■■■ 参考2によるデータ受信 ■■■
private delegate void Delegate_RcvDataToTextBox(string data);
// データ受信イベント
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort seriPort = (SerialPort)sender;
int readByteS = seriPort.BytesToRead; // 受信データ長取得
if (readByteS > 0)
{
byte[] buff = new byte[readByteS];
seriPort.Read(buff, 0, readByteS);
strReceive = "";
for (int i = 0; i < buff.Length; i++)
{
strReceive += string.Format("{0:X2}", buff[i]);
strReceive += " ";
}
string data = strReceive.Trim();
//serialPort1.DiscardInBuffer(); // 入力バッファークリア
if (this.InvokeRequired){
Invoke(new Delegate_RcvDataToTextBox(RcvDataToTextBox), new Object[] { data });
} else {
this.textBox1.Text += strReceive + Environment.NewLine;
}
}
}
//受信データをテキストボックスに設定する
private void RcvDataToTextBox(string data) {
if (data != null) {
string d_trim = data.Trim();
string l_str = d_trim.Substring(d_trim.Length - 2);
if (l_str == "0D"){
textBox1.AppendText(d_trim);
textBox1.AppendText(Environment.NewLine);
} else {
textBox1.AppendText(data);
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UTR_S201_COM_TEST01
{
public static class std
{
public static byte[][] S201_CMD = new byte[][] {
new byte[]{ 0x02, 0x00, 0x4F, 0x01, 0x00, 0x03 } ,
new byte[]{ 0x02, 0x00, 0x4F, 0x01, 0x90, 0x03 } ,
new byte[]{ 0x02, 0x00, 0x4E, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03 } ,
new byte[]{ 0x02, 0x00, 0x55, 0x02, 0x41, 0x01, 0x03 } ,
new byte[]{ 0x02, 0x00, 0x55, 0x0B, 0x31, 0x01, 0x1F, 0xCE, 0x81, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03 } ,
new byte[]{ 0x02, 0x00, 0x4E, 0x07, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 } ,
new byte[]{ 0x02, 0x00, 0x4E, 0x07, 0x00, 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03 }
}
}
ARDUINO受信例
配線接続
ARDUINOプログラム
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX,TXの割り当て
// 設定コマンド
uint8_t CMD[6][18]={
{ 0x02,0x00,0x4F,0x01,0x00,0x03,0x55,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },
{ 0x02,0x00,0x4F,0x01,0x90,0x03,0xE5,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } ,
{ 0x02,0x00,0x4E,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x5A,0x0D,0xFF,0xFF,0xFF,0xFF } ,
{ 0x02,0x00,0x55,0x02,0x41,0x01,0x03,0x9E,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } ,
{ 0x02,0x00,0x55,0x0B,0x31,0x01,0x1F,0xCE,0x81,0x02,0x00,0x00,0x00,0x00,0x02,0x03,0x09,0x0D } ,
{ 0x02,0x00,0x4E,0x07,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0x03,0xBF,0x0D,0xFF,0xFF,0xFF,0xFF } ,
};
// 初期設定
void setup() {
Serial.begin(115200); // シリアルモニタ出力
mySerial.begin(115200); // ソフトウェアシリアル通信開始
int cn_fct = sizeof(CMD[0]) ;
int cn_cmd = sizeof(CMD) / cn_fct ;
uint8_t buf_tmp[ cn_fct ] ;
for(int i = 0 ; i < cn_cmd ; ++i ){
for(int j = 0 ; j < cn_fct ; ++j ){ buf_tmp[j] = CMD[i][j];}
// コマンド送信
send_cmd_S201( buf_tmp , cn_fct );
delay(1);
// データ受信
String rcvDat="";
while(mySerial.available() > 0){
int val = mySerial.read() ;
String str = "00" + String(val , HEX);
str = str.substring(str.length() - 2) + " " ;
rcvDat += str;
if(val==13){
Serial.println(rcvDat);
break;
}
}
//if(i>=1){ break; }
delay(300);
}
Serial.println("");
Serial.println("START!");
}
// ■メイン処理■
void loop() {
// データ受信
String rcvDat="";
uint8_t rBuf[26];
int rcv_cn = 0;
int sum_ck = 0;
while(mySerial.available() > 0){
int val = mySerial.read() ;
if(rcv_cn < 26){ rBuf[rcv_cn] = val; }
if(rcv_cn < 24){ sum_ck += val; }
String str = "00" + String(val , HEX);
str = str.substring(str.length() - 2) + " " ;
rcvDat += str;
rcv_cn++;
if(val==13){
if(rcv_cn == 26){
sum_ck = sum_ck & 0xFF ;
if(rBuf[0]==2 && rBuf[23]==3 && rBuf[24]==sum_ck){
Serial.println(rcvDat);
}
}
break;
}
}
}
// データ送信
void send_cmd_S201(uint8_t * buf , int sz_bf){
for(int i = 0 ; i < sz_bf ; ++i ){
String str = "00" + String(buf[i] , HEX);
str = str.substring(str.length() - 2) ;
Serial.print(str);
Serial.print(" ");
mySerial.write(buf[i]);
if(buf[i]==0x0D || buf[i]==0xFF){ break; }
}
Serial.println("");
delay(100);
}
まとめ
いつか自分の役に立つことを願っています。