Hi,
I have several ADC inputs configured like this:
const ADC_INIT_CHANNEL_STRUCT adc_channel_param1 =
{
Zone1_ADC_Input, // physical ADC channel
ADC_CHANNEL_MEASURE_LOOP | ADC_CHANNEL_START_TRIGGERED, // runs continuously after IOCTL trigger
4, // number of samples in one run sequence
0, // time offset from trigger point in us
200000, // period in us = 150mS
0x10000, // scale range of result (not used now)
4, // circular buffer size (sample count)
ADC_TRIGGER_1, // logical trigger ID that starts this ADC channel
};
The above period is set to 150mS, but it doesnt block.
How should I use the ADC to run 4 samples over 150mS and block to the processor can do its other various tasks while it waits?
Solved! Go to Solution.
Seems to be working as above for me now, though I did remove the other 12 tasks. I think maybe I had a higher priorty task taking up to much processing power or something.
I will look into it.
I have written some code to run a blocking ADC task, however, it never blocks.
The code only needs to run every 150mS, and the ADC should take 4 samples over the 150mS. The task must also be blocked for the entire 150mS.
The actual ADC works without the lwevent i.e. I can read the ADC and get the expect results, I just cannot get it to block when I add the lwevent code.
#ifndef MQX_USE_LWEVENTS #error This application requires LWEVENTS in config.h to be set #endif //I have 4 of these, one for each ADC (X = 1 to 4)const ADC_INIT_CHANNEL_STRUCT adc_channel_paramX = { ADC_SOURCE_AN1, // physical ADC channel ADC_CHANNEL_MEASURE_LOOP | ADC_CHANNEL_START_TRIGGERED, // runs continuously after IOCTL trigger 4, // number of samples in one run sequence 0, // time offset from trigger point in us 37500, // period in us = 150mS (4 / 150mS = 375000, so it actually samples 4 times at 37.5mS) 0x10000, // scale range of result (not used now) 4, // circular buffer size (sample count) ADC_TRIGGER_1, // logical trigger ID that starts this ADC channel &LWE_ADC1};//I have four lwevents defined, not sure if I can use one as I cannot choose which flags each ADC gets setstatic LWEVENT_STRUCT LWE_ADC1;static LWEVENT_STRUCT LWE_ADC2;static LWEVENT_STRUCT LWE_ADC3;static LWEVENT_STRUCT LWE_ADC4;void ADC_Task(uint_32){ FILE_PTR f, z1, z2, z3, z4; ADC_RESULT_STRUCT data; if ((_lwevent_create(&LWE_ADC1, LWEVENT_AUTO_CLEAR) != MQX_OK) || (_lwevent_create(&LWE_ADC2, LWEVENT_AUTO_CLEAR) != MQX_OK) || (_lwevent_create(&LWE_ADC3, LWEVENT_AUTO_CLEAR) != MQX_OK) || (_lwevent_create(&LWE_ADC4, LWEVENT_AUTO_CLEAR) != MQX_OK)) { printf("lwevent_creat failed!\n"); _task_block(); } z1 = fopen("adc:1", (const char*)&adc_channel_param1); z2 = fopen("adc:2", (const char*)&adc_channel_param2); z3 = fopen("adc:3", (const char*)&adc_channel_param3); z4 = fopen("adc:4", (const char*)&adc_channel_param4); //Doesnt start unless I do this for some reason ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_1); ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_2); ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_3); ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_4); for(;;) { if (_lwevent_wait_ticks(&LWE_ADC1, 0x01, TRUE, 0) == MQX_OK) { if(read(z1, &data, sizeof(data) )) { //run my code to check the data } } if (_lwevent_wait_ticks(&LWE_ADC2, 0x01, TRUE, 0) == MQX_OK) { if(read(z2, &data, sizeof(data) )) { //run my code to check the data } } if (_lwevent_wait_ticks(&LWE_ADC3, 0x01, TRUE, 0) == MQX_OK) { if(read(z3, &data, sizeof(data) )) { //run my code to check the data } } if (_lwevent_wait_ticks(&LWE_ADC4, 0x01, TRUE, 0) == MQX_OK) { if(read(z4, &data, sizeof(data) )) { //run my code to check the data } } }}
I am also not sure exactly how the ADC will handle having four lwevents all triggered one afte the other.
I have another task running at a lower priority, and it never runs as this task never blocks.
Thanks in advance.
PS: I have not really used lwevents before, so its probably something obvious?!
Hi Carl,
your code is fine, there is no mistake. It should work. I have no report about events not working in ADC. Which version of MQX do you use?
Thanks for checking that JuroV, I am using 3.4.
I thought it should be a simple task, but several hours of trying various things I came up with no solution.
Seems to be working as above for me now, though I did remove the other 12 tasks. I think maybe I had a higher priorty task taking up to much processing power or something.
I will look into it.
Hi,
I have been using the above code for testing. I have a simple voltage divider on the input wiht a 100nF cap for filtering. There are also a dozen other busy tasks running.
At completely random intervals (usually within 24 hours), I will get a case where the first ADC read shows the correct value, and the other 3 show the wrong value (I think they must go down to 0, or close too. I will log this over then next 24 hour period).
As the first event always returns the correct value and the following three all show the wrong value at the time of the error, I wonder if there is a problem with _lwevent_wait_ticks? The loop basically blocks until the first ADC event happens, then goes and checks all the lwevents, could this cause a problem? I there a 'better' way to do the above code?
I managed to capture the ADC returning the wrong values by putting a printf in each read, then loging the fread's for just over 10 hours, here is the section with he error:
0123456: 992 998 1001 998 846 1267
0123456: 993 996 1000 1000 830 1267