workshop/SonyFelicaRC_S620S/main

学生がICタグを利用したプロダクトのプロトタイピングを行いたいということで,Arduinoで簡単にできるものとしてSonyのFelicaリーダを教えてあげたら速攻で持ってきてくれたので, その接続方法等をまとめました.今回は書き出しはせず,読み込みだけできればOKな仕様だったのでサンプルもそのようにしています.なおこのRC-S620Sを調べてみると,デバイスとの 通信線にRX,TXピンを使ってしまうので,それをPCでカード情報を読み取るためには少し工夫しなければなりません.具体的には下記のようなやりかたです.

  • Felicaリーダの通信線をSoftware Serialで実装する
  • ハードシリアルを複数本持つArduino Mega等でプロトタイプする
  • AVRマイコンを追加する

上記のような対応が考えられるかと思いますが,どれも面倒くさかったので,Arduino一発で荒っぽくやりました.RC-S620Sに使われているシリアル線(TX)に取得IDを 送信して,それをPC側で判別してデータを取得する.といった具合です.PC側からはFelicaリーダへのデータ送信も拾ってしまうので,こちらのデータ・フォーマットを 決めて,そのデータだけを抜き出すようなプログラムをProcessingで作成しました.

プログラムに慣れていない人は,http://hello.processing.orgにて学習しておきましょう.

ArduinoとRC-S620Sをつなぐ準備

http://9ensan.com/blog/diy/arduino-rc-s620s/を参照して,まずは接続からArduinoの スケッチを準備してください.

Arduino

#include "RCS620S.h"
#include <inttypes.h>
#include <string.h>

#define COMMAND_TIMEOUT  400
#define PUSH_TIMEOUT    2100
#define POLLING_INTERVAL 500

#define LED_PIN 13

RCS620S rcs620s;

int waitCardReleased = 0;

void setup() { 
  int ret;
 
  pinMode(LED_PIN, OUTPUT);   // for Polling Status
  digitalWrite(LED_PIN, LOW); 
 
  Serial.begin(115200);      // for RC-S620/S
  
  // initialize RC-S620/S
  ret = rcs620s.initDevice();
  while (!ret) {}             // blocking
}
 
void loop() {
  int ret, i;
 
  // Polling
  digitalWrite(LED_PIN, HIGH);
  rcs620s.timeout = COMMAND_TIMEOUT;
  ret = rcs620s.polling();

  if(ret) {
    Serial.write(250);
    for(i = 0; i < 8; i++)
    {
      digitalWrite(LED_PIN, LOW);
      Serial.write(rcs620s.idm[i]);
    }
    Serial.write(251);
  } else {
    digitalWrite(LED_PIN, HIGH);
  }
 
  rcs620s.rfOff();
  delay(POLLING_INTERVAL);
}

Processing

import processing.serial.*;

Serial myPort;  // The serial port

void setup() {
  // List all the available serial ports
  println(Serial.list());
  Serial.list();
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, "/dev/tty.usbmodem145421", 115200);
  size(800, 400);
}

void draw() {
  byte[] inBuffer = new byte[9];
  char first_data = myPort.readChar();

  if ( first_data == 0xFA ) {
    background(0);
     myPort.readBytes(inBuffer);
    if( inBuffer == null ){
      return;
    }
    
    if ( int(inBuffer[8]) == 0xFB ) {
      for ( int i = 0; i < 8; i++ ) {
        text(hex(inBuffer[i]), 20, 20+i*10);
      }
    }
  }
}

以上でProcessingを実行し,カードリーダ上にスイカとかなんかのICタグをおけばそのIDmが表示されます. IDmについてはFeliCa技術方式の各種コードについて(176KB)2010年10月15日 Version1.2を参照してください. http://www.sony.co.jp/Products/felica/business/tech-support/index.html#Port

決められたICタグが置かれたら音がなるプログラム

音声ファイルは各自で用意してください.また,ProcessingはVersion.3.0a4を利用してください.processing.soundのライブラリは Version3.0a4に標準で含まれています.データ一式はこちら

import processing.sound.*;
import processing.serial.*;

SoundFile soundfile_on;
SoundFile soundfile_off;
int id[] = {0x01, 0x2E, 0x30, 0xD2, 0x00, 0x8A, 0x86, 0x41};

// use 1,2,3 for id number
int recognized_tag = 0;
int recognized_tag_previous = 0;

int time_stamp = 0;

Serial myPort;  // The serial port

void setup() {
         
  //Load a soundfile
  soundfile_on = new SoundFile(this, "Blow.aiff");
  soundfile_off = new SoundFile(this, "Submarine.aiff");
  // List all the available serial ports
  println(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[(Serial.list().length-1)], 115200);
  
  time_stamp = millis();
  size(800, 400);
}

void draw() {

  byte[] inBuffer = new byte[9];
  char first_data = myPort.readChar();

  if ( first_data == 0xFA ) {
    background(0);
    time_stamp = millis();
     myPort.readBytes(inBuffer);
    if( inBuffer == null ){
      return;
    }
    
    // Got correct IDm Data
    int number_of_equal = 0; 
    if ( int(inBuffer[8]) == 0xFB ) {
      for ( int i = 0; i < 8; i++ ) {
        if( int(inBuffer[i]) == id[i] ){
          number_of_equal++;
        }
        text(hex(inBuffer[i]), 20, 20+i*10);
      }
      if( number_of_equal == 8 ){
        recognized_tag = 1;
        if( recognized_tag_previous != recognized_tag ){
          recognized_tag_previous = recognized_tag;
          soundfile_on.play();
        }
      }
    }
  }
  
  // removed the ic tag
  if( millis() > time_stamp + 1000 && 
      recognized_tag != 0 && recognized_tag_previous != 0 ){
    recognized_tag_previous = recognized_tag = 0;
    soundfile_off.play();
  }
}

Copyright (c) 2015 Tetsuaki BABA all rights reserved.