LoginSignup
3
0

More than 5 years have passed since last update.

Arduino IDEでのIniファイル読込

Last updated at Posted at 2018-05-10

ESP32やESP8266の小物を作っていると、WiFi導入部は毎回同じ記述になってきました。
しかし、サーバーアプリなどはhostnameを別物にしないと名前解決できません。
とは言えソースコードにhostnameを直接埋めると、混乱するし・・・・・
てなわけでinifile形式でデータを読み込むライブラリを作成しました。

必要な機能

 SPIFFS / FS等のファイルアクセスの設定
 FTPは推奨

使い方

ソースはこんな風にします。 

usage.ino
#include <fs.h>
#include <inifile.h>

const char *iniFileName = "\SETUP.ini";
const char *iniHeader = "HEADER";
unsigned char *stringData;
bool boolData;
int integerData;

void setup( void ){
  File fp = SPIFFS.open( iniFileName, "r" );
  stringData= inifileString( fp, (char *)iniHeader, "STRING", "default" );
  boolData= inifileBool( fp, (char *)iniHeader, "BOOL", true );
  integerData= inifileInteger( fp, (char *)iniHeader, "integer", -1 );
  fp.close();
}

データファイルはこんな風に作成します。

SETUP.ini
[HEADER]
STRING=stringdata
BOOL=false
integer=100

ソースコード

inifile.h
#ifndef INIFILE_H
#define INIFILE_H

#if defined(ESP8266)
#include <FS.h>
#else
#include <SPIFFS.h>
#endif
#include <string.h>

char *inifileString( File fp, char *header, char *detail, char *defaultData=NULL ){
int  position, length, index = 0;
char str[256], *output = NULL;
bool hit, headerHit = false;
  if( !fp ){
    return defaultData;
  }
  fp.seek( 0 );
#ifdef DEBUG
  Serial.print( header );  Serial.print( ":" );  Serial.print( detail );  Serial.print( ":" );
#endif
  while ( fp.available() ){
    str[index] = fp.read();
    if( !(str[index]==0x0d || str[index]==0x0a ) ){
      if( index!=255 )
        index++;
      continue;
    }
    str[index] = 0x00;
    if( str[0]=='[' ){
      if( strchr( str, ']' )!=NULL ){
        headerHit = false;
        for( int i=0 ; ; i++ ){
          if( header[i]==0 ){
            if( str[1+i]==']' )  headerHit = true;
            break;
          }
          if( toupper(str[1+i])!=toupper(header[i]) )  break;
        }
      }
    }
    if( headerHit==true ){
      char *strpos = strchr( str, '=' );
      if( strpos!=NULL ){
        position = (strpos - str);
        if( position==strlen( detail ) ){
          hit = true;
          for( int i=0 ; i<position ; i++ ){
            if( toupper(str[i])!=toupper(detail[i]) ){
              hit=false;
              break;
            }
          }
          if( hit==true ){
            length = strlen( &str[position+1] );
            if( output!=NULL )  free( output );
            output = (char *)malloc( length+1 );
            memcpy( output, &str[position+1], length );
            output[length] = 0;
            break;
          }
        }
      }
    }
    index = 0;
  }
  if( output==NULL ){
#ifdef DEBUG
    Serial.print( "(none)" );
#endif
    if( defaultData!=NULL ){
#ifdef DEBUG
      Serial.println( defaultData );
#endif
      output = (char*)malloc( strlen(defaultData)+1 );
      strcpy( output, defaultData );
    }
    return defaultData;
  }
#ifdef DEBUG
  Serial.println( output );
#endif
  return output;
}


int inifileInteger( File fp, char *header, char *detail, int defaultData=-1 ){
char *str = inifileString( fp, header, detail, NULL );
  if( str==NULL ){
#ifdef DEBUG
    Serial.println( defaultData );
#endif
    return defaultData;
  }
  int num = atoi( str );
  free( str );
  return num;
}


bool inifileBool( File fp, char *header, char *detail, bool defaultData=false ){
char *str = inifileString( fp, header, detail, NULL );
  if( str==NULL ){
#ifdef DEBUG
    Serial.println( defaultData );
#endif
    return defaultData;
  }
  int num = strcasecmp( str, "true" );
  free( str );
  return ( (num==0)?true:false );
}
#endif
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0