Needing more than a spark test?

I am considering using a test square-wave pulse from a generator, it's energy spread into a capacitor via a RC low pass filter.
Then, one can use the generator output control to make little increments in amplitude.
Then check if the ADC area assessment of energy tracks those.

In this, we have the pulse rate stay constant, and the period over which we count stay fixed. Any bucket will always see the same count.

We should get a single spike, always the same count, that will move across to the next bucket as we increment the height of the pulses. The idea is to discover just how small a change in energy can reliably move the plot to the next bucket.
 
I may have discovered a problem in my MCA library. I haven't had an opportunity to see how it affects the end result, but....

In the MCA_begin code I calculate the bin size for the MCA's x axis. It is used to convert a floating point input (like voltage peak or pulse area) into an integer that indexes into the MCA array. It uses the length of the array, an unsigned integer, and divides that into the specified data range -- a floating point number. I don't have a typecast from integer to float for the integer....with no resultant complaint from the compiler! I don't know if it's just quietly doing the typecast or not (the latter case would definitely cause problems!). This would be atypical behavior from a C compiler but it's designated as "Cpp" code, to suit the Arduino IDE. Maybe that's the difference?? I'd think that a more modern language would implement even stronger type-testing but mebbe not?
Are you using Arduino IDE? Which version? The older one, or the newer IDE2? I just got burned by this, in IDE2.

In V2, PJRC is using every warning known to mankind, nearly everything unkosher gets flagged. It's annoying as all get out, but it sure helps you find all those warnings! I suspect you are either using IDE 1.8.x or something else. Comparatively speaking V1 IDE is lax compared to V2. I learned this the hard way. Took me a week to fix my working V1 ELS code to get it to run in V2. Was quite the eye opener. So V2 is tough, but that makes for a lot better code. It found all the unused (and dangerous) variables, and complained about every single type issue you could think of. Forced me to use const char, etc.
 
Some observations. Not meant as a criticism, more as trying to understand, and observational.

In MCA_AddPulse, there are interesting things going on. What is the type and value of max and min? You didn't include MCA.h, so they are missing. Or they are in a different header file. What do max and min represent? Just trying to understand what binsize represents.

i gets redefined from uint16_t to int16_t within a few lines. Arduino 2 would complain about that!

i should be a uint16_t. i is the index into your array. I don't think you ever want to index off into la la land by generating a negative number. You do prevent i >= MCA_Bins, but you do not test for i < 0. To prevent a negative index use uint16_t.

The expression for i is a float then converted to int16_t. Can value ever be less than MCA_min? Do you test for that? Should you round it first then convert to uint to get more predictable results? Please note, I do not know if that works reliably!

Perhaps you want to test if normalized value is between
0 and binsize, binsize and 2*binsize, 2*binsize and 3*binsize, etc.
Not as fast as casting, but perhaps more reliable?

Why is MCA_array limited to uint16_t? It seems you check for overflow - why would it overflow? I see you have an overflow return flag, is it used? Is the type just for convenience? Saves memory? Old habits (from little Arduinos)? In real life it is never expected to be that large? Just curious.

Don't feel bad, I had several dozens of these issues that I had to clean up in my ELS code this week after switching to IDE2. The new IDE with its stricter settings wouldn't let me get away with anything. At one point I had 371 lines of warnings... Now 0. My code's a little better too.
 
Are you using Arduino IDE? Which version? The older one, or the newer IDE2? I just got burned by this, in IDE2.

In V2, PJRC is using every warning known to mankind, nearly everything unkosher gets flagged. It's annoying as all get out, but it sure helps you find all those warnings! I suspect you are either using IDE 1.8.x or something else. Comparatively speaking V1 IDE is lax compared to V2. I learned this the hard way. Took me a week to fix my working V1 ELS code to get it to run in V2. Was quite the eye opener. So V2 is tough, but that makes for a lot better code. It found all the unused (and dangerous) variables, and complained about every single type issue you could think of. Forced me to use const char, etc.
I'm using 2.03. That's the Arduino version number. I think Teensyduino is 1.54 or something?
 
Some observations. Not meant as a criticism, more as trying to understand, and observational.

In MCA_AddPulse, there are interesting things going on. What is the type and value of max and min? You didn't include MCA.h, so they are missing. Or they are in a different header file. What do max and min represent? Just trying to understand what binsize represents.

i gets redefined from uint16_t to int16_t within a few lines. Arduino 2 would complain about that!

i should be a uint16_t. i is the index into your array. I don't think you ever want to index off into la la land by generating a negative number. You do prevent i >= MCA_Bins, but you do not test for i < 0. To prevent a negative index use uint16_t.

