Hi guys,
I've struggled for a bit as a beginner programmer to tackle an arduino based project and I've semi succeeded.
Basically, I wanted to build an adjustable constant current source for my 50W LED projector. The energy source is a hoverboard battery pack - 10S Li-ion @ 4Ah, which I had laying around.
I've decided for the arduino after blowing up a LM2596 and a LM2596HV boards(with diy current sense feedback), probably due to the voltage (42V) or their low quality, or just me :D.
So the idea was to build a sort of buck converter and have a current sense resistor with an Opamp(for gain) to provide current feedback and an Arduino to generate the driving signals and work as the "regulator". I've used the ADC to sample the current and the current setting(a potentiometer). The components I've used are not ideal (esp. the opamp), but I had them from previous projects: LM358 - opamp, IRF540 N - channel Mosfet, IR2101 High&Low side gate driver, 50W LED(1.5A@34V) and an arduino nano.
I've attached my schematic and put the code below.
The whole thing works efficiently, current limiting is also okish, but i've had some issues with the slow ADC so I ended up using 32 ADC prescaler, and working with a switching frequency of 31khz.
The current regulation as a function of input voltage is not that great: it varies about 70mA as the voltage goes from 36V to 42V. Also I'm having some slight shimmering. Any ideeas on why that is?
Any other opinions are welcome cause I want to learn as much as I can.
bool busy;
bool A01 = true;
unsigned int count = 0;
int pot = 0;
int i_m = 0;
int Err;
ISR (TIMER2_OVF_vect) {
if (!busy) {
count++;
if (count > 5000) {
ADMUX |= B00000001;
A01 = false;
count = 0;
}
else {
ADMUX &= B11111110;
A01 = true;
}
ADCSRA |= B01000000;
busy = true;
}
}
void softstart()
{
unsigned int i_ms = 0;
do {
i_ms = analogRead(A0);
} while (i_ms > 100);
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(COM2B0) | _BV(WGM20);
TCCR2B = _BV(CS20);// setari PWM 31khz
OCR2A = 0;
OCR2B = 255;
pinMode(11, OUTPUT);
pinMode(3, OUTPUT);
do {
OCR2A = OCR2A + 1;
OCR2B = OCR2A + 20;
}
while (OCR2A < 70 && OCR2B < 240);
}
void led_on() {
if (bit_is_clear(ADCSRA, ADSC) && (A01 == true))
{
i_m = ADC; // citeste curent masurat
busy = false; // ADC liber
i_m = map(i_m, 0, 1023, 0, 255);
//Serial.println(i_m);
}
if (bit_is_clear(ADCSRA, ADSC) && (A01 == false))
{
pot = ADC;
busy = false;
pot = map(pot, 0, 1023, 19, 50);
}
Err = i_m - pot ;
if (Err > 0 && OCR2A > 1)
{
OCR2A = OCR2A - 1;
OCR2B = OCR2B - 1;
}
else if (Err < 0 && OCR2B < 240)
{
OCR2B = OCR2B + 1;
OCR2A = OCR2A + 1;
}
}
void setup() {
cli();
softstart();
ADCSRA = B00000000;
ADCSRA = B00000100 ;
ADCSRA = ADCSRA | B10000000;
ADMUX = B01000000;
TIMSK2 = _BV(TOIE2);
TIMSK0 &= B11111000;
}
void loop() {
sei();
led_on();
}