Arduino ethernet enabled receipt printer [Resolved]

I have a receipt printer hooked up to my Arduino with the ethernet shield (wiznet one), and the Arduino basically takes POST data from a form, and spits it out onto a thermal receipt. The problem that I’m having is that the first time after a reset or upload, it initializes and gets an IP, but if I try and send anything over, it just times out. If I hit stop in the browser and send again, it’ll sometimes go through this second time, or maybe I have to hit stop and send again, and it works on the 3rd time. Also, if I let it sit for a while, then try to send another bit of data, I have to repeat the process.

How can I get it to work the first time through?

I have the following code:

#include <SoftwareSerial.h>
#include <Ethernet.h>

SoftwareSerial printer(2, 3); // RX, TX
byte mac[] = { 
  0x54, 0x55, 0x58, 0x10, 0x00, 0x24 };
EthernetServer server(80);
String postString;
String message;
String poster;

void setup()  
{
     printer.begin(9600);
     printer.println("---------------PRINTER INIT-----------------"); //Prints this line to the receipt printer
     printer.write(0x0A); //Printer End Page
     
      if (Ethernet.begin(mac) == 0) {
         printer.println("Failed to configure Ethernet using DHCP");
         printer.write(0x0A);
        for(;;)
          ;
      }else{
        
        printer.println("DHCP Ready");
        for (byte thisByte = 0; thisByte < 4; thisByte++) {
          // print the value of each byte of the IP address to the receipt printer
          printer.print(Ethernet.localIP()[thisByte], DEC);
          printer.print(".");
        }
        printer.println();
        printer.write(0x0A);
      }
      
      server.begin();
}

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  
  if (client) {
    boolean currentLineIsBlank = true;
    boolean hasPOSTdata = false;
      while (client.connected()) {
        
        if (client.available()) {
            char c = client.read();
            if (c == '\n' && currentLineIsBlank) {
               printer.println("-------------MESSAGE START---------------");
               hasPOSTdata = true;
            } else if (c == '\n' && hasPOSTdata == false) {
                // you're starting a new line
                currentLineIsBlank = true;
            } else if(c == '\n' && hasPOSTdata == true){
              hasPOSTdata = false;
            }else if (c != '\r') {
                // you've gotten a character on the current line
                currentLineIsBlank = false;
                if(hasPOSTdata == true){
                    postString = postString + c; //append the character to the message string
                }
            }
         }else{
           
          postString.replace("+"," ");      //translates the + in the data to a space
           postString.replace("%2C",","); //translates a comma code to a comma
           postString.replace("%27","'");  //translates a parens code to a parenthesis
           postString.replace("-"," ");     //translates a dash to a space
           
           //form that is posting here submits 2 vars: m=[the message] and b=[the poster]
           message = postString.substring(2, postString.indexOf("&b="));
           poster = postString.substring(postString.indexOf("&b=")+3);
           
          printer.print("Message:");
          printer.println(message);
          printer.print("Poster:");
          printer.println(poster);
          
          postString = "";
          currentLineIsBlank = true;
          hasPOSTdata = false;
          
          printer.println("");
           printer.println("---------------END POST-----------------");

          //spit out a quick OK message to tell the client we got the form data
           client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html><head></head><body>OK DONE</body></html>");
           
           
           
           client.stop();
           i=0;
         }
      }
      delay(1);
      printer.write(0x0A);
     
  }
}

To say it short:

  • Don't use the String class
  • Don't use SoftwareSerial if you have hardware serial

The String class fragments your memory and has some serious memory bugs, your Arduino will reset quite often because of that.

The SoftwareSerial's timing is not as exact as the hardware version and because of that some devices fail to correctly communicate with it. You don't seem to use the hardware serial so try moving your printer communication there, it's much more reliable.

I'll try commenting out the String functions and taking out the include to see what happens. As for the software serial, it's there, because when the printer is connected and you upload any firmware, the printer will printout an endless garbled mess. I have much better control with the software serial, and it works great for what I need.

pylon: To say it short:

  • Don't use the String class

So that caused the problem?

zoomkat:

pylon:
To say it short:

  • Don’t use the String class

So that caused the problem?

Actually- no it didn’t. After removing all the fancy string stuff, I still have the issue.

If I echo out some serial data inside the void right after if(client), I still don’t get anything till I hit refresh and submit again:

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  
  if (client) {
    Serial.println(client.read());
Serial.println(client.read());

That line consumes the first character of the connection. Is that what your intention is?

pylon:

Serial.println(client.read());

That line consumes the first character of the connection. Is that what your intention is?

My intention was to echo out to the serial port what client data was coming through at that point. In various other debugging if I Serial.print(client) before the if(client) statment, I get a -1, until my second retry.

I opened wireshark and was looking at the data, and it looks like the Arduino isn’t responding to ARP requests. When I send the 2nd request, everything is good.

The arduino sits on a 10.1.2.x network, and I’m accessing it from a 10.10.4.x network, though there is a path to that other network.

Well, I finally figured out the issue with the ARP not resolving. I had a manual IP address configured on an unplugged ethernet port, while my wireless was connected to the network.

The laptop would attempt to do an ARP on the ethernet port first, and ultimately fail. On the second request, it would send the ARP request out on wireless, to which it got a reply and worked. Once I disabled the ethernet adapter completely, everything worked first time though.

Been working on this all day, and to find it wasn't the Arduino after all is a good thing. I re-enabled the String functions and everything is working happily.

Actually- no it didn't. After removing all the fancy string stuff, I still have the issue.

That just makes the point that often some suggestions made are just BS as to correcting the real problem.

That just makes the point that often some suggestions made are just BS as to correcting the real problem.

Where was the code after the String class was removed? I'd need to see proof that removing the String class failed to solve the problem before calling BS.