質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

textbox

HTMLの<input type="text">で生成されるtextboxに関するタグです。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Q&A

解決済

2回答

4888閲覧

テキスト入力で16進数に変換されてしまう

ncncup

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

textbox

HTMLの<input type="text">で生成されるtextboxに関するタグです。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

0グッド

0クリップ

投稿2016/07/27 02:54

編集2016/07/27 04:39

こんにちは。ビジュアルスタジオでC#を使ってWindows Formsアプリを作成しています。質問なんですが、
シリアル通信で豆電球を点灯させたり、消灯させたりしています。
フォームには 送信テキストボックスと受信テキストボックス、送信ボタンとチェックボックス16個あります。
豆電球が16個ついている装置をUSBとつないでます。
チェックボックス1をチェックすると豆電球1が点灯します。チェックを外すと消灯します。

装置とアプリの関係は
・アプリでコマンド値(16進数)をテキストぼっくすに入力して送信ボタンを押すとシリアル通信でそのコマンドを送出する
・コマンド値は豆電球のオンオフをビットパターンで表していて、0x0001=豆電球1~0x8000=豆電球16に対応している。
・コマンド送信を実行すると、コマンド値でビットが1になっている豆電球について、アプリ側ではチェックボックスがオンになり装置側では豆電球が点灯する(ビットが0ならチェックがオフ、豆電球が消灯)

やりたいことは
デバックしてテキストボックスに16進数"mh,ffff"と入力して送信すると豆電球は全部点灯して、フォームのチェックボックスもチェックされた状態になります。
16進数を入力して送信して狙った豆電球を点灯できるのですが、
テキスト送信で "ms,1" と入力し送信したらで豆電球1だけをを点灯し、"mr,1" で消灯する、同じく"ms,2"で豆電球2が点灯し、"mr,2"で消灯する
という風にできていたのですが、16進数に変換されて送信されて"ms,1"入力で豆電球1だけを点滅させるのが他の豆電球も点灯してしまいます。
ms,1 やmr,1などの文字は16進数に変換せずにそのまま送信したいのです。

なんか対処法はないでしょうか?下手な説明で申し訳ないのですがご教授お願いいたします。

コードは次のようになります。

public void sndTextBox_KeyDown(Object sender, KeyEventArgs e)
{

// エンターを押したらテキストが送信される
if (e.KeyCode == Keys.Enter)
{
switch (this.sndTextBox.Text.Trim())
{
case "MS,1":
case "Ms,1":
case "mS,1":
case "ms,1":
this.checkBox1.Checked = true;
break;
case "MR,1":
case "Mr,1":
case "mR,1":
case "mr,1":
this.checkBox1.Checked = false;
break;

case "MS,2":
case "Ms,2":
case "mS,2":
case "ms,2":
this.checkBox2.Checked = true;
break;
case "MR,2":
case "Mr,2":
case "mR,2":
case "mr,2":
this.checkBox2.Checked = false;
break;

}
//! シリアルポートをオープンしていない場合、処理を行わない
if (serialPort1.IsOpen == false)
{
return;
}

//! テキストボックスから、送信するテキストを取り出す
String data = sndTextBox.Text;

//! 送信するテキストがない場合、データ送信は行わない
if (string.IsNullOrEmpty(data) == true)
{
return;
}

try
{

//! シリアルポートからテキストを送信する.
serialPort1.Write(data + "\n");
int startIndex = data.IndexOf(",");

if (startIndex > -1)
{
startIndex = startIndex + 1; // 開始位置","の次の文字
string tValue = data.Substring(startIndex);
int value = Convert.ToInt32(tValue, 16);

for (int i = 1; i <= 16; i++)
{
//画面上の処理対象チェックボックスコントロールを特定
Control[] cs = this.Controls.Find("CheckBox" + i.ToString(), true);

//チェック対象ビットに1が立っていればチェックオン、0ならチェックオフ
((CheckBox)cs[0]).Checked = ((value & (1 << (i - 1))) > 0);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

}

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2016/07/27 03:33

インデントが外れていますよ。読みにくいので直してください。
KIYOSHI

2016/07/27 04:03

ちょっと質問がちがうんですが、連投されていますね。 色々ためされているんでしょうが、 もう他の質問と同じようなないようですのでどちらかに絞った方がいいと思います。
KoichiSugiyama

2016/07/27 04:14

「変な感じに点灯しています」とはどんな状態でしょうか?"MS,1"を送った場合、どの豆電球が点灯するのでしょうか?現象が安定しないのなら安定しない、と書いてもらわないと、状況が把握できません。 あと勘違いしていたら申し訳ないのですが、送信データが"MS,ffff"だとうまくいくが、"MS,1”だとうまくいかないとのことですが、使用しているのがSystem.IO.Ports.SerialPortだとすると、単純にWrite()で文字列を書き込んで送信しているだけのはずですので、受信側で”MS,1"を自動で"MS,0001"と解釈してくれないと上手くいかないと思いますが、そのあたりの仕様はどうなっていますか?
guest

回答2

0

完全に蛇足ですが、
ビット配列の操作が伴う時は、
BitArrayクラスを用いるとコードをすっきりさせれるかと思います。
BitArrayクラス-MSDN

ちなみに整数値からBitArrayを生成する場合は、

C#

1// ビット値0101 2BitArray b = new BitArray(new int[] { 5 });

という感じで初期化できます。

投稿2016/07/27 23:47

編集2016/07/28 03:25
Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KIYOSHI

2016/07/28 02:39

BitArrayは、 送信後のChackBoxをOn/Offする際に活用できそうですよね。
Panzer_vor

2016/07/28 03:05 編集

コメントありがとうございます。 BitArray自体が各要素をboolで管理してくれるのでチェックボックスとの相性は良さそうですね^^
guest

0

ベストアンサー

"MS,1"の1が16進数に変換されて送られてはないと思います。
[追加情報依頼]に書かれているかたもいらっしゃいますが、
MS,0001と送らないと認識しないのではないでしょうか?


###追記
コメントにともない、"MS,"で始まる場合は、
","以降を10進数としてBit変換し、16進数に置き換える

C#

1 // dataの先頭がMSなら。数字を10進数から 2 // Bit変換(5なら5Bit目を1)して 3 if (data.ToUpper().StartsWith("MS,") == true) 4 { 5 int iLampNo = 0; 6 7 string sLampNo = data.Substring(3); 8 if (int.TryParse(sLampNo, out iLampNo) == false) 9 { 10 // MS,の後が数字ではない 11 MessageBox.Show("MS,の後が数字ではない"); 12 return; 13 } 14 15 if (iLampNo >16) 16 { 17 // 16より大きいのでエラー 18 MessageBox.Show("16まで"); 19 return; 20 } 21 22 // Bit変換 23 int bitLamp = 1 << (iLampNo-1); 24 25 // 16進数に変換 26 string hLamp = Convert.ToString(bitLamp, 16); 27 28 // 送信用文字列 29 data = "MS," + hLamp; 30 } 31 32 serialPort1.Write(data + "\n");

投稿2016/07/27 04:53

編集2016/07/28 02:01
KIYOSHI

総合スコア268

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ncncup

2016/07/27 05:14

ありがとうございます。 MS、0001と送っても変換されちゃっていますね。 ms,5 と送って豆電球5を光らせてチェックボックス5をチェックさせたいのですが、 豆電球1と3が点灯されてしまいます。
KIYOSHI

2016/07/27 05:21

提示のソースでは、 //! テキストボックスから、送信するテキストを取り出す String data = sndTextBox.Text; //! シリアルポートからテキストを送信する. serialPort1.Write(data + "\n"); ですので、シリアル通信では、 TextBoxに入力した文字をそのまま送ってますよ。
ncncup

2016/07/27 05:31

丁寧な回答ありがとうございます。 送信した際に int value = Convert.ToInt32(tValue, 16); で16進数に変換されて送信されていると思うんですけど、 ms,1やmr、1 を送信したときは、 int value = Convert.ToInt32(tValue, 16); の処理を無視したいんですけどできますでしょうか?
KIYOSHI

2016/07/27 05:38

いえいえ、 送信は serialPort1.Write(data + "\n"); ですので、 16進数の変換はその後ですので、送信には影響与えてないですよ。
KoichiSugiyama

2016/07/27 05:45 編集

横から済みません、 > ms,5 と送って豆電球5を光らせてチェックボックス5をチェックさせたいのですが、 > 豆電球1と3が点灯されてしまいます。 だとすると、ちゃんと"ms,5"が"ms, 0005”に変換されていますよね。 5の二進表現は0101なので、間違っていません。 5番目を点灯させたいのでしたら”ms, 0010"とすべきでしょう。
KIYOSHI

2016/07/27 06:16

KoichiSugiyama さん そのとおりですね。 入力したTextをそのまま送信しているので、16進数で入力しないといけませんね。
ncncup

2016/07/27 07:09

ありがとうございます。 ms, と入力して送信する場合だけ16進数に変換しないってのはできますでしょうか?
KIYOSHI

2016/07/27 07:42

「MSの場合に16進数に変換しない」ではなく、 今は、テキストに16進数を入れて送信しておくるようになってますよね。 MSの場合は、MS,(10進数)を入力 例:MS,5 MHの場合は、MH,(16進数)を入力 例:MH,10 ということですか?
ncncup

2016/07/27 08:03

はい。そのとおりです。 よろしくお願いいたします。
KIYOSHI

2016/07/27 08:09 編集

再確認 MSの場合は、MS,FFFFとは入力しないですね。 変換しないではなく、 MSの場合は10進数を入力し、16進数に変換して送信する。 ということですか?
ncncup

2016/07/27 08:18

はい。 msの場合は10進数の数字(1 〜16)しか入力しません。 よろしくお願いいたします。
ncncup

2016/07/27 08:19

それかms,1を数字ではなく文字列として変換することは可能でしょうか?
ncncup

2016/07/27 08:20

2つの質問をして申し訳ないですが、よろしくお願いいたします。
KIYOSHI

2016/07/27 08:27

ms,1を文字列としてとは? "ms,1"で文字ですよね。
KIYOSHI

2016/07/27 11:59 編集

MSの場合、単に16進数ではなく、Bit変換(5なら5Bit目を1)して16進数表示となりますので、変更しました。
KIYOSHI

2016/07/28 02:08

昨晩の修正でソースがBit操作してないソースのままでしたので、差し替えました。
ncncup

2016/07/28 02:15

本当にありがとうございます。 無事解決できましした。ほんとに助かりました。 コードのなどもご教授本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問