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

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

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

シリアルポート

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

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

2回答

6900閲覧

VBA→Arduinoへのシリアル送信に関して

uimaro

総合スコア14

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

シリアルポート

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

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2020/06/04 06:00

Excel側からArduino側へデータを送信したいです。
具体的にはExcelから送られてきた数値を元にArduinoを動かしたいです。

下記のようなプログラムにて、easycommを使用してExcelからArduinoへシリアル通信を行っているのですが、Excelで受信したデータは「1」が「49」となってしまいます。

送信した数字と受信した数字がどのタイミングで変わってしまっているのかわかりません。
「1」と送信したら「1」と帰ってくるようにしたいのです。
アドバイスをいただければ幸いです。

環境はExcel2010、ArduinoProMini、Windows10です。

コードは下記の通りです。

VBA

1Private Sub CommandButton1_Click() 2 3 MsgBox "送信を開始します" 4 Debug.Print "###送受信開始###" 5 6 7 'ポート接続 8 Connect 'ポート接続用関数 9 10 MsgBox "OK押すと進む" 11 ec.Ascii = "1" '文字を送信 12 13 Dim Ltime As Date 14 Ltime = DateAdd("S", 5, Now) 15 16 Do While Now < Ltime 17 If ec.InBuffer > 0 Then 18 Range("B11").Value = ec.Ascii 19 Debug.Print ec.Ascii 20 End If 21 ec.DozeSeconds = 1 22 Loop 23 ec.COMn = -1 24 MsgBox "終了" 25 26End Sub 27

Arduino

1if(Serial.available()>0){ 2 long buf = Serial.read(); 3 Serial.print(buf); 4 Serial.println(); 5 6 }

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

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

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

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

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

guest

回答2

0

コンピュータは基本的に「数値」しか扱えません。でも、(「数字」を含む)文字も扱いたいので、「文字を扱うことにした」場合は、例えば数字'1'に対して数値49を、文字'A'に対して数値65を割り当てて、数値と文字を読み替えることによって文字を扱います。いわゆる「文字コード」です。数字'1'を数値1の意味としたいのなら、一番簡単には'1'(つまり49)から'0'(48)を引いてやればいいです。
「文字コード」は(とりあえずC言語の規則では)'0'~'9'までが連続していることが保証されています。

2文字以上で構成される「文字列」(例えば"1234"とか)をやりとりしたくなったらまた別のことを知らなきゃいけませんが、まだそういう話はないのですね?


シリアル通信(TCP/IPとかでも同じことですが)の通信の単位は、1byteです。通信の根っこのところでは、1byteのバラバラのデータでしかなく、「塊」にはならない、というのが1つ重要なこと。
つまり、送る側で'1''2''3''4''5'をまとめて送ったとしても、受ける側がそれをまとめて受け取る保証はないのです。'1''2'と'3''4''5'とか、'1'と'2'と'3'と'4'と'5'とかで受け取るかも知れません。
なので、データがどのようにまとまっているのか、どこで区切ればいいのかは、データの送信側と受信側で打ち合わせておいて、何らかの規則を設けて判別してやらなければいけません。

カンマ区切りで複数の数値データ(1桁以上)をArduino側に送信して

ということであれば、一文字ずつ送られてくるデータを蓄積して、カンマあるいは改行コードを受け取ったらその時点で溜めておいたデータを数値に変換する、というような手続きが必要です。くれぐれも、ある受信操作で'1''2'を受け取ったから12だ、と判断したりしませんように。その次に'3' ','が送られてきたら、実は123だった...ということになってしまいます。

実装方法はいろいろありますが...'Arduino シリアル カンマ区切り'あたりで検索すればいろいろ例が見つかると思います。

投稿2020/06/04 12:25

編集2020/06/06 14:10
thkana

総合スコア7610

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

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

uimaro

2020/06/05 01:23

ありがとうございます。 最終的には、カンマ区切りで複数の数値データ(1桁以上)をArduino側に送信して、その情報を元にArduinoを動作させるという風にしたいので、一桁以上の数値を送信したいです。
guest

0

文字列"1"の文字コード(Asciiコード)は49なので、文字コードを受信しているのではないですか?
このため、受信した49を該当文字に変換すればよいのではないでしょうか?

投稿2020/06/04 06:54

編集2020/06/04 06:57
kenshirou

総合スコア772

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

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

uimaro

2020/06/05 01:21

ありがとうございます。 私も調べてみて、どうやらAsciiコードで発信もしくは受信しているようであることはわかりました。 しかし、これをArduino側ではどのように認識しているのかがわかりません。
kenshirou

2020/06/05 02:40 編集

EasyCommを使ったことがないので詳細は分かりませんが、ec.Ascii = "1"は"1"という文字のアスキーコードを送信するようにセットしていることになるようです。 厳密に1という数値を送信したいなら、ec.Binary = 1 と書く必要があるようです。 ※実際にどのようなデータを通信したいのかは不明ですが、文字列を扱いたいのであれば、バイト配列でデータを受け取ることを理解する必要があります。 ※以下サイトを参照しました。 https://nobita-rx7.hatenablog.com/entry/28093327
uimaro

2020/06/05 03:54

どうやら、シリアルポートとの接続設定の中の、ハンドシェイクの設定を変更したらうまくいきました。 RTS/CTSによるハンドシェイクに設定していたのですが、ハンドシェイク無しの設定に変更することで、送信した文字列がそのまま帰ってくるようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問