2

I'm trying to create a simple application that stores a struct in the EEPROM memory and on startup it reads the stored struct from the EEPROM and then executes the rest based on the stored data.

This is my main ino file:

extern "C" {
    #include "Structs.h"
}

Settings settings;

void setup()
{
    settings = settings_read();
}

void loop()
{

  /* add main program code here */

}

This is the Structs.h file:

#ifndef _STRUCTS_h
#define _STRUCTS_h

#if defined(ARDUINO) && ARDUINO >= 100
    #include "arduino.h"
#else
    #include "WProgram.h"
#endif

typedef struct {
    byte lastCountry;
    byte lastMode;
} Settings;

#endif

This is the Settings.ino file:

#include <EEPROM.h>

Settings settings_read() {
    byte country, mode;
    Settings settings;

    country = EEPROM.read(0);
    mode = EEPROM.read(1);

    settings = {
        country,
        mode
    };

    return settings;
}

This is the compiler error:

Compiling 'Stoplicht' for 'Arduino Uno'
Stoplicht.ino:5:1: error: 'Settings' does not name a type
Stoplicht.ino:In function 'void setup()'
Stoplicht.ino:9:27: error: 'settings_read' was not declared in this scope
Error compiling

I tried a lot of different things to get this to work. I tried putting the code from Settings.ino into a .C file. That gave more error's and it said the EEPROM.h function were not declared. I also tried putting the struct and settings_read into Settings.ino that gave even more errors. I'm completely new to C, I just can't find what I'm doing wrong here.

Feanaro
  • 922
  • 3
  • 19
  • 35
  • Maybe there ? http://stackoverflow.com/questions/21409042/correct-way-to-include-cpp-and-h-files-in-an-arduino-sketch – Michel Billaud Jun 01 '15 at 20:01
  • The accepted answer is not applicable to my code. I already include the necessary header files like `Arduino.h`. But thank you for the reference! – Feanaro Jun 01 '15 at 20:54
  • The Settings.ino file must include `Settings.h`, as `.ino` files are compiled separately, and Setting.ino refers to the Settings type. – Michel Billaud Jun 02 '15 at 06:43

2 Answers2

2

As I said in a comment, the langage de prédilection for Arduino is C++, not C.

So is seems a good idea to comply to the C++ way of structuring your applications. Forget the C way which often consists of workarounds for the lack of adequate mechanisms for clean programming in C. (not that C++ is perfect...).

So I restructured your sample code, which now shows how to define and use a library for the Settings type.

First start from the main ino file

// StopLicht.ino

#include "Settings.h"

Settings settings;

void setup()
{
   settings.read(); // doing it the OO way
}

void loop()
{
   // code here. does some stuff with 
   // settings.mode and settings.country
}

The Settings type is defined as a struct with 2 fields, and (here comes C++) a member function read() which acts on Settings :

// Settings.h

#ifndef SETTINGS_H_INCLUDED
#define SETTINGS_H_INCLUDED

struct Settings 
{
  byte country; 
  byte mode;

  void read();   // to get values from EEPROM
};

#endif

And it is implemented in an ino file

// Settings.ino

#include <EEPROM.h>

#include "Settings.h"

void Settings::read() 
{
     country = EEPROM.read(0);
     mode    = EEPROM.read(1);
};

Remark: Settings could of course be written as a class instead of a struct. Not a big deal in this case.

Michel Billaud
  • 1,758
  • 11
  • 14
1

It's "Arduino.h", not "arduino.h" so you should change the lines to:

#ifndef _STRUCTS_h
#define _STRUCTS_h

#if defined(ARDUINO) && ARDUINO >= 100
    #include "Arduino.h"
#else
    #include "WProgram.h"
#endif

typedef struct {
    byte lastCountry;
    byte lastMode;
} Settings;

#endif

The next problem is your awkward include syntax?! I don't know this extern "C" stuff, but it should work by simply using:

#include "Structs.h"

without any boilder plate.

Just as a tip, when working with multiple files Arduino IDE, it's missing autocomplete and its *.ino garbage will get your project messy and ensure you to get compile problems from time to time. For multifile projects i would recommend using biicode(http://docs.biicode.com/arduino/gettingstarted.html) with default c/++.

Lukasstr
  • 435
  • 2
  • 19
  • Despite a rather common belief, the usual language on Arduino is not a modified C, but C++ (with a restricted "standard" library, no dynamic allocation etc). So better drop some C-isms, you don't need `typedef` to name structs, for example. After a declaration like `struct Settings { ....}`, the name `Settings` is a type name. – Michel Billaud Jun 02 '15 at 06:26