Bug: Ballistic Chronograph

I’m working on a building a ballistic chronograph (bullet speed measurer), and appear to have a bug somewhere in my code. When I record and tabulate my values, the first one is always rather odd/ not what it should be. Sometimes I get a negative value, or it is simply very low (e.g. ~150 fps rather than ~4500 fps). I’m using another arduino to fake external outputs for testing purposes, so that could also be the problem, although I’m not sure how. I think I’ve prevented any overflow errors in the timing section, but I might have missed something. I could probably find the problem myself, except I’ve been working on the project too long and another pair of eyes would probably be much more effective at finding errors. :slight_smile: You know how it gets in a big project.

Aside from the bug, any suggestions for optimization for speed and space efficiency would be appreciated. I’m not that great a coder :slight_smile:

I had to attach it: it came to more than 9000 characters.


Ballistic_Chronograph_Full_Code.ino (14.1 KB)

So much of your code is displaying the data on the tft that it gets in the way. Also, it makes it difficult for us because most of us won't have that display so reproducing your error becomes difficult.

My suggestion is to make a test bed that doesn't use the tft, but just the "ballistics" code and use that for testing. Once that's stable, then add the tdt display code back in. That approach would get rid of a lot of clutter that doesn't seem to be pertinent to your problem. Also, you define the loop counters multiple times as the first expression in a for loop. Why? Why not just define it once at the top of loop()? Some of these loop test against shots, but that variable is both increment and decremented. What happens if it is 0 and you decrement it? It's an unsigned data type.

I have very briefly scanned your code and have a couple of observations:

  1. You use noInterrupts() without a close corresponding interrupts().
  2. Your ISR contains a function call which is a potential overhead.
  3. what does set() do in setup() ?

Thanks for the quick replies!

I'll work on cleaning it up for a test version. Thanks for the idea. (It might take a bit to finish that. :slight_smile: )
I guess I could clean up the counters; doing it this way makes it a bit more legible, but your suggestion would probably be more efficient. As for shots, I think I prevented decrementing from 0, as I only call a decrement in one place:
if (shots > 0) {
shots -= 1;

the noInterrupts() is called to prevent any objects that trigger the sensor inputs from being observed and causing an interrupt when the gui is being used. Only when I go into "shooting mode" do I call interrupts(). Simplifying the code as suggested should help avoid this kind of communication problem. I realize it's somewhat hard to follow as is. Ditto with set(), that's just for the gui, nothing to do with timing.

As far as the function call in my ISR, it's required to store the value just recorded from timer1, but I suppose it would be tidier to move all that right into the ISR.