Robot is Happy creating our robot overlords one day at a time

There are two forms of this advance Payday Loans UK But now, you have an extra
9Dec/090

Monitoring message queues with Arduino by Alex Kane

Finished product
This is a gadget I made to tell me at a glance the size of the various message queues that I manage at TuneCore.  It sits on my desk next to my monitor and tells me right away what's going on with our delivery system.  A steady light means the queue is not very long; a rapidly blinking light means that the number of items in the queue is very large and it needs attention.

I built it over a weekend using an Arduino microcontroller with an Ethernet shield. It requests the queue sizes from a web server once a minute.

Parsing an HTTP Response

Here's an example of an HTTP response that I have to parse in order to get the values I'm looking for:

Buffer: HTTP/1.1 200 OK
Buffer: Date: Tue, 08 Dec 2009 14:15:34 GMT
Buffer: Server: Apache/2.2.3 (CentOS)
Buffer: Last-Modified: Tue, 08 Dec 2009 14:15:02 GMT
Buffer: ETag: "fc117-28-332a2580"
Buffer: Accept-Ranges: bytes
Buffer: Content-Length: 40
Buffer: Connection: close
Buffer: Content-Type: text/plain; charset=UTF-8
Buffer:
Buffer: queue_sizes
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 1
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 0
Buffer: 0

It turns out that there's a lot of libraries for setting the Arduino Ethernet shield up as a server but I couldn't find any that make it easy to parse a response.

There were two major hurdles in the design of the program. One was how to parse the HTTP response. It took some thought (and Googling) but what you have to do is build string buffers as you read the the response one character at a time. Then process the buffer to determine if your looking at the HTTP header or the actual data that you've served.

The other programming problem was getting the lights to blink independently of one another. It was a difficult because the Arduino only does one thing at a time. I was able to accomplish this using the Metronome library, although there is still some blocking going on when the lights blink. I believe the solution will be to remove the delay() statements in the blink code.

This is the first time I've felt that a project is worthy of mounting in a project box. I got all the LEDs, mounts and box from Radio Shack, and bought a Dremel and label maker at Target. The next few hours were spent cursing and carving the plastic and soldering everything together.

More pictures

Internet-enabled blinkenlights

Internet-enabled blinkenlights

Installed

The code

Here's the code that make this thing tick:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#include <Metro.h>
#include <WString.h>
#include <Ethernet.h>
 
#define MAX_STRING_LEN  20
#define BLINK_DELAY 100
#define LED_INTERVAL 60000
 
#define AMAZON_LED 2 // Define the led's pin
#define AMAZONOD_LED 3
#define NOKIA_LED 4
#define ITUNES_LED 5
#define LIMEWIRE_LED 6
#define RHAPSODY_LED 7
#define NAPSTER_LED 8
#define LALA_LED 9
 
int amazon_q;
int amazonod_q;
int amiestreet_q;
int emusic_q;
int groupietunes_q;
int itunes_q;
int lala_q;
int limewire_q;
int napster_q;
int nokia_q;
int rhapsody_q;
int shockhound_q;
int streaming_q;
 
Metro queueCheckMetro = Metro(10000);
 
Metro amazonMetro = Metro(1000);
Metro amazonodMetro = Metro(1000);
Metro nokiaMetro = Metro(1000);
Metro itunesMetro = Metro(1000);
Metro limewireMetro = Metro(1000);
Metro rhapsodyMetro = Metro(1000);
Metro napsterMetro = Metro(1000);
Metro lalaMetro = Metro(1000);
 
int state = HIGH;
 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 2, 2 };
byte gateway[] = { 192, 168, 2, 1 };
byte subnet[] = { 255, 255, 255, 0 };
byte server[] = { 0,0,0,0 }; // Put the server's IP address here
Client client(server, 80);
int data_index = 0;
boolean header = true;
String buffer = String(100);
int response_writeindex = 0;
 
void setup()
{
 
  pinMode(AMAZON_LED,OUTPUT);
  digitalWrite(AMAZON_LED,state);
  pinMode(AMAZONOD_LED,OUTPUT);
  digitalWrite(AMAZONOD_LED,state);
  pinMode(NOKIA_LED,OUTPUT);
  digitalWrite(NOKIA_LED,state);
  pinMode(ITUNES_LED,OUTPUT);
  digitalWrite(ITUNES_LED,state);
  pinMode(LIMEWIRE_LED,OUTPUT);
  digitalWrite(LIMEWIRE_LED,state);
  pinMode(RHAPSODY_LED,OUTPUT);
  digitalWrite(RHAPSODY_LED,state);
  pinMode(NAPSTER_LED,OUTPUT);
  digitalWrite(NAPSTER_LED,state);
  pinMode(LALA_LED,OUTPUT);
  digitalWrite(LALA_LED,state);
 
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
 
  delay(1000);
 
  Serial.println("connecting...");
 
  if (client.connect()) {
    Serial.println("connected");
    client.println("GET /queue_size.txt HTTP/1.0");
    client.println();
  } else {
    Serial.println("connection failed");
  }
}
 
