Webserver only w/o any other functions, single thread. Running on STM32F013+W5500

Dependencies:   NTPClient W5500Interface Watchdog device_configuration eeprom_flash mbed-rpc-nucleo mbed-rtos mbed

Fork of F103-Serial-to-Ethernet by Chau Vo

Files at this revision

API Documentation at this revision

Comitter:
olympux
Date:
Tue Jul 19 07:50:53 2016 +0000
Parent:
44:4e8a9b466695
Child:
46:971bdaa3507c
Commit message:
Tested

Changed in this revision

Formatter.cpp Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Formatter.cpp	Thu Jun 16 21:51:38 2016 +0000
+++ b/Formatter.cpp	Tue Jul 19 07:50:53 2016 +0000
@@ -138,7 +138,7 @@
 </head> \
 <body>";
 
-const char* INTERACTIVE_HTML_CODE_2 = "<h3>Device Configuration</h3>\
+const char* INTERACTIVE_HTML_CODE_2 = "<h3>Device Configuration (not yet)</h3>\
 <form>\
 IP (x.x.x.x): <input type=\"text\" id=\"ipadd\"><br>\
 Subnet (x.x.x.x): <input type=\"text\" id=\"subnet\"><br>\
--- a/README.md	Thu Jun 16 21:51:38 2016 +0000
+++ b/README.md	Tue Jul 19 07:50:53 2016 +0000
@@ -15,11 +15,19 @@
 
 Initial version
 
+Features
+
 - Use eeprom for device configuration
 - HTTP server
 - RPC over HTTP:
   + Support creating objects including AnalogIn
   + Support RPC string variable
+- Additional RPC commands:
+  + Set ip address: /ipaddr/write 192.168.0.121
+  + Save ip address: /saveipaddr/run
+  + Enable configured flag: /setconf/run
+  + Disable configured flag: /resetconf/run
+  
 
 Bug fixes
 
--- a/main.cpp	Thu Jun 16 21:51:38 2016 +0000
+++ b/main.cpp	Tue Jul 19 07:50:53 2016 +0000
@@ -37,16 +37,16 @@
 
 
 /*
-* Hardware defines
-*/
+ * Hardware defines
+ */
 // Ethernet
 SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
 EthernetInterface eth(&spi, PA_4, PC_9); // spi, cs, reset
 int ethernet_init(void);
 
 /*
-* EEPROM section
-*/
+ * EEPROM section
+ */
 // Virtual address defined by the user: 0xFFFF value is prohibited
 uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
                                      0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
@@ -72,9 +72,9 @@
  * Variables for network configuration, TCP server
  */
 // Device configuration
-uint16_t u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4], u16mac_addr[3]; // 16-bits, directly loaded from eeprom
-char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16], str_mac_addr[20]; // for printf and RPC, converted from 16-bits u16ip_xxx
-uint8_t u8ip_addr[4];// keep ip address in 8-bits
+uint16_t u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4], u16mac_addr[3]; // 16-bits variables to be compatible with eeprom functions
+char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16], str_mac_addr[20]; // RPC variables, converted from 16-bits u16ip_xxx
+uint8_t u8ip_addr[4]; // keep ip address in 8-bits
 uint16_t configured_ip = 0;  // flag indicates a static ip has been configured 0xA5A5
 uint8_t u8mac[6]; // mac in 8-bits
 
@@ -82,31 +82,28 @@
 uint16_t tcp_server_local_port = 10000; // change to 7000 if internet required
 uint16_t udp_server_local_port = 11000;
 
-// TCP client
+// Used for TCP client mode
 // this section is used to set the TCP server that this device connects to in TCP client mode.
 // this device will update its status to the server every transmit_time_period.
 uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s
-uint16_t u16server_ip_addr[4]; // directly loaded from eeprom
+uint16_t u16server_ip_addr[4]; // 16-bit variable to be compatible with eeprom functions
 uint8_t u8server_ip_addr[4]; // server ip address in 8-bits
-char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr
-uint16_t u16tcp_server_port; // directly loaded from eeprom
-uint16_t u16enable_tcp_server, u16enable_tcp_client;// flags for enabling TCP client or TCP server
+char str_server_ip_addr[16]; // RPC variable, converted from 16-bits u16server_ip_addr
+uint16_t u16tcp_server_port; // 16-bit variable to be compatible with eeprom functions
+uint16_t u16enable_tcp_server, u16enable_tcp_client; // flags for enabling TCP client or TCP server
 
 // Corresponding RPC variables
 RPCVariable<char*> rpcIPAddress(str_ip_addr, 16, "ipaddr");
 RPCVariable<char*> rpcSubnet(str_ip_subnet, 16, "subnet");
 RPCVariable<char*> rpcGateway(str_ip_gateway, 16, "gateway");
 RPCVariable<char*> rpcMac(str_mac_addr, 20, "mac");
-RPCVariable<unsigned short> rpcLocalTCPServerPort(&tcp_server_local_port, "localtcpserverport");
+//RPCVariable<unsigned short> rpcLocalTCPServerPort(&tcp_server_local_port, "localtcpserverport");
 RPCVariable<unsigned short> rpcLocalUDPPort(&udp_server_local_port, "localudpport");
-RPCVariable<unsigned short> rpcEnableTCPServer(&u16enable_tcp_server, "enabletcpserver");
+//RPCVariable<unsigned short> rpcEnableTCPServer(&u16enable_tcp_server, "enabletcpserver");
 
 // RPC function definitions
-// Create a function of the required format
-void save_ip_addr(Arguments* args, Reply* rep);
-void disable_static_ip_addr_flag(Arguments* args, Reply* rep);
-
-void save_ip_addr(Arguments* args, Reply* rep){
+// save ip address only
+void set_ip_addr(Arguments* args, Reply* rep){
     int b[4], n, i;
     char ipaddr[4];
     
@@ -123,23 +120,130 @@
         DBG("Saving IP address failed");
     }
 }
-void set_configuration(Arguments* args, Reply* rep){
+
+// set configuration flag
+void set_configuration_flag(Arguments* args, Reply* rep){
     set_conf();
 }
-void reset_configuration(Arguments* args, Reply* rep){
+
+// reset configuration flag
+void reset_configuration_flag(Arguments* args, Reply* rep){
     reset_conf();
 }
-// Attach it to an RPC object
-RPCFunction rpcSaveIPAddr(&save_ip_addr, "saveipaddr");
-RPCFunction rpcSetConfiguration(&set_configuration, "setconf");
-RPCFunction rpcResetConfiguration(&reset_configuration, "resetconf");
+
+// Attach eeprom functions to RPC functions
+RPCFunction rpcSaveIPAddr(&set_ip_addr, "saveipaddr");
+RPCFunction rpcSetConfiguration(&set_configuration_flag, "setconf");
+RPCFunction rpcResetConfiguration(&reset_configuration_flag, "resetconf");
+
 
+/*
+ * RPC Protocol
+ * Use the RPC enabled wrapped class  - see RpcClasses.h for more info
+ */
+// DigitalIn
+RpcDigitalIn di0(PB_14, "di0");
+RpcDigitalIn di1(PB_12, "di1");
+RpcDigitalIn di2(PB_10, "di2");
+RpcDigitalIn di3(PB_1, "di3");
+RpcDigitalIn di4(PB_15, "di4");
+RpcDigitalIn di5(PB_13, "di5");
+RpcDigitalIn di6(PB_11, "di6");
+RpcDigitalIn di7(PB_2, "di7");
+DigitalIn din0(PB_14);
+DigitalIn din1(PB_12);
+DigitalIn din2(PB_10);
+DigitalIn din3(PB_1);
+DigitalIn din4(PB_15);
+DigitalIn din5(PB_13);
+DigitalIn din6(PB_11);
+DigitalIn din7(PB_2);
+// DigitalOut
+RpcDigitalOut do0(PB_3, "do0");
+RpcDigitalOut do1(PB_5, "do1");
+RpcDigitalOut do2(PB_7, "do2");
+RpcDigitalOut do3(PB_9, "do3");
+RpcDigitalOut do4(PD_2, "do4");
+RpcDigitalOut do5(PB_4, "do5");
+RpcDigitalOut do6(PB_6, "do6");
+RpcDigitalOut do7(PB_8, "do7");
+DigitalOut dout0(PB_3);
+DigitalOut dout1(PB_5);
+DigitalOut dout2(PB_7);
+DigitalOut dout3(PB_9);
+DigitalOut dout4(PD_2);
+DigitalOut dout5(PB_4);
+DigitalOut dout6(PB_6);
+DigitalOut dout7(PB_8);
+// AnalogIn
+RpcAnalogIn adc10(PC_0, "ai0"); // adc10
+RpcAnalogIn adc11(PC_1, "ai1"); // adc11
+AnalogIn ain0(PC_0);
+AnalogIn ain1(PC_1);
+// AnalogOut, PWM
+RpcPwmOut pwm11(PA_8, "pwm0"); // pwm11
+RpcPwmOut pwm21(PA_15, "pwm1"); // pwm21
 // Serial
+RpcSerial rpcUsart(USBTX, USBRX, "uart"); // usart2
 Serial uart(USBTX,USBRX);
+// Timer
+RpcTimer timer1("tmr1");
 // Watchdog
 Watchdog wdt;
 
 
+// Some variable types that can be modified through RPC.
+//int wheelsOn;
+//char lcdBannerMessage;
+//float speed;
+int current_time;
+int enable_onoff_dout = 0; // 8-bit LSB
+int do0OnTime = 64800, do0OffTime = 21600; //default ON = 18:00, OFF = 6:00
+int do1OnTime = 64800, do1OffTime = 21600;
+int do2OnTime = 64800, do2OffTime = 21600;
+int do3OnTime = 64800, do3OffTime = 21600;
+int do4OnTime = 64800, do4OffTime = 21600;
+int do5OnTime = 64800, do5OffTime = 21600;
+int do6OnTime = 64800, do6OffTime = 21600;
+int do7OnTime = 64800, do7OffTime = 21600;
+ 
+//RPCVariable<int> rpcLights(&wheelsOn, "wheels");
+//RPCVariable<char> rpcBanner(&lcdBannerMessage, "banner");
+//RPCVariable<float> rpcSpeed(&speed, "speed");
+RPCVariable<int> rpcCurrentTime(&current_time, "Time");
+RPCVariable<int> rpcEnableOnOffDout(&enable_onoff_dout, "EnableOnOffDout");
+RPCVariable<int> rpcdo0OnTime(&do0OnTime, "do0OnTime");
+RPCVariable<int> rpcdo0OffTime(&do0OffTime, "do0OffTime");
+RPCVariable<int> rpcdo1OnTime(&do1OnTime, "do1OnTime");
+RPCVariable<int> rpcdo1OffTime(&do1OffTime, "do1OffTime");
+RPCVariable<int> rpcdo2OnTime(&do2OnTime, "do2OnTime");
+RPCVariable<int> rpcdo2OffTime(&do2OffTime, "do2OffTime");
+RPCVariable<int> rpcdo3OnTime(&do3OnTime, "do3OnTime");
+RPCVariable<int> rpcdo3OffTime(&do3OffTime, "do3OffTime");
+RPCVariable<int> rpcdo4OnTime(&do4OnTime, "do4OnTime");
+RPCVariable<int> rpcdo4OffTime(&do4OffTime, "do4OffTime");
+RPCVariable<int> rpcdo5OnTime(&do5OnTime, "do5OnTime");
+RPCVariable<int> rpcdo5OffTime(&do5OffTime, "do5OffTime");
+RPCVariable<int> rpcdo6OnTime(&do6OnTime, "do6OnTime");
+RPCVariable<int> rpcdo6OffTime(&do6OffTime, "do6OffTime");
+RPCVariable<int> rpcdo7OnTime(&do7OnTime, "do7OnTime");
+RPCVariable<int> rpcdo7OffTime(&do7OffTime, "do7OffTime");
+
+// RPC function definitions
+// Create a function of the required format
+void set_current_time(Arguments* args, Reply* rep);
+void set_current_time(Arguments* args, Reply* rep){
+    time_t ct = (time_t)current_time; // convert
+    struct tm *st = localtime(&ct);
+    
+    set_time(ct); // set time
+    
+    DBG("Set current time to: %s", ctime(&ct));
+    DBG("Time only: %d:%d:%d", st->tm_hour, st->tm_min, st->tm_sec);
+}
+// Attach it to an RPC object
+RPCFunction rpcSetCurrentTime(&set_current_time, "SetTime");
+
 
 /*
  * Threads
@@ -168,6 +272,9 @@
     return srv;
 }
 
+// Prototypes
+void digital_outputs_timer_thread(void const* args);
+
 // Main code
 int main()
 {
@@ -196,6 +303,7 @@
     * UI threads
     */
     Thread t3(wdt_reset_thread);
+    Thread t4(digital_outputs_timer_thread);
     
     // rpc
     RPCType::instance().register_types();
@@ -270,3 +378,372 @@
     return 0;
 }
 
+// Timer thread to check on/off time of digital outputs
+void digital_outputs_timer_thread(void const* args)
+{
+    Thread::wait(700);
+    
+    while(true) {
+        // read current time
+        time_t seconds = time(NULL);
+        struct tm *st = localtime(&seconds);
+        int current_time_in_seconds = 3600*(st->tm_hour) + 60*(st->tm_min) + st->tm_sec;
+        DBG("Current time: %d:%d:%d", st->tm_hour, st->tm_min, st->tm_sec);
+        
+        // check do0
+        if ((enable_onoff_dout && 0x01) == 0x01) {
+            if (do0OnTime < do0OffTime) {
+                if ((current_time_in_seconds >= do0OnTime) && (current_time_in_seconds < do0OffTime)){
+                    if (dout0 == 0) {
+                        dout0 = 1;
+                        DBG("do0 ON");
+                    }
+                    else {
+                        DBG("do0 ON'ed");
+                    }
+                }
+                else {
+                    if (dout0 == 1) {
+                        dout0 = 0;
+                        DBG("do0 OFF'ed");
+                    }
+                    else {
+                        DBG("do0 OFF");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do0OffTime) && ((current_time_in_seconds < do0OnTime))) {
+                    if (dout0 == 1) {
+                        dout0 = 0;
+                        DBG("do0 OFF");
+                    }
+                    else {
+                        DBG("do0 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout0 == 0) {
+                        dout0 = 1;
+                        DBG("do0 ON");
+                    }
+                    else {
+                        DBG("do0 ON'ed");
+                    }
+                }
+            }
+        } // end check do0
+        
+        // check do1
+        if ((enable_onoff_dout && 0x02) == 0x02) {
+            if (do1OnTime < do1OffTime) {
+                if ((current_time_in_seconds >= do1OnTime) && (current_time_in_seconds < do1OffTime)){
+                    if (dout1 == 0) {
+                        dout1 = 1;
+                        DBG("do1 ON");
+                    }
+                    else {
+                        DBG("do1 ON'ed");
+                    }
+                }
+                else {
+                    if (dout1 == 1) {
+                        dout1 = 0;
+                        DBG("do1 OFF");
+                    }
+                    else {
+                        DBG("do1 OFF'ed");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do1OffTime) && ((current_time_in_seconds < do1OnTime))) {
+                    if (dout1 == 1) {
+                        dout1 = 0;
+                        DBG("do1 OFF");
+                    }
+                    else {
+                        DBG("do1 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout1 == 0) {
+                        dout1 = 1;
+                        DBG("do1 ON");
+                    }
+                    else {
+                        DBG("do1 ON'ed");
+                    }
+                }
+            }
+        } // end check do1
+        
+        // check do2
+        if ((enable_onoff_dout && 0x04) == 0x04) {
+            if (do2OnTime < do2OffTime) {
+                if ((current_time_in_seconds >= do2OnTime) && (current_time_in_seconds < do2OffTime)){
+                    if (dout2 == 0) {
+                        dout2 = 1;
+                        DBG("do2 ON");
+                    }
+                    else {
+                        DBG("do2 ON'ed");
+                    }
+                }
+                else {
+                    if (dout2 == 1) {
+                        dout2 = 0;
+                        DBG("do2 OFF");
+                    }
+                    else {
+                        DBG("do2 OFF'ed");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do2OffTime) && ((current_time_in_seconds < do2OnTime))) {
+                    if (dout2 == 1) {
+                        dout2 = 0;
+                        DBG("do2 OFF");
+                    }
+                    else {
+                        DBG("do2 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout2 == 0) {
+                        dout2 = 1;
+                        DBG("do2 ON");
+                    }
+                    else {
+                        DBG("do2 ON'ed");
+                    }
+                }
+            }
+        } // end check do2
+        
+        // check do3
+        if ((enable_onoff_dout && 0x08) == 0x08) {
+            if (do3OnTime < do3OffTime) {
+                if ((current_time_in_seconds >= do3OnTime) && (current_time_in_seconds < do3OffTime)){
+                    if (dout3 == 0) {
+                        dout3 = 1;
+                        DBG("do3 ON");
+                    }
+                    else {
+                        DBG("do3 ON'ed");
+                    }
+                }
+                else {
+                    if (dout3 == 1) {
+                        dout3 = 0;
+                        DBG("do3 OFF");
+                    }
+                    else {
+                        DBG("do3 OFF'ed");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do3OffTime) && ((current_time_in_seconds < do3OnTime))) {
+                    if (dout3 == 1) {
+                        dout3 = 0;
+                        DBG("do3 OFF");
+                    }
+                    else {
+                        DBG("do3 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout3 == 0) {
+                        dout3 = 1;
+                        DBG("do3 ON");
+                    }
+                    else {
+                        DBG("do3 ON'ed");
+                    }
+                }
+            }
+        } // end check do3
+        
+        // check do4
+        if ((enable_onoff_dout && 0x10) == 0x10) {
+            if (do4OnTime < do4OffTime) {
+                if ((current_time_in_seconds >= do4OnTime) && (current_time_in_seconds < do4OffTime)){
+                    if (dout4 == 0) {
+                        dout4 = 1;
+                        DBG("do4 ON");
+                    }
+                    else {
+                        DBG("do4 ON'ed");
+                    }
+                }
+                else {
+                    if (dout4 == 1) {
+                        dout4 = 0;
+                        DBG("do4 OFF");
+                    }
+                    else {
+                        DBG("do4 OFF'ed");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do4OffTime) && ((current_time_in_seconds < do4OnTime))) {
+                    if (dout4 == 1) {
+                        dout4 = 0;
+                        DBG("do4 OFF");
+                    }
+                    else {
+                        DBG("do4 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout4 == 0) {
+                        dout4 = 1;
+                        DBG("do4 ON");
+                    }
+                    else {
+                        DBG("do4 ON'ed");
+                    }
+                }
+            }
+        } // end check do4
+        
+        // check do5
+        if ((enable_onoff_dout && 0x20) == 0x20) {
+            if (do5OnTime < do5OffTime) {
+                if ((current_time_in_seconds >= do5OnTime) && (current_time_in_seconds < do5OffTime)){
+                    if (dout5 == 0) {
+                        dout5 = 1;
+                        DBG("do5 ON");
+                    }
+                    else {
+                        DBG("do5 ON'ed");
+                    }
+                }
+                else {
+                    if (dout5 == 1) {
+                        dout5 = 0;
+                        DBG("do5 OFF");
+                    }
+                    else {
+                        DBG("do5 OFF'ed");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do5OffTime) && ((current_time_in_seconds < do5OnTime))) {
+                    if (dout5 == 1) {
+                        dout5 = 0;
+                        DBG("do5 OFF");
+                    }
+                    else {
+                        DBG("do5 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout5 == 0) {
+                        dout5 = 1;
+                        DBG("do5 ON");
+                    }
+                    else {
+                        DBG("do5 ON'ed");
+                    }
+                }
+            }
+        } // end check do5
+        
+        // check do6
+        if ((enable_onoff_dout && 0x40) == 0x40) {
+            if (do6OnTime < do6OffTime) {
+                if ((current_time_in_seconds >= do6OnTime) && (current_time_in_seconds < do6OffTime)){
+                    if (dout6 == 0) {
+                        dout6 = 1;
+                        DBG("do6 ON");
+                    }
+                    else {
+                        DBG("do6 ON'ed");
+                    }
+                }
+                else {
+                    if (dout6 == 1) {
+                        dout6 = 0;
+                        DBG("do6 OFF");
+                    }
+                    else {
+                        DBG("do6 OFF'ed");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do6OffTime) && ((current_time_in_seconds < do6OnTime))) {
+                    if (dout6 == 1) {
+                        dout6 = 0;
+                        DBG("do6 OFF");
+                    }
+                    else {
+                        DBG("do6 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout6 == 0) {
+                        dout6 = 1;
+                        DBG("do6 ON");
+                    }
+                    else {
+                        DBG("do6 ON'ed");
+                    }
+                }
+            }
+        } // end check do6
+        
+        // check do7
+        if ((enable_onoff_dout && 0x80) == 0x80) {
+            if (do7OnTime < do7OffTime) {
+                if ((current_time_in_seconds >= do7OnTime) && (current_time_in_seconds < do7OffTime)){
+                    if (dout7 == 0) {
+                        dout7 = 1;
+                        DBG("do7 ON");
+                    }
+                    else {
+                        DBG("do7 ON'ed");
+                    }
+                }
+                else {
+                    if (dout7 == 1) {
+                        dout7 = 0;
+                        DBG("do7 OFF");
+                    }
+                    else {
+                        DBG("do7 OFF'ed");
+                    }
+                }
+            }
+            else {
+                if ((current_time_in_seconds >= do7OffTime) && ((current_time_in_seconds < do7OnTime))) {
+                    if (dout7 == 1) {
+                        dout7 = 0;
+                        DBG("do7 OFF");
+                    }
+                    else {
+                        DBG("do7 OFF'ed");
+                    }
+                }
+                else {
+                    if (dout7 == 0) {
+                        dout7 = 1;
+                        DBG("do7 ON");
+                    }
+                    else {
+                        DBG("do7 ON'ed");
+                    }
+                }
+            }
+        } // end check do7
+        
+        
+        // wait 1s
+        Thread::wait(10000); // Thread::wait() in ms
+    }
+}
\ No newline at end of file