WLAN-robot running in circles - need code help (GET, infinite loop)

Hi there,

Took me some time but now I really don't know any further. We built a robot that should be controlled by WLAN, it hosts a small HTML-page and the controls are made by GET-calls.
As long as the bot is connected via USB and the Serial Monitor is open, everything works fine: The WLAN-Shield connects to a router, the HTML-page is displayed, the motor shield executes the commands, the wheels turn.. But as soon as I disconnect the USB cable and send another command, it is executed infinitely, the robot starts to run in circles or advance uncontrollably.

I think we did everything to prevent this from happening, and I'm not sure anymore if it is a fault in the code or if it is a hardware issue. Can you 'quickly' check the code and tell me if there's something fishy?
Any help is greatly appreciated. Thanks in advance!

This is the hardware list:

  • Arduino Uno R2
  • Arduino WLAN Shield
  • Grove Base Shield
  • Grove I2C Motor Driver

This is the tricky part of the sketch. The whole sketch is posted as attachment.

void loop() {
    webServer();
}

void webServer() {
  //Serial.println("webServer: waiting!");
  // an http request ends with a blank line
  boolean currentLineIsBlank = true;
  
  // Get Request?
  boolean FoundCmd = false;
  boolean FoundGet = false;
  boolean cmdRunned = false;
  
  char strGet[GetBufSize+1]; //always room to terminate
  char * cpGetStart;
  char * cpTemp;
  int Count = 0; //current line char #
		
  HitCount++;
  
  // listen for incoming clients
  WiFiClient client = server.available();
  
  if (client) {
    Serial.println("new client");
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
              
          if (FoundCmd) { //get statement (argument) received
              if(!cmdRunned){
                Serial.print("SendCommand: ");
                cpGetStart += 9;
                Serial.println( cmd );
                commandSwitcher( cmd );
                cmdRunned = true;
              }
          }else{
            outputHTMLHomePage(client);
          }
          cmd = '0';
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          // we're starting a new line
	  if (!FoundGet) {
	    strGet[Count] = 0; //terminate input string
	    cpGetStart = strstr(strGet, "GET /cmd"); //check for GET msg (argument)
	    if (cpGetStart != NULL) {
              cpGetStart += 9;
              cpTemp = strstr(cpGetStart, " HTTP/1.1");
              if (cpGetStart != NULL) {
                * cpTemp = 0; //strip HTTP message, if present
                cmd = cpGetStart[0];
                Serial.print("Found GET: (");
                Serial.print(cmd);
                
                Serial.println(")");
                
                FoundCmd = true;
	      }
              
              //cpGetStart += 5; //set the pointer to the start of the GET message
              
	    }
          }
	  Count = 0;
          currentLineIsBlank = true;
          
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
	  if (!FoundGet && Count < GetBufSize) {
	    strGet[Count] = c; 
	    Count++;
	  }
        }
      }
    }
    // give the web browser time to receive the data
    delay(200);
      // close the connection:
      client.stop();
      Serial.println("client disonnected");
  }
}

void outputHTMLHomePage(WiFiClient client) {
  // send a standard http response header
  client.println("Connnection: close");
  client.println();
          
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          
          client.println("<head>");
          // add a meta refresh tag, so the browser pulls again every 5 seconds:
          //client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          client.println("</head>");
          client.println("<body><center>");
          client.println("<b>Arduino Test Client 2</b>

");
          client.println("<a href=\"/cmd/3\" target=\"frame\">Move Forward</a>
");
          client.println("<a href=\"/cmd/1\" target=\"frame\"><--Turn Left  |</a>");
          client.println("<a href=\"/cmd/2\" target=\"frame\">|  Turn Right--></a>

");
          client.println("<a href=\"/cmd/4\" target=\"frame\">Capturing Image</a>");
          // client.println("<iframe id=\"frame\" src=\"\" width=\"100%\" height=\"300\"></iframe>");
          client.println("</center></body>");
          client.println("</html>");
}

void commandSwitcher(char command) {
  Serial.println();
  Serial.print("Switch Command: ");
  Serial.println(command);
  
  switch(command) {
    case CMD_M_LEFT:
        Serial.println("Execute: CMD_M_LEFT");
        robotLeft(500);
      break;
      
    case CMD_M_RIGHT:
        Serial.println("Execute: CMD_M_RIGHT");
        robotRight(500);
      break;
      
    case CMD_M_FORWARD:
        Serial.println("Execute: CMD_M_FORWARD");
        robotForward(1000);
      break;
      
    case CMD_C_CAPTURING:
        Serial.println("Execute: CMD_C_CAPTURING");
        robotCapture();
      break;
      
  }
  
  robotStop();
}

/* Motor Commands */

void robotStop() {
  motorAndspd(0xa1,0b01,0);
  motorAndspd(0xa5,0b10,0);
}

void robotForward(int time) {
  motorAndspd(0xa1,0b01,200);
  motorAndspd(0xa5,0b10,200);
  delay(time); 
}

void robotLeft(int time) {
  motorAndspd(0xa5,0b10,150);
  motorAndspd(0xa1,0b10,150);
  delay(time);
}

void robotRight(int time) {
  motorAndspd(0xa5,0b01,150);
  motorAndspd(0xa1,0b01,150);
  delay(time);
}

void robotCapture(){
  for(int i =0; i < 5; i++){
  digitalWrite(ledPin, HIGH);  
  delay(100);          
  digitalWrite(ledPin, LOW);
  delay(100) ;
  }
}

This is the content of the Serial Monitor until the 'freeze':

WiFi shield working
Attempting to connect to SSID: ArduinoNet
SSID: ArduinoNet
IP Address: 192.168.0.2
signal strength (RSSI):-51 dBm
new client
GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: de-CH
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Host: 192.168.0.2
Connection: Keep-Alive

client disonnected
new client
GET /cmd/1 HTTP/1.1
Found GET: (1)
Accept: text/html, application/xhtml+xml, */*
Referer: http://192.168.0.2/
Accept-Language: de-CH
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Host: 192.168.0.2
Connection: Keep-Alive

SendCommand: 1

Switch Command: 1
Execute: CMD_M_LEFT

Demo1.ino (9.24 KB)

How is it being powered when you disconnect the USB?

The Arduino is powered from a 9V battery and the Motor Shield is powered by 4 AA 1.5V batteries.

A few things to try:

If it's easy to do, disconnect the motors and see whether the problem still happens. If not, this would indicate that you may have a power supply/electrical noise problem, or a wiring fault. Do you have a circuit diagram you could post to show how this lot is connected to the Arduino?

Comment out the actual actions in commandSwitcher() and confirm that the problem doesn't happen.

Reinstate the actions in commandSwitcher, and add a Serial.print() statement before robotStop() to confirm the program has gone past the action without crashing, then add another Serial.print after the call to robotStop() to confirm it's completed the stop without crashing.

Try different commands. Do they all produce the same problem?

I..I don't know what to say. I disconnected the motors, fired up the sketch once more, and reconnected them. Now it works like a charm! Without even changing the code..

I think you were right, there must have been a faulty wiring in the motor / motor shield.

Thanks a lot for your input. You definitely made my day..!

Poor ground connections can often cause issues.