opener-6

Dependencies:   TextLCD_HelloWorld2 TextLCD mbed

Fork of TextLCD_HelloWorld2 by Wim Huiskamp

Revision:
5:93f48c84e645
Parent:
4:a3e4bb2053cb
--- a/main.cpp	Sun Mar 29 13:12:07 2015 +0000
+++ b/main.cpp	Mon Apr 16 12:09:03 2018 +0000
@@ -1,76 +1,710 @@
-/* Hello World! for the TextLCD Enhanced Library*/
+
+//  DOOR OPENER   version 1.4 (Opener-6)
+//
+//
+//  program and related hardware serve to test the "door opener"
+//  general function:
+//
+//      open and close via buttons or automatically
+//      motor stops when endposition is reached (or current to high)
+//      duty cycle, ramp- time and pause time for automatic
+//      are adjustable via potentiometers
+//
+//      current, cycles, ramp- time, pause- time will be displayed
+//
+//
+//
+//  include the following functions:
+//  read the digital inputs         button open
+//                                  button close
+//                                  proximity switch open
+//                                  proximity switch close
+//                                  auto_on
+//
+//  read the analog inputs          motor_current
+//                                  duty_cycle      10..100%
+//                                  ramp_time       0.1...9.9 sec
+//                                  pause_time      1.0..99.9 sec
+//
+//  set the outputs                 myled
+//                                  out_status_led
+//                                  out_led_open
+//                                  out_led_close
+//                                  pwm_close
+//                                  pwm_open
+//                                  motor enable
+//  ---------------------------------------------
+//  first date  : 26-07-2017
+//  last change : 10-11-2017
+//  name        : Hillebrand, Martin (Iserlohn)
+//  target      : FRDM K64F (from NXP)
+//  software    : mbed (online)
+//  programming : USB direct to SDA- interface
+//  ---------------------------------------------
 
 #include "mbed.h"
 #include "TextLCD.h"
- 
-// Host PC Communication channels
-Serial pc(USBTX, USBRX); // tx, rx
+
+#define     OPEN        1
+#define     CLOSE       2
+
+// variable declaration
+// ====================
+
+int     old_value           = 0;    //         for single shot putty- output
+int     new_value           = 0;    //         dto.
+
+float   duty_open           = 0;    //         duty cycle in direction open
+float   duty_close          = 0;    //         duty cycle in direction close
+
+double  motor_current       = 0;    //         current from motor controller CT
+
+int     button_open         = 0;    //         following variables contains the 
+int     button_close        = 0;    //         input values, but logical correct
+int     endpos_open         = 0;    //         e. g.  button_open = 1 activ
+int     endpos_close        = 0;    //         switch_auto = 1, when auto is ON
+int     switch_auto         = 0;    //         
+int     time_flag           = 0;    //         flag for resetting timer
+
+int     dir                 = 0;
+int     off_flag            = 0;
+int     auto_status         = 0;
+int     auto_cycle          = 0;
+int     k                   = 0;
+int     start_move          = 0;
+int     flag_9              = 0;
+
+
+
+float   current_motor       = 0;    //          
+double  duty_cycle_percent  = 0;    //                     
+double  duty_cycle_current  = 0;    //         
+
+double  pause_time          = 0;    //          
+double  ramp_time           = 0;
+double  voltage3v3          = 0;    //          analog values refer  
+double  m_old_value         = 0;
+double  m_new_value         = 0;
+double  elapsed_time        = 0;    // elapsed time since t.start()
+double  timeout_x_time      = 0;    // elapsed time for timeout
+double  gradient            = 0;    // gradient for solving
+double  timeouttime         = 60;   // fix value for reaching the endposition
+
+
+Timer   t;   
+Timer   x;
+
+// function declaration
+// ====================
+
+void    initialize(void);
+void    state_to_usb(void);
+void    read_inputs(void);
+void    monitor_output(void);
+void    endpos_led(void);
+void    motor_manual(int);
+void    motor_auto(int);
+void    automatic(void);
+void    motor_off(void);
+void    motor_off_auto(void);
+
+void    manual_mode(void);
+void    lcd_output_start(void);     // display after reset
+void    lcd_output_setting(void);     // setting mode
+void    lcd_output_manual(void);     // auto, waiting for close door
+void    lcd_output_auto0(void);     // auto, close, waiting for start
+void    lcd_output_auto1(void);     // 
+void    lcd_output_auto2(void);
+void    lcd_output_auto3(void);
+
+
+// define inputs and outputs
+// =========================
+
+DigitalOut myled(LED1);             // internal Test- LED
+PwmOut     pwm_open(PTD2);          // PWM- signal for direction open
+PwmOut     pwm_close(PTD0);         // PWM- signal for direction close
+
+DigitalOut out_enable(PTC4);         // enable motor driver
+DigitalOut out_led_open(PTC16);      // indicator in button open
+DigitalOut out_led_close(PTC17);     // indicator in button close
+DigitalOut out_led_status(PTB9);     // led status
  
