Hello
I have two questions.
1)I am using the ADC on QG8 in 8 bit mode and continous compare to interrupt when a certain value to the input is above the set value in ADCCVL.
I now want a window comparator where I want to monitor an ADC i/p of less than some set value.How can I do this since QG8 has either a higher than or lesser than compare value (ACFGT).
Further I had a problem while using the 'higher than' setting.I am using a CT (current transformer) to measure a current value and the secondary side is rectified and filtered and fed to the ADC i/p.Even if I set the ADCCVl at 0xFF,so that the voltage at which it interrupts is 3.3V,it gives an interrupt for a voltage drop of 2V.To aggravate it also interrupts for a very small load because of the current surge.How can I take care of this?
2)In the same circuit I am powering the QG8 and related ckt using an unisolated Power supply.(The mains is not stepped down with a transformer)The neutral on mains and the ckt ground are common.
I also drive a relay with one of the GPIO on the QG8.
Whenever I run the code on a battery generated 5V(or the debugger),the code executes flawlessly.
But when the unisolated PSU is connected,the noise starts working into the MCU.I have heavily filtered the key points on the board,but still the problem continues.
It is further aggravated when the relay switches with some load.The EMI/EMC on the contacts of the relay make the MCU misbehave and it jumps to unknown routines.
How immune is the QG8 to this kind of noise?
Has anyone worked on this kind of setup before?....The same kind of setup is used in washing machines and it works nicely.
Please someone help....and thank you for reading this long post
Thanks and regards
Dear Abi,
I think that you are squuezing too much on a hardware sollution. Probably you'll get better results if you sample the signal - you could use CW to sample it N times and extract average value - and write your own software handler for this situation involving surge and so on.
As you are dealing w/ commercial AC maybe you could set a timer to 1KHz rate, call the CW analog measurement functions and maybe use a state-machine based function to implement your handler.
Cheers,
Celso
Hello celsoken
Thanks so much for the reply
What is CW?
Sorry for the ignorance
Apart from that I got the idea...thanks
Please also guide me towards the window comparison approach
Thanks and regards
Dear Abi, sorry, CW stands for CodeWarrior, I meant that you could use CW built-in functions to read the ADC and extract average value.
Regarding guiding you, I could try to answer your questions, ok?
Cheers,
Celso
Hello celsoken
Thanks again for replying
Ok I got the idea.
In my ckt ,I have measure a value corresponding to a current.If the current is above a value then a GPIO pin should be pulled low and the MCU just waits there --no action.It comes out of that wait only on a hardware reset.
When the current is below a threshold value,the GPIO pin is again pulled low but the MCU doesnt wait for a RESET.
Earlier the requirement was for current-above-reset and that was done using a ACFGT=1 and a finite ADCCVL=0x(some value)..but this current-low is thrown in now,and since there are numerous approaches to this,I was lookin out for a fairly simple approach..
The accuracy is not that important (since I am measuring mains curent through a CT) I am using 8bit resolution.
Please help me if you can
Thanks and regards
Dear Abi,
If you want a simple approach, why don't you use a classical two-comparator hardware sollution. If you don't wanna spend extra in hardware, use the QG8 internal comp for the higher limit and an external discrete comparator for the lower limit. Some mickey-mouse logic will save you some pennies.
Otherwise there is the software sollution wich will take you some implementing time. Probably much better but it will take time...
Cheers,
Celso
Hello celsoken
Thanks again
Can you tell me about the software approach?...some algorithm?
Thanks and regrds
Hello,
An alternative method might be considered that uses single conversion mode, rather than continuous conversion. Enable ADC conversion complete interrupt, and initiate the first ADC conversion within the initialisation section of your program.
Within the ADC ISR, test for both upper and lower threshold limits, and do the required action associated with the particular ADC reading. Then start the next conversion and exit.
Depending on how much other background activity needs to occur within your program, you might choose a lower ADC clock frequency, and select the long acquisition period, to provide more cycles for the background activities.
Regards,
Mac
Hello mac
Thanks for the reply.
I wrote this code
void Init_ADC(void){ ADCSC1_ADCH = 0x1f; // all channels selected disables the ADC during config ADCCFG_ADICLK = 0b01; // clock source, 00=bus clock, 11 = async. clock,01=bus/2 ADCCFG_MODE = 0b00; // conversion mode, 00 = 8 bit, 10 = 10 bit mode ADCCFG_ADLSMP = 1; // sample time, 1 = long sample time ADCCFG_ADIV = 0b11; // clock divide, 11 = input clock/8 ADCCFG_ADLPC = 1; // low power config, 1 = low power ADCSC2_ADTRG = 0; // trigger select, 0 = software trigger ADCSC2_ACFE = 0; // compare function, 1 = enable compare function //ADCSC2_ACFGT = 1; // 1 = compare function greater than ADCSC1_ADCO = 0; // enable single conversion, 1 is continuous conversion ADCSC1_AIEN = 1; // enable ADC interrupt APCTL1_ADPC2 = 1; // disable I/O control on pin //ADCCVL = 255; // set a compare value ADCSC1_ADCH = 0x02; //ADP2 enable }//-------------------------------------------------------------------------------------interrupt 19 void ADC_ISR(void) { ADC_Read=ADCRL; //Acknowledge the Read Value to disable COCO Flag if ( ADC_Read>=(unsigned char)90) { PTAD_PTAD1 = RESET; //reset Relay PTBD_PTBD1 = SET ; //red LED on while(1); //wait here until reset } if ( ADC_Read<=(unsigned char)50) { PTAD_PTAD1 = RESET; //reset Relay PTBD_PTBD0 = SET ; //green LED on while(1); } ADCSC1_ADCO = 0; // enable single conversion, 1 is continuous conversion ADC_Read=0; }
But the ADC_ISR is invoked all the time.The relay is reset always.
Now when I remove the
ADCSC1_ADCO = 0;
and put in main( ) where there's a 'forever' loop, the ADC interrupt isn't invoked and no action takes place.
What might be wrong?
Thanks and regards
Hello,
I think the problem is that you are writing to ADCSC1 within the ISR, but not stipulating that the conversion requires to be for the ADP2 channel; I suspect that subsequent conversions will occur for ADP0. Since any write to ADCSC1 will start a new conversion, it is important that all bits be written simultaneously, i.e. ADCSC1 = 0x02;
Again, during the inititialisation, the coding will be simplified if the whole register is written, rather than individual bits, or groups of bits.
The following is the modified code for the ISR.
interrupt 19 void ADC_ISR(void)
{
if (ADCRL >= 90) {
PTAD_PTAD1 = RESET; //reset Relay
PTBD_PTBD1 = SET; //red LED on
while(1); //wait until reset
}
if (ADCRL <= 50) {
PTAD_PTAD1 = RESET; //reset Relay
PTBD_PTBD0 = SET; //green LED on
while(1);
}
ADCSC1 = 0x02; // Commence new conversion ADP2 & clear flag
}
Note that the COCO flag will be cleared when a new conversion commences. Also the casts would seem unnecessary. I assume that the out-of-range reset is caused by COP timeout.
Regards,
Mac
Hello mac
Thanks for the reply.
The funny thing is that it never enters the ADC_ISR with
ADCSC1 = 0x02; // Commence new conversion ADP2 & clear flag
It only enters the ISR 'ONLY' on ADCSC1_ADCO=0;
My ADCCFG (after checking multiple values for clocks and divisors where i thought it might work corerctly) is ADCCFG = 0xb0;
I have disabled COP in SOPT so theres no question of COP reset.
I have also added another instruction so that it will poll for COCO flag and then go about doing the stuff in the ISR w/o using interrupt..but the same thing is being repeated.
I am really out of ideas now..
Please provide an insight
Thanks and regrds
Hello Mac
The ADCSC1 =0x02 you suggested is missing the AIEN and ADCO, so the ISR is never invoked.
Now if I set these in the ADCSC1=0x62, the code will not go anywhere else other than the ISR.
So I cleared the AIEN thus ADCSC1=0x22, and set the AIEN in my main( ) where there's a continuos loop.This repeats my earlier problem (works in debugger).
SO no matter how it's setup,it isn't working as it should.
Please steer me along...since I am close to breaking down now with this 'seemingly' trivial problem
Thanks and regards
Hello
I have done some more things here.
Please have alook at my init and ISR
void Init_ADC(void){ ADCSC1 = 0x3f;// disable all ADCCFG = 0xe9; //same as above 0b ADCSC2=0x00; APCTL1= 0x04; // disable I/O control on pin ADCSC1= 0x42 ; }//-------------------------------------------------------------------------------------interrupt 19 void ADC_ISR(void) { ADC_CNT++; ADC_Read+=ADCR; //Acknowledge the Read Value to disable COCO Flag if (ADC_CNT>=10) { ADC_Read= ADC_Read/10; if ( ADC_Read>=350) { PTAD_PTAD1 = RESET; //reset Relay PTBD_PTBD1 = SET ; //red LED on } if ((( ADC_Read<=50)) && (PTAD_PTAD1==1) ) { PTAD_PTAD1 = RESET; //reset Relay PTBD_PTBD0 = SET ; //green LED on } ADC_CNT=0; ADC_Read =0 ; } ADCSC1_ADCH=0x02; } void main ( ){ SOME CODE ;for (;;){ SOME CODE; ADCSC1_ADCO = 0; // enable single conversion, 1 is continuous conversion}
The ADCSC1_ADCO = 0; // enable single conversion, 1 is continuous conversion
was earlier in the ADC_ISR but this didn't get me anywhere.
Now with the above code too whenever I run it in step mode the ISR is invoked and the routine is serviced but on RUN it never enters the ISR.
What could be wrong?
Thaks and regards
Hello
The ripple on the ADC i/p is substantial.
It is the o/p of a CT which is half wave rectified and filtered (now) with close to 100uF capacitor.
Will this play some major part...since i think the ADC will sample only an average,according to the code i have written.
Please see the ripple on my oscilloscope attached.
Hello
Someone please help.I am stuck up here..
Hello
Please someone can write an ADC initialisation routine for me?
My BUSFREQ = 8MHz
Especially setting the ADCCFG.Since whichever ADC freq i set (changing ADIV and ADICLK) the ISR is invoked in single step but never in RUN mode
Thanks and regards
Hello
It is not a question of the ripple of the CT..since now I checked with a DC voltage through a preset.
I am not able to get the correct ADC freq.
My BUS freq is 8MHz and i checked ADC freq from 500KHz and above but no joy
Wish someone would take interest in my problem and guide me..
Thanks and regards
Hello Abi.
I have some experience with a circuit similar to yours and I would caution you that you can get erratic behavior from using an un-isolated supply (running directly off the mains).
When you connect the debug pod and computer to your board you are also connecting the computer ground to the mains neutral. I broke the usb port on my laptop in just this way. This may explain why you get different operation when running off the dc supply.
Also, as Bigmac said, I think it is a mistake to run the ADC in continuous conversion mode. It complicates your life un-necessarily. I always use use a different timer, such as a heart-beat interrupt, to call an ADC single-conversion module. I stay within the module till I get the result (conversion complete flag set) then run the result thru a filter and leave it in a variable for other processes to use.
ron
Hello ron
Thanks for replying
Well last year I broke my USB DSO and my computer MB due to such kind of a PSU..so I have been extremely cautious while measuring such kind of unisolated waveforms ,since then.
But as you can see in my earllier posts,that the PSU had nothing to do with the behaviour of the ADC since it doesn't work in pure DC too!!
I have run out of timers in this project so I was enabling the ADC for single conversion in a continuos loop (similar to your heartbeat)
Eventually I have got it to run in cont conversion mode only...long sample and low power 10bit mode.
Since i tried a lot (a lot) in single conversion but fruitlessly!!!!
Thanks and regards
Hello
I have been able to go a bit further.
In debug mode whenever I RUN the code and i switch on a high load ,it should go in the ADC_ISR and turn the pin low so that the load is turned off.
But it doesn't do this.When I hit HALT and then again RUN the code does the pin turn low (according to the decision set)
To add ,if i run it in STEP mode it acts as it should.
Not able to understand this...
Hello
I solved the noise problem by using RC snubbers on the relay.
I am still working on the window comparator with the ADC
If someone can direct me to a simple approach...that would be wonderful
Thanks and regards