EthernetShield V1 über INI Datei konfigurieren

Hallo Leute,

versuche gerade ein EthernetShield V1 über eine INI Datei zu konfigurieren.

Nutze Datei die Library stevemarple INiFile.
Die ini ist wie in Example konfiguriert und wird auch korrekt ausgelesen.

Bei der Zuweisung für die MAC Koniguration und bei aktiviertem DHCP bekommt der Adurino eine IP vom DHCP.

Wenn ich aber versuche eine feste IP zu vergeben, wird das Ethernet nicht konfiguriert. Ich weis auch, das es an der Zuweisung der festen IP liegt.

Ich schaffe es einfach nicht, die IP die als char / String in folgenden Format vorliegt in ein Byte Array umzuwandeln. Viele ansätze die ich im Netz gefunden habe, haben mich leider nicht weiter gebracht.

// default includes
#include <Arduino.h>
#include <SPI.h>

// include for SD Card and INI File
#include <SD.h>
#include <IniFile.h>
// #include <SDConfigFile.h>


// Ethernet shield 
// Used by Classes in 01-Network.ino & 03-UDPState.ino
#include <Ethernet.h>
#include <EthernetUdp.h>

// SQLConnection
// Used in Classes in ....
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

// Definitions

#define errorPin 11

// Configs from config.ini

char *MAC;                                        // MAC address
char *lclIP;                                      // IP address
char *lclMask;                                    // Subnet Mask
char *lclGateway;                                 // Gateway
boolean lclDHCP;                                  // DHCP true or false
EthernetServer server(80);

boolean UDP_actived;                              // UDP true or false
unsigned int UDP_local_port;                      // UDP Port for client
IPAddress UDP_server();                           // UDP destination server
unsigned int UDP_dest_port;                       // UDP destination port

boolean SQL_actived;                              // MySQL logging true or false
char *SQL_user;                                   // MySQL username
char *SQL_pwd;                                    // MySQL password
IPAddress SQL_server();                           // MySQL server
unsigned int SQL_port                             // MySQL port

char *DHT_typ;
unsigned int DHT_pin;


// The filename of the configuration file on the SD card
const char CONFIG_FILE[] = "options.ini";
const int pinSelectSD = 4; // SD shield Chip Select pin.
boolean didReadConfig;

/*
 * Function for Fatal Error 
 * Programm stops and the Error LED blinking
 */
void FATALERROR(byte errorCode)
{  
  switch (errorCode)
    {
      case 1:
        {
          Serial.println("FATAL ERROR: Can't open SD card - SYSTEM HALTING");
          break;
        }
      case 2:
        {
          Serial.println("FATAL ERROR: Can't read config file - SYSTEM HALTING");
          break;
        }
      default:
          break;
    }
  while (1)
    {
      digitalWrite(errorPin, HIGH);
      delay(500);
      digitalWrite(errorPin, LOW);
      delay(500);
    }  
}

void printErrorMessage(uint8_t e, bool eol = true)
{
  switch (e) {
  case IniFile::errorNoError:
    Serial.print("no error");
    break;
  case IniFile::errorFileNotFound:
    Serial.print("file not found");
    break;
  case IniFile::errorFileNotOpen:
    Serial.print("file not open");
    break;
  case IniFile::errorBufferTooSmall:
    Serial.print("buffer too small");
    break;
  case IniFile::errorSeekError:
    Serial.print("seek error");
    break;
  case IniFile::errorSectionNotFound:
    Serial.print("section not found");
    break;
  case IniFile::errorKeyNotFound:
    Serial.print("key not found");
    break;
  case IniFile::errorEndOfFile:
    Serial.print("end of file");
    break;
  case IniFile::errorUnknownError:
    Serial.print("unknown error");
    break;
  default:
    Serial.print("unknown error value");
    break;
  }
  if (eol)
    Serial.println();
}