-// I2C Communication
-I2C i2c_lcd(p9,p10); // SDA, SCL
-//I2C i2c_lcd(p28,p27); // SDA, SCL
- 
-// SPI Communication
-SPI spi_lcd(p5, NC, p7); // MOSI, MISO, SCLK
+DigitalIn  in_btn_open(PTD1);       // button open
+DigitalIn  in_btn_close(PTD3);      // button close
+DigitalIn  in_end_pos_open(PTB23);  // signal endposition open
+DigitalIn  in_end_pos_close(PTA1);  // signal endposition close
+DigitalIn  in_sw_auto(PTC12);       // switch to start auto sequence
+
+
+AnalogIn    a_in_motor(PTC10);      // A5- motor current
+AnalogIn    a_in_duty(PTC11);       // A4- duty cycle analog 
+AnalogIn    a_in_ramp(PTB11);       // A3- ramp analog value 0.1..9.9  seconds
+AnalogIn    a_in_pause(PTB10);      // A2- pause analog value0.0..99.9 seconds
+AnalogIn    a_in_3v3(PTB3);         // A1- reference voltage 3,3 volt
+
+
 
-// LCD instantiation 
-//TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x2);        // 4bit bus: rs, e, d4-d7
-TextLCD_I2C lcd(&i2c_lcd, 0x40, TextLCD::LCD20x4);                  // I2C exp: I2C bus, PCF8574 Slaveaddress, LCD Type
-//TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD16x2, TextLCD::WS0010); // I2C exp: I2C bus, PCF8574 Slaveaddress, LCD Type, Ctrl Type
-//TextLCD_I2C lcd(&spi_lcd, p8, TextLCD::LCD24x4D);                   // I2C exp: SPI bus, CS pin, LCD Type
-//TextLCD_SPI_N lcd(&spi_lcd, p8, p9, TextLCD::LCD16x2, NC, TextLCD::ST7032_3V3); // SPI native: SPI bus, CS pin, RS pin, LCDType=LCD16x2, BL=NC, LCDTCtrl=ST7032
-//TextLCD_I2C_N lcd(&i2c_lcd, ST7032_SA, TextLCD::LCD16x2, NC, TextLCD::ST7032_3V3); // I2C native: I2C bus, slaveaddress, LCDType=LCD16x2, BL=NC, LCDTCtrl=ST7032 =Ok
-//TextLCD_I2C_N lcd(&i2c_lcd, SSD1803_SA1, TextLCD::LCD20x4D, NC, TextLCD::SSD1803_3V3); // I2C native: I2C bus, slaveaddress, LCDType=LCD20x4D, BL=NC, LCDTCtrl=SSD1803 =Ok
- 
-int main() {   
-  Timer t;
+/*
+AnalogIn    a_in_motor(PTB2);       // A0- motor current
+AnalogIn    a_in_duty(PTB3);        // A1- duty cycle analog 
+AnalogIn    a_in_ramp(PTB10);       // A2- ramp analog value 0.1..9.9  seconds
+AnalogIn    a_in_pause(PTB11);      // A3- pause analog value0.0..99.9 seconds
+AnalogIn    a_in_3v3(PTC11);        // A4- reference voltage 3,3 volt
+
+*/
+Serial pc(USBTX, USBRX);            //  Host PC Communication channels tx, rx
+I2C i2c_lcd(PTE25,PTE24);           // SDA, SCL for K64
+
+TextLCD_I2C lcd(&i2c_lcd, 0x27<<1, TextLCD::LCD20x4);  
 
-  pc.printf("TextLCD Enhanced Test. Columns=%d, Rows=%d\n\r", lcd.columns(), lcd.rows());
+//-----------------------------------------------------------------------------
+void    lcd_output_start(void)
+{
+    wait(0.5);
+    lcd.setBacklight(TextLCD::LightOn);     // LCD backlight on
+    lcd.cls();
+    lcd.printf("- door opener v4.6 -");   // LCD Headline
+}
+//-----------------------------------------------------------------------------
+void    lcd_output_setting(void)
+{
+    lcd.locate(0,0);                        
+    lcd.printf("--- setting mode ---");
+    lcd.locate(0,1);                        
+    lcd.printf("duty cycle =  %3.0f %% ",duty_cycle_percent);
+    lcd.locate(0,2);                        
+    lcd.printf("ramp time  =  %3.1f s ",ramp_time);
+    lcd.locate(0,3);  
+    if (pause_time >=10.0)
+    {                                  
+        lcd.printf("pause time = %3.1f s ",pause_time);
+    }
+    else
+    {
+        lcd.printf("pause time =  %3.1f s ",pause_time);
+    }
+}
+//-----------------------------------------------------------------------------
+void    lcd_output_manual(void)
+{
+   
+    if (button_open || button_close)
+    {
+        k++;
+        if (k >8)
+        {
+            lcd.cls();
+            lcd.locate(0,0);               
+            lcd.printf("--- manuel mode ---\n");
+            motor_current = (double)a_in_motor*1000.0;
+            lcd.locate(0,2);               
+            lcd.printf("Current = %6.1f mA\n",motor_current);
+            lcd.locate(0,3);               
+            lcd.printf("duty    = %5.0f %%\n",duty_cycle_current);
+            k = 0;
+        }
+    }
+}
+//-----------------------------------------------------------------------------
+void    lcd_output_auto0(void)
+{
+    k++;
+    if (k >8)
+    {
+        
+    lcd.cls();
+    lcd.locate(0,0);  
+    lcd.printf("-- automatic mode --\n");
+    lcd.locate(0,1);  
+    lcd.printf("status = %d\n", auto_status);
+    motor_current = (double)a_in_motor*1000.0;
+    lcd.locate(0,2);  
+    lcd.printf("door is open");
+    lcd.locate(0,3);  
+    lcd.printf("close door!\n");
+    k = 0;
+    }
+}
+//-----------------------------------------------------------------------------
+void    lcd_output_auto1(void)
+{
+    k++;
+    if (k >8)
+    {
+        
+    lcd.cls();
+    lcd.locate(0,0);  
+    lcd.printf("-- automatic mode --\n");
+    lcd.locate(0,1);  
+    lcd.printf("status = %d\n", auto_status);
+    motor_current = (double)a_in_motor*1000.0;
+    lcd.locate(0,2);  
+    lcd.printf("door is closed");
+    lcd.locate(0,3);  
+    lcd.printf("waiting for start!   ");
+    k = 0;
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+void    lcd_output_auto2(void)
+{
     
-  for (int row=0; row<lcd.rows(); row++) {
-    int col=0;
-      
-    pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
-//    lcd.putc('-');
-    lcd.putc('0' + row);      
-      
-    for (col=1; col<lcd.columns()-1; col++) {    
-      lcd.putc('*');
+    k++;
+    if (k >8)
+    {
+        
+    lcd.cls();
+    lcd.locate(0,0);  
+    lcd.printf("-- automatic mode --\n");
+    lcd.locate(0,1);  
+    if (dir == OPEN)
+    {
+        lcd.printf("status = %d OPEN \n", auto_status);
     }
- 
-    pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
-    lcd.putc('+');       
-  }    
-
-// Fill screen again and time it
-  t.start();
+    if (dir == CLOSE)
+    {
+        lcd.printf("status = %d CLOSE\n", auto_status);
+    }
+    motor_current = (double)a_in_motor*1000.0;
+    lcd.locate(0,2);  
+    lcd.printf("running, cycle %d    ",auto_cycle);
 
-  for (int row=0; row<lcd.rows(); row++) {
-    int col=0;
-      
-    lcd.putc('0' + row);      
-      
-    for (col=1; col<lcd.columns()-1; col++) {    
-      lcd.putc('*');
+    lcd.locate(0,3);  
+    lcd.printf("Current = %6.1f mA\r\n",motor_current);
+    k = 0;
     }
- 
-    lcd.putc('+');       
-  }    
-  t.stop();    
-  pc.printf("All my hard work took %f sec\r\n", t.read());          
-
-// Show cursor as blinking character
-   lcd.setCursor(TextLCD::CurOff_BlkOn);
- 
-// Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780.
-// They are defined by a 5x7 bitpattern. 
-  lcd.setUDC(0, (char *) udc_0);  // Show |>
-  lcd.putc(0);    
-  lcd.setUDC(1, (char *) udc_1);  // Show <|
-  lcd.putc(1);    
-    
-  pc.printf("Bye now\r\n");          
 }
 
 
+//-----------------------------------------------------------------------------
+void    lcd_output_auto3(void)
+{
+    k++;
+    if (k >8)
+    {
+        
+    lcd.cls();
+    lcd.locate(0,0);  
+    lcd.printf("-- automatic mode --\n");
+    lcd.locate(0,1);  
+    lcd.printf("status = %d\n", auto_status);
+    motor_current = (double)a_in_motor*1000.0;
+    lcd.locate(0,2);  
+    lcd.printf("running, cycle %d\r\n",auto_cycle);
 
+    lcd.locate(0,3);  
+    lcd.printf("Pause: %3.1f of %3.1f s\r\n",elapsed_time, pause_time);
+    k = 0;
+    }
+}
+
+//-----------------------------------------------------------------------------
+void    monitor_output(void)
+{
+    m_old_value = duty_cycle_percent + ramp_time + pause_time;
+    
+    if (abs(m_new_value - m_old_value) > 1.0)
+    {
+        pc.printf("\r\n");
+        pc.printf("----------------------------\r\n");
+        pc.printf("duty  cycle = %3.1f Prozent \r\n", duty_cycle_percent);
+        pc.printf("ramp  time  = %3.1f Sekunden \r\n", ramp_time);
+        pc.printf("pause time = %4.1f  Sekunden \r\n",  pause_time);
+        wait(0.1);
+    }
+    m_new_value = m_old_value;
+}
+//-----------------------------------------------------------------------------
+void    read_inputs(void)           // and calculate 
+{
+    button_open         =   !in_btn_open;               
+    button_close        =   !in_btn_close;
+    
+    endpos_open         =   !in_end_pos_open; 
+    endpos_close        =   !in_end_pos_close;
+    switch_auto         =   !in_sw_auto;
+    
+    
+    
+    voltage3v3          =   (float)a_in_3v3;
+    
+    duty_cycle_percent  =   (double)(a_in_duty*100.0f/voltage3v3);
+    if (duty_cycle_percent > 100.0)  duty_cycle_percent = 100.0;
+    if (duty_cycle_percent < 10.0)   duty_cycle_percent =  10.0;
+    
+    ramp_time           =   (double)(a_in_ramp*9.9f/voltage3v3);
+    if (ramp_time <0.1) ramp_time = 0.1;
+    if (ramp_time >9.9) ramp_time = 9.9;
+      
+    pause_time          =   (double)(a_in_pause*99.9f/voltage3v3);
+    if (pause_time <1.0)  pause_time = 1.0;
+    if (pause_time >99.9) pause_time = 99.9;
+    
+    if (!button_open && !button_close && !switch_auto)
+    {
+        lcd_output_setting();
+    }
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void    initialize(void)
+{
+    out_led_status = 1;
+    out_enable = 1;
+    pwm_close.period(1.0/1000);
+    pwm_open.period(1.0/1000);
+}
+// -----------------------------------------------------------------------------
+void    endpos_led(void)
+{
+        if (endpos_open) // switching ON of the "end pos"-led in the button OPEN
+        {                   
+            out_led_open = 1;
+        } else 
+        {                
+            out_led_open = 0;
+        }
+        //=====================================================================
+        if (endpos_close) // switching ON "end pos"-led in the button CLOSE
+        {                                       
+            out_led_close = 1;
+        } else
+        {
+            out_led_close = 0;
+        }
+}
+// ----------------------------------------------------------------------------
+void    state_to_usb(void)
+{
+    new_value = (int)(button_open * 1 + button_close * 2 + endpos_open * 
+    4 + endpos_close * 8 + switch_auto * 16 + auto_status *32);
+    
+    if (new_value!= old_value) 
+    {           // state of inputs if new values different from former values
+
+        pc.printf("----------------------\r\n");
+        pc.printf("Button Open          %d \r\n", (int)button_open);
+        pc.printf("Button Close         %d \r\n", (int)button_close);
+        pc.printf("End Position Open    %d \r\n", (int)endpos_open);
+        pc.printf("End Position Close   %d \r\n", (int)endpos_close);
+        pc.printf("Switch Auto          %d \r\n", (int)switch_auto);
+        pc.printf("auto status          %d \r\n", (int)auto_status);
+        
+
+        old_value = new_value;              
+    }
+    out_led_status = !out_led_status;       
+    wait(0.05);
+}
+// -----------------------------------------------------------------------------
+void    automatic(void)
+{
+        switch (auto_status) 
+        {
+// -----------------------------------------------------------------------------            
+            case 0:
+                lcd_output_auto0();
+                if (endpos_close)
+                {
+                    auto_status = 1;
+                }                 
+            break;
+// -----------------------------------------------------------------------------            
+            case 1:
+                lcd_output_auto1();
+                if (endpos_close && button_open)
+                {
+                    auto_status = 2;        // forward to status 2
+                }   
+                if (!endpos_close)          // back to status 0
+                {
+                    auto_status = 0;
+                }   
+            break;
+// -----------------------------------------------------------------------------            
+            case 2:
+                lcd_output_auto1();
+                if (endpos_close && !button_open)  // release start button
+                {
+                    auto_status = 3;
+                }    
+                if (!endpos_close)                  // back to status 0
+                {
+                    auto_status = 0;
+                }   
+            break;
+// -----------------------------------------------------------------------------            
+            case 3:
+                lcd_output_auto2();
+                if (endpos_close && !button_open)   // release start button
+                {
+                    wait(0.3);
+                    auto_status = 4;
+                    start_move  = 1;        //?
+                    time_flag   = 0;
+                }    
+            break;
+// -----------------------------------------------------------------------------            
+            case 4:
+                lcd_output_auto2();
+                motor_auto(OPEN);    // motor runs until 
+                                     // a.) position is open      
+                                     // b.) auto switch turned off 
+                                     // c.) timeout reached
+                                     //    
+                start_move = 0;
+                if (!endpos_close)   // motor leave endpos close
+                {
+                    x.reset();
+                    x.start();
+                    timeout_x_time = 0;
+                    
+                    auto_status = 5;
+                    
+                }    
+            break;
+// -----------------------------------------------------------------------------        
+        case 5:
+                lcd_output_auto2();
+                motor_auto(OPEN);     // motor runs until 
+                                      // a.) position is open      
+                                      // b.) auto switch turned off 
+                                      // c.) timeout reached
+                                      //  
+                    
+                timeout_x_time  = x.read();                
+                if (timeout_x_time > timeouttime)
+                {
+                    motor_off_auto();
+                    out_led_status = 1;
+                    
+                }
+        
+            
+            
+            
+                
+                    
+                if (endpos_open)      // motor reach open position
+                {
+                    motor_off_auto();
+                    auto_status = 6;
+                }    
+        break;
+// -----------------------------------------------------------------------------        
+        case 6:
+                lcd_output_auto2();
+                time_flag   = 0;
+                if (endpos_open)        //
+                {
+                    auto_status = 7;
+                }    
+        break;              
+// -----------------------------------------------------------------------------        
+        case 7:
+                lcd_output_auto3();
+                if (!time_flag)
+                {
+                    t.reset();
+                    t.start();
+                    time_flag = 1;
+                    elapsed_time = 0;
+                }
+                elapsed_time = t.read();                
+                if (elapsed_time > pause_time)
+                {
+                    auto_status = 8;
+                    time_flag = 0;
+                }
+        break;
+// -----------------------------------------------------------------------------        
+            case 8:
+                lcd_output_auto2();
+                motor_auto(CLOSE);    // motor runs until 
+                                     // a.) position is open      
+                                     // b.) auto switch turned off 
+                                     // c.) timeout reached
+                if (!endpos_open)   
+                {
+                    auto_status = 9;
+                }    
+            break;
+// -----------------------------------------------------------------------------        
+        case 9:
+                lcd_output_auto2();
+                motor_auto(CLOSE);     // motor runs until 
+                                      // a.) position is open      
+                                      // b.) auto switch turned off 
+                                      // c.) timeout reached
+                if (endpos_close)   
+                {
+                    motor_off_auto();
+                    auto_status = 10;
+                    time_flag = 0;
+                    auto_cycle++;                   
+                    if (auto_cycle > 100000) auto_cycle = 0;
+                }    
+        break;
+// -----------------------------------------------------------------------------        
+        case 10:
+                lcd_output_auto3();
+                if (!time_flag)
+                {
+                    t.reset();
+                    t.start();
+                    time_flag = 1;
+                    elapsed_time = 0;
+                }
+                elapsed_time = t.read();                
+                if (elapsed_time > pause_time)
+                {
+                    auto_status = 11;
+                    time_flag = 0;
+                }
+        break;
+// -----------------------------------------------------------------------------        
+        case 11:
+                lcd_output_auto2();
+                if (endpos_close)  
+                {
+                    auto_status = 2;
+                }    
+        break;
+// -----------------------------------------------------------------------------        
+        default:        
+        break;
+    }
+}
+// -----------------------------------------------------------------------------
+void    motor_manual(int direction)
+{
+    if (!time_flag)
+    {
+        t.reset();
+        t.start();
+        time_flag = 1;
+        elapsed_time = 0;
+    }
+    elapsed_time = t.read();
+    gradient = (duty_cycle_percent-10.0f)/ramp_time;
+    
+    if (elapsed_time < ramp_time) 
+    {
+        duty_cycle_current = 10.0 + elapsed_time * gradient;
+    }
+    else
+    {
+        duty_cycle_current = duty_cycle_percent;
+    }
+    if (direction == OPEN)
+    {
+        pwm_open.write(duty_cycle_current/100.0f);
+    }
+    if (direction == CLOSE)
+    {
+        pwm_close.write(duty_cycle_current/100.0f);
+    }
+    lcd_output_manual();
+}
+// ----------------------------------------------------------------------------
+void    motor_auto(int direction)
+{
+    dir = direction;
+    
+    if (!time_flag)
+    {
+        t.reset();
+        t.start();
+        time_flag = 1;
+        elapsed_time = 0;
+    }
+        
+    elapsed_time = t.read();
+    gradient = (duty_cycle_percent-10.0f)/ramp_time;
+    
+    if (elapsed_time < ramp_time) 
+    {
+        duty_cycle_current = 10.0 + elapsed_time * gradient;
+    }
+    else
+    {
+        duty_cycle_current = duty_cycle_percent;
+    }
+    if (direction == OPEN)
+    {
+        pwm_open.write(duty_cycle_current/100.0f);
+    }
+    if (direction == CLOSE)
+    {
+        pwm_close.write(duty_cycle_current/100.0f);
+    }
+}
+// ----------------------------------------------------------------------------
+void    motor_off_auto(void)
+{
+    duty_cycle_current = 0;
+    pwm_close.write(0);
+    pwm_open.write(0);
+}
+// ----------------------------------------------------------------------------
+void    motor_off(void)
+{
+    duty_cycle_current = 0;
+    pwm_close.write(0);
+    pwm_open.write(0);
+    lcd_output_manual();
+}
+// ----------------------------------------------------------------------------
+void    manual_mode(void)
+{
+    auto_status = 0;
+    //-----------------------------------
+    if(button_open && !endpos_open)     
+    {
+        motor_manual(OPEN);
+        off_flag = 0;
+    }    
+    //-----------------------------------
+    if(button_close && !endpos_close)     
+    {
+        motor_manual(CLOSE);
+        off_flag = 0;
+    }    
+    //-----------------------------------
+    if (off_flag)
+    {
+        motor_off();
+        off_flag = 0;   
+        time_flag = 0;
+    }
+}
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+int main()
+{
+    initialize();
+    lcd_output_start();
+    while (1) 
+    {                                         
+        read_inputs();
+        state_to_usb();    
+        monitor_output();
+        endpos_led();
+
+        off_flag = 1;               // to prevent display flicker
+
+        if (!switch_auto)           // manual mode
+        {
+            manual_mode();
+        }        
+        if (switch_auto)            // auto mode
+        {   
+            automatic();
+        }
+    }
+}