Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotate SH1107 to landscape #72

Open
guhland opened this issue Nov 18, 2021 · 14 comments
Open

Rotate SH1107 to landscape #72

guhland opened this issue Nov 18, 2021 · 14 comments
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@guhland
Copy link

guhland commented Nov 18, 2021

I want to rotate the display 90 degrees.

#48

This issue is about the same topic. It mentions that I could use canvas and write my own method to rotate the display. How would I go about doing that?

There has to be a way to do this.

@guhland guhland added the question Further information is requested label Nov 18, 2021
@Pedrohpcavalcante
Copy link

I have the same problem

@lexus2k
Copy link
Owner

lexus2k commented Feb 24, 2022

The 1-bit canvas has the associated buffer with it, where pixels are represented the same way, as described in display controllers datasheets.

For example, if canvas size is 128x64, then each row consists of 128 bytes and each byte row describes 8 rows of pixels on the display. Because each byte is 8 vertical pixels (1 bit per pixel). This is done for speed.

So, the address of each pixel can be described as:

buffer_index = x + (y / 8) * width;
bit_index = y & 0x07;

In your case, since you want to have vertical orientation you need have 1bitx64x128 canvas. Then you draw what you need in the canvas, and the rotate the content. The rotation must result in the different buffer 1bitx128x64. So, you need something like this:

new_width = height;
new_height = width;
for(x=0; x<64; x++)
    for(y=0; y<128; y++)
    {
        uint8_t pixel = (m_buffer[x + (y / 8) * width] >> (y & 0x07)) & 0x01; // width is 64 here
        new_buffer[y + (x / 8) * new_width] |= pixel << (x & 0x07); // width is 128 here
    }

Another way is to rewrite all display 1-bit functions - a bit time consuming development.

@guhland
Copy link
Author

guhland commented Feb 24, 2022

Okay I sort of follow what is going on here. I am not 100 percent on it, but it looks like you are getting the pixel from the buffer and then writing it to a new location in a new buffer. Here is what I wrote for a rotate function for in canvas.cpp:

template <> void NanoCanvasOps<1>::rotate()
{
    lcdint_t new_width = height();
    lcdint_t new_height = width();
    uint8_t new_buffer[new_width * new_height * 1];
    for ( int x = 0; x < 64; x++ )
    {
        for ( int y = 0; y < 128; y++ )
        {
            uint8_t pixel = (m_buf[x + (y / 8) * width()] >> (y & 0x07)) & 0x01; // width is 64 here
            new_buffer[y + (x / 8) * new_width] |= pixel << (x & 0x07);          // width is 128 here
        }
    }
m_buf = new_buffer;
}

This does not work. What am I doing wrong? Let me know if you need more info or a picture...

@lexus2k
Copy link
Owner

lexus2k commented Mar 4, 2022

The code doesn't work because you assign a pointer to the locally allocated array: new_buffer is defined inside the function.

@lexus2k lexus2k added the enhancement New feature or request label Mar 5, 2022
@lexus2k
Copy link
Owner

lexus2k commented Mar 5, 2022

I added enhancement label. Once I have free time, this feature will be implemented.

@lexus2k
Copy link
Owner

lexus2k commented Mar 9, 2022

Hi @guhland

Good news that I implemented rotate method for 1-bit displays.

NanoCanvas<64,32,1> canvas;
NanoCanvas<32,64,1> rotatedCanvas;

void setup()
{
    /* Initialize and clear display */
    display.begin();
    display.clear();
    canvas.setMode( CANVAS_MODE_TRANSPARENT );
    canvas.clear();
    canvas.drawBitmap1( 5, 8, 8, 8, heartImage );
    canvas.drawRect(0,0,63,31);
    canvas.rotateCW(rotatedCanvas);
}


void loop()
{
    lcd_delay(40);

    /* Now, draw original canvas on the display */
    display.drawCanvas( 0, 0, canvas );
    /* Now, draw rotated canvas on the display */
    display.drawCanvas( 80, 0, rotatedCanvas );
}

The band news is that such rotation requires 2X SRAM memory.
But as long as you're using powerful microcontrollers that doesn't matter.

