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