The expression for i is a float then converted to int16_t. Can value ever be less than MCA_min? Do you test for that? Should you round it first then convert to uint to get more predictable results? Please note, I do not know if that works reliably!

Perhaps you want to test if normalized value is between
0 and binsize, binsize and 2*binsize, 2*binsize and 3*binsize, etc.
Not as fast as casting, but perhaps more reliable?

Why is MCA_array limited to uint16_t? It seems you check for overflow - why would it overflow? I see you have an overflow return flag, is it used? Is the type just for convenience? Saves memory? Old habits (from little Arduinos)? In real life it is never expected to be that large? Just curious.

Don't feel bad, I had several dozens of these issues that I had to clean up in my ELS code this week after switching to IDE2. The new IDE with its stricter settings wouldn't let me get away with anything. At one point I had 371 lines of warnings... Now 0. My code's a little better too.
I just uploaded MCA.h for your viewing pleasure. If that even makes sense ;)

Yes, I caught that uint vs int issue and fixed that. MCA.h reflects that improvement.

Regarding the test for overflow, that was put in place well before I started seeing how much was being put into the MCA array bins. 65536 counts in a single bin would take forever so the overflow test isn't realistic, just anal programming :rolleyes:.

The expression for i is a float then converted to int16_t. Can value ever be less than MCA_min? Do you test for that? Should you round it first then convert to uint to get more predictable results? Please note, I do not know if that works reliably!

The code does test to determine if value is less than MCA_min. I'm using MCA_min and MCA_max to basically establish an energy window. Theoretically, I can set MCA_min to a level that would reject the aluminum peak so that would help reduce the "contaminated" iron peak I'm seeing. But the FWHM for the peaks is pretty wide so it may not be possible to totally eliminate the counts arising from aluminum.

Should you round it first then convert to uint to get more predictable results? Please note, I do not know if that works reliably!
I think that's a good idea. Part of the "fuzzy" appearance of the spectrum plots might be due to "hard" truncation that my code is doing.
 
I'm using 2.03. That's the Arduino version number. I think Teensyduino is 1.54 or something?
I think 1.54 is a bit more lenient. I got forced into upgrading to the 1.58.3beta, because of some library issues on my ELS.

The beta version can be installed via Boards Manager as "V0.58.3". This is to prevent Arduino from auto updating. The latest Teensyduino stable is 1.57.2.

All I can say is the beta version has -Wall set for warnings and no settings in the IDE will calm it down. It's built into the PJRC supplied settings. It generated lots of warnings, where previously there were few. Lets just say it complained a lot. I wouldn't be surprised if it set a flag to be extra picky.
 
I think 1.54 is a bit more lenient. I got forced into upgrading to the 1.58.3beta, because of some library issues on my ELS.

The beta version can be installed via Boards Manager as "V0.58.3". This is to prevent Arduino from auto updating. The latest Teensyduino stable is 1.57.2.

All I can say is the beta version has -Wall set for warnings and no settings in the IDE will calm it down. It's built into the PJRC supplied settings. It generated lots of warnings, where previously there were few. Lets just say it complained a lot. I wouldn't be surprised if it set a flag to be extra picky.
OK -- thanks for the info! I've been worrying about the likelihood of other similar problems in my code so it will be good to see what a more stringent compiler will find.
 
anal programming
Umm, this is actually good.

As for my viewing pleasure? That's a stretch;) Thanks for the file. Very much appreciated.

I'm half thinking of modifying one of my ELS PCBs for this project. I have a blank PCB I can build. It has the display wired, and mounts for the display. Is it possible to buy one of your ADC PCB's? What do you want for one? Yes, I realize it hasn't even been fully tested, but it's a lot better starting point than I have right now. I have nothing built up to convert the stuff which appears to be riding on a 3V DC offset from U1.

I could wire up my PCB to your board. It would be a kludge, but I could then possibly get some data to look at.
 
OK -- thanks for the info! I've been worrying about the likelihood of other similar problems in my code so it will be good to see what a more stringent compiler will find.
Be careful what you ask for. Seriously took me a few days to beat all my warnings into submission. I couldn't believe how many were generated!
 
I think I've found at least one issue that is contributing to the poor results I'm seeing when using pulse area. I've been using a variable called DataClip to determine the end-of-pulse. It's generated in my SetBaseline routine and is computed by adding the lowpass-filtered analog input voltage to the RMS noise. However, each data point entered into my ring buffer is equal to the (float_t) ADC value MINUS the (float_t) baseline voltage. So the pulse data was being truncated because the baseline-offset pulse voltage should decay to zero. On average, anyway.

I changed my code to address the problem and I'm acquiring a new spectrum right now to see how it looks.
 
Back
Top