1

I am currently working on a camera platform based on the MT9D111 module from Micron. The first thing to do is to write the configuration to the numerous registers of the chip which is done via an i2C connection.

I adapted the code from here for testing this with an Arduino Uno. 3.3V supply and 8MHz clock are also provided by the Arduino.

Everything seems to work fine, but there are some odds which I don't know the reason for.

So here is the code (I just added the soft reset sequence according to the Developers Guide):

const int freqOutputPin = 9;   // OC1A output pin for ATmega328 boards

#define TMR1 0

#include <Wire.h>
#include <avr/io.h>
#include <util/delay.h>
//#include <TimerOne.h>
#include <avr/interrupt.h>

void setup() {
  pinMode(freqOutputPin, OUTPUT);
  Serial.begin(9600);

  TCCR1B |= (1 << CS10);  //selecting prescaler 0b001 (Tclk/1)
  TCCR1B &= ~((1 << CS12) | (1 << CS11)); // turn off CS12 and CS11 bits
  TCCR1A |= ((1 << WGM11) | (1 << WGM10)); //Configure timer 1 for TOP mode (with TOP = OCR1A)
  TCCR1B |= ((1 << WGM13) | (1 << WGM12));
  TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
  TCCR1A &= ~(1 << COM1A1);
  TCNT1 = 0;
  OCR1A = TMR1;

  delay(500);  //Initial delay
  Wire.begin(); // join i2c bus as master
  Serial.begin(9600);
  Serial.println("MT9D111 Camera Module + Arduino");
  Serial.println("Read and Write 16-bit register value example");
  Serial.println("*  Read expected value = 0x1519 from Register 0x00");
  Serial.println("*  Write value = 0xA5F0 to Register 0x20:1");
  Serial.println();
  init1(); //execute code just 1 time
}

void loop() {
}

void init1() {
  int16_t a;

  delay(500);  //wait until start
  Serial.print("Soft reset first");
  Serial.println();
  soft_reset();//do a soft reset at startup

 //***************Configuration here!****************//
  Serial.print("Read result from register 0x00");
  a = read_reg(0);
  Serial.println();
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
  Serial.print("Read original data from register 0x0a, should be 11");
  Serial.println();
  a = read_reg(10);  
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();

  //Enable this part for writing register
  //Some example reads and writes follow
  Serial.print("Writing 0xA5F0 in register 0x20:1");
  Serial.println();
  write_reg(32, 1, 165, 240);
  Serial.print("Read new value from register 0x20:1");
  Serial.println();
  a = read_reg(32);
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
  Serial.print("Writing 0xA1F3 in register 0x20:1");
  Serial.println();
  write_reg(32, 1, 161, 243);
  Serial.print("Read new value from register 0x20:1");
  Serial.println();
  a = read_reg(32);  
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
}

//Write 2Byte register
void write_reg(int reg_address, int page, int data_msb, int data_lsb) {
  delay(5);  //5ms
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(240);   //page register address
  Wire.write(0);
  Wire.write(page);   //select page 0/1/2
  Wire.endTransmission(1);    // stop transmitting
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(reg_address);   //register address 8bit, decimal
  Wire.write(data_msb);  //msbyte
  Wire.write(data_lsb);  //lsbyte
  Wire.endTransmission(1);    // stop transmitting
}

//read 2Byte register
//be careful about selected register page
int16_t read_reg(int reg_address) {
  int16_t err;
  delay(5);  //5ms
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(reg_address);   //register address 8bit, decimal
  err = Wire.endTransmission(1);    // stop transmitting
  Serial.println(err);
  Wire.requestFrom(93, 2, 1); //request value form device 93, 2 bytes with stop bit
  int16_t result = ((Wire.read() << 8) | Wire.read());  //read 16 bits
  return result;
}

//Perform Soft reset, required at startup
void soft_reset(){
  write_reg(101, 0, 160, 0);//write registers according to dev guide
  write_reg(195, 1, 5, 1);
  write_reg(13, 0, 0, 33);
  delay(5);
  write_reg(13, 0, 0, 0);
  delay(5);//wait for i2c to be ready again
}

Running this code gives me the following result on the serial monitor:

Serial Monitor

So here are the questions:

  1. Do you have any ideas why I get an extra FFFF when reading a register after writing it? (underlined in blue)
  2. Why are there some extra zeros in the output? (marked in yellow)
  • How did you get this to work. I tried the same code with OV2640 but I always get error as 2 and value read as 0xFFFF. Please help me. – Sriranjan Rasakatla Sep 29 at 6:56
1

The 0 comes from your code:

Serial.println(err);

It's printing the error code. 0, hence no error.

As for the extra FFFF I'd say it's because you are using signed integers. Change your a declaration to uint16_t and see if that fixes it.

  • 1
    Thanks, that was some fast help. Solved the problems :-) – deinoppa Dec 2 '15 at 8:10
  • Happy to help :-) – dda Dec 2 '15 at 8:19

protected by VE7JRO Sep 29 at 13:29

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.