Jump to content


Photo
- - - - -

MIOS32 Voxel Space Graphics Demo on 256x64 Graphical OLED


  • Please log in to reply
60 replies to this topic

#41 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 05 April 2012 - 08:32

J: great to hear! The moar 256x64 OLED users, the better :)

Ultra:
very nice! As far as i´ve understood, you are currently using the "lineTo" methods to draw the font, which makes sense for this linear font.
But to have a more universal font-drawing mechanism, i´d recommend to implement a packed bitmap font engine, that can handle characters with front leading ("j" in your example).
What you always have to keep in mind is the uC-limitations, you don´t have endless space, so "packing" data as well as possible is a necessity, or you will run out of memory for your main program...
So instead of using a full byte, if a pixel is lit or not, you could use a bit and extract it via bit operations (and/or/not bitwise operators -> wikipedia has some article on it).

To store a character with left offset, and flexible length you could
* put all characters in a 16x12 pixel bitmap (width x height), which will use only 192/8 = 24 bytes of space for each character.
* have a character "leading" and character "width" control parameter associated with each character, which you can also put into your packed font data structure (=26 bytes per character).
* do not output "blank pixels", so that the left offset of the "j" does not overwrite the right character pixels of the "a" in your demo.

Quick pseudo-algorithm to draw "j" with positive left-side leading
(Sorry don´t have more time to write the inner loop pixel checking and setting)

unsigned char x = 100; // Current x "cursor" coordinate
unsigned char y = 16; // Current y "cursor" coordinate

// Grab output buffer, that has enough room to store the to-be-rendered screen data
...

// Character output loop, example just writing character "j", assuming font with height 12 pixels, j has a left lead of 2 pixels, forces cursor to "go back"
unsigned char leftLead = packedCharacter['j'][24]; // Byte 25 contains the left leading
unsigned char width = packedCharacter['j'][25]; // Byte 26 contains the width

for (unsigned char yChar = y; yChar < y + 12; yChar++)
{
   for (unsigned char xChar = x - leftLead; xChar < x - leftLead + width; xChar++)
   {
  	// Code, that checks, if a pixel is lit in character buffer
  	// Only, if pixel is lit, modify output buffer
   }
}

// Write output buffer to screen
...

Edited by Hawkeye, 05 April 2012 - 08:37.


#42 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 05 April 2012 - 22:01

i understand what you mean with your algorithm and left lead and i'll implement that later. first, i need a method to store font information. i figured that 16x16 space is good for the maximum character size. this allows a u16 array[16] to be used to store the information. then i'll analyze the actual number to get the bits out of it. how does this look for a beginning to storing the actual fonts? this format might make it easy for others to add their own fonts:

// describes various fonts which can be up to 16 x 16 px wide.
// number of characters per font is 94.
// character index has a range of 0-94, which corresponds to chars 32-128 on the ascii table.  it's necessary to subtract 32 from the character code to get the correct character.

struct font_char {
    u16 bitmap[16];
    u8 left_lead;
    u8 width;
  };
 
struct font {
    u8 *name;
    u8 height;
    struct font_char chars[94];
  };
 
struct font fonts[] = {
    /* first font */
    {
        // superpoint square
        {
            // space
            {
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // bitmap
                0, // left lead
                2 // width
            },
            /* second character, and so on */
            /* ... */
        },
    },
    /* second font, and so on */
    /* ... */
};

keep in mind i'm just learning about how to use structs now, so maybe this is the wrong approach or the code is simply wrong.

Edited by ultra, 05 April 2012 - 22:02.


#43 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 05 April 2012 - 23:41

Hi there,

nice!
Instant initialization of complex pointered structures is not available in C - when dealing with "pointer" types, you need to store an address to a memory location, so initialization would be a 2-stage process, first storing the data, then getting and storing the address of it.

But, data serialization to the rescue. You can write a small "font data serializer" on your real computer, in your favourite language (script language is also fine), that creates a "C readable" seralized font description, that can be directly accessed.

Also, I´d put the different serialized fonts into different header or c files, so the user can include anything that is necessary (and thus reduce code size).

The font_char struct looks quite fine. It has a sizeof 16*2 + 1 + 1 bytes, which would be 34 bytes. Nao, some architectures/compilers do a structure aligning to int-size boundaries (here: 4bytes), i´d therefore make left_lead and width also 16 bits wide (u16), just to be on the safe side (sizeof / 4 = not a fraction), maybe structure aligning is turned off on MIOS32, but me iz not sure, also unsure about the future :).

Ok, long talk, here is some code, you need to strip away the typedefs, the main, and the printf(), i just tried it on a big computer, so that i do not tell you complete nonsense :)

typedef unsigned short u16;
typedef unsigned char u8;

/* One font char contains 18 16-bit words, or 36 bytes */
struct font_char
{
   u16 bitmap[16];
   u16 left_lead; 
   u16 width;	
};

struct font
{
   struct font_char character[96];  /* Starting at ascii character 32, which is a space, 
               						includes numbers, symbols, upper and lowercase letters */
};


/* Generated by off-line generator, made by big computer <img src='http://midibox.org/forums/public/style_emoticons/<#EMO_DIR#>/smile.gif' class='bbc_emoticon' alt=':)' /> */
/* Put this in a header file and let the user choose which fonts he needs, to save space */
struct font serialized_square_font = { 0x0000, 0x1001, 0xFEED, 0xBEEF /* ,... and 1724 16-bit words more */};


int main()
{
 
   /* Let the user choose which font he wants, be obtaining a pointer to his preferred font */
   struct font* myFont = &serialized_square_font;

   /* Lets output the second and third bitmap "line" of the first character in the user-selected font */
   printf("%x\n", myFont->character[0].bitmap[2]);
   printf("%x\n", myFont->character[0].bitmap[3]);

   /* Note, you have to subtract "32" from every printed character value, as your
  	font "starts" at character 32, which is the "space". */
}


Have lots of fun!
Bye, Peter

Edit:
having switched to C++ 10 years or so ago, i was unaware of the following method of struct "by name" initialization - I´d *highly* recommend to go this route:
http://linuxprograms...ation-advanced/
It has the advantage, that the correct element order is not necessary and that less errors can occur - just write a "c font generator" that creates initializations in that format.

Edited by Hawkeye, 05 April 2012 - 23:59.


#44 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 06 April 2012 - 11:56

in my program to output the serialization, do i have to define each character like this?

for instance, here's a lowercase 'a' in superpoint square:

0000000000000000
0000000000000000
0000000000000000
1111111000000000
0000001000000000
0000001000000000
1111111000000000
1000001000000000
1000001000000000
1111111000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000

i left 3 px above it for uppercase letters extending upward, 3 px below for lowercase letters extending downward, and the unused 0's underneath. ignore what i said before about 11px fonts. this is 13 overall. this one is designed assuming the 0,0 coordinate is at the top-left, but it could be changed to the bottom-left. anyway, those specifics don't matter as much right now.

what i'm wondering is how i feed this into a serialization program? do i 'draw' each character like this, then write the program to loop through the lines and output a hex value for each set of 16 bits? if that's the case, i get how this works. just loop through the data, making a string with the hex value and concatenating a ', ' to the end. copy, paste into my C program, and repeat. or write in all the chars and have it output the information once.

also, does the serialized data contain left_lead and width information? 96*18=1728, so i'm assuming the two extra 16 bit words include the information. therefore, to retrieve the character's width, does it look like this?

width = myFont->character[0].bitmap[17]);

thanks for helping, i'm learning a lot about programming that i didn't know. i'm going to try to start working on a python program to output the serialized data.

#45 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 06 April 2012 - 21:18

Hi there,

Yes, now convert every binary line into a 16bit hex value, separate by commas and you are good to go.

Your serializer also needs to write width and left_lead -> see the last link in my "edit" note below for how the serializer output format should look, ignore my long posting above, the proposed advanced structure initialization is much better. You should read the bitmap font first (on your big computer) and then write out the serialized "c struct initialization string", which you put into a separate header file for each font.

For each font, make your serializer iterate all 96 characters starting with character 32 (which is space).
Write a serializer loop that writes a long string for the whole font struct, that is a "C struct initialization" just as described in the link.
To access the width of a "space", just:

width = myFont->character[0].width;

Bye,
Peter

