Turned into long term project; Chronograph (Solved)

HI all

I did not want to buy a chronograph just to use it once every two years, and it is a easy Arduino uno project that I can learn from. NOT

Here some exsamples on the net of nearly precisely what I am attempting:

http://www.glacialwanderer.com/hobbyrobotics/?p=347

http://www.nlvocables.com/blog/?p=76

I started with IR Leds sensor pairs, then IR Leds & Ir transistors, then IR Leds & IR pin diodes, I now have on order some Ir receivers with digital outputs, some more IR pin photodiodes.

code wise I started with analogue read( worked but to slow), went on to digital read(worked but to slow),
Then I had a go at port manipulation but stopped 90% done with that code.

After looking at net a someone’s project that had access to a oscilloscope that its not how fast the pin gets read BUT how often it gets read. With my code the pin does not get read often enough.

It was a good learning curve but enough. I just want it to work. I can not make head or tails from the code giving with the working ensamples on the net.

With my current set up the pin goes high when the ir receiver is blocked because I then can substitute the “sensor” for a thin magnet wire, that would break and sent the pin high. This way I can determine if it is the code or sensor.( tested HIGH and LOW from IR “sensor” with millimetre >0.4V and 4.5v)

I will post my attempt at port manipulation, although I am starting to look at while loops.
Out put to lcd on project and serial monitor for debugging.

/* Attempting to use external interrupts on pins 2,3 on uno
to record the micro seconds when the pin changes state.*/

#include <LiquidCrystal.h>;
LiquidCrystal lcd(12,11,5,4,13,10);

// create memmory space for values//
int first = 2; 
int second = 3;
volatile int time = 0;
volatile int time2 = 0;
float ms,fs,elap;

//declare input pins, atach interrups and start lced and serial 
//monitor

void setup(){
  pinMode (first,INPUT);
  pinMode (second,INPUT);
  attachInterrupt(0,Grab,CHANGE);
  attachInterrupt(1,Grab2,CHANGE);
  Serial.begin (9600);
  lcd.begin(16,2);
  Serial.println("Wainting on shot...");
  lcd.print("Awaiting shot");
}
  // SRI for interup on pin 2.... and where the error leis
  void Grab(){
    time = micros();
    detachInterrupt(0); 
  }
  
  void Grab2(){
    time2=micros();
    detachInterrupt(1);
  }
  
  void loop(){
    
    elap = time2-time;
    if (elap !=0){
    //Serial.println(elap);
    //delay (1000);
    ms = 250000/elap;
    fs = 820210/elap;
    
   // Serial.println(ms);
   // Serial.println (fs);
   // delay (1000);
    if (ms>1){
      Serial.print (ms);
      Serial.println (" M/s");
      Serial.print (fs);
      Serial.println (" F/s)");
      
      lcd.clear();
      lcd.setCursor (0,0);
      lcd.print (ms);
      lcd.print(" M/s");
      lcd.setCursor (0,1);
      lcd.print (fs);
      lcd.println (" F/s ");
      time = 0;
      time2 =0;
    }}}

Please help or some explanation of code given with working net examples.

I just want it to work.

Can you explain:

  • What the code currently does
  • What you are expecting

I gather they differ, but it isn’t obvious in what way.

volatile int time = 0;
volatile int time2 = 0;

Time variables should be unsigned long, not int.

Hi Nick

I was attempting to use interups for two gates made up of IR led and IR transisters.

When pin goes High (pin2 interupt0) record micros and detach interrupt. When pin3 goes High (interrupt 1) record micros and detach interrupt. In the main loop function do some math and print out to lcd and serial monitor meter/sec and feet/sec.

O, I have read your previous posts about similar projects http://forum.arduino.cc/index.php?topic=198520.0 but I find it really hard to follow your code. Your help is appreciated.

Tjaart: ... and detach interrupt.

Don't do that! That's a really slow operation. Is there another bullet following so closely behind the first one that you have trouble keeping them apart?

In another net tutorial about interrupts, they use this method to" debounce" the signal. Since the pellet might be blocking the IR for more than one read/sense time cycle.

I would be considering the timer input capture registers. It's the most accurate way to measure time intervals.

I now have on order some Ir receivers with digital outputs

I have been following the various incarnations of this thread and I believe that you have never had a manageable signal to start and stop timers. Your latest effort with the digital sensors sounds very promising.

Pin change or external interrupts, timer input capture interrupts, and while loop pin change monitoring should all work better than your attempts with the analogRead and pin polling in loop.

I agree with MorganS that you should not detach the interrupt. Because you have two sensors, and the bullet will pass each in turn, I think that you will want to use RISING or FALLING to trigger the timing.

I think one of the issues you will face depends upon the speed of the bullet and the spacing of the sensors. I don't remember the timing from the previous threads, but you may wish to work with the hardware timers rather than micros().

