> For the complete documentation index, see [llms.txt](https://irseeker.buildingblockrobotics.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://irseeker.buildingblockrobotics.com/guides/advanced-arduino.md).

# Advanced (Arduino)

A 3.3v Arduino can be connected to the IR Seeker as an I2C device. The sample code below will read the best sensor value and the signal strength of the board.

The IR Seeker feature switches should be set to:

1. Off
2. On

The pinout for I2C:

<figure><img src="https://4213710887-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fwumhy9Amexb1fvjNOGl8%2Fuploads%2Fhx3w8JU3MHG2VG3N8tR5%2FI2CPinOut.png?alt=media&amp;token=52af838f-7396-4dd3-b7e4-a4f206803f16" alt="" width="375"><figcaption></figcaption></figure>

```arduino
#include <Arduino.h>
#include <Wire.h>
                    
void setup() 
{  
    Wire.begin(); 
}
                
void loop() 
{    
    Wire.requestFrom(0x10 / 2, 2);
    while (Wire.available())    
    {     
        int c = Wire.read(); // direction is the first byte    
        Serial.print("Best Sensor is: ");    
        Serial.println(c);   
        //smaller number the closer the ball
        int strength = Wire.read(); 
        Serial.print("Strength is: ");    
        Serial.println(strength);          
    }  
    delay(250);
}
```

```c
/*
 * Example: read the whole sensor ring from the IR seeker over I2C.
 *
 * The seeker must be in ADVANCED_MODE (DIP switch 2 up) for its I2C peripheral to be enabled.
 *
 * The ALL register (0x02) returns one 16-byte snapshot per read:
 *
 *   byte  0..11  raw pulse count per sensor, 0..255, in sensor order 1..12
 *   byte  12     best sensor, 1..12 (0 = no ball)
 *   byte  13     strength, 0..100
 *   byte  14..15 bearing, little-endian uint16: 0..359 degrees, 361 = no ball
 *
 * Everything in the frame comes from the same detection cycle, so the counts
 * always agree with the best sensor and bearing reported alongside them.
 *
 * Wiring: seeker SDA/SCL to the master's SDA/SCL, plus a common ground.
 * Pull-ups are on the seeker board.
 */
#include <Arduino.h>
#include <Wire.h>

#define IR_ADDR        0x08   // 7-bit address (the board sets it as 0x10/2)

#define IR_MODE_DIRECTION 0x00
#define IR_MODE_ANGLE     0x01
#define IR_MODE_ALL       0x02

#define IR_SENSORS     12
#define IR_ALL_LEN     (IR_SENSORS + 4)
#define IR_ANGLE_NONE  361

struct IRFrame {
    uint8_t  counts[IR_SENSORS];   // 0..255 per sensor, sensor 1 first
    uint8_t  bestSensor;           // 1..12, 0 = no ball
    uint8_t  strength;             // 0..100
    uint16_t angle;                // 0..359, or IR_ANGLE_NONE
};

// Select which register subsequent reads return. Only needs sending when the
// mode changes — the board remembers it until the next write (or a reset).
void irSetMode(uint8_t mode) {
    Wire.beginTransmission(IR_ADDR);
    Wire.write(mode);
    Wire.endTransmission();
}

// Read one ALL frame. Returns false (leaving `f` untouched) if the board did
// not supply a full frame, e.g. it is unplugged or not in ADVANCED_MODE.
bool irReadAll(IRFrame& f) {
    if (Wire.requestFrom(IR_ADDR, IR_ALL_LEN) != IR_ALL_LEN) {
        return false;
    }

    uint8_t buf[IR_ALL_LEN];
    for (int i = 0; i < IR_ALL_LEN; i++) {
        buf[i] = Wire.read();
    }

    for (int i = 0; i < IR_SENSORS; i++) {
        f.counts[i] = buf[i];
    }
    f.bestSensor = buf[IR_SENSORS];
    f.strength   = buf[IR_SENSORS + 1];
    f.angle      = (uint16_t)buf[IR_SENSORS + 2] |
                   ((uint16_t)buf[IR_SENSORS + 3] << 8);
    return true;
}

void setup() {
    Serial.begin(115200);
    while (!Serial && millis() < 3000) {}

    Wire.begin();            // join the bus as master
    irSetMode(IR_MODE_ALL);  // ask for the full frame from now on

    Serial.println(F("IR seeker: reading ALL register (0x02)"));
}

void loop() {
    IRFrame f;
    if (!irReadAll(f)) {
        Serial.println(F("no response - check wiring and DIP 2"));
        delay(500);
        return;
    }


    Serial.print(F("counts:"));
    for (int i = 0; i < IR_SENSORS; i++) {
        Serial.print(' ');
        Serial.print(f.counts[i]);
    }

    if (f.angle == IR_ANGLE_NONE) {
        Serial.println(F("  | no ball"));
    } else {
        Serial.print(F("  | sensor "));
        Serial.print(f.bestSensor);
        Serial.print(F("  strength "));
        Serial.print(f.strength);
        Serial.print(F("  bearing "));
        Serial.print(f.angle);
        Serial.println(F(" deg"));
    }

    delay(50);
}

```

{% embed url="<https://youtu.be/UE-1PWVJN48>" %}
