Here’s my IRC Arduino Bot. It uses a regular Arduino 328 and an Ethernet Shield both from sparkfun. As for software, I’m using the Ethernet2 library (see my previous post about this), the WString library and a homerolled IRC protocol parser. The breadboard’s power is connected to arbitrary pin 5 and some resistors to keep the LED from burning out.
Basically, my bot joins an IRC channel and then listens for PRIVMSG commands starting with a password. It takes those commands and controls an LED. For example, I’d send this privately to the Arduino:
command password LEDON
And then the red LED comes on. I tell it “LEDOFF” and it turns off. Ok, it’s not a new RFC spec worthy of IEEE recognition and international adoption. But it got the job done in a human-readable manner. Previously on my facebook status light project, I had done much of the processing on my laptop and only send hex codes to the Arduino to light up LEDs. The difference now is that the Arduino is doing the processing and no computer is needed.
While I was working on this little project, I had the bot join the channel and announce itself.
At one point, I was working on code and then my bot would disconnect. I checked the serial monitor and the server seemed to drop me after a few minutes. The channel would say that I timed out. I realized that I wasn’t responding to the PING from the server. So I threw in some code that checks for anything from the server that starts with “PING :”. I then respond with “PONG”. I remember seeing PING?/PONG! messages in mIRC back in the day. Now it makes sense why mIRC was doing that in the console window.
It works great and I was excited about how much this little board could do in 14KB. And then I kept testing it. After about 7 or 8 “turn on” and “turn off” commands, the Arduino wouldn’t do anything anymore. It’s like it just froze. If I typed 5 commands, it’d stay connected for a long time. But every time I’d send it 7 to 8 commands, it would lock up. And by lock up, I mean the commands wouldn’t work anymore and it would time out from the server. WTF. So close!
So I figure that it’s something to do with pointers and memory. I really don’t have a solid grasp on pointers and C. I got a lot of this working by iterative experimentation over many days. So I was looking for a better way to send human readable commands to my bot. By human readable I mean something that works like a unix command “command arg1 arg2”. Of course this human readable bit introduces strings which is tricky enough in C (for me) and even worse on the Arduino. I figured this was a problem that someone smarter than me had solved.
I found a library called Messenger. It’s pretty simple to install, just throw it in your ~/Documents/Arduino/libraries folder on Mac and um … the equivalent on Windows? There are examples in the Messenger folder that you can checkout. HOWEVER the whole point of me posting this big long thing is the following.
The example checkString really threw me for a loop. It did exactly what I need it do to in a much cleaner way. I uploaded to the Arduino and then broke out to a shell.
$ screen /dev/tty.usbserial-A9005bCr 115200
Substitute your virtual usb device for the /dev/tty path. Note that the sketch uses 115k serial speed. You won’t see anything when you type but if you hit “enter” (to clear the buffer) “on[enter]” in screen LED 13 will turn on. Type “off[enter]” ([enter] means the enter key) and it will turn off. Great! Exactly what I need. But then I tried typing “on” then “off” then “muffins” then “on” and the light stayed off. Any garbage gets the Arduino stuck like my sketch. Ok, is what I’m trying to do impossible or is this just coincidence?
I modified the checkString example to look like this:
I added the break and it’s able to deal with garbage. I tested more than 20 commands with banging on the keyboard in between and it seems pretty solid. Now I just need to integrate this with my IRC bot and I might have something that can stay online for a while.
By the way, after you use screen to connect to a serial port, hit “Ctrl+A, k” to kill the window and break out of screen.
Update: People have asked for the code. It’s posted after the break.
Be sure to change the two sections of CHANGE ME. Also please note that like I said in my post, I never integrated these two source files together. So the IRC bot is unstable after about 8 commands.