Edited by Hawkeye, 06 April 2012 - 23:09.


#46 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 07 April 2012 - 00:29

well that was easy

user_input = "0000100110001110"
total = 0

for bit in range(0, len(user_input)):
    total += int(user_input[bit]) << (15 - bit)

total = hex(total)
print(total)

0x98e

now i just need a bunch of instructions and loops and formatting and whatnot. :)

Edited by ultra, 07 April 2012 - 00:30.


#47 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 09 April 2012 - 01:08

i've written most the font generating program and it's working very well. it's pretty user friendly.

but i'm stuck trying to combine the information at the page you linked with how it should be in this context. should i end up with a .h file for the structs and a .c file for initialization?

so far, this is my output. i only put in two characters b/c i could spend all day testing this with 96. the series of hexadecimal numbers include the left_lead (now called left_shift) and width. but i'm assuming i don't have to do that since i'll be generating the initialization code.

anyway, here is what it looks like so far:

struct character {
	u16 bitmap[16];
	u16 left_shift;
	u16 width;
};

struct font {
	struct character characters[96];
};

struct serialized_superpoint_square = {0x0, 0x0, 0x0, 0xfe00, 0x200, 0x200, 0xfe00, 0x8200, 0x8200, 0xfe00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x8000, 0x8000, 0x8000, 0xfe00, 0x8200, 0x8200, 0xfe00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7};


this is of course not in the output. it's what you see as you build a character. 0/. is used for input to make it easier to see, and it's later translated into 1/0 for the hex output.

................
................
................
0000000.........
......0.........
......0.........
0000000.........
0.....0.........
0.....0.........
0000000.........
................
................
................
................
................
................

0...............
0...............
0...............
0000000.........
0.....0.........
0.....0.........
0000000.........
................
................
................
................
................
................
................
................
................

sorry for my lack of understanding with what to do with this, but at least when this is done we will be able to do some really cool things with this display. :)

ultra

Edited by ultra, 09 April 2012 - 01:12.


#48 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 09 April 2012 - 10:00

Hi there,

that already looks very nice!

Regarding your .h / .c question, there are two approaches.
In both cases, create one .h file by hand, which contains the struct info.

In case one, your generator only creates a square_font.h file, which the user can include, when he needs it - the advantage is, that he needs not add a .c file to the makefile - the disadvantage is, when the font is used by more than one module (.c), there will be a linker problem because of redefined data.

In case two, which is more general, your generator should create a square_font.h file, which contains an "extern" definition, so that any module can include it and use that font, and the .c file contains the font data. I would recommend this approach, as the benefits outweigh :)

Example, to keep it simple, i´ve just created one "character" struct, a font is an array of characters. Also, the lazy generator only creates a .h file (method one), this has to be adapted later.

font.h (not generated):
--------
typedef struct character_struct
{  
   u16 bitmap[16];
   u16 left_shift;
   u16 width;
} character;


square_font.h (generated)
------------------------------------
#include "font.h"
character square_font[] = 
{
   {
  	.bitmap = {  0x0, 0x0, 0x0, 0xfe00, 0x200, 0x200, 0xfe00, 0x8200, 0x8200, 0xfe00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0  },
  	.width = 0x07,
  	.left_shift = 0x00
   },
   {
   	...
   }, 
   ...
};

Did not test this in the compiler, may contain some typos but like this the "named" structure initialization should work.

Greets & have fun,
Peter

Edited by Hawkeye, 09 April 2012 - 10:49.


#49 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 09 April 2012 - 13:33

i'm a little confused.

i don't see an 'extern' definition. does it go like this?

extern character square_font[] = ...

font.h shouldn't be generated, but maybe it'd be easiest for the programmer if i output that to its own file if it doesn't exist?

you said the .c file should contain the font data, but isn't this the font data in the .h file?

