Forum Rule: Always post complete source code & details to reproduce any issue!
Page 6 of 6 FirstFirst ... 4 5 6
Results 126 to 143 of 143

Thread: Teensy 4: Global vs local variables speed of execution

  1. #126
    Quote Originally Posted by jonr View Post
    Note that while the T4 doesn't have a pseudo differential mode, with two converters, one can sample the signal and a reference voltage at about the same time. So similar common mode noise/offset reduction benefit.
    So connect one ADC to a voltage reference and read the signal on the other?

    I have read a bit more about the circuit part of things, I have a few more things to try. I think the noise can be further reduced. Right now the only thing that made a noticeable difference was a low pass filter before the ADC. I also have to try this as well: http://sim.okawa-denshi.jp/en/OPstool.php

    Also I have to try a charge amplifier piezo circuit.

    https://www.allaboutcircuits.com/tec...ctric-sensors/

  2. #127
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    485
    > connect one ADC to a voltage reference and read the signal on the other

    Yes, ideally with the voltage reference being near the signal source and both lines treated exactly the same (ie, differential pairs).

  3. #128
    Quote Originally Posted by jonr View Post
    > connect one ADC to a voltage reference and read the signal on the other

    Yes, ideally with the voltage reference being near the signal source and both lines treated exactly the same (ie, differential pairs).
    Actually itís a non issue. With defragsters unrolled loop and placing all code only while waiting for the ADCís I can use 8 averages and still get 30 reads per sensor per millisecond which is probably twice more than what I need.

    Back to the topic of global vs local variables, Iím having a hard time to figure out how to use only local variables for this application.

    Iím doing many loops fast and I need the program to remember the previous values through the loops and itís a lot of values. Seems like local variables would only make it more messy.

    Iíve read that local variables are evil but Iím trying to figure out how to best approach this and not use so many global ones.

    Basically I need to do peak tracking on the previous values while the adc is sampling. I need the functions to return many values (probably need to make the functions into many smaller ones) so not sure how one would pass the values on and remember them for the next loop.

    When is it preferable to use global vs local variables?

    I can ise static but howís that different from a global variable?

  4. #129
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,967
    Awesome the unrolled loop shows promise! Are the 8 averages on 10 or more bits of resolution?

    It is global variables that are evil ... because that is the easiest thing to do - though can be made perfectly safe and good depending on the use case - just a debate issue

    Generally having variables 'only available as and where needed' prevents them getting used or abused where not expected or intended/required - makes code easy to understand and maintain. Versus integrated in multiple places that prevents any easy or expected change to their use when needed later.

    Static/Permanent data areas are needed - just a matter of how they are accessed.

    Globals are handy and permanent - but if used in 10 places - that is 10 places that need to change to alter the nature of the global variable - or 10 places where some use could alter the global unexpected to the other 9 places.

    Locals on the stack don't survive leaving the function, they can be made static so the value is maintained outside the stack and they retain their value on re-entry to that function where only that function can see them.

    The fun is finding the middle ground that limits access to those that need it and know what can be done and what the data represents, and make it clear when changed exactly where and how it was used.

    Depending on the use case there are ways to encapsulate the data in a class or other code that provides needed uniform and limited access.

  5. #130
    Quote Originally Posted by defragster View Post
    Awesome the unrolled loop shows promise! Are the 8 averages on 10 or more bits of resolution?

    It is global variables that are evil ... because that is the easiest thing to do - though can be made perfectly safe and good depending on the use case - just a debate issue

    Generally having variables 'only available as and where needed' prevents them getting used or abused where not expected or intended/required - makes code easy to understand and maintain. Versus integrated in multiple places that prevents any easy or expected change to their use when needed later.

    Static/Permanent data areas are needed - just a matter of how they are accessed.

    Globals are handy and permanent - but if used in 10 places - that is 10 places that need to change to alter the nature of the global variable - or 10 places where some use could alter the global unexpected to the other 9 places.

    Locals on the stack don't survive leaving the function, they can be made static so the value is maintained outside the stack and they retain their value on re-entry to that function where only that function can see them.

    The fun is finding the middle ground that limits access to those that need it and know what can be done and what the data represents, and make it clear when changed exactly where and how it was used.

    Depending on the use case there are ways to encapsulate the data in a class or other code that provides needed uniform and limited access.
    Your idea for the unrolled loop is genius.

    Iím getting great results with 10 bits and 8 averages although itís possible 12 bits with 4 averages may be even better. There is also the possibility to use less averages on the ADC and in stead use some kind of average in software to get more bits. Iíve read about noisy signals opening up the possibility to give much more resolution by averaging the signal into more bits but I havenít explored it. Anyway this is working great for now as is.

    I went over the part about classes a bit too fast when I read the C syntax I think. How would a class be used in a scenario with sensors, peak values and whatnot?

    Any simple example I could use as inspiration?

    Basically Iím storing the three last rising values before a peak (both the sensor value and the micros when they occurred). Then I track the three falling sensor values after the peak. Iím using a window threshold approach. I plan to average them to get a more accurate/consistent occurrence in time. The reason for all this is to use it later to calculate striking position with time difference of arrival but that is a future problem to solve. Also remove signal hot spots when sensors are struck directly.

    Right now I made a function to do all that and made everything global. Only thing that is passed To the function is the sensor value.

  6. #131
    Why not try using a sliding window averaging scheme?

    The advantage is that you get new results or new data with every completed analog conversion, but it is simply averaged with the previous raw analog data. You can make as many averages as you want. I use 16 because I can simply right shift the sum 4 times to get the averaged results.

    I just posted some example code for this in another post: https://forum.pjrc.com/threads/61801...-axis-bouncing

    Just make sure the number of averaged samples is a power of two.

  7. #132
    Yeah I've thought about that too. I've thought about using 10bit readings, multiply them by say 4 and then do the averages. That should get more resolution (I think) because sometimes a voltage is between two "steps" and it jumps up and down.

    For now this works well and is simpler. I'm still very new at coding and I'm thinking I'd get something that works and I can add improvements and explore better ways to do it later.

    Thanks for the example, I will save it for later.

  8. #133
    Quote Originally Posted by frankzappa View Post
    Yeah I've thought about that too. I've thought about using 10bit readings, multiply them by say 4 and then do the averages. That should get more resolution (I think) because sometimes a voltage is between two "steps" and it jumps up and down.

    For now this works well and is simpler. I'm still very new at coding and I'm thinking I'd get something that works and I can add improvements and explore better ways to do it later.

    Thanks for the example, I will save it for later.
    Are you talking about performing oversampling and averaging as a means to improve resolution (i.e., improving SNR of white noise)?

  9. #134
    Yeah. I figure if you have say ten sensor readings. They have a value of 10 and 11 every other reading. If you average them out they will still probably show 10 and 11 but the real value is 10,5. If multiply them by two so they are showing 20 and 22 in stead and then average them out they will show a consistent 21.

    Iím sure there are even better ways to do this.

    There is an even better way to do it by applying a white noise and force the values to jump up and down and use some algorithm I think but I havenít explored it.

  10. #135
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,967
    It all depends on the reception and measure of the analog values in the system for how it actually works out to get better reading on two more bits ... so only you can test this ... i.e. YMMV

    But it seems the Resolution of 12 bits and 4 averages would be faster and better - and allow discarding the lower two bits (/4) leaving what should be a more stable lowest bit.

    Not sure how clean the analog reading is when the input to test is done after changing it 5 times in a row - ten times per millisecond? That is if it has any effect on the perhaps the first reading in each average group. Also how independent the two ADC unit are from each other in that fast update/change environment. Ideally they are great and wonderful - but earlier posts noted that simple analogRead() was 'at first' giving better results. Again since these are fast percussive hits the values are never stable for very long unless un-hit - not like a simple potentiometer or other slowly changing input. And given that adding averaging on top of the read averaging will certainly smooth the value - but it also might average out true peaks.

  11. #136
    Quote Originally Posted by frankzappa View Post
    Yeah. I figure if you have say ten sensor readings. They have a value of 10 and 11 every other reading. If you average them out they will still probably show 10 and 11 but the real value is 10,5. If multiply them by two so they are showing 20 and 22 in stead and then average them out they will show a consistent 21.

    I’m sure there are even better ways to do this.

    There is an even better way to do it by applying a white noise and force the values to jump up and down and use some algorithm I think but I haven’t explored it.
    Read this applications note on oversampling. It will tell you how to calculate the number of samples required to get X bits of increased resolution. You need a lot of samples, which may render what you want to achieve as not doable, but you should be able to answer that after reading it...

    https://www.cypress.com/file/236481/download

  12. #137
    @defragster
    Iím measuring a half wave that is about 0.5 - 2ms in lenght so not very fast signals. Signals above say 1000 Hz are just noise in this application.

    Averaging is good in this case.

    I did notice some spillover to other pins on the same ADC. However I was using everything at very high speed and also my circuit had a 4k resistance so I assume it can be tweaked away by just removing the resistance and use maybe medium speed. I will have to test that but one problem at a time. I will test 12 bits as well.

    Reading just one pin vs reading 10 doesnít seem to affect signal quality. The adcs seem completely independent but as I said a small spillover to other pins on the same ADC can be seen. Not a total catastrophy because Iím reading the same source with multiple sensors but I should be able to reduce it.

    Is there any reason to not use division on the teensy since itís so fast? The previous comment said bit shifting in stead of division/multiplication.

  13. #138
    Thanks 😊 🙏

  14. #139
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,967
    The compiler likely will take away any clear /2 or /4 and program as a shift, and if not the CPU can do integer divisions in a single cycle AFAIK - so not worth worrying over the difference ... what ever is clearest for your reading and usage without confusion.

    Interesting the signal levels will persist for at least 500 us or more - indeed then if reading 10 times per 1 ms then doing a rolling avg of four of them should get a good value.

  15. #140
    Quote Originally Posted by defragster View Post

    Interesting the signal levels will persist for at least 500 us or more - indeed then if reading 10 times per 1 ms then doing a rolling avg of four of them should get a good value.
    Well itís an AC signal, the first peak is a negative half wave sinusoidal signal that lasts up to 2ms but it vibrates up/down for maybe 50milliseconds after the first peak before calming down completely. The first negative peak is of interest and is triggered. The rest of it is a matter of making the threshold an envelope that passes barely above the rest of the 50ms so new signals can be triggered if they are above the aftershocks.

  16. #141
    Quote Originally Posted by frankzappa View Post
    Well it’s an AC signal, the first peak is a negative half wave sinusoidal signal that lasts up to 2ms but it vibrates up/down for maybe 50milliseconds after the first peak before calming down completely. The first negative peak is of interest and is triggered. The rest of it is a matter of making the threshold an envelope that passes barely above the rest of the 50ms so new signals can be triggered if they are above the aftershocks.
    More likely it is the sample and hold circuit inside the A/D.

  17. #142
    Quote Originally Posted by Loren42 View Post
    More likely it is the sample and hold circuit inside the A/D.
    Yeah as I said I used the fastest settings for conversion and sampling. I can use medium and see if it goes away. My guess is that the capacitor inside the A/D doesnít discharge in time for some reason.

  18. #143
    Quote Originally Posted by frankzappa View Post
    Yeah as I said I used the fastest settings for conversion and sampling. I can use medium and see if it goes away. My guess is that the capacitor inside the A/D doesn’t discharge in time for some reason.
    Best to read the manufacture's data sheet on the A/D operation or ask tech support.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •