Jump to content
43oh

ATX2CHARGER - switch your ATX into a car battery charger with MSP430 [UPDATED]


Recommended Posts

Hi everyone,

I have idea to use msp430 and hacked atx power supply as a car battery charger. Simply msp430 will be used to control of charge process, different charging current, time, precharging and swichable load for accurate voltage measurement will be available.

Done:

* hacked atx to 17V

* enclosure

* schematics

* pcb

* functional code



To do:
* firmware development



If anyone have some suggestions fell free to post within this topic, I'll be grateful.


Simple description of operation:

At first voltage measurement is initiated, user set type of car battery, capacity and charge strategy. While charging is started PWM signal control P-MOSFET to set correct current, feedback is taken from 5mR shunt resistor trough RC low-pass filter and software implementation of 3 order Chebyshev LP filter. Every 5 minutes charge process stops, load resistor is applied and voltage reading is taken. During charge process user can see actual voltage, current, elapsed time and estimated period to end of charging. If battery will be accidentally disconnected mcu stops charging process.

 

 

[uPDATE] 22.12.2012 ======================================================

 

Results.

 

ATX2CHARGER is now working, I've successfully charged some car batteries. In near future I need to finish firmware, add rest of options etc. Tomorrow I'll add attachments (sorce of firmware and gerbers).

 

 

Final schematics:

post-30018-0-67297400-1356207158_thumb.jpg
 
 
PCB:
post-30018-0-73340800-1356207190_thumb.png
post-30018-0-69852000-1356207189_thumb.png
post-30018-0-64009200-1356207188_thumb.png
post-30018-0-49273500-1356207171_thumb.jpg
post-30018-0-27400200-1356207187_thumb.png
post-30018-0-91186100-1356207185_thumb.png
post-30018-0-78753600-1356207149_thumb.jpg
post-30018-0-67969400-1356207140_thumb.jpg
 
 
Tests of working unit:

 

 

main.c:

/*====================================================================
 *
 * 		ATX2CHARGER v1.0
 * 		2012 by blankfield <blank0field@gmail.com>
 * 		MSP430G2553 @ 16MHz, 3,3V
 *
 ===================================================================*/
/*====================================================================
 *
 * headers and includes
 *
 ===================================================================*/
#include <msp430.h>
#include <ti/mcu/msp430/csl/CSL.h>
#include <stdio.h>
#include <string.h>
#include "msp430g2553.h"
#include "main.h"
#include "LCD2x16.h"


/*====================================================================
 *
 * constants and definitions
 *
 ===================================================================*/
//charge indicator animation
const char bat0[8] = {0x0A, 0x1F, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F};
const char bat1[8] = {0x0A, 0x1F, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x1F};
const char bat2[8] = {0x0A, 0x1F, 0x11, 0x11, 0x11, 0x1F, 0x1F, 0x1F};
const char bat3[8] = {0x0A, 0x1F, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x1F};
const char bat4[8] = {0x0A, 0x1F, 0x11, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
const char bat5[8] = {0x0A, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};

#define SWSTART		BIT7	//P2.7 - START
#define SWF1		BIT7	//P1.7 - F1
#define SWF2		BIT6	//P1.6 - F2
#define FIRNtap 	15   	//fir lp filter number of tap
#define Vref        (float)3.3
#define ADCRES      (float)1023
#define R7resistor  (float)4650
#define R9resistor  (float)1005
#define R15resistor (float)0.005
#define Uconstant   (float)((Vref/ADCRES)*((R7resistor+R9resistor)/R9resistor))
#define Iconstant   (float)((Vref/ADCRES)/(R15resistor))
enum enumdisplay_menu 		{startup, measure_acc, settings, chargeing_params,
						     chargeing_time, summary};
enum enumcharge_type		{emergency, normal, mainterance_free};
enum enumaccu_voltage	 	{U6V, U12V};
enum enumstate				{idle, charge, discharge};


#pragma DATA_SECTION(ee_charge_type, ".mydata");
#pragma DATA_SECTION(ee_accu_capacity, ".mydata");
#pragma DATA_SECTION(ee_accu_voltage, ".mydata");
#pragma DATA_ALIGN(ee_charge_type, 1);
#pragma DATA_ALIGN(ee_accu_capacity, 1)
#pragma DATA_ALIGN(ee_accu_voltage, 1);


/*====================================================================
 *
 * variables
 *
 ===================================================================*/
//FLASH "EEPROM" VALUES
unsigned char ee_charge_type;
unsigned char ee_accu_capacity;
unsigned char ee_accu_voltage;

struct timeformat {
	char hours;
	char minutes;
	char seconds;
}time;

int   time_prescale=0;
int   measurments[4];
float measured_charge_current = 0;
float measured_charge_voltage = 0;
float measured_discharge_current = 0;
float measured_discharge_voltage = 0;
float measured_idle_current = 0;
float measured_idle_voltage = 0;
float Iavg					= 0;
float Imax					= 0;
float Ucellmax				= 2.5;
float Ucelloptimum			= 2.4;
char  accu_capacity 		= 75;
char  accu_voltage	 		= U12V;
char  charge_type       	= normal;
//char  charge_time       	= 0;
char  charge_progress   	= 0;
char  elapsed_1s            = false;

char  tempstring[20];
float DCV[10];
char  display_level = startup;
char  state = idle;



/*====================================================================
 *
 * main()
 *
 ===================================================================*/
int main(int argc, char *argv[]){
	CSL_init();// Activate Grace-generated configuration
	__delay_cycles(5000);
	init_mcu();
    _delay_cycles(1000000);
    LCD2x16_Initialize();
    __delay_cycles(5000);
	LCD2x16_WriteCommand(0x01);
	__delay_cycles(5000);
	ADC10CTL0 |= ENC;//Start ADC
	TA1CCR1 = 0;
    while(1){
    	control();
    	if (elapsed_1s){
    		sprintf(tempstring,"%1.2f;%1.2f;%1.2f;%1.2f;%1.2f;%1.2f;",
    				measured_idle_voltage,measured_idle_current,
    				measured_charge_voltage,measured_charge_current,
    				measured_discharge_voltage,measured_discharge_current);
    		int i;
    		for (i=0; i<sizeof(tempstring); i++)
    		{
    			while (!(IFG2 & UCA0TXIFG));
    			UCA0TXBUF = tempstring[i];
    		}
    		elapsed_1s=false;
    	}
    	switch(display_level){
    	case startup:
    		menu_redraw();
    		__delay_cycles(25000000);
    		display_level = measure_acc;
    		menu_redraw();
    		break;
    	case measure_acc:
    		menu_redraw();
    		if (!(P2IN & SWSTART)) {
    			beep_sound();
    			display_level=settings;
    			menu_redraw();
    		}
    		if (!(P1IN & SWF1)) {
    			beep_sound();
    			if (accu_voltage == U12V) accu_voltage = U6V;
    			else accu_voltage = U12V;
    			menu_redraw();
    		}
    		break;
    	case settings:
    		if (!(P2IN & SWSTART) && true) {
    			beep_sound();
    			time.seconds=0;
    			time.minutes=0;
    			time.hours=0;
    			Iavg=0;
    		    display_level = chargeing_params;
    		    state = charge;
    		   	menu_redraw();
    		   	}
    		if (!(P1IN & SWF1)) {
    			beep_sound();
    			accu_capacity += 5;
    			if (accu_capacity > 200) accu_capacity = 5;
    		   	menu_redraw();
    		}
    		if (!(P1IN & SWF2)) {
    			beep_sound();
    			charge_type++;
    			if (charge_type>=3) charge_type=0;
    			menu_redraw();
    		}
    		break;
    	case chargeing_params:
    		if (!(P2IN & SWSTART)) {
    			beep_sound();
    		    display_level=summary;
    		    state = idle;
    		   	menu_redraw();
    		   	}
    		if (!(P1IN & SWF1)) {
    			beep_sound();
    			display_level=chargeing_time;
    		   	menu_redraw();
    		}
    		break;
    	case chargeing_time:
    		if (!(P2IN & SWSTART)) {
    			beep_sound();
    		    display_level=summary;
    		    state = idle;
    		   	menu_redraw();
    		   	}
    		if (!(P1IN & SWF1)) {
    			beep_sound();
    			display_level=chargeing_time;
    		   	menu_redraw();
    		}
    		break;
    	case summary:
    		if (!(P2IN & SWSTART)) {
    			beep_sound();
    		    display_level=measure_acc;
    		   	menu_redraw();
    		   	}
    		break;
    	}
    }
}


/*====================================================================
 *
 * menu_redraw()
 *
 ===================================================================*/
void menu_redraw(void){
	LCD2x16_GoTo(0,0);
	switch(display_level){
	case startup:
		LCD2x16_WriteText("ATX2CHARGER v1.0");
		LCD2x16_GoTo(0,1);
		LCD2x16_WriteText("   by blankfield");
		break;
	case measure_acc:
		if (measured_idle_voltage <=1){
			LCD2x16_WriteText("Check battery,  ");
			LCD2x16_GoTo(0,1);
			sprintf(tempstring,"%01.2fV is too low ",measured_idle_voltage);
			LCD2x16_WriteText(tempstring);
		}
		else{
			sprintf(tempstring,"Battery U=%02.2fV  ",measured_idle_voltage);
			LCD2x16_WriteText(tempstring);
			LCD2x16_GoTo(0,1);
			//sprintf(tempstring,"P=%01.0f I= %02.2fA ", TA1CCR1*0.05, measured_idle_current);
			sprintf(tempstring,"Type     F1:%02.0dV ",(accu_voltage*6)+6);
			LCD2x16_WriteText(tempstring);
		}
		break;
	case settings:
		sprintf(tempstring,"Set cap F1:%03.0dAh  ",accu_capacity);
		LCD2x16_WriteText(tempstring);
		LCD2x16_GoTo(0,1);
		if (charge_type==normal) LCD2x16_WriteText("F2: standard    ");
		if (charge_type==mainterance_free) LCD2x16_WriteText("F2: mainter.free");
		if (charge_type==emergency) LCD2x16_WriteText("F2: emerg.charg.");
		break;
	case chargeing_params:
		sprintf(tempstring,"U=%02.1fV I=%02.1fA", measured_charge_voltage, measured_charge_current);
		LCD2x16_WriteText(tempstring);
		LCD2x16_GoTo(0,1);
		sprintf(tempstring,"U=%02.1fV I=%02.1fA", measured_discharge_voltage, measured_discharge_current);
		break;
	case chargeing_time:
		sprintf(tempstring,"Elapsed %2.0f:%2.0f:%2.0f", time.hours, time.minutes, time.seconds);
		LCD2x16_WriteText(tempstring);
		LCD2x16_GoTo(0,1);
		sprintf(tempstring,"Iavg=%2.2f      ", Iavg);
		LCD2x16_WriteText(tempstring);
		break;
	case summary:
		LCD2x16_WriteText("Finished!       ");
		LCD2x16_GoTo(0,1);
		sprintf(tempstring,"%2.0f:%2.0f:%2.0f @ %2.2f", time.hours, time.minutes, time.seconds, Iavg);
		LCD2x16_WriteText(tempstring);
		break;
	}
}

/*====================================================================
 *
 * control()
 *
 ===================================================================*/
void control(void){
	switch (state){
	case idle:
		TA1CCR1=0;
		TA1CCR2=0;
		break;
	case charge:
		TA1CCR2=0;
		if ((measured_charge_voltage < (Ucelloptimum*3*(accu_voltage+1)))
		&& (measured_charge_current < (accu_capacity/5/(charge_type+1)))
		&& (TA1CCR1<1999)){
			TA1CCR1++;
		}
		if (((measured_charge_voltage > (Ucelloptimum*3*(accu_voltage+1)))
		|| (measured_charge_current > (accu_capacity/5/(charge_type+1))))
		&& (TA1CCR1>1)){
			TA1CCR1--;
		}
		if (TA1CCR1 <=100 && measured_charge_voltage >= (Ucelloptimum*3*(accu_voltage+1))){
			state = idle;
			display_level = summary;
			beep_sound();
		}
		break;
	case discharge:
		TA1CCR1=0;
		TA1CCR2=1000;
		break;
	}
}



/*====================================================================
 *
 * init_mcu()
 *
 ===================================================================*/
void init_mcu(void){
	WDTCTL = WDTPW + WDTHOLD;
	char name[18]="AT+NAMEATX2CHARGER";
	int i;
	for (i=0; i<18; i++)
	{
		while (!(IFG2 & UCA0TXIFG));
		UCA0TXBUF = name[i];
	}
}



/*====================================================================
 *
 * measure()
 * interrupts from ADC
 *
 ===================================================================*/
void measure(void){
	time_prescale++;
	if (time_prescale==999){
		elapsed_1s=true;
		time.seconds++; //increase every 1s
		if(time.seconds==60){
			time.seconds=0;
			time.minutes++;
			if(time.minutes==60){
				time.minutes=0;
				time.hours++;
			}
		}
	}
	switch (state){
	case idle:
		measured_idle_current = measurments[3]*Iconstant;
		measured_idle_voltage = measurments[0]*Uconstant;
		break;
	case charge:
		measured_charge_current	= measurments[3]*Iconstant;
		Iavg = (Iavg + measured_charge_current)/2;
		measured_charge_voltage = measurments[0]*Uconstant;
		break;
	case discharge:
		measured_discharge_current = measurments[3]*Iconstant;
		measured_discharge_voltage = measurments[0]*Uconstant;
		break;
	}
	return;
}



/*====================================================================
 *
 * beep_sound()
 *
 ===================================================================*/
void beep_sound(void){
	TA0CCR1 = 1000;
	__delay_cycles(500000);
	TA0CCR1 = 0;
	return;
}


/*====================================================================
 *
 * fir()
 *
 =====================================================================
		WinFilter version 0.8
		http://www.winfilter.20m.com
		akundert@hotmail.com

		Filter type: Low Pass
		Filter model: Chebyshev
		Filter order: 3
		Sampling Frequency: 1000 Hz
		Cut Frequency: 6.000000 Hz
		Pass band Ripple: 1.000000 dB
		Coefficents Quantization: float

		Z domain Zeros
		z = -1.000000 + j 0.000000
		z = -1.000000 + j 0.000000
		z = -1.000000 + j 0.000000

		Z domain Poles
		z = 0.981540 + j -0.000000
		z = 0.990073 + j -0.036073
		z = 0.990073 + j 0.036073
***************************************************************/
float fir(float NewSample) {
    float FIRCoef[FIRNtap] = {
        0.06499156895458164900,
        0.06567519555537033900,
        0.06626048168634461600,
        0.06674435292740793500,
        0.06712913054423083600,
        0.06742809591680600000,
        0.06768722943723189100,
        0.06816788995605341200,
        0.06768722943723189100,
        0.06742809591680600000,
        0.06712913054423083600,
        0.06674435292740793500,
        0.06626048168634461600,
        0.06567519555537033900,
        0.06499156895458164900
    };

    static float x[FIRNtap]; //input samples
    float y=0;            //output sample
    int n;

    //shift the old samples
    for(n=FIRNtap-1; n>0; n--)
       x[n] = x[n-1];

    //Calculate the new output
    x[0] = NewSample;
    for(n=0; n<FIRNtap; n++)
        y += FIRCoef[n] * x[n];

    return y;
}


/*====================================================================
 *
 * flashEraseSegment(int FarPtr)
 *
 ===================================================================*/
void flashEraseSegment(int FarPtr){
    int *Flash_ptr;               // local Flash pointer
    Flash_ptr = (int *) FarPtr;   // Initialize Flash pointer
    FCTL1 = FWKEY + ERASE;
    FCTL3 = FWKEY;
    *Flash_ptr = 0;               // dummy write to start erase
    while (FCTL3 & BUSY );
    FCTL1 = FWKEY;
    FCTL3 = FWKEY +  LOCK;
}


/*====================================================================
 *
 * saveSettings(void)
 *
 ===================================================================*/
void saveSettings(void){
    flashEraseSegment((int) 0xC000);
    FCTL1 = FWKEY + WRT;
    FCTL3 = FWKEY;
    ee_charge_type = (char)charge_type;
    ee_accu_capacity = (char)accu_capacity;
    ee_accu_voltage = (char)accu_voltage;
    FCTL1 = FWKEY;
    FCTL3 = FWKEY +  LOCK;
}

/*====================================================================
 *
 * loadSettings(void)
 *
 ===================================================================*/
void loadSettings(void){
	charge_type = (char)ee_charge_type;
	accu_capacity = (char)ee_accu_capacity;
	accu_voltage = (char)ee_accu_voltage;
}

 

 

main.h:

#ifndef MAIN_H_
#define MAIN_H_
#define false 0
#define true 1
void  menu_redraw(void);
void  control(void);
void  init_mcu(void);
void  buttons(void);
void  measure(void);
void  beep_sound(void);
float fir(float NewSample);
void  flashEraseSegment(int FarPtr);
void  saveSettings(void);
void  loadSettings(void);
#endif /* MAIN_H_ */

 

LCD2x16.c:

// ----------------------------------------------------------------#include "LCD2x16.h"#include "msp430g2553.h"#define RS BIT3           // RS - P2.3  RW - GND#define EN BIT5           // EN - P2.5#define D4 BIT4           // D4 - P1.4#define D5 BIT5           // D5 - P1.5#define D6 BIT0           // D6 - P2.0#define D7 BIT1           // D7 - P2.1//Polish language characters//E6 B9 B3 EA F3 F1 9F 9C A5 BF CA C6 D1 A3 8C D3 AF 8F//?  ?  ?  ?  ?  

post-30018-0-07377900-1353455425_thumb.jpg

post-30018-0-80219900-1353455427_thumb.jpg

post-30018-0-44067600-1353455430_thumb.jpg

post-30018-0-74144100-1353455432_thumb.jpg

post-30018-0-07480600-1353455435_thumb.jpg

post-30018-0-02984900-1353455438_thumb.jpg

post-30018-0-73437100-1353455440_thumb.jpg

post-30018-0-90739300-1353455442_thumb.jpg

post-30018-0-69600800-1353455445_thumb.jpg

post-30018-0-67969400-1356207140_thumb.jpg

post-30018-0-78753600-1356207149_thumb.jpg

post-30018-0-67297400-1356207158_thumb.jpg

post-30018-0-49273500-1356207171_thumb.jpg

post-30018-0-51508000-1356207181_thumb.jpg

post-30018-0-91186100-1356207185_thumb.png

post-30018-0-27400200-1356207187_thumb.png

post-30018-0-64009200-1356207188_thumb.png

post-30018-0-69852000-1356207189_thumb.png

post-30018-0-73340800-1356207190_thumb.png

post-30018-0-68859600-1356207582_thumb.jpg

post-30018-0-21397900-1356207591_thumb.jpg

post-30018-0-01386300-1356207599_thumb.jpg

post-30018-0-54183800-1356207614_thumb.jpg

atx2charger-firmware.zip

gerbers-mirror.zip

gerbers.zip

Link to post
Share on other sites

Interesting concept, I like it.

17v seems excessive, most cars charge at 13.7 to 14.7v, over 15v with significant amps can/will boil the battery. The final voltage at the battery is what matters of course, the PSU may droop down to that point.

 

Have you given it a test run yet? What sort of amperage are you expecting into the battery?

Link to post
Share on other sites

Some information about charging lead-acid batteries, particularly deep cycle: http://www.pacificpowerbatteries.com/aboutbatts/Deep%20Cycle%20Battery%20FAQ/dcfaq6.html (sorry for the link- don't want to leech)

 

 

You're definitely going to want current limiting - a self-resetting thermal breaker could suffice; and reverse voltage protection- I've seen trained mechanics hook up chargers and other things backwards.

Link to post
Share on other sites

Hi,

 

...17v seems excessive, most cars charge at 13.7 to 14.7v, over 15v with significant amps can/will boil the battery.

 

This is only maximal voltage to drive mosfet (Uds) to achieve desired current. PWM will drop this value.

 

Have you given it a test run yet? What sort of amperage are you expecting into the battery?

 

I've made test with resistive load and light bulbs but not with battery, I've measured up to 9A not more because my DMM limit.

 

You're definitely going to want current limiting - a self-resetting thermal breaker could suffice; and reverse voltage protection- I've seen trained mechanics hook up chargers and other things backwards.

 

I have to add some reverse protection diode's on ISENSE and USENSE in parallel and one diode in series with 5V rail. This should protect msp430. MOSFET should protect secondary side of atx, I have to make some simulations in LTspice to check this. I didn't mention that charge process is started only when at least 2V (positive = good polarity) are present on battery terminals.

 

By the way thanks for constructive comments.

Link to post
Share on other sites
... I have to add some reverse protection diode's on ISENSE and USENSE in parallel and one diode in series with 5V rail. This should protect msp430. MOSFET should protect secondary side of atx, I have to make some simulations in LTspice to check this. I didn't mention that charge process is started only when at least 2V (positive = good polarity) are present on battery terminals.

 

By the way thanks for constructive comments.

I wasn't just referring to protecting the equipment. ;) Batteries don't like being charged backwards either. The self resetting breaker would help some there as if the charger can deliver

10A @ 15v and the battery is strong enough to produce 5A @ 12v, you're looking at least a 14A current across the charger output (unless my math is wrong: 10*15=150W, 5*12=60W, 150+60=210, 210/12=17.5A @ 12v, 210/15=14A @ 15v). Been a while since I worked on automotive charging circuits so forgive me if I'm wrong; please correct me if you will.

Link to post
Share on other sites

210/12=17.5A @ 12v, 210/15=14A @ 15v

 

In case of wrong polarity with mosfet switched on, a car battery can provide lot more amps. In this case current is limited only by series resistance of battery, wires, Rds(ON), atx transformer secondary side winding etc.

I've made some simulations and conclusion is only one: don't switch this mosfet when battery is in wrong polarity, it's easy to make software protections for this situation. Wrong polarity for circuit is safety, I don't want to add reverse protection diode on high current path because of power losses.

post-30018-0-08839700-1353542051_thumb.png

post-30018-0-15052700-1353542055_thumb.png

post-30018-0-23429800-1353542059_thumb.png

post-30018-0-78437300-1353542062_thumb.png

post-30018-0-73624600-1353542066_thumb.png

post-30018-0-76373100-1353542071_thumb.png

Link to post
Share on other sites

Can you provide the details of hack.

Nura

In few words it depends on kind of PWM switching controller which ATX supply is using. I have tested models with TL494 and SG6105 IC's both with success. At first you need to remove all components from 3.3V, 5V, -5V rails, then "upgrade" components in 12V rail to new required voltages and power. After this and based on datasheet you need to provide correct voltages on feedback inputs of switching controller basically from resistor dividers, this step bypass OV, UV, OVC protections for missing rails. Via value change in resistor dividers of feedback it's easy to set output voltage. When I finish a project I will try to provide more detail and complete materials about this topic.

 

 

Probably final schematic in attachment.

post-30018-0-68078100-1353723778_thumb.jpg

Link to post
Share on other sites
  • 4 weeks later...

What's the highest voltage one can achieve with modifying the ATX power supply? At sometime I needed 32.4v and 36v to charge my battery pack (A123 cells - for an RC helicopter), and there was no charger available at the time for this kind of voltage, so I had to incorporate a step-up regulator (to 50v max from 12v) and a MSP430 to modify the feedback voltage of the regulator. http://www.rcgroups.com/forums/showthread.php?t=928136&

Link to post
Share on other sites

How much modifying? If you're willing to do some creative modifactions to the feedback bits and replace all the capacitors on the second side you might be able to get a decent bit more. I don't know that anybody has tried. I seriously doubt you'd get 30+ volts though, the transformer is wound to take ~380v and make it 12v after all.

The 12V filter caps are all rated at 16V, as such going over 13.5-14ish without replacing them isn't an especially good idea.

Link to post
Share on other sites

Thanks for the info,

 

changing P.D to output higher voltage seems simple but do i have to rewind the trafo with new turns ?

 

 

Nura

 

Hi, my project basis only on modification of some feedback resistors, no need to play with trafo.

 

 

What's the highest voltage one can achieve with modifying the ATX power supply? At sometime I needed 32.4v and 36v to charge my battery pack (A123 cells - for an RC helicopter), and there was no charger available at the time for this kind of voltage, so I had to incorporate a step-up regulator (to 50v max from 12v) and a MSP430 to modify the feedback voltage of the regulator. http://www.rcgroups.com/forums/showthread.php?t=928136&

 

Up to ~17V for typical ATX PSU is maximum value. Above this value you need to rewind or made a new transformer. In my opinion it's to tricky, especially to disassemble fragile core (2 "E" shapes glued together).

Link to post
Share on other sites
  • 3 weeks later...
  • 2 months later...

Whoa, pretty impressive. Is it functioning fine? Really interesting project. Isn't PWM stressing battery somehow?

EDIT: I was reading code, probably it is just lack of my knowledge, but in code R7resistor - 4650, while in schematic 5600ohm. :?

EDIT2: So, I managed to blow up my ATX three times in a row, but fixed that only twice. Luckily I got one more. Meanwhile I was checking LCD code, and Polish character stuff (commented one) was unclear for me. I wanted to add some Latvian chars, like ? {0x1F, 0x000, 0x1F, 0x11, 0x1F, 0x11, 0x11, 0x000};, but couldn't compile, got an error about "const char". So I changed it to just "char". Then it compiled fine. What else should I do to successfully print out these chars on LCD?

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...