ATtiny45 ADC problem <solved>

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Tiny45 keeps nagging me. First the silicon flaw in Timer1, and now this:

When I power the tiny45 with 3.1V, I get wrong ADC results. When I raise the supply to above 4.2V it works.

I stripped the application to just a bare minimum to show the problem.

' ADC check1  rev 1.1 HW

' Aug 16, 2012    Nard Awater

' ATtiny45 in MyLedLamps_drop_in rev1.1 HW project
' 8 MHz internal RC oscillator

' Silicon error in this Tiny45: Timer1. See errata. Kudos to snigelen for his help

' Now facing another issue with the tiny45: ADC shows strange behaviour.
' When powered with 3.1V, ADC-results are incorrect. I use the internal 1.1V reference. So that should work.
' However, I need to power it with 4.2V or more to get the correct results.

' PinB.3 = ADC3 = Oscillator Driver Current: Drv_current over 0R5 <<<<< for TEST replaced with a potmeter >>>>>
' PinB.2 = ADC1 = Vsupply
' PortB.4 = OC1B = Oscillator Drive: PWM_Drv



Const Soft_uart_out = 1
Const Soft_uart_in = 0

Const F_proc = 8000000
$regfile = "Attiny45.dat"
$crystal = F_proc

'Fuses
'$prog &HFF , &HE2 , &HD5 , &HFF                             ' generated. Take care that the chip supports all fuse bytes.

'setup IO
Ddrb = &B00000010                                           'just ddrb.1 for soft uart out

Dim Long_t As Long
Dim Drv_current As Word                                     'in mV across the shunt of 0R5


Dim Temperature As Integer                                  'in degrees C
Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
Const Bg_ref = 1173                                         'calculated using actual voltmeter on Vcc
'Temperature sensor in Tiny45; defaults, not calibrated yet
Const Temp_coeff = 1
Const Temp_offset = -275



'For terminal on USB connection:
#if Soft_uart_out = 1
'Terminal on USB
Open "comb.1:19200,8,n,1" For Output As #4                  'soft UART for output on PortB.1
#endif
#if Soft_uart_in = 1
'Terminal on USB
Open "comb.0:19200,8,n,1" For Input As #3                   'soft UART for input on PortB.0
#endif

Waitms 500                                                  'wait a while when powering up to get everything settled


Do

   Drv_current = Getadc(3)
   'to mV's; Use Long For That
   Long_t = Drv_current
   Long_t = Long_t * Bg_ref
   Long_t = Long_t / 1024
   Drv_current = Long_t
'   Drv_current = 2 * Drv_current                            'in mA with shunt of 0R5
'   Print #4 , "Drv_current in mA = " ;
   Print #4 , "potmeter wiper = " ;
   Print #4 , Drv_current

   Temperature = Getadc(15)
   Temperature = Temp_coeff * Temperature
   Temperature = Temperature + Temp_offset
   Print #4 , "Temperature in degr C (not cal'd ) = " ;
   Print #4 , Temperature

   Waitms 500

   Print #4 , "ADMUX = " ;
   Print #4 , Admux


Loop

 'Very formal, but I want a Happy and Clean End  :-)
#if Soft_uart_out = 1
Close #4
#endif

#if Soft_uart_in = 1
Close #3
#endif

End

@ Vcc=3.1V this is the terminal output:

Quote:
ADMUX = 143
potmeter wiper = 178
Temperature in degr C (not cal'd ) = -160

The voltmeter tells 452 mV

@ Vcc=5V this is the terminal output:

Quote:
ADMUX = 143
potmeter wiper = 804
Temperature in degr C (not cal'd ) = 33

The voltmeter tells 730 mV

I print ADMUX as well to make sure that Bascom does its job right. And it does.
(143 dec = &B 1000 1111 : reference 1.1V internal, Mux 15 = temp sensor)

If I'd be using the 2.56V reference, I would be quite close (with Vcc = 3.1V) to the lower limit of Vcc.

I am pretty sure this is NOT a silicon error, but I cannot find a reason for this behaviour.

Cheers

Nard

A GIF is worth a thousend words   They are called Rosa, Sylvia, Tricia, and Ulyana. You can find them https://www.linuxmint.com/

Dragon broken ? http://aplomb.nl/TechStuff/Dragon/Dragon.html for how-to-fix tips

Last Edited: Fri. Aug 17, 2012 - 01:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see that the core of the program is in a loop. Are results consistent over, e.g., 10 repetitions?

Try doing several conversions on each channel, and reporting the result of the last conversion.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Results are consistent.
I have used quite some AVR-types in the past years, and this is the first time I see this happening.
I will rig-up my good-old STK200 with a different AVR, ATmega8 or so and will see what happens.

A GIF is worth a thousend words   They are called Rosa, Sylvia, Tricia, and Ulyana. You can find them https://www.linuxmint.com/

Dragon broken ? http://aplomb.nl/TechStuff/Dragon/Dragon.html for how-to-fix tips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Results are consistent.

Have you tried the multiple conversions on >>each<< channel? IIRC there is a thread about that with internal temperature sensors.

But that doesn't explain the voltage dependency.

Quote:

Prescaler = Auto

Hmmm--double-check to ensure you are not going too fast. >>That<< might explain your results.

(I don't have any '45 apps, but I have a number of '25 apps that use the ADC and have not noticed any anomalies.)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Lee, I will do.

A GIF is worth a thousend words   They are called Rosa, Sylvia, Tricia, and Ulyana. You can find them https://www.linuxmint.com/

Dragon broken ? http://aplomb.nl/TechStuff/Dragon/Dragon.html for how-to-fix tips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ADC clock is set by the compiler @ 125kHz ( /64 ) when Auto is selected in the Config statement. Good choice IMO.

I run 10 conversions after eachother, with this as result @ Vcc=5V:

Quote:
ADMUX = 143
ADCSRA = 150
potmeter wiper = 744 nr. 0
potmeter wiper = 746 nr. 1
potmeter wiper = 745 nr. 2
potmeter wiper = 746 nr. 3
potmeter wiper = 746 nr. 4
potmeter wiper = 744 nr. 5
potmeter wiper = 746 nr. 6
potmeter wiper = 744 nr. 7
potmeter wiper = 746 nr. 8
potmeter wiper = 746 nr. 9
Temperature in degr C (not cal'd ) = 33

result @ Vcc=3.1V:

Quote:
ADMUX = 143
ADCSRA = 150
potmeter wiper = 147 nr. 0
potmeter wiper = 146 nr. 1
potmeter wiper = 146 nr. 2
potmeter wiper = 146 nr. 3
potmeter wiper = 146 nr. 4
potmeter wiper = 146 nr. 5
potmeter wiper = 146 nr. 6
potmeter wiper = 146 nr. 7
potmeter wiper = 146 nr. 8
potmeter wiper = 146 nr. 9
Temperature in degr C (not cal'd ) = -170

It's late and warm, so with a fresh view tomorrow I'll re-think all this. And do a test on a different AVR.

result @ Vcc=3.1V, temperature as well with 10 sequential conversions:

Quote:
ADMUX = 143
ADCSRA = 150
potmeter wiper = 146 nr. 0
potmeter wiper = 146 nr. 1
potmeter wiper = 146 nr. 2
potmeter wiper = 145 nr. 3
potmeter wiper = 146 nr. 4
potmeter wiper = 146 nr. 5
potmeter wiper = 146 nr. 6
potmeter wiper = 146 nr. 7
potmeter wiper = 146 nr. 8
potmeter wiper = 146 nr. 9
Temperature in degr C (not cal'd ) = -171 nr. 0
Temperature in degr C (not cal'd ) = -171 nr. 1
Temperature in degr C (not cal'd ) = -171 nr. 2
Temperature in degr C (not cal'd ) = -171 nr. 3
Temperature in degr C (not cal'd ) = -171 nr. 4
Temperature in degr C (not cal'd ) = -170 nr. 5
Temperature in degr C (not cal'd ) = -170 nr. 6
Temperature in degr C (not cal'd ) = -171 nr. 7
Temperature in degr C (not cal'd ) = -171 nr. 8
Temperature in degr C (not cal'd ) = -171 nr. 9

A GIF is worth a thousend words   They are called Rosa, Sylvia, Tricia, and Ulyana. You can find them https://www.linuxmint.com/

Dragon broken ? http://aplomb.nl/TechStuff/Dragon/Dragon.html for how-to-fix tips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Replaced the Tiny45 with a Tiny13, same HW setup.

I needed to make some tweaks to the program to make it run on little flash and sram. And the soft uart has some issues with printing variables so I converted those variables to strings before printing.

The Tiny13 works as it is supposed to.

@ Vcc=5V:

Quote:
ADMUX = 67
ADCSRA = 150
pot 742 nr. 0
pot 741 nr. 1
pot 739 nr. 2
pot 742 nr. 3
pot 742 nr. 4
pot 742 nr. 5
pot 742 nr. 6
pot 742 nr. 7
pot 742 nr. 8
pot 739 nr. 9

@ Vcc=3.1V:

Quote:
ADMUX = 67
ADCSRA = 150
pot 436 nr. 0
pot 437 nr. 1
pot 437 nr. 2
pot 435 nr. 3
pot 435 nr. 4
pot 436 nr. 5
pot 437 nr. 6
pot 437 nr. 7
pot 437 nr. 8
pot 437 nr. 9

So is this is another issue of the Tiny45 ? It looks like it.

Edit: FOUND IT :!:
Pin5 was connected to a FT232 output pin (transmitter, 4k7 in series. That shouldn't be a problem but apparently is.

I will do some more tests to find out what pin5 tolerates.

A GIF is worth a thousend words   They are called Rosa, Sylvia, Tricia, and Ulyana. You can find them https://www.linuxmint.com/

Dragon broken ? http://aplomb.nl/TechStuff/Dragon/Dragon.html for how-to-fix tips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To see how vulnerable a Tiny45 is on pin 5, I made this pin toggle.
Result:

Fv700mv = 660 counts
Temperature (not cal'd ) = 39 degrC
ADMUX = 143
ADCSRA = 150
pin5 at Vcc
----
Fv700mv = 660 counts
Temperature (not cal'd ) = 39 degrC
ADMUX = 143
ADCSRA = 150
pin5 0V
----

I could vary Vcc from 2.7 to 5V, and just a few counts variation: sensitivity of the bandgap-voltage.

So this pin is not connected to the internal 1.1V reference.
Nevertheless, it is more sensitive than a standard IO-pin.
The small current, coming from the FT232 (5V IO-setting, 4k7 safety resistor in series), upset the internal 1.1V reference.

Lesson learned !

Test program:

Quote:

' adc check tiny45 rev1

' Aug 17, 2012 Nard Awater, a.k.a. as Plons

' ATtiny45 in MyLedLamps_drop_in rev1.1 HW project
' 8 MHz internal RC oscillator

' Silicon error in this Tiny45: Timer1. See errata. Kudos to snigelen for his help

' Now facing another issue with the tiny45: ADC shows strange behaviour.
' When powered with 3.1V, ADC-results are incorrect. I use the internal 1.1V reference. So that should work.
' However, I need to power it with 4.2V or more to get the correct results.

' PinB.3 = ADC3 = Fv700mv = fixed voltage of 700mV

Const Soft_uart_out = 1

Const F_proc = 8000000
$regfile = "Attiny45.dat"
$crystal = F_proc

'Fuses
'$prog &HFF , &HE2 , &HD5 , &HFF ' generated. Take care that the chip supports all fuse bytes.

'setup IO
Set Ddrb.1 'ddrb.1 for soft uart out
Set Ddrb.0 'make pin5 output to test vulnerability of Tiny45

Dim Fv700mv As Word 'Fv700mv = fixed voltage

Dim Temperature As Integer 'in degrees C
Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
Const Bg_ref = 1100 'default, not calibrated
'Temperature sensor in Tiny45; defaults, not calibrated yet
Const Temp_coeff = 1
Const Temp_offset = -275

'For terminal on USB connection:
#if Soft_uart_out = 1
'Terminal on USB
Open "comb.1:19200,8,n,1" For Output As #4 'soft UART for output on PortB.1
#endif

Waitms 500 'wait a while when powering up to get everything settled

Main:

Do

Fv700mv = Getadc(3)
Print #4 , "Fv700mv = " ;
Print #4 , Fv700mv ;
Print #4 , " counts"

Temperature = Getadc(15)
Temperature = Temp_coeff * Temperature
Temperature = Temperature + Temp_offset
Print #4 , "Temperature (not cal'd ) = " ;
Print #4 , Temperature ;
Print #4 , " degrC"

Print #4 , "ADMUX = " ;
Print #4 , Admux
Print #4 , "ADCSRA = " ;
Print #4 , Adcsra

Toggle Portb.0

If Pinb.0 = 0 Then
Print #4 , "pin5 0V"
Else
Print #4 , "pin5 at Vcc"
End If

Print #4 , "----"

Waitms 500

Loop

'Very formal, but I want a Happy and Clean End :-)
#if Soft_uart_out = 1
Close #4
#endif

End

A GIF is worth a thousend words   They are called Rosa, Sylvia, Tricia, and Ulyana. You can find them https://www.linuxmint.com/

Dragon broken ? http://aplomb.nl/TechStuff/Dragon/Dragon.html for how-to-fix tips