View previous topic :: View next topic |
Author |
Message |
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Nov 01, 2016 1:39 pm Post subject: Non Linear LED and PWM |
|
|
Hello everybody,
I'm trying to control an LED's brightness via PWM, simple job I would think.
An AT Mega 8a is being used in this project along with an LTC6102 current monitor. the problem lies in the fact that there is an Variable resistor on ADC 0 and just spits out 0 to 5 Vdc like it should and the ADC reads it nicely, 0 to 3ff (10 bit). The Led is a 3 watt unit that runs at 2.5 up to 3.9 Vdc and is not linear. So I cant get it to work by just varying the voltage to as normally would be done.
I want to control it by current up to 1000 ma. So it starts to work at to 2.5 Vdc up the 3.9 max rating. When my PWM starts up (10 bit also) it's Variable resistor is at 50% of the way just to get it barely lit up.
What I would like is to somehow re scale the vr to work with the LED, so when the vr is at it's lowest voltage output to the ADC the PWM should be roughly at 50% of is value.
Timer one is configured for PWM=10 and works. I have tried to hard code this in Bascom but the memory is is not enough to hold it in the AVR.
Is there some type of cleaver way to do this? I need to say something like if ADC's value is 0 then output at 50% duty cycle on the PWM.
That's not to bad to implement but I still need to cover the rest of the ADC (what if its 0x3ff (1023)
I'm not sure I can figure this out, I tried using a lookup table, but it would be so big, it does not fit.
Any suggestions?
Robert
(BASCOM-AVR version : 2.0.7.8 ) |
|
Back to top |
|
|
six1
Joined: 27 Feb 2009 Posts: 553
|
Posted: Tue Nov 01, 2016 2:08 pm Post subject: |
|
|
Hi Robert
could be the way...
int start_adc = 512
int end_adc = 1023
float calc_adc = start_adc / (end_adc - start_adc)
out_adc = ( getadc(0) / calc_adc) + start_adc
best, michael _________________ For technical reasons, the signature is on the back of this message. |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Nov 01, 2016 2:22 pm Post subject: |
|
|
Just to make sure I got this right:
Quote: | int start_adc = 512
int end_adc = 1023
float calc_adc = start_adc / (end_adc - start_adc)
out_adc = ( getadc(0) / calc_adc) + start_adc |
int is an integer by the name of: "start_adc" and a value of 512
the same for "int end_adc" with a value of 1023
could you shed some light on this, where does "Calc_adc" come from along with "out_adc"?
I take it that they are dimmed variables of the word type?
Can you provide an example of this in code form of your intended usage of this?
Thanks for your help mate, it looks like it just may work.
Robert |
|
Back to top |
|
|
six1
Joined: 27 Feb 2009 Posts: 553
|
Posted: Tue Nov 01, 2016 2:40 pm Post subject: |
|
|
Hi Robert,
"out_adc" was not a good name for it... let's rename it to "out_pwm"
Declare start_adc and end_adc as word or as Constant.
Calc_adc is type single and out_pwm is type word variable.
The only part for you is, to do calculation step by step in multiple lines in bascom style
What it does: the whole width of adc is calculated to use it between start and end values and out_pwm will be between start_adc and end_adc (...my hope )
best, michael _________________ For technical reasons, the signature is on the back of this message. |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Nov 01, 2016 2:47 pm Post subject: |
|
|
Thank-you for the clarification,
I'll give it a go..
By the way, your signature is quite cool, ingenues
Robert |
|
Back to top |
|
|
six1
Joined: 27 Feb 2009 Posts: 553
|
Posted: Tue Nov 01, 2016 2:54 pm Post subject: |
|
|
...do you have had a look backside your screen? _________________ For technical reasons, the signature is on the back of this message. |
|
Back to top |
|
|
six1
Joined: 27 Feb 2009 Posts: 553
|
Posted: Tue Nov 01, 2016 2:54 pm Post subject: |
|
|
.... _________________ For technical reasons, the signature is on the back of this message. |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Nov 01, 2016 3:56 pm Post subject: |
|
|
Code: | Dim Current_val As Word '- Current sensor reading
Dim Setpoint As Word '- Holds our Thumb-wheel setpoint
Dim Start_adc As Word '- Used in VR's Array look up table
Dim End_adc As Word
Dim Calc_adc As Single
Dim Out_pwm As Word
On Timer2 T2_isr_a '- Fires on Timer2 Compare match A ISR
'- Set items to only run once at startup
Call Configure_adc() '- Setup the ADC registers
Call Timer1_setup() '- Setup Timer1 for 10bit pwm PortB bit 1 only (PB1)
Call Timer2_setup() '- Setup Timer2 compare match A
Enable Interrupts '- Enable global interupts
Enable Timer1 '- Start Timer1 (PWM timer)
Compare1a = &H00 '- Set the PWM DUTY to 0x00 at start
Enable Timer2 '- Start Timer2 (Polarity switching)
Start_adc = 512
End_adc = 1023
Start Adc '- Start the adc Conversion
'- End Set items to only run once at startup
'-------------------------------------------------------------------------------
'Main program loop
'-------------------------------------------------------------------------------
Do
' *** NOTES ***
'- Led does not lite up until 2.5 Vdc. top = 3.9 Vdc 0 to 1000 Ma of current
'- 50% of pot will be useless 5 Vdc/1023 = .0048 Mv. per step 1FF (511) = 2/5 Vdc
'- That leaves 50 of the pot to control the LED brightness
'- Need to scale pot to the LEDs Current curve and still make it fit in the memory of the ATMEGA8
''Float Calc_adc = Start_adc /(end_adc - Start_adc)
Calc_adc = Start_adc /(end_adc - Start_adc)
Out_pwm =(getadc(0) / Calc_adc) + Start_adc
Loop |
Always get:
Error : 242 Line : 88 Data type of source and target variables do not match [ 0] , in File : C:\Users\Robert\Desktop\ATMEGA8\Camera_atmega8.bas
Error : 35 Line : 91 3 parameters expected , in File : C:\Users\Robert\Desktop\ATMEGA8\Camera_atmega8.bas
Error : 124 Line : 91 LOOP expected , in File : C:\Users\Robert\Desktop\ATMEGA8\Camera_atmega8.bas
A code snippet would be ideal here. |
|
Back to top |
|
|
six1
Joined: 27 Feb 2009 Posts: 553
|
Posted: Tue Nov 01, 2016 5:11 pm Post subject: |
|
|
Hi,
you can't do that operation in one step, as i mentiond before...
NOT
Calc_adc = Start_adc /(end_adc - Start_adc)
Better
Calc_adc = end_adc - Start_adc
Calc_adc = Start_adc / Calc_adc
NOT
Out_pwm =(getadc(0) / Calc_adc) + Start_adc
BETTER
Out_pwm = getadc(0)
Out_pwm = Out_pwm / Calc_adc
Out_pwm = Out_pwm + Start_adc
AND!
there a more steps to reach goal!
out_pwn now is a value between Start_adc and end_adc.
for your pwm, wich can be at max 255, you have to divide by 4 ! _________________ For technical reasons, the signature is on the back of this message. |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
|
Back to top |
|
|
six1
Joined: 27 Feb 2009 Posts: 553
|
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Wed Nov 02, 2016 8:56 pm Post subject: |
|
|
Yes on the right track, it reads the right way.
As for dividing by 4 it's not needed, as the adc and pwm are both 10 bit.
It works well thus far in the debugger, tomorrow I will test it out on the real circuit... Your code looks just like mine, I will post up the results
from the test and what ever needs to be changed on my end.
Once again, Thanks for your help,
Robert |
|
Back to top |
|
|
|