Go Down

Topic: Pixel limit with U8g2 (Read 322 times) previous topic - next topic

LittleHobbyShop

I'm new to Arduino and trying to find my way around with the U8g2 library.

I have a small SSD1306 128x32 display which I have working no problem.

I have a sketch which scrolls text based on the movements of a rotary encoder and it works very well with short text strings moving from left to right on the display as i turn the encoder back and forth.

My confusion comes when I try a long string. After a few experiments I've discovered that the pixels in the x direction restart after double the display width at 256 pixels.

So this:
Code: [Select]
u8g2.drawStr(256,10,"Hello World!")
gives the same result on the display as:
Code: [Select]
u8g2.drawStr(0,10,"Hello World!")
Perhaps this is the display driver handling this? I don't know.

So how can I handle a text string longer than 256 pixels? I guess I need to display a 'chunk' of the text up to the width of the display and then move on to the next 'chunk' as required but i can't quite figure how to do that. I've had a look at the scrolling text example but it doesn't run nicely on my display with text overlapping and restarting in odd places. I've had a good read of the U8g2 documentation but haven't found enlightenment there either.

I'm not necessarily looking for a whole answer but if someone could point me in the right direction that'd be great. Attached is the aforementioned sketch.

septillion

That's because drawStr() (and I think all methods) expects a byte for the x and y position. Why would it expect anything larger if the screen is just 128x32?

And if you try to whack an int like 256 into a byte it's MSB's are lost resulting in just a plain 0.

Solution is for you to constrain the inputs :)
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

LittleHobbyShop

#2
Jul 10, 2019, 09:58 pm Last Edit: Jul 10, 2019, 10:03 pm by LittleHobbyShop
Ok, you are right. I don't know what MSB's are but I'll give it a google.

So if I constrain the inputs to 0-255 what about if the string is longer than that?

What I'm trying to achieve though is to scroll through a text string that ends up longer than the 256 pixels. I can get the pixel length of the text with u8g2.getUTF8Width(text) but how to break that up into smaller pieces that i can iterate through and display?

After a bit more reading it seems like I would need to use 16-bit mode.

septillion

MSB(s) = Most Significant Bit(s). In this case, the top 8 bits of the (16-bit) int.

16-bit mode of what?

If text is long it indeed gets a bit complicated. Let me guess, at the moment you also try to position it on a negative x/y? Because it expects a byte it also can't handle negative numbers. The value is just wrapped around (has to do with two's complement but that's outside the scope). So -4 will become 252 etc. So you are fakeing space on the left side.

If the text is longer then 255 pixels you need to figure out which part of the text is used on the screen and just use that part. You can use getUTF8Width() on parts of your text as well to figure out where in the text you are. And yeah, that can be come pretty complicated. Also quite a lot to calculate. For now, I can't really think of a simple implementation. :/
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

LittleHobbyShop

Thank you for the thorough explanation. So much is new to me here and I'm probably missing some of the core knowledge which is easy to do when following examples and chopping them up to get where I want to be. I'll get there eventually.

I did experiment with negatives and the text hangs of the left side of the display as you describe.

The U8g2 library has 16 bit mode see https://github.com/olikraus/u8g2/wiki/u8g2setupcpp#16-bit-mode

Not much detail but there but I've seen it mentioned around various parts of the documentation and in examples for use with higher resolution displays. I assume this would come at a cost of more resources but worrying about efficiency is some way down the road for me yet :) I'll keep playing.

septillion

Yeah, that might work because it will fake al larger canvas. But I can indeed imagine it will use more memory and be slower.

Another thing that might help is looking at the source code for u8g2.drawStr() and see how it determines what to draw to the canvas and what not. Might help you, might not.

Otherwise I would say:
- Check the length of each char on by one of the string you want to print
- Sum up the length
- Stop when the text would enter the screen (aka, (negative) x + length >= 0
- now you know at which character of the string to start
- and from the length you know at what x to really start printing that
- same can be done for exiting the screen
- you don't have to check the whole string every time because the next time it will be close to the last time.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

olikraus

I just want to confirm the two solutions, discussed above:
1) U8g2 16 bit mode will increase the of x and y coordinates from 1 byte to two bytes. This will probably solve your scrolling problems (at least as long as the string has lesser than 64K pixels in length), but it will also leave it to u8g2 to do the clipping for such a long string. Drawback is a bigger and slower code on AVR systems.
2) The second approach is to cut out the visible part of the string and display this part only. As mentioned above, this calculation is a little bit complicated, especially if you use a none-monospaced font. I personally think it is doable with a monospaced font (where each glyph has the same width).

There is no example which exactly matches your problem, but the Shennong.ino example includes a similar calculation  (for lines instead of chars): https://github.com/olikraus/u8g2/blob/master/sys/arduino/u8g2_full_buffer/Shennong/Shennong.ino

Oliver

septillion

Hi Oliver,

Thanks for your reaction! And for confirming I'm sane 8)

With a fixed width font it would indeed be a lot easier because you can directly calculate the position in the string.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Go Up