Connecter une camera Pixart sur Arduino en protocole I2C

Schéma de câblage


Schéma de câblage

Schéma de câblage

Montage du PCB

Montage du PCB

Arduino Nano monté sous le PCB

Arduino Nano sous le PCB

Note : Le fichier de routage du PCB n’est plus téléchargeable. Après montage du circuit, le soudage de la caméra a été une véritable galère (voir photo ci-dessus). Il est conseillé de fixer la caméra directement sur les pistes du PCB sans soudure par simple contact à l’instar des sockets de microprocesseur.
Attention : La caméra Pixart ne supporte pas le contact prolongé du fer à souder


Format des données ( Source )

Le format définit la présence ou pas de certaines données, il en découle 3 modes de fonctionnement ( Basic, Extended et Full ) avec une organisation des informations différentes dans chacun d’eux.

La configuration du mode s’effectue en écrivant la valeur indiquée entre parenthèse dans le registre 0×33.

Le code arduino fourni en bas de page traite les données en mode Extended, il est possible de rendre le script plus rapide en ignorant les données de sensibilité avec le mode Basic.

  BASIC (0×01)
Byte 7 6 5 4 3 2 1 0
0 X1<7:0>
1 Y1<7:0>
2 Y1<9:8> X1<9:8> Y2<9:8> X2<9:8>
3 X2<7:0>
4 Y2<7:0>

  EXTENDED (0×03)
Byte 7 6 5 4 3 2 1 0
0 X<7:0>
1 Y<7:0>
2 Y<9:8> X<9:8> S<3:0>

  FULL (0×05)
Byte 7 6 5 4 3 2 1 0
0 X<7:0>
1 Y<7:0>
2 Y<9:8> X<9:8> S<3:0>
3 0 X min<6:0>
4 0 Y min<6:0>
5 0 X max<6:0>
6 0 Y max<6:0>
7 0
8 Intensity<7:0>

Sensibilité

Cette partie est la plus délicate à traiter. Le fabricant Pixart n’a pas rendu public la datasheet du capteur.
Les valeurs fournies par wiibrew sont donc à traiter avec une grande réserve.

Toutefois, le développeur Johnny Chung Lee fait ressortir à travers son travail le code source suivant dans le fichier windowsxp/WiimoteTest/WiimoteLib/Wiimote.cs

WriteData(REGISTER_IR_SENSITIVITY_1, 9, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x41 });
WriteData(REGISTER_IR_SENSITIVITY_2, 2, new byte[] { 0x40, 0x00 });

Après quelques test il est confirmé que le code d’Inio propose le meilleur compromis.
En revanche le code fournis par Kestrel semble inutilisable, la sensibilité est bien augmentée au maximum mais le capteur est trop sensible aux lumières parasites… à éviter !

Block 1 Block 2 Notes
00 00 00 00 00 00 90 00 C0 40 00 Suggested by Marcan
00 00 00 00 00 00 FF 00 0C 00 00 Suggested by Kestrel (max sensitivity)
00 00 00 00 00 00 90 00 41 40 00 Suggested by inio (high sensitivity)
02 00 00 71 01 00 64 00 fe fd 05 Wii level 1
02 00 00 71 01 00 96 00 b4 b3 04 Wii level 2
02 00 00 71 01 00 aa 00 64 63 03 Wii level 3 (Suggested by Cliff)
02 00 00 71 01 00 c8 00 36 35 03 Wii level 4
07 00 00 71 01 00 72 00 20 1f 03 Wii level 5

Un autre facteur important pour optimiser la détection des blobs par le capteur Pixart est la led infrarouge.
Plusieurs facteurs sont à prendre en considération comme l’angle d’ouverture et la puissance.

Un facteur est toutefois plus critique que les autres, il s’agit de la longueur d’onde qui doit s’accorder au mieux avec le spectre de sensibilité du capteur, sa valeur est donnée à 940nm.

Les valeurs théoriques des datasheets n’étant pas toujours le reflet de la réalité, il est préférable d’effectuer quelques tests pour évaluer le rendements des leds.

Internet est encore d’une aide précieuse car l’artiste Richard Scott a publié ses résultats de recherche en s’appuyant sur les tests donnés ici pour se focaliser uniquement sur les meilleurs leds.

Un autre article très intéressant traite l’utilisation des objectifs pour augmenter le champ de vision du capteur.

Comparatif des meilleures leds IR

Fig. Comparatif de leds infrarouge 940nm

Note : Bien que les led de 850nm ne figure pas dans le tableau ci-dessus ces dernières restent envisageables. Elles seront toutefois perçues par le capteur avec deux fois moins d’intensité.


CODE ARDUINO / Télécharger

/***************************************************
 * Arduino 1.6.7
 * Initialization IR sensor code based on kako's work http://kako.com/neta/2008-009/2008-009.html
 * and http://wiibrew.org/wiki/Wiimote#IR_Camera
 * Modified by Xavier Detourbet http://notepad.xavierdetourbet.com/?p=1021
 * 
 *  ONLY FOR ONE BLOB & MAX BIT RATE I2C 800Khz 
 * 
****************************************************/
 
#include <Wire.h>
 
#define SENSOR_ADDRESS  0x58
byte data_buf[4];
int x, y , s ;
byte setting1[9] = {0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x41};
byte setting2[2] = {0x40,0x00};
 
void Write_2bytes(byte d1, byte d2)
{
    Wire.beginTransmission(SENSOR_ADDRESS);
    Wire.write(d1); Wire.write(d2);
    Wire.endTransmission();
}

void Write_Nbytes(byte d1, byte * ds, byte n) {
    Wire.beginTransmission(SENSOR_ADDRESS);
    Wire.write(d1);
    for ( byte i = 0; i <  n; i++ ){
      Wire.write(ds[i]);
    }
    Wire.endTransmission();
}
 
void setup()
{
    Serial.begin(9600); // 9600 for processing
    Wire.begin();

    TWBR = 1 ; // max bit rate possible 800khz // IR_cam support the Fast Plus Mode I2C  
    // To change the bit rate use TWBR = ((F_CPU / F_I2C) - 16) / 2
    // For example 400khz (Fast Mode) with 16Mhz oscillator => TWBR = ((16000000L / 400000L) - 16) / 2

    // IR sensor initialize
    Write_2bytes(0x30,0x08); delay(10);  // begin config
    Write_Nbytes(0x00,setting1,9); delay(10); // sensiblity 1
    Write_Nbytes(0x1A,setting2,2); delay(10); // sensiblity 2
    Write_2bytes(0x33,0x03); delay(10); // data mode extended
  
}

void loop()
{
    Wire.beginTransmission(SENSOR_ADDRESS);
    Wire.write(0x36);
    Wire.endTransmission();
    Wire.requestFrom(SENSOR_ADDRESS, 4); 
    
    for (byte i = 0 ; i < 4 ; i++){
      data_buf[i] = 0 ;
      data_buf[i] = Wire.read();
    }

    x = data_buf[1];
    y = data_buf[2];
    s   = data_buf[3];
    x += (s & 0x30) <<4;
    y += (s & 0xC0) <<2;
    s &= 0x0F ;

    Serial.print( int(x) );
    Serial.print( "," );
    Serial.print( int(y) );
    Serial.print( "," ); // only if you use processing to visualize
    Serial.println( int(s) );
    //Serial.print((char)0); // required to finish XML data for XMLSocket protocol    
    delay(30); // only if you use processing to visualize
    
}

CODE PROCESSING / Télécharger

import processing.serial.*;
 
int lf = 10;    // Linefeed in ASCII
String myString = null;
Serial myPort;  // The serial port
 
void setup() {
  // 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()[10], 9600);
  myPort.clear();
  // Throw out the first reading, in case we started reading 
  // in the middle of a string from the sender.
  myString = myPort.readStringUntil(lf);
  myString = null;
  size(1023,767);
  //frameRate(30);
}
 
void draw() {
  background(77);
  //while (myPort.available() > 0) {
    myString = myPort.readStringUntil(lf);
    if (myString != null) {
      int[] output = int (split(myString, ','));
 
      println(myString); // display the incoming string
          
      int x = output[0];
      int y = output[1];
  
      ellipseMode(RADIUS);  // Set ellipseMode to RADIUS
      fill(255, 0, 0);  // Set fill to white
      ellipse(x, y, 20, 20);

    }
}

Caméra DFRobot

La boutique DFRobot propose une caméra infrarouge identique à celle intégrée dans une manette wiimote.
Là où il était nécessaire de démonter le capteur de la manette pour y rajouter les résistances de pull-up du bus I2C ainsi que le résonateur 24Mhz, tout est intégré dans le module de DFRobot, un gain de temps énorme pour un prix aux alentours de 24$.


Tracking Camera DF_Robot


Liens utiles :


Câblage

  • Rouge – VCC+
  • Jaune – SDA
  • Vert – SCL
  • Noir – GND

Sur un arduino Nano la ligne SDA se trouve sur ADC4 et SCL en ADC5.
La tension de fonctionnement est de 3V3 à 5V.


So, what do you think ?

You must be logged in to post a comment.