How to read an asynchronous digital signal (please

Dear All,
I am trying to interface a Arduino mega with a video sensor called C3088
http://courses.cit.cornell.edu/ee476/FinalProjects/s2006/jzs3_da65/jzs3_da65/C3088.pdf

that outputs image data via a 8 pin port (Y0~7). Since the two device do not have the same clock, I am having some fundamental problem in understanding how to do this.

What I want is to download images, size=176X144, at 3 frames per second and pass them via the serial port to a PC. Ideally I'd like to pass one line at the time (or a pixel at the time).

Arduino board and C3088 are connected via a 8 bit digital port that I will call (Y0~7) and 3 additional lines named VSYN, HREF and PCLK. Here is what happens.
VSYN is normally LOW and becomes HIGH and then LOW again every 1/3 s. VSYNC indicates the beginning of a full frame (about 176X144=25k byte)
HREF is normally LOW and becomes HIGH and then LOW again every 1/462 s. VSYNC indicates the beginning of a frame line.
PCLK is a standard clock signal that is running at 259 kHz.

void loop(){
 
  Serial.println("let's count HREF...");
  
  while(digitalRead(VSYNC) == LOW) {} // detect the raising and falling edge of VSYNC
  while(digitalRead(VSYNC) == HIGH) {}
  while(digitalRead(VSYNC) == LOW) {}
  
  while(digitalRead(HREF) == LOW) {} // detect the raising and falling edge of HREF
  while(digitalRead(HREF) == HIGH) {}
  while(digitalRead(HREF) == LOW) {}
  
  ind=0;
      // start clocking 
  for (int i=0 ; i < 900000 ; i++){ 
    while(digitalRead(PCLK) == HIGH) {} // detect the falling edge of CLOCK
    while(digitalRead(PCLK) == LOW) {}
    ind++;
    if (digitalRead(VSYNC) == HIGH){ 
      Serial.println(ind);
      break;
    }
  }

So the questions I have are:

  • is PCLK too fast for Arduino?
  • what is the best way to implement the reading routine?
  • as first attempt I'd like to count how many clock edges there are in a frame (or in a line), see the code. But it looks like I am not doing it right.

-the output of this routine is about 1442 which I don't think is right. (it should be way more then 25k)

-the way I implemented the detection of a clock rising edge is by two While()s one after the other. is there a better way? maybe PCLK is too fast...

  • Since I have a other Arduino board, is there a way I can quickly implement (or download) a logic analyser with it? any recommendation?

thanks a lot for your help

regards
fabrizio

What I want is to download images, size=176X144, at 3 frames per second and pass them via the serial port to a PC.

If these are eight bit pixels, that's 1761443 bytes per second = 76 032.
That would mean running the serial line at at least 760 320 bits per second.

More useful data here:

hum... that's a pretty good point. Than I will probably lower the frame rate so that I can give the serial port the time to do so.
My main concern now is about the double while{} method to detect asynchronous values. Is it a common method?
thanks
fabrizio

I skimmed the datasheet (page 6) - looks like video data is valid whilst HREF is high, but you're waiting for it to go low.
I think you should be counting your pclks while HREF is high.

260 kHz is pretty fast to read with digitalRead. I would go down to the port level and use either a pin change interrupt, regular interrupt pin, or input capture (associated with Timer 1).

I would think you would need to use assembler code to get the data in fast enough and I would doubt you could get it the data out fast enough through the serial port. Although I am often surprised at what can be done using Arduino, this project may not be achievable even if you have assembly language skills and a good logic analyzer.

Not as much fun, but its a lot easier just connecting a web cam to the pc :wink:

no doubt image-related stuff are not very double with a 8-bit 16MHz micro.
The truth is that i am interested in a battery-powered sensor application and a computer (with a web-cam connected to it) is not very portable :wink:

The truth is that I actually can process the image line by line and send (truth the serial port or whatever) just a little amount of info. The process of reading is however happening at 260KHz and I cannot really change that.

Could somebody give me and indication of how to implement one of the following suggested solutions:
1 a pin change interrupt
2 regular interrupt pin
3 input capture (associated with Timer 1)

thank you all for the great support
cheers
fabrizio

I doubt any of those would help you to decode the video signal. 260KHz clock rate means you have 60 cpu cycles to read and decode each pixel. The interrupt handler overhead alone would eat into much of this. I think your code would need to sit in a tight loop to monitor the data using direct port i/o and store the bytes in an array. You don't have enough memory to hold a complete frame so you will need to do some processing in the line blanking interval – and that does not give you much to play with.

Can you say more about what processing you want to do on the signal?

Is it worth considering storing the data in an EEPROM while in the hard loop? Possibly one could buffer up a few frames and then send it to the PC. I don't know if your application would allow the time it takes to do the serial communication without losing important video data.

[edit]Sorry, the EEPROM write time would be too long to buffer the data byte-wise, maybe do a page or block write during the blanking intervals?[/edit]

[edit]Never mind. The blanking intervals aren't long enough to write the amount of data you get. Sounds like you need a micro with an external address and data bus.[/edit]

Let's see...using input capture:

// Assumes PORTK is 8-bit video input
// Assumes PCLK is on PORTL bit 0 input

// Configure input capture for rising edges, noise canceller
TCCR4B = _BV(ICNC4) | _BV(ICES4);
TIFR4 = _BV(ICF4); // Clear input capture flag

// Other setup stuff

// start clocking
for (i=0; i < 176; i++) {
  while ((TIFR4 & _BV(ICF4)) == 0) /* wait */ ;

  TIFR4 = _BV(ICF4); // clear flag
  ...... = PINK;  // Read 8-bit data
}

The idea is to store a reference image somewhere in an external memory (any suggestion?) once a reference frame is available any future image will be compared (subtracted ) to it and the difference (hopefully small enough) will be processed or sent over the serial port.

I know understand that the 260 KHz clock signal puts the whole micro in a problematic situation.
I will learn how to make an interrupt and see how fast I can get.

The other thing is that the resolution of the image is quite large but a routine to reduce it should be feasible.

thanks a lot for your support, I will port back as soon as I know what an interrupt is !
fabrizio