News:

Let's find out together what makes a PIC Tick!

Main Menu

5V PIC interfacing with OLED display.

Started by david, Feb 04, 2024, 05:14 AM

Previous topic - Next topic

david

Hi All,
I think I'm guilty of misusing OLED displays.  I have done various hobby projects using a 5V PIC and interfaced directly to the OLED display.  Now the OLED displays usually have their own 5V to 3.3V regulator on board, along with SDA, SCL pull-up resistors to the 3.3V supply.  I've been thinking that's fine because the PIC's I2C hardware is open drain and any Write signals to the display will get pulled up to 3.3V by the resistors.  Now I've totally ignored the fact that there is a ACK signal back which needs to be 0.7x 5V=3.5V as a minimum logic high which it is never going to get.
It appears I've been lucky to date but what's the simplest way around this?   I don't have access to the regulated 3.3V line on the display but could run the PIC and OLED at 3.3V because I'm already regulating down from a higher voltage but then the OLED display's regulator would be in drop-out.  A 4.5V regulator would solve everything but it's a bit quirky.

Cheers,
David

trastikata

Quote from: david on Feb 04, 2024, 05:14 AMNow I've totally ignored the fact that there is a ACK signal back which needs to be 0.7x 5V=3.5V as a minimum logic high which it is never going to get.
It appears I've been lucky to date but what's the simplest way around this? 

If you are using software I2C routines and connect the Data pin to a port with TTL buffer you should be fine.

david

Thanks for your reply. 
I'm using hardware I2C but could use software I2C.  The SDA line needs to be bidirectional and I'm trying to avoid having to access a 3.3V supply as it's internal to the OLED display.
I may have misunderstood how you would implement the TTL buffer.

As a tacky alternative I could add a high value pull-up resistor from SDA to +5V along with the pull-up resistor to 3.3V .  This could lift the SDA voltage when the open drain is OFF to just over 3.5V which shouldn't upset any substrate diodes in the OLED chip and is only going to draw about 20uA.

David

trastikata

#3
Quote from: david on Feb 04, 2024, 10:14 AMI may have misunderstood how you would implement the TTL buffer.

Hi David,

Pins with a TTL buffer when used as Digital I/O (check the datasheet to see which have it) have minimum Input High voltage 2v on 5v tolerant PICs. So as long as the line is over 2v, the PIC has no problem seeing the Logic High level.

Example:

david

My apologies - I thought you were talking about adding a single gate buffer of some type hence my confusion as to how it became bidirectional.
Using a TTL I/O appears to be a very safe and robust option.  Many thanks for the suggestion.  I shall do some speed trials but I don't believe it will be an issue.

Thanks again for your input.
David

top204

#5
At the momemt, the PIC microcontrollers default to TTL for their pins, but with microchip you can never tell for future devcies. :-) However, they, stupidly, default to the slew enabled on pins for devices that have the ability, so the compiler disables them within a device's '.def' file before a user's program starts, otherwise lots of peripherals and operations do not work because the pins do not toggle fast enough.

I found that out the hard way and worried that people would blame the compiler and not the silly thing done on the microcontroller, so I went through all the '.def' files and added the disable code to them quite a few years ago, along with ADC and comparators etc... You can see the SFR (Special Function Register) defaults near the end of each device's '.def' file. For example, in a PIC18F26K40 device's '.def' file, it has the code:

'-----------------------------------------------------------------------------------
' Make the device's I/O pins digital (if required) before the main program starts
' This can be added too by the user and shared on the forum
'
#IfnSym __SYSCOM_LIBRARY_OFF_       ' Has the library been disabled in the compiler?
    ANSELA = $00
    ANSELB = $00
    ANSELC = $00
    SLRCONA = $00
    SLRCONB = $00
    SLRCONC = $00
    CM1CON0 = $00
    CM2CON0 = $00
#EndIfSym

The device '.def' files can be found here: "C:\Program Files (x86)\ProtonIDE\PDS\Includes\Defs\"

But just to make sure with the TTL/Schmitt, I usually add some defines in a project program's header '.inc' file so the TTL can be enabled or disabled easily. For example:

$define Schmitt_PORTA() INLVLA = 255            ' Enable Schmitt trigger inputs on all of PORTA
$define Schmitt_RA0() INLVLA.0 = 1              ' Enable Schmitt on pin PORTA.0
$define Schmitt_RA1() INLVLA.1 = 1              ' ....
$define Schmitt_RA2() INLVLA.2 = 1              ' ....
$define Schmitt_RA3() INLVLA.3 = 1              ' ....
$define Schmitt_RA4() INLVLA.4 = 1              ' ....
$define Schmitt_RA5() INLVLA.5 = 1              ' ....
$define Schmitt_RA6() INLVLA.6 = 1              ' ....
$define Schmitt_RA7() INLVLA.7 = 1              ' Enable Schmitt on pin PORTA.7

