This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
i want take adc samples using tiva board , i tried with the tiva example code on tiva TM4c129 board in that i am taking samples from the adc along with that time stamp from the Hibernation module (sec : sub seconds)
and i am sending that data to the UART at 460800 baud rate i am able to get the samples , but the problem is sampling time is not uniform (i observed the sub seconds counter , the interval between each sample is changing ). how to make it as uniform as much as possible.
thank you in advance.
Greetings Bruno,
Well advised - although "paragraphing/bullet-pointing" would make those sound ideas (more) visually appealing. (more - to be kind)
At its heart - you've suggested:
Such ARE the "Rules of KISS" - which direct attention to, "One Small and "Measurable" Step at a time - ONLY when that "step is proven/verified" - may one proceed!
It is that (vital) "Laser Focus" (one small step) - and test/verify (via a "carefully" chosen MEASURABLE means) - which your keen analysis does not (to me) adequately highlight - and best drives (and yields) user success.
hey thanks for your answers,
but i am unable to understand what you are saying to give more information about my problem here i am attaching the code and output which i am getting,
if u observe the output , the difference between the sub seconds counter value is not the same for each sample (time interval) how to make it uniform , is there any possibility by changing code .
#include <stdbool.h> #include <stdint.h> #include <time.h> #include "inc/hw_memmap.h" #include "driverlib/adc.h" #include "driverlib/adc.c" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/uart.c" #include "utils/uartstdio.h" #include "driverlib/hibernate.h" uint32_t g_ui32SysClock; void ConfigureUART0(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig(0,460800,g_ui32SysClock); } int main(void) { uint32_t pui32ADC0Value[1]={0}; g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); ConfigureUART0(); // // The ADC0 peripheral must be enabled for use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // // Select the analog ADC function for these pins. // Consult the data sheet to see which functions are allocated per pin. // TODO: change this to select the port/pin you are using. // GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); // // Enable sample sequence 3 with a processor signal trigger. Sequence 3 // will do a single sample when the processor sends a signal to start the // conversion. Each ADC module has 4 programmable sequences, sequence 0 // to sequence 3. This example is arbitrarily using sequence 3. // ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); // // Configure step 0 on sequence 3. Sample channel 0 (ADC_CTL_CH0) in // single-ended mode (default) and configure the interrupt flag // (ADC_CTL_IE) to be set when the sample is done. Tell the ADC logic // that this is the last conversion on sequence 3 (ADC_CTL_END). Sequence // 3 has only one programmable step. Sequence 1 and 2 have 4 steps, and // sequence 0 has 8 programmable steps. Since we are only doing a single // conversion using sequence 3 we will only configure step 0. For more // information on the ADC sequences and steps, reference the datasheet. // ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); // // Since sample sequence 3 is now configured, it must be enabled. // ADCSequenceEnable(ADC0_BASE,3); // // Clear the interrupt status flag. This is done to make sure the // interrupt flag is cleared before we sample. // ADCIntClear(ADC0_BASE,3); SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); HibernateEnableExpClk(SYSCTL_OSC_EXT32); HibernateClockConfig(HIBERNATE_OSC_HIGHDRIVE); HibernateRTCDisable(); HibernateRTCSet(0); HibernateRTCEnable(); uint8_t sec = HibernateRTCGet(); uint16_t subsec = HibernateRTCSSGet(); uint8_t hr = 10; uint8_t min = 10; while(1) { // Trigger the ADC conversion. ADCProcessorTrigger(ADC0_BASE, 3); // Wait for conversion to be completed. while(!ADCIntStatus(ADC0_BASE,3, false)) { } // Clear the ADC interrupt flag. ADCIntClear(ADC0_BASE, 3); // Read ADC Value. ADCSequenceDataGet(ADC0_BASE,3, pui32ADC0Value); sec = HibernateRTCGet(); subsec = HibernateRTCSSGet(); if(sec>59) { min++; sec=0; if(min>59) { hr++; min=0; } } // Display the AIN0 (PE7) digital value on the console. UARTprintf("%4d %d:%d:%d:%u\n", pui32ADC0Value[0],hr,min,sec,subsec); } while(1); }
Rupendra,
Thank you for posting the image. I believe the initial explanation was good already, and I had understood what your problem is. For what is worth, the period differences are not too significant.
Read again what I posted initially, and there is no "running away from it": you WILL NEED to understand what is written there, even if you have to read a few times and search more information about timers and embedded programming in other sites to help you.
You need to control the timing of your code. Do you understand the timer hardware which is part of your MCU? Are you using timers? Are you using interrupts on the ADC? Do you have an oscilloscope to help you practicing this? You can simply generate timed pulses and measure them on the scope for a clearer understanding.
One other thing that you need to answer (to yourself) is "when are you recording those time counter values"? Is it when you prepare the text output message? When the sample is finished? Sometime in between?
There are lots of possible solutions - and for now, we don't even know if there is a problem, because the numbers are close enough and you have not stated what sort of precision is REQUIRED on your project. Getting a bit into the joking side, you can simply use sprintf(outputString,"2033 10:10:7:%04d",adcValue); and you will ALWAYS have a regular interval, won't you? Just an unpolite way of saying that a solution can only be crafted when there is a clear objective.
Regards
Bruno
Hi Bruno,
Bruno Saraiva said:Apparently your issue is not related to the ADC (actually, it surely is not). Rather, it is a matter of how you are structuring your code execution.
Actually might posters issue be directly related to the several types of ADC trigger methods available for sampling an analog input signal. My opinion much as yours (comments) seems to point out is application software execution is intertwined with hardware timing control of the ADC samples (window). So how can the ADC be ruled out as not being the cause of a condition noted by posters later print out of varied time stamps.
It appears poster has some kind of ADC triggered sample window timing, the question then becomes what kind of trigger, how often and when as your key points. Perhaps the poster could show a small portion of ADC configuration for our curiosity?
Hello Brett,
Google Maps reveals the "last hours" of your "Thanksgiving Turkey" - allowed to "free-range" - w/in your (dare I mention) (near) pristine - yet (green-free) "DEAD FET Strewn" (burial ground/back yard.)
Might the combination of tomorrow's:
somehow "lessen" your holiday spirit/enjoyment? (we're told you've the local ER on speed dial)
The power of that mapping system always amazes - we note the (almost) return of (some) green - upon (each) of your neighbor's yards... (i.e. discarded FETs may have to be "buried" deeper!)
What - (just) Bruno - timely/topical/EPA (Turkey/FET) comment "escapes" such LIKE? (even tho - and especially tho - bullet points enhance legibility!)