Phatline Posted April 19, 2018 Report Share Posted April 19, 2018 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); Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 19, 2018 Author Report Share Posted April 19, 2018 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 Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 19, 2018 Author Report Share Posted April 19, 2018 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? Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 19, 2018 Report Share Posted April 19, 2018 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 Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 19, 2018 Author Report Share Posted April 19, 2018 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: Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 19, 2018 Author Report Share Posted April 19, 2018 (edited) 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: 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: 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: MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_BitmapPrint(bitmap); Parameters: [in] bitmap the bitmap which should be print Returns: < 0 on errors Here is the call graph for this function: 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 April 20, 2018 by Phatline Quote Link to comment Share on other sites More sharing options...
Hawkeye Posted April 20, 2018 Report Share Posted April 20, 2018 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 Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 20, 2018 Author Report Share Posted April 20, 2018 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; Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 20, 2018 Author Report Share Posted April 20, 2018 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 Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 20, 2018 Author Report Share Posted April 20, 2018 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? Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 20, 2018 Report Share Posted April 20, 2018 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 Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 20, 2018 Author Report Share Posted April 20, 2018 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: 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: Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 20, 2018 Report Share Posted April 20, 2018 (edited) 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 April 20, 2018 by Antichambre 1 Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 20, 2018 Author Report Share Posted April 20, 2018 thx man... great help Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 23, 2018 Author Report Share Posted April 23, 2018 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: --------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------. ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** --------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------.--------------------------------. Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 26, 2018 Author Report Share Posted April 26, 2018 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; Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 28, 2018 Author Report Share Posted April 28, 2018 (edited) here the result: Edited April 28, 2018 by Phatline 1 Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 28, 2018 Report Share Posted April 28, 2018 Great! Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 29, 2018 Report Share Posted April 29, 2018 refer to this post for bitmap manipulation Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.