1対多シリアル通信
Arduinoを使った1対多のシリアル通信をやってみました.Arduino Duemilanove(UNO)はI2C通信が使えるのです が,この場合アナログ4,5ピンが使用されるので,アナログを6ポートとも使い たい場合には使えません.
それでシリアル通信を使って1対多の通信をやってみました.
その様子↓

手書きメモ

ホストはハードウェアシリアルを使う.
ターゲットはハードウェアシリアルの受信と,ソフトウェアシリアルの送信を使う. ホスト側のTXをターゲットのRXに並列接続. ターゲットのTX(ソフトウェアシリアルでデジタル3ピン)は100Ωの抵抗を 介してホストのRXに並列接続.
ホストからの送信は,ターゲットが並列に受信.
ターゲットは自分が呼ばれたら応答をソフトウェアシリアルで返す.
ターゲットのソフトウェアシリアルのTXは, 通常はピンモードを強制的にINPUTにしてハイインピーダンス状態.
送信時だけピンモードをOUTPUTにして送信. 送信後にピンモードをINPUTに戻して,ターゲットデバイスの並列なTXとの 干渉を防ぐ.
※このモード切替がハードウェアシリアルではできなかったのでターゲットからの 送信にはソフトウェアシリアルを使った.
ホスト側のスケッチ
#include < MsTimer2.h>
int ch=0;
void recvStr(char *buf)
{
int i = 0;
char c;
while (1) {
if (Serial.available()) {
c = Serial.read();
buf[i] = c;
if (c == '\n') break;
i++;
}
}
buf[i] = '\0'; // \0: end of string
}
// ---------タイマー処理 ----------
void fTimer() {
if (ch==0) ch=1; else ch=0; // チャンネルの切替
sendRequest(ch);
}
void sendRequest(int num){
Serial.print("Q"); Serial.println(num);
}
void setup(){
// 状態表示のためにタイマーセット
MsTimer2::set(2000, fTimer); // 2s 周期でタイマー割込み
MsTimer2::start();
Serial.begin(9600);
}
void loop()
{
char str[90]; // string buffer
if (Serial.available()) {
recvStr(str);
Serial.println(str);
}
}
ターゲット側のスケッチ
#include < SoftwareSerial.h>
char ch[]="Q0"; // ここでデバイス側のチャンネルを指定
char rs[]="R0"; // 受信文字列をそのまま返すとループに陥るので応答を変える
SoftwareSerial mySerial=SoftwareSerial(2,3); // 3のTXしか使わない
void recvStr(char *buf)
{
int i=0;
char c;
while (1) {
if (Serial.available()) {
c = Serial.read();
buf[i] = c;
if (c == '\n') break;
i++;
}
}
buf[i] = '\0'; // \0: end of string
}
void setup(){
Serial.begin(9600);
mySerial.begin(9600);
pinMode(3,INPUT); // 一旦TXを絶縁状態にする
}
void loop()
{
char str[90]; // 文字列バッファ
if (Serial.available()) {
recvStr(str);
if(strncmp(str,ch,2)==0) {
pinMode(3,OUTPUT);
mySerial.print(rs); mySerial.println(" response");
pinMode(3,INPUT);
}
}
}
|
ESP32 Wifi Bluetooth開発ボード |
|
Arduino Nano Every |
|
Raspberry Pi pico |
|
FPGA XILINX Artix-7 |
