第2回では光通信の定義を行いました。今回は実際のプログラムについて検討していきます。
システム概要で紹介しましたが、今回はArduinoとGR-SAKURAを利用します。もちろん、Arduinoが2台でもいいですし、GR-SAKURAが2台でも大丈夫です。もしくはArduino派生品でも(おそらく)大丈夫しょう。
送信側(発光)プログラム
発光側の仕事はパソコンから指示されたデータをシリアル化し、プロトコルに沿って点灯・消灯することです。
/*GR-SAKURA Sketch Template Version: V1.08*/
#include <rxduino.h>
void setup()
{
pinMode(8, OUTPUT); // for drive LED
Serial.begin(9600, SCI_USB0); // for pc-communication
}
void loop()
{
char cChr; // recive charactor
int iCnt; // counter for data bit
// receivable?
for(; Serial.available(); ){
cChr = Serial.read(); // 1charactor recieved
digitalWrite(8, 1); // start bit
delay(500); // 500ms
for(iCnt = 0; iCnt < 8; iCnt++){
if(cChr & 0x80){ // pickup MSB
digitalWrite(8, 1);
}else{
digitalWrite(8, 0);
}
cChr <<= 1; // shift left
delay(500);
}
digitalWrite(8, 0); // stop bit
Serial.println(":Sended"); // debug infomation(1charactor sended)
delay(500); // wait for next charactor
}
}
受信側(受光)プログラム
受光側の仕事はプロトコルに沿ってシリアルデータを文字化し、パソコンに再通知することです。
static int iStatus; // management recieve status
static unsigned long ulTimer; // management recieve status
void setup(){
pinMode(8,INPUT); // recieved led light(CdS)
pinMode(13,OUTPUT); // led monitor
Serial.begin(9600); // serial monitor
iStatus = 0; // not recieved
}
void loop(){
char cChr; // recieved charactor
int iCnt; // recieved counter
switch(iStatus){
case 0:
if(digitalRead(8) != 0){
iStatus = 1; // to start bit
ulTimer = millis() + 450; // term of start bit
}
break;
case 1:
if(digitalRead(8) != 0){
digitalWrite(13,1);
if(ulTimer < millis()){ // over term of start bit
iStatus = 2; // to 1st data bit
digitalWrite(13,0);
delay(250); // 250ms until 1st bit
}
}else{
iStatus = 0; // to waiting
}
break;
case 2:
cChr = 0;
for(iCnt = 0; iCnt < 7 ; iCnt++){
if(digitalRead(8) != 0){
cChr |= 0x01;
digitalWrite(13,1);
}else{
cChr &= 0xfe;
digitalWrite(13,0);
}
cChr <<= 1; // left shift
delay(500);
}
// last bit
if(digitalRead(8) != 0){
cChr |= 0x01;
}else{
cChr &= 0xfe;
}
digitalWrite(13,0);
iStatus = 0; // next communication
Serial.print(cChr); // display charactor
Serial.println(""); // line feed
break;
}
}
いかがでしょうか?無事光通信は確認できたでしょうか?
私がお試しに光通信(LED-CdS)行った様子は下記からご参照いただけます。
今回プログラム、前回記事ではデータの間隔を100msと書いていましたが、実際は500msとしました。
LEDの発光/消灯によってデータのやりとりをしている様子を動画にはっきりと撮りたかったからです。どのくらい短い間隔で通信が行えるかは皆様でご確認いただければと思います。

