Phatline

glcd - waveform display - osci - newbee problems

19 posts in this topic

using the ssd1306

i am learning at the moment the handle of graphical displays... specially the waveform display

 

now i stuckking,  i already have X-Y coordinates, and a timline... in theory it is working, it works with Characters... but i need pixels

i stuck by writing a single pixel to the display, i want to write a pixel every millisecond, and after the time of the loop (loop point 0) it should clear the display... (APP_LCD_Clear();))

 

is there a way to directly draw a single pixel, without the must of " changing a bitmap, and print the whole bitmap again..."

i can set the courser with:

        APP_LCD_Clear();
         
        APP_LCD_Cmd(0x75); // Row
        APP_LCD_Data(V);
         
        APP_LCD_Cmd(0x15); // Column
        APP_LCD_Data(H);

 

but then i have no command to activate a pixel,  has it something to do with the write ram >>> APP_LCD_Cmd(0x5C);

Share this post


Link to post
Share on other sites

like this:

Quote

        MUTEX_LCD_TAKE;
            MIOS32_LCD_DeviceSet(14);              
            MIOS32_LCD_GCursorSet     (     H,  V );
            MIOS32_LCD_PrintFormattedString("*");    
        MUTEX_LCD_GIVE;

but in Pixel-Resolution

Share this post


Link to post
Share on other sites

now trying to make it with bitmaps... but that is not easyer, not working....

 

also the "APP_LCD_Clear();" isnt working.

when looking @

http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fmodules%2Fapp_lcd%2Fssd1322%2Fapp_lcd.c

Quote

/////////////////////////////////////////////////////////////////////////////
// Clear Screen
// IN: -
// OUT: returns < 0 on errors
/////////////////////////////////////////////////////////////////////////////
s32 APP_LCD_Clear(void)
{
  u8 i, j;

  for (j=0; j<64; j++)
  {
    APP_LCD_Cmd(0x15);
    APP_LCD_Data(0+0x1c);

    APP_LCD_Cmd(0x75);
    APP_LCD_Data(j);

    APP_LCD_Cmd(0x5c);

    for (i=0; i<64; i++)
    {
       APP_LCD_Data(0);
       APP_LCD_Data(0);
    }
  }

  return 0;
}

then i ask myself for what  there is a "for loop" with "i" when no is used anywhere?

 

Share this post


Link to post
Share on other sites

Hello,
Check ssd1306 datasheet, you can write only one segment at a time, you can not write a single pixel. A segment is a 8 vertical pixel.
Use:
 


    APP_LCD_Cmd(0x5c); // Write RAM
    APP_LCD_Data(abyte);

Shift the pixel in the byte using >> or <<
e.g.

abyte = 1 << ( V % 8 );


Something like that ;)

best
Bruno

Share this post


Link to post
Share on other sites

hei

 i tryed this code

        MUTEX_LCD_TAKE;
            MIOS32_LCD_DeviceSet(14);

            APP_LCD_Cmd(0x75); // Row
            APP_LCD_Data(V);
        
            APP_LCD_Cmd(0x15); // Column
            APP_LCD_Data(H);

            static int abyte = 0;
            abyte = 1 << ( V % 8 );
        
            APP_LCD_Cmd(0x5C); // Write Pixel
            APP_LCD_Data(abyte);

            //MIOS32_LCD_CursorSet(0, 0);
            //MIOS32_LCD_BitmapPrint(bitmap);
        MUTEX_LCD_GIVE;

but its not workin... got this:

 

 

Share this post


Link to post
Share on other sites

my tryings with Bitmap, also are not working well

this code: Filterbox-V1.zip

                // calculate H V Positions
                V = v * aout[x].lfo[y];             if(V <= 0) { V=0;}      if(V >= 63)  { V=63;}
                H = h / time * counter[x][y];       if(H <= 0) { H=0;}      if(H >= 127) { H=127;}


                MUTEX_LCD_TAKE;   //////// show WAVE-FORM - S C O P E ////////
                    MIOS32_LCD_DeviceSet(14);
                    // clear screen
                    if ( sync_waiting   == 1 ) { int h; int v; for (h=0; h<128; h++) { for (v=0; v<64; v++) {  APP_LCD_BitmapPixelSet(bitmap, h, v, 0); }}}
            
                    APP_LCD_BitmapPixelSet(bitmap, H, V, 1);
            
                        MIOS32_LCD_DeviceSet(14);
                        MIOS32_LCD_CursorSet(0, 0);
                        MIOS32_LCD_BitmapPrint(bitmap);
                MUTEX_LCD_GIVE;

