Hi guys,
I am totally new to this but I have read tons of posts and can't seem to find a fix for my problem. Here's the story:
My team and me created an installation for a museum. A part of it consist of small stations where visitors can scan their ticket and push a button (A or B). This answer is send to a server via a php request.
To make this happen, we use an Arduino Duomilanove, an ethernet shield (rev 4, so without the sd card slot), a stripped barcode scanner and some buttons and stuf.
Here's our problem: Everything works fine for a while when we reset the board and the ethernet shield. But after a random amount of scans, out software gets stuck at "connecting" (check the code below). The problem is that it never revives after that. I posteds the code below, I am very sorry it's so much lines, but we put a lot of effort in making it easy to change the ip and server etc.
Hopefully someone can help us with this issue. Here's the code:
/*
VraagAntwoord
Software with the final hardware configuration
Version 1.7
*/
/*
Ethernet for sending messages to a server,
PS2Keyboard for reading barcodes,
EEPROM for writing/reading permanent data (questionId, IP addresses)
*/
#include <SPI.h>
#include <Ethernet.h>
#include <PS2Keyboard.h>
#include <EEPROM.h>
// Answers
#define YES 1
#define NO 0
#define VERSION "1.7"
// EEPROM addresses to write to (or with the ip addresses the address to begin writing to
#define ADDRQUESTION 0
#define ADDRSERVER 10
#define ADDRIP 20
// Ethernet reset pin
#define DO_RESET_ETH_SHIELD 9
#define RESET_AFTER_QUESTIONS 1
byte questionId = 1;
int answeredQuestions = 0;
/*
Barcode scanner
*/
int codeIRQPin = 2;
int codeDataPin = 3;
int codeLedPin = 4; // Connection status LED, blinking once: succes, blinking twice: connection failed
int ledAPin = 5;
int ledBPin = 6;
int buttonAPin = 7;
int buttonBPin = 8;
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[4]; // Our ip
byte gateway[] = {
172, 16, 0, 254 };
byte subnet[] = {
255, 255, 255, 0 };
byte server[4]; // Server ip
Client client(server, 80);
PS2Keyboard keyboard;
// Buffer for the barcode reader
char codeBuffer[16]; // Should be enough to hold our barcodes
int codeBufferI;
char code[sizeof codeBuffer + 1]; // +1 for the null char
// Buffer for the serial port
char serialBuffer[32];
int serialBufferI = 0;
// The setup() method runs once, when the sketch starts
void setup() {
Serial.begin(9600);
delay(1000);
questionId = EEPROM.read(ADDRQUESTION);
mac[5] = questionId; // mac address is dependent on the questionId
//Serial.println("Reading server ip");
readAddress(server, ADDRSERVER);
//Serial.println("Reading this unit's ip");
readAddress(ip, ADDRIP);
//Serial.println("Setting pinModes ..");
// LEDs
pinMode(ledAPin, OUTPUT);
pinMode(ledBPin, OUTPUT);
pinMode(codeLedPin, OUTPUT);
// Knoppen
pinMode(buttonAPin, INPUT);
pinMode(buttonBPin, INPUT);
//Serial.println("Done");
//Serial.println("Setting up ethernet ..");
init_ethernet();
delay(1000);
//Serial.println("Setting up keyboard ..");
keyboard.begin(codeDataPin, codeIRQPin);
//Serial.println("Done");
delay(1000);
Serial.println();
Serial.println();
Serial.print("VraagAntwoord v");
Serial.println(VERSION);
Serial.println();
Serial.print("questionId: ");
Serial.println(questionId, DEC);
Serial.print("ip: ");
printAddress(ip);
Serial.print("server ip: ");
printAddress(server);
Serial.println();
usage();
}
void init_ethernet()
{
Ethernet.begin(mac,ip,gateway,subnet);
delay(1000);
}
// Add a char to the code buffer if possible, silently fails if not possible.
void addChar(char c) {
if (codeBufferI < sizeof codeBuffer) {
codeBuffer[codeBufferI] = c;
codeBufferI++;
}
}
// the keyboard class's buffer
void Buffer() {
while (keyboard.available()) {
keyboard.read();
}
}
void doRequest(const char * code, int answer) {
Serial.print("Sending answer ");
if (answer == YES) {
Serial.print("YES");
}
else {
Serial.print("NO");
}
Serial.println();
Serial.println("connecting...");
client.connect();
delay(1000);
if (client.connected()) {
Serial.println("connected");
char request[128]; // Should fit, somewhat dependant on the barcode length
strcpy(request, "GET /in_question.php?code="); // Copy string to pointer to char[]
strcat(request, code);
strcat(request, "&qid=");
sprintf(request+strlen(request), "%d", questionId);// Sprintf converts decimal number (%d) to int, places it in a string, starting at pointer location.
strcat(request, "&answer=");
sprintf(request+strlen(request), "%d", answer);
strcat(request, " HTTP/1.0");
Serial.println(request);
client.println(request);
delay(500);
client.println();
delay(500);
digitalWrite(codeLedPin, HIGH);
delay(200);
digitalWrite(codeLedPin, LOW);
}
else {
Serial.println("connection failed");
digitalWrite(codeLedPin, HIGH);
delay(200);
digitalWrite(codeLedPin, LOW);
delay(200);
digitalWrite(codeLedPin, HIGH);
delay(200);
digitalWrite(codeLedPin, LOW);
}
while(client.connected()) {
client.flush();
client.stop();
delay(1000);
}
}
void readSerialChar(char c) {
if (serialBufferI < sizeof serialBuffer) {
serialBuffer[serialBufferI] = c;
serialBufferI++;
}
if (c == '@') {
switch(serialBuffer[0]) {
case 'q':
setQuestionId();
break;
case 's':
setServer();
break;
case 'i':
setIp();
break;
default:
Serial.println("Invalid command.");
usage();
}
for(int i=0; i < sizeof serialBuffer; i++) {
serialBuffer = 0;
- }*
- serialBufferI = 0;*
- }*
}
void readAddress(byte * dest, int eepromBeginAddr) {
- for(int i=0; i < 4; i++) {*
_ dest = EEPROM.read(eepromBeginAddr + i);_
* }*
}
void printAddress(byte * address) {
* for(int i=0; i < 4; i++) {*
_ Serial.print(address*, DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.println();
}
void writeAddress(byte * dest, int eepromBeginAddr) {
byte address[4];
int i = 1;
for(int part=0; part < 4; part++) {
byte value = 0;
while (serialBuffer != '.' && serialBuffer != '@') {
if (serialBuffer >= '0' && serialBuffer <= '9') {
value = 10;
value += serialBuffer - '0';
i++;
* }
}
address[part] = value;
i++;
}
// Save the address to EEPROM*
* for(int i=0; i < 4; i++) {
EEPROM.write(eepromBeginAddr + i, address);
}
memcpy(dest, address, 4);
}
void setServer() {
Serial.print("Setting new server ip address: ");
writeAddress(server, ADDRSERVER);
printAddress(server);
Serial.println("remember to restart");
}
void setIp() {
Serial.print("Setting new ip: ");
writeAddress(ip, ADDRIP);
printAddress(ip);
Serial.println("remember to restart");
}
void setQuestionId() {
int i = 1;
byte value = 0;
while(serialBuffer != '@') {
value = 10;
value += serialBuffer - '0';
i++;
* }
Serial.print("Setting questionId to ");
Serial.println(value, DEC);
EEPROM.write(ADDRQUESTION, value);
questionId = value;
}
// the loop() method runs over and over again,
// as long as the Arduino has power*
void loop()
{
* // blink A and B status: ready*
* digitalWrite(ledAPin, HIGH);
digitalWrite(ledBPin, HIGH);
delay (200);
digitalWrite(ledAPin, LOW);
digitalWrite(ledBPin, LOW);
delay (200);
digitalWrite(ledAPin, HIGH);
digitalWrite(ledBPin, HIGH);
delay (200);
digitalWrite(ledAPin, LOW);
digitalWrite(ledBPin, LOW);
// Waiting for barcode*
* Serial.println("Waiting for barcode");
Buffer();
boolean done = false;
while (!done) {
if (keyboard.available()) {
char c = keyboard.read();_
if (c == PS2_ENTER) {
_ Serial.print("[End of code]"); // Code ingelezen.
Serial.println();
addChar('\0'); // End the string*
* strcpy(code, codeBuffer);
codeBufferI = 0;
Serial.print(code);
Serial.println();
done = true;
}
else {
addChar(c);
Serial.print(c);
}
}
if (Serial.available() > 0) {
readSerialChar(Serial.read());
}
}
// Waiting for answer*
* Serial.println("Waiting for answer");
digitalWrite(ledAPin, HIGH);
digitalWrite(ledBPin, HIGH);
while (digitalRead(buttonAPin) == LOW && digitalRead(buttonBPin) == LOW) {
delay(10);
}
digitalWrite(ledAPin, LOW);
digitalWrite(ledBPin, LOW);
if (digitalRead(buttonAPin) == HIGH) {
// Geef antwoord "Ja"
doRequest(code, YES);
}
else {
// Geef antwoord "Nee"
doRequest(code, NO);
}
checkReset();
}
void checkReset() {
answeredQuestions++;_
if (answeredQuestions >= RESET_AFTER_QUESTIONS) {
init_ethernet();
_ answeredQuestions = 0;
}
}
void usage() {
Serial.println("Usage:");
Serial.println("q@ Sets the questionId");
Serial.println("s...@ Set the ip address of the server the data should go to");
Serial.println("i...@ Set this unit's ip address");
Serial.println();
Serial.println("Commands can not be concatenated, one command at the time. Have fun!");
Serial.println();
}*
Thanks in advance for all your trouble!_