Oled print character cut in half upper and lower half swapped

Hi Everyone.

OLED is SH1106 .

Running the code on Atiny85.
I found this code below , the option is in the code to print bigger Characters I created a 16x16 2

But the lower half is printed first , I did try to swap the Page number but the then nothing Prints on the screen.

I am lost , busy for days now.
Please Help.

Code found in Google.

//Author: Vivekanand Dhakane
//updated on: 10 June 2020
//https://oledtutorials.blogspot.com/2020/06/tutorial-2-using-glcd-font-creator-for.html
#include <Wire.h>

#define OLED_I2c_ADDRESS       0x3d//   0x3C
// registers Addresses
#define COMMAND_REG    0x80  // B1000 0000
#define DATA_REG       0x40  // B0100 0000
// commands
#define ON_CMD                0xAF
#define NORMAL_DISPLAY_CMD    0xA6//  INVERT B/W = 0xA7
#define PAGE_ADDRESSING_MODE  0x02 //

#define Char_Verticle_Pages_Required 2
#define Char_Horizontal_Columns_Required 16

/*
//---- 2LINE CHESS BOARD -----
  byte data[] = {0x33, 0x33, 0x33, 0x33, 0xCC, 0xCC, 0xCC,
               0xCC, 0x33, 0x33, 0x33, 0x33, 0xCC, 0xCC,
               0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33, 0xCC,
               0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
               0xCC, 0xCC, 0xCC, 0xCC };
//===================
*/

//---------- Big 2 ------------
 byte data[] = {0x0D, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xE0, 0x0E, 0xF0, 
                0x06, 0xF8, 0x03, 0xFC, 0x03, 0xDC, 0x03, 0xCE, 0x03,
                0xC7, 0x03, 0xC3, 0x83, 0xC3, 0xFF, 0xC1, 0x7E, 0xC0,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


//================= 
void setup() {
  oled_begin();
  setCursor(0, 0);

  //send data in array to display
  for (int j = 0; j < Char_Horizontal_Columns_Required; j++)  //
  {

    for (int i = 0; i < Char_Verticle_Pages_Required; i++)  //(int i = 0; i < Char_Verticle_Pages_Required; i++)
    {
      setCursor(j, i);
      writeData(data[j * Char_Verticle_Pages_Required + i]);  //writeData(data[j * Char_Verticle_Pages_Required + i]);
    }
  }
}


void loop() {
  // put your main code here, to run repeatedly:

}

void oled_begin()
{
  Wire.begin(); // join i2c bus (address optional for master)
  turnON();
  NormalDisplayMode();
  setPageMode();
  writeCommand(0x8d); //Charge Pump
  writeCommand(0x14);
  clearFullDisplay();
}


void writeCommand(byte command) {
  Wire.beginTransmission(OLED_I2c_ADDRESS); // begin transmitting  (OLED_I2c_ADDRESS=0x3C)
  Wire.write(COMMAND_REG);                  // Command Reg Address (COMMAND_REG     =0x80 )
  Wire.write(command);                      // Command to be excuted
  Wire.endTransmission();                   // stop transmitting
}

void writeData(byte data) {
  Wire.beginTransmission(OLED_I2c_ADDRESS); // begin transmitting   (OLED_I2c_ADDRESS=0x3C)
  Wire.write(DATA_REG);                     //Data Reg Address      (DATA_REG        =0x40)
  Wire.write(data);                         //Write data
  Wire.endTransmission();                   // stop transmitting
}

void turnON() {
  writeCommand(ON_CMD);
}
void NormalDisplayMode() {

  writeCommand(NORMAL_DISPLAY_CMD);

}

void setPageMode() {
  byte addressingMode = PAGE_ADDRESSING_MODE;
  writeCommand(0x20);        //set addressing mode
  writeCommand(PAGE_ADDRESSING_MODE);   //set page addressing mode
}



//clearFullDisplay()
// In this function we are setting X,Y=0
// then write data on 128 column and
// then change page and do same till 7th page
void clearFullDisplay() {
  for (byte page = 0; page < 8; page++) {

    setCursor(0, page);
    for (byte column = 0; column < 128; column++) { //clear all columns
      writeData(0x00);
    }

  }
  setCursor(0, 0);
}

void setCursor(byte X, byte Y) {
  writeCommand(0x00 + (X & 0x0F));        //set column lower address
  writeCommand(0x10 + ((X >> 4) & 0x0F)); //set column higher address
  writeCommand(0xB0 + Y);                 //set page address

}

image

We all are, because you took some code from the internet and then it does not work for your display. Well, that was expected.

I tried it with a SSD1306 display in Wokwi simulation and got something similar as with your display.

Result:
afbeelding

A good library knows the most common displays and adjusts the orientation and mirroring automatically.

I'm afraid that this is not the answer your were looking for.
Can you do your project with a Raspberry Pi Pico board ? (and use a good library).

Thanks.

Dont have a Raspberry and there is no good Library for the Atiny85 with bigger fonts.

Tiny4K no big fonts.
U8g2 U8x8 tiny85 .. give up on this on.
Adafruit SH110X works great on a Nano , a lot of compile errors with Digitstamp and AtinyCore.

I searched for 2 weeks now.

That code can surely be made to work, but it will probably take some effort to understand and fix the problem.

There are many other options.

This evil thing got me obssessed it took my live away for 10 days.

I earned a Badge for spending 10 consecutive days on this forum searching for solutions.

Google searches that points to this forum was all followed up.

Please -- Other options?

There are countless screens, screen libraries and MCUs to run them.

Surely you can find some tested, off the shelf combination that will display the characters in the way you like.

This excercicse is aimed at trying to claim back some of my Nanos.

Reading 1 Analog and displaying the Voltage on a OLED I2C is a waist of a good Board with many Pins and Memory.

The prices of Arduino products sky rocketed after Covid.

There is many Libraries for this Oled (SH1106) that works on a Nano but nothing for the Atiny with BIG Fonts.

Yesterday I was playing with an Attiny85 and Tiny4kOLED, and it was able to display double size fonts.
Following @Koepel idea, I just recreated my yesterday experiment in Wokwi.

2 Likes

Appology .. replying from my phone.
Copy Quote option does not work.

YES been there got it to work.

Font 2 lines thats it ..I need bigger...Fonts.

Only 0 to 9 will do and the code to know where the next digit starts in PROG MEM..what a mess!

When you produced the data, did it come as 16-bit values, like:
0x0D00, 0x0000, 0x000C, 0xE00E, 0xF006, 0xF803, ...

The problem could be that the AVR processors are 'Little Endian" and the LSB is put into memory first. In memory those 16-bit values would be:
0x00, 0x0D, 0x00, 0x00, 0x0C, 0x00, 0x0E, 0xE0, 0x06, 0xF0, 0x03, 0xF8...

Try swapping bytes in each word. The top and bottom halves of each character should swap. The character will still be upside-down. I think your font editing software needs to change the byte and bit order.

@jhonwasser

You opened a door to a new Demon this is getting complicated I will explore.

I am lost. You showed a 16x16 pixel character, so I assumed that is the size you need. Tiny4K has more fonts, even a 16x32p font.
image

If that is big enough, I have updated the Wokwi example to display it.

1 Like

Wow I need that .. Maybe different versions .. I dont know ..?

![image|276x420](upload://a931RiEFxjM8XYeT0jdzVY1bzcl.png)


Load shedding!

Are you sure the first byte should be 0x0D? That gives you 33 bytes of data, and produces what appears to be pixels that are not part of the character. Seems to work using this:

byte data[] = {
  0x00, 0x00, 0x00, 0x00, 0x0C, 0xE0, 0x0E, 0xF0,
  0x06, 0xF8, 0x03, 0xFC, 0x03, 0xDC, 0x03, 0xCE,
  0x03, 0xC7, 0x03, 0xC3, 0x83, 0xC3, 0xFF, 0xC1,
  0x7E, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
1 Like

This is in my Tiny4k Library , where did you get bigger fonts?

Yes 100% correct this was mentioned on the Web site but I forgot to delete the first byte.

Ok .. there is a Fonts x 2 option.

I use the SH1106 OLED not the SSD1306

You have to install also the associated TinyOLED-Fonts library. Then you can select one font out of a very long list of fonts.

Look at my Wokwi example source.

The double Font option does not work on the SH1106 Oled.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.