Hello there,
I currently try to write a little IRC Bot with the Arduino and the Ethernet Shield. I ran into a problem and I think that it is maybe a bug in the Ethernet lib. I am not a really good C/C++ coder and also absolutly new to hardware and micros.
The code isn´t very well designed (not optimized) at the moment, because it´s just a prototype I wrote in about 3h.
Sketch:
#include <MsTimer2.h>
#include <Ethernet.h>
#include <Client.h>
// Network
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 0, 111 };
byte ircserver[] = { 207, 182, 240, 74 };
// IRC
char hostname[] = "irc.freenode.net";
char nickname[] = "stahlArduinoBot";
char ident[] = "arduinoBot";
char channel[] = "#stahlstift";
// Don´t touch anything!
Client client(ircserver, 6667);
const int bufferSize = 1024;
char buffer[bufferSize]; // Buffer für die Timerfunktion
int pingDelay = 100; // Wird für einen sicheren Anmeldeprozess benötigt!
// NTC
int tempPin = 0;
float voltbit = 0.0048828125f;
boolean authIRC() {
int buffSize = 512;
char authBuffer[buffSize]; // lokaler Buffer, da dieser nur einmal benötigt wird
int i = 0;
boolean initData = false;
boolean authInfoSended = false;
long authTimeout = 60000; // 60 Sekunden
long startTime = millis();
while(!initData) { // Ich muss sicher sein, das Daten eingetroffen sind
if(client.available()) {
initData = true; // Hier weiß ich nun das Daten vorhanden sind und kann die WhileSchleife später beenden
while (client.available()) {
char c = client.read();
if (c == 13) {
authBuffer[i] = 0;
i = 0;
if (authInfoSended) {
// TODO: Registrierter Benutzername
if (strstr(authBuffer, "Welcome to the freenode IRC Network") != NULL) {
return true;
}
// Timeout damit wir uns nicht in einer Endlosschleife befinden, falls mit der Anmeldung was schief ging
if ((millis() - startTime) > authTimeout) {
Serial.println("Timeout!");
return false;
}
} else {
// Anmelden
client.print("NICK ");
client.println(nickname);
client.print("USER ");
client.print(ident);
client.print(" ");
client.print(hostname);
client.println(" bla :arduino");
authInfoSended = true;
startTime = millis(); // Ab hier beginnt die Timeoutzählung
}
} else {
authBuffer[i] = c;
i++;
}
delay(pingDelay);
}
}
}
return false;
}
void checkMsg() {
int i = 0;
// DEBUG 1 Check
if(client.available()) {
Serial.println("not empty!");
} else {
Serial.println("empty!"); // it will print empty
}
// DEBUG 2 Check
if(client.available()) {
Serial.println("not empty!"); // it will print not empty!
} else {
Serial.println("empty!");
}
// DEBUG 3 Check
if(client.available()) {
Serial.println("not empty!"); // it will print not empty!
} else {
Serial.println("empty!");
}
// DEBUG 4 Check
if(client.available()) {
Serial.println("not empty!"); // it will print not empty!
} else {
Serial.println("empty!");
}
while(client.available()) {
char c = client.read();
if (c == 13) {
buffer[i] = 0;
i = 0;
// Auf Server PING antworten
if (strstr(buffer, "PING ") != NULL) {
if (buffer[0] == 'P' && buffer[1] == 'I' && buffer[2] == 'N' && buffer[3] == 'G') {
client.println("PONG");
}
}
// Nachricht aus dem aktuellen Channel?
if (strstr(buffer, channel) != NULL) {
// Auf !roomtemp im aktuellen Channel reagieren
if (strstr(buffer, "!roomtemp")) {
// NTC
float tmp = analogRead(tempPin) * voltbit;
int r1 = (5 * 1000 / (5-tmp)) - 1000;
client.print("PRIVMSG ");
client.print(channel);
client.print(" :In stahlstift´s room is currently ");
client.print(r1);
client.println(" (NTC ohm - translation table will be there in a feature version). Thanks for your interest! (simpleIRC v0.1 by stahlstift on Arduino Duemilanove)");
}
}
Serial.print("checkMsg(): ");
Serial.println(buffer);
} else {
buffer[i] = c;
i++;
}
}
}
void joinRoom() {
client.print("JOIN ");
client.println(channel);
}
void setup() {
Ethernet.begin(mac, ip);
Serial.begin(9600);
delay(2000); // EthernetShield etwas Zeit lassen
if (client.connect()) {
if(!authIRC()) {
Serial.println("Authentifizierung fehlgeschlagen!");
} else {
Serial.println("Authentifizierung erfolgreich");
joinRoom();
client.flush(); // Message of the Day, Raumliste etc, den ganzen Mist löschen, den wollen wir nicht einlesen :)
delay(1000); // Noch ne Sekunde warten bevor es los geht :)
// Der Timer ruft jede Sekunde "checkMsg" auf welche Kommandos entgegen nimmt
MsTimer2::set(1000, checkMsg);
MsTimer2::start();
}
} else {
Serial.println("Verbindung fehlgeschlagen!");
}
}
void loop() {
if (!client.connected()) {
Serial.println("Verbindung verloren");
client.flush();
client.stop();
while(true); // Damit Verbindung verloren nicht gespammed wird!
}
}
The problem is in "void checkMsg() {".
Because freenode spams me with motd and channel list I want to do client.flush() and so I do. But client.available() is in the first statment empty, in the second not and in the while-loop also not.
Maybe it´s a failure from me, so...
I am using the Arduino 2009 and Arduino 0017.
Greetings!