# OLED Performance

**URL:** <https://community.sparkfun.com/t/oled-performance/26539>\
**Category:** Arduino\
**Created:** [April 17, 2013, 11:53am UTC](https://community.sparkfun.com/t/oled-performance/26539 "2013-04-17T11:53:14Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 17, 2013, 11:53am UTC](https://community.sparkfun.com/t/oled-performance/26539/1 "2013-04-17T11:53:14Z")

</div>

Hello there people, i need an advice here.

I’m looking to make a Raycaster in Arduino similar to the one of this video

[http://www.youtube.com/watch?feature=pl … xd6c#t=35s](http://www.youtube.com/watch?feature=player_detailpage&v=iHNqnbSxd6c#t=35s)

he made it using an OLED with SPI interface. the code for it is free so i downloaded, he stated there the exact model (which is Samsung) and controller, but i’m unable to find to buy that specific OLED Model.

i found two alternatives to sell over the web and i’d like to know if they have the same power to achieve that Raycasting with the performance that is in the video. i’m no expert in the hardware area so i’m not sure if the performance is more to do with the ATMEGA Controller than the OLED itself. the videos author also stated that even though SPI is regarded as slow for displays, the OLED thus being 128x128 is able to draw at \>30fps.

These are those i found:

[http://www.adafruit.com/products/684](http://www.adafruit.com/products/684)

[http://www.ebay.com/itm/SPI-1-5-Color-O … 1e7212fbc8](http://www.ebay.com/itm/SPI-1-5-Color-OLED-display-for-Arduino-compatible-PIC-AVR-ARM-/130762865608?pt=LH_DefaultDomain_0&hash=item1e7212fbc8)

ANY help is appreciated, thanks in advance.

-Lucas

---

<div class="post-metadata">

**Author:** ![Ross\_Robotics](https://avatars.discourse-cdn.com/v4/letter/r/cc9497/32.png) [@Ross\_Robotics](https://community.sparkfun.com/u/Ross_Robotics)\
**Post date:** [April 17, 2013, 2:36pm UTC](https://community.sparkfun.com/t/oled-performance/26539/2 "2013-04-17T14:36:32Z")

</div>

You Youtube and Ebay links are messed up.

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 17, 2013, 3:28pm UTC](https://community.sparkfun.com/t/oled-performance/26539/3 "2013-04-17T15:28:06Z")

</div>

Oops, sprry for that, fixed already 😉

Please anyone help me on this 😕

---

<div class="post-metadata">

**Author:** ![Mee\_n\_Mac](https://avatars.discourse-cdn.com/v4/letter/m/aeb1de/32.png) [@Mee\_n\_Mac](https://community.sparkfun.com/u/Mee_n_Mac)\
**Post date:** [April 17, 2013, 10:23pm UTC](https://community.sparkfun.com/t/oled-performance/26539/4 "2013-04-17T22:23:20Z")

</div>

There is no set speed for SPI transfers. IIRC the default is something like 4 MHz. If you have the source code that was used, you can see what was used for the display(s) he had. There’s no info on the E-Bay display so I can’t tell what speed it would or wouldn’t support. The Adafruit display has a link to the controller datasheet and on pg 57 of that it says the min serial cycle time it will support is 150 nS. I interpret that to mean it’ll work up to a 6.6 MHz SPI rate, perhaps higher though not guaranteed. I’ve not tried to compare the number of pixels btw the displays. Obviously if one has 2x the pixels used in the video, it’ll take 2x longer to transfer the data and that may affect the frame rate.

[http://www.adafruit.com/datasheets/SSD1331\_1.2.pdf](http://www.adafruit.com/datasheets/SSD1331_1.2.pdf)

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 17, 2013, 11:47pm UTC](https://community.sparkfun.com/t/oled-performance/26539/5 "2013-04-17T23:47:22Z")

</div>

Thanks for the reply, well in other words, the adafruit display is theoretically capable?

The ebays controller is the SSD1351u3

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 18, 2013, 12:45am UTC](https://community.sparkfun.com/t/oled-performance/26539/6 "2013-04-18T00:45:56Z")

</div>

I found the ebays controller DS:

[http://www.embeddedartists.com/sites/de … SD1351.pdf](http://www.embeddedartists.com/sites/default/files/support/datasheet/SSD1351.pdf)

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 18, 2013, 1:35am UTC](https://community.sparkfun.com/t/oled-performance/26539/7 "2013-04-18T01:35:27Z")

</div>

So, i’m gonna do some math here, correct me if i’m wrong (I really don’t know much about electronics).

You said it to run at 6.6 MHz, that gives us 6,600,000 Bits per second transfer rate?

So considering the screen is 96 x 64 Pixels = 6144 total Pixels

i don’t remember how much data is needed for each pixel, i think its 2 bytes, so we need 6,144 x 16 = 98,304 bits needed to refill the whole screen;

6,600,000 / 98,304 = 67.13, so that gives us 67 Frames per second?

Sorry i’m mistaken a lot, as i don’t understand much of the logic underlying those technologies.

Thanks

---

<div class="post-metadata">

**Author:** ![Mee\_n\_Mac](https://avatars.discourse-cdn.com/v4/letter/m/aeb1de/32.png) [@Mee\_n\_Mac](https://community.sparkfun.com/u/Mee_n_Mac)\
**Post date:** [April 18, 2013, 3:55am UTC](https://community.sparkfun.com/t/oled-performance/26539/8 "2013-04-18T03:55:25Z")

</div>

Your math is about right. At a glance it looked as the controller did transfer 1 byte at a time so there will be a little wasted time btw each byte’s transfer, and so the overall transfer rate a tad slower … but the above is good enough for now. There’s also time needed to tell the controller what type of data it’s getting and what address the data is going to. I’d expect that you’d only need to specify the stating address and perhaps the number of bytes and then stream the data across (vs send addr, data, addr, data). If it’s the latter then the time needed just to transfer data could be 2x as long.

I think your 2 bytes per pixel is correct. Perhaps in grayscale mode there’s a way to reduce the data needed as there’s only 64 different grayscale levels (6 bits). Again you’d have to read the datasheet or infer the transfer size from the source code. A lot of what can be done can be told by looking at the code as used.

The next question is how the controller handles the data to refresh the display. How long does it take to update the pixels and can it be reading in the data for the next frame while it’s updating the screen ? That is, doing 2 things simultaneously. I’d have to spend some time going through the datasheet but at 1’st blush I’d guess that 30 fps looks do-able.

I note the Adafruit display has the option of using an 8 bit parallel interface and so the above questions become moot if you have the pins to spare.

You might post on an Adafruit forum asking about achieved frame rates with that display. Or perhaps Google the controller PN and see what people claim.

The other controller looks much the same but has more pixels and thus more bits to transfer. And it’s seems to use 18 bits/pixel, I’m not sure if it uses an odd 9 bit / transfer or you have to waste time transfering another byte ? It does list a 50 nS clock period though, perhaps 3x faster than the other controller … if the Arduino could support that ?!?

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 18, 2013, 3:55am UTC](https://community.sparkfun.com/t/oled-performance/26539/9 "2013-04-18T03:55:54Z")

</div>

Its very hard to find someone commenting anything about those displays.

the guy from the video used an arduino too so i assume he is capable of supporting too,

i found out that the eBay display can be configured to use 16 or 18 bits for 64k and 262k color depths.

so, using the same math from above, and assuming it is 3x faster:

Raw Data Transfer: 19,800,000

128 pxls x 128 pxls = 16384 pxls

Number of data needed for 262k = 294912

Number of data needed for 65k = 262144

19,800,000 / 294912 = 67.13

19,800,000 / 262144 = 75.53

so, can we assume they are almost equivalent? as i can see if i lower the color depth i can gain even more “frames”.

I think im going to buy the 128x128 as for i didnt found another one to compare and these two look almost the same on performance, based on our math.

---

<div class="post-metadata">

**Author:** ![Mee\_n\_Mac](https://avatars.discourse-cdn.com/v4/letter/m/aeb1de/32.png) [@Mee\_n\_Mac](https://community.sparkfun.com/u/Mee_n_Mac)\
**Post date:** [April 18, 2013, 5:49am UTC](https://community.sparkfun.com/t/oled-performance/26539/10 "2013-04-18T05:49:07Z")

</div>

I would only say that I think the fastest SPI clock that the ATMega328 supports is 8 MHz. A faster, more capable controller may not translate into any faster transfer speed. But if the guy in the video did what he did with an ATMega328 and the same pixel count and color depth … seems like a fair bet you can replicate it.

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 18, 2013, 6:27am UTC](https://community.sparkfun.com/t/oled-performance/26539/11 "2013-04-18T06:27:54Z")

</div>

Ok thanks for the advices, shall buy it tomorrow, i was just in doubt if the difference of oled would turn it impossible.

Thanks Mee\_n\_Mac!

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 18, 2013, 1:05pm UTC](https://community.sparkfun.com/t/oled-performance/26539/12 "2013-04-18T13:05:15Z")

</div>

Now i started thinking, you’re right Me\_n\_mac, Arduino on SPI interface has the maximum Clock of 8Mhz (16mhz/2) so even if the 128x128 OLED can run at more than 8Mhz, it doesnt matter.

I made the final math

[[![](https://canada1.discourse-cdn.com/sparkfun/original/2X/b/baf68a52aef8fd45bee496416c20a2e0dc3790db.jpeg) ![](https://canada1.discourse-cdn.com/sparkfun/original/2X/b/baf68a52aef8fd45bee496416c20a2e0dc3790db.jpeg)](http://imgur.com/emEOon7)

another interesting discovery is that i found on the Video Authors Code the following:

```auto
//	Fill a 16 bit color
//	Blit 16 bit pixels
//	Blit 8 bit indexed pixels from palette
//	400,000 pixels/sec on a 16Mhz AVR for Solid fills and 16bpp blits
//	380,000 pixels/sec for indexed blits
//	The code looks crazy 'cause it is using shadow of the spi data clocks
//	do work for the next round. It is within 10% of a hardware 9 bit spi

```

So he’s using 65k Color Depth, he manages to get 400,000 pixels/sec on an arduino,which results more or less 24,4 FPS.

The Interesting fact is that on the math _theoretically_ it should perform at 500,000 pixels/sec. So that time loss you said its true, so its not Raw Math, its something around 80% of the math.

Now im afraid again of the choice, but it seems to be OK to use the 128x128 at 65k Colors.]([Imgur: The magic of the Internet](http://imgur.com/emEOon7))

---

<div class="post-metadata">

**Author:** ![Mee\_n\_Mac](https://avatars.discourse-cdn.com/v4/letter/m/aeb1de/32.png) [@Mee\_n\_Mac](https://community.sparkfun.com/u/Mee_n_Mac)\
**Post date:** [April 18, 2013, 2:06pm UTC](https://community.sparkfun.com/t/oled-performance/26539/13 "2013-04-18T14:06:00Z")

</div>

About the only thing I gathered from glancing at the datasheet was that the 3-wire SPI transfers are an odd 9 bit transfer (so you might have to work some special coding to make that happen). Now you might think that’s because of the color depth but nope, it’s 8 bits of data and 1 bit of command-vs-data identifier. The 4-wire SPI breaks that 9’th bit out and puts it on the 4’th “wire” (so SPI transfers are 8 bits).

At the 65k depth it seems that 2 transfers are all that’s needed, the RGB components are packed into 16 bits (see table 8-8 in the file you linked to). Using grayscale doesn’t help as it works on the RGB data _after_ it’s been transferred to the LCD controller. There are perhaps half a dozen or so command registers to be setup prior to every updating of the 128x128 pixels but it looks that you can just transfer pixel1 data, pixel2 data, etc, etc until done and the controller knows to bump the addressing of GDDRAM for each pixel.

As you’ve figured out there’s some overhead that decreases the true overall transfer rate. One thing I think can be done with the 128x128 display is trade off pixels for frame rate. I don’t think you have to display all the pixels. And I believe you can, with some added overhead, transfer only those that will get displayed. So if frame rate is uber important to you, you may give that a thought.

What I don’t know is how, _or even if_, you can sync the LCD updating with the transferring of new data so as to prevent screens that have part old data, part new data. But perhaps that’s like complaining about how poorly pigs fly.

Good luck with all this.

---

<div class="post-metadata">

**Author:** ![lordareon](https://avatars.discourse-cdn.com/v4/letter/l/8edcca/32.png) [@lordareon](https://community.sparkfun.com/u/lordareon)\
**Post date:** [April 18, 2013, 2:30pm UTC](https://community.sparkfun.com/t/oled-performance/26539/14 "2013-04-18T14:30:25Z")

</div>

I’ve seen in another thread (the only one about the 128x128 i could found) in they were complaining that they couldnt “write to pixel”, but write to the ram, and the controller would draw them, thus agreeing in what you said and i dont know if thats good or bad though. It is stated on the DS that it has “programable framerate”, though i cant find on the datasheet how to achieve that.

I found out too that it supports 256 color mode, that would mean that only one byte would be used on the transfer?

As for the adafruit one ive seen that it has an “hardware accelerated drawing” that help drawing lines, squares, etc… That feature would help?

As i will try to port the existing raycast code, the author, after casting the rays he calls this function:

```auto
OLED_Slice(ray,SCREEN_HEIGHT,buffer,(u8*)palette);

```

Which is a wrapper to another function

```auto
void OLED_Slice(u8 x, u8 height, u8* buffer, u8 *palette)
{
	FillBlit(0,height,buffer,palette);
}

```

And fillBlit

```auto
void FillBlit(u32 color, u32 count, const u8* data = 0, const u8* palette = 0)
{
	SPSR |= 1;	// 2x clock

	u8 a,b;
	
	//	Handle 16 bit blits and index mode
	signed char x = 0;
	u8 y;
	const u8* p = 0;
	if (data)
	{
		a = *data++;
		x = 1;
		if (palette)
		{
			p = palette + (a << 1);
			a = pgm_read_byte(&p[0]);
			b = pgm_read_byte(&p[1]);
			x = -1;
			y = 0;
		}
	}
	else
	{
		a = color >> 8;
		b = color;
	}

	count <<= 1;
	int loop = count >> 8;
	u8 c = count;
	if (c)
		loop++;

	SPCR = _BV(MSTR) | _BV(SPE);	// SPI Master ... get it?
	while (loop)
	{
		// up to 256 per loop
		for (;;)
		{
			SPDR = a; // Now we have 16 clocks to kill

			//	16 clocks to do fill, blit or indexed blit

			//	Indexed blit - 380k
			if (x < 0)
			{
				if ((y^=1))
				{
					a = b;
					p = palette + ((*data++) << 1);
					if (--c)
						continue;	// Early out
				} else {
#ifdef OLED96	// shameful hack TODO
					a = p[0];
					b = p[1];
					nop();
					nop();
#else
					a = pgm_read_byte(&p[0]);
					b = pgm_read_byte(&p[1]);
#endif
					if (--c)
						continue;	// Early out
				}
				break;
			}

			if (x)
			{
			//	Blit
				a = *data++;
				nop();
				nop(); // 400k
			}
			else
			{
				// Solid Fill
				u8 t = a;	// swap pixel halves
				a = b;
				b = t;
				nop();
				nop(); // 400k
			}
			if (!--c)
				break;	// 5 
		}; // loop takes 3 clocks
		c = 0;
		loop--;
		while (!(SPSR & _BV(SPIF)));	// wait for last pixel
	}
	SPCR = 0;
}

```

This last function im not certain of what it does, i think it fills a buffer of a single slice of raycast, maybe im wrong, so i think i would have to make it write to the controllers RAM.

---

<div class="post-metadata">

**Author:** ![Mee\_n\_Mac](https://avatars.discourse-cdn.com/v4/letter/m/aeb1de/32.png) [@Mee\_n\_Mac](https://community.sparkfun.com/u/Mee_n_Mac)\
**Post date:** [April 18, 2013, 3:04pm UTC](https://community.sparkfun.com/t/oled-performance/26539/15 "2013-04-18T15:04:49Z")

</div>

The last function is doing the SPI transfers. But I looked and am unable to figure out all it’s inner workings. I can see where some colors are being packed into the 16 bits. I don’t see what the “palette” sections are intended to do.