@guhland
Copy link
Author

guhland commented Mar 15, 2022

Thanks a bunch for your support. I had something working similarly with the pseudocode you provided before. This is working better. However, I have a issue a ran into before where the only the rotated "left" half of the screen will print anything. I am using a 64x128 display. Let me know if you need more info.

@lexus2k
Copy link
Owner

lexus2k commented Mar 15, 2022

Hi

It would be nice to have full sketch example (as simple as possible), that doesn't work in your case. So I can run tests and figure out what's wrong.

@guhland
Copy link
Author

guhland commented Mar 17, 2022

#include "lcdgfx.h"

NanoCanvas<64,128,1> canvas;
NanoCanvas<128,64,1> rotatedCanvas;

int main(){

    /* Initialize and clear display */
    DisplaySH1107_64x128_I2C display(-1,{-1, 0x3C, -1, -1 , 0});
    display.begin();
    display.clear();
    canvas.setMode( CANVAS_MODE_TRANSPARENT );
    canvas.clear();
    canvas.setFixedFont(ssd1306xled_font5x7);
    canvas.printFixed(5,5,"test1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    canvas.rotateCW(rotatedCanvas);
    lcd_delay(40);

    /* Now, draw original canvas on the display */
    //display.drawCanvas( 0, 0, canvas );
    /* Now, draw rotated canvas on the display */
    display.drawCanvas( 63, 0, rotatedCanvas );
       

    display.end();
    return 0;

}

The added "!" are just to make sure it would normally fit the entire screen.

@lexus2k
Copy link
Owner

lexus2k commented Mar 17, 2022

Hi,

I slightly modified your example to run in Arduino IDE.
Please, find my comments below

#include "lcdgfx.h"

DisplaySH1107_64x128_I2C display(-1,{-1, 0x3C, -1, -1 , 0});

NanoCanvas<128,64,1> canvas; // <<< Change (64,128) to (128,64) as you would like to have it in landscape mode
NanoCanvas<64,128,1> rotatedCanvas; // <<< Change (128,64) to (64,128) as you need to rotate canvas before displaying

void setup()
{
    /* Initialize and clear display */
    display.begin();
    display.clear();
    canvas.setMode( CANVAS_MODE_TRANSPARENT | CANVAS_TEXT_WRAP_LOCAL ); // <<< Set text wrap local mode
    canvas.clear();
    canvas.setFixedFont(ssd1306xled_font5x7);
    canvas.printFixed(5,5,"test1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    canvas.rotateCW(rotatedCanvas);
}

void loop()
{
    lcd_delay(40);
    /* Now, draw original canvas on the display */
    //display.drawCanvas( 0, 0, canvas );
    /* Now, draw rotated canvas on the display */
    display.drawCanvas( 0, 0, rotatedCanvas ); // <<< change (63,0) to (0,0) since you need to draw canvas on the entire display without any shift
}

@guhland
Copy link
Author

guhland commented Mar 18, 2022

So following what you wrote here. I am still only able to print to half of the screen. Only this time being the top half instead of the right. However, if I remove the offset like you suggested, Nothing prints. Right now I am at a offset of 95.... Thoughts?

@lexus2k
Copy link
Owner

lexus2k commented Mar 19, 2022

This is how it looks like if to run the example provided by you:
image

This is how the display looks like, if to apply my recommendations:
image

If the issue relates to some specific hardware you have, I need much more information on the setup, including the display hardware part number, datasheet for your display, CPU/MCU hardware part number (maybe board description), etc.

@guhland
Copy link
Author

guhland commented Mar 21, 2022

I am using a raspberry pi 4 4GB right now. I have plans to use the display with other things. Testing with the pi right now. I am able to get your second image. However, I cannot print to the bottom half.
oledissue

@lexus2k
Copy link
Owner

lexus2k commented Mar 22, 2022

изображение

If the issue relates to some specific hardware you have, I need much more information on the setup, including the display hardware part number, datasheet for your display, CPU/MCU hardware part number (maybe board description), etc.

Without details on your setup I can do nothing. I know that you have Raspberry Pi, and since it's 64-bit, the data types, used by the library is not the issue in your case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants