View previous topic :: View next topic |
Author |
Message |
Meister
Joined: 27 May 2010 Posts: 319
|
Posted: Mon Sep 29, 2014 3:51 pm Post subject: 10-bit ADC, bipolar |
|
|
Hi,
I am using a 10-bit ADC in bipolar mode (Attiny). In order to handle negative values, I use this (from Galahat):
Code: | W1 = Adc 'integer
If W1.9 = 1 Then W1 = W1 Or &HFE00 |
At 14MHz, the first line take about 1µs, whereas the second line if condition is met takes 200µs.
That appears to be waist of time since I need to get as many samples/s as possible.
Does somebody know a faster conversion method (maybe assembler code)?
Tanks for any help, Meister
(BASCOM-AVR version : 2.0.7.7 ) |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Mon Sep 29, 2014 4:43 pm Post subject: |
|
|
Code: | Dim W1 As Integer
Dim W1_h As Byte At W1 + 1 Overlay 'Fast access to high byte
W1 = ADC
$asm
LDS r24,{W1_h} 'Load high byte
SBRC R24,1 'Skip next command if W1_h.1 = 0 (equal W1.9 = 0)
ORI r24,&HFE 'Or $FE
STS {W1_h},r24 'save high byte. Takes 6 Cycles = 0,42µs at 14MHz
$end Asm |
|
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Mon Sep 29, 2014 5:05 pm Post subject: |
|
|
BTW, Code: | If W1.9 = 1 Then W1 = W1 Or &HFE00 | takes 20 Cycles = 1,4µs in simulator. 200µs wouldn't make any sense.
Edit: 200µs is the conversation time of the ADC... |
|
Back to top |
|
|
Meister
Joined: 27 May 2010 Posts: 319
|
Posted: Mon Sep 29, 2014 6:49 pm Post subject: |
|
|
Hello laboratory rat , (translated by Google)
Thank you very much for the assembler code. I try it out later. So, I might gain ~1µs:
Concerning the timings: You were right. I probably missed to delete a Wait statement....
I tested this way:
Code: | 'ADC free running
Pinb.2 = 1 'toggle PortB.2 (Tiny841)
W1 = Adc
if W1.9 = 1 Then
W1 = W1 Or &HFE00
End If
Pinb.2 = 1 |
The logic analyzer measures 2.5µs including reading the ADC. Only reading takes ~1µs so the simulator result looks fine.
But, the conversion time is much, much less than 200µs, should be about 1µs (~10-20 cycles), right?
Greetings, Meister |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Mon Sep 29, 2014 7:18 pm Post subject: |
|
|
Meister wrote: |
But, the conversion time is much, much less than 200µs, should be about 1µs (~10-20 cycles), right? |
If you have configured the ADC via Config ADC = FREE, the GetADC() routine is altered and doesn't wait for a conversion result, instead it simply reads ADCL/ADCH.
This takes some cycles too, but its speed doesn't depend on the ADC.
Disadvantage is: you never know, how old the last conversion result is, as the ADC continuously converts and the GetADC() just reads the latest available result.
The speed of the ADC however depends on its prescaler setting. If the prescaler clock is too low, the result in free-run may be not very actual at the time it is read, if this clock is too high, you loose accuracy. |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Mon Sep 29, 2014 7:25 pm Post subject: |
|
|
Yes, with a tiny841 a conversation takes 15 cycles, but ADC clock cycles. If you want to have 10 Bit resolution, the maximum clockrate for ADC is 200kHz. ADC clock comes from system clock through a prescaler, on a 14 MHz BASCOM will choose a prescaler of 128 (-> 137µs). You can manually set the prescaler - see help "config adc". You can go faster (up to 1Mhz) but you will loose precision. Maybe a prescaler of 64 is uncritical in your application.
Of course your program can do other things while adc is in free running mode. |
|
Back to top |
|
|
Meister
Joined: 27 May 2010 Posts: 319
|
Posted: Mon Sep 29, 2014 10:07 pm Post subject: |
|
|
Quote: | but ADC clock cycles |
Thanks to both of you for the clarifications.
I was'nt aware of that but always I had a bad feeling about the consequences of the ADC timings
- which was not important until now.
At present I try to eliminate residual periodic ~1MHz "noise" by averaging many ADC readings
- with disappointing results.
Maybe single conversion will do better in this case. I will try. |
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Tue Sep 30, 2014 4:02 am Post subject: ADC conversion |
|
|
Meister,
Bascom does two conversions per GETADC.
You can change it to one conversion by editing out the second conversion in the mcs.lib and recompiling in TOOLS, LIB MANAGER. Select the edited mcs.lib and compile. Exit with OK.
Check if it looks like this:
[_GETADC]
_GetADC:
* Sbi ADCSR,6 ; start conversion
_GetADC_1:
* Sbic ADCSR,6 ; skip next instruction if ready
Rjmp _GetADC_1 ; not ready
;--- remark the next 4 lines for single conversion
;* Sbi ADCSR,6 ; we need 2 conversions for a good result
;_GetADC_2:
;* Sbic ADCSR,6 ; skip next instruction if ready
; Rjmp _GetADC_2 ; not ready
;-------------------------------------------------
* In r24,ADCL ; first read lower data register
* In r25,ADCH ;then read upper data register
Ret
[END]
---------------------
Do not forget to safe mcs.lib and mcs.lbx under an other name or directory before editing.
You might also try to increase the ADC-clock up to 1 MHz with manual prescaler.
This will increase error by approx. 1-2 LSB.
Do not forget to insert one dummy GETADC after bootup.
The mcs.lib procedure was discussed quite some time ago.
Good luck.
Hubert |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Tue Sep 30, 2014 8:16 am Post subject: |
|
|
Meister wrote: | At present I try to eliminate residual periodic ~1MHz "noise" by averaging many ADC readings
- with disappointing results. |
To measure a much faster signal with a much slower ADC will not work, a better way is to do some hardware-filtering.
Quote: | Maybe single conversion will do better in this case. I will try. |
At least samples are taken then more periodically, as compared with freerun and unsync'd fetch of the ADC-result.
Likely it will fail also, as the first statement still applies.
You'd be much better off, if you don't describe your failed experiments, but the problem as whole. |
|
Back to top |
|
|
Meister
Joined: 27 May 2010 Posts: 319
|
Posted: Tue Sep 30, 2014 11:37 am Post subject: |
|
|
Thanks to everybody,
@MWS:
The ~1-2 MHz periodic noise is the remainder of a clock signal generated by Timer0 in CTC mode,
fed into some external hardware and measuring the outcome by the ADC after RC-filtering (I can't show the whole project).
Damping the signal by heavier filtering appears to be not the best since any change in the filter would have to be done by soldering...
I will try now to trigger the ADC by "Timer/Counter0 Compare Match A".
If the sample-and-hold circuit charges up during the full time determined by the prescaler,
that should take care of the noise in one ADC shot, hopefully.
I have to play now with the registers (not using config ADC).
Would you consider that as a useful method? |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Tue Sep 30, 2014 7:14 pm Post subject: |
|
|
Meister wrote: | Would you consider that as a useful method? |
A good sniper would shoot between two heartbeats
But you have a problem, if the heartbeat is faster than the bullet.
Also, did you read this?
Quote: | Differential Gain Channels
...
The gain stage is optimized for a bandwidth of 4 kHz at all gain settings. Higher frequencies may be subjected to non-linear amplification. |
It's not a big deal to try it out.
Hm, the generated CTC clock itself is not at 1MhZ, isn't it? As then I would wonder, how the ADC behaves, if it is triggered faster, than it can do a conversion. |
|
Back to top |
|
|
Meister
Joined: 27 May 2010 Posts: 319
|
Posted: Tue Sep 30, 2014 9:53 pm Post subject: |
|
|
MWS:
You are right,
with ADC bandwidth of 4kHz, the 1-2 MHz (adjustable) CTC -related signal (as seen by a differential, isolated Oscilloscope)
should be far off from being detectable by the ADC...
But there is fluctation in averaged ADC values transmitted each ~50ms.
Since the MHz noise is the only one I see I conclude the fluctuation is related to that.
Quote: | w=0
for i=1 to 128
w1=adc
w=w+w1
next
Shift w,right,5 'or more shifts
|
Maybe that very fast averaging is nonsense since the 128 readings all might be the same due to the free running ADC.
So I have reconsider the handling of the ADC in view of these discussions.
Quote: | I would wonder how the ADC behaves, if it is triggered faster, than it can do a conversion. |
I think during a conversion further triggers are neglected. I think I have read that in the manual (Attiny841). |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Tue Sep 30, 2014 9:53 pm Post subject: |
|
|
I like to add that it is better to copy code from the lib and place it in your own lib.
That way you only need to add $lib "your.lib" to your code and you dont need to worry that an update will overwrite your modifications.
Since the compiler will search mcs.lib last, it will include code found in a user defined lib. _________________ Mark |
|
Back to top |
|
|
|