[ニュース十勇士クラブTV] プチコンとArduinoでデータ通信

2012年10月23日放送。電子工作マガジン2012年11月号の記事を参考に、プチコンmkIIArduinoを使ったデータ通信をやってみました。

  1. プチコンのBASICプログラムで、文字列の各ビットに合わせて画面を白黒点滅
  2. Arduino+フォトトランジスターの回路で信号を読み込み、文字列を復号化、シリアルモニタに表示

●プチコン側の送信プログラム

電子工作マガジン掲載のプログラムを改造して、一度に2ビットずつパラレル送信するように高速化しました。
※ライブ終了後に再度書き換え、コードを整理しています。

◇プチコンmkII用QRコード

1 2
petitcom-arduino-qr1.png petitcom-arduino-qr2.png

◇プチコンプログラムリスト

※現在は「SP0=60」として、1シグナル=1秒(1倍速、2bps)にしています。
最高で「SP0=1」にすると、1シグナル=1/60秒(60倍速、120bps)になります。
ライブ中で、60倍速まで受信できることを確認しました。

'************
'* *
'* プチコン+ *
'* Arduino *
'* デ-タツウシン *
'* *
'************

'2012.10.25
'2ビット パラレル ソウシン

'=== ショキセッテイ ===

ACLS
COFF=14 'ショウトウ(クロ)
CON =15 'テントウ(シロ)
SZ =40 'セイホウケイ サイズ
SP0 =60 'シグナル ジカン

'ソウシン モジレツ
A$="ABC"

'=== ソウシン マエ 3ビョウ マチ ===

PRINT "Speed=x";60/SP0
PRINT "Wait 3sec."
WAIT 180
PRINT

'=== メイン ル-プ ===
@MAIN

'--- モジレツ ソウシン ---
FOR I=0 TO LEN(A$)-1
C1$=MID$(A$,I,1)
BDAT=ASC(C1$)
PRINT "[";C1$;"]=";BDAT
GOSUB @SENDBYTE
NEXT

'--- ENDコ-ド[00H] ソウシン ---
BDAT=0
PRINT "[END]=00H"
GOSUB @SENDBYTE

GOTO @MAIN

'=== 1モジ ソウシン サブ ===
@SENDBYTE

'--- カイシ シンゴウ ---
GFILL 255-SZ,0,255,SZ,CON
PRINT " START=01"
VSYNC SP0

'--- 2ビット ズツ ソウシン ---
MSK=&H80
FOR BCNT=1 TO 8 STEP 2
C0=COFF:C1=COFF
B0=0:B1=0

'ジョウイ 1ビット
IF MSK AND BDAT THEN C1=CON:B1=1
GFILL 255-SZ*2,0,255-SZ,SZ,C1
PRINT " bit";8-BCNT;"=";B1

'カイ 1ビット
IF MSK/2 AND BDAT THEN C0=CON:B0=1
GFILL 255-SZ,0,255,SZ,C0
PRINT " bit";8-BCNT-1;"=";B0

MSK=MSK/4
VSYNC SP0
NEXT

'--- ENDビット[00] ソウシン ---
GFILL 255-SZ*2,0,255-SZ,SZ,COFF
GFILL 255-SZ,0,255,SZ,COFF
PRINT " END=00"
VSYNC SP0*2

PRINT
RETURN

●Arduino側のセンサー回路図

petitcom-arduino-circuit.png

petitcom-arduino-photo1.jpg

petitcom-arduino-photo2.jpg

●Arduino側の受信プログラム

※ライブ中に作ったプログラムから若干修正しています。
シリアルモニタに確認用の数値などを表示する部分は、コメントで残しています。

/*
フォトトランジスターで読み取りプログラム
*/

// ===初期設定===

int phototr0 = 0;
int phototr1 = 7;
int th = 100;
int spx = 1;  // 読み取り速度(1-60倍速)

void setup() {

  // シリアルモニタのセットアップ
  Serial.begin(9600);
  while (!Serial) {
  }
  Serial.println("*** Start ***");
 
}

// === ループ ===
void loop() {
 
  // ---開始信号待ち---
  int a0 = 0;
  int a7 = 0;
  while (a0 < th) {
    // A0から読み込み
    a0 = analogRead(phototr0);
  }
  // Serial.println("Char. Start");
  delay((1000+500)/spx);
 
  // ---2ビットずつ読み込み---
  int mask = B10000000;
  int rdata = 0;
  for (int i = 3; i >= 0; i--) {
    a0 = analogRead(phototr0);
    a7 = analogRead(phototr1);

    /*
    Serial.print("bit");
    Serial.print(i*2+1);
    Serial.print("=");
    */
    if (a7 > th) {
      rdata = rdata + mask;
      // Serial.println(1);
    } else {
      // Serial.println(0);
    }

    /*
    Serial.print("bit");
    Serial.print(i*2);
    Serial.print("=");
    */
    if (a0 > th) {
      rdata = rdata + mask / 2;
      // Serial.println(1);
    } else {
      // Serial.println(0);
    }

    mask = mask >> 2;
    delay(1000/spx);
  }

  // シリアルモニタに読んだ値を表示
  // 0だったら改行、それ以外は連続表示
  // Serial.println(rdata);
  if (rdata == 0) {
    Serial.println("");
  } else {
    Serial.print(char(rdata));
  }
}