I think that the first step is to get the new sensors, see if you get clean transitions, and test out the code you have with slight modifications.

Hi

"Pin change or external interrupts, timer input capture interrupts, and while loop pin change monitoring should all work better than your attempts with the analogRead and pin polling in loop. "

I am still a newby at coding so interrupts are a high demand for me, let alone 'timer input interrupts' and all this other code about 'bits and bytes'

I got the best results with digital read. After reading: http://gammon.com.au/interrupts According to info from forum I have about 10microsec (pellet in front of IR) some time+/- 300microsec between first and second IR gate, and about 10 micros again. (pellet in front of ir)

Maybee even interup is to slow? That cant be, can it?

Maybee even interup is to slow? That cant be, can it?

No. You are well within the capabilities of the 16 MHz processors if you are trying to time two events 300 microseconds apart. The pellet just needs to block enough IR during its passage through the gate to produce a trigger signal to start and stop the timer.

Do you have the specifications for the new sensors?

Think I am going to make a little video and post it up, just to calm some of the confusion. (my confusion)
Be back in a little while

Tjaart: Hi Nick

I was attempting to use interups for two gates made up of IR led and IR transisters.

When pin goes High (pin2 interupt0) record micros and detach interrupt. When pin3 goes High (interrupt 1) record micros and detach interrupt. In the main loop function do some math and print out to lcd and serial monitor meter/sec and feet/sec.

O, I have read your previous posts about similar projects http://forum.arduino.cc/index.php?topic=198520.0 but I find it really hard to follow your code. Your help is appreciated.

Yeah, instead of detaching the interrupts, if you just want the first transition to be kept, just do this (much quicker):

void Grab(){
    if (time == 0) {
        time = micros();
    }
  }

  void Grab2(){
    if (time2==0) {
        time2=micros();
    }
  }

I will most definitely use that, thanks arduinodlb.

(to all video still uploading to you tube)

You can service an interrupt in around 4 µs, so timing 300 µs is quite feasible. I don't see what port manipulation will give you. Once the interrupt fires you just want to quickly store the current time. I should point out that micros() has a resolution of only 4 µs anyway. You can improve on that by using your own timers.

I was attempting to use interups for two gates made up of IR led and IR transisters.

You haven't stated what results you are getting. Is the code not working at all? Working but giving unbelievable results? It isn't clear what problem you are trying to solve, is.

OK

Im back heres the vid:

https://youtu.be/Eo3Jhmp1Q54

Here is some older vids: https://www.youtube.com/watch?v=dcpKH3gw_tY https://www.youtube.com/watch?v=Snt0KNvrdWU

If any body feel they can do this, feel free to jump in. Who's got the best/fastest code for this.

Sense pins need to go from low to high upon trigger. (should one remove the 'sensor' and replace it with a wire to break)

I will have one final go at the code two.

Response to last post: The code I posted is, the code I am working now. But Have decided to change in to use a wile loop incorporating port manipulation and interrupts / if that's possible at all/ AND looking for some help.

Tjaart: Response to last post: The code I posted is, the code I am working now. But Have decided to change in to use a wile loop incorporating port manipulation and interrupts / if that's possible at all/ AND looking for some help.

Just using the interrupts should be enough for your purposes. You should not need to do anything more complicated than that.

Your wire panels look like a good idea, and if they can switch a pin when they break they should enable you to develop your code before the digital IR sensors arrive.

But Have decided to change in to use a wile loop incorporating port manipulation and interrupts / if that's possible at all/ AND looking for some help.

Direct port reading of a pin using PINX(where X is the port register) with a while loop is a good technique for this measurement. You are not actually using an interrupt with the while loop. Your are holding the code until the pin state changes

If , for example you are using INPUT_PULLUP and the wire break sends a pin HIGH, you code might look something like this if your wire panels are connected to D4 and D5.

while ((PIND & B00010000) == B00000000);    // while LOW, wait for HIGH on Digital Pin 4
    startTime = micros(); //when pin goes HIGH record the start time
  while ((PIND & B00100000) == B00000000);    // while LOW, wait for HIGH on Digital Pin 5
     endTime = micros(); ///when pin goes HIGH record the end time

As a later refinement, the micros() can be changed for reading of timer values with higher precision.

thanks cattledog

That’s the kind of advise I need.

Tjaart: Response to last post: The code I posted is, the code I am working now. But Have decided to change in to use a wile loop incorporating port manipulation and interrupts / if that's possible at all/ AND looking for some help.

Feel free to answer the questions I posted above:

You haven't stated what results you are getting. Is the code not working at all? Working but giving unbelievable results? It isn't clear what problem you are trying to solve, is.

The code I posted is, the code I am working now.

Right, so problem solved?

AND looking for some help.

For what? You said the code is working.

Unfortunately I have to leave my laptop now.

I will hook it all up tomorrow again and post a vid. Should explain what's wrong with it at this stage.