Help with analog raster scanning

I'm working on a homebrew microscope setup, and I'd like to use an Arduino to control the acquisition of images. My setup is described by this image:

what i would like to have the arduino do is:

  1. produce sawtooth waveforms to drive the x and y mirrors (with the x and y waveforms at different frequencies)
  2. perform an AnalogRead() at a given frequency and then report the values back to a computer (from the detector), and have those AnalogReads be /synced to the raster scan/ (so I can figure out which analog value goes to which pixel; 8-bit resolution is enough for this).

That last part is the entire reason I need the arduino; otherwise I know how I would do this completely asynchronously.

Is there a way I can use the arduino's timer to keep the analogRead call and the sawtooth generation synced, or perhaps an IC exists out there that I can use the arduino to drive a sawtooth with?

I can use non-sawtooth waveforms to drive the mirror, but they take an analog signal in to drive them (-10 V to +10 V) and I want the overall scan pattern to produce a raster scan over the sample.

Hmm, why would you need timers for this?

Why not just
while (not_yet_finished) {sample, proceed to next sawtooth step, delay}

This would keep the sawtooth and the sampling automatically in sync.

The two biggest performance killers will be the analog sampling and the output of the sampled values through the serial interface.

I admire your attitude, but I think this is way too big of both a control and data acquisition project for an Arduino.

With things like a 2 megapixel color USB microscope camera going for under $35 ( AGPtek 2.0 MP 400x USB Digital Microscope ),
I'd look for the the Arduino to do a different part, like control the laser and/or move the stage while your PC then grabs the image
via USB.

perform an AnalogRead() at a given frequency

It's hard to say whether the Arduino can even handle it without knowing that frequency.

Pete

You can control the position of the 2 mirrors?
This would seem fairly simple then.

int mirror0pin  = 9; // PWM on pin9, voltage corresponds to mirror position (check pin#)
int mirror0;
int mirror1pin  = 10; // PWM on pin 10, voltage corresponds to mirror position (check pin#)
int mirror1;
int analogIn = A0;
int imageData;

void setup(){
pinMode (mirror1pin, OUTPUT);
pinMode (mirror2pin, OUTPUT);
// no need to declare analog inputs
Serial.begin (115200); // write serial data out to a PC

} // end void setup

void loop(){
// now run a loop with in a loop to position the mirrors, and take a reading
for (mirror0 = 0; mirror0 <256; mirror0 = mirror0 + 1){
   for (mirror1 = 0; mirror1 <256; mirror1 = mirror1 +1){
      analogWrite (mirror0pin, mirror0);
      analogWrite (mirror1pin, mirror1);
      delay (100); // give mirrors tim to settle?
     imageData = analogRead (A0);
// send the data out
   Serial.write (mirror0); // PC to receiver HEX data from 0-255
                                      // or use Serial.println (mirror0) to monitor on Serial Monitor for initial testing
   Serial.write (mirror1);
   Serial.write (highByte ( imageData );
   Serial.write (lowByte ( imageData );
    } // end mirror0 loop
  } // end mirror1 loop
} // end void loop

Then use an external amp to amplify the 0-5V from the PWM of analogWrite to -10 to +10.

Wow, thanks for all of the suggestions!

Techylah: The problem with a USB Camera is that for proper confocal imaging, you need to get the brightness of a single pixel at a time -- something that I think the USB Camera would have trouble with.

In addition, I was actually thinking of using a Maple for this (for the additional processing power and a larger PWM range), but just wasn't sure how to handle getting a nice clean sawtooth out.

Do you think I'll need to add some sort of RC filter/Op Amp Buffer at the output to ensure that the sawtooth is nice and clean?

Thanks!

nathan

"RC filter/Op Amp Buffer at the output"
Yes. The analogWrite output is PWM at ~490 Hz, with narrow pulses that get wider until they reach full on.
Filter and amplify to get full -10V to +10V output.
Or, use external DACs powered from +/-12V to get full +/-10V output, and with better than 8 bit resolution.

I understand. Some more points.

  1. If the laser is only illuminating one point at a time, the detector can simply be pointed at the whole specimen - no mirrors needed.
  2. Rotating is inherently non-linear. The beam will be moving slowest at 90 degrees to the mirror and fastest at smaller angles. Move a led pointer from the straight up to 45 degrees along a wall.
  3. Do you really need mirrors at all? Perhaps one slow scan will do it. Can the specimen me put on a stage with two servos, one for X and one for Y?
    The your arduino moves the stage, turns on the led, reads the photodetector, turns off the led and repeats.
    It's then all perfectly linear and controlled. Small 4 mm actuators are $10 ( Muscle Wire Actuator - NM706-Super NanoMuscle - ROB-08782 - SparkFun Electronics )
    but larger, 50 and 100mm ones are ~ $100. ( Linear Actuators, Linear Actuator, Miniature Actuator, Miniature Linear Actuator )
    Also this way you can go slower and add up a lot of samples for a higher dynamic range of image.
    Alternatively you can have the arduino just time how long the laser has to be on any given x y spot in order to reach a certain accumulated threshold of fluorescence.
    Highly fluorescent samples would scan quickly while you'd be able to scan even slightly fluorescent ones, only much more slowly.

Oh if you can't move the rock, perhaps you could move the LED/detector part, but also with an x y stage for repeatability and linearity.
Maybe a good mechanical designer (not me) could do it with two inexpensive rotary servo motors.
What do you think?