.bitmap = { 0x0...

it's looking like i'm closer than i thought to having this completed. all the pieces are in place.

ultra

#50 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 09 April 2012 - 15:02

Hi ultra,

heheh, yes, me was lazy, thats why the example refers to approach type "one", which is good to start with - once that is done and you can use your font after #include "square_font.h", we can move to the next step, that is put the font extern declaration in the header and the font data in the square_font.c file - its all in the text somewhere :)

Bye,
Peter

#51 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 09 April 2012 - 21:01

here's the output from two iterations of the main character input loop:

#include font.h
character superpoint_square[] = {
	{
		.bitmap = {0xc000, 0xc000, 0xc000, 0xf800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
		.left_shift = 0,
		.width = 5
	},
	{
		.bitmap = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
		.left_shift = 0,
		.width = 0
	}
};

now what? :P

edit: nm, i think i got it.

Edited by ultra, 09 April 2012 - 21:05.


#52 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 10 April 2012 - 03:12

i have this working and i'm able to access .bitmap[x], .left_shift, and .width from my mios32 app. i'm assuming the next step is to make a font.c that handles drawing the font from the hex values?

should this somehow implement the standard mios32 display functions? i'm not sure if that would work because we can add parameters such as shade, position, etc, for each character or whatever we want. also i plan on making some general use meters and perhaps some other graphics. so should the standard mios32 display functions be ignored and i write my own display printing code from scratch?

ultra

#53 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 10 April 2012 - 09:09

Great progress! I´d recommend to roll font.c on your own, and let it render a rectangular area to a memory buffer (like the voxel demo),
which can then be put to the screen by specialized routines written for different displays (and thus be reused by MIOS users with other graphical displays).

It is a kind of an abstraction layer - font rendering is generic, putting the rendered buffers to screen is specialized.

Possible module layout idea:
font.h/.c (generates rectangular bitmaps, ready for outputting to screen, takes a user-supplied character array pointer - to choose the font)
gfx_1322.h /.c (general purpose gfx routines for this oled, such as outputting a rectangular buffer to screen, putpixel, setpixel, line(), etc... )

Also, I´d put special things like meters, virtual "knobs" like the machinedrum display has, etc. to different modules, as they have nothing to do with a font, they can also render to rectangular buffers and the gfx_1322 routines can output them (so they can too be reused by users with other displays).

Have a great time!
Peter

Edited by Hawkeye, 10 April 2012 - 09:11.


#54 ultra

ultra

    MIDIbox Guru

  • Programmer
  • PipPipPipPip
  • 801 posts

Posted 10 April 2012 - 11:51

so does gfx_1322 call into font.c to get the bitmap data?

here's where i'm confused:

i want to write the text "midibox" to the display, starting at x/y coordinates 16/32 with a shade of 8. i'd assume that the function would have to be specific to this display, since others might not have shades, or might even be rgb and then have a color argument.

so would my function to write text actually call into gfx_1322, like this?

print_text("midibox", 16, 32, 8);

then gfx_1322 loops through the characters, passing each one into font.c and getting back the bitmap data on a character which will then generate the 1322 specific code to write pixel/shade data to the buffer?

if this is correct, then font.c is doing nothing more than translating the hex codes into 1/0 data and returning it to gfx_1322.c for buffer and output.

#55 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 10 April 2012 - 13:29

Hi there,

it is your choice, but I would recommend to have better separation, all glued together by main, to keep inter-module dependencies low:

your main.c module includes square_font.h, creates a pointer to it, includes font.h (for rendering) and gfx_1322.h (for output)
the font pointer is passed to functions in font.c, with the to-be rendered string and renders to a render buffer (with 16 shades of grey)
that buffer is then passed to gfx_1322 (or any other low-level gfx engine) to be output on the screen.

possible function calls in main.c:
u8* buf = create_buffer(256, 16); // Allocate, clear and return a 256*16 pixel square output buffer (that can hold 16 shades of grey) = 2048 bytes
character* font = &superpoint_square;
render_text(font, "midibox", 8 /* chosen brightness */, 0, 0 /* in-buffer coordinates */, buf, 256 /* buffer width */);
display_buffer_1322(0, 20 /* screen coordinates */, buf, 256, 16 /* buffer width & height */);
free_buffer(buf);

Bye,
Peter

Edited by Hawkeye, 10 April 2012 - 13:35.


#56 Josh

Josh

    MIDIbox Newbie

  • Members
  • Pip
  • 3 posts

Posted 12 April 2012 - 02:49

Hi chaps,

I've bought a couple of these displays and I'm generally banging my head against the wall trying to get some initialisation code to work on them.

I'm using an Atmel AVR powered by 2.5V which is from stepped-down 5V USB. As far as I can tell my code works, and I've checked it on the scope, but I can't get anything to light up. I'm going to have a look at adding a cap and I'll report back. Essentially my mission at the moment is to write up full documentation for both initialization and the command set because frankly what's provided by Solomon and Newhaven is terrible!

Really looking forward to getting it working, though the micro only has 1K of RAM, so a 256x64 4-byte buffer is a no-no for me (I should point out I'm not involved with MIDI devices, but I really want to get this screen working and I'd be happy to share code/otherwise collaborate!)

The main problem seems to be that Newhaven have taken a completely backwards approach to interpreting the SSD1322 datasheet. The impression I got was that you provide a 3.3V line (VCI) to power the logic and then you turn on an internal 2.5V regulator (VDD). The data pins are set to VDDIO which is 0-VCI, i.e. 3.3V tolerant. So the obvious choice, to me, is to provide a 3.3V interface and regulate VDD internally. They've gone the opposite way and forced you to provide a highly stable 2.5V power signal which also means you need to provide 2.5V data lines, etc.

I'm hoping to get some sample C code working over the next couple of days, but I was annoyed enough that I designed a new backboard for the display which you can see here: http://img23.imagesh...120412at024.png

It's an 8 pin breakout, 3V3, GND, CS, DC, CLK, SDIN, RES and 12VENABLE. There's an onboard 3.3V-12V step-up converter and you can enable the 12V line using the 12VENABLE pin - based on the datasheet, the OLED power line should be turned on after core logic. Newhaven don't seem to have bothered and it doesn't look like it makes a difference, so you could just tie it to 3V3 and have done with it. Otherwise, I think it's a lot simpler and a lot neater than their board. Not entirely finished - I need to draw up the holes for the display, but otherwise it's done. I don't think many people are interested in programming this in parallel, so I figured go for the minimal number of pins.

Best,
Josh

Edited by Josh, 12 April 2012 - 02:55.


#57 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 12 April 2012 - 10:30

Hi Josh,

Welcome to MIDIbox :)

not getting the display to "lighten up" using the default Newhaven datasheet init commands has been experienced by a few people by now - could you try the custom initialization, which I´ve written with TKs help some time ago? See APP_LCD_Init() and try the same Command/Data pairs on your display:

http://svnmios.midib...322%2Fapp_lcd.c

Regarding 2.5V on the data lines, we fed it with 3.3V accidentally for some minutes, would not fry the unit, but that may have been luck - agreed on the need for a stable 2.5V supply though (use caps to buffer).
You would not need a full video buffer for using the display, you can directly draw on the screen, as long as you can write blocks of 4 pixels (2 bytes), overwriting the background pixels on that location.

Bye and best of luck!
Peter

Edited by Hawkeye, 12 April 2012 - 10:31.


#58 Josh

Josh

    MIDIbox Newbie

  • Members
  • Pip
  • 3 posts

Posted 15 April 2012 - 22:26

Ok, so after a bit of fiddling I got it working. I think the problem was with my serial code, rather than the init sequence itself. I had the clock signal with the wrong polarity (idle low rather than idle high)...

I'm running it at 3.3V with the following assumptions:

1. The data pins are 3.3V tolerant in the datasheet
2. The VCC pin on the Newhaven board simultaneously powers VDD, VDDIO and VCI
3. If you power on with 3.3V and turn on the internal 2.5V regulator (via command) for VDD, you're now essentially running the whole board (VDDIO and VCI) at 3.3V hence it's not going to damage anything. Plus, the onboard 2.5 is probably better than what we're slinging into it with cheap LDO regulators.

Anything less than this gives very flickery or dim displays. I've also got 220uF and 0.1uF capacitors in parallel to give it a bit of extra oomph. I'm not particularly concerned about the lifetime of the display, it looks rock solid with all the pixels on at 3.3V so that's where it's going to stay!

The init sequence is essentially yours, I believe, I've set the contrast to 127 after initialisation which looks nice. I've uploaded working C code. It's an extremely simple circuit, 5V USB goes to a 3.3V LDO regulator which powers both the micro and the display. The display is set up in 4-wire serial mode directly to the MOSI/SCK pins on the AVR and a couple of extra GPIOs dealing with Reset, CS and DC.

I'm going to look into getting some fonts and other bits and pieces working today.

Only one other question - high contrast causes a fair amount of banding, not sure if that's normal?

Thanks for this thread, it's a lifesaver!

Josh

Attached Files


Edited by Josh, 15 April 2012 - 22:32.


#59 Hawkeye

Hawkeye

    MIDIbox Guru

  • Frequent Writer
  • PipPipPipPip
  • 1,435 posts
  • LocationGermany, Munich

Posted 16 April 2012 - 09:05

Hi Josh,

great to hear that it successfully runs on 3.3V and that you can switch it to 2.5V mode - when I continue to work on it, i´d like to try that too, because it would make connecting it much easier, just as you said.

Banding may be because of the "guesswork" timing initialization - I randomly played with the values for a few hours until I got a more or less "stable" picture, could not get one with default Newhaven values.
I played around with the following seven parameters, by manipulating them via mouse on the big computer and sending them to the microcontroller via MIDI (its MIDIbox :), it was TKs idea, without him, these displays would still be dark ;-) - you can get fancy "strobe-like" effects with the right parameters, very demo-like - so if you have a means of external communication with your uC (or some on-board encoders), you could try it :)

1.
APP_LCD_Cmd(0xb3); // Set_Display_Clock(0x91);
APP_LCD_Data((u8)midi_package.value/2);

2.
APP_LCD_Cmd(0xca); // Set_Multiplex_Ratio(0x3F);
APP_LCD_Data((u8)midi_package.value/2);

3.
APP_LCD_Cmd(0xb1); // Set_Phase_Length(0xE2);
APP_LCD_Data((u8)midi_package.value/2);

4.
APP_LCD_Cmd(0xbb); // Set_Precharge_Voltage(0x1F);
APP_LCD_Data((u8)midi_package.value*2);

5.
APP_LCD_Cmd(0xb6); // Set_Precharge_Period(0x08);
APP_LCD_Data((u8)midi_package.value*2);

6.
APP_LCD_Cmd(0xbe); // Set_VCOMH(0x07);
APP_LCD_Data((u8)midi_package.value*2);

7.
APP_LCD_Cmd(0xc1); // Constrast Current
APP_LCD_Data(midi_package.value*2);

Have lots of fun with the display!
Peter

#60 Josh

Josh

    MIDIbox Newbie

  • Members
  • Pip
  • 3 posts

Posted 24 April 2012 - 01:14

I haven't bothered to play with the timings, but attached is my current efforts. I've got a 10 by X variable width font engine working which I'm pleased with. I had it at 8 high to begin with, but 10 lets you have hanging letters and for what I want to do I can have 5x11px rows (10+1 space) and then 9px for a status bar at the top.

Conveniently it takes almost no RAM and doesn't need much in the way of a buffer though it's just fast enough at 1MHz (fine because only a few characters change at any one time), at 8 it's more than quick. Fonts can be stored in program memory space (around 2k out of 32k for 8-bit ASCII) and the engine renders one character at a time into a 4x10 pixel block , compensates for overflow into the next block and adds an (ascii) space afterwards. It also pads up to 4 pixels on the end to ensure the entire string prints. The print string function returns an x-offset so instead of concatenating strings, you could do:

/* printstring(uint8_t * input_string , char intensity, uint8_t x, uint8_t y, uint8_t * x offset); */
printstring("ADC Value", 15,0,0,&offset);
printstring(itoa(ADC), 15, offset,0,&offset);

You might lose up to 3 pixels - as the previous string could have forced 3px of space maximum, but it's not such a big deal.

Ignore the little battery thing at the top right, I was experimenting. You can fit nearly 6 rows of text, allowing for some tails being cut off on the bottom row. The number of characters per line is variable due to the changing letter widths, but you should be able to get at least 32 full width characters worst case, and often more.

It's cool now it works, debugging programs via the screen is so much easier than simulating in Proteus and staring at logic traces!

Apologies for the blurrycam, my SLR is at home :(

Attached Files


Edited by Josh, 24 April 2012 - 02:48.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users