Help with Uno reset after signal aquisition

Hello. I am writing code to send TTL signal pulses to a laser based on input pulses recieved from a camera. The code takes interrupts from the camera pin and runs code based the frame for the imaging sequence. What I would like the program to do would be to reset the arduino after the experiment to get ready for the next camera signal. This works great, except the camera will often send more pulses at the end of the video than frames recorded, messing up the reset. I coded in a serial "reset" command that I can send to the Uno, but my users want a more automatic solution. I'm wondering if maybe like a timer will run that resets the arduino after a couple of seconds if there aren't any pulses from the camera? anyone else have a better solution? Any help would be great thanks.

/* defining variables for input parameters*/
/* pin setup for lasers and camera */
int EMCCD_FIRE = 2; 
int LASER552 = 11;
int LASER647 = 12;

String command;
/* setup of frames per cycle */

int r = 200;
int g = 200;
/*int v = 2; */
int cycles = 5;
int startFrame = 50;
int stopFrame = startFrame + cycles*(r+g);
int framesPerCycle = r+g;

volatile unsigned int pulse; 

void(* resetFunc) (void) = 0;

void setup() 
{ 
Serial.begin(9600); 
pulse = 0;
pinMode(EMCCD_FIRE, INPUT); 
pinMode(LASER552, OUTPUT);
pinMode(LASER647, OUTPUT);
digitalWrite(LASER552, LOW);
digitalWrite(LASER647, LOW);
attachInterrupt(digitalPinToInterrupt(2), count_pulse, RISING); 
interrupts();
} 
 
void loop() {
  if(Serial.available()) {
    command = Serial.readStringUntil('\n');

    if(command.equals("reset")){
      Serial.print("Reset");
      delay(1000);
      resetFunc();
    }
  }
  
  
  
  
}

void count_pulse() {
  pulse++; 
  if (pulse % 10 == 0) { 
    Serial.print("Frame number: "); 
    Serial.println(pulse);
  } 

  int phase = pulse % framesPerCycle;
  /*Serial.println(phase); */
  
  if (phase >=r && pulse <= framesPerCycle*cycles) {
    digitalWrite(LASER647,LOW);
    digitalWrite(LASER552,HIGH);
  }
  else if (phase < r && pulse <= framesPerCycle*cycles) {
    digitalWrite(LASER647,HIGH);
    digitalWrite(LASER552,LOW);
  }
  
  else {
    digitalWrite(LASER647,LOW);
    digitalWrite(LASER552,LOW);
    /*resetFunc(); */
  }
} 

If I understand correctly ……

It shouldn’t be needed to reset the Arduino , just use a procedure to reset variables if your end of message is detected , then start listening again .
Resetting is a bit of a crude way of programming , but if you must , you can just use a digital output connected to the reset pin .

If @hammy and I are not wrong, there seems to be only "pulse" that had to be reset ...

You may have a look at this:

/* defining variables for input parameters*/
/* pin setup for lasers and camera */
int EMCCD_FIRE = 2; 
int LASER552 = 11;
int LASER647 = 12;

String command;
/* setup of frames per cycle */

int r = 200;
int g = 200;
/*int v = 2; */
int cycles = 5;
int startFrame = 50;
int stopFrame = startFrame + cycles*(r+g);
int framesPerCycle = r+g;

volatile unsigned int pulse; 
volatile boolean ResetPulses = false;

unsigned int oldpulse = 0;

void(* resetFunc) (void) = 0;

void setup() 
{ 
Serial.begin(9600); 
pulse = 0;
pinMode(EMCCD_FIRE, INPUT); 
pinMode(LASER552, OUTPUT);
pinMode(LASER647, OUTPUT);
digitalWrite(LASER552, LOW);
digitalWrite(LASER647, LOW);
attachInterrupt(digitalPinToInterrupt(2), count_pulse, RISING); 
interrupts();
} 
 
void loop() {
  if(Serial.available()) {
    command = Serial.readStringUntil('\n');

    if(command.equals("reset")){
      Serial.print("Reset");
      delay(1000);
      resetFunc();
    }
  }

  printPulses();  // Prints the no of pulses 

  if (ResetPulses) {  // This is the "Reset function"
    pulse = 0;
    oldpulse = 0;
    ResetPulses = false;
    Serial.println("Reset pulses to zero!");
    delay(2000); // Just to wait for some time ... in case of unwanted pulses coming in
    Serial.println("Ready for the next job ...");
  }
}

void printPulses(){
  if (oldpulse != pulse){  // oldpulse makes sure that this is only done once in loop()
    oldpulse = pulse;
    if (pulse % 10 == 0) {  
      Serial.print("Frame number: "); 
      Serial.println(pulse);
    } 
  }
}  

void count_pulse() {
  pulse++; 

  int phase = pulse % framesPerCycle;
  
  if (phase >=r && pulse <= framesPerCycle*cycles) {
    digitalWrite(LASER647,LOW);
    digitalWrite(LASER552,HIGH);
  }
  else if (phase < r && pulse <= framesPerCycle*cycles) {
    digitalWrite(LASER647,HIGH);
    digitalWrite(LASER552,LOW);
  }
  
  else {
    digitalWrite(LASER647,LOW);
    digitalWrite(LASER552,LOW);
    /*resetFunc(); */
    ResetPulses = true;   // Sets the boolean to true if the conditions to reset are met
    
  }
}

I have allocated Serial printing and the variable reset to loop() (as Serial printing in an ISR is not recommended).

Is anything wrong with this approach?

Yes I think this is exactly what I need! Thank you for writing a better "reset" function. I think the delay is exactly what I need. I wasn't sure if the interrupt signal would overwrite a delay so I'm glad it doesn't. Thanks!

I'm glad it helped you!

Depending on how your overall design works you can still of course optimize:

  • Remove the Serial reset
  • Delete or adjust the delay() after reset of the variables
  • If the delay is not required you could reset the variables in the ISR directly (just change oldpulse to volatile too)

Good luck with your project!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.