What I did Friday night (or: I might be a geek)

I’ve recently picked up an Arduino with an ethernet shield. I didn’t have good reason to, and I probably shouldn’t have paid as much as I did, but it sure is a fun toy. I say that as someone who’s played around a little with AVRs too. I bought my kit on Friday night. I sat down, followed the install guide, and before I knew it the sun was rising and I had written an IRC bot that connects via ethernet and doesn’t need a computer at all.

I learned about AVRs in my Computer Organization course, CSC 258. It’s one of my favourites because we had a great instructor, Corey Manders. I won’t be able to forget the first day of class. He admitted that he already set the course grading scheme and couldn’t change the weighting of labs, but he still wanted us to do nine labs instead of the three or four our course usually contains. I’m glad we voted yes. He also pulled some strings to get us, the lowly computer science students, access to an engineering lab with FPGA development boards and awesome oscilloscopes. We wound up doing three labs in TTL gates, three labs in FPGAs, and three labs in AVRs. We also had an assignment in gate logic and another AVR coding.

Atmel AVR ATmega8 PDIP
Image via Wikipedia

I wound up coding a simple game, a security system, sophisticated blinkie and interrupt triggered serial communication; all in assembler on AVRs. It was good prep for working in C on my own later. I only dabbled in it. The summer after CSC 258 I decided that I wanted to get my AVR on the internet. There were plans out there that required you to build your own board using an ethernet controller with an SPI interface, but you had to load in your own TCP stack which took up most of your RAM. Maybe I could have a second AVR just for ethernet? There was another expensive box that I handle sockets for me, and maybe I could use wireless over SDIO, or any number of ideas that required circuit building skills that I didn’t have. Eventually I twisted my programming cable in the wrong way, the solder broke, and I forgot all about it.

Nuit Blanche Toronto, in front of the Royal On...
Image via Wikipedia

Fast forward to last Friday. I had volunteered to staff the desk at Hacklab.to to keep it open until 4am for Nuit Blanche. I wanted something to do so I hit Creatron to buy some LEDs, capacitors and transistors to make blinkies. Right below the glass on the checkout counter was an array of gadgetry from Arduino and Sparkfun. Temptation was too much this time. I broke down and bought the Arduino kit with an ethernet shield.

The Arduino itself was $31.75. It hurt to pay that much for what I knew contained a microcontroller that was, at most, worth two dollars. The premium I paid was for the board which contained a USB to serial adapter, software to program using it, several LEDs and a button. Pretty paltry for a development board, but it’s there. Okay, there’s one more thing that they add that makes the premium worth it: The headers for the shields. These shields mean I can skip all the work of building in extensions like ethernet support, or bluetooth, or any number of complicated addons. The ethernet shield cost $67, which stung a bit, but I knew that the ethernet controller on the board alone was probably worth $50. Plus, I wouldn’t be capable of building the thing myself.

On the same Friday night I got I’ve managed to write a very basic IRC bot that can maintain a connection and listen to commands. It differs from the other IRC bots out there because it reads line by line, not character by character, then tokenizes the string. Right now I have a very simple branching table which is good enough.

My plans are to first merge it with the hacklab.to toilet code so that we can revive the IRC bot. Previously it would connect, spit a message, and then disconnect. It got a little spammy. My version will maintain the connection and spit out a message and include rate limiting.

For the curious, here’s the blocking readclrf() function that I wrote, as well as the code that keeps the simple bot going. In its present form I think it’ll eventually crash, I need to properly allocate and free the memory when tokenizing. Readclrf() should be fine though.

[cc lang="cpp"]void loop()
{
if (client.available()) {
char c[256];
readcrlf(c, 256);
//Serial.println(c); // debug

// tokenize the string, enter FSM
// maybe generate an interrupt on PING?
int i = 0;
char *msg_tok = strtok(c, ” “);
char *msg_toks[6]; // TODO: allocate this properly later
while (msg_tok != NULL) {
strcpy(msg_toks[i], msg_tok);
if (++i >= 6) {
break; // :nick!user@host #channel :command arg1 arg2
}
msg_tok = strtok(NULL, ” “);
}

if (!strcmp(msg_toks[0],”PING”)) {
// it’s a ping, PONG IT BACK
client.print(“PONG “);
client.println(msg_toks[1]);
Serial.print(“Ping? Pong! “);
Serial.println(msg_toks[1]);
}

// Command loop checks all tokens
for (int j; j < 6; j++) {
if (!strcmp(msg_toks[j], “:quit”)) {
client.println(“QUIT”); // add verification
}
// add port reading and setting commands here
}
}

if (!client.connected()) {
Serial.println();
Serial.println(“disconnecting.”);

client.stop();
for(;;)
;
}
}

int readcrlf(char *buf, int max)
{
memset(buf, 0, max);
int b;
int i = 0;

while (client.connected()) {
b = client.read();

if (b == -1)
continue;

if (i >= max) {
break;
}

if (b == ‘\n’)
continue;

if ((b == ‘\r’) || (b == 0)) {
break;
}

buf[i] = b;

i++;
}

return i;
}[/cc]

Reblog this post [with Zemanta]

2 Comments to “What I did Friday night (or: I might be a geek)”

  1. Simon 14 October 2009 at 11:36 pm #

    This is the coolest! I love AVRs… Also, with this you can kinda have a more or less independent AI bot just hanging around that’s the size of your palm.

  2. Ivy 12 November 2009 at 6:37 am #

    wow, you’re not a geek, but a genius.

    If you’re a geek, I’m a geek too.


Leave a Reply