This is a program for using fonts in MCUs. I have 4 files. 'zar.h' and 'zar.cpp' contains data of one font. 'font.h' and 'font.cpp' contains pointers and functions for set fonts dynamically. There is a lot of problems with pointers. When access elements of "XB_Zar_name" array, by "uni_name[i]" pointer, MCU dos reset's. Another problem is counting the strings in "XB_Zar_name" string array. There are definitely other errors that will appear after fixing these errors. Pleas help me.
zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern char XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern String XB_Zar_name[];
zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
char XB_Zar_width[]= {2,2,2,2,2};
const unsigned char* XB_Zar_addr[] = {XB_Zar_118,XB_Zar_119,XB_Zar_120,XB_Zar_121,XB_Zar_122};
String XB_Zar_name[] = {"۰","۱","۲","۳","۴","۵"};
font.h
#pragma once
#include "zar.h"
extern unsigned char *char_addr;
extern unsigned int *char_width;
extern String **uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(String *uniChar, int *index, int *width);
font.cpp
#include "font.h"
unsigned char *char_addr = NULL;
unsigned int *char_width = NULL;
String **uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = (unsigned char *)(XB_Zar_addr);
*uni_name = XB_Zar_name;
char_width = (unsigned int *)XB_Zar_width;
break;
default:
char_addr = (unsigned char *)XB_Zar_addr;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(String *uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= "+*uniChar);
Serial.println("uni_name[i]= "+*uni_name[0]);// <---this resets the mcu
int countOfUniChars = sizeof(uni_name) / sizeof(String*);
for (int i = 0; i < countOfUniChars ; i++)
{
if (*uniChar == *uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
return -1;
}
Inside of getGliphData()
, uni_name
is just a pointer, so the sizeof()
trick you are trying to use to calculate countOfUniChars
simply won't work (there are numerous questions on StackOverflow on that very issue).
So, either store the array length into another global variable at the same time you store the array pointer, or else terminate each array with a sentry value (in this case, a blank string) and then loop through the array until you reach the sentry.
Also, there is no need to use a String**
pointer when a String*
pointer will suffice, as you are iterating through only 1 array of String
s. Were you iterating through an array of pointers to arrays of String
s then String**
would make more sense.
Also, another problem I see is that XB_Zar_width[]
and XB_Zar_addr[]
only have 5 elements in them, but XB_Zar_name[]
has 6 elements, and getGliphData()
is trying to loop through XB_Zar_name[]
using its indexes to access the elements of XB_Zar_width[]
and XB_Zar_addr[]
, which will obviously not work for the 6th element.
That being said, try something more like this instead:
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
extern const int XB_Zar_name_len;
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵"}; // TODO: remove the 6th element?
const int XB_Zar_name_len = sizeof(XB_Zar_name)/sizeof(XB_Zar_name[0]);
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern int uni_name_len;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
int uni_name_len = 0;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
uni_name_len = XB_Zar_name_len;
break;
default:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; i < uni_name_len; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
}
return -1;
}
Alternatively:
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵", ""}; // TODO: remove the 6th element?
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
break;
default:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; uni_name[i].Length() > 0; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
}
return -1;
}