arduino,使用SD配置文件中的数据设置以太网和网络

问题描述 投票:0回答:1

我尝试将动态方式添加到我的草图中,以从配置文件(config.txt)设置以太网信息(mac,ip,网关,子网)。因此,运行网络服务器并从sd卡提供htm文件,用户可以转到设置页面,用这些信息填写表单,并在发布时,网络服务器解析http表单并保存(更新)config.txt文件。在该系统重新启动之后,为了开始新的设置(通过读取config.txt文件)

我已经通过读取config.txt文件成功创建了除获取参数之外的所有部分(sd,以太网,web服务器,webclient,从发布的表单数据创建配置文件)。

我可以逐行读取配置,我可以将行拆分为参数和值,现在我需要用读取的数据填充一些字节变量。我可以(经过一个月的Google搜索)将IP(十进制值)读取到字节数组。 Im堆栈将MAC ADDRESS十六进制读取为字节数组。配置文件包含:

mac=8f:2c:2b:19:e0:b7;
ip=192.168.1.200;
netmask=255.255.255.0;
gateway=192.168.1.254;
dns=8.8.8.8;
posturl=192.168.1.157;
postport=8080;
postscript=/itherm/update.php;
interval=60000;

和我用来阅读的代码是:

byte myMAC[6];
byte myIP[4];

  File fset;
  fset = SD.open("config.txt");
  if (fset){
    char ff[40];
    while (fset.available()>1){
      bool eol=false;
      for (int i=0; !eol;i++){
        ff[i]=fset.read();
        if (ff[i]=='\n'){
           eol=true;
        }
      }
      String par="";
      bool DONE=false;
      for (int i=0; !DONE;i++){
        par+=ff[i];
        if (ff[i]== '='){DONE=true;}
      }
      String pval="";
      DONE=false;
//------------------------

      if (par=="ip=" ){
        int x=0;
        while(!DONE){
          for(int i=3;i<=i+21;i++){
            if(ff[i]=='.'){
              myIP[x]=pval.toInt();
              x++;
              i++;
              pval="";
            }
            else if(ff[i]==';' || i>20){
              myIP[x]=pval.toInt();
              DONE=true;
              break;
            }
            pval+=ff[i];
          }
        }
      }

    } //while (fset.available()>1)
  } //if (fset)

我将不胜感激。简单使用Serial.print(),请不要回答。我发现了数百条建议,但没有一条可以正常读取所有参数(十进制,十六进制,字符串)。经过一个月的努力和搜索,我想知道为什么社区中不存在如此必要和有用的东西,它们完全可以正常工作!

最诚挚的问候

arduino config ethernet sd-card
1个回答
0
投票

好的,这是一整套完成所需操作的例程-我认为您误解了char数组与单个char [0]的概念。这些例程已记录在案并且具有自我解释性。我建议不要用完结;但是在您的示例中仍然存在“ \ n”(您也看不到换行符)要获取mac地址,我需要三行:

  if (strncmp(cfgLine, "mac=", 4) == 0) {
    strcpy (macAddr, cfgLine + 4);
  }

第一行比较前4个字符,如果为0(表示适合)第二行将第5个字符从lineBuffer的最后一个字符复制到目标数组,该数组实际上可以用作函数的参数。文件结构应为no;就像你必须解析的一样;和\ n

mac=8f:2c:2b:19:e0:b7
ip=192.168.1.200
....
postport=8080

[将char数组转换为int,我们使用atoi(),将单个char [0]转换为单个数字,我们使用int singleDigit = char [0] -48;

const char configurationFilePath [] = "/someconfig.txt";
char cfgLine[128] = {'\0'};  // this is a global temp char array to hold the read lines (lenght= chars longest line +1)
char numBuffer[16] = {'\0'};  // this is a global temo char array to help to convert char to number

char macAddr [18] =  {'\0'};  // this is a global char array to hold the mac address
char ipAddr [16] =  {'\0'};  // this is a global char array to hold the IP address - max xxx.xxx.xxx.xxx
int postport=0;
// .... you can easyly implement for all other data you want to store/retrieve

// Counts the lines of a file 
uint16_t countLines() {
  uint16_t currentLineCount = 0;
  File cfgFile = SD.open(configurationFilePath, "r");
  if (!cfgFile) {
    Serial.println(F("Config file open failed on read"));
  } else {
    while (cfgFile.available()) {
      /** Lets read line by line from the file */
      if (cfgFile.read() == '\n') currentLineCount ++; // Lines are delimited by '\n'
    }
    cfgFile.close();
  }
  return currentLineCount;
}

//Load the config file from SD/SPIFFS/LittleFS
bool loadConfigFile() {
  uint16_t lineCounter = countLines();
  if (lineCounter <= 0)  {
    Serial.print(F("No config data stored in file ")); Serial.println(configurationFilePath);
    return false;
  }
  else {
    File cfgFile = SD.open(configurationFilePath, "r");
    while (cfgFile.available()) {
      strcpy (cfgLine, (cfgFile.readStringUntil('\n').c_str()));  // normaly you use new line, we copy one line at a time
//      Serial.println(cfgLine); /** Printing for debuging purpose */
      while (cfgLine[0] != '\0') { /* Block refilling of cfgLine till processed */
        loadSingleCfgLine();
      }
    }
    cfgFile.close();
    Serial.println(F("[Success] Loaded config !"));
    return true;
  }
}
//Load the data of a single line into a char array
void loadSingleCfgLine() {
  if (strncmp(cfgLine, "mac=", 4) == 0) {
    strcpy (macAddr, cfgLine + 4);
  }
  if (strncmp(cfgLine, "ip=", 3) == 0) {
    strcpy (ipAddr, cfgLine + 3);
  }
  if (strncmp(cfgLine, "postport=", 9) == 0) {
    strcpy (numBuffer, cfgLine + 9);
    postport = atoi(numBuffer); // One extra step to convert to int
  }

// ... easy to implement for all other data
}

我将例程划分为小的独立函数,因此它很容易适应不同的用途。很抱歉,我不深入您的代码,因为它很难遵循并且不清楚您想做什么。

© www.soinside.com 2019 - 2024. All rights reserved.