Time measurements for function in microcontroller - microcontroller

I am using two microcontrollers for a project, I want to measure execution time for some code with the help of internal timer of both microcontrollers. But One microcontroller's timer count till 32 bit value and second microcontroller's timer can count till 16bit value then it restart. I know that execution time of code is more than 16 bit value. could you suggest me any solution for this problem. (Turning ON and OFF GPIO pin doesn't provide useful results)

You should be able to measure execution time using either type of timer, assuming that execution time is less than days or hours. The real problem is how to configure the timer to meet your needs. How you configure the timer will control the precision or granularity of the measurement, as well as the maximum interval that can be measured.
The general approach will be thus:
Identify required precision and estimate the longest interval to be measured
Given the precision, determine the timer clock prescaler or divider that will meet your precision requirements. For example, if the clock speed is 50 MHz, and you need microsecond precision, then select a prescaler such that (Prescaler) / (Clock speed) ~ 1 microsecond. A spreadsheet helps with this. For this case, a divider value of 64 gives us about 1.28 microseconds per timer increment.
Determine if your timer register is large enough. For a 16-bit timer, you can measure (1.28 microseconds) * (2^16 - 1) = 0.084 seconds, or about a tenth of a second. If the thing you are measuring takes longer than this, you will need to rethink your precision requirements.
You should by now have identified the key parameters to configuring the timer, keeping in mind the limitations. If you update your answer with more specifics, such as the microcontrollers you plan to use and what you're trying to measure, I can be more specific.

Related

BLE Cycling Speed and Cadence Service - Crank Timing Data

A Bluetooth LE Cycling Speed and Cadence sensor sends measurements data according to the Gatt characteristic measurement data. For the crank cadence this is:
Cumulative Crank Revolutions - an unsigned 16bit integer
Last Crank Event Time - an unsigned 16bit integer with 1/1024s resolution
I'd like to understand how the Last Crank Event Time is defined. The documentation makes it sound like a timestamp but because it is a 16bit integer at 1/1024s it overflows after about 1 minute. So I suspect it is actually a time interval. Below is a sequence of events on a time scale. Message B sends n+2 for the number of crank revolutions but what is the Last Crank Event Time for B?
In section "4.4 CSC Measurement" of the Cycling Speed and Cadence Profile document it says:
The Collector shall take into account that the Wheel Event Time and
the Last Crank Event Time can roll over during a ride.
so my reading of this is that it is a time stamp but as you only need to know the difference between the last two readings it can still be calculated even if it overflows.
There is more information in the Cycling Speed and Cadence Service (CSCS) document that states:
The ‘crank event time’ is a free-running-count of 1/1024 second units
and it represents the time when the crank revolution was detected by
the crank rotation sensor. Since several crank events can occur
between transmissions, only the Last Crank Event Time value is
transmitted. This value is used in combination with the Cumulative
Crank Revolutions value to enable the Client to calculate cadence.
The Last Crank Event Time value rolls over every 64 seconds.
Calculation of cadence at the Collector can be derived from data in two successive measurements. The Collector calculation can be performed as shown below:
Cadence = (Difference in two successive Cumulative Crank Revolution
values) / (Difference in two successive Last Crank Event Time values)

Arduino Lightbulb Control

I am completely new to arduinos, and I am trying to run a lightbulb-style apparatus off of an arduino uno, and I need it to only operate on a certain time interval that I can adjust according to the situation. I believe that there is an internal time function in the arduino that counts in milliseconds. All i need it to do is turn on after a set amount of time, and then turn off after about a minute. How would I go about setting up the code for this?
You can use the millis() function to get the current arduino operational time in milliseconds. Then compare it in the next loop(). You probably don't care what the real time is, just the relative time since the last time you checked or did something. You can create a variable to store the last event time and compare the current time to that.
Be aware that millis() may be quite large if your program runs for a long time so you should use an unsigned long type, otherwise the value may roll over the top bit and become interpreted as a negative number (this is a common problem).

Why does the first execution of an Ada procedure takes longer than other executions?

I try to write a delay procedure for a FE310 microcontroller. I need to write this procedure because I use a zero footprint runtime (ZFP) that doesn't provide the native Ada delays.
The procedure rely on a 64 bits hardware timer. The timer is incremented 32768 times per second. The procedure reads the timer, calculates the final value by adding a value to the read value and then reads the timer until it reaches its final value.
I toggle a pin before and after the execution and check the delay with a logic analyzer. The delays are quite accurate except for the first execution where they are 400 us to 600 us longer than requested.
Here is my procedure:
procedure Delay_Ms (Ms : Positive)
is
Start_Time : Machine_Time_Value;
End_Time : Machine_Time_Value;
begin
Start_Time := Machine_Time;
End_Time := Start_Time + (Machine_Time_Value (Ms) * Machine_Time_Value (LF_Clock_Frequency)) / 1_000;
loop
exit when Machine_Time >= End_Time;
end loop;
end Delay_Ms;
Machine_Time is a function reading the hardware timer.
Machine_Time_Value is a 64 bits unsigned integer.
I am sure the hardware aspect is correct because I wrote the same algorithm in C and it behaves exactly as expected.
I think that GNAT is adding some code that is only executed the first time. I searched to web for mentions of a similar behavior, but didn't find anything relevant. I found some information about elaboration code and how it can be removed, but after some research, I realized that elaboration code is executed before the main and shouldn't be the cause my problem.
Do you know why the first execution of procedure like mine could take longer? Is it possible to avoid this kind of behavior?
As Simon Wright suggested, the different first execution time is because the MCU reads the code from the SPI flash on first execution but reads it from the instruction cache on subsequent executions.
By default, the FE310 SPI clock is the processor core clock divided by 8. When I set the SPI clock divider to 2, the difference in execution time is divided by 4.

Is it possible to read in data from multiple pins of a microcontroller at the same time?

I am using a PIC24 microcontroller and have multiple inputs. Via these I would like to obtain analog voltage data as fast as possible. I have 8 different data arriving to the microcontroller and I am a bit confused how to solve the problem.
My first idea was to to read in the data sequentially. First from AN0, then AN1 and so forth, but this may take quite a while and I am not at all sure it would be fast enough to do without any other trick. Especially because I do not only want to read in one single value per pin, but an array of voltages, then store and numerically integrate and send the results through USB to the PC. While doing so, new data should be constantly received via the aforementioned pins.
Is it feasible at all what I'm trying to achieve here?
Thanks in advance :)
You should think through your requirements a little more, especially the "at the same time" and "as fast as possible" statements. If you sample each channel within 10 to 100 microseconds of the next would that be satisfactory? What is the maximum frequency of the input signal that you need to detect? Your sampling frequency should be at least double the maximum signal frequency of interest.
Use a single ADC with enough input channels. Configure the ADC so that each time it is triggered to take a sample it will sample all of the channels in sequence (multichannel scan). It won't sample all 8 channels at literally "the same time", but it will cycle through each channel and sample them one after the other at nearly the same time. This could be within a few microseconds depending on the clock rate of the ADC and the channel setup time that you configure.
Now you could configure the ADC to sample in continuous mode where it would start the next sample scan immediately after finishing the previous scan. That would be "as fast as possible" but that might be faster than you need and produce more data than can be processed. Instead you should choose the sampling rate based upon the input signal frequency of interest and setup the ADC to sample at that rate. This rate might be much less than "as fast as possible". You might configure the ADC to collect one sample per channel when it is triggered (single conversion mode) and also setup a hardware timer to expire at the desired sampling rate and trigger the ADC to take a sample scan. The sample period (time between samples) must be greater than the time required to scan all the channels because you won't be able to trigger the ADC again before it has completed the previous channel scan.
If you really need to sample all channels at literally the same time then you probably need a separate ADC for each channel and then trigger all the ADCs to collect a sample at once.

