command interface for remote control
authorGuido Socher <guidosocher@fastmail.fm>
Fri, 25 Jun 2010 22:00:00 +0000 (00:00 +0200)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Sun, 23 Feb 2014 21:34:24 +0000 (22:34 +0100)
README.htm
main.c
screenshot-cmd-interface.gif [new file with mode: 0644]

index 40a985b..9019f19 100644 (file)
@@ -58,7 +58,6 @@ Here you can change also the settings between the 30V and the 22V version.
 In general you should only need to change 
 U_DIVIDER and I_RESISTOR by very small amounts. 
 
----------------------------------------------------------------
 
 Overview
 ========
@@ -81,47 +80,39 @@ The software is prepared for 2 versions:
 - 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
@@ -136,6 +127,7 @@ digitaldcpower-0.6.1 -- 2010-06-06 Number conversion to display string
                         improved.
                      -- Basic uart interface prompt, no remote control yet
 
+digitaldcpower-0.6.2 -- 2010-06-26 Full UART command interface
                         
 -------------------------------------------------------------------
 </pre>
diff --git a/main.c b/main.c
index 1f05d91..39f3f5c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -24,7 +24,7 @@
 #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:
@@ -43,16 +43,23 @@ static int16_t set_val[2];
 // 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'){
@@ -60,7 +67,16 @@ void delay_ms_uartcheck(uint8_t ms)
                                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
@@ -68,6 +84,7 @@ void delay_ms_uartcheck(uint8_t ms)
                                uart_has_one_line=1; 
                        }
                }
+#endif
                 ms--;
         }
 }
@@ -175,9 +192,62 @@ static void store_permanent(void){
 
 // 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');
@@ -187,7 +257,6 @@ static uint8_t check_buttons(void){
                        uart_sendstr(buf);
                        uart_sendchar(']');
                        uart_sendchar(',');
-                       uart_sendchar(' ');
                        int_to_dispstr(measured_val[0],buf,2);
                        uart_sendstr(buf);
                        uart_sendchar('A');
@@ -196,17 +265,16 @@ static uint8_t check_buttons(void){
                        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;
@@ -231,9 +299,12 @@ int main(void)
        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();
@@ -244,7 +315,9 @@ int main(void)
                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) {
diff --git a/screenshot-cmd-interface.gif b/screenshot-cmd-interface.gif
new file mode 100644 (file)
index 0000000..27450a5
Binary files /dev/null and b/screenshot-cmd-interface.gif differ