Oled display ssd1306 [help]

andrefcarvalho

New Member
Good morning everyone,

I've come to ask for your help, once in a project useri a lcd 40x2 using the protocologo i2c, but the form of writing is different from what I'm using, however part of the code is this:
Code:
'------------------------------------menu pincipal--------------------------------
limpar_lcd:
	writei2c 0,(12,4) 'limpar lcd
	
er_temp: 'temperatura

'escrever no lcd
	writei2c 0,(0,2,7,19)
	writei2c 0,(".:State:.")
	writei2c (0,2,21)
	writei2c (" Motor ",129)
	writei2c (0,2,41)
	writei2c (" Exterior ",129)

ler_tempx:
	'setfreq m16 ' cristal exterior de 16mhz
'ler temperatura
	readtemp12 D.1,w13

temp1:
	if w13>= 64656 then 'caso o valor seja negativo

		let w13 =  65535-w13+1*10/16 'calculos para valores negativos
		'debug
		writei2c (0,2,31)
		bintoascii w13,b0,b1,b2
		hi2cout("-",b0,b1,".",b2,128)
	else
		let w13 = w13*10/16 'calculo para valores positivos
		'debug
		writei2c (0,2,32)
		bintoascii w13,b0,b1,b2
		hi2cout("","",b0,b1,".",b2,128)

	endif
It works, but due to the size of the lcd in the car (I'm using par to read the engine temperature with a ds18b20) I wanted to implement an lcd olc 0.96 "I bought on ebay, has the drive ssd1306 that I managed to work by reading this topic http://www.picaxeforum.co.uk/showthread.php?27651-I2C-OLED-display&highlight=ssd1306

IMG_20170914_115938.jpg
ja alterei o codigo que encontrei a minha medida, sei que esta confuso, mas ainda não consegui perceber ao certo a maior parte dos comandos

IMG_20170914_120307.jpg

here is the code and in the part of reading the temperature, I am not getting the way to implement the values as I had in the last code, how can I implement this?
below is the code I'm using
 

hippy

Technical Support
Staff member
Similar to how you were outputting the number on your LCD, with the SSD1306 you need to split the number into digits using BINTOASCII and then send them individually to the display. Untested -

Code:
w13 = 123
BinToAscii w13, b0,b1,b2
aByte = b0  : Gosub DisplayChar
aByte = b1  : Gosub DisplayChar
aByte = "." : Gosub DisplayChar
aByte = b2  : Gosub DisplayChar
To avoid using the b0, b1 and b2 variables you can do that BINTOASCII on a per digit basis -

Code:
w13 = 123
aByte = w13 / 100 // 10 + "0" : Gosub DisplayChar
aByte = w13 / 10  // 10 + "0" : Gosub DisplayChar
aByte = "."                   : Gosub DisplayChar
aByte = w13       // 10 + "0" : Gosub DisplayChar
 

andrefcarvalho

New Member
I was not trying to figure it out, so I let some time go by and I got the code again, and I managed to make it work with hippy help, so the characters are still giving me stress to show the values, not yet I know for sure how to get the characters to apply to the "table" (table (0x00, 0x00, 0x5F, 0x00, 0x0) ' .) command plus ".", does anyone have an idea how it works?

IMG_20170923_175434.jpg

Code:
ler_temp:'ler temperatura
	'readtemp12 D.0,w12
	
		let w12 = 999
		let w12 = w12*10/16 'calculo para valores positivos


		row = 4
		col = 8
	gosub setposition

		aByte = w12 / 100 // 10 + "0" : Gosub DisplayChar
		aByte = w12 / 10  // 10 + "0" : Gosub DisplayChar
		aByte = "."                   : Gosub DisplayChar
		aByte = w12       // 10 + "0" : Gosub DisplayChar
		aByte = "C" 			: Gosub DisplayChar

	pause 20
 

AllyCat

Senior Member
Hi,

999 * 10 / 16 is indeed 6 2 4 which looks correct.

Code:
	'table (0x00, 0x00, 0x5F, 0x00, 0x00) ' !
....
	table (0x08, 0x08, 0x08, 0x08, 0x08) ' -
	table (0x00, 0x00, 0x5F, 0x00, 0x00)  ' .
Your table has the same data field for '!' and '.' .

The 5 data values define the 5 "columns" of each character, so table (0x00, 0x00, 0x08, 0x00, 0x00) will define a central "decimal point". To put a dot ("full stop") on the lowest line you probably need table (0x00, 0x00, 0x40, 0x00, 0x00) ' . Compare that with the character 'L' (I can't see an underscore '_' in the table) .

Cheers, Alan
 

hippy

Technical Support
Staff member
This may help visualise things better ...

Code:
        - - # - - bit 0 -----------.
        - - # - -                  |
        - - # - -                  |
        - - # - -                  |
        - - # - -                  |
        - - - - -                  |
        - - # - -                  |
        - - - - - bit 7 ---.       |
                           |       |
0x00 ---' | | | |          |       |
0x00 -----' | | |          |       |
0x5F -------' | |   0x5F = 0101 1111
0x00 ---------' |
0x00 -----------'
 

andrefcarvalho

New Member
This may help visualise things better ...

Code:
        - - # - - bit 0 -----------.
        - - # - -                  |
        - - # - -                  |
        - - # - -                  |
        - - # - -                  |
        - - - - -                  |
        - - # - -                  |
        - - - - - bit 7 ---.       |
                           |       |
0x00 ---' | | | |          |       |
0x00 -----' | | |          |       |
0x5F -------' | |   0x5F = 0101 1111
0x00 ---------' |
0x00 -----------'
thanks for the tip ;)

I posted a routine for the ssd1306 that might help with various character sets/sizes and plotting and drawing lines if useful http://www.picaxeforum.co.uk/showthread.php?29727-Picaxe-Tron
over the weekend I'll take a closer look, but it seems to be a good help.

however I am doing research to make interface with the pressure sensors that I will use, such as temperature, gasoline engine rpm, afr, among other things, the calculations that I have been researching and adapting, I think they are right, now it is a question of testing and implementing the code to see how it reacts

when you have things oriented, I will put here more info
 

andrefcarvalho

New Member
due to some setbacks in the project, I ended up not going any further with it, however the second phase is to be able to use transducer type these I have been testing various equations for values that I can use and I have come to this
val=value in psi
ADC=value in volts
XP =pressure sensor ex: 15 for 15psi or 100 for 100psi

VAL=(ADC-0,5)*XP/4
what is now blocking me is to use values in the beads as 0.5 (minimum sensor value (0.5v-4.5v)) in theory was to read the adc, convert to volts and then to psi, some simpler solution ?
 

hippy

Technical Support
Staff member
Assuming a 5V power supply, and reading with READADC. Using scaled maths where one unit represents 0.1V ...

PSI = ADC * 50 / 255 Min 5 Max 45 - 5 * XP / 40
 
Last edited:

hippy

Technical Support
Staff member
The number read by READADC, Nadc, is ...

Nadc = ( Vin / Vpsu ) * 255

We can calculate what the voltage in, Vin, was from that Nadc ...

Vin = ( Nadc * Vpsu ) / 255

So if we could do decimal maths ...

Vin = Nadc * 5.0 / 255

Then, limited to 0.5V-4.5V and adjusting 0.5V down to 0 ...

Nadc * 5.0 / 255 Min 0.5 Max 4.5 - 0.5

Then it's just a question of multiplying that by XP/4 ...

Nadc * 5.0 / 255 Min 0.5 Max 4.5 - 0.5 * XP / 4

But we can't do decimal maths so we multiply everything by 10 to scale up to do the maths, then divide by 10 to scale back down when done ...

Nadc * 50 / 255 Min 5 Max 45 - 5 * XP / 4 / 10
 

andrefcarvalho

New Member
being using 3.3ve 5v on the same board, I was mistaken and was feeding the vcc with 3.3v on the voltage dipper, so I was not realizing the why of showing bad values, thanks for the say, I have now it's from make a code to not show values ​​0 left
 

andrefcarvalho

New Member
continuing in the project, in the short time I have had, this turns out to be more doubts about math than anything else.
because well trying to idealize the project in the simplest way, in this case to measure the rpm of the motor, I am using this circuit with lm2907, I think that the arduino calculation formula is different from the picaxe and ideally convert the voltage in rpm works using 0.5209 v per 1000 rpm so
Code:
v=tension
=1000*v/0,52
not being able to use 0.52, I used the code below
Code:
	rpm:
	
	readadc a.0,w4
	
		w4 = w4*255/5'tens?o
		w4 = 1000*w4/52
		w4 = w4*100
		
		row = 7
		col = 5
		
	gosub setposition
		
		aByte = w4 / 100 // 10 + "0"  	: Gosub DisplayChar
		aByte = w4 / 10  // 10 + "0"  	: Gosub DisplayChar
		aByte = w4       // 10 + "0" 	: Gosub DisplayChar
		aByte = w4       // 1 + "0" 		: Gosub DisplayChar
my question is, is this the most correct formula to translate for code?
because in lcd having 5v of the value 5000, not being similar ..
 

hippy

Technical Support
Staff member
Try this. Note it uses READADC10 to maximise accuracy ...

Code:
Symbol aByte = b0
Symbol adc   = w1
Symbol rpm   = w2

ReadAdc10 A.0, adc

rpm = adc *  9
rpm = adc ** 25097 + rpm

aByte = rpm / 1000 // 10 + "0" : Gosub DisplayChar
aByte = rpm / 100  // 10 + "0" : Gosub DisplayChar
aByte = rpm / 10   // 10 + "0" : Gosub DisplayChar
aByte = rpm        // 10 + "0" : Gosub DisplayChar
If you feed in 5V it should show 9598 RPM
 

hippy

Technical Support
Staff member
Yes, my Freeserve site disappeared many Christmases ago. I never replaced it.

The maths for the Post #16 calculations is explained below -

For the READADC10 analogue input -

adc = Vin * 1023 / Vpsu

Vin = adc * Vpsu / 1023


For the rpm calculation -

Krpm = Vin / 0.5209

rpm = Vin * 1000 / 0.5209


Replace the Vin in the rpm calculation -

rpm = Vin * 1000 / 0.5209

rpm = ( adc * Vpsu / 1023 ) * ( 1000 / 0.5209 )

rpm = ( adc * 5 / 1023 ) * ( 1000 / 0.5209 )

rpm = ( adc * 5 * 1000 ) / ( 1023 * 0.5209 )

rpm = adc * ( 5000 / 532.8807 )

rpm = adc * 9.3829632


Now convert that into usable PICAXE maths -

rpm = adc * 9.3829632

rpm = adc * ( 9 + 0.3829632 )

rpm = ( adc * 9 ) + ( adc * 0.3829632 )

rpm = ( adc * 9 ) + ( adc * 0.3829632 * 65536 / 65536 )

rpm = ( adc * 9 ) + ( adc * ( 0.3829632 * 65536 ) / 65536 )

rpm = ( adc * 9 ) + ( adc * 25097 / 65536 )

rpm = ( adc * 9 ) + ( adc ** 25097 )


Turn into actual PICAXE code -

; rpm = ( adc * 9 ) + ( adc ** 25097 )

rpm = adc * 9
rpm = adc ** 25097 + rpm
 
Last edited:

andrefcarvalho

New Member
using the "space" as a character instead of "0" works as I want below the value <10 of the character as seen in the video, supposedly the correct value would have been entered, this was the simplest way I got to remove the value 0 on sites that are not worth being
Code:
fuel_press:
	
	readadc a.1,b4
	
		b4 = b4 * 50 / 255 Min 5 Max 45 - 5 * 15 / 40'15 sensor
		debug
		row = 3
		col = 6
	gosub setposition
	
		aByte = b4 / 10  // 10 + " " : Gosub DisplayChar
		aByte = b4       // 10 + "0"  : Gosub DisplayChar
		aByte = " " 			: Gosub DisplayChar
		aByte = "P" 			: Gosub DisplayChar
		aByte = "S" 			: Gosub DisplayChar 
		aByte = "I" 			: Gosub DisplayChar
		goto fuel_press
[video]https://youtu.be/dpoU96E70KI[/video]
 

hippy

Technical Support
Staff member
The Wayback machine has snapshots of Hippy's web pages from the past.
I am not sure how useful any of those PICAXE pages are now. They were last updated over a decade ago and really only apply to PICAXE chips which are rarely found these days. There was no coverage of the M2, X1 and X2 chips which are now in production.

Things were somewhat different back then. The PICAXE wasn't well known outside educational use, had significantly less memory, and the programming capabilities and editor were nowhere near as advanced as they are now. What was useful back then isn't applicable now and Rev-Ed's documentation has replaced and superseded what I had.
 

andrefcarvalho

New Member
I started to use picaxe around 2007, at the time there was some evolution, but nowadays many of the things I'm not updated, I left part of the squeeze behind, the picaxe has some limitations, but still powerful and simple code for who wants to start
 

andrefcarvalho

New Member
having the thing more or less defined, I ordered the lm2907 to do the tests, though I can already start to define the layout of the board, it was to use the designspark, but I'll end up going to the eagle
 

premelec

Senior Member
Thermocouple or possibly non-contact IR depending on your situation, there are ICs which condition thermocouples and give appropriate zero reference TCs need... I haven't read this thread otherwise so don't know what you are doing...;-0 There are perhaps a few glass cased thermistors for this but they are very non-linear and need quite a bit of lookup or math to get a linear reading to appear from them. I almost forgot - resistance platinum units - pt100 or pt1000...
 
Last edited:
Top