SSD0303 OLED Display - Clock Demo

nick12ab

Senior Member
Uses a 14M2 and OSRAM OLED display.

(Note: If this is your first time using this display I recommend starting with the text demo first because it uses less components so there are less opportunities to make a mistake when making the circuit)

I used a DS1307 (at 3V - should really use a 3V-approved part like DS1338 but didn't have any) and to generate the voltage required to drive the OLED two 7660s are used (because I didn't have the correct inductor in order to use the built-in voltage booster). Due to that latter thing the component count could be reduced. I used the display in i2c mode.

The four switches are used to: Increment hours; increment minutes; zero seconds and change brightness.



This display has no built-in fonts so a font is specified using a lookup table. Since only large numbers and nothing else is required for this program, that is all that is specified using the table command.

Code:
#picaxe 14m2
#no_end
#terminal off
symbol brightnessstate0 = bit0
symbol brightnessstate1 = bit1
symbol buttonvar = bit2
symbol loopcounter = b4
symbol oldhour = b5
symbol oldminute = b6
symbol oldsecond = b7
symbol hour = b8
symbol minute = b9
symbol second = b10
symbol dataout = b11
symbol dataout2 = b12
symbol dataout3 = b13
symbol readvar = b14
symbol hourbutton = pinC.4
symbol minutebutton = pinC.3
symbol secondbutton = pinC.2
symbol brightnessbutton = pinC.1


main:
	pullup %0001111100111110
	setfreq m32
	oldhour = 254			'Sets 'old' time variables to this value
	oldminute = 254			'which won't ever happen to force a
	oldsecond = 254			'display update
	hi2csetup i2cmaster,%01111000,i2cslow_32,i2cbyte
	pause 150
	hi2cout 0,(%10100100)		'Set entire display on/[normal]
	hi2cout 0,(%10101000)		'Multiplex rate command
	hi2cout (%00001111)		'Set multiplex rate for 16 rows
	hi2cout 0,(%10110000)		'Set page address for read/write to 0
	hi2cout 0,(%11000000)		'Set scan direction
	hi2cout 0,($81,$00)		'Set contrast
	hi2cout 0,($DD)			'Enable "low power mode" (whatever that does)
	pause 150
	hi2cout 0,(%10110000)		'Top line
	hi2cout 0,($00,$10)		'Reset column register
	hi2cout $40,(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$18,$18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$18,$18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
	hi2cout 0,(%10110001)		'Bottom line
	hi2cout 0,($00,$10)		'Reset column register
	hi2cout $40,(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$C,$C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$C,$C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
	hi2cout 0,(%10101111)		'Turn on display
	
	do
		hi2csetup i2cmaster,%11010000,i2cslow_32,i2cbyte
		hi2cin 0,(second,minute,hour)
		hi2csetup i2cmaster,%01111000,i2cslow_32,i2cbyte
		if second <> oldsecond then
			oldsecond = second
			dataout = second & $F0 / 16
			dataout2 = dataout * 12
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110000)		'Top line
			hi2cout 0,($00,$14)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			dataout2 = dataout2 + 120
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110001)		'Bottom line
			hi2cout 0,($00,$14)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			
			dataout = second & $0F
			dataout2 = dataout * 12
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110000)		'Top line
			hi2cout 0,($0D,$14)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			dataout2 = dataout2 + 120
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110001)		'Bottom line
			hi2cout 0,($0D,$14)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
		end if
		if minute <> oldminute then
			end if
			oldminute = minute
			dataout = minute & $F0 / 16
			dataout2 = dataout * 12
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110000)		'Top line
			hi2cout 0,($00,$12)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			dataout2 = dataout2 + 120
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110001)		'Bottom line
			hi2cout 0,($00,$12)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			
			dataout = minute & $0F
			dataout2 = dataout * 12
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110000)		'Top line
			hi2cout 0,($0D,$12)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			dataout2 = dataout2 + 120
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110001)		'Bottom line
			hi2cout 0,($0D,$12)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
		if hour <> oldhour then
			oldhour = hour
			dataout = hour & $F0 / 16
			dataout2 = dataout * 12
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110000)		'Top line
			hi2cout 0,($00,$10)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			dataout2 = dataout2 + 120
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110001)		'Bottom line
			hi2cout 0,($00,$10)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			
			dataout = hour & $0F
			dataout2 = dataout * 12
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110000)		'Top line
			hi2cout 0,($0D,$10)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
			dataout2 = dataout2 + 120
			dataout3 = dataout2 + 11
			hi2cout 0,(%10110001)		'Bottom line
			hi2cout 0,($0D,$10)		'Reset column register
			for loopcounter = dataout2 to dataout3
				readtable loopcounter,readvar
				hi2cout $40,(readvar)
			next
		end if
		hi2csetup i2cmaster,%11010000,i2cslow_32,i2cbyte
		if hourbutton = 0 and buttonvar = 0 then
			buttonvar = 1
			dataout = hour & $F0 / 16 * 10
			dataout2 = hour & $0F
			dataout = dataout + dataout2
			if dataout < 23 then
				inc dataout
			else
				dataout = 0
			end if
			dataout2 = dataout // 10
			dataout = dataout / 10 * 16 or dataout2
			hi2cout 2,(dataout)
		end if
		if minutebutton = 0 and buttonvar = 0 then
			buttonvar = 1
			dataout = minute & $F0 / 16 * 10
			dataout2 = minute & $0F
			dataout = dataout + dataout2
			if dataout < 59 then
				inc dataout
			else
				dataout = 0
			end if
			dataout2 = dataout // 10
			dataout = dataout / 10 * 16 or dataout2
			hi2cout 1,(dataout)
		end if
		if secondbutton = 0 and buttonvar = 0 then
			buttonvar = 1
			hi2cout 0,(0)
		end if
		hi2csetup i2cmaster,%01111000,i2cslow_32,i2cbyte
		if brightnessbutton = 0 and buttonvar = 0 then
			if b0 = 0 then
				hi2cout 0,($81,$00)
				inc b0
			elseif b0 = 1 then
				hi2cout 0,($81,$0F)
				inc b0
			elseif b0 = 2 then
				hi2cout 0,($81,$2F)
				inc b0
			else
				hi2cout 0,($81,$7F)
				b0 = 0
			end if
			buttonvar = 1
		end if
		if brightnessbutton = 1 and secondbutton = 1 and minutebutton = 1 and hourbutton = 1 then
			buttonvar = 0
		end if
	loop


table 000,($f0,$fc,$0e,$06,$03,$03,$03,$03,$06,$0e,$fc,$f0,$0,$0,$0,$0,$0c,$fe,$ff,$00,$0,$0,$0,$0,$08,$0c,$0e,$06,$03,$03,$03,$83,$c3,$e6,$3e,$18,$3,$03,$03,$03,$c3,$e3,$f3,$db,$cf,$87,$03,$1,$00,$80,$c0,$e0,$b0,$98,$8c,$fe,$ff,$80,$80,$80,$7f,$7f,$63,$23,$33,$33,$33,$33,$63,$e3,$c3,$03,$e0,$f8,$1c,$8e,$87,$83,$83,$83,$83,$00,$00,$00,$3,$3,$03,$03,$03,$83,$e3,$73,$1b,$f,$7,$3,$3c,$7e,$e6,$c3,$c3,$c3,$c3,$c3,$c3,$e6,$7e,$3c,$18,$7c,$e6,$c3,$83,$83,$83,$c3,$c7,$ee,$fc,$f0)
table 120,($7,$1f,$38,$30,$60,$60,$60,$60,$30,$38,$1f,$7,$0,$0,$0,$0,$60,$7f,$7f,$60,$0,$0,$0,$0,$40,$60,$70,$78,$7c,$6e,$67,$63,$61,$60,$60,$60,$0,$18,$38,$30,$60,$60,$60,$60,$71,$3f,$1f,$0,$1,$1,$1,$1,$1,$1,$1,$7f,$7f,$1,$1,$1,$4,$1c,$38,$30,$60,$60,$60,$60,$30,$38,$1f,$7,$7,$1f,$3b,$73,$61,$61,$61,$61,$61,$33,$1e,$c,$0,$0,$00,$70,$7e,$f,$1,$0,$0,$0,$0,$0,$1e,$3f,$33,$61,$61,$61,$61,$61,$61,$33,$3f,$1e,$0,$0,$0,$60,$61,$61,$61,$71,$38,$1c,$f,$3)
Breadboard assembly: (not programmed to be clock in this photo)



I used this adapter to convert the connector into a 1" pitch and a bit of stripboard was used to create a gap between the two rows of pins to allow it to be inserted into stripboard.

Picture of clock display:



So far it has been running for 2 weeks on the same set of 2xAA NiMH rechargeables on the lowest brightness setting.

Also available: OS96016PP08MB2B10 OLED Text Demo
 
Last edited:

nick12ab

Senior Member
So far it has been running for 2 weeks on the same set of 2xAA NiMH rechargeables on the lowest brightness setting.
It eventually ran out of battery after three weeks.

Something I want to point out regarding the brightness settings - or contrast as they call it - the graph on page 30 of the datasheet shows that current consumption is directly proportional to the set level - however the apparent brightness to the eye is a square root graph shape instead.
 
Top