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);
}

1 Answer 1

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);
 }
Sign up to request clarification or add additional context in comments.

7 Comments

great that fixes that issue, but I am getting a new error: invalid conversion from 'char*' to 'char' [-fpermissive]
Also I am getting this interesting error with just passing a String type through: - 'EEPROMAnyType<E>::EEPROMReadAny(unsigned int, E) [with E = String]::<anonymous union>::~<constructor>()' is implicitly deleted because the default definition would be ill-formed: union{
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?
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 stackoverflow.com/questions/37002058/…
Here is where theconversion error is happening: invalid conversion from 'char*' to 'char' [-fpermissive] eepBLEtoothchar.EEPROMReadAny(readaddrSSID, readSSID);
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.