TrevaなるカメラをArduinoにつなげてみる.


つなげてみた.
trevaはクロックを与えるだけで,データを出力してくれる素敵なカメラ.

http://www.paken.org/aaf/treva/


上のページの解析結果を参考にスケッチを描いてみる.

#include <stdio.h>

#define CLK 8
#define DAT 9

#define BAUDRATE 115200

void setup()
{
  pinMode(CLK, OUTPUT);
  pinMode(DAT, INPUT);
  
  Serial.begin(BAUDRATE);
}

void loop()
{
  capture();
}

void capture()
{
  long magic = 0,i,k;
  int v = 0, u = 0, y = 0;
  int r = 0, g = 0, b = 0;
  unsigned char d;
  
  while((magic & 0xffffff) != 0xaa55ff)
  {
    magic <<= 1;
    if(readbit())
    {
      magic |= 0x01;
    }
  }
  for(i=0; i<29*8; i++)
  {
    readbit();
  }
  
  Serial.println("get!!");
  for( k=0; k < 96*72*2; k++){
    d = 0;
    for (i=0; i<8; i++){
  	d <<= 1;
  	if(readbit())
  	  d |= 0x1;
    }
    if((k & 0b11) == 0b00){
      v = d - 128;
    }else if((k & 0b11) == 0b10){
      u = d - 128;
    }else if((k & 0b11) == 0b01 || (k & 0b11) == 0b11){
      y = d;
      r = u + y;
      g = 0.98 * y - 0.53 * u - 0.19 * v;
      b = v + y;
      
      if(r > 255) r = 255;
      if(r < 0) r = 0;
      if(g > 255) g = 255;
      if(g < 0) g = 0;
      if(b > 255) b = 255;
      if(b < 0) b = 0;
      
      Serial.print(r, DEC);
      Serial.print(" ");
      Serial.print(g, DEC);
      Serial.print(" ");
      Serial.print(b, DEC);
      Serial.print(" ");
    }
  }
  Serial.println("");
}

int readbit()
{
  int a;
  digitalWrite(CLK, HIGH);
  //delayClk(1);
  a = digitalRead(DAT);
  digitalWrite(CLK, LOW);
  //delayClk(1);
  if(a){
    return 1;
  }else{
    return 0;
  }
}

void delayClk(int clk)
{
  int i;
  for(i=0;i<clk;i++);
}


これをアップロードすると,シリアルポートからPPM画像のデータ部を出力する.
ので,適当に保存してimageMagickで変換してみた画像がこれ.


96*72画素しかないので,こんなもんだけど,ロボットカーコンテストで赤いパイロンを見分けるぐらいには使えるだろうと思い込む.
オリジナルの出力はYUVで,96*72*2バイト出力されるけど,Arduino本体のメモリには格納できない気がするので,どうやって画像処理するか悩む.
明るい,暗い,赤いっぽいものが目の前にある,とかそんなもんしか認識できないよなー,なんて妄想.