Multiple analogRead() calls at timed intervals

I'm looking to add the ability to capture wave forms to an ATmega 328 based product and I've been unable to find details on how responsive the ATmega 328 is when doing A/D conversions. The code is being prototyped on an Arduino, but will be migrated to custom board when done.
My plan is to have a total period (typically 16 to 20 milliseconds, based on local AC line frequency) and sample a single pin on the order of 50 to 100 times during that interval. Can the ATmega 328 reliably perform that many conversions successively? The minimum interval per conversion is 16ms / 100 = 160us.
I can add a code example if anyone has to see code, but right now I'm more concerned about the minimum period between multiple successive A/D conversions.
The easiest way would be to write a Arduino script and do some timing benchmarks for yourself.
The other way - doing this by spec - requires some more input for each involved level.
On the lowest level is the ATmega328 chip. The docs on the ADC part says:
By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.
Assuming a 16 MHz clock for the ATMega the only available prescaler value for the ADC clock is 128 which is 125kHz for 10 bit resolution. You could use the prescaler value 64 (250kHz) if you can get away with 8 bit resolution.
Next: The doc says:
A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (ADEN in ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
So taking the 125kHz ADC clock this would mean ~9600Hz sample rate in "single conversion" mode. This is 104µs per sample. These are the Arduino defaults.
Compared to your requirement of 160µs this seems good.
BUT: So far only the conversion alone have been considered. You have to transfer the data somewhere. ALSO the Arduino analogRead() function has some overhead as you can see in the file wiring_analog.c in the Arduino dist.
This overhead might be to much - you have to test it for yourself.
On the other hand: Nobody forces you to use the Arduino analogRead function. Some available choices:
you can ditch the overhead of analogRead and/or
you can reconfigure the ADC to your needs (8 bit only, higher ADC clock) and/or
you can use "advanced" modes like continuous sampling ("freerunning mode"9 of the ADC or
you can use even interrupts to trigger the conversions.
Of course all of these choices heavily depend on your knowledge and time budget. :-)

Resources