Arduino UNO and RedFly not stabil

Hi,

I have a Arduino project with Watterott RedFly and I have 2 problems.
The first: I’m sending UDP broadcasts. On the iPhone is listening a UDP Server on the same port. The issue is, that I get the UDP-message from the Arduino sometimes with special characters. The number of characters is different. It looks like that the udp string is not terminated.
The second: My webserver on the Arduino ist not stable. After a number of days the Arduino sends no udp broadcasts and the web server stops responding. Attached my Arduino program.

Any suggestions
Andreas

#include <RedFly.h>
#include <RedFlyServer.h>
#include <RedFlyClient.h>


#define doorBuzzerPin 7             //Pin for door buzzer
#define errorLedPin   6             //error indicator Led Pin
#define buzzerTime 5                //5s time buzzer
#define udpTime 3                   //2s do udp broadcast   
#define clientConnectionTestTime 60 //60s do client connetcion test   
#define tempPin  0                  //analogRead Pin 0   



char ssid[] = "XXXX";
char key[]="dsfhgfhsdgf";

char router[]="192,168,1,1";
char func[]="d,t";
char ip_all_func_on[120];
char ip_all_func_off[120];



const char action_door_buzzer[] = "door_buzzer";

uint8_t http=INVALID_SOCKET;               //socket handle for Client Connect


float actualTemp = 0.0;


uint8_t bytes[4];                         //ip adress for the client connect

// Config RedFly
byte ip[4];                               //ip adress from RedFly after DHCP connect
byte mac[8];                              //mac adress of the shield


//UDP Broadcast ip
byte udpip[] = {255,255, 255, 255 };

String httpRequest;
boolean mustSwitchDoorBuzzerOff = false;  
RedFlyClient udpClient(udpip,65000);      //UDP Broadcast an Port 65000
RedFlyServer server(80);

void setup()
{
  int i;
  Serial.begin(115000);                   //init serial port and set baudrate
  while(!Serial);                         //wait for serial port to connect (needed for Leonardo only)

  pinMode(doorBuzzerPin, OUTPUT);        //door buzzer 
  pinMode(errorLedPin, OUTPUT);          //error indicator

  digitalWrite(errorLedPin, LOW);

  char *p_router = router;
  for ( int i = 0; i < 5; i++ )
  {
    bytes[i] = strtol( p_router , &p_router, 10 );
    p_router++;
  }

  //start WiFi
  while(startwifi() != 0){ 
    delay(1000); 
    digitalWrite(errorLedPin, LOW);
  }

}

void loop()
{
  unsigned long time;
  static unsigned long next_time_router_connect=0;
  static unsigned long next_time_udp_call=0;
  static unsigned long time_switch_off_buzzer=0;
  static uint8_t connection=0;
  char tmp[200];
  char tempStr[10];

  time = millis();

  // do door buzzer
  if (httpRequest.indexOf(action_door_buzzer) >0) 
  {
    //debugoutln("Door buzzer switch on");
    digitalWrite(doorBuzzerPin, HIGH);
    time_switch_off_buzzer = time + (buzzerTime*1000UL);
    mustSwitchDoorBuzzerOff = true;
  }

  if (time > time_switch_off_buzzer && mustSwitchDoorBuzzerOff)
  {
    mustSwitchDoorBuzzerOff = false;
    //debugoutln("Door buzzer switch off");
    digitalWrite(doorBuzzerPin, LOW);     // deactivate door buzzer
  }
  httpRequest = String();                                    //init http Request String


    if(time > next_time_udp_call)
  {
    next_time_udp_call = time + (udpTime*1000UL);           //every 2s
    udpClient.connectUDP();
    if(mustSwitchDoorBuzzerOff) udpClient.println(ip_all_func_on);
    else udpClient.println(ip_all_func_off);
    server.stop();
    udpClient.stop();
  }  


  //client code for connection test
  if(time > next_time_router_connect)                       //connection test every 60s
  {
    //new temperature measurement
    calculateActualTemperature();
    next_time_router_connect = time + (clientConnectionTestTime*1000UL); //every 60s

    http = RedFly.socketConnect(PROTO_TCP, bytes, 80);     //start connection to the router on port 80
    if(http == 0xFF)
    {
      debugoutln("client not ok");  
      RedFly.disconnect();

      if(++connection >= 3)
      {
        while(startwifi() != 0){ 
          delay(1000); 
        } //restart WiFi module
        connection = 0;
      }
    }
    else
    {
      debugoutln("client ok");
      connection = 0;
    }

  }


  //listen for incoming clients
  if(server.available())
  {
    //a http request ends with a blank line
    boolean currentLineIsBlank = true;
    while(server.available())
    {
      char c = server.read();
 

      httpRequest += c;

      if(c == '\n' && currentLineIsBlank)
      {
        //clear input buffer
        server.flush(); 

        //send standard HTTP 200 header
        server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));

        //send some text
        server.println_P(PSTR("<HTML><HEAD><TITEL>RedFly und Arduino </TITEL></HEAD><BODY>"));
        server.println_P(PSTR("<table border=0 cellpadding=2 cellspacing=2 with250><tbody><tr>"));

        memset(tempStr,0,sizeof(tempStr));
        dtostrf( actualTemp, 7, 1, tempStr );                    //convert float to char  
        memset(tmp,0,sizeof(tmp));        
        sprintf_P(tmp, PSTR("<td>Temp :</td><td>%s</td></tr><tr>"),tempStr);
        server.print(tmp);


        memset(tmp,0,sizeof(tmp));  
        sprintf_P(tmp, PSTR("<td>Func :</td><td>%s</td></tr></tbody></table></body></html>"), ip_all_func_on);
        server.print(tmp);        

        break;
      }
      if(c == '\n')
      {
        //you're starting a new line
        currentLineIsBlank = true;
      } 
      else if(c != '\r')
      {
        //you've gotten a character on the current line
        currentLineIsBlank = false;
      }
    }

    //close connection
    server.stop();
  }
  else if(!server.connected()) //listening port still open?
  {
    server.stop(); //stop and reset server
    server.begin(); //start server
  }
}


void debugout(char *s)
{
  RedFly.disable();
  Serial.print(s);
  RedFly.enable();
}

void debugoutln(char *s)
{
  RedFly.disable();
  Serial.println(s);
  RedFly.enable();
}



void calculateActualTemperature()
{
  float temp_all = 0;

  for (int i=0;i<10;i++)
  {
    temp_all += (analogRead(tempPin)/2)-2;
  }
  actualTemp = temp_all/10;
}  

uint8_t startwifi()
{
  uint8_t ret;
  char ip_ch[10];
  char mac_ch[20];
  char *p_ssid = &ssid[0]; 
  char *p_key = &key[0];

  //init the WiFi module
  if(RedFly.init(115000,HIGH_POWER) != 0) //LOW_POWER MED_POWER HIGH_POWER
  {
    digitalWrite(errorLedPin, HIGH);
    debugoutln("Fehler 1");
    return 1;
  }

  //join network the ssid of network must be visible
  RedFly.scan();


  if( strlen(p_key)==0) 
  {
    ret = RedFly.join(p_ssid);
    if(ret)
    {
      digitalWrite(errorLedPin, HIGH);
      debugoutln("Fehler ssid");
      return 2;
    }
  }
  else
  {
    ret = RedFly.join(p_ssid, p_key, INFRASTRUCTURE);
    if(ret)
    {
      digitalWrite(errorLedPin, HIGH);
      debugoutln("Fehler ssid key");
      return 2;
    }    
  }

  ret = (RedFly.begin() !=0);
  if (ret)
  {
    digitalWrite(errorLedPin, HIGH);
    debugoutln("Fehler 3");
    RedFly.disconnect();
    return 3;
  }

  memset(ip_all_func_on,0,sizeof(ip_all_func_on));  // initialize ip adress, function for udp
  memset(ip_all_func_off,0,sizeof(ip_all_func_off));
  memset(mac,0,sizeof(mac));
  RedFly.getlocalip(ip); //receive shield IP 
  RedFly.getmac(mac);


  for (int i=0;i<6;i++)      //build mac adress is used for udp broadcast
  {
    memset(ip_ch,0,sizeof(ip_ch));
    itoa(mac[i],ip_ch,10);
    if(i==0) strcpy(ip_all_func_on,ip_ch);
    else
    {
      strcat(ip_all_func_on,ip_ch);
      if (i==5) strcat(ip_all_func_on,",");
      else strcat(ip_all_func_on,"-");
    }
  }  

  for (int i=0;i<4;i++)      //build ip adress is used for udp broadcast
  {
    memset(ip_ch,0,sizeof(ip_ch));
    itoa(ip[i],ip_ch,10);
    strcat(ip_all_func_on,ip_ch);
    if (i==3) strcat(ip_all_func_on,",");
    else strcat(ip_all_func_on,".");
  } 


  strcpy(ip_all_func_off,ip_all_func_on);
  strcat(ip_all_func_on,"on");
  strcat(ip_all_func_on,",2,");

  strcat(ip_all_func_on,func);
  ip_all_func_on[strlen(ip_all_func_on)] = '\0';
  
  strcat(ip_all_func_off,"off");
  strcat(ip_all_func_off,",2,");
  strcat(ip_all_func_off,func);

  ip_all_func_off[strlen(ip_all_func_off)] = '\0';
  server.begin();
  return 0;      
}

My webserver on the Arduino ist not stable. After a number of days the Arduino sends no udp broadcasts and the web server stops responding.

Eliminate the use of the String class in your sketch. It's implementation is improper for microcontrollers (without a MMU) and, additionally, the current IDE versions have a memory leak in the dynamic memory deallocation which the String class is using extensively.

Your usage of the server class is very strange by constantly stopping and starting the server socket. It might not be completely wrong but it make the code overly complex and it might cause other problems I haven't found yet.

The issue is, that I get the UDP-message from the Arduino sometimes with special characters. The number of characters is different. It looks like that the udp string is not terminated.

Can you post some examples?

What do you expect a line like this to do?

  ip_all_func_on[strlen(ip_all_func_on)] = '\0';

Hi pylon,

thanks for your help. I have changed my program and replaced the String Object with a char array.

void loop()
{
  unsigned long time;
  static unsigned long next_time_router_connect=0;
  static unsigned long next_time_udp_call=0;
  static unsigned long time_switch_off_buzzer=0;
  static uint8_t connection=0;
  char tmp[200];
  char tempStr[10];
  char request[300];
  time = millis();
  char buff[1000];
  char *s;

  s = strstr(httpRequest, "door_buzzer");      // search for string "action_door_buzzer" in httpRequest
 
  // do door buzzer
  if (s != NULL)  
  {
    debugoutln("Door buzzer switch on");
    digitalWrite(doorBuzzerPin, HIGH);
    time_switch_off_buzzer = time + (buzzerTime*1000UL);
    mustSwitchDoorBuzzerOff = true;
  }

  if (time > time_switch_off_buzzer && mustSwitchDoorBuzzerOff)
  {
    mustSwitchDoorBuzzerOff = false;
    debugoutln("Door buzzer switch off");
    digitalWrite(doorBuzzerPin, LOW);     // deactivate door buzzer
  }
  //httpRequest = String();                                    //init http Request String
  //memset(httpRequest,0,sizeof(httpRequest));
  memset(request,0,sizeof(request));
  if(time > next_time_udp_call)
  {
    next_time_udp_call = time + (udpTime*1000UL);           //every 2s
    udpClient.connectUDP();
    if(mustSwitchDoorBuzzerOff) udpClient.println(ip_all_func_on);
    else udpClient.println(ip_all_func_off);
    server.stop();
    udpClient.stop();
  }  


  //client code for connection test
  if(time > next_time_router_connect)                       //connection test every 60s
  {
    //new temperature measurement
    calculateActualTemperature();
    next_time_router_connect = time + (clientConnectionTestTime*1000UL); //every 60s

    http = RedFly.socketConnect(PROTO_TCP, bytes, 80);     //start connection to the router on port 80
    if(http == 0xFF)
    {
      debugoutln("client not ok");  
      RedFly.disconnect();

      if(++connection >= 3)
      {
        while(startwifi() != 0){ 
          delay(1000); 
        } //restart WiFi module
        connection = 0;
      }
    }
    else
    {
      //debugoutln("client ok");
      connection = 0;
    }

  }


  //listen for incoming clients
  if(server.available())
  {
    int index = 0;
    //a http request ends with a blank line
    boolean currentLineIsBlank = true;
    while(server.available())
    {
      char c = server.read();
      //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
      
      httpRequest[index] = c;
      index++;
      
      if(c == '\n' && currentLineIsBlank)
      {
        httpRequest[index] = '\0';
         
        //clear input buffer
        server.flush(); 

        //send standard HTTP 200 header
        server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));

        //send some text
        server.println_P(PSTR("<HTML><HEAD><TITEL>RedFly und Arduino </TITEL></HEAD><BODY>"));
        server.println_P(PSTR("<table border=0 cellpadding=2 cellspacing=2 with250><tbody><tr>"));

        memset(tempStr,0,sizeof(tempStr));
        dtostrf( actualTemp, 7, 1, tempStr );                    //convert float to char  
        memset(tmp,0,sizeof(tmp));        
        sprintf_P(tmp, PSTR("<td>Temp :</td><td>%s</td></tr><tr>"),tempStr);
        server.print(tmp);


        memset(tmp,0,sizeof(tmp));  
        sprintf_P(tmp, PSTR("<td>Func :</td><td>%s</td></tr></tbody></table></body></html>"), ip_all_func_on);
        server.print(tmp);        

        break;
      }
      if(c == '\n')
      {
        //you're starting a new line
        currentLineIsBlank = true;
      } 
      else if(c != '\r')
      {
        //you've gotten a character on the current line
        currentLineIsBlank = false;
      }
    }

    //close connection
    server.stop();
  }
  else if(!server.connected()) //listening port still open?
  {
    server.stop(); //stop and reset server
    server.begin(); //start server
  }
}

Now the program hangs if a request comes in and the redFly restarts. It’s only works with my String Object. I’ve already tried it earlier. I do not know why

  char tmp[200];
  char tempStr[10];
  char request[300];
  time = millis();
  char buff[1000];

Just how much memory do you think your Arduino has? This alone is using more than 3/4 of the SRAM on a 328-based Arduino.

Just now I'm using a mega. The memory is not the problem...