Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

GETADC Command

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
MOR_AL

Bascom Member



Joined: 08 May 2014
Posts: 11
Location: Rio de Janeiro - Brasil

brazil.gif
PostPosted: Fri Aug 28, 2020 9:02 pm    Post subject: GETADC Command Reply with quote

I looked for my question and I didn't find it here.

I would be grateful if someone could clarify my doubts.

1 - When Bascom AVR finds the command var = GETADC (x), is there an internal procedure that waits for the end of the conversion, or do we have to wait for the end of the conversion to proceed with the next command?

2 - Can we monitor the ADCSRA.ADIF bit until it equals "0"?

3 - The ADCSRA.ADIF bit is reset by hardware at the end of the conversion if the ADCSRA.ADIE bit is set to "1" and the interruption occurs. Will ADIF flag have to be reset by software, when the ADIE bit is set to "0"?

Thank you.

MOR_AL

(BASCOM-AVR version : 2.0.8.2 , Latest : 2.0.8.3 )
Back to top
View user's profile
Evert :-)

Bascom Expert



Joined: 18 Feb 2005
Posts: 2115

netherlands.gif
PostPosted: Fri Aug 28, 2020 9:10 pm    Post subject: Reply with quote

Hi,

I depends on the mode you have choose in Config ADC.
In the single mode there will be waited for the conversion to be finished.
The adc register bits is taken care of by Bascom, you don't have to anything with them.

_________________
www.evertdekker.com Bascom code vault
Back to top
View user's profile Visit poster's website
MOR_AL

Bascom Member



Joined: 08 May 2014
Posts: 11
Location: Rio de Janeiro - Brasil

brazil.gif
PostPosted: Fri Aug 28, 2020 9:43 pm    Post subject: Reply with quote

I thank you for the quick return and your answer makes perfect sense.
It would be an elementary failure if it did not happen.
At the moment I have no problems with the conversion speed. I would just like to clarify my doubt.

I read on another forum, that a person did a "For" loop with 50,000 (X) values containing GETADC (7) and he reported that the loop lasted about 1 second.

https://www.avrfreaks.net/forum/atmega16-bascom-avr-adc-speed

The datasheet reports that the conversion limit is around 15kSPS. Of course, there was no time for conversions to be completed.
...
Code:
Config Adc = Single, Prescaler = 2, Reference = Avcc
$ regfile = "m16def.dat"
$ crystal = 8000000
$ hwstack = 32
$ swstack = 10
$ framesize = 40
For X = 0 To 50000 Step 1
A = Getadc (7)
Next X

...
Do you have any comments on this incompatibility?
Thank you.
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 1827

blank.gif
PostPosted: Fri Aug 28, 2020 10:52 pm    Post subject: Reply with quote

There's no 'incompatibility', only because one overdrives the ADC beyond its limits, it does not mean, one gets correct results.
Means precision deteriorates if sample speed goes too high.
Btw., GETADC() always samples two times and discards the first sample, this makes sure that under all conditions a correct result is achieved. If you know what you do, you can speed sampling up by doing your own routine.
Back to top
View user's profile
JC

Bascom Member



Joined: 15 Dec 2007
Posts: 490
Location: Cleveland, OH

usa.gif
PostPosted: Fri Aug 28, 2020 10:57 pm    Post subject: Reply with quote

If you are using the ADC to read a temperature then high speed sampling and exact timing don't usually matter.
If, however, you wished to do some pseudo-real time signal processing, that usually assumes that the data samples are obtained at a fixed interval.

