Hello everyone, I can't figure out why my sketch gives strange results.
Hardware info: I'm using a cheap Pro Mini clone (ATmega328p 16Mhz) connected to a 4 pin I2C 128x64 OLED LCD with an SSD1306 controller (SCL & SDA connected to A5 & A4).
This is my entire sketch. It requires the U8g2 library to be installed:
#include <Arduino.h>
#include <U8g2lib.h>
#define REVERSE 1
#define ALIGNRIGHT 2
//Functions
void reverseheb(unsigned char *string);
void printheb(uint8_t xpos, uint8_t y, char ch[], uint8_t flags);
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
void setup(void) {
u8g2.begin();
Serial.begin(57600);
}
void loop(void) {
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.clearBuffer();
printheb(0, 20, "This is just a simple test.", REVERSE | ALIGNRIGHT);
u8g2.sendBuffer();
delay(5000);
}
void reverseheb(unsigned char *string)
{
int i,j;
char *temp;
//
j = strlen(string);
temp = (char*)malloc(j+1);
temp[j] = 0;
for(i=0 ; string[i] ; i++)
{
if(string[i] == 0xD7)
{
temp[j-i-1] = string[i+1];
temp[j-i-2] = 0xD7;
i++;
}
else
{
if((string[i] < '0' || string[i] > '9') && (string[i] < 'A' || string[i] > 'Z') && (string[i] < 'a' || string[i] > 'z')) temp[j-i-1] = string[i];
else
{
int m,k;
k = i;
while((string[i] >= '0' && string[i] <= '9') || (string[i] >= 'A' && string[i] <= 'Z') || (string[i] >= 'a' && string[i] <= 'z'))
{
i++;
}
i--;
for(m=0 ; m<(i-k+1) ; m++)
{
temp[j-(k+m)-1] = string[i-m];
}
}
}
}
strcpy(string,temp);
free(temp);
}
void printheb(uint8_t xpos, uint8_t y, char ch[], uint8_t flags)
{
int i,j,k;
char tmp;
char *temp;
//
if(!flags) // if not REVERSE and not ALIGNRIGHT
{
u8g2.drawUTF8(xpos, y, ch);
return;
}
if(((flags & 1) == 1) && ((flags & 2) == 0) ) // (Line 84) if REVERSE but not ALIGNRIGHT
//if(flags == 1) // (Line 85)
{
temp = (char *)malloc(strlen(ch) + 1);
strcpy(temp, ch);
reverseheb(temp); // (Line 89)
Serial.println("Alert");
u8g2.drawUTF8(xpos, y, temp);
}
if((flags & 2) == 0) return;
k = 0;
for(i=0,j=0 ; ch[i] ;)
{
j++;
if(ch[i] == (char)0xD7) i+=2;
else i++;
if(j == ( ( (u8g2.getDisplayWidth() - xpos)/u8g2.getMaxCharWidth()) ) || !ch[i])
{
tmp = ch[i];
ch[i] = 0;
temp = (char *)malloc(strlen(&ch[k]) + 1);
strcpy(temp, &ch[k]);
if((flags & 1) == 1) // if REVERSE
{
reverseheb(temp);
}
u8g2.drawUTF8((u8g2.getDisplayWidth() - (u8g2.getMaxCharWidth() * j) - xpos), y, temp);
free(temp);
y+=u8g2.getMaxCharHeight();
ch[i] = tmp;
if(ch[i] == 0) break;
k = i;
j = 0;
}
}
}
The problem: The output is incorrect. Debugging the code shows that the cause is at the if block at line 84 (I have commented the line number in the sketch).
- If the block is removed, the output is correct.
- If line 84 is commented out and line 85 is uncommented the output is correct.
- If line 89 is commented out, the output is correct.
Note: Nothing is printed to the serial monitor, so the condition in line 84 is not met but despite that somehow it still affects the output and I don't understand why.