In general you should only need to change
U_DIVIDER and I_RESISTOR by very small amounts.
----------------------------------------------------------------
Overview
========
- 0-22V 0-2.5A
- 0-30V 0-2A
-It is possible to build a different version without major
-re-design.
-
----------------------------------------------------------------
-How the software works
-======================
-
-I have added a lot more comments to the software than usual.
-It should be possible even for somebody with little experience in
-C programming to understand how this software works.
-
-The circuit uses as internal units ADC steps. All external values
-(Volt, Ampere) are converted to steps of the analog to digital
-converter (ADC). When you change the voltage then this is first
-converted to ADC steps and then it will be further processed.
-
-
-main.c -- this is the main program. All initialization starts here.
- It contains a infinite while loop which will execute the slow tasks
- one by one:
- + Convert ADC results to display values
- + Update the LCD
- + Check push buttons
-
-analog.c -- the analog to digital converter and the main control loop
- for the power supply. Everything is interrupt based here as
- it needs to be fast.
- Voltage control, current limitation and short circuit protection
- are all implemented here.
-
-dac.c -- the digital to analog converter. Initalized from main.c but
- used exclusivly from analog.c
-
-kbd.c -- the keyboard driver
-
-lcd.c -- the LCD driver. This is a special version which will not need
- the rw pin of the display. It uses instead an internal timer
- which should be long enough for the display to finish its task.
- The RW pin which is normally used to poll the display to see
- if it is ready is not needed.
+If you want to build a version that has a smaller output
+range than any of the two version then you can just
+modify the file hardware_settings.h.
+
+The unit can be controlled remotely from a computer using
+a USB serial interface. An add-on card is available from
+http://shop.tuxgraphics.org which offers galvanic separation
+such that you can use this power supply relative to
+any reference point (e.g build two power supply and use
+one as negative and one as positive power supply).
+
+Terminal settings for remote control via your computer
+======================================================
+You can e.g use putty under windows
+http://www.chiark.greenend.org.uk/~sgtatham/putty/
+it supports as well serial connections
+For Linux I can recommend picocom
+http://code.google.com/p/picocom/
+(use command picocom -l -b 9600 /dev/ttyUSB0)
+
+port : Virtual com port (e.g /dev/ttyUSB1 or /dev/ttyUSB0
+ or COM5 under windows or ... to whatever port the
+ virtual com port maps)
+flowcontrol: none
+baudrate : 9600
+parity : none
+databits : 8
+</pre>
+<br>
+<img src=screenshot-cmd-interface.gif>
+<br>
+<pre>
-------------------------------------------------------------------
Copyright: GPL V2
Author: Guido Socher
improved.
-- Basic uart interface prompt, no remote control yet
+digitaldcpower-0.6.2 -- 2010-06-26 Full UART command interface
-------------------------------------------------------------------
</pre>
#include "hardware_settings.h"
// change this when you compile:
-#define SWVERSION "ver: ddcp-0.6.1"
+#define SWVERSION "ver: ddcp-0.6.2"
//#define DEBUGDISP 1
//debug LED:
// the set values but converted to ADC steps
static int16_t set_val_adcUnits[2];
static uint8_t bpress=0;
+// comment this out to use a debug LED on PD0 (RXD):
+#define USE_UART 1
+//
+#ifdef USE_UART
#define UARTSTRLEN 8
static char uartstr[UARTSTRLEN+1];
static uint8_t uartstrpos=0;
static uint8_t uart_has_one_line=0;
+#endif
void delay_ms_uartcheck(uint8_t ms)
// delay for a minimum of <ms>
{
+ int ist_start_of_line=1;
while(ms){
_delay_ms(0.85);
+#ifdef USE_UART
if(uart_has_one_line==0 && uart_getchar_noblock(&uartstr[uartstrpos])){
uart_sendchar(uartstr[uartstrpos]); // echo back
if (uartstr[uartstrpos]=='\n'||uartstr[uartstrpos]=='\r'){
uart_has_one_line=1;
uart_sendchar('\n'); // the echo back puts a \r
}
- uartstrpos++;
+ // ignore leading white space on the line:
+ if (!(uartstr[uartstrpos]==' ' || uartstr[uartstrpos]=='\t')){
+ ist_start_of_line=0;
+ uartstrpos++;
+ }else{
+ // white space
+ if (ist_start_of_line==0){
+ uartstrpos++;
+ }
+ }
if (uartstrpos>UARTSTRLEN){
uart_sendstr_P("\r\nERROR\r\n");
uartstrpos=0; // empty buffer
uart_has_one_line=1;
}
}
+#endif
ms--;
}
}
// check the keyboard
static uint8_t check_buttons(void){
+ uint8_t uartprint_ok=0;
+ uint8_t cmdok=0;
+#ifdef USE_UART
char buf[21];
+#endif
+ //
+#ifdef USE_UART
if (uart_has_one_line){
- // if (strncmp("?",uartstr,1)==0){
+ if (uartstr[0]=='i' && uartstr[1]=='=' && uartstr[2]!='\0'){
+ set_val[0]=atoi(&uartstr[2]);
+ if(set_val[0]>I_MAX){
+ set_val[0]=I_MAX;
+ }
+ if(set_val[0]<0){
+ set_val[0]=0;
+ }
+ uartprint_ok=1;
+ }
+ // version
+ if (uartstr[0]=='v' && uartstr[1]=='e'){
+ uart_sendstr_p(P(" "));
+ uart_sendstr_p(P(SWVERSION));
+ uart_sendstr_p(P("\r\n"));
+ cmdok=1;
+ }
+ // store
+ if (uartstr[0]=='s' && uartstr[1]=='t'){
+ store_permanent();
+ uartprint_ok=1;
+ }
+ if (uartstr[0]=='u' && uartstr[1]=='=' && uartstr[2]!='\0'){
+ set_val[1]=atoi(&uartstr[2]);
+ if(set_val[1]>U_MAX){
+ set_val[1]=U_MAX;
+ }
+ if(set_val[1]<0){
+ set_val[1]=0;
+ }
+ uartprint_ok=1;
+ }
+ // help
+ if (uartstr[0]=='h' || uartstr[0]=='H'){
+ uart_sendstr_p(P(" Usage: u=V*10|i=mA/10|store|help|version\r\n"));
+ uart_sendstr_p(P(" Examples:\r\n"));
+ uart_sendstr_p(P(" set 6V: u=60\r\n"));
+ uart_sendstr_p(P(" max 200mA: i=20\r\n"));
+ cmdok=1;
+ }
+ if (uartprint_ok){
+ cmdok=1;
+ uart_sendstr_p(P(" ok\r\n"));
+ }
+ if (uartstr[0]!='\0' && cmdok==0){
+ uart_sendstr_p(P(" command unknown\r\n"));
+ }
+
int_to_dispstr(measured_val[1],buf,1);
uart_sendstr(buf);
uart_sendchar('V');
uart_sendstr(buf);
uart_sendchar(']');
uart_sendchar(',');
- uart_sendchar(' ');
int_to_dispstr(measured_val[0],buf,2);
uart_sendstr(buf);
uart_sendchar('A');
int_to_dispstr(set_val[0],buf,2);
uart_sendstr(buf);
uart_sendchar(']');
- uart_sendchar(' ');
if (is_current_limit()){
uart_sendchar('I');
}else{
uart_sendchar('U');
}
uart_sendchar('>');
- // }
uart_has_one_line=0;
uartstrpos=0;
}
+#endif
if (check_u_button(&(set_val[1]))){
if(set_val[1]>U_MAX){
set_val[1]=U_MAX;
char out_buf[21];
uint8_t i=0;
uint8_t ilimit=0;
+
+#ifndef USE_UART
// debug led, you can not have an LED if you use the uart
- //DDRD|= (1<<DDD0); // LED, enable PD0, LED as output
- //LEDOFF;
+ DDRD|= (1<<DDD0); // LED, enable PD0, LED as output
+ LEDOFF;
+#endif
init_dac();
lcd_init();
set_val[1]=eeprom_read_word((uint16_t *)0x04);
set_val[0]=eeprom_read_word((uint16_t *)0x02);
}
+#ifdef USE_UART
uart_init();
+#endif
sei();
init_analog();
while (1) {