void loop()
{ 
 
  if(queueCheckMetro.check() == 1){
   checkQueues();
 }
 
  blinkLEDS();
}
 
void checkQueues(){
  queueCheckMetro.interval(60000); // check the queues once a minute
 while (client.available()) {
    serialEvent();
  }
 
  calculateBlinkRates();
 
  if (!client.connected()) {
    Serial.println();
    Serial.println("Disconnected");
    client.stop();
 
     if (client.connect()) {
      client.println("GET /queue_size.txt HTTP/1.0");
      client.println();
      delay(2000);
    } else {
      Serial.println("Reconnect failed");
    }
  }
}
 
void serialEvent(){
  char inChar = client.read();
 
  if(inChar != '\n'){
   buffer.append(inChar);
  } else {
    Serial.print("Buffer: ");
    Serial.println(buffer);
    if(buffer.contains("queue_sizes")){
      // Finished reading HTTP header
      header = false;
    }
 
    if(header == false){
      parse_data_buffer();
      data_index = data_index++;
    }
    buffer = "";
  }
 
}
 
void parse_data_buffer(){
  // Parse the line
  switch (data_index){
          case 3:
            amazon_q = atoi(buffer);
            break;
          case 4:
            amazonod_q = atoi(buffer);
            break;
          case 5:
            amiestreet_q = atoi(buffer);
            break;
          case 6:
            emusic_q = atoi(buffer);
            break;
          case 7:
            groupietunes_q = atoi(buffer);
            break;
          case 8:
            itunes_q = atoi(buffer);
            break;
          case 9:
            lala_q = atoi(buffer);
            break;
          case 10:
            limewire_q = atoi(buffer);
            break;
          case 11:
            napster_q = atoi(buffer);
            break;
          case 12:
            nokia_q = atoi(buffer);
            break;
          case 13:
            rhapsody_q = atoi(buffer);
            break;
          case 14:
            shockhound_q = atoi(buffer);
            break;
          case 15:
            streaming_q = atoi(buffer);
            break;
        }
        return;
  }
 
void calculateBlinkRates(){
  if(amazon_q == 0){
    amazon_q=1;
  }
  if(amazonod_q == 0){
    amazonod_q=1;
  }
  if(nokia_q == 0){
    nokia_q=1;
  }
  if(itunes_q == 0){
    itunes_q=1;
  }
  if(limewire_q == 0){
    limewire_q=1;
  }
  if(rhapsody_q == 0){
    rhapsody_q=1;
  }
  if(napster_q == 0){
    napster_q=1;
  }
  if(lala_q == 0){
    lala_q=1;
  }
  int amazon_on_for = LED_INTERVAL / amazon_q;
  int amazonod_on_for = LED_INTERVAL / amazon_q;
  int nokia_on_for = LED_INTERVAL / nokia_q;
  int itunes_on_for = LED_INTERVAL / itunes_q;
  int limewire_on_for = LED_INTERVAL / limewire_q;
  int rhapsody_on_for = LED_INTERVAL / rhapsody_q;
  int napster_on_for = LED_INTERVAL / napster_q;
  int lala_on_for = LED_INTERVAL / lala_q;
  amazonMetro.interval(amazon_on_for);
  amazonodMetro.interval(amazon_on_for);
  nokiaMetro.interval(nokia_on_for);
  itunesMetro.interval(itunes_on_for);
  limewireMetro.interval(limewire_on_for);
  rhapsodyMetro.interval(rhapsody_on_for);
  napsterMetro.interval(napster_on_for);
  lalaMetro.interval(lala_on_for);
}
 
void blinkLEDS(){
 if (amazonMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(AMAZON_LED);
  }
 if (amazonodMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(AMAZONOD_LED);
  }
 if (nokiaMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(NOKIA_LED);
  }
 if (itunesMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(ITUNES_LED);
  }
 if (limewireMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(LIMEWIRE_LED);
  }
 if (rhapsodyMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(RHAPSODY_LED);
 }
 if (napsterMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(NAPSTER_LED);
 }
 if (lalaMetro.check() == 1) { // check if the metro has passed it's interval .
    blinkLED(LALA_LED);
 }
}
 
void delayWithBlink(int delay){
 for(int i=0; i &lt;= delay; i++){
  blinkLEDS();
 }
}
 
void blinkLED(int pin){
  digitalWrite(pin, LOW);
  delay(BLINK_DELAY);
  digitalWrite(pin,HIGH);
}