lcd code not doing what I want

stan74

Senior Member
Hi guys. I've posted some oled code that I thought may be useful and thought a "scope for 08m2" would be nice as seems lots of people have trouble with getting a working example to start off with it's tedious so posted template code but for picaxe with 1K scratchpad. I got this code from a light meter I posted and compiled to 255 bytes 08m2. I didn't use x2 stuff like power or rotate or set bit so it was portable but I just get a few pixels.
Anyone other than hippy (don't spoil it) want to point out my errors and then it could be handy code example to play with. 1st time I used bptr. You can assume the oled is working and set up so I didn't post the boring stuff. inefficient 1st draft ...so don't point it out...please :)


Code:
gosub InitialiseLcd
gosub ClearDisplay
adcsetup = %0000000000000010
for bptr=0 to 127 ;get 127 samples and store twice in 2 128 byte arrays 
	readadc a.0,sample
	@bptr = sample/4 ;fit to screen res and store sample in 1st array
	push bptr ;save array pointer
	bptr=bptr+127
	@bptr=sample/4 ;store same sample in 2nd array
	pop bptr ;restore array pointer
next bptr
;
start:
for bptr =0 to 127 ; number of bytes in array
	push bptr ;save pointer
	bptr=bptr+128 ;point to 2nd array
	sample=@bptr/8 ;screen row
	pop bptr ;restore pointer to 1st array
	hi2cout (0,SSD1306_PAGEADDR)
	hi2cout (0,sample) ;set screen row 0 to 7
	hi2cout (0,7) ;control code thingy
;
	hi2cout (0,SSD1306_COLUMNADDR)
	hi2cout (0,bptr) ;set column 0 to 127
	hi2cout (0,127) ;control code thingy
;
	hi2cout (64,0) ;erase old screen data in 1st array	
;
	;sample=@bptr
	pixel=@bptr and 7 ;pixel in byte
	screen_byte=1
	do until pixel=1
		screen_byte=screen_byte*2 ;get pixel position in byte!!! maybe wrong this bit "not a pun"
		dec pixel
	loop
;	
	hi2cout (0,SSD1306_PAGEADDR)
	hi2cout (0,sample) ;set row 0 to 7
	hi2cout (0,7) ;control code thingy
;
	hi2cout (0,SSD1306_COLUMNADDR)
	hi2cout (0,bptr) ;set columnn 0 to 127
	hi2cout (0,127) ;control code thingy
;
	hi2cout (64,screen_byte) ;plot new screen data in 1st array as pixel
next bptr
;get new samples into 1st array
for bptr=0 to 127
	temp=@bptr    ; get old sample
	bptr=bptr+128 ; point to 2nd array
	@bptr=temp    ; copy last data from 1st array to old data in 2nd array for erasing on screen
	bptr=bptr-128 ; restore bptr	
;	
	readadc a.0,sample ;get new sample
	sample=sample/4 ;scale to screen res	
	@bptr=sample ;store new data in 1st array
next bptr
;
goto start
The code should erase display old data-2nd array, then display new data-1st array,then swap 1st array with 2nd then fill 1st array with new data and repeat.
 
Last edited:

AllyCat

Senior Member
Hi,

"scope for 08m2" .... for picaxe with 1K scratchpad.

bptr=bptr+127
M2s don't have any scratchpad, and the 08M2 just 128 bytes of RAM! Also, the 08M2 bptr has only 7 bits, so just wraps back around to zero after 127.

Cheers, Alan.

PS: If it does have more RAM (e.g 14, 18 and 20 M2s) then you should use bptr - bptr + 128
 
Last edited:

stan74

Senior Member
cheers Alan.I'm testing it on 28x2 but without the added features so for m2 also. check my array scanning and the do loop for rotating a byte from 1 to 7 pixel please..easier with x2. No scratch pad? I did the code with write read eprom but thought naff but thought m2 had 255 to 1k??
 

AllyCat

Senior Member
Hi,

Most M2s have 512 bytes of RAM (and a 9-bit bptr) but the lower bytes overlay the normal bit, byte and word variables.

You haven't shown any SYMBOL declarations, but you'd need to use S_W1 ... S_W6 for any variables such as _COLUMNADDR, _PAGEADDR, etc., if you're using all the RAM as "scratchpad".

Cheers, Alan.
 

stan74

Senior Member
it uses no ram to display 128 samples and fill the screen with 1024 zeros to clear screen and repeat but not a tidy real time display..hence the array palava...just would look nicer..maybe
 

stan74

Senior Member
ok Alan I'll post the whole code. I thought with others having bought these cheapo lcds I give some code to play with. Most people can't display text and the control codes are a pain.
Code:
#picaxe 28x2
setfreq em64
symbol sample=b14
symbol pixel=b15
symbol screen_byte=b16

	SYMBOL  SSD1306_ADDR  = $3C << 1    ; this is the I2C address ($78)
	

	' b0-b3 are used for temp loops
	
	SYMBOL  DispNum  = W2
	
	SYMBOL  row = b6
	SYMBOL  col = b7
	
	
	SYMBOL  temp  = b11
	SYMBOL  aByte = b12
	SYMBOL  index = b13
	SYMBOL TWI_BUFFER_LENGTH 		= 32	
	SYMBOL SSD1306_LCDWIDTH   		= 128
  	SYMBOL SSD1306_LCDHEIGHT            = 64
	
	SYMBOL SSD1306_SETCONTRAST 		=0x81
	SYMBOL SSD1306_DISPLAYALLON_RESUME 	=0xA4
	SYMBOL SSD1306_DISPLAYALLON 		=0xA5
	SYMBOL SSD1306_NORMALDISPLAY 		=0xA6
	SYMBOL SSD1306_INVERTDISPLAY 		=0xA7
	SYMBOL SSD1306_DISPLAYOFF 		=0xAE
	SYMBOL SSD1306_DISPLAYON 		=0xAF
	
	SYMBOL SSD1306_SETDISPLAYOFFSET 	=0xD3
	SYMBOL SSD1306_SETCOMPINS 		=0xDA
	
	SYMBOL SSD1306_SETVCOMDETECT 		=0xDB
	
	SYMBOL SSD1306_SETDISPLAYCLOCKDIV 	=0xD5
	SYMBOL SSD1306_SETPRECHARGE 		=0xD9
	
	SYMBOL SSD1306_SETMULTIPLEX 		=0xA8
	
	SYMBOL SSD1306_SETLOWCOLUMN 		=0x00
	SYMBOL SSD1306_SETHIGHCOLUMN 		=0x10
	
	SYMBOL SSD1306_SETSTARTLINE 		=0x40
	
	SYMBOL SSD1306_MEMORYMODE 		=0x20
	SYMBOL SSD1306_COLUMNADDR 		=0x21
	SYMBOL SSD1306_PAGEADDR   		=0x22		; Page 0-7 represents line 0 - 7
	
	SYMBOL SSD1306_COMSCANINC 		=0xC0
	SYMBOL SSD1306_COMSCANDEC 		=0xC8
	
	SYMBOL SSD1306_SEGREMAP 		=0xA0 | 1
	
	SYMBOL SSD1306_CHARGEPUMP 		=0x8D
	
	SYMBOL SSD1306_EXTERNALVCC 		=0x1
	SYMBOL SSD1306_SWITCHCAPVCC 		=0x2
	
	;Scrolling SYMBOLs
	SYMBOL ACTIVATE_SCROLL 				=0x2F
	SYMBOL DEACTIVATE_SCROLL 			=0x2E
	SYMBOL SET_VERTICAL_SCROLL_AREA 		=0xA3
	SYMBOL RIGHT_HORIZONTAL_SCROLL 		=0x26
	SYMBOL LEFT_HORIZONTAL_SCROLL 		=0x27
	SYMBOL VERT_AND_RIGHT_HORIZONTAL 		=0x29
	SYMBOL VERT_AND_LEFT_HORIZONTAL 		=0x2a 
     ;**************************************************************   
;initialise
gosub InitialiseLcd
gosub ClearDisplay
adcsetup = %0000000000000010
for bptr=0 to 127 ;get 127 samples and store twice in 2 128 byte arrays 
	readadc a.0,sample
	@bptr = sample/4 ;fit to screen res and store sample in 1st array
	push bptr ;save array pointer
	bptr=bptr+127
	@bptr=sample/4 ;store same sample in 2nd array
	pop bptr ;restore array pointer
next bptr
;
start:
for bptr =0 to 127 ; number of bytes in array
	push bptr ;save pointer
	bptr=bptr+128 ;point to 2nd array
	sample=@bptr/8 ;screen row
	pop bptr ;restore pointer to 1st array
	hi2cout (0,SSD1306_PAGEADDR)
	hi2cout (0,sample) ;set screen row 0 to 7
	hi2cout (0,7) ;control code thingy
;
	hi2cout (0,SSD1306_COLUMNADDR)
	hi2cout (0,bptr) ;set column 0 to 127
	hi2cout (0,127) ;control code thingy
;
	hi2cout (64,0) ;erase old screen data in 1st array	
;
	;sample=@bptr
	pixel=@bptr and 7 ;pixel in byte
	screen_byte=1
	do until pixel=1
		screen_byte=screen_byte*2 ;get pixel position in byte!!! maybe wrong this bit "not a pun"
		dec pixel
	loop
;	
	hi2cout (0,SSD1306_PAGEADDR)
	hi2cout (0,sample) ;set row 0 to 7
	hi2cout (0,7) ;control code thingy
;
	hi2cout (0,SSD1306_COLUMNADDR)
	hi2cout (0,bptr) ;set columnn 0 to 127
	hi2cout (0,127) ;control code thingy
;
	hi2cout (64,screen_byte) ;plot new screen data in 1st array as pixel
next bptr
;get new samples into 1st array
for bptr=0 to 127
	temp=@bptr    ; get old sample
	bptr=bptr+128 ; point to 2nd array
	@bptr=temp    ; copy last data from 1st array to old data in 2nd array for erasing on screen
	bptr=bptr-128 ; restore bptr	
;	
	readadc a.0,sample ;get new sample
	sample=sample/4 ;scale to screen res	
	@bptr=sample ;store new data in 1st array
next bptr
;
goto start


	
	
	
DisplayNum:

     ' Words are always 5 chars long, but may be zero led.
     
     
     b3 = 1
     
     for b2 = 0 to 4   
     	      
     	      temp = 4-b2
        	aByte = DispNum DIG temp + "0"
        	
        	if aByte="0" and b3=1 then 
        		goto DisplayNumCont				' Don't show leading spaces
        		
	      elseif abyte<>"0" and b3=1 then
	         b3=0
	      endif
	        	
		GOSUB DisplayChar
		 
     DisplayNumCont:
     
     next b2
    

     return
it's just cobbled together stuff I use and have posted, big so in bits sorry
 

stan74

Senior Member
Code:
mainloop:   
	gosub cleardisplay
	
	
	eeprom 125, (SSD1306_COLUMNADDR)
	eeprom 126, (0)		;   			;Column start address (0 = reset)
	eeprom 127, (127)	 				;Column end address (127 = reset)
	eeprom 128, (SSD1306_PAGEADDR)
	eeprom 129, (0) 					;Page start address (0 = reset)
	eeprom 130, (7) 					;Page end address
	
	
	
	for index = 125 TO 130
		read index,aByte
		gosub DirectSendCmd
	next


	
			
	
	
	gosub clearDisplay
	
	row = 3
	col = 10
	
	gosub setposition
	
	
	eeprom 31, ("0123456789 TEST")
	eeprom 46, ("HELLO WORLD")
	
	for index = 31 TO 45
		read index,aByte
		gosub displayChar;
	next index
	
	row = 5
	col = 2
	gosub setposition
	
	for index = 46 to 56
		read index,aByte
		gosub displayChar;
	next index
	
	
	DispNum = 32016		' Display any word sized number.
	row = 6
	col = 8
	gosub setposition
	gosub displayNum
	
	
	
	row = 1			' Display in top yellow section.
	col = 1
	gosub setposition
	
	eeprom 57, ("HIGH TEMP - ")
	for index = 57 to 68
		read index,aByte
		gosub displayChar;
	next index
	
	
	DispNum = 180		
	
	gosub displayNum
	
	abyte = "C"
	gosub displayChar
	
	
	
	pause 10000
    
    
    
goto mainloop






'  INITIALIZE LCD
' -----------------------------------------------------------------
'
InitialiseLcd:

	
	' initialize I2C
	PAUSE 500
	i2cslave SSD1306_ADDR, i2cfast, i2cbyte
	
	for index = 0 TO 23
		read index,aByte
		gosub DirectSendCmd
	next
	
	
	eeprom 0, (SSD1306_DISPLAYOFF);                   ; 0xAE
	eeprom 1, (SSD1306_SETDISPLAYCLOCKDIV);           ; 0xD5
	eeprom 2, (0x80);                                 ; the suggested ratio 0x80
	eeprom 3, (SSD1306_SETMULTIPLEX);                 ; 0xA8
	eeprom 4, (0x3F);
	eeprom 5, (SSD1306_SETDISPLAYOFFSET);             ; 0xD3
	eeprom 6, (0x0);                                  ; no offset
	eeprom 7, (SSD1306_SETSTARTLINE);            	  ; line #0
	eeprom 8, (SSD1306_CHARGEPUMP);                   ; 0x8D
	eeprom 9, (0x14);						  ; INTERNAL VCC
	eeprom 10, (SSD1306_MEMORYMODE);                  ; 0x20
	eeprom 11, (0x00);                                ; Horiz mode. 0x0 act like ks0108
	eeprom 12, (SSD1306_SEGREMAP);
	eeprom 13, (SSD1306_COMSCANDEC);
	eeprom 14, (SSD1306_SETCOMPINS);                  ; 0xDA
	eeprom 15, (0x12);
	eeprom 16, (SSD1306_SETCONTRAST);                 ; 0x81
	eeprom 17, (0xCF)						  ; INTERNAL VCC
	eeprom 18, (SSD1306_SETPRECHARGE);                ; 0xd9
	eeprom 19, (0xF1)						  ; INTERNAL VCC
	eeprom 20, (SSD1306_SETVCOMDETECT);               ; 0xDB
	eeprom 21, (0x40);
	eeprom 22, (SSD1306_DISPLAYALLON_RESUME);         ; 0xA4
	eeprom 23, (SSD1306_DISPLAYON);                	  ; 0xA4
	
	'eeprom 24, (SSD1306_DISPLAYALLON);               ; 0xA5
           
return






' SEND INIT CMD BYTE - SEND CMD BYTE - SEND DATA BYTE
' -----------------------------------------------------------------
'




SetPosition:


	'20 line x 4 rows is accompished by wrapping the text on each line past 20 characters to two lines down (not next line down). Position 20 (dec) is row 3, col 1


	

	abyte= SSD1306_PAGEADDR
	GOSUB DirectSendCmd
	abyte = row
	GOSUB DirectSendCmd
	abyte = 7
	GOSUB DirectSendCmd
	
		
	abyte= SSD1306_COLUMNADDR
	col = col * 5 					'columns per character
	GOSUB DirectSendCmd
	abyte = col
	GOSUB DirectSendCmd
	abyte = 127
	GOSUB DirectSendCmd
	
	
      return
      
      	

	


    

DirectSendCmd:

    ' Commands are preceeded by a 0 filled byte    
    writei2c (0,abyte)
      
    
return


ClearDisplay:

	b0 = SSD1306_LCDWIDTH
  
  	FOR b1 = 0 to b0
  
	' 0x40 = 01000000 (C/O = 0, D/C = 1) -- Not a command, but data follows.
	
	' Clear 16 columns at a time
	writei2c(0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
		
     next b1
     
     	
	for index = 25 TO 30
		read index,aByte
		gosub DirectSendCmd
	next
    
return




  


	' STANDARD FONT

	' This is the ASCII Font Table starting at space and ending at Z -- lower case is not included (not enough memory)
	' The first 8 are in program direct writes
	
	'table (0x00, 0x00, 0x00, 0x00, 0x00)	' Space
	'table (0x00, 0x00, 0x5F, 0x00, 0x00)	' !
	'table (0x00, 0x07, 0x00, 0x07, 0x00) 	' "
	'table (0x14, 0x7F, 0x14, 0x7F, 0x14) 	' #
	'table (0x24, 0x2A, 0x7F, 0x2A, 0x12) 	' $
	'table (0x23, 0x13, 0x08, 0x64, 0x62) 	' %
	'table (0x36, 0x49, 0x56, 0x20, 0x50) 	' &
	'table (0x00, 0x08, 0x07, 0x03, 0x00) 	' '

	table (0x00, 0x1C, 0x22, 0x41, 0x00) 	' (
	table (0x00, 0x41, 0x22, 0x1C, 0x00) 	' )
	table (0x2A, 0x1C, 0x7F, 0x1C, 0x2A) 	' *
	table (0x08, 0x08, 0x3E, 0x08, 0x08) 	' +
	table (0x00, 0x80, 0x70, 0x30, 0x00) 	' ,
	table (0x08, 0x08, 0x08, 0x08, 0x08)	' -
  	table (0x00, 0x00, 0x5F, 0x00, 0x0)		' .
	table (0x20, 0x10, 0x08, 0x04, 0x02)	' /
	
	table (0x3E, 0x51, 0x49, 0x45, 0x3E) 	' 0
	table (0x00, 0x42, 0x7F, 0x40, 0x00)	; 1
	table (0x72, 0x49, 0x49, 0x49, 0x46)
	table (0x21, 0x41, 0x49, 0x4D, 0x33)
	table (0x18, 0x14, 0x12, 0x7F, 0x10)
	table (0x27, 0x45, 0x45, 0x45, 0x39)
	table (0x3C, 0x4A, 0x49, 0x49, 0x31)
	table (0x41, 0x21, 0x11, 0x09, 0x07)
	table (0x36, 0x49, 0x49, 0x49, 0x36)
	table (0x46, 0x49, 0x49, 0x29, 0x1E)
	table (0x00, 0x00, 0x14, 0x00, 0x00)
	table (0x00, 0x40, 0x34, 0x00, 0x00)
	table (0x00, 0x08, 0x14, 0x22, 0x41)
	table (0x14, 0x14, 0x14, 0x14, 0x14)
	table (0x00, 0x41, 0x22, 0x14, 0x08)
	table (0x02, 0x01, 0x59, 0x09, 0x06)
	table (0x3E, 0x41, 0x5D, 0x59, 0x4E)
	table (0x7C, 0x12, 0x11, 0x12, 0x7C)
	table (0x7F, 0x49, 0x49, 0x49, 0x36)
	table (0x3E, 0x41, 0x41, 0x41, 0x22)
	table  (0x7F, 0x41, 0x41, 0x41, 0x3E)
	table  (0x7F, 0x49, 0x49, 0x49, 0x41)
	table  (0x7F, 0x09, 0x09, 0x09, 0x01)
	table  (0x3E, 0x41, 0x41, 0x51, 0x73)
	table  (0x7F, 0x08, 0x08, 0x08, 0x7F)
	table  (0x00, 0x41, 0x7F, 0x41, 0x00)
	table  (0x20, 0x40, 0x41, 0x3F, 0x01)
	table  (0x7F, 0x08, 0x14, 0x22, 0x41)
	table  (0x7F, 0x40, 0x40, 0x40, 0x40)
	table  (0x7F, 0x02, 0x1C, 0x02, 0x7F)
	table  (0x7F, 0x04, 0x08, 0x10, 0x7F)
	table  (0x3E, 0x41, 0x41, 0x41, 0x3E)
	table  (0x7F, 0x09, 0x09, 0x09, 0x06)
	table  (0x3E, 0x41, 0x51, 0x21, 0x5E)
	table  (0x7F, 0x09, 0x19, 0x29, 0x46)
	table  (0x26, 0x49, 0x49, 0x49, 0x32)
	table  (0x03, 0x01, 0x7F, 0x01, 0x03)
	table  (0x3F, 0x40, 0x40, 0x40, 0x3F)
	table  (0x1F, 0x20, 0x40, 0x20, 0x1F)
	table  (0x3F, 0x40, 0x38, 0x40, 0x3F)
	table  (0x63, 0x14, 0x08, 0x14, 0x63)
	table  (0x03, 0x04, 0x78, 0x04, 0x03)
	table  (0x61, 0x59, 0x49, 0x4D, 0x43)	; Z
	
	

DisplayChar:
	
	
	temp = abyte - " "
	
	if temp< 8 then
	
		if temp=0 then
	 		writei2c(0x40, 0x00, 0x00, 0x00, 0x00, 0x00)		' space
	 	elseif temp=1 then
	 		writei2c(0x40, 0x00, 0x00, 0x5F, 0x00, 0x00)		' !
	 	elseif temp=2 then
	 		writei2c(0x40, 0x00, 0x07, 0x00, 0x07, 0x00) 		' "
	 	elseif temp=3 then
	 		writei2c(0x40, 0x14, 0x7F, 0x14, 0x7F, 0x14) 		' #
	 	elseif temp=4 then
	 		writei2c(0x40, 0x24, 0x2A, 0x7F, 0x2A, 0x12) 		' $
	 	elseif temp=5 then 
	 		writei2c(0x40, 0x23, 0x13, 0x08, 0x64, 0x62) 		' %
	 	elseif temp=6 then
	 		writei2c(0x40, 0x36, 0x49, 0x56, 0x20, 0x50) 		' &
	 	elseif temp=7 then 
	 		writei2c(0x40, 0x00, 0x08, 0x07, 0x03, 0x00) 		' '
	 	endif
	 	return
	 	
	 endif
	 
	 
	temp = temp - 8
	temp = temp * 5	
		
	b1 = temp + 4
	
	for b0 = temp to b1
		readtable b0, aByte
		writeI2C(0x40,abyte)
		
	next b0
	return
	
	
	
DisplayNum:

     ' Words are always 5 chars long, but may be zero led.
     
     
     b3 = 1
     
     for b2 = 0 to 4   
     	      
     	      temp = 4-b2
        	aByte = DispNum DIG temp + "0"
        	
        	if aByte="0" and b3=1 then 
        		goto DisplayNumCont				' Don't show leading spaces
        		
	      elseif abyte<>"0" and b3=1 then
	         b3=0
	      endif
	        	
		GOSUB DisplayChar
		 
     DisplayNumCont:
     
     next b2
    

     return
 

stan74

Senior Member
I replaced adc sample with sample=127 so should get a mid screen line ..didn't do anything so not scanning or more my plot pixel not right..darn m2
This works in my head
Code:
	pixel=@bptr and 7 ;pixel in byte
	screen_byte=1
	do until pixel=1
		screen_byte=screen_byte*2 ;get pixel position in byte!!! maybe wrong this bit "not a pun"
		dec pixel
	loop
;	
	sample=@bptr
	sample=sample/8
	hi2cout (0,SSD1306_PAGEADDR)
	hi2cout (0,sample) ;set row 0 to 7
	hi2cout (0,7) ;control code thingy
;
	hi2cout (0,SSD1306_COLUMNADDR)
	hi2cout (0,bptr) ;set columnn 0 to 127
	hi2cout (0,127) ;control code thingy
;
	hi2cout (64,screen_byte) ;plot new screen data in 1st array as pixel
 
Last edited:

stan74

Senior Member
commenting the above and replacing with screen_byte=1 gives a 1 pixel horizontal line after reming readadc so..try x2 code for the 'sample and 7' to find pixel and use 'set bit screen_byte,pixel' instead
 

stan74

Senior Member
I changed
;screen_byte=1
pixel=@bptr and 7 ;pixel in byte
setbit screen_byte,pixel ;set bit in screen_byte to pixel value 0 to 7
; screen_byte=1
; do until pixel=1
; screen_byte=screen_byte*2 ;get pixel position in byte!!! maybe wrong this bit "not a pun"
; dec pixel
; loop
and got this..getting some where.
https://youtu.be/iefTtuxmNQY
 
Top