gave me 8 lines on the display

and i did not know why!   --- really no clue (had the same result yesterday...)

 

un words of the night:  :doubt:    STRUCTS   and   TYPES....  may it be easy when you are the architect of it, but for me it is horror!

Quote

app.c:503:57: error: incompatible types when assigning to type 'mios32_lcd_bitmap_t' from type 'struct mios32_lcd_bitmap_t (*)(u8 *, u16,  u16,  u16,  u8)'

damm i hate that structs... where are the simple arrays, code, bam ready, next task...... after 6  ours of trying to come to an end with that structs - i make a end and go to bed ... i hate structs!

 

and som other highlights:

Quote

app.c:503:21: error: 'bitmap' has an incomplete type
app.c:503:57: error: lvalue required as left operand of assignment

app.c:505:21: error: incompatible type for argument 1 of 'APP_LCD_BitmapPixelSet'

/home/mios32/trunk/modules/app_lcd/universal/app_lcd.h:45:12: note: expected 'mios32_lcd_bitmap_t' but argument is of type 'struct mios32_lcd_bitmap_t (*)(u8 *, u16,  u16,  u16,  u8)'

app.c:510:25: error: incompatible type for argument 1 of 'MIOS32_LCD_BitmapPrint'

/home/triggermatrix/mios32/trunk/include/mios32/mios32_lcd.h:125:12: note: expected 'mios32_lcd_bitmap_t' but argument is of type 'struct mios32_lcd_bitmap_t (*)(u8 *, u16,  u16,  u16,  u8)'

 

 

 

 

 

specially i wanted to get the bitmap thing to run, these documentation, did not help, and got no results after 6 ours:

Quote
mios32_lcd_bitmap_t MIOS32_LCD_BitmapInit ( u8 memory,
    u16  width,
    u16  height,
    u16  line_offset,
    u8  colour_depth  
  )      

Only supported for graphical LCDs: initializes a bitmap type and clears it with the background colour.

Example:


   // global array (!)
   u8 bitmap_array[APP_LCD_BITMAP_SIZE];

   // Initialisation:
   mios32_lcd_bitmap_t bitmap = MIOS32_LCD_BitmapClear(bitmap_array, 
                                                    APP_LCD_NUM_X*APP_LCD_WIDTH,
                                                    APP_LCD_NUM_Y*APP_LCD_HEIGHT,
                                                    APP_LCD_NUM_X*APP_LCD_WIDTH.
                                                 APP_LCD_COLOUR_DEPTH);
Parameters:
[in]  memory  pointer to the bitmap array
[in]  width  width of the bitmap (usually APP_LCD_NUM_X*APP_LCD_WIDTH)
[in]  height  height of the bitmap (usually APP_LCD_NUM_Y*APP_LCD_HEIGHT)
[in]  line_offset  byte offset between each line (usually same value as width)
[in]  colour_depth  how many bits are allocated by each pixel (usually APP_LCD_COLOUR_DEPTH)
Returns:
a configured bitmap as mios32_lcd_bitmap_t

 

s32 MIOS32_LCD_BitmapPixelSet ( mios32_lcd_bitmap_t  bitmap,
    u16  x,
    u16  y,
    u32  colour  
  )      

Inserts a pixel at the given x/y position into the bitmap with the given colour.

Example:



 
Parameters:
[in]  bitmap  the bitmap where the pixel should be inserted
[in]  x  the X position of the pixel
[in]  y  the Y position of the pixel
[in]  colour  the colour of the pixel (value range depends on APP_LCD_COLOUR_DEPTH, mono GLCDs should use 0 or 1)
Returns:
< 0 on errors

 

Here is the call graph for this function:
group___m_i_o_s32___l_c_d_ga31f22984b169

 

 

s32 MIOS32_LCD_BitmapPrint ( mios32_lcd_bitmap_t  bitmap  )   

Only supported for graphical LCDs: transfers a bitmap to the LCD at the current graphical cursor position.

Example:

Parameters:
[in]  bitmap  the bitmap which should be print
Returns:
< 0 on errors

 

Here is the call graph for this function:
group___m_i_o_s32___l_c_d_ga2db7f849aadb

 

also the structs are other written... for me logical is for example:

 typedef struct storage { 
   
        u8      SWING_16th;
        u8      SWING_32th;
        u8      SWING_Switch;                   
} store_t;
 
 store_t beat;
 store_t beat_cpy;

here i know what is going on... when using them i just write

beat.swing_16th... o

r copy them with memcpy by typing beat or beat_cpy and so on....

 

 

maybe its easyier to just understand following code (i tryed by my own, but it seems that it cant work with arrays...), to make things more directly - in sense of outputing matrices without converting them (my matrice data is most of the time x-y-z generated), maybe anyone can explain this part more exactly ( special that pointer and bitshifts things, and how to more simplyfy the code, for simple arrays as input   -  and not some crypted file "con"structs)   &  alternativly how to adapt it for realtime operation (output Pixel @ position [x][y])

Quote

  int line;
  int y_lines = (bitmap.height >> 3);

  for(line=0; line<y_lines; ++line) {
    // select the view
    APP_LCD_GCursorSet(mios32_lcd_x, mios32_lcd_y);
    APP_LCD_Cmd(0x5c); // Write RAM

    // calculate pointer to bitmap line
    u8 *memory_ptr = bitmap.memory + line * bitmap.line_offset;

    // transfer bitmap
    int x;
    for(x=0; x<bitmap.width; ++x)
      APP_LCD_Data(*memory_ptr++);
  }

  // fix graphical cursor if more than one line has been print
  if( y_lines >= 1 ) {
    mios32_lcd_y = mios32_lcd_y - (bitmap.height-8);
    APP_LCD_GCursorSet(mios32_lcd_x, mios32_lcd_y);

i can break it down to:

      int line;
      for(line=0; line<8; ++line) { // count from 0-7   &   do 8x following code:
        
            APP_LCD_GCursorSet(0,0);    // set insert Position   for Bitmap
            APP_LCD_Cmd(0x5c);          // send command "Write RAM"   to   GLCD
        
            // calculate pointer to bitmap line
            u8 *memory_ptr = bitmap.memory + line * bitmap.line_offset;
        
            // transfer bitmap
            int x;
            for(x=0; x<128; ++x)
              APP_LCD_Data(*memory_ptr++);
      }

 

 

Edited by Phatline

Share this post


Link to post
Share on other sites

just a very short note - if you want to create an oscilloscope output (i.e a waveform display) with many set (and cleared) pixels per frame, it might make sense to just send a whole framebuffer update for every frame (buffer pixels in ram, then send full screen) instead of individual pixels - you can have a look at playground/hawkeye/mbprogramma to see how it works there (implemented a .pcx bitmap loader for label OLEDs) - it is quite simple and should be fast enough if you only want to update a single display. But you need to manipulate single pixel data in a way Bruno wrote, i.e. with bitwise or, and, xor operators because of the packed memory format... The advantage of this is, that a screen only takes (128*64)/8 bytes of ram.

Have fun and good luck!
Peter

Share this post


Link to post
Share on other sites

what i noticed

        MUTEX_LCD_TAKE;   //////// CLEAR S C O P E ////////
            MIOS32_LCD_DeviceSet(14);
            MIOS32_LCD_Clear(); 
       MUTEX_LCD_GIVE;}

will clear all connected displays! not only the selected device, thats bad, because 8 displays are showing static values (describtion of UI)

a Horiz Vertic - Position  will make it not better:

        MUTEX_LCD_TAKE;   //////// CLEAR S C O P E ////////
            MIOS32_LCD_DeviceSet(14);
            APP_LCD_GCursorSet(H,V);    // (h, v) set insert Position   for Bitmap
            MIOS32_LCD_Clear(); 
       MUTEX_LCD_GIVE;}

and this is the worst (not usable slow), but @ least it dont kill the other displays:

        MUTEX_LCD_TAKE;   //////// CLEAR S C O P E ////////
            MIOS32_LCD_DeviceSet(14);
                    int ho; int ve;
                    for(ho=0; ho<128; ho++) { for (ve=0; ve<64; ve++)  {
                    APP_LCD_GCursorSet(ho,ve);    // (h, v) set insert Position for pixel
                    APP_LCD_Cmd(0x5c);          // send command "Write RAM"   to   GLCD
                    APP_LCD_Data(0);
                    }}
        MUTEX_LCD_GIVE;

 

this code for printing out Pixel is working, but it will shift all other and itself vertically about 32pixel! - what i dont understand:

//////// show WAVE-FORM - S C O P E ////////
MUTEX_LCD_TAKE;     MIOS32_LCD_DeviceSet(14);

            APP_LCD_GCursorSet(H,V);    // (h, v) set insert Position   for Bitmap
            APP_LCD_Cmd(0x5c);          // send command "Write RAM"   to   GLCD
            APP_LCD_Data(1 << ( V % 8 ));
                    
MUTEX_LCD_GIVE;

 

Share this post


Link to post
Share on other sites

ok i got rid of the 32pixel offset, by removing that cmd(0x5c)

//////// show WAVE-FORM - S C O P E ////////
MUTEX_LCD_TAKE;     MIOS32_LCD_DeviceSet(14);

            APP_LCD_GCursorSet(H,V);    // (h, v) set insert Position   for Bitmap
            APP_LCD_Data(1 << ( V % 8 ));
                    
MUTEX_LCD_GIVE;

 

now i have to find out a smart way to clear a display

 

Share this post


Link to post
Share on other sites
1 hour ago, Hawkeye said:

just a very short note - if you want to create an oscilloscope output (i.e a waveform display) with many set (and cleared) pixels per frame, it might make sense to just send a whole framebuffer update for every frame (buffer pixels in ram, then send full screen) instead of individual pixels - you can have a look at playground/hawkeye/mbprogramma to see how it works there (implemented a .pcx bitmap loader for label OLEDs) - it is quite simple and should be fast enough if you only want to update a single display. But you need to manipulate single pixel data in a way Bruno wrote, i.e. with bitwise or, and, xor operators because of the packed memory format... The advantage of this is, that a screen only takes (128*64)/8 bytes of ram.

Have fun and good luck!
Peter

ja i of course a deep look in programmer and loopa and others  --- but dont find it soo easy,  i am still new to this task, and to crystalize the information in a environment like a programmer - had not worked, it worked not out most of the time in my life... i need the root, but the root itself -for me- is sooo boring that i cant learn it... i am a bit in reverse engenieering... i know what have to done  to get what i want, but the syntax is my problem.....

i already have the problems with the "many cleared" pixel per frame.... i have to clear every lfo,cycle or env.trigger 1to8 displays, and pixelwise - it is not working

-of course i saw already the lcd-clear mios_lcd_clear(), but that clears all displays - also the 8 that need no update the whole runtime (UI-describtion)

the

Quote
mios32_lcd_bitmap_t MIOS32_LCD_BitmapInit ( u8 memory,
    u16  width,
    u16  height,
    u16  line_offset,
    u8  colour_depth  
  )  

is  just confusing, and for me not working, it always sayst that it is a function, and for that, the parameters are not right, and it have to initalize, and its not a struct and this and that...

is there no "blank" command, that let do this work the ssd1306 by itself?

Share this post


Link to post
Share on other sites

Hello,

Yes, refer to trunk/modules/app_lcd/ssd1306/app_lcd.c

you don't need the command, sorry I shared a part of the universal module code.

I don't understand the result you want to achieve(graphically) can you explain?

Like peter said, it's better to manipulate a full frame instead of singles bit, this will avoid to get wrong remaining pixels.

Best

Share this post


Link to post
Share on other sites
3 hours ago, Antichambre said:

Hello,

Yes, refer to trunk/modules/app_lcd/ssd1306/app_lcd.c

you don't need the command, sorry I shared a part of the universal module code.

I don't understand the result you want to achieve(graphically) can you explain?

Like peter said, it's better to manipulate a full frame instead of singles bit, this will avoid to get wrong remaining pixels.

Best

hei.

sure i can tell, i have made a picture:

SCOPE-explain.thumb.png.6a5f91505fb271f5

i have this LFO screen 4times, and i have also 4 screens for Envelope too (=8x scope displays - that are showing 4x8=32ENV/LFOs - i have 4 Channelstrips - this CV-Application will drive Distortion, ACs Filters...)

The same is for Envelope, except that when a Note-sustains - it will hold Position and it is not growing, until note is released... its pretty much the same., the LCD-Clear is triggered with a incoming note-on

i have in booth cases the knowledge about -how long is the duty cycle,   so i dont need to shift or sync display to left or right,  the lines is growing and thats it.

 

but also look @ the video i already posted - in the video it does what it should too (ok there are bugs, and the V-Axis has to scaled from 0-63 to 63-0, and the clear-screen is a problem...) the video:

 

Share this post


Link to post
Share on other sites

interresting ;)

for your Y axis:

//////// show WAVE-FORM - S C O P E ////////
MUTEX_LCD_TAKE;     MIOS32_LCD_DeviceSet(14);

            APP_LCD_GCursorSet(H,(63-V));    // (h, v) set insert Position   for Bitmap
            APP_LCD_Data(0x80 >> ((63-V) % 8));
                    
MUTEX_LCD_GIVE;

Where   0 <= V < 64

Edited by Antichambre
1 person likes this

Share this post


Link to post
Share on other sites

thx man... great help :cheers:

 

Share this post


Link to post
Share on other sites

na didnot work

            APP_LCD_GCursorSet(H,(63-V));    // (h, v) set insert Position   for Bitmap
            APP_LCD_Data(0x80 >> ((63-V) % 8));

give me something like this:

--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.

                                                             **

                                                                  **

                                                                        **

                                                                              **

                                                                                    **

                                                                                         **

                                 **

                                      **

                                            **

                                                  **

                                                        **

                                                             **

**

      **

            **

                  **

                        **

                             **

--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.

Share this post


Link to post
Share on other sites

got it... this works: (will post video once timing gets better...)

    // SCOPEs   //   WAVE FORM DISPLAY
    static u16 upd_count = 0;
    upd_count++;
    if ( upd_count >= Scope_Upd_Rate   ||  flag.update_LCD == 1) {  upd_count = 0; //  U P D A T E   R A T E
                // Scope Lines
                static float h = APP_LCD_WIDTH;
                static float v = APP_LCD_HEIGHT/65536.0;  // scale u16 range to 0-64 //u16 range = 0 - 65536  half is: 32768
                static int H = 0; // horizontal position
                static int V = 0; // vertical   position
                static int y = 0; // scope/lfo number
                static int x = 0; // use "channel_strip"
                float  time = lfo_cycle[x][y]; 
        
                // calculate H V Positions
                V = (65536-aout[x].lfo[y])  *  v;   if(V <= 0) { V=0;}      if(V >= 63)  { V=63;} //65536-lfo: invert screen v-whise
                H = h / time * counter[x][y];       if(H <= 0) { H=0;}      if(H >= 127) { H=127;}

                
        if ( sync_waiting   == 1 ) {
                MUTEX_LCD_TAKE;   //////// CLEAR S C O P E ////////
                    MIOS32_LCD_DeviceSet(14);
                    MIOS32_LCD_CursorSet(0, 0);  MIOS32_LCD_PrintFormattedString("                      ");  
                    MIOS32_LCD_CursorSet(0, 1);  MIOS32_LCD_PrintFormattedString("                      ");
                    MIOS32_LCD_CursorSet(0, 2);  MIOS32_LCD_PrintFormattedString("                      ");
                    MIOS32_LCD_CursorSet(0, 3);  MIOS32_LCD_PrintFormattedString("                      ");
                    MIOS32_LCD_CursorSet(0, 4);  MIOS32_LCD_PrintFormattedString("                      ");
                    MIOS32_LCD_CursorSet(0, 5);  MIOS32_LCD_PrintFormattedString("                      ");
                    MIOS32_LCD_CursorSet(0, 6);  MIOS32_LCD_PrintFormattedString("                      ");
                    MIOS32_LCD_CursorSet(0, 7);  MIOS32_LCD_PrintFormattedString("                      ");  
               MUTEX_LCD_GIVE;
           }
    
        //////// show WAVE-FORM - S C O P E ////////
        MUTEX_LCD_TAKE;     MIOS32_LCD_DeviceSet(14);
    
            APP_LCD_GCursorSet(H,V);    // (h, v) set insert Position   for Bitmap
            APP_LCD_Data(1 << ( V % 8 ));
                    
        MUTEX_LCD_GIVE;

 

Share this post


Link to post
Share on other sites

here the result:

 

 

 

Edited by Phatline
1 person likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now