byte getIP(String ipStr)
{
  String myString = ipStr;
  Serial.println(myString);
  byte myByteArray[4];
  myString.getBytes(myByteArray,4);
  return myByteArray;

/*
  const char* _ipStr = ipStr;
  byte ip[4];
  parseBytes(ipStr, '.', ip, 4, 10); 
*/
}

boolean readConfiguration()
{
  const size_t bufferLen = 80;
  char buffer[bufferLen];

  IniFile ini(CONFIG_FILE);
  if (!ini.open())
  {
    Serial.print("Ini file ");
    Serial.print(CONFIG_FILE);
    Serial.println(" does not exist");
    FATALERROR(2);
  }
  
  Serial.println("Ini file exists");

  // Check the file is valid. This can be used to warn if any lines
  // are longer than the buffer.
  if (!ini.validate(buffer, bufferLen))
  {
    Serial.print("ini file ");
    Serial.print(ini.getFilename());
    Serial.print(" not valid: ");
    printErrorMessage(ini.getError());
    // Cannot do anything else
    while (1)
      ;
  }

  // Fetch a value from a key which is present
  if (ini.getValue("network", "dhcp", buffer, bufferLen))
  {
    lclDHCP = buffer;
    if (!lclDHCP)
    {
      // read IP address
      if (ini.getValue("network", "ip", buffer, bufferLen)) 
      { lclIP = buffer; }
      else
      { printErrorMessage(ini.getError());}
      // read IP MASK
      if (ini.getValue("network", "mask", buffer, bufferLen)) 
      { lclMask = buffer; }
      else
      { printErrorMessage(ini.getError()); }
      // read GATWAY
      if (ini.getValue("network", "gateway", buffer, bufferLen)) 
      { lclGateway = buffer; }
      else
      { printErrorMessage(ini.getError()); }
    }
    if (ini.getValue("network", "mac", buffer, bufferLen)) 
    { MAC = buffer; }
    else
    { printErrorMessage(ini.getError()); }
  }
  

  return true;
}

void setup() 
{
  Serial.begin(9600);                               // Serial communication init
  Serial.println("Starting ....");
  pinMode (errorPin, OUTPUT);                       // Default pin for Error LED

  Serial.println(" ");
  Serial.println("Calling SD Card....");
  if (!SD.begin(pinSelectSD)) 
  {
    Serial.println("SD.begin() failed. Check: ");
    Serial.println("  card insertion,");
    Serial.println("  SD shield I/O pins and chip select,");
    Serial.println("  card formatting.");
    FATALERROR(1);
  }
  Serial.println("...succeeded.");

  SPI.begin();

  didReadConfig = readConfiguration();              // read the configuration from options.ini
  if (!didReadConfig)
  {
    FATALERROR(2);
  }
  else
  {
    Serial.println("Configuration reading was success full....");
  }

  if (lclDHCP)
  { 
    Ethernet.begin(MAC, lclIP, lclGateway, lclGateway, lclMask);
  }
  else 
  {
    Ethernet.begin(MAC);
  }
  server.begin();
  Serial.print("IP address is: ");
  Serial.println(Ethernet.localIP());

  Serial.print("Gatway address is: ");
  Serial.println(Ethernet.gatewayIP());

  Serial.print("Subnet Mask is: ");
  Serial.println(Ethernet.subnetMask());

  Serial.print("DNS IP address is: ");
  Serial.println(Ethernet.dnsServerIP());
}

void loop() 
{

}

Ich versuche in der Function:

byte getIP(String ipStr)
{
  String myString = ipStr;
  Serial.println(myString);
  byte myByteArray[4];
  myString.getBytes(myByteArray,4);
  return myByteArray;

/*
  const char* _ipStr = ipStr;
  byte ip[4];
  parseBytes(ipStr, '.', ip, 4, 10); 
*/
}

die IP in ein Byte umzuwandeln.

Nutze ich die

  • nicht auskommentierte Variante - bekomme ich zwar keine Fehlermeldung vom Compiler, aber das Shield wird nicht initialisiert.
  • auskommentierte Variante - bekomme ich einen Fehler vom Compiler, das parseBytes nicht declariert wurde.

Hier nach die ini Datei:

# Local Ethernet configuration

[network]

# MAC address generated by
dhcp = false
mac = 00:A5:75:EC:3F:90
ip = 192.168.178.240
gateway = 192.168.178.1
mask = 255.255.255.0




# UDP configuration

[UDP]

UDP_Active = true
UDP_Port = 8888
UDP_Server = 192.168.178.33



# MySQL configuration

[mySQL]

mySQL_Active = true
mySQL_Server = 192.168.178.23
mySQL_Port = 3306
mySQL_User = arduino
mySQL_Pwd = arduino



# different configuration

[misc]

DHT_Typ = DHT22
DHT_Pin = 2

:wink: Hat einer von euch eventuell eine Lösung für mich? Wäre dankbar.

Ansonsten eine frohes Weihnachtsfest für alle.

Die Klasse IPAddress kann das schon selbst. Die hat eine Methode fromString(...).

Kleiner Tip: Die Klasse String auf dem Arduino ist keine gute Wahl, da das nicht gut für dessen Speicher ist. Nimm lieber Chararrays.
Infos dazu gibt es hier.

Gruß Tommy

Edit: Deine Lib arbeitet auch mit char-Arrays ("buffer"). Schau Dir mal dort die Beispiele an.

Moin Tommy,

super das hat geholfen .fromString. Hab ich total übersehen. :o

Jetzt bekomme ich vom compiler nur noch folgende Warnungen.
Bekommt man die auch irgendwie weg.

C:\Projekts\Elektronik\Sketchbooks\kreatim_full\kreatim_full.ino: In function 'void setup()':

C:\Projekts\Elektronik\Sketchbooks\kreatim_full\kreatim_full.ino:238:25: warning: invalid conversion from 'char*' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

{ Ethernet.begin(MAC); }

^

In file included from C:\Projekts\Elektronik\Sketchbooks\libraries\IniFile-master\src/IniFile.h:11:0,

from C:\Projekts\Elektronik\Sketchbooks\kreatim_full\kreatim_full.ino:18:

C:\Program Files (x86)\Arduino\libraries\Ethernet\src/Ethernet.h:23:7: note: initializing argument 1 of 'int EthernetClass::begin(uint8_t*, long unsigned int, long unsigned int)'

int begin(uint8_t *mac_address, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);

^

C:\Projekts\Elektronik\Sketchbooks\kreatim_full\kreatim_full.ino:242:65: warning: invalid conversion from 'char*' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

Ethernet.begin(MAC, lclIP, lclGateway, lclGateway, lclMask);

^

In file included from C:\Projekts\Elektronik\Sketchbooks\libraries\IniFile-master\src/IniFile.h:11:0,

from C:\Projekts\Elektronik\Sketchbooks\kreatim_full\kreatim_full.ino:18:

C:\Program Files (x86)\Arduino\libraries\Ethernet\src/Ethernet.h:27:8: note: initializing argument 1 of 'void EthernetClass::begin(uint8_t*, IPAddress, IPAddress, IPAddress, IPAddress)'

void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);

^

Der Sketch verwendet 26352 Bytes (10%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 2019 Bytes (24%) des dynamischen Speichers, 6173 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.

Ansonsten finktioniert das jetzt, so wie ich mir das vorstelle.

Gruß ZHermann

Da musst Du noch ein paar Typen anpassen:

char ist mit Vorzeichen, uint8_t ist ohne (unsigned). Diese Umwandlung warnt der Kompiler an, da es dabei Informationsverluste geben kann.

Gruß Tommy

Edit: z.B. char *MAC; ändern in uint8_t *MAC;
Es kann aber dann sein, dass das aus Deiner Lib anders kommt.
Früher (TM) hat das den Kompiler nicht gestört. Er ist da kritischer geworden.
Deshalb sind ältere Libs / Codebeispiele dafür anfällig.