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.

Committer:
PrzemekWirkus
Date:
Mon Apr 14 09:29:41 2014 +0000
Revision:
5:5c0288a4e2c7
Parent:
4:186148592f35
Child:
6:df775c94a9c8
1. Small fixes.; 2. Added separate function to dosplay integer on LCD.; 3. Added simple Doxygen documentation.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
PrzemekWirkus 4:186148592f35 1 #include <string>
PrzemekWirkus 4:186148592f35 2 #include <vector>
PrzemekWirkus 4:186148592f35 3 #include <sstream>
stevep 0:98c94cf86eb8 4 #include "mbed.h"
stevep 0:98c94cf86eb8 5 #include "EthernetInterface.h"
stevep 0:98c94cf86eb8 6 #include "dispBoB.h"
PrzemekWirkus 3:56c6df84e619 7
PrzemekWirkus 3:56c6df84e619 8 namespace {
PrzemekWirkus 3:56c6df84e619 9 const char* MUNIN_SERVER_ADDRESS = "172.28.22.45";
PrzemekWirkus 3:56c6df84e619 10 const int MUNIN_SERVER_PORT = 4949;
PrzemekWirkus 3:56c6df84e619 11 char CMD_FETCH_USERS[] = "fetch users\n";
PrzemekWirkus 3:56c6df84e619 12 }
stevep 0:98c94cf86eb8 13
stevep 0:98c94cf86eb8 14
PrzemekWirkus 5:5c0288a4e2c7 15 /** MuninDisplay class, used to fetch counters from Munin and display them on dispBoB.
PrzemekWirkus 5:5c0288a4e2c7 16 *
PrzemekWirkus 5:5c0288a4e2c7 17 * Example:
PrzemekWirkus 5:5c0288a4e2c7 18 * @code
PrzemekWirkus 5:5c0288a4e2c7 19 * MuninDisplay munin_lcd;
PrzemekWirkus 5:5c0288a4e2c7 20 * munin_lcd.dhcp_connection(); // DHCP connection
PrzemekWirkus 5:5c0288a4e2c7 21 *
PrzemekWirkus 5:5c0288a4e2c7 22 * while(true) {
PrzemekWirkus 5:5c0288a4e2c7 23 * while (munin_lcd.socket_connection(MUNIN_SERVER_ADDRESS, MUNIN_SERVER_PORT) < 0) {
PrzemekWirkus 5:5c0288a4e2c7 24 * wait(1);
PrzemekWirkus 5:5c0288a4e2c7 25 * }
PrzemekWirkus 5:5c0288a4e2c7 26 *
PrzemekWirkus 5:5c0288a4e2c7 27 * munin_lcd.socket_recv();
PrzemekWirkus 5:5c0288a4e2c7 28 * munin_lcd.socket_send(CMD_FETCH_USERS, sizeof(CMD_FETCH_USERS));
PrzemekWirkus 5:5c0288a4e2c7 29 * munin_lcd.socket_recv_all();
PrzemekWirkus 5:5c0288a4e2c7 30 * munin_lcd.get_param_value("usercount.value");
PrzemekWirkus 5:5c0288a4e2c7 31 *
PrzemekWirkus 5:5c0288a4e2c7 32 * munin_lcd.socket_close();
PrzemekWirkus 5:5c0288a4e2c7 33 * wait(3);
PrzemekWirkus 5:5c0288a4e2c7 34 * }
PrzemekWirkus 5:5c0288a4e2c7 35 * @endcode
PrzemekWirkus 5:5c0288a4e2c7 36 */
PrzemekWirkus 3:56c6df84e619 37 class MuninDisplay {
PrzemekWirkus 3:56c6df84e619 38 public:
PrzemekWirkus 5:5c0288a4e2c7 39 /** Initialize dispBoB object
PrzemekWirkus 5:5c0288a4e2c7 40 */
PrzemekWirkus 4:186148592f35 41 MuninDisplay() : bob_display(p28, p27, p26) {
PrzemekWirkus 4:186148592f35 42 bob_display.cls();
PrzemekWirkus 3:56c6df84e619 43 }
PrzemekWirkus 3:56c6df84e619 44
PrzemekWirkus 5:5c0288a4e2c7 45 /** Prints string on LCD
PrzemekWirkus 5:5c0288a4e2c7 46 *
PrzemekWirkus 5:5c0288a4e2c7 47 * @param str Text to be displayed on 'bob' display
PrzemekWirkus 5:5c0288a4e2c7 48 */
PrzemekWirkus 3:56c6df84e619 49 void lcd_print_str(const char *str) {
PrzemekWirkus 4:186148592f35 50 bob_display.cls();
PrzemekWirkus 4:186148592f35 51 bob_display.printf("%s\n", str);
PrzemekWirkus 3:56c6df84e619 52 }
PrzemekWirkus 3:56c6df84e619 53
PrzemekWirkus 5:5c0288a4e2c7 54 /** Prints integer on LCD
PrzemekWirkus 5:5c0288a4e2c7 55 *
PrzemekWirkus 5:5c0288a4e2c7 56 * @param value Integer to be displayed on 'bob' display
PrzemekWirkus 5:5c0288a4e2c7 57 */
PrzemekWirkus 5:5c0288a4e2c7 58 void lcd_print_int(const int value) {
PrzemekWirkus 5:5c0288a4e2c7 59 bob_display.cls();
PrzemekWirkus 5:5c0288a4e2c7 60 bob_display.printf("%d\n", value);
PrzemekWirkus 5:5c0288a4e2c7 61 }
PrzemekWirkus 5:5c0288a4e2c7 62
PrzemekWirkus 5:5c0288a4e2c7 63 /** Connect to DHCP
PrzemekWirkus 5:5c0288a4e2c7 64 */
PrzemekWirkus 3:56c6df84e619 65 void dhcp_connection() {
PrzemekWirkus 3:56c6df84e619 66 printf("DHCP: Connecting ... ");
PrzemekWirkus 3:56c6df84e619 67 eth.init(); //Use DHCP
PrzemekWirkus 3:56c6df84e619 68 eth.connect();
PrzemekWirkus 3:56c6df84e619 69 printf("%s\r\n", eth.getIPAddress());
PrzemekWirkus 3:56c6df84e619 70 }
PrzemekWirkus 3:56c6df84e619 71
PrzemekWirkus 5:5c0288a4e2c7 72 /** Create a dispBoB object defined on the I2C master bus
PrzemekWirkus 5:5c0288a4e2c7 73 *
PrzemekWirkus 5:5c0288a4e2c7 74 * @param server Munin server IP / name
PrzemekWirkus 5:5c0288a4e2c7 75 * @param port Munin server port
PrzemekWirkus 5:5c0288a4e2c7 76 */
PrzemekWirkus 5:5c0288a4e2c7 77 int socket_connection(const char *server, const int port) {
PrzemekWirkus 3:56c6df84e619 78 printf("TCP: Connecting ... ");
PrzemekWirkus 5:5c0288a4e2c7 79 int ret = socket.connect(server, port) < 0;
PrzemekWirkus 3:56c6df84e619 80 printf("[OK]\r\n");
PrzemekWirkus 3:56c6df84e619 81 return ret;
PrzemekWirkus 3:56c6df84e619 82 }
PrzemekWirkus 3:56c6df84e619 83
PrzemekWirkus 5:5c0288a4e2c7 84 /** Closes socket conenction to Munin server
PrzemekWirkus 5:5c0288a4e2c7 85 */
PrzemekWirkus 4:186148592f35 86 void socket_close() {
PrzemekWirkus 3:56c6df84e619 87 socket.close();
PrzemekWirkus 3:56c6df84e619 88 }
stevep 0:98c94cf86eb8 89
PrzemekWirkus 5:5c0288a4e2c7 90 /** Recv data from Munin to buffer 'buf'
PrzemekWirkus 5:5c0288a4e2c7 91 */
PrzemekWirkus 3:56c6df84e619 92 int socket_recv() {
PrzemekWirkus 3:56c6df84e619 93 const int n = socket.receive(buf, sizeof(buf) - 1);
PrzemekWirkus 3:56c6df84e619 94 if (n > 0) {
PrzemekWirkus 3:56c6df84e619 95 buf[n] = '\0';
PrzemekWirkus 3:56c6df84e619 96 printf("RECV: %s\r\n", buf);
PrzemekWirkus 3:56c6df84e619 97 }
PrzemekWirkus 3:56c6df84e619 98 return n;
PrzemekWirkus 3:56c6df84e619 99 }
PrzemekWirkus 3:56c6df84e619 100
PrzemekWirkus 5:5c0288a4e2c7 101 /** Recv data from Munin to buffer 'buf'. Used to fetch reply for Munin command (given counter name)
PrzemekWirkus 5:5c0288a4e2c7 102 */
PrzemekWirkus 3:56c6df84e619 103 int socket_recv_all() {
PrzemekWirkus 3:56c6df84e619 104 const int n = socket.receive_all(buf, sizeof(buf) - 1);
PrzemekWirkus 3:56c6df84e619 105 if (n > 0) {
PrzemekWirkus 3:56c6df84e619 106 buf[n] = '\0';
PrzemekWirkus 3:56c6df84e619 107 printf("RECV: %s\r\n", buf);
PrzemekWirkus 3:56c6df84e619 108 }
PrzemekWirkus 3:56c6df84e619 109 return n;
PrzemekWirkus 3:56c6df84e619 110 }
PrzemekWirkus 3:56c6df84e619 111
PrzemekWirkus 5:5c0288a4e2c7 112 /** Send data using socket to Munin server. Used to send command to Munin server.
PrzemekWirkus 5:5c0288a4e2c7 113 * @param cmd Munin command string, must end with \n
PrzemekWirkus 5:5c0288a4e2c7 114 * @param cmd_size Munin command buffer size
PrzemekWirkus 5:5c0288a4e2c7 115 */
PrzemekWirkus 3:56c6df84e619 116 int socket_send(char *cmd, const int cmd_size) {
PrzemekWirkus 3:56c6df84e619 117 const int n = socket.send(cmd, cmd_size - 1);
PrzemekWirkus 3:56c6df84e619 118 return n;
PrzemekWirkus 3:56c6df84e619 119 }
stevep 0:98c94cf86eb8 120
PrzemekWirkus 5:5c0288a4e2c7 121 /** Explodes Munin command reply into individual counters divided by '\n'.
PrzemekWirkus 5:5c0288a4e2c7 122 * Function extract counter value from conunter wirh name param_name.
PrzemekWirkus 5:5c0288a4e2c7 123 * @param param_name counter name
PrzemekWirkus 5:5c0288a4e2c7 124 */
PrzemekWirkus 3:56c6df84e619 125 int get_param_value(std::string param_name) {
PrzemekWirkus 5:5c0288a4e2c7 126 // Explode Munin command and creaste separate strings with counters
PrzemekWirkus 3:56c6df84e619 127 std::vector<std::string> s = explode(std::string(buf), '\n');
PrzemekWirkus 3:56c6df84e619 128
PrzemekWirkus 5:5c0288a4e2c7 129 // For each counter name get its name and if name matches param_name extract and return counter value
PrzemekWirkus 3:56c6df84e619 130 for (std::vector<std::string>::iterator it = s.begin(); it != s.end(); ++it) {
PrzemekWirkus 3:56c6df84e619 131 std::string &param = *it;
PrzemekWirkus 3:56c6df84e619 132 printf("PARAM_RECV: %s\r\n", param.c_str());
PrzemekWirkus 3:56c6df84e619 133 if (!param.compare(0, param_name.size(), param_name)) {
PrzemekWirkus 3:56c6df84e619 134 printf("PARAM_FOUND: %s is '%s' \r\n", param.c_str(), param_name.c_str());
PrzemekWirkus 3:56c6df84e619 135 std::vector<std::string> name_value = explode(param, ' ');
PrzemekWirkus 3:56c6df84e619 136 if (name_value.size() == 2) {
PrzemekWirkus 3:56c6df84e619 137 const int val = atoi(name_value[1].c_str());
PrzemekWirkus 3:56c6df84e619 138 printf("DISPLAYING: %s\r\n", name_value[1].c_str());
PrzemekWirkus 3:56c6df84e619 139 return val;
PrzemekWirkus 3:56c6df84e619 140 }
PrzemekWirkus 3:56c6df84e619 141 }
PrzemekWirkus 3:56c6df84e619 142 }
PrzemekWirkus 3:56c6df84e619 143 return 0;
PrzemekWirkus 3:56c6df84e619 144 }
PrzemekWirkus 3:56c6df84e619 145
PrzemekWirkus 3:56c6df84e619 146 protected:
stevep 0:98c94cf86eb8 147 EthernetInterface eth;
stevep 0:98c94cf86eb8 148 TCPSocketConnection socket;
PrzemekWirkus 4:186148592f35 149 dispBoB bob_display;
stevep 0:98c94cf86eb8 150 char buf[256];
stevep 0:98c94cf86eb8 151
PrzemekWirkus 5:5c0288a4e2c7 152 // String explode function
PrzemekWirkus 3:56c6df84e619 153 std::vector<std::string> explode(std::string const &s, char delim)
PrzemekWirkus 3:56c6df84e619 154 {
PrzemekWirkus 3:56c6df84e619 155 std::vector<std::string> result;
PrzemekWirkus 3:56c6df84e619 156 std::istringstream iss(s);
PrzemekWirkus 3:56c6df84e619 157 for (std::string token; std::getline(iss, token, delim); ) {
PrzemekWirkus 3:56c6df84e619 158 result.push_back(token);
PrzemekWirkus 3:56c6df84e619 159 }
PrzemekWirkus 3:56c6df84e619 160 return result;
PrzemekWirkus 3:56c6df84e619 161 }
PrzemekWirkus 3:56c6df84e619 162 };
stevep 0:98c94cf86eb8 163
PrzemekWirkus 3:56c6df84e619 164 int main() {
PrzemekWirkus 3:56c6df84e619 165 MuninDisplay munin_lcd;
PrzemekWirkus 3:56c6df84e619 166 munin_lcd.dhcp_connection(); // DHCP connection
PrzemekWirkus 3:56c6df84e619 167
PrzemekWirkus 3:56c6df84e619 168 while(true) {
PrzemekWirkus 5:5c0288a4e2c7 169 while (munin_lcd.socket_connection(MUNIN_SERVER_ADDRESS, MUNIN_SERVER_PORT) < 0) {
stevep 0:98c94cf86eb8 170 wait(1);
stevep 0:98c94cf86eb8 171 }
stevep 0:98c94cf86eb8 172
PrzemekWirkus 3:56c6df84e619 173 munin_lcd.socket_recv();
PrzemekWirkus 3:56c6df84e619 174 munin_lcd.socket_send(CMD_FETCH_USERS, sizeof(CMD_FETCH_USERS));
PrzemekWirkus 3:56c6df84e619 175 munin_lcd.socket_recv_all();
PrzemekWirkus 5:5c0288a4e2c7 176 int counter_value = munin_lcd.get_param_value("usercount.value");
PrzemekWirkus 5:5c0288a4e2c7 177 munin_lcd.lcd_print_int(counter_value);
stevep 0:98c94cf86eb8 178
PrzemekWirkus 3:56c6df84e619 179 munin_lcd.socket_close();
PrzemekWirkus 3:56c6df84e619 180 wait(3);
stevep 0:98c94cf86eb8 181 }
PrzemekWirkus 3:56c6df84e619 182 }