0

I am having an issue with passing an array into function which is contained in a library. I am using the Arduino IDE 16.7. If I pass a non-array/non-pointer variable than the code compiles fine. I think I have made a basic flaw with my addresses of pointers. But I am unable to see what it is

Here are the errors I am getting:

  • invalid conversion from 'char*' to 'uint8_t {aka unsigned char}' [-fpermissive]

  • initializing argument 2 of 'void EEPROMClass::write(int, uint8_t)' [-fpermissive]

Both of these errors are related to the EEPROM Arduino library I am using.

The compiler doesn't seem to agree with my passing of an array/pointer to the EEPROm library like this... Why?

H file:

#ifndef EEPROMAnyType_h
#define EEPROMAnyType_h

#include <Arduino.h>
#include <EEPROM.h>

template <class E> 
class EEPROMAnyType
{
    public:
        int EEPROMReadAny(unsigned int addr, E x); //Reads any type of variable EEPROM
        int EEPROMWriteAny(unsigned int addr, E x);//Writes any type of variable to EEPROM
//    EEPROMAnyType(unsigned int addr, E x);
};
//#include "EEPROMAnyType.cpp"
#endif

CPP file:

#include <Arduino.h>
#include <EEPROM.h>
#include "EEPROMAnyType.h"



template <class E>
int EEPROMAnyType<E>::EEPROMReadAny(unsigned int addr, E x) 
{
  union{
    byte b[sizeof(x)];
    E y;//generaltype y //have a variable that has no type here(using a tempplate???)
  };

  int i;
  x = x; //assign x to y( a variable of no type) which should be n the union
  y = x;
  for(i = 0; i < sizeof(y); i++){ // Why can I not declare i as an integer in the for loop?
    b[i] = EEPROM.read(addr+i);
  }
  return i;
}

template <class E>
int EEPROMAnyType<E>::EEPROMWriteAny(unsigned int addr, E x)
{
  union{
    byte b[sizeof(x)];
    E y;//generaltype y //have a variable that has no type here(using a tempplate???)
  };
  int i = 0;
  y = x;
  for(i = 0; i < sizeof(y); i++){
    EEPROM.write(addr+i, y);
  }
  return i;
}

INO file(implements the library):

#include <Arduino.h>
#include <EEPROM.h>
#include <EEPROMAnyType.h>
#include <EEPROMAnyType.cpp>
int addressCharArray;
const int writes = 80;
const int memBase = 350;
unsigned int eeaddrPASS;
unsigned int eeaddrSSID;
char eePASS[writes];
char eeSSID[writes];

EEPROMAnyType<char*> eepblueString;//instantiates EEPROMANyType class

boolean check = false;
void setup(){
  if (check = true){
    EEPROMwifiUpdate(eeaddrPASS, eeaddrSSID, eePASS, eeSSID);
  }
}
void loop(){
  EEPROMwifiRead(eeaddrPASS, eeaddrSSID, eePASS, eeSSID);
}

void EEPROMwifiUpdate(unsigned int writeaddrPASS, unsigned int writeaddrSSID, char writePASS[writes], char writeSSID[writes]){
  eepblueString.EEPROMWriteAny(writeaddrPASS, writePASS);
  eepblueString.EEPROMWriteAny(writeaddrSSID, writeSSID);
}

void EEPROMwifiRead(unsigned int readaddrPASS, unsigned int readaddrSSID, char readPASS[writes], char readSSID[writes]){
  eepblueString.EEPROMReadAny(readaddrPASS, readPASS);
  eepblueString.EEPROMReadAny(readaddrSSID, readSSID);
}
John B.
  • 15
  • 6

1 Answers1

0

In this call

for(i = 0; i < sizeof(y); i++){
  EEPROM.write(addr+i, y);
}

y is (if I'm not wrong) of type char[] (more or less char *) and the second argment of EEPROM.write() should be (according to the error message) a uint8_t (similar to a char)

I suppose you should write something like

for(i = 0; i < sizeof(y); ++i){
  EEPROM.write(addr+i, y[i]);
}

or (using the union)

for(i = 0; i < sizeof(b); ++i){
  EEPROM.write(addr+i, b[i]);
}

like in EEPROMReadAny().

Unrelated suggestion: taking in count that you confront it with an unsigned value (sizeof(y)), it's better if you define i (in EEPROMReadAny() and in EEPROMWriteAny()) unsigned or std::size_t.

p.s.: sorry for my bad English.

--- EDIT ---

Second question: error "invalid conversion from 'char*' to 'char' [-fpermissive] eepBLEtoothchar.EEPROMReadAny(readaddrSSID, readSSID);"

I don't understand this error, but... I see a couple of other problems.

I problem

You define eepblueString

 EEPROMAnyType<char*> eepblueString;

as a EEPROMAnyType<char*>. So, in EEPROMAnyType<E>, the type E is a char *. And sizeof(E) is 4 (or 8, if you are in a 64 bit platform).

When you pass readPASS and readSSID, they are char[80] so, I suppose, your intention is read 80 chars. But your object try to read only 4 (or 8) chars.

II problem

The second argument to EEPROMReadAny() is passed by value; so you can read 4 (or 8) chars but they are loose when you exit from the method. To save the readed chars, you should pass the second argument by reference.

You really need the EEPROMAnyType?

I mean: if EEPROMReadAny() can be a simple function, you can deduce the E type from the second argument, avoiding the first problem.

I propose the following solution (should solve the II problem to, passing the second argument by reference)

template <class E>
int EEReadAny (unsigned int add, E & x)
 {
   char * b = (char *)&x;

   for ( unsigned ui = 0U ; ui < sizeof(E) ; ++ui )
      b[ui] = EEPROM.read(addr+i);

   return sizeof(E);
 }
max66
  • 65,235
  • 10
  • 71
  • 111
  • great that fixes that issue, but I am getting a new error: invalid conversion from 'char*' to 'char' [-fpermissive] – John B. May 05 '16 at 06:07
  • Also I am getting this interesting error with just passing a String type through: - 'EEPROMAnyType::EEPROMReadAny(unsigned int, E) [with E = String]::::~()' is implicitly deleted because the default definition would be ill-formed: union{ – John B. May 05 '16 at 06:26
  • What does this mean? Can I even pass a String type? What is wrong with the constructor destrcutor? I know I have not initialized one but that should be initialized by itself anyway shouldn't it? – John B. May 05 '16 at 06:27
  • About the "invalid conversion from 'char*' to 'char'", I suppose there is another point with a similar problem of conversion; you shoul show us the full message to understand where the problem is and the relative code. About the problem, a `std::string` is illegal in a C++ union pre C++11 (and dangerous in C++11/C++14); give a look, for this, at http://stackoverflow.com/questions/37002058/compiling-error-when-passing-an-array-pointers-into-a-procedure-in-a-library/37002253?noredirect=1#comment61636284_37002253 – max66 May 05 '16 at 11:26
  • Here is where theconversion error is happening: invalid conversion from 'char*' to 'char' [-fpermissive] eepBLEtoothchar.EEPROMReadAny(readaddrSSID, readSSID); – John B. May 05 '16 at 12:52
  • Yes I have found some sources on this. Although I am not sure if I understand it.I don' understand what a special member function is. haha you sent a link to the same page we are on here :P. Here is the good resource I found: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=556 – John B. May 05 '16 at 12:57
  • Isn't completely clear to me but... I try to add an edit to the response – max66 May 05 '16 at 14:24