$define Schmitt_PORTB() INLVLB = 255            ' Enable Schmitt trigger inputs on all of PORTB
$define Schmitt_RB0() INLVLB.0 = 1              ' Enable Schmitt on pin PORTB.0
$define Schmitt_RB1() INLVLB.1 = 1              ' ....
$define Schmitt_RB2() INLVLB.2 = 1              ' ....
$define Schmitt_RB3() INLVLB.3 = 1              ' ....
$define Schmitt_RB4() INLVLB.4 = 1              ' ....
$define Schmitt_RB5() INLVLB.5 = 1              ' ....
$define Schmitt_RB6() INLVLB.6 = 1              ' ....
$define Schmitt_RB7() INLVLB.7 = 1              ' Enable Schmitt on pin PORTB.7

$define Schmitt_PORTC() INLVLC = 255            ' Enable Schmitt trigger inputs on all of PORTC
$define Schmitt_RC0() INLVLC.0 = 1              ' Enable Schmitt on pin PORTC.0
$define Schmitt_RC1() INLVLC.1 = 1              ' ....
$define Schmitt_RC2() INLVLC.2 = 1              ' ....
$define Schmitt_RC3() INLVLC.3 = 1              ' ....
$define Schmitt_RC4() INLVLC.4 = 1              ' ....
$define Schmitt_RC5() INLVLC.5 = 1              ' ....
$define Schmitt_RC6() INLVLC.6 = 1              ' ....
$define Schmitt_RC7() INLVLC.7 = 1              ' Enable Schmitt on pin PORTC.7

$define TTL_PORTA() INLVLA = 0                  ' Enable TTL inputs on all of PORTA
$define TTL_RA0() INLVLA.0 = 0                  ' Enable TTL on pin PORTA.0
$define TTL_RA1() INLVLA.1 = 0                  ' ....
$define TTL_RA2() INLVLA.2 = 0                  ' ....
$define TTL_RA3() INLVLA.3 = 0                  ' ....
$define TTL_RA4() INLVLA.4 = 0                  ' ....
$define TTL_RA5() INLVLA.5 = 0                  ' ....
$define TTL_RA6() INLVLA.6 = 0                  ' ....
$define TTL_RA7() INLVLA.7 = 0                  ' Enable TTL on pin PORTA.7

$define TTL_PORTB() INLVLB = 0                  ' Enable TTL inputs on all of PORTB
$define TTL_RB0() INLVLB.0 = 0                  ' Enable TTL on pin PORTB.0
$define TTL_RB1() INLVLB.1 = 0                  ' ....
$define TTL_RB2() INLVLB.2 = 0                  ' ....
$define TTL_RB3() INLVLB.3 = 0                  ' ....
$define TTL_RB4() INLVLB.4 = 0                  ' ....
$define TTL_RB5() INLVLB.5 = 0                  ' ....
$define TTL_RB6() INLVLB.6 = 0                  ' ....
$define TTL_RB7() INLVLB.7 = 0                  ' Enable TTL on pin PORTB.7

$define TTL_PORTC() INLVLC = 0                  ' Enable TTL inputs on all of PORTC
$define TTL_RC0() INLVLC.0 = 0                  ' Enable TTL on pin PORTC.0
$define TTL_RC1() INLVLC.1 = 0                  ' ....
$define TTL_RC2() INLVLC.2 = 0                  ' ....
$define TTL_RC3() INLVLC.3 = 0                  ' ....
$define TTL_RC4() INLVLC.4 = 0                  ' ....
$define TTL_RC5() INLVLC.5 = 0                  ' ....
$define TTL_RC6() INLVLC.6 = 0                  ' ....
$define TTL_RC7() INLVLC.7 = 0                  ' Enable TTL on pin PORTC.7

Then to make the whole of PORTB TTL, use: TTL_PORTB(), or to make it Schmitt enabled, use: Schmitt_PORTB(). Or each pin can be TTL or Schmitt. i.e. TTL_RA3(). The $defines can be expanded or reduced for different devices with different amounts of ports.

I may add the code to the device '.def' files to make sure they are all TTL in future versions of the compiler but I do not like to bulk up code memory for no reason. :-)

david

Oh wow!   I can see I lead a sheltered life using mainly older PICs.
I will keep this in mind for the future.
Many thanks Les.

Best regards,
David

trastikata

With older PICs one has to be careful with the hardware design because not all ports support TTL, but I did not know you can select the input level on newer devices, thanks Les.