Pulsing a Laser on a Photocell and Recording

Hello guys,

Device: Arduino Duevilanove ATMEGA328

So I’m in the process of building a device where I pulse a laser at a photocell and record the drop in voltage across a 10kOhm resistor (in series with photocell) at the same time. I was able to get it to record the voltage through matlab via serial, but can only do it with the laser constantly on. When I try to make a code for the laser to blink and record the information at the same time, it is VERY SLOW and matlab fails to record some of the data (I can tell that some pieces of data is being dropped). Anyone know how to make the Arduino do two things at once? Pulse laser at a certain interval and record at that same interval? This is crucial for my project. Any help that can be provided will be very much appreciate. Thank you guys!

“Pulse” could mean anything from femtoseconds to days.
Could you give us some idea of the timescales involved in your process and post the sketch you have?

If you are using a Cadmium Sulphide photocell, you’re not going to get very speedy. If you can detect a 5kHz signal I would be surprised.

Use a photo-transistor instead.

50Hz would be going some for CdS!
Where did the 5kHz value come from?
Have I missed something?

I want to pulse it for 100ms if possible. That is the timing I’ve been using. As for the photocell. I’m using a cadmium sulfide photocell. I don’t know if what you said was true, Mike, but I can get Matlab to produce real time data signal. I visually plot the data received from the arduino and it can detect when someone blocks the laser emission instantaneously. Here are some pictures of my setup:

http://img21.imageshack.us/img21/2746/img0260tw.jpg
http://img27.imageshack.us/img27/352/img0253d.jpg

The laser is constantly powered on right now. The laser reflects off a reflective pressure sensor (can’t see it in the frame) and shines back on the photocell. Here is my current code:

int PhotoresistorPin;
int PhotoresistorReading;
int ledPin =  13;

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

void loop(void)
{
  for (int i = 0; i <= 100; i++)
  {
  PhotoresistorReading = analogRead(PhotoresistorPin);
  Serial.println(PhotoresistorReading);
  digitalWrite(ledPin,HIGH);
  delay(100);
  digitalWrite(ledPin,LOW);
  delay(100);
  }
}

The code will be executed once Matlab tells it to.

10Hz shouldn’t be a problem.

As for doing more than one thing at a time, have a look at:

Just remember that at 9600 baud, each character takes just over 1ms to transmit, so the most you can do is 96 characters in one pulse period.

(please use the “Code” (#) button when posting code).

Ok, I am sorry. I fixed it. I did not know that that was the option for code.

I will try out your idea and get back to you. Thank you.

Ok, AWOL.

So I augmented the blink without delay code and it works pretty well!

The only problem that I have now though is to restrict the data going through the serial. If I click on the “Serial Monitor” button on the Arduino Java Environment, it is recording at a substantial rate (50-100) samples a seconds it seems. How can I shorten this so that it doesn’t overload my memory?

Sure - just put another set of delay-less pauses within the loop.
It’s good exercise!

Sorry, I might need some clarification. :frowning:

How exactly does “delay-less pause” work? What’s the code. I’m searching for it online and I don’t see what it means. I know generally you use delay(100) or something, but what’s delay-less?

Delayless pause is where you don’t use delay to make it pause for a time (blink without delay is an example).

It means the arduino can be doing something productive whilst ‘waiting’.

hmm, ok. I can’t get it to work still. This is my original augmented code. I still can’t get it to record at the same frequency as the blinking light:

int PhotoresistorPin;
int PhotoresistorReading;
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 100;           // interval at which to blink (milliseconds)

void setup(void)
{
  // set the digital pin as output:
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);      
}

void loop(void)
{
  {
  PhotoresistorReading = analogRead(PhotoresistorPin);
  Serial.println(PhotoresistorReading);
  }
  if (millis() - previousMillis > interval)
  {
    // save the last time you blinked the LED 
    previousMillis = millis();   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
      
    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

You need to reuse the mechanism that you used to pulse the laser at 10Hz to read the analogue pin at, say, 25Hz.
Don’t forget that as soon as “loop” returns, it gets called again.

[edit]

pulse the laser at 10Hz

Make that 5Hz.[/edit]

Ohhh, I got it. I just had to move one of my lines of code. Thanks a lot AWOL. I might come back and make another thread on another topic if I run into trouble with my next step. Thanks again!

AWOL,

I have one last question. I have been trying to figure out how this “save to RAM” on the arduino works. I want to use the previous code that I have and make it save the data to the arduino’s internal memory for later extraction to matlab for data analysis. How can I augment the following code to do this?

int PhotoresistorPin;              //defines PhotoresistorPin
int PhotoresistorReading;          //defines PhotoresistorReading
int LaserState = LOW;              //sets laser "off" by putting low power
long previousMillis = 0;           //stores last time laser was updated
const int LaserPin =  13;          //designates laser pin number on arduino board
int LEDPin = 11;                    //designates LED pin number on arduino board

long timer = 100;                  //interval that the laser will blink at in milliseconds

void setup(void)
{
  Serial.begin(9600);
  pinMode(LaserPin, OUTPUT);       //sets digital port to "output"   
  pinMode(LEDPin, OUTPUT);
  delay(5000);
  digitalWrite(LEDPin, HIGH); delay(500);
  digitalWrite(LEDPin, LOW); delay(500);  
  digitalWrite(LEDPin, HIGH); delay(500);
  digitalWrite(LEDPin, LOW); delay(500);
  digitalWrite(LEDPin, HIGH); delay(500);
  digitalWrite(LEDPin, LOW); delay(500);
  digitalWrite(LEDPin, HIGH);
}
void loop(void)
{
  PhotoresistorReading = analogRead(PhotoresistorPin);
  
  if (millis() - previousMillis > timer)
  {
    previousMillis = millis();                           //saves the last time the laser was turned on
    Serial.println(PhotoresistorReading);                //prints voltage ratio to serial

    if (LaserState == LOW)                               //turns laser on/off or vice versa
      LaserState = HIGH;
    else
      LaserState = LOW;

    digitalWrite(LaserPin, LaserState);                  //sets laser with the LaserState of the variable
  }
}

Anyone else is free to chime in. This is great help! Thanks in advance for advice!

For that, you need an array and a some means of indexing it.
Be aware though, that the AVR is very limited wrt RAM.
http://arduino.cc/en/Reference/Array

For reading and writing stored data that remains on power loss you want:
http://www.arduino.cc/en/Reference/EEPROMWrite
and
http://arduino.cc/en/Reference/EEPROMRead

Mowcius