LoginSignup
0
0

More than 5 years have passed since last update.

WaffleにGroveのシリアルカメラキットを接続したかったが、そのままではつながらないことがわかった

Last updated at Posted at 2018-09-23

Arduino互換ボード『Waffle』にGroveのシリアルカメラキットをつなごうとしているがうまくいかないので、その奮闘記をログとして残しておきます。

【注意】うまくいく方法がわかりました。こちらの記事を参照してください。(以下の情報には間違いがあります)

Waffleとは

こちらを参照のこと。

シリアルカメラモジュールとは

こちらを参照のこと。

接続ポート

今回は、WaffleのD5ポートに繋ぐこととします。
image.png

使用するケーブルは、シリアルカメラキットに含まれているものではなく、ストレートです。
この件に関してはこちらを参照してください。

接続後はこんな感じになります。
image.png

プログラム

カメラとの接続は、ハードウェアリシアルではなくて、ソフトウェアシリアルを使用します。

#include <SoftwareSerial.h>

#define PIC_FMT_VGA    7
#define PIC_FMT_CIF    5
#define PIC_FMT_OCIF   3
#define CAM_ADDR       0
#define CAM_SERIAL     softSerial

#define PIC_FMT        PIC_FMT_VGA

SoftwareSerial softSerial(5, 6);  //rx,tx

const byte cameraAddr = (CAM_ADDR << 5);  // addr

WaffleのD5ポートは、D5がPD5に、D6がPD6につながっていますので、カメラ側の「送信」「受信」に合わせて、受信をD5、送信をD6とします。
image.png

次に、初期化(setup())で、カメラの初期化を行います。

/*********************************************************************/
void setup() {
  Serial.begin(115200);
  CAM_SERIAL.begin(9600);       //cant be faster than 9600, maybe difference with diff board.

  initialize();
}

まず、PCへのモニター出力の通信速度を115,200bpsで設定しています。(これは特に意味はありません)
次に、カメラと接続しているソフトウェアシリアルの通信速度を9,600bpsに設定しています。
カメラの仕様上は115,200bpsまで行けそうですが、今回の接続はUARTではない(RS-232を使用)ので9,600bpsにしておきます。

/*********************************************************************/
void sendCmd(char cmd[], int cmd_len)
{
  for (char i = 0; i < cmd_len; i++) CAM_SERIAL.write(cmd[i]); 
}
/*********************************************************************/
int readBytes(char *dest, int len, unsigned int timeout)
{
  int read_len = 0;
  unsigned long t = millis();
  while (read_len < len)
  {
    while (CAM_SERIAL.available()<1)
    {
      if ((millis() - t) > timeout)
      {
        return read_len;
      }
    }
    *(dest+read_len) = CAM_SERIAL.read();
    //Serial.write(*(dest+read_len));
    read_len++;
  }
  return read_len;
}
/*********************************************************************/
void initialize()
{   
  char cmd[] = {0xaa,0x0d|cameraAddr,0x00,0x00,0x00,0x00} ;  
  unsigned char resp[6];

  Serial.print("initializing camera...");

  while (1) 
  {
    // Send "SYNC"
    sendCmd(cmd,6);
    // Read "ACK"
    if (readBytes((char *)resp, 6,1000) != 6)
    {
      Serial.print(".");
      continue;
    }
    if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x0d && resp[4] == 0 && resp[5] == 0) 
    {
      // Read "SYNC"
      if (readBytes((char *)resp, 6, 500) != 6){
        continue; 
      }
      if (resp[0] == 0xaa && resp[1] == (0x0d | cameraAddr) && resp[2] == 0 && resp[3] == 0 && resp[4] == 0 && resp[5] == 0) break; 
    }
  }  
  // Send "ACK"
  cmd[1] = 0x0e | cameraAddr;
  cmd[2] = 0x0d;
  sendCmd(cmd, 6); 
  //Serial.println("\nCamera initialization done.");
}

初期化の関数内で、カメラとハンドシェイクを行っています。
 Waffle「SYNC」→カメラ「ACK」→カメラ「SYNC」→Waffle「ACK」
となっています。

問題発生

ところがこの初期化処理がうまく動きません。
image.png

残念ながら、現状は、Waffleから「SYNC」を送り、カメラから返事(6バイト)が返ってきているのですが、なぜかすべて0になっています。(0x00が6つ)
これは正式な電文ではないので、どこかでうまく受け取れていないようです。

ただ、ちゃんと6バイト返している(返してきているバイト数は確認済み)ところから考えて、以下の可能性があると予想しています。

  • ビットが立っている(5V)はずが立っていなくて(電圧が低くて)、0と判断されている(ハード側の問題)

RS-232

そもそも、カメラ側のインターフェースはRS-232なのですが、こちらの規格は以下のような電圧差でビットのON/OFFを判断しています。
http://www.automationmedia.com/Images/KB_RS232_signals.gif

つまり、+3V~+13Vだったら0、-3V~-13Vだったら1ということになります。(※出力の場合は+5V~+15Vが0、-5V~-15Vが1)
ちなみに、Groveは0V~0.8Vが0で+2V~+5Vが1になります。

つまり、Waffleからカメラへの送信信号はなんとかカメラ側で読めるのですが、カメラ側からWaffle側への送信信号は読めないということになります。

この間の変換(RS-232-TTL変換)を行うのがMAX232等のチップになるようです。

結論

ということで、間に変換をかまさないとダメのようです。

※工作は辛いから、こんな感じのものを利用すればいいのかな?

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0