Displays a value on an RS display board

Dependencies:   EthernetInterface PCA9635 dispBoB mbed-rtos mbed munin-client-lib

Displaying values retrieved from a munin node on an RS display board. Porting this code to work with an alternative display should be trivial, I have also used an mbed application board's LCD to display the values for example.

Hardware

Software

Most of the work is done by libraries that are freely available on mbed.org. The code uses the lwip based EthernetInterface library. The only code I had to write was submit a command to a munin node and parse it's response.

Testing

The software has currently been running for around 2 weeks without any problems. On a previous run it stopped updating after 4 days.

Revision:
3:56c6df84e619
Parent:
2:b4e81333dfef
Child:
4:186148592f35
--- a/main.cpp	Fri Apr 11 10:52:21 2014 +0000
+++ b/main.cpp	Fri Apr 11 18:05:00 2014 +0000
@@ -1,82 +1,123 @@
 #include "mbed.h"
 #include "EthernetInterface.h"
 #include "dispBoB.h"
+#include <string>
+#include <vector>
+#include <sstream>
+#include <utility>
+
+namespace {
+    const char* MUNIN_SERVER_ADDRESS = "172.28.22.45";
+    const int MUNIN_SERVER_PORT = 4949;
+    char CMD_FETCH_USERS[] = "fetch users\n";
+}
 
 
-const char* MUNIN_SERVER_ADDRESS = "172.28.22.45";
-const int MUNIN_SERVER_PORT = 4949;
-char cmd[] = "fetch users\n";
+class MuninDisplay {
+public:
+    MuninDisplay::MuninDisplay() : db(p28, p27, p26) {
+        db.cls();   
+    }
+
+    void lcd_print_str(const char *str) {
+        db.cls();
+        db.printf("%s\n", str);        
+    }
+
+    void dhcp_connection() {
+        printf("DHCP: Connecting ... ");
+        eth.init(); //Use DHCP
+        eth.connect();
+        printf("%s\r\n", eth.getIPAddress());
+    }
+    
+    int socket_connection() {
+        printf("TCP: Connecting ... ");
+        int ret = socket.connect(MUNIN_SERVER_ADDRESS, MUNIN_SERVER_PORT) < 0;
+        printf("[OK]\r\n");
+        return ret;
+    }
+
+    int socket_close() {
+        socket.close();
+    }
 
-dispBoB db(p28, p27, p26);
+    int socket_recv() {
+        const int n = socket.receive(buf, sizeof(buf) - 1);
+        if (n > 0) {
+            buf[n] = '\0';
+            printf("RECV: %s\r\n", buf);
+        }
+        return n;   
+    }
+
+    int socket_recv_all() {
+        const int n = socket.receive_all(buf, sizeof(buf) - 1);
+        if (n > 0) {
+            buf[n] = '\0';
+            printf("RECV: %s\r\n", buf);
+        }
+        return n;   
+    }
+
+    int socket_send(char *cmd, const int cmd_size) {
+        const int n = socket.send(cmd, cmd_size - 1);
+        return n;
+    }
 
-int main() {
+    int get_param_value(std::string param_name) {
+        std::vector<std::string> s = explode(std::string(buf), '\n');
+        
+        for (std::vector<std::string>::iterator it = s.begin(); it != s.end(); ++it) {
+            std::string &param = *it;
+            printf("PARAM_RECV: %s\r\n", param.c_str());
+            if (!param.compare(0, param_name.size(), param_name)) {
+                printf("PARAM_FOUND: %s is '%s' \r\n", param.c_str(), param_name.c_str());
+                std::vector<std::string> name_value = explode(param, ' ');
+                if (name_value.size() == 2) {
+                    const int val = atoi(name_value[1].c_str());
+                    db.cls();
+                    db.printf(" %s\n", name_value[1].c_str());
+                    printf("DISPLAYING: %s\r\n", name_value[1].c_str());                    
+                    return val;
+                }
+            }
+        }
+        return 0;
+    }
+
+protected:
     EthernetInterface eth;
     TCPSocketConnection socket;
-    
+    dispBoB db;
     char buf[256];
-    char *value;
-    int n, count, wd=0, curval=0;
-    
-    printf("DHCPing\n");
 
-    eth.init(); //Use DHCP
-    eth.connect();
+    std::vector<std::string> explode(std::string const &s, char delim)
+    {
+        std::vector<std::string> result;
+        std::istringstream iss(s);
+        for (std::string token; std::getline(iss, token, delim); ) {
+            result.push_back(token);
+        }
+        return result;
+    }
+};
 
-    printf("IP: %s\n", eth.getIPAddress());
-    
-    while(1) {
-        wd++;
-        while (socket.connect(MUNIN_SERVER_ADDRESS, MUNIN_SERVER_PORT) < 0) {
-            printf("Cnct");
+int main() {
+    MuninDisplay munin_lcd;
+    munin_lcd.dhcp_connection();    // DHCP connection
+                
+    while(true) {
+        while (munin_lcd.socket_connection() < 0) {
             wait(1);
         }
-        
-        n = socket.receive(buf, 256);
-        buf[n] = '\0';
-        n = socket.send(cmd, sizeof(cmd) - 1);
-        
-        buf[0] = '\0';
-        n = socket.receive_all(buf, 256);
-        buf[n] = '\0';
 
-        count = 0;
-        
-        for (int i=0; i < sizeof(buf); i++) {
-            if (buf[i] == '\n' && (i == 0 || buf[i-1] != '.')) {
-                count++;
-            }
-        }
-    
-        char* ptr = buf;
-        
-        printf("%s\n", buf);
-    
-        for (int i=0; i < count; i++) {
-            char *space = strstr(ptr, " ");
-            value = space + 1;
-            char *name;
-    
-            *space = 0;
-            name = ptr;
-        
-            ptr = value;
-            ptr = strstr(ptr, "\n");
-            *ptr = 0;
-            
-            if (strncmp(name, "usercount.value", 15) == 0) {
-                printf("%s\n", value);
-                if (curval < atoi(value)) {
-                    curval = atoi(value);
-                    db.cls();
-                    db.printf(" %s\n", value);
-                }
-                break;
-            }
-    
-            ptr++;
-        }
+        munin_lcd.socket_recv();
+        munin_lcd.socket_send(CMD_FETCH_USERS, sizeof(CMD_FETCH_USERS));
+        munin_lcd.socket_recv_all();
+        munin_lcd.get_param_value("usercount.value");
           
-        socket.close();
-        wait(10);
+        munin_lcd.socket_close();
+        wait(3);
     }
-}
\ No newline at end of file
+}