我在显示正确字符串的蓝牙/ oled显示器上遇到一些困难。目标是从蓝牙读取数据,更新类变量(Music.setArtist()),然后稍后从该变量读取(Music.getArtist()),以使用绘制文本函数对其进行绘制。
如果我只调用一次drawText,它将正常工作。但是,在循环中多次调用drawText会导致一些未定义的行为,通常是第二个指针被覆盖。这将导致drawText中的指针为null,某些随机字符或其他内容。
这是我的音乐对象。
#ifndef Music_h
#define Music_h
class Music {
private:
char *track,*artist,*length, *position;
int progressBar;
bool playing;
public:
Music(char* t, char* a, char* l, char* po, bool pl, int p): track(t), artist(a), length(l), position(po), playing(pl), progressBar(p){};
~Music(){};
char* getLength(){return length;}
char* getPosition(){return position;}
char* getArtist(){return artist;}
char* getTrack(){return track;}
bool getPlaying(){return playing;}
int getProgressBar(){return progressBar;}
void setLength(char * l){length = l;}
void setPosition(char *p){position = p;}
void setArtist(char *a){artist = a;}
void setTrack(char *t){track = t;}
void setPlaying(bool p){playing = p;}
void setProgressBar(int p){progressBar = p;}
};
#endif
这是我的drawText函数
void Display_obj::drawText(double xPos, double yPos,char str[], int stringSize, uint8_t asciiBuff)
{
bitmapLetter fnt_controller(0,0,0x00,0,0);
bitmapLetter sheldon_alph[0x5A];
fnt_controller.createDictionary(sheldon_alph,6,8);
int startX = xPos;
int startY = yPos;
for (int i=0; i < stringSize; i++){
char charAt = str[i];
uint8_t ascii = (uint8_t)charAt;
if (ascii > 0x60)
{
charAt = charAt & ~(0x20);
ascii = ascii & ~(0x20);
}
int width = sheldon_alph[ascii-asciiBuff].getWidth();
int height = sheldon_alph[ascii-asciiBuff].getHeight();
size_t siz = sheldon_alph[ascii-asciiBuff].getSize();
unsigned char* bitmap = sheldon_alph[ascii-asciiBuff].getLetter();
drawBitmap(startX,startY,width,height,bitmap,siz);
startX = startX - 8;
if (startX <= 0)
{
startX = xPos;
startY = startY+8;
}
}
}
而且我的主循环看起来像这样
Music music("", "", "", "", false, 0);
RideTracking ride("", "", "", "", "", false);
Navigation nav("", "", "", "", "", false);
void loop(){
if (bt.getDataUpdated() == false)
{
bt.recvWithEndMarker(&bt,&music);
}
else
{
//Serial.println(music.getTrack());
musicUpdateTrack(music.getTrack());
//Serial.println(music.getArtist()); --> This returns gibberish. If the above update is commented out, it works.
musicUpdateArtist(music.getArtist());
bt.setDataUpdated(false);
}
}
我已经尝试了我能想到的一切,弄乱了指针和地址以查看其分配是否正确。这是最接近的ive,但是好像drawText破坏了我将来调用的其他char指针。我不认为问题与闪存或SRAM有关,因为两者似乎都在正常值范围内。任何帮助将不胜感激。
编辑:在我的蓝牙对象中,有两个呼叫。一种是接收数据,另一种是更新对象。我最初没有包含它,因为看起来数据设置正确。如果我不调用drawtext,而只是调用print语句,则数据是正确的。
void blue::updateData(Music* music) {
if (getDataUpdated() == true) {
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, receivedChars);
else{
char s1[55];
char s2[55];
char s3[15];
char s4[15];
char s5[15];
if(doc["music"]) {
strlcpy(s1, doc["music"]["track"]);
music->setTrack(s1);
strlcpy(s2, doc["music"]["artist"]);
music->setArtist(s2);
strlcpy(s3, doc["music"]["track_length"]);
music->setLength(s3);
strlcpy(s4, doc["music"]["position"]);
music->setPosition(s4);
music->setProgressBar(doc["music"]["progressBar"]);
music->setPlaying(doc["music"]["playing"]);
}
}
void blue::recvWithEndMarker(blue* bt,Music* mu) {
char rc;
while (ble.available() > 0 && getDataUpdated() == false) {
rc = ble.read();;
if (rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
brackets++;
if(brackets != 2)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
receivedChars[ndx] = rc;
receivedChars[ndx+1] = '\0'; // terminate the string
ndx = 0;
brackets = 0;
setDataUpdated(true);
}
}
}
bt->updateData(mu);
}
找到了!在音乐课上,我将诸如* track之类的变量更改为硬轨道[50]。然后,在set方法中,我将其更改为
void setLength(char * l){
strlcpy(length,l,strlen(l)+1);
}
void setPosition(char *p){
strlcpy(position,p,strlen(p)+1);
}
void setArtist(char *a){
strlcpy(artist,a,strlen(a)+1);
}
void setTrack(char *t){
strlcpy(track,t,strlen(t)+1);
}
随着它的传递方式进行了一些更改,现在可以使用了。谢谢!我已经坚持了好几天。