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 10:55:50 2014 +0000
Revision:
7:951c113bba49
Parent:
6:df775c94a9c8
Child:
8:17b925cab77c
Added scroll functionality to class methods.

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 6:df775c94a9c8 60 bob_display.printf("% 6d\n", value);
PrzemekWirkus 5:5c0288a4e2c7 61 }
PrzemekWirkus 5:5c0288a4e2c7 62
PrzemekWirkus 7:951c113bba49 63 /** Scrolls string on LCD
PrzemekWirkus 7:951c113bba49 64 *
PrzemekWirkus 7:951c113bba49 65 * @param str Text to be displayed on 'bob' display
PrzemekWirkus 7:951c113bba49 66 */
PrzemekWirkus 7:951c113bba49 67 void lcd_print_scroll(const char *str, float speed) {
PrzemekWirkus 7:951c113bba49 68 bob_display.cls();
PrzemekWirkus 7:951c113bba49 69 bob_display.scroll(str, speed);
PrzemekWirkus 7:951c113bba49 70 }
PrzemekWirkus 7:951c113bba49 71
PrzemekWirkus 5:5c0288a4e2c7 72 /** Connect to DHCP
PrzemekWirkus 5:5c0288a4e2c7 73 */
PrzemekWirkus 3:56c6df84e619 74 void dhcp_connection() {
PrzemekWirkus 3:56c6df84e619 75 printf("DHCP: Connecting ... ");
PrzemekWirkus 3:56c6df84e619 76 eth.init(); //Use DHCP
PrzemekWirkus 3:56c6df84e619 77 eth.connect();
PrzemekWirkus 3:56c6df84e619 78 printf("%s\r\n", eth.getIPAddress());
PrzemekWirkus 3:56c6df84e619 79 }
PrzemekWirkus 3:56c6df84e619 80
PrzemekWirkus 5:5c0288a4e2c7 81 /** Create a dispBoB object defined on the I2C master bus
PrzemekWirkus 5:5c0288a4e2c7 82 *
PrzemekWirkus 5:5c0288a4e2c7 83 * @param server Munin server IP / name
PrzemekWirkus 5:5c0288a4e2c7 84 * @param port Munin server port
PrzemekWirkus 5:5c0288a4e2c7 85 */
PrzemekWirkus 5:5c0288a4e2c7 86 int socket_connection(const char *server, const int port) {
PrzemekWirkus 3:56c6df84e619 87 printf("TCP: Connecting ... ");
PrzemekWirkus 5:5c0288a4e2c7 88 int ret = socket.connect(server, port) < 0;
PrzemekWirkus 3:56c6df84e619 89 printf("[OK]\r\n");
PrzemekWirkus 3:56c6df84e619 90 return ret;
PrzemekWirkus 3:56c6df84e619 91 }
PrzemekWirkus 3:56c6df84e619 92
PrzemekWirkus 5:5c0288a4e2c7 93 /** Closes socket conenction to Munin server
PrzemekWirkus 5:5c0288a4e2c7 94 */
PrzemekWirkus 4:186148592f35 95 void socket_close() {
PrzemekWirkus 3:56c6df84e619 96 socket.close();
PrzemekWirkus 3:56c6df84e619 97 }
stevep 0:98c94cf86eb8 98
PrzemekWirkus 5:5c0288a4e2c7 99 /** Recv data from Munin to buffer 'buf'
PrzemekWirkus 5:5c0288a4e2c7 100 */
PrzemekWirkus 3:56c6df84e619 101 int socket_recv() {
PrzemekWirkus 3:56c6df84e619 102 const int n = socket.receive(buf, sizeof(buf) - 1);
PrzemekWirkus 3:56c6df84e619 103 if (n > 0) {
PrzemekWirkus 3:56c6df84e619 104 buf[n] = '\0';
PrzemekWirkus 3:56c6df84e619 105 printf("RECV: %s\r\n", buf);
PrzemekWirkus 3:56c6df84e619 106 }
PrzemekWirkus 3:56c6df84e619 107 return n;
PrzemekWirkus 3:56c6df84e619 108 }
PrzemekWirkus 3:56c6df84e619 109
PrzemekWirkus 5:5c0288a4e2c7 110 /** Recv data from Munin to buffer 'buf'. Used to fetch reply for Munin command (given counter name)
PrzemekWirkus 5:5c0288a4e2c7 111 */
PrzemekWirkus 3:56c6df84e619 112 int socket_recv_all() {
PrzemekWirkus 3:56c6df84e619 113 const int n = socket.receive_all(buf, sizeof(buf) - 1);
PrzemekWirkus 3:56c6df84e619 114 if (n > 0) {
PrzemekWirkus 3:56c6df84e619 115 buf[n] = '\0';
PrzemekWirkus 3:56c6df84e619 116 printf("RECV: %s\r\n", buf);
PrzemekWirkus 3:56c6df84e619 117 }
PrzemekWirkus 3:56c6df84e619 118 return n;
PrzemekWirkus 3:56c6df84e619 119 }
PrzemekWirkus 3:56c6df84e619 120
PrzemekWirkus 5:5c0288a4e2c7 121 /** Send data using socket to Munin server. Used to send command to Munin server.
PrzemekWirkus 5:5c0288a4e2c7 122 * @param cmd Munin command string, must end with \n
PrzemekWirkus 5:5c0288a4e2c7 123 * @param cmd_size Munin command buffer size
PrzemekWirkus 5:5c0288a4e2c7 124 */
PrzemekWirkus 3:56c6df84e619 125 int socket_send(char *cmd, const int cmd_size) {
PrzemekWirkus 3:56c6df84e619 126 const int n = socket.send(cmd, cmd_size - 1);
PrzemekWirkus 3:56c6df84e619 127 return n;
PrzemekWirkus 3:56c6df84e619 128 }
stevep 0:98c94cf86eb8 129
PrzemekWirkus 5:5c0288a4e2c7 130 /** Explodes Munin command reply into individual counters divided by '\n'.
PrzemekWirkus 5:5c0288a4e2c7 131 * Function extract counter value from conunter wirh name param_name.
PrzemekWirkus 5:5c0288a4e2c7 132 * @param param_name counter name
PrzemekWirkus 5:5c0288a4e2c7 133 */
PrzemekWirkus 3:56c6df84e619 134 int get_param_value(std::string param_name) {
PrzemekWirkus 5:5c0288a4e2c7 135 // Explode Munin command and creaste separate strings with counters
PrzemekWirkus 3:56c6df84e619 136 std::vector<std::string> s = explode(std::string(buf), '\n');
PrzemekWirkus 3:56c6df84e619 137
PrzemekWirkus 5:5c0288a4e2c7 138 // For each counter name get its name and if name matches param_name extract and return counter value
PrzemekWirkus 3:56c6df84e619 139 for (std::vector<std::string>::iterator it = s.begin(); it != s.end(); ++it) {
PrzemekWirkus 3:56c6df84e619 140 std::string &param = *it;
PrzemekWirkus 3:56c6df84e619 141 printf("PARAM_RECV: %s\r\n", param.c_str());
PrzemekWirkus 3:56c6df84e619 142 if (!param.compare(0, param_name.size(), param_name)) {
PrzemekWirkus 3:56c6df84e619 143 printf("PARAM_FOUND: %s is '%s' \r\n", param.c_str(), param_name.c_str());
PrzemekWirkus 3:56c6df84e619 144 std::vector<std::string> name_value = explode(param, ' ');
PrzemekWirkus 3:56c6df84e619 145 if (name_value.size() == 2) {
PrzemekWirkus 3:56c6df84e619 146 const int val = atoi(name_value[1].c_str());
PrzemekWirkus 3:56c6df84e619 147 printf("DISPLAYING: %s\r\n", name_value[1].c_str());
PrzemekWirkus 3:56c6df84e619 148 return val;
PrzemekWirkus 3:56c6df84e619 149 }
PrzemekWirkus 3:56c6df84e619 150 }
PrzemekWirkus 3:56c6df84e619 151 }
PrzemekWirkus 3:56c6df84e619 152 return 0;
PrzemekWirkus 3:56c6df84e619 153 }
PrzemekWirkus 3:56c6df84e619 154
PrzemekWirkus 3:56c6df84e619 155 protected:
stevep 0:98c94cf86eb8 156 EthernetInterface eth;
stevep 0:98c94cf86eb8 157 TCPSocketConnection socket;
PrzemekWirkus 4:186148592f35 158 dispBoB bob_display;
stevep 0:98c94cf86eb8 159 char buf[256];
stevep 0:98c94cf86eb8 160
PrzemekWirkus 5:5c0288a4e2c7 161 // String explode function
PrzemekWirkus 3:56c6df84e619 162 std::vector<std::string> explode(std::string const &s, char delim)
PrzemekWirkus 3:56c6df84e619 163 {
PrzemekWirkus 3:56c6df84e619 164 std::vector<std::string> result;
PrzemekWirkus 3:56c6df84e619 165 std::istringstream iss(s);
PrzemekWirkus 3:56c6df84e619 166 for (std::string token; std::getline(iss, token, delim); ) {
PrzemekWirkus 3:56c6df84e619 167 result.push_back(token);
PrzemekWirkus 3:56c6df84e619 168 }
PrzemekWirkus 3:56c6df84e619 169 return result;
PrzemekWirkus 3:56c6df84e619 170 }
PrzemekWirkus 3:56c6df84e619 171 };
stevep 0:98c94cf86eb8 172
PrzemekWirkus 3:56c6df84e619 173 int main() {
PrzemekWirkus 3:56c6df84e619 174 MuninDisplay munin_lcd;
PrzemekWirkus 3:56c6df84e619 175 munin_lcd.dhcp_connection(); // DHCP connection
PrzemekWirkus 3:56c6df84e619 176
PrzemekWirkus 3:56c6df84e619 177 while(true) {
PrzemekWirkus 5:5c0288a4e2c7 178 while (munin_lcd.socket_connection(MUNIN_SERVER_ADDRESS, MUNIN_SERVER_PORT) < 0) {
stevep 0:98c94cf86eb8 179 wait(1);
stevep 0:98c94cf86eb8 180 }
stevep 0:98c94cf86eb8 181
PrzemekWirkus 3:56c6df84e619 182 munin_lcd.socket_recv();
PrzemekWirkus 3:56c6df84e619 183 munin_lcd.socket_send(CMD_FETCH_USERS, sizeof(CMD_FETCH_USERS));
PrzemekWirkus 3:56c6df84e619 184 munin_lcd.socket_recv_all();
PrzemekWirkus 7:951c113bba49 185 {
PrzemekWirkus 7:951c113bba49 186 const char *param = "usercount.value";
PrzemekWirkus 7:951c113bba49 187 int counter_value = munin_lcd.get_param_value(param);
PrzemekWirkus 7:951c113bba49 188 munin_lcd.lcd_print_int(counter_value);
PrzemekWirkus 7:951c113bba49 189 }
stevep 0:98c94cf86eb8 190
PrzemekWirkus 3:56c6df84e619 191 munin_lcd.socket_close();
PrzemekWirkus 3:56c6df84e619 192 wait(3);
stevep 0:98c94cf86eb8 193 }
PrzemekWirkus 3:56c6df84e619 194 }