yeah that actually works but it will only let me set one pixel per column, like the scope.
looking at your code i think it might be much easier for you to add something that reads from a straight up display buffer table, rather than decoding the 128x int from the scope for the 8x8pixel pages? if you don't feel like doing it i'd love to give it a try if you can hold my hand on how to get the embedded version to re-compile...
SPI/I2C OLED display
you can't really use an embedded version. just copy it to your local files (with the .h file that contains the font) and edit that.
includes do not work with embedded objects, has been like that for ages now
My OLED objects do not include an image buffer and they are optimized specifically for scopes and text. So they are light on CPU and RAM.
If you want to make a general purpose OLED driver you will have to implement an image buffer and the primitives to set and reset pixels and line drawing (Bresenham)... Also, you may need to do double buffering to avoid flickering. Every image buffer will take 1kByte from RAM.
yeah thats what i as gonna try and do, set up the image buffer as a big table for now, but i was failing to change your OLED object to convert the OLED "pages" from a bigger table that represents each pixel, instead of the "1.5 dimensional" scope table. from looking at the code i think while probably inefficient that shouldn't be too hard to realize, so then one could start building proper gfx routines based on that image buffer table. i think it would be graet ot have a way to just access every pixel manually for now, even at the cost of 1-2k ram.
i will try and see if i get anywhere with @lokki's recommendation. did the same before when modifying some MI objects.
Don't forget that it is a 128x64 on off display (no greyscales) complicated graphics would look like retro computing, I mean ZX81 sinclair retro...
yeah i udnerstand, i don't wanna go all out gfx madneses, but what i do on thee same OLEDs controlled by a teensy is just displaying basic info in a little more flexible style. for example displaying ADSR shapes or sample waveform overviews would be fun for me, or custom shaped icons and bars. what you did already is absolutely incredible and more than good enough for the most use cases, especially cause a lot of customisation can still be done by just hhacking into your font file i guess. it just seems like a pretty low hanging fruit to just replace the scope buffer with a more universal 128x64x1bit buffer, so i'll see if i get around to trying something!
edit.
i felt adventurous after working on my synth, got the stock 24band analyzer object to display at least something on the OLED, no luck in making it pretty or getting the full rfft to display, yet
working on some other stuff i finally understood how to work with includes on custom objects... so maybe one of these days i'll give the OLEDs a shot
Just got this working on a modified AxoControl and wanted to thank @SmashedTransistors and everyone else who helped get this going. So very cool...
Regards,
John
ok @SmashedTransistors so what i did is hack your OLED object, currently ignores modes and all text stuff and just copies 128 bytes for each of the 8 pages, from an objref "t" array that now is [8][128]. then i started doing some basic pixel routines so you can manipulate them in a normal [128,64] pixel adressing. stole a line algorithm from adafruit, somewhat working. i'll post code snippets later in casee someone wants to investige further. it's really quick and dirty though and i am sure very inefficiently written. no overflow protection or whatever. memory use should remain at 1kB though.
main Thread (reduced the thdSleep from iirc 32 to 4 for smooth updates, tradeoff probably more audio glitches, less cpu left). might need a double buffer or some syncing to avoid the current screen tearing when OLED gets updated while buffer changes are happening.
msg_t ThreadX2()
{
setup();
while (!chThdShouldTerminate()) {
if(!disable){
for(int i = 0; i < 8; i++){
memcpy(tY, &attr_scope.t[i][0],128);
sendPage(i);
}
}
chThdSleepMilliseconds(4);
}
chThdExit((msg_t)0);
}
and for the sendPage i just ripped out all the text/scope/mode stuff and again just copied memory from temp buffer to tx buffer (i guess one could avoid the temp buffer with this method altogether since all actual rendering has to happen somewhere else anyways haha. saves 128B memory.
void sendPage(int page){
i2cAcquireBus(&I2CD1);
//prepare transmission to the "page"
cmd(COLUMNADDR, 0, 127); // Column start end
cmd(PAGEADDR, page, page); // Page start end
if(attr_type == 1106){
cmd(0xB0 + page);//set page address
cmd(2 & 0xf);//set lower column address
cmd(0x10 | (2 >> 4));//set higher column address
}
i2cReleaseBus(&I2CD1);
//
memcpy(txbuf, tY, 128);
//
//transmit the page
txbuf[0] = 0x40;
i2cAcquireBus(&I2CD1);
i2cMasterTransmitTimeout(&I2CD1, attr_I2CADDR, txbuf, 129, rxbuf, 0, 30);
i2cReleaseBus(&I2CD1);
}
.
temporary gfx code. forum software blockquote sucks for spacing. that being said, i wish the axo patcher had an auto-format function.
uint8_t t[8][128];
//
void clearDisplay (void){
for (int i=0; i<8; i++){
for (int j=0; j<128; j++){
t[i][j]=0b00000000;
}
}
}
//
void writePixel (uint8_t x, uint8_t y){
uint8_t ppage = y>>3;
uint8_t prow = y & 0b00000111;
//LogTextMessage("page %d - row %d", ppage, prow);
t[ppage][x] += (1<<prow);
}
all this being said and done i agree 100% that any more elaborate GFX/UI tasks are better offloaded to an external teensy or whatever MCU, and not hog your precious DSP board with that.
Superb weasel, this is awesome...well done
you and SmashedTransistors working together on this, I'm very excited
I assume thats a bitwise or add or something? I was just calling some blind shots.. Good call, makes sense!
Haha appreciate the kind words but it’s really all smashis work, i merely deleted a couple lines. I have a couple more thoughts on this and will fwd to you guys but tbh i think i should focus on working on my actual project rather than doing gfx libraries i’ll never use lol
Smasher i’ll send you what i have after one more day of cleaning up maybe you have a vibe to make it into something real!
I've made it, and it was very straightforward
Removed the resistor on the OLED and connected the other two pads.
Pull-up 10k resistors on PB8 and PB9
Working!!
Now onto the hard part, the code
gpio/i2c/config has these two lines:
palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(4)|PAL_STM32_PUDR_PULLUP|PAL_STM32_OTYPE_OPENDRAIN);// SCL
palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(4)|PAL_STM32_PUDR_PULLUP|PAL_STM32_OTYPE_OPENDRAIN);// SDA
Which means, it configures PB8 and PB9 with STM32 internal pullups.
yes I've been working with the @SmashedTransistors objects, when I said code I meant patching stuff.. I don't actually code anything in the Axoloti
Hey guys, lately I wanted to play around with the Oled object from SmashedTransistors.
Beign quite a beginner in terms of code, i thought I could just embed the Oled Object as a patch/object and then try to play with the code.
Unfortunately, the resulted patch does not compile after that operation, it gets stuck on "Done changing working directory".
Is there something I'm missing? Is there a solution for that?
thanks!
sure. the OLED objects use an include, look at the original file. in short: you cannot embed them. you rather want to copy the file to your local library and copy the included file over as well (preserve the folder structure)...
Thanks, yes it make sense, the included file is the font informations I guess.
I'll try it tomorrow!
I've always felt that these tiny OLEDs have much more potential for controlling the Axoloti so I've started messing with tiar's OLED objects.
First of all I've added an 'invert Line' inlet which highlights one line just like when you'd scroll through a menu line by line (with integer inlet: 0=off, 10=line1, etc.).
For now I am adding functions via additional inlets/outlets to the existing objects, but that would leave it to each user to implement a higher-level UI on their OLEDs.
For ease of use I would eventually want to create a small collection of "menu UI" objects which offer a menu tree that:
- must be easy to populate and navigate (dedicated menu tree object)?
- can send and receive values to/from objects?
- can interface with preset objects so you could load, edit, and store presets
Any thoughts?
Great ideas! I also feel that having a good collection of Oled objects would change a lot the approach of Axoloti to some people. Some friends bought an Axoloti and sold it back later because they were lacking visual feedback and the did not have the knowledge or the will to fiddle around.
I'm also currently trying to study Tiar's objects, I'm quite noobish with C++ and doing more reverse engineering than coding at the moment, so I can't offer my help on the technical side.
I did start, however, to program my own fonts as well as using these to create animations on the screen.
Right now, I'm still limited by the number of lines (pages) and characters and I need to build a puzzle typeface to display an image and animate it.
I believe that a great addition would be the possibility to change (via an inlet or a selector) the number of line the user wants to display (as well as the size of the font).
being able to play around with the graphics would be a great addition and could lead to great custom animations, fonts ans menus.