One method to do that is to set up a Timer/Counter in CTC mode so that it fires an interrupt at a known, fixed, rate; for example once every 1 mSec.
Then within the ISR one reads the LAST sample and then triggers the start of the ADC obtaining the Next sample.
The ISR is then always 1 sample behind, in this case 1 mSec behind, absolute real time.
(That doesn't usually matter)

The program below was never written to be displayed...
But I'll post it anyways.

It was a quickie test program to answer a question on another Forum with an Arduino Nano, reading the ADC and sending the data to a PC via a USB link.
In this case the sampling was at 7 K Samples / Sec and the USART baud rate was 250000.

What this example also shows is setting up the Timer/Counter and the ADC using low level control of their registers instead of using the high level Bascom commands, although Bascom is used for the overall program.

One could do this all with high level Bascom commands, but if you read the data sheet you can configure the peripherals exactly how you wish them to be set up, and you do not have to guess about any of the Bascom command parameters that you are uncertain of their action.

In the following program the Main Loop flashes an LED on and off just to show that it is doing something.
Within the ISR the ADC sample is read and stuffed into the USART transmission buffer, and the next ADC sample is triggered to start taking it.

Note that this doesn't look at the data conversion complete flags as the sampling is being done at 1 KHz, which is slow, so it is known that the conversion will be completed by the time the ISR fires again.

Good luck with your project.

JC


Code:

'File Name:  Nano ADC to USART Test V1.bas
'JEC  Bascom   Oct 2, 2017

'This is a quickie test project for a Forum question regarding sampling ADC
'at 7 KHz and uploading the data via the USART.

'This uses an Arduino Nano board, Mega328P @ 16 MHz, 5V system
'This Nano has a USART to USB bridge chip: CP2102.

'Nano Hardware:
'USB Bridge is on PortD.0, RxD
'USB Bridge is on PortD.1, TxD
'On PCB LED is on PortB.5  LED
'
'Extra hardware on the breadboard at the moment, not needed:
'PortD.3    LED   Hi = On
'PortD.4    LED   Hi = On
'PortD.5    LED   Hi = On
'
'PortD.6    PB Switch   Needs Internal Pull Up Resistor enabled.
'PB Switch normally reads high, is low when pressed.

'Note:  ARef pin has a cap to ground, it is NOT connected to any
'voltage reference.
'The ADC is configured to use the Vcc rail, set up internally.

'V1   Oct. 2, 2017  Works
'Set up T/C for 7 KHz ISR
'Set up ADC for 10bit data to a Word variable
'Set up ring buffered, interrupt driven, USART TxData driver

'Note well:
'The functionality of this program is really entirely within the
'ISR.  Main Loop flashes an LED for fun.

'Method:
'Isr Fires At 7 Khz.
'Inside ISR read the LAST ADC reading and stuff it in USART TxData buffer
'Trigger the next ADC reading to take the next reading
'There is NO Packetization of the data.
'There is NO data compression.
'Data synchronization at the PC end is left as an exercise for the user
'Note:  After reading the ADC data, this program changes the ADC data value
'to a "C" to allow it to be seen on a terminal emulator program on a PC.

'Note:  With the USART running with a Baud Rate of 250000 one has time to send
'the TWO data bytes to the PC in the interval between the ISR firings.
'The 10 Bit data is send as a Word, (two 8-bit Bytes).
'No data compression is used.
'One might fit in a third Byte, (just barely, didn't calc or test this).


'-----------------------------------------------------------------------------------------

$regfile = "m328pdef.dat"                                   'Micro used
$crystal = 16000000                                         'Micro's Clock Frequency

$hwstack = 64                                               'Hardware Stack
$swstack = 64                                               'Software Stack
$framesize = 64                                             'Frame Space
'$baud = 57600                                               'Set Baud Rate
$baud = 250000                                              'Set Baud Rate

   'Configure the Port's Pins for Input or Output mode.
   Config Portb.5 = Output                                  'LED
   Config Portd.3 = Output                                  'LED
   Config Portd.4 = Output                                  'LED
   Config Portd.5 = Output                                  'LED
   Config Portd.6 = Input                                   'User Push Button Switch

   'Type Word is 16 Bit unsigned
   'ADC Value is 10 Bit data, Right justified.

   Dim Regval As Byte                                       'Register Value for manual config
   Dim X As Byte                                            'Loop counter
   Dim Ttcnt As Word                                        'TicTock ISR Counter

   Dim Adcval As Word                                       'ADC Data Value, Word
   Dim Pbsw1 As Byte                                        'PB Switch #1's value

   Led0 Alias Portb.5                                       'LED on Nano PCB
   Led1 Alias Portd.3                                       'Led, Red
   Led2 Alias Portd.4                                       'Led, Yellow
   Led3 Alias Portd.5                                       'Led, Green
   Pbs1 Alias Pind.6                                        'PB Switch, Pressed = Low

'...............................................................................
   'Setup Timer/Counter #0 for Interrupts:
   'Bascom can configure the Timer/Counter for generating interrupts.
   'I prefer to do it myself, then I know the specific details of how it
   'has been configured.

   'This will configure the M328P Timer/Counter #0, (8-bit), for an interrupt
   'rate of APPROXIMATELY 7 KHz.
   'One can, of course, look at using other T/C prescaler settings, or a 16 bit
   'T/C and see if the error in the 7KHz rate can be reduced.
   'This example, however, demonstrates the concept and the 7 KHz sampling rate
   'is actually at 6944.4 Hz, for < 1% sampling rate error.

   'Configure M328P Timer/Counter #0,(8-Bit), for APPROX 7 KHz ISR rate:
   'CTC Mode, Clear Timer On Compare Mode
   'Enable TC0 in Power Reduction Register.
   'Do not enable any hardware output pins.
   'uC Clock = 16 MHz
   'Prescale = /64    16MHz/64 = 250,000 clock into the TC0 module.
   '250k / 7000 = 35.714, so round this up to 36
   'This means if the T/C counts to 36 it will generate an interrupt at ~ 7 KHz.
   'Set the T/C TOP value to 35, as the T/C roll over from TOP to zero also
   'counts as one count.

   'Using Output Compare A for this.
   'Must write 0 to PRR Bit 5 to Enable TC0.  Leave other bits alone.

   'First Turn On the Timer/Counter0 Module.
   'Read the Power Reduction Register, set the PRTim0 bit to 0 to Enable it.
   'Then write it back.  This does NOT alter any other module's activity.
   'Bitwise AND with 1101 1111   All bits unchanged, except Bit 5 = 0.
   Regval = Prr                                             'Read in current Power Reduction Register Values
   Regval = Regval And &B11011111                           'Force Bit 5 = 0
   Prr = Regval                                             'Save new value

   'Now set up the Timer/Counter#0 Control Registers for CTC Mode,
   'PreScale Div by 64:
   'No output on hardware pins.
   Tccr0a = &B00000010                                      'Timer/Counter Control Register A
   Tccr0b = &B00000011                                      'Timer/Counter Control Register B

   'Now set the TOP value for the A Output Compare Register.
   'I want this to be 35 dec  for a count of 36 dec.
   Ocr0a = 35                                               'TOP for CTC count of 36d, ~ 7KHz

  ' Ocr0a = 249                                              'TOP for CTC count of 250, 1 KHz ISR

   'Now Set The Interrupt Mask:  Enable Output Compare A Match Interrupt
   Timsk1 = &B00000010                                      'Timer/Counter1 Interrupt Mask Register

   'Now Enable the Interrupt and define the ISR handler:   Output Compare 0 A
   Enable Compare0a
   On Oc0a Heartbeat
'...............................................................................

   'ADC Module Setup:
   'Configure the M328P ADC for Single Conversion Mode
   '10 Bit resolution
   'There are 8 Analog Inputs on PortA.
   'Use the Multiplexer to set the desired input Pin.
   'Config for Vref = Internal connection to the Vcc, (5V) rail.
   'Config for ADC0 as the input source.
   'Config for Single conversion, without using ADC interrupts.
   'Manually start conversion by setting Bit 6 in ADCSRA register.
   'Ignore first conversion result.

   'First Turn On the ADC Module in the Power Reduction Register,
   'In PRR Bit 0 = 0 to Enable the ADC module
   'Read the Power Reduction Register, set the PRADC bit to 0 to Enable it.
   'Then write it back.  This does NOT alter any other module's activity.
   'Bitwise AND with 1111 1110   All bits unchanged, except Bit 0 = 0.
   Regval = Prr                                             'Read in current Power Reduction Register Values
   Regval = Regval And &B11111110                           'Force Bit 0 = 0
   Prr = Regval                                             'Save new value

   'ADC: Vref = Vcc internally selected, R just data, ADC Ch 0
   Admux = &B01000000

   'Trigger the first ADC Read to set up the ADC hardware:
   'Enable ADC, No Interrupts, Pre-Scale = 128, (ADC Clock = 125 kHz)
   Adcsra = &B11000111

'............................................................................
   'Setup USART:
   'Config the HW USART for interrupt driven ring buffered output
   'Serialout = serialout0 = The first USART.
   'Default N,8,1 is used if Config isn't used.
   Config Serialout = Buffered , Size = 128

'............................................................................


'............................................................................
Premain:
   'Turn on PB Switch's Internal Pull Up Resistor:
   Portd.6 = 1                                              'Turn On Pull Up Resistor


   'Flash an LED on Startup:
   For X = 1 To 10
      Set Led0
      Waitms 50
      Reset Led0
      Waitms 50
   Next X


   'Now Enable Global Interrupts:
   Enable Interrupts                                        'Global Enable Interrupts

Main:
   'Program's real work is done within the ISR.
   'This Main Loop just flashes an LED for kicks.
   'Flash an LED about 1 Hz (Without ISR)

   'LED's Off
   Reset Led1
   Reset Led2
   Reset Led3

   Do
      'Flash an LED, NOT ISR driven
      Set Led2
      Waitms 100
      Reset Led2
      Waitms 900

   Loop


Heartbeat:
   'Timer/Counter #0 ISR:
   'This ISR fires at APPROX 7 KHZ rate.
   '  Set an I/O Pin for O'scope monitoring
   '  Read in Last ADC conversion
   '  Trigger the next ADC conversion
   '  Stuff ADC reading into the USART Transmit Buffer
   '  Flash an LED at 1 / Sec
   '  Push Button Switch Debounce can be added, also...
   '  Clear the O'scope Pin

   'TickTock counter  TTCnt

   'Set PortD.3 I/O Pin to watch ISR fire on O'Scope.
   'This is LED 1, so it will also glow dimly.
   Set Led1                                                 'Pin High

   'Process ADC Data:
   'Read in the current ADC reading
   'Trigger the Next ADC reading
   'Then stuff the ADC data into the USART's Transmit buffer

   'Automatically read in ADCL, then ADCH, put in ADCVal variable:
   Adcval = Adc                                             'Get ADC data

   'Trigger the next ADC Reading
   'Enable ADC, No Interrupts, Pre-Scale = 128, (ADC Clock = 125 kHz)

   '**********************************
   '  Change the ADC Data to an ASCII Character to
   '  see it on the PC terminal program
  '  One sees "C"s filling the screen instead of the actual data values.
   '**********************************

   Adcval = 67                                              '"C"  Fake Data
   Adcsra = &B11000111                               'Trigger the next ADC reading.

   Printbin Adcval                                          'Upload the ADC data

   'Flash an LED once per second
   Ttcnt = Ttcnt + 1                                        'Incr
   If Ttcnt < 100 Then
      Set Led0                                              'LED On
   Else
      Reset Led0                                            'LED Off
   End If

   If Ttcnt > 999 Then
      Ttcnt = 0                                             'Rollover
   End If


   Reset Led1                                               'Clear O'scope marker

   Return


   End
 
Back to top
View user's profile Visit poster's website
MOR_AL

Bascom Member



Joined: 08 May 2014
Posts: 11
Location: Rio de Janeiro - Brasil

brazil.gif
PostPosted: Sat Aug 29, 2020 2:28 pm    Post subject: Reply with quote

Ok, I got it.
I thank you who helped to clarify my doubts.

JC!
I will study your program. You have certainly endeavored to produce it.

MOR_AL
Back to top
View user's profile
hgrueneis

Bascom Member



Joined: 04 Apr 2009
Posts: 862
Location: A-4786 Brunnenthal

austria.gif
PostPosted: Sun Aug 30, 2020 4:47 pm    Post subject: Reply with quote

You can also edit out the second ADC-scan to half the acquisition time. Described by Mark Alberts some Years ago.

Best regards
Hubert
Back to top
View user's profile
MOR_AL

Bascom Member



Joined: 08 May 2014
Posts: 11
Location: Rio de Janeiro - Brasil

brazil.gif
PostPosted: Sun Aug 30, 2020 9:38 pm    Post subject: Reply with quote

hgrueneis wrote:
You can also edit out the second ADC-scan to half the acquisition time. Described by Mark Alberts some Years ago.

Best regards
Hubert


OK!
Thank you.
MOR_AL
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum