Problem with structure

Hello guy, i'm a newbie and i've a problem with structure in my project. I use 2 type of structure to save the network and sensors parameters, loaded from sd.

#include <EEPROM.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <OneWire.h>
#include "structure.h";

#define MAX_SENSORS 5

SENSORS_T sensor[MAX_SENSORS];
NETWORK_T network;

char file_net_cfg[] = { 
  "config/net.cfg"};
char file_sensors_cfg[] = { 
  "config/sensors.cfg"};

boolean from_eeprom = false;


//************************************************************************************//
//FUNCTION TO START NETWORK & IMPORT PARAMETERS IN STRUCTURE   //
//**********************************************************************************//
void network_setup(String net_cfg[],boolean &eeprom )
{
  File ipcfg;
  char lastread[1];
  network.mac[0] = 0xA2;
  network.mac[1] = 0xDA;
  network.mac[2] = 0x00;
  network.mac[3] = 0x22;
  network.mac[4] = 0x27;
  network.mac[5] = 0x90;
  Serial.print(F("Loading ethernet from "));
  if (!eeprom)
  {
      Serial.print(F("SD: "));
      byte *tmp = (byte *) malloc(4);
      
      strIp2byteVect(net_cfg[0], tmp);
      for(uint8_t i=0;i<4;i++) network.ip[i] = tmp[i];

      strIp2byteVect(net_cfg[1], tmp);
      for(uint8_t i=0;i<4;i++) network.subnet[i] = tmp[i];

      strIp2byteVect(net_cfg[2], tmp);
      for(uint8_t i=0;i<4;i++) network.gateway[i] = tmp[i];

      free(tmp);
      Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
      Serial.println(F("OK"));
      Serial.print(F("IP: "));
      Serial.println(Ethernet.localIP());
  } else { 
    Serial.print(F("EEPROM: "));
    uint8_t arr_count = 0; //contatore per array variabili temporanee
    for (uint8_t a = 20; a < 32; a++)
    {
      if (arr_count == 4 && a < 32) arr_count = 0;
      if ((a-20) < 4) network.ip[arr_count] = EEPROM.read(a);
      if ((a-20) == 4 && (a-20) < 8) network.subnet[arr_count] = EEPROM.read(a);
      if ((a-20) == 8 && (a-20) < 12) network.gateway[arr_count] = EEPROM.read(a);
      arr_count++;
    }

    Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
    Serial.println(F("OK"));
  }
}
//**********************************************************************//



//*************************************************************************//
//FUNCTION TO IMPORT SENSORS PARAMETERS IN STRUCTURE                     //
//***********************************************************************//

void sensors_setup(String sensors[])
{
  char buffer[10];
  Serial.print(F("Loading Sensors: "));    
  for (uint8_t i = 0; i <  5; i++){
        int commaPosition = 0;
        uint8_t column = 1;
      do
        {
            commaPosition = sensors[i].indexOf(',');
             switch (column) {
               case 1:
                   sensors[i].substring(0,commaPosition).toCharArray(buffer,sensors[i].substring(0,commaPosition).length()+1);
                   strcpy(sensor[i].index, buffer);
                 break;
              /* case 2:
                   sensors[i].substring(0,commaPosition).toCharArray(sensor[i].pintype,sensors[i].substring(0,commaPosition).length()+1);
                 break; 
               case 3:
                   sensors[i].substring(0,commaPosition).toCharArray(buffer,sensors[i].substring(0,commaPosition).length()+1);
                   sensor[i].pin = atoi(buffer);
                 break;   
             case 4:
                   sensors[i].substring(0,commaPosition).toCharArray(sensor[i].model,sensors[i].substring(0,commaPosition).length()+1);
                 break;
               case 5:
                   sensors[i].substring(0,commaPosition).toCharArray(sensor[i].address,sensors[i].substring(0,commaPosition).length()+1);
                 break;  
               case 6:
                   sensors[i].substring(0,commaPosition).toCharArray(sensor[i].description,sensors[i].substring(0,commaPosition).length()+1);
               break;   */    
           }
           //Serial.println(sensor[i].index[0]);
            sensors[i] = sensors[i].substring(commaPosition+1, sensors[i].length()); 
            column++;
        } while(commaPosition >=0);
        
      }
      Serial.println(F("OK"));
}
//**********************************************************************//

//*************************************************************************//
//FUNCTION TO READ DATA FROM FILE IN SD                     //
//***********************************************************************//
void file_read(String data[],char* path){
File file_to_read;
file_to_read = SD.open(path, FILE_READ);
if (file_to_read){
  uint8_t line = 0;
      char lastread[1];
      while (file_to_read.available())
      {
        //read esegue la lettura di un byte alla volta
        lastread[0] = file_to_read.read();
       if (lastread[0] == 10 || lastread[0] == 13)
        {  
          line++;
        } else {
          data[line] += lastread[0];      
        }
      }
      file_to_read.close();
    }
}

//*************************************************************************//
//FUNCTION TO SPLIT STRING TO BYTE ARRAY                          //
//***********************************************************************//
void strIp2byteVect(String str, byte *ipVect){
  String tmpStr;
  uint8_t bytesCount,			 //contatore per il num di byte
  i;				    //contatore per il ciclo sulla stringa

  i = 0;
  for (bytesCount = 0; bytesCount < 4; bytesCount++){     //Ciclo sui byte
    for ( ; (str.charAt(i) != '.') && (str.charAt(i) != '\0'); i++)  //Ciclo sulla stringa
      tmpStr += str.charAt(i);
    ipVect[bytesCount] = tmpStr.toInt();
    tmpStr = "";
    ++i;
  }
}
//**********************************************************************//


void setup() {
  Serial.begin(19200);
  Wire.begin();
  boolean sd_start = SD.begin(4);
  String sensorcfg[MAX_SENSORS];
  String netcfg[3];
  if(sd_start) {
      file_read(netcfg, file_net_cfg);
      file_read(sensorcfg, file_sensors_cfg);
      sensors_setup(sensorcfg);
      network_setup(netcfg,from_eeprom);
  }  else {
      from_eeprom = true;
      network_setup(netcfg,from_eeprom);
  } 
}  


void loop(){

}

When i try to assign (ex. strcpy(sensor_.index, buffer):wink: or read (ex. Serial.println(sensor*.index[0]):wink: value to sensors struct member, value assignment of network parameters failed and Ethernet.localIP() return 0.0.0.0. I've created a new tab, named structure.h, with this content:_
_
```_
#ifndef structure_h
#define structure_h

typedef struct{
  char index[2];
  char pintype[3];
  char pin[3];
  char model[11];
  char address[10];
  char description[31];
}SENSORS_T;

typedef struct{
  byte ip[4];
  byte subnet[4];
  byte gateway[4];
  byte mac[6];
} NETWORK_T;

#endif*
```
Where's the problem? Maybe i'm the problem?!

Where's the problem?

Where's the debug output? Do you know that the array of Strings passed to file_read contains anything useful when the function ends?

You have global arrays of the two kinds of structs. Why is it necessary to collect the data in an array of String objects, then parse the String objects to get the data. Populate the struct elements while reading the file, and save a boatload of memory. The String class is, without a doubt, the most memory wasteful class in the shed.

I use the String object because it's more sample to operate with a string. When i read from sd, the result is a string like this:
"0,D,12,DS18B20,0,External_temperature"
With a few istruction i can split the string in struct. When i try to write value in sensors struct, all variable array in network struct are equal to 0! If i delete line where i valorize sensors struct, network variable array has the right value. you advice me to substitute string object with struct variable?

I use the String object because it's more sample to operate with a string.

Everything that the String class can do it does using the string functions under the covers. You really should learn to do those things yourself, to strings (with lower case s). The parsing is done with strtok() (NOT strtok_r()).

When i try to write value in sensors struct, all variable array in network struct are equal to 0!

Unless I missed something, I don't see how you know this.

This is crap:

sensors[i].substring(0,commaPosition).toCharArray(buffer,sensors[i].substring(0,commaPosition).length()+1);

The second argument to the toCharArray() function is the size of the array to write to. It is NOT the length of the string to write to the array.

Some meaningful names would be real helpful to. Keeping track that sensor[n] is one kind of variable, and sensors[n] is a completely different kind of variable is difficult.

                   strcpy(sensor[i].index, buffer);

Where do you verify that the buffer array is not larger than the index array? How do you KNOW that you are not writing past the end if the index array.

Your array of sensor structs is using 300 bytes. That's a relatively significant chunk of memory, when you only have 2000 bytes (on other than the Mega).

Add some debug code to see what is actually in buffer when you go to write it to the sensor element.

Thanks for your advice. I'm trying to replace String object with char array, but the result is........horrible. I've modified the old file_read() function with this:

//*************************************************************************//
//FUNCTION TO READ DATA FROM FILE IN SD                                   //
//***********************************************************************//
void file_read(char data[][70],char path[]){
File file_to_read;
file_to_read = SD.open(path, FILE_READ);
if (file_to_read){
  int line = 0;
      char lastread[2];
      int index = 0;
      while (file_to_read.available())
      {
        //read esegue la lettura di un byte alla volta
        lastread[0] = file_to_read.read();
       if (lastread[0] == 10 || lastread[0] == 13)
        {  
          line++;
          index = 0;
        } else {
          
          data[line][index] = lastread[0];
          index++; 
          Serial.println(data[line]); 
            
        }
         
      }
      
      file_to_read.close();
    } else {
      Serial.println(F("error reading file"));
    }
}

This is a setup code:

void setup() {
  Serial.begin(19200);
  Wire.begin();
  boolean sd_start = SD.begin(4);
  char data[6][70];
  if(sd_start) {
      file_read(data, file_net_cfg);
      //file_read(sensorcfg, file_sensors_cfg);
      //sensors_setup(sensorcfg);
      //network_setup(netcfg,from_eeprom);
  }  else {
      from_eeprom = true;
     // network_setup(netcfg,from_eeprom);
  } 
}

and this is the unexpected result:

192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
192.168.1.20?¯®?8{¢Ë~?¤9§p?÷?QÿÝoU?ëõ¾Ù??µÏÛcs½è¶{vYÞ7ç?«µÿùý255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
255.255.255.0§ê¯âø½çÏË?:ÿÿy??wîÙû,r¯#µ÷®?¾ã~b5¯¥¯i ÌÙß§þ»·õ§Ti®èÿ19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!
19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
19·ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192ÿ?µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192.1µÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192.16ÍgoY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192.168goY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192.168.oY?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192.168.1Y?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192.168.1.?Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}
192.168.1.1Ý??¾O8Ç}¶´ú?ýÖmý¨í?úCÓ'6	¿}ü?Ûcí?ݐoÖ_qòÿ?÷?¾ïÿûn»!ëÙö?wVùÿËytÊ÷9îßt)à¶ô?÷þý}

Where is the error? I have tried to delclare array inside file_read() function but with the same result!

Thanks for your advice. I'm trying to replace String object with char array, but the result is........horrible. I've modified the old file_read() function with this:

Yes. it is. There is no reason to read the entire file into memory. Read a line. Process that line. Read another line. Process that line.

The file_read function should take one argument - the name of the file to read.

      char lastread[2];

Why are you using an array to hold one character? The File::read() function returns a char, not a char array.

          data[line][index] = lastread[0];
          index++;

The string that data[line] refers to IS NOT A STRING.

I'll say this one more time. A string is an array of chars THAT IS NULL TERMINATED.

You are not NULL terminating you arrays. Therefore they are NOT strings. Therefore, you can not pass them to functions that expect strings, like Serial.print().

You sould print a line AFTER reading the carriage return character. Moreover you must add the NULL character that terminates the string:

      while (file_to_read.available())
      {
        //read esegue la lettura di un byte alla volta
        lastread[0] = file_to_read.read();
       if (lastread[0] == 10 || lastread[0] == 13)
        {  
          data[line][index] = '\0';     // NULL terminate the string.
          Serial.println(data[line]);  // Print the line.
          line++;
          index = 0;
        } else {
          data[line][index] = lastread[0];
          index++;             
        }
         
      }

I'll say this one more time. A string is an array of chars THAT IS NULL TERMINATED.

I thought that the compiler add null terminator when array is declared! I would like to read all lines in the file and process them in other function (data in file must be splitted in the struct). You think that there's a better way?

I thought that the compiler add null terminator when array is declared!

The compiler initializes global variables, NOT local ones. Every time you add a character to the array, you must follow that with a NULL.

You think that there's a better way?

Yes. Process the records one at a time. You can keep the processing function, but make it deal with one record, not an array of records.

I followed your advice and i change much code!! This is a new code:

#include <EEPROM.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <OneWire.h>

#define MAX_SENSORS 5

typedef struct{
  char index[2];
  char pintype[3];
  char pin[2];
  char model[11];
  char address[11];
  char description[31];
}SENSORS_T;

typedef struct{
  byte ip[4];
  byte subnet[4];
  byte gateway[4];
  byte mac[6];
} NETWORK_T;

SENSORS_T sensor[MAX_SENSORS]; 
NETWORK_T network;

char file_net_cfg[] = { 
  "config/net.cfg"};
char file_sensors_cfg[] = { 
  "config/sensors.cfg"};

boolean from_eeprom = false;

//*************************************//
//FUNCTION FOR EEPROM DEBUG           //
//***********************************//
/*void read_eeprom()
{
  for (int a = 20; a < 38; a++)
  {
    byte eeread = EEPROM.read(a);
    Serial.print("EEPROM position: ");
    Serial.print(a);
    Serial.print(" contains ");
    Serial.println(eeread);
  }
}*/
//********************************//


//*************************************************************************//
//FUNCTION TO START NETWORK & IMPORT PARAMETERS IN STRUCTURE              //
//***********************************************************************//
void network_setup(char data[],boolean &eeprom )
{
  network.mac[0] = 0xA2;
  network.mac[1] = 0xDA;
  network.mac[2] = 0x00;
  network.mac[3] = 0x22;
  network.mac[4] = 0x27;
  network.mac[5] = 0x90;
  Serial.print(F("Loading ethernet from "));
  if (!eeprom)
  {
      uint8_t a = 0;
      char* net_data = strtok(data,".");
      while(net_data)
      {
          if(a >= 0 && a < 4 )network.ip[a] = atoi(net_data);
          if(a >= 4 && a < 8)network.subnet[a-4] = atoi(net_data);
          if(a >= 8 && a < 12) network.gateway[a-8]= atoi(net_data);
          net_data = strtok(NULL,".");
          a++;
      }
      free(net_data);
      network.ip[4] = '\0';
      network.subnet[4] = '\0';
      network.gateway[4] = '\0';
      network.mac[6] =  '\0';
      Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
      Serial.println(F("OK"));
      Serial.print(F("IP: "));
      Serial.println(Ethernet.localIP()); 
      
  } else { 
    Serial.print(F("EEPROM: "));
    uint8_t arr_count = 0; //contatore per array variabili temporanee
    for (uint8_t a = 20; a < 32; a++)
    {
      if (arr_count == 4 && a < 32) arr_count = 0;
      if ((a-20) < 4) network.ip[arr_count] = EEPROM.read(a);
      if ((a-20) == 4 && (a-20) < 8) network.subnet[arr_count] = EEPROM.read(a);
      if ((a-20) == 8 && (a-20) < 12) network.gateway[arr_count] = EEPROM.read(a);
      arr_count++;
    }

    Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
    Serial.println(F("OK"));
  }
}
//**********************************************************************//



//*************************************************************************//
//FUNCTION TO IMPORT SENSORS PARAMETERS IN STRUCTURE                     //
//***********************************************************************//

void sensors_setup(char data[])
{
  Serial.print(F("Loading Sensors: "));    
      

      int line = 0;
      uint8_t row = 0;
      char* sensor_data = strtok(data,",");
      while(sensor_data)
      {
          if(row == 0)strcpy(sensor[line].index,sensor_data);
          /*if(row == 1)strcpy(sensor[line].pintype,sensor_data);
          if(row == 2)strcpy(sensor[line].pin,sensor_data);
          if(row == 3)strcpy(sensor[line].model,sensor_data);
          if(row == 4)strcpy(sensor[line].address,sensor_data);
          if(row == 5) {
            strcpy(sensor[line].description,sensor_data);
            line++;
          }*/
          sensor_data = strtok(NULL,",");
          row++;
      }
      Serial.println(F("OK"));
      free(sensor_data); 
     
}
//**********************************************************************//


//*************************************************************************//
//FUNCTION TO READ DATA FROM FILE IN SD                                   //
//***********************************************************************//
void file_read(char data[], char path[]){
File file_to_read;
file_to_read = SD.open(path, FILE_READ);
if (file_to_read){
      uint8_t index = 0;
      int lastread;
      while (file_to_read.available())
      {
          lastread = file_to_read.read(); //read 1 byte in cicle
          data[index] = lastread;
          index++;
      }
      data[index] = '\0';
      file_to_read.close();
    } else {
      Serial.println(F("error reading file"));
    }
}

void setup() {
  Serial.begin(19200);
  Wire.begin();
  boolean sd_start = SD.begin(4);
  char sd_tmpdata[250];
  if(sd_start) {
      file_read(sd_tmpdata, file_sensors_cfg);
      sensors_setup(sd_tmpdata);
      file_read(sd_tmpdata,file_net_cfg);
      network_setup(sd_tmpdata,from_eeprom);
  }  else {
      from_eeprom = true;
     // network_setup(netcfg,from_eeprom);
  } 
}  


void loop(){

}

The problem is in sensors_setup() function, when i try to copy string to struct element arduino, arduino crash and there is no output! There are a problems with strcpy() and array of structure?

      free(sensor_data);

The strtok() function does not do any dynamic memory allocation, so there is nothing to free.

void sensors_setup(char data[])
{
Serial.print(F("Loading Sensors: "));
Serial.print("Input data: ");
Serial.print(data);
Serial.println("]");

while(sensor_data)
{
Serial.print("Token: [");
Serial.print(sensor_data);
Serial.println("]");
if(row == 0)strcpy(sensor[line].index,sensor_data);

Add the highlighted code, and show what gets written to the serial monitor.

I added the code above, but serial console not return anything!If i comment out the line

sensors_setup(sd_tmpdata);

from setup() function or comment out the line

if(row == 0)strcpy(sensor[line].index,sensor_data);

serial console return this:

Loading ethernet from SD: OK
IP: 192.168.1.20

It's two day that i try and retry :frowning:

If i comment out the line ... from setup() function or comment out the line ... serial console return this:

If there is nothing printed by

  Serial.print("Input data: ");
  Serial.print(data);
  Serial.println("]");

then the sensors_setup() function did not get called. So, what it does can not be the source of the Arduino crashing. You need to add more Serial.print() stuff to see where in the program it is actually getting to.

For instance, what really is read from the file?
What does sd_tmpdata contain when file_read is done?

With this code in sensors_setup()

void sensors_setup(char data[])
{
      Serial.println(F("Loading Sensors: "));    
      Serial.print("Input data: ");
      Serial.print(data);
      Serial.println("]");
      int line = 0;
      uint8_t row = 0;
      //char* sensor_data = strtok(data,",");
      /*while(sensor_data)
      {
          Serial.print("Token: [");
          Serial.print(sensor_data);
          Serial.println("]");
          if(row == 0)strcpy(sensor[line].index,sensor_data);
          if(row == 1)strcpy(sensor[line].pintype,sensor_data);
          if(row == 2)strcpy(sensor[line].pin,sensor_data);
          if(row == 3)strcpy(sensor[line].model,sensor_data);
          if(row == 4)strcpy(sensor[line].address,sensor_data);
          if(row == 5) {
            strcpy(sensor[line].description,sensor_data);
            line++;
          }
          sensor_data = strtok(NULL,",");
          row++;
      }*/
      Serial.println(F("OK"));
}

the result is:

Loading Sensors:
Input data: 0,D,12,DS18B20,0,Sensore_temperatura_esterno
1,I,8,TMP102,72,sensore_temperatura_interno
2,A,0,MQ5,0,Sensore_GAS_cucina
3,W,7,DHT11,0,Sensore_temp-unidita_camera
4,A,1,CTSENSOR,0,Sensore_consumi]
OK
Loading ethernet from SD: OK
IP: 192.168.1.20

I'have no idea why arduino crash. Is there another way to debug?

In setup(), you have this:

  if(sd_start) {
      file_read(sd_tmpdata, file_sensors_cfg);
      sensors_setup(sd_tmpdata);
      file_read(sd_tmpdata,file_net_cfg);
      network_setup(sd_tmpdata,from_eeprom);
  }

This part:

      file_read(sd_tmpdata, file_sensors_cfg);
      sensors_setup(sd_tmpdata);

results in this output:

Loading Sensors:
Input data: 0,D,12,DS18B20,0,Sensore_temperatura_esterno
1,I,8,TMP102,72,sensore_temperatura_interno
2,A,0,MQ5,0,Sensore_GAS_cucina
3,W,7,DHT11,0,Sensore_temp-unidita_camera
4,A,1,CTSENSOR,0,Sensore_consumi]
OK

This part:

      file_read(sd_tmpdata,file_net_cfg);
      network_setup(sd_tmpdata,from_eeprom);

results in this output:

Loading ethernet from SD: OK
IP: 192.168.1.20

There is nothing else in setup(), so setup ends.

Your loop() function looks like:

void loop(){

}

Your Arduino hasn't crashed. You just haven't given it anything more to do!

If i comment out the the following line, Arduino work correctly and Serial console output is right

//char* sensor_data = strtok(data,",");
      /*while(sensor_data)
      {
          Serial.print("Token: [");
          Serial.print(sensor_data);
          Serial.println("]");
          if(row == 0)strcpy(sensor[line].index,sensor_data);
          if(row == 1)strcpy(sensor[line].pintype,sensor_data);
          if(row == 2)strcpy(sensor[line].pin,sensor_data);
          if(row == 3)strcpy(sensor[line].model,sensor_data);
          if(row == 4)strcpy(sensor[line].address,sensor_data);
          if(row == 5) {
            strcpy(sensor[line].description,sensor_data);
            line++;
          }
          sensor_data = strtok(NULL,",");
          row++;
      }*/

I'm sure that Arduino crashes when i operate with strcpy() and struct array! Could be ide 1.0 problem? Same problem declaring bidimensional array and pass it to strcpy() function.

//char* sensor_data = strtok(data,",");

What does sensor_data contain initially, if not commented?

If i comment out the the following line, Arduino work correctly and Serial console output is right

What does this mean? You haven't given the Arduino anything to do, unless you have changed the code and not posted new code.

I'm sure that Arduino crashes when i operate with strcpy() and struct array!

Proof? What evidence do you have that the Arduino is not behaving correctly? You haven't posted anything to back up this claim.

Could be ide 1.0 problem? Same problem declaring bidimensional array and pass it to strcpy() function.

No.

So, this is the situation. The fallowing code run correctly :

#include <EEPROM.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <OneWire.h>

#define MAX_SENSORS 5

typedef struct{
  char index[2];
  char pintype[3];
  char pin[2];
  char model[11];
  char address[11];
  char description[31];
}SENSORS_T;

typedef struct{
  byte ip[4];
  byte subnet[4];
  byte gateway[4];
  byte mac[6];
} NETWORK_T;

SENSORS_T sensor[MAX_SENSORS]; 
NETWORK_T network;

char file_net_cfg[] = { 
  "config/net.cfg"};
char file_sensors_cfg[] = { 
  "config/sensors.cfg"};

boolean from_eeprom = false;


//*************************************************************************//
//FUNCTION TO START NETWORK & IMPORT PARAMETERS IN STRUCTURE              //
//***********************************************************************//
void network_setup(char data[],boolean &eeprom )
{
  network.mac[0] = 0xA2;
  network.mac[1] = 0xDA;
  network.mac[2] = 0x00;
  network.mac[3] = 0x22;
  network.mac[4] = 0x27;
  network.mac[5] = 0x90;
  Serial.print(F("Loading ethernet from "));
  if (!eeprom)
  {
      uint8_t a = 0;
      char* net_data = strtok(data,".");
      Serial.print(F("SD: "));
      while(net_data)
      {
          if(a >= 0 && a < 4 )network.ip[a] = atoi(net_data);
          if(a >= 4 && a < 8)network.subnet[a-4] = atoi(net_data);
          if(a >= 8 && a < 12) network.gateway[a-8]= atoi(net_data);
          net_data = strtok(NULL,".");
          a++;
      }
      network.ip[4] = '\0';
      network.subnet[4] = '\0';
      network.gateway[4] = '\0';
      network.mac[6] =  '\0';
      Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
      Serial.println(F("OK"));
      Serial.print(F("IP: "));
      Serial.println(Ethernet.localIP()); 
      
  } else { 
    Serial.print(F("EEPROM: "));
    uint8_t arr_count = 0; //contatore per array variabili temporanee
    for (uint8_t a = 20; a < 32; a++)
    {
      if (arr_count == 4 && a < 32) arr_count = 0;
      if ((a-20) < 4) network.ip[arr_count] = EEPROM.read(a);
      if ((a-20) == 4 && (a-20) < 8) network.subnet[arr_count] = EEPROM.read(a);
      if ((a-20) == 8 && (a-20) < 12) network.gateway[arr_count] = EEPROM.read(a);
      arr_count++;
    }

    Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
    Serial.println(F("OK"));
  }
}
//**********************************************************************//



//*************************************************************************//
//FUNCTION TO IMPORT SENSORS PARAMETERS IN STRUCTURE                     //
//***********************************************************************//

void sensors_setup(char data[])
{
      Serial.println(F("Loading Sensors: "));    
      Serial.print("Input data: ");
      Serial.print(data);
      Serial.println("]");
      int line = 0;
      uint8_t row = 0;
      char* sensor_data = strtok(data,",");
      while(sensor_data)
      {
          Serial.print("Token: [");
          Serial.print(sensor_data);
          Serial.println("]");
          sensor_data = strtok(NULL,",");
          row++;
      }
      Serial.println(F("OK"));
     
}
//**********************************************************************//


//*************************************************************************//
//FUNCTION TO READ DATA FROM FILE IN SD                                   //
//***********************************************************************//
void file_read(char data[], char path[]){
File file_to_read;
file_to_read = SD.open(path, FILE_READ);
if (file_to_read){
      uint8_t index = 0;
      int lastread;
      while (file_to_read.available())
      {
          lastread = file_to_read.read(); //read 1 byte in cicle
          data[index] = lastread;
          index++;
      }
      data[index] = '\0';
      file_to_read.close();
    } else {
      Serial.println(F("error reading file"));
    }
}
//**********************************************************************//


void setup() {
  Serial.begin(19200);
  Wire.begin();
  boolean sd_start = SD.begin(4);
  char sd_tmpdata[250];
  if(sd_start) {
      file_read(sd_tmpdata, file_sensors_cfg);
      sensors_setup(sd_tmpdata);
      file_read(sd_tmpdata,file_net_cfg);
      network_setup(sd_tmpdata,from_eeprom);
  }  else {
      from_eeprom = true;
     network_setup(netcfg,from_eeprom);
  } 
}  


void loop(){

}

This is the serial output:

Loading Sensors: 
Input data: 0,D,12,DS18B20,0,Sensore_temperatura_esterno
1,I,8,TMP102,72,sensore_temperatura_interno
2,A,0,MQ5,0,Sensore_GAS_cucina
3,W,7,DHT11,0,Sensore_temp-unidita_camera
4,A,1,CTSENSOR,0,Sensore_consumi]
Token: [0]
Token: [D]
Token: [12]
Token: [DS18B20]
Token: [0]
Token: [Sensore_temperatura_esterno
1]
Token: [I]
Token: [8]
Token: [TMP102]
Token: [72]
Token: [sensore_temperatura_interno
2]
Token: [A]
Token: [0]
Token: [MQ5]
Token: [0]
Token: [Sensore_GAS_cucina
3]
Token: [W]
Token: [7]
Token: [DHT11]
Token: [0]
Token: [Sensore_temp-unidita_camera
4]
Token: [A]
Token: [1]
Token: [CTSENSOR]
Token: [0]
Token: [Sensore_consumi]
OK
Loading ethernet from SD: OK
IP: 192.168.1.20

But, if i add line with strcpy(), Arduino crash. This is the code:

...........

//*************************************************************************//
//FUNCTION TO IMPORT SENSORS PARAMETERS IN STRUCTURE                     //
//***********************************************************************//

void sensors_setup(char data[])
{
      Serial.println(F("Loading Sensors: "));    
      Serial.print("Input data: ");
      Serial.print(data);
      Serial.println("]");
      int line = 0;
      uint8_t row = 0;
      char* sensor_data = strtok(data,",");
      while(sensor_data)
      {
          Serial.print("Token: [");
          Serial.print(sensor_data);
          Serial.println("]");
          if(row == 0)strcpy(sensor[line].index,sensor_data); //with this line Arduino crash
          sensor_data = strtok(NULL,",");
          row++;
      }
      Serial.println(F("OK"));
     
}
//**********************************************************************//

.............

With this code..........no output from serial console. Where's the error?! Why the strcpy makes arduino crashes? I have no idea how to solve this problem!PLEASE HELP ME :frowning:

With this code..........no output from serial console. Where's the error?! Why the strcpy makes arduino crashes? I have no idea how to solve this problem!PLEASE HELP ME

Your debug output is telling you what at least part of the problem is.

Token: [Sensore_temperatura_esterno
1]

Does that look right to you?

You are assuming that every token ends with a comma, and that is not the case. The strtok() function takes a string, not a char, as the 2nd argument, and looks for a token that ends with one of the characters in the string. So, your string of delimiters should be ",\n", not ",".

With the strcpy() call uncommented, are you saying that you get NO serial output?

I fixed the code by adding ",\n\r" to sensors_setup() and ".\n\r" to network_setup()!! Thanks PaulS :slight_smile:

With the strcpy() call uncommented, are you saying that you get NO serial output?

Even with the code fixed, with strcpy() uncommented there isn't output from serial and the Arduino led remain on!!! Here the fixed code:

#include <EEPROM.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <OneWire.h>

#define MAX_SENSORS 5

typedef struct{
  char index[2];
  char pintype[3];
  char pin[2];
  char model[11];
  char address[11];
  char description[31];
}SENSORS_T;

typedef struct{
  byte ip[4];
  byte subnet[4];
  byte gateway[4];
  byte mac[6];
} NETWORK_T;

SENSORS_T sensor[MAX_SENSORS]; 
NETWORK_T network;

char file_net_cfg[] = { 
  "config/net.cfg"};
char file_sensors_cfg[] = { 
  "config/sensors.cfg"};

boolean from_eeprom = false;

//*************************************//
//FUNCTION FOR EEPROM DEBUG           //
//***********************************//
/*void read_eeprom()
{
  for (int a = 20; a < 38; a++)
  {
    byte eeread = EEPROM.read(a);
    Serial.print("EEPROM position: ");
    Serial.print(a);
    Serial.print(" contains ");
    Serial.println(eeread);
  }
}*/
//********************************//


//*************************************************************************//
//FUNCTION TO START NETWORK & IMPORT PARAMETERS IN STRUCTURE              //
//***********************************************************************//
void network_setup(char data[],boolean &eeprom )
{
  network.mac[0] = 0xA2;
  network.mac[1] = 0xDA;
  network.mac[2] = 0x00;
  network.mac[3] = 0x22;
  network.mac[4] = 0x27;
  network.mac[5] = 0x90;
  Serial.print(F("Loading ethernet from "));
  if (!eeprom)
  {
      uint8_t a = 0;
      char* net_data = strtok(data,".\n\r");
      Serial.print(F("SD: "));
     while(net_data)
      {
          if(a >= 0 && a < 4 )network.ip[a] = atoi(net_data);
          if(a >= 4 && a < 8)network.subnet[a-4] = atoi(net_data);
          if(a >= 8 && a < 12) network.gateway[a-8]= atoi(net_data);
          net_data = strtok(NULL,".\n\r");
          a++;
      }
      network.ip[4] = '\0';
      network.subnet[4] = '\0';
      network.gateway[4] = '\0';
      network.mac[6] =  '\0';
      Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
      Serial.println(F("OK"));
      Serial.print(F("IP: "));
      Serial.println(Ethernet.localIP()); 
      
  } else { 
    Serial.print(F("EEPROM: "));
    uint8_t arr_count = 0; //contatore per array variabili temporanee
    for (uint8_t a = 20; a < 32; a++)
    {
      if (arr_count == 4 && a < 32) arr_count = 0;
      if ((a-20) < 4) network.ip[arr_count] = EEPROM.read(a);
      if ((a-20) == 4 && (a-20) < 8) network.subnet[arr_count] = EEPROM.read(a);
      if ((a-20) == 8 && (a-20) < 12) network.gateway[arr_count] = EEPROM.read(a);
      arr_count++;
    }

    Ethernet.begin(network.mac, network.ip, network.gateway, network.subnet);
    Serial.println(F("OK"));
  }
}
//**********************************************************************//



//*************************************************************************//
//FUNCTION TO IMPORT SENSORS PARAMETERS IN STRUCTURE                     //
//***********************************************************************//

void sensors_setup(char data[])
{
      Serial.println(F("Loading Sensors: "));    
      Serial.print("Input data: ");
      Serial.print(data);
      Serial.println("]");
      int line = 1;
      int row = 0;
      char* sensor_data = strtok(data,",\n\r");
     while(sensor_data)
      {
          Serial.print("Token: [");
          Serial.print(sensor_data);
          Serial.println("]");
          if(row == 0)strcpy(sensor[line].index,sensor_data); //with this line Arduino crash and no output from console
          sensor_data = strtok(NULL,",\n\r");
          row++;
      }
      Serial.println(F("OK"));
     
}
//**********************************************************************//


//*************************************************************************//
//FUNCTION TO READ DATA FROM FILE IN SD                                   //
//***********************************************************************//
void file_read(char data[], char path[]){
File file_to_read;
file_to_read = SD.open(path, FILE_READ);
if (file_to_read){
      uint8_t index = 0;
      int lastread;
      while (file_to_read.available())
      {
          lastread = file_to_read.read(); //read 1 byte in cicle
          data[index] = lastread;
          index++;
      }
      data[index] = '\0';
      file_to_read.close();
      Serial.println("file reading");
    } else {
      Serial.println(F("error reading file"));
    }
}
//**********************************************************************//


void setup() {
  Serial.begin(19200);
  Wire.begin();
  boolean sd_start = SD.begin(4);
  char ip_tmpdata[50];
  char sens_tmpdata[250];
  
  if(sd_start) {
      file_read(sens_tmpdata, file_sensors_cfg);
      sensors_setup(sens_tmpdata);
      file_read(ip_tmpdata,file_net_cfg);
      network_setup(ip_tmpdata,from_eeprom);
  }  else {
      from_eeprom = true;
      network_setup(ip_tmpdata,from_eeprom);
  } 
}  


void loop(){

}

without line

if(row == 0)strcpy(sensor[line].index,sensor_data); //with this line Arduino crash and no output from console

The output is:

file reading
Loading Sensors: 
Input data: 0,D,12,DS18B20,0,Sensore_temperatura_esterno,
1,I,8,TMP102,72,sensore_temperatura_interno,
2,A,0,MQ5,0,Sensore_GAS_cucina,
3,W,7,DHT11,0,Sensore_temp-unidita_camera,
4,A,1,CTSENSOR,0,Sensore_consumi,]
Token: [0]
Token: [D]
Token: [12]
Token: [DS18B20]
Token: [0]
Token: [Sensore_temperatura_esterno]
Token: [1]
Token: [I]
Token: [8]
Token: [TMP102]
Token: [72]
Token: [sensore_temperatura_interno]
Token: [2]
Token: [A]
Token: [0]
Token: [MQ5]
Token: [0]
Token: [Sensore_GAS_cucina]
Token: [3]
Token: [W]
Token: [7]
Token: [DHT11]
Token: [0]
Token: [Sensore_temp-unidita_camera]
Token: [4]
Token: [A]
Token: [1]
Token: [CTSENSOR]
Token: [0]
Token: [Sensore_consumi]
OK
file reading
Loading ethernet from SD: OK
IP: 192.168.1.20