Pages: 1 2 3 [4]   Go Down
Author Topic: Ethernet shield problems! Time to update library?  (Read 17945 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I already read in a lot of posts that the problem lies in that direction. I will try with 18 today and post the results.

By the way, in the forum I saw some adjustments to the client class to handle the sockets in a more clever way, but they used 17, so I figured that those adjustments were made in the class of 21...
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi again!

I made some changes to the code, so here it is again. I am using version 18 now like you suggested and I just powered up a testsetup. I will simply keep it running overnight and see what happens.

I am very curious wether I am closing the sockets right. I did not change anything in the library, so it may be just that problem.

EDIT: I just did some more testing. I scanned barcodes over and over again and the shield doesn't crash. I think I scanned over 40 times. However, after a minute or 30, I scan a few more times and then suddenly it stops working. Realy random  smiley-sad

Thanks for your trouble again!

/*
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 <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 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()
{
 pinMode(DO_RESET_ETH_SHIELD, OUTPUT);      // sets the digital pin as output
 digitalWrite(DO_RESET_ETH_SHIELD, LOW);
 delay(1000);  //for ethernet chip to reset
 digitalWrite(DO_RESET_ETH_SHIELD, HIGH);
 delay(1000);  //for ethernet chip to reset
 pinMode(DO_RESET_ETH_SHIELD, INPUT);      // sets the digital pin input
 delay(1000);  //for ethernet chip to reset
 Ethernet.begin(mac,ip);
 delay(1000);  //for ethernet chip to reset
 Ethernet.begin(mac,ip);
 delay(1000);  //for ethernet chip to reset
}

// 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(100);

    client.println();

    delay(100);

    digitalWrite(codeLedPin, HIGH);
    delay(100);
    digitalWrite(codeLedPin, LOW);

  }
  else {
    Serial.println("connection failed");
    digitalWrite(codeLedPin, HIGH);
    delay(100);
    digitalWrite(codeLedPin, LOW);
    delay(100);
    digitalWrite(codeLedPin, HIGH);
    delay(100);
    digitalWrite(codeLedPin, LOW);
    Serial.println("resetting ethernet shield");
    init_ethernet();
    
  }

  while(client.connected()) {
    client.stop();
    delay(00);
  }
    client.flush();
}

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);
  }

}

void usage() {
  Serial.println("Usage:");
  Serial.println("q<number>@                               Sets the questionId");
  Serial.println("s<number>.<number>.<number>.<number>@    Set the ip address of the server the data should go to");
  Serial.println("i<number>.<number>.<number>.<number>@    Set this unit's ip address");
  Serial.println();
  Serial.println("Commands can not be concatenated, one command at the time. Have fun!");
  Serial.println();
}
« Last Edit: October 26, 2010, 11:12:47 am by lebelg » Logged

Seattle, WA
Offline Offline
Full Member
***
Karma: 0
Posts: 194
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is how I usually close my socket.

Code:
webclient.flush();
webclient.stop();
  while(webclient.status() != 0) { // ADDED Aug 2 (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235991468)
             delay(5);
 }
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'll implement your code next thing tomorrow. However, it might be something else. I am powering the whole setup with a switchable power supply (1500mAh) set at 9 volt. Just now I read in a post that the voltage regulator can't handle this amount and will overheat and lock up the board. I'll try to switch the power supply to 7,5 volt and see what happens.

My question to you guys: How do you power your Duomilanove - ethernetshield setup?
Logged

Seattle, WA
Offline Offline
Full Member
***
Karma: 0
Posts: 194
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Funny you mention that.  I'm dealing with a power supply issue right now.  I thought 9vdc is acceptable.  I have used 5VDC @ 1A (which caused issues), 6VDC, and 9VDC @ 250ma.   My issue is around startup.  I have to press reset on the arduino to get the shield to work from a cold start state.  It's random too... sometimes it works just fine.

If you find out let me know.   I have not, however, had any issues with it stopping to work after a while of use.
Logged

Pages: 1 2 3 [4]   Go Up
Jump to: