News:

;) This forum is the property of Proton software developers

Main Menu

Voltmeter with an OLED indicator

Started by tolyan249, Sep 09, 2026, 10:22 AM

Previous topic - Next topic

tolyan249

I'm making a voltmeter using an OLED display, displaying 3 digits without a decimal point across the entire display, but something isn't working. I'm posting the project.

trastikata

Quote from: tolyan249 on Sep 09, 2026, 10:22 AMbut something isn't working. I'm posting the project.

Hi tolyan249,

it would be good if you can be more specific what exactly is not working.  :)

RGV250

Hi,
You need to give more information on here as to what you think should happen or what is not happening if you expect a reply. Just saying "something isn't working" does not help.
I notice there is a CSV file for EcoEye, if it is the same EcoEye that I use it is current output, not voltage?

Trastikata beat me to it

Regards,
Bob

tolyan249

#3
The indicator doesn't display any numbers, even if you simply substitute numbers into the variable, without performing any measurement — just output 3 numbers. 

   Digit[0] =  2    ' Hundreds
    Digit[1] = 3    ' Tens
    Digit[2] = 4    ' Ones

trastikata

Hello tolyan249,

I can't open the design file, but what pins did you use for the hardware I2C? Did you connect the pull-up resistors? Looked at your code and I think there's a lot missing?

I have had some projects with the SSD1306 I2C displays and all worked fine, but they need much more coding than what I see in your program listing. Here are some basic functions I've taken from my program, so you have an idea what to do.

Symbol SSD1306 = $3C << 1
Symbol ControlByteCMD  = %10000000         ;Co bit set = Command follows
Symbol ControlByteData = %01000000         ;D/C# bit set = GDRAM byte follows

GoSub INITIALIZE_LCD
GoSub LCD_ON
GoSub LCD_NORMAL
GoSub LCD_CLEAR_START
DelayMS 1000
GoSub LCD_CLEAR

INITIALIZE_LCD:
    DelayMS 500
    HBStart
        HBusOut SSD1306
    HBStop
    DelayMS 10
    HBStart                     ;Send a Start condition to the I2C bus
        HBusOut SSD1306         ;Slave Adress
   
        HBusOut ControlByteCMD  ;
        HBusOut $AE             ;turn off oled panel
       
        HBusOut ControlByteCMD  ;
        HBusOut $D5             ;set display clock divide ratio/oscillator frequency
        HBusOut ControlByteCMD  ;
        HBusOut $F0             ;set divide ratio  default=$80 / F0
       
        HBusOut ControlByteCMD  ;
        HBusOut $A8             ;set multiplex ratio 1 to 64
        HBusOut ControlByteCMD  ;
        HBusOut $3F             ;1/64 duty
       
        HBusOut ControlByteCMD  ;
        HBusOut $D3             ;set display offset
        HBusOut ControlByteCMD  ;
        HBusOut $00             ;not offset
       
        HBusOut ControlByteCMD  ;
        HBusOut $8d             ;set Charge Pump enable/disable
        HBusOut ControlByteCMD  ;
        HBusOut $14             ;set $10=disable 14=enable ???Why
       
        HBusOut ControlByteCMD  ;
        HBusOut $40             ;set start line address
        HBusOut ControlByteCMD  ;
        HBusOut $A6             ;set normal display
       
        HBusOut ControlByteCMD  ;
        HBusOut $A4             ;Disable Entire Display On (=RAM to Dispaly)
       
        HBusOut ControlByteCMD  ;
        HBusOut $A1             ;set segment re-map 127 to 0 =Reversed (Normal=$A0)
       
        HBusOut ControlByteCMD  ;
        HBusOut $C8             ;Set COM Output Scan Direction 63 to 0 =Reversed (Normal=$C0)
       
        HBusOut ControlByteCMD  ;
        HBusOut $DA             ;set com pins hardware configuration
       
        HBusOut ControlByteCMD  ;
        HBusOut $12             ;Disable COM remapping & Alternative COM pins
       
        HBusOut ControlByteCMD  ;
        HBusOut $81             ;set contrast control register
        HBusOut ControlByteCMD  ;
        HBusOut $FF             ;Default $8F $FF=Maximum $00=Minimum
       
        HBusOut ControlByteCMD  ;
        HBusOut $D9             ;set pre-charge period
        HBusOut ControlByteCMD  ;
        HBusOut $F1             ;Default $22 ?????
       
        HBusOut ControlByteCMD  ;
        HBusOut $DB             ;set vcomh
        HBusOut ControlByteCMD  ;
        HBusOut $40             ;Value WRONG Only Possible $00, $10, $20, $30
       
        HBusOut ControlByteCMD  ;
        HBusOut $AF             ;turn on oled panel
    HBStop
Return


LCD_ON:
    HBStart
        HBusOut SSD1306, [ControlByteCMD, $AF]
    HBStop
Return

LCD_OFF:
    HBStart
        HBusOut SSD1306, [ControlByteCMD, $AE]
    HBStop
Return

LCD_NORMAL:
    HBStart
        HBusOut SSD1306, [ControlByteCMD, $A6]
    HBStop
Return

LCD_HORIZONTAL_ADDRESSING:
    HBStart
        HBusOut SSD1306         ;Slave address
        HBusOut ControlByteCMD  ;
        HBusOut $20             ;Set Memory Addressing Mode
        HBusOut ControlByteCMD  ;
        HBusOut $00            ;Horizontal Adressing ($01=Vertical $20=Paged)
    HBStop     
Return

LCD_VERTICAL_ADDRESSING:
    HBStart
        HBusOut SSD1306         ;Slave address
        HBusOut ControlByteCMD  ;
        HBusOut $20             ;Set Memory Addressing Mode
        HBusOut ControlByteCMD  ;
        HBusOut $01            ;Horizontal Adressing ($01=Vertical $20=Paged)
    HBStop     
Return

LCD_START_POSITION:
    HBStart
        HBusOut SSD1306         ;Slave address
       
        HBusOut ControlByteCMD  ;
        HBusOut $20             ;Set Memory Addressing Mode
        HBusOut ControlByteCMD  ;
        HBusOut $00            ;Horizontal Adressing ($01=Vertical $20=Paged)
       
        HBusOut ControlByteCMD  ;
        HBusOut $21             ;Set Colomn Address
        HBusOut ControlByteCMD  ;
        HBusOut $00             ;Start Colomn
        HBusOut ControlByteCMD  ;
        HBusOut 127             ;End Colomn
       
        HBusOut ControlByteCMD  ;
        HBusOut $22             ;Set Page Address
        HBusOut ControlByteCMD  ;
        HBusOut $00             ;Start Page
        HBusOut ControlByteCMD  ;
        HBusOut 7               ;End Page
    HBStop   
Return

LCD_CLEAR_START:
    GoSub LCD_START_POSITION
    HBStart
        HBusOut SSD1306
        HBusOut ControlByteData
        For c = 0 To 127   
            For d = 0 To 7
                HBusOut 255
            Next   
        Next
    HBStop
   
    DelayMS 1500
   
    GoSub LCD_START_POSITION
    HBStart
        HBusOut SSD1306
        HBusOut ControlByteData
        For c = 0 To 127   
            For d = 0 To 7
                HBusOut 0
            Next   
        Next
    HBStop
   
    HBStart
        HBusOut SSD1306         ;Slave address
        HBusOut ControlByteCMD  ;
        HBusOut $20             ;Set Memory Addressing Mode
        HBusOut ControlByteCMD  ;
        HBusOut $20            ;Paged Adressing ($01=Vertical $20=Paged)
    HBStop
Return

LCD_CLEAR:
    GoSub LCD_START_POSITION
    HBStart
        HBusOut SSD1306
        HBusOut ControlByteData
        For c = 0 To 127   
            For d = 0 To 7
                HBusOut 0
            Next   
        Next
    HBStop
   
    HBStart
        HBusOut SSD1306         ;Slave address
        HBusOut ControlByteCMD  ;
        HBusOut $20             ;Set Memory Addressing Mode
        HBusOut ControlByteCMD  ;
        HBusOut $20            ;Paged Adressing ($01=Vertical $20=Paged)
    HBStop
Return

Print_GLCD:
    HBStart
        HBusOut SSD1306         ;Slave address
        HBusOut ControlByteCMD  ;
        HBusOut $21             ;Set Colomn Address
        HBusOut ControlByteCMD  ;
        temp1 = (pos * 8)
        HBusOut temp1           ;Start Colomn
        HBusOut ControlByteCMD  ;
        HBusOut 127             ;End Colomn
        HBusOut ControlByteCMD  ;
        HBusOut $22             ;Set Page Address
        HBusOut ControlByteCMD  ;
        temp1 = row
        HBusOut temp1           ;Start Page
        HBusOut ControlByteCMD  ;
        HBusOut temp1           ;End Page
    HBStop 
   
    'Send pixel data
    HBStart
        HBusOut SSD1306
        HBusOut ControlByteData
        For c = 0 To 7
            HBusOut page1_array[c]
        Next
    HBStop
    Clear page1_array
Return 

tolyan249

#5
Thank you very much for your help.

Pepe

demo proteus

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 12F1840

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_OFF, STVREN_OFF, BORV_19, LVP_OFF

;**** End of Fuse Configurator Settings ****

Declare Xtal = 16
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog off
Declare Hbus_Bitrate 400

Symbol OLED_W = $78
Symbol OLED_R = $79

Declare Adin_Res 10
Declare Adin_Tad 32_FOSC
Declare Adin_Stime 50

' Variables
Dim Voltage As Dword
Dim vresult As Word
Dim i,j,d ,k As Byte
Dim index As Word
Dim ch As Byte
Dim texto[8] As Byte  ="VOLTAGE:" ' Vector de texto

OSCCON = %01111010   
TRISA = %00001001     ' RA0 - ADC input
ANSELA = %00000001    ' RA0 - Analog mode
ADCON1.7 = 1



' Inicializar OLED
HBusOut OLED_W,[$80,$AE, $00,$20,$00, $00,$81,$7F, $80,$A1, $80,$A4, $80,$A6, $00,$A8,$3F, $80,$C8, $00,$D5,$90, $00,$D9,$22, $00,$DA,$12, $00,$DB,$30, $00,$8D,$14, $80,$AF]
DelayMS 100

 
' Mostrar texto

PrintTextVec (texto,5,3)   ' columna=5 fila= 3                       


' Bucle principal
Do
     ' 1. Get ADC value (0-1023)
    vresult = ADIn 0
    ' Apply your scaling formula
    Voltage = vresult * 5000
    Voltage = Voltage / 1023
 
    PrintNumber(Voltage,3,55,3)  ' 3 = numero de decimales   columna=55 fila= 3
    PrintChar("V")
    DelayMS 200
Loop

' Imprime un número sin usar strings

Proc PrintNumber(valor As Dword,punto As Byte,c As Byte,f As Byte)

    Dim pos As Byte
    Dim digito As Byte
    Dim mostrar As Bit

    HBusOut OLED_W, [$00, $21, c, 127]  ' Columna  55
    HBusOut OLED_W, [$00, $22, f, 1]
    mostrar = 0

    For pos = 4 To 0 Step -1
        digito = Dig valor,pos

        If digito > 0 Then
            mostrar = 1
        EndIf

        ' Mostrar siempre los dígitos desde la parte decimal
        ' pero eliminar ceros innecesarios a la izquierda
        If mostrar = 1 Or pos <= punto Then
            PrintChar(digito + "0")
        EndIf

        If pos = punto Then
            PrintChar(".")
        EndIf
    Next

    PrintChar(" ")
EndProc


' Imprime un carácter en OLED usando fuente
Proc PrintChar(pChar As Byte)
    Dim dato As Byte
    If pChar < 32 Or pChar > 95 Then ExitProc
    For j = 0 To 4
        index = ((pChar - 32) * 5) + j
        dato = CRead8 Fonts[index]
        HBusOut OLED_W, [$40, dato]
    Next
    HBusOut OLED_W, [$40, 0]
EndProc
' imprimir vector de texto
Proc PrintTextVec(texto[8] As Byte,c As Byte,f As Byte)
HBusOut OLED_W, [$00, $21, c, 127] 
HBusOut OLED_W, [$00, $22, f, 1]   

    i = 0
    While texto[i] <> 0
        ch = texto[i]
         PrintChar(ch)
        Inc i
    Wend
EndProc

' Fuente 5x7 ASCII 32 a 127


Fonts:
CData $00,$00,$00,$00,$00,_   ; 32 
      $00,$00,$5F,$00,$00,_   ; 33 !
      $00,$07,$00,$07,$00,_   ; 34 "
      $14,$7F,$14,$7F,$14,_   ; 35 #
      $24,$2A,$7F,$2A,$12,_   ; 36 $
      $23,$13,$08,$64,$62,_   ; 37 %
      $36,$49,$55,$22,$50,_   ; 38 &
      $00,$05,$03,$00,$00,_   ; 39 '
      $00,$1C,$22,$41,$00,_   ; 40 (
      $00,$41,$22,$1C,$00,_   ; 41 )
      $14,$08,$3E,$08,$14,_   ; 42 *
      $08,$08,$3E,$08,$08,_   ; 43 +
      $00,$50,$30,$00,$00,_   ; 44 ,
      $08,$08,$08,$08,$08,_   ; 45 -
      $00,$60,$60,$00,$00,_   ; 46 .
      $20,$10,$08,$04,$02,_   ; 47 /
      $3E,$51,$49,$45,$3E,_   ; 48 0
      $00,$42,$7F,$40,$00,_   ; 49 1
      $42,$61,$51,$49,$46,_   ; 50 2
      $21,$41,$45,$4B,$31,_   ; 51 3
      $18,$14,$12,$7F,$10,_   ; 52 4
      $27,$45,$45,$45,$39,_   ; 53 5
      $3C,$4A,$49,$49,$30,_   ; 54 6
      $01,$71,$09,$05,$03,_   ; 55 7
      $36,$49,$49,$49,$36,_   ; 56 8
      $06,$49,$49,$29,$1E,_   ; 57 9
      $00,$36,$36,$00,$00,_   ; 58 :
      $00,$56,$36,$00,$00,_   ; 59 ;
      $08,$14,$22,$41,$00,_   ; 60 <
      $14,$14,$14,$14,$14,_   ; 61 =
      $00,$41,$22,$14,$08,_   ; 62 >
      $02,$01,$51,$09,$06,_   ; 63 ?
      $32,$49,$79,$41,$3E,_   ; 64 @
      $20,$54,$54,$54,$78,_   ; 97 a
      $7F,$48,$44,$44,$38,_   ; 98 b
      $38,$44,$44,$44,$20,_   ; 99 c
      $38,$44,$44,$48,$7F,_   ; 100 d
      $38,$54,$54,$54,$18,_   ; 101 e
      $08,$7E,$09,$01,$02,_   ; 102 f
      $18,$A4,$A4,$A4,$7C,_   ; 103 g
      $7F,$08,$04,$04,$78,_   ; 104 h
      $00,$44,$7D,$40,$00,_   ; 105 i
      $40,$80,$84,$7D,$00,_   ; 106 j
      $7F,$10,$28,$44,$00,_   ; 107 k
      $00,$41,$7F,$40,$00,_   ; 108 l
      $7C,$04,$18,$04,$78,_   ; 109 m
      $7C,$08,$04,$04,$78,_   ; 110 n
      $38,$44,$44,$44,$38,_   ; 111 o
      $FC,$24,$24,$24,$18,_   ; 112 p
      $18,$24,$24,$18,$FC,_   ; 113 q
      $7C,$08,$04,$04,$08,_   ; 114 r
      $48,$54,$54,$54,$20,_   ; 115 s
      $04,$3F,$44,$40,$20,_   ; 116 t
      $3C,$40,$40,$20,$7C,_   ; 117 u
      $1C,$20,$40,$20,$1C,_   ; 118 v
      $3C,$40,$30,$40,$3C,_   ; 119 w
      $44,$28,$10,$28,$44,_   ; 120 x
      $0C,$50,$50,$50,$3C,_   ; 121 y
      $44,$64,$54,$4C,$44,_   ; 122 z
      $00,$7F,$41,$41,$00,_   ; 123 [
      $02,$04,$08,$10,$20,_   ; 124 \
      $00,$41,$41,$7F,$00,_   ; 125 ]
      $04,$02,$01,$02,$04,_   ; 126 ^
      $40,$40,$40,$40,$40     ; 127 _

Pepe

demo proteus big digits

'===============================================================================
' PIC12F1840
' OLED 128x64 I2C SSD1306 / SSD1315
' 3 DIGITOS GRANDES
'===============================================================================
;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 12F1840

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_OFF, STVREN_OFF, BORV_19, LVP_OFF

;**** End of Fuse Configurator Settings ****


Declare Xtal = 16
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog off
OSCCON = %01111010

'-------------------------------------------------------------------------------
' PUERTOS
'-------------------------------------------------------------------------------

TRISA = %00001001
ANSELA = %00000001
ADCON1.7 = 1
' RA0 = ADC

'-------------------------------------------------------------------------------
' ADC
'-------------------------------------------------------------------------------

Declare Adin_Res = 10
Declare Adin_Tad = 32_FOSC
Declare Adin_Stime = 50

'-------------------------------------------------------------------------------
' I2C
'-------------------------------------------------------------------------------

Declare Hbus_Bitrate = 400

Symbol OLED_W = %01111000

'-------------------------------------------------------------------------------
' VARIABLES
'-------------------------------------------------------------------------------

Dim vresult As Word
Dim Voltage As Dword

Dim Digit[3] As Byte

Dim p As Byte
Dim i As Byte
Dim c As Byte
Dim w As Byte

Dim DataByte As Byte
Dim FontAddress As Word

'===============================================================================
' INICIALIZAR OLED
'===============================================================================

HBusOut OLED_W,[$00,$AE]       ' Display OFF

HBusOut OLED_W,[$00,$20]       ' Memory addressing mode
HBusOut OLED_W,[$00,$00]       ' Horizontal addressing

HBusOut OLED_W,[$00,$B0]       ' Page start

HBusOut OLED_W,[$00,$C8]       ' COM scan direction

HBusOut OLED_W,[$00,$00]       ' Low column

HBusOut OLED_W,[$00,$10]       ' High column

HBusOut OLED_W,[$00,$40]       ' Start line

HBusOut OLED_W,[$00,$81]       ' Contrast
HBusOut OLED_W,[$00,$7F]

HBusOut OLED_W,[$00,$A1]       ' Segment remap

HBusOut OLED_W,[$00,$A6]       ' Normal display

HBusOut OLED_W,[$00,$A8]       ' Multiplex
HBusOut OLED_W,[$00,$3F]

HBusOut OLED_W,[$00,$D3]       ' Display offset
HBusOut OLED_W,[$00,$00]

HBusOut OLED_W,[$00,$D5]       ' Clock
HBusOut OLED_W,[$00,$80]

HBusOut OLED_W,[$00,$D9]       ' Pre-charge
HBusOut OLED_W,[$00,$F1]

HBusOut OLED_W,[$00,$DA]       ' COM pins
HBusOut OLED_W,[$00,$12]

HBusOut OLED_W,[$00,$DB]       ' VCOM
HBusOut OLED_W,[$00,$40]

HBusOut OLED_W,[$00,$8D]       ' Charge pump
HBusOut OLED_W,[$00,$14]

HBusOut OLED_W,[$00,$AF]       ' Display ON

DelayMS 200


'===============================================================================
' PROGRAMA PRINCIPAL
'===============================================================================

Main:

    '---------------------------------------------------------------------------
    ' LEER ADC
    '---------------------------------------------------------------------------

    vresult = ADIn 0

    Voltage = vresult * 500/1023

    If Voltage > 999 Then
        Voltage = 999
    EndIf


    '---------------------------------------------------------------------------
    ' SEPARAR DIGITOS
    '---------------------------------------------------------------------------

    Digit[0] = Dig Voltage, 2

    Digit[1] = Dig Voltage, 1

    Digit[2] = Dig Voltage ,0


    '---------------------------------------------------------------------------
    ' BORRAR PANTALLA
    '---------------------------------------------------------------------------

    For p = 0 To 7

        HBusOut OLED_W,[$00,$B0 + p]
        HBusOut OLED_W,[$00,$00]
        HBusOut OLED_W,[$00,$10]

        For i = 0 To 2

            '---------------------------------------------------------------
            ' Dirección del dígito
            '---------------------------------------------------------------

            FontAddress = Digit[i] * 5

            '---------------------------------------------------------------
            ' Cinco columnas
            '---------------------------------------------------------------

            For c = 0 To 4

                DataByte = CRead8 Fonts[FontAddress + c]

                '-----------------------------------------------------------
                ' Extraer el BIT correspondiente a esta página
                '-----------------------------------------------------------

                If (DataByte & (1 << p)) <> 0 Then

                    DataByte = $FF

                Else

                    DataByte = $00

                EndIf


                '-----------------------------------------------------------
                ' Agrandar horizontalmente
                '-----------------------------------------------------------

                For w = 0 To 6

                    HBusOut OLED_W,[$40,DataByte]

                Next

            Next


            '---------------------------------------------------------------
            ' Espacio entre dígitos
            '---------------------------------------------------------------

            For w = 0 To 5

                HBusOut OLED_W,[$40,$00]

            Next

        Next

    Next


    DelayMS 100

GoTo Main


'===============================================================================
' FUENTE 5x8
'
' Cada dígito = 5 columnas
' Cada bit = una fila vertical
'
'===============================================================================

Dim Fonts As Code = As Byte _
    $3E,$51,$49,$45,$3E, _       ' 0
    $00,$42,$7F,$40,$00, _       ' 1
    $42,$61,$51,$49,$46, _       ' 2
    $21,$41,$45,$4B,$31, _       ' 3
    $18,$14,$12,$7F,$10, _       ' 4
    $27,$45,$45,$45,$39, _       ' 5
    $3C,$4A,$49,$49,$30, _       ' 6
    $01,$71,$09,$05,$03, _       ' 7
    $36,$49,$49,$49,$36, _       ' 8
    $06,$49,$49,$29,$1E          ' 9

End


tolyan249

Thank you very much for your help.

Pepe

more digits
'===============================================================================
' PIC12F1840
' OLED 128x64 I2C SSD1306 / SSD1315
' 3 DIGITOS GRANDES
'===============================================================================
;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 12F1840

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_OFF, STVREN_OFF, BORV_19, LVP_OFF

;**** End of Fuse Configurator Settings ****


Declare Xtal = 16
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog off
OSCCON = %01111010

'-------------------------------------------------------------------------------
' PUERTOS
'-------------------------------------------------------------------------------

TRISA = %00001001
ANSELA = %00000001
ADCON1.7 = 1
' RA0 = ADC

'-------------------------------------------------------------------------------
' ADC
'-------------------------------------------------------------------------------

Declare Adin_Res = 10
Declare Adin_Tad = 32_FOSC
Declare Adin_Stime = 50

'-------------------------------------------------------------------------------
' I2C
'-------------------------------------------------------------------------------

Declare Hbus_Bitrate = 400

Symbol OLED_W = %01111000

'-------------------------------------------------------------------------------
' VARIABLES
'-------------------------------------------------------------------------------

Dim vresult As Word
Dim Voltage As Dword

Dim Digit[4] As Byte

Dim p As Byte
Dim i As Byte
Dim c As Byte
Dim w As Byte

Dim DataByte As Byte
Dim FontAddress As Word

'===============================================================================
' INICIALIZAR OLED
'===============================================================================

HBusOut OLED_W,[$00,$AE]       ' Display OFF

HBusOut OLED_W,[$00,$20]       ' Memory addressing mode
HBusOut OLED_W,[$00,$00]       ' Horizontal addressing

HBusOut OLED_W,[$00,$B0]       ' Page start

HBusOut OLED_W,[$00,$C8]       ' COM scan direction

HBusOut OLED_W,[$00,$00]       ' Low column

HBusOut OLED_W,[$00,$10]       ' High column

HBusOut OLED_W,[$00,$40]       ' Start line

HBusOut OLED_W,[$00,$81]       ' Contrast
HBusOut OLED_W,[$00,$7F]

HBusOut OLED_W,[$00,$A1]       ' Segment remap

HBusOut OLED_W,[$00,$A6]       ' Normal display

HBusOut OLED_W,[$00,$A8]       ' Multiplex
HBusOut OLED_W,[$00,$3F]

HBusOut OLED_W,[$00,$D3]       ' Display offset
HBusOut OLED_W,[$00,$00]

HBusOut OLED_W,[$00,$D5]       ' Clock
HBusOut OLED_W,[$00,$80]

HBusOut OLED_W,[$00,$D9]       ' Pre-charge
HBusOut OLED_W,[$00,$F1]

HBusOut OLED_W,[$00,$DA]       ' COM pins
HBusOut OLED_W,[$00,$12]

HBusOut OLED_W,[$00,$DB]       ' VCOM
HBusOut OLED_W,[$00,$40]

HBusOut OLED_W,[$00,$8D]       ' Charge pump
HBusOut OLED_W,[$00,$14]

HBusOut OLED_W,[$00,$AF]       ' Display ON

DelayMS 200


'===============================================================================
' PROGRAMA PRINCIPAL
'===============================================================================

Main:

    '---------------------------------------------------------------------------
    ' LEER ADC
    '---------------------------------------------------------------------------

    vresult = ADIn 0

    Voltage = vresult * 5000/1023

    If Voltage > 9999 Then
        Voltage = 9999
    EndIf


    '---------------------------------------------------------------------------
    ' SEPARAR DIGITOS
    '---------------------------------------------------------------------------

    Digit[0] = Dig Voltage, 3

    Digit[1] = Dig Voltage, 2

    Digit[2] = Dig Voltage ,1
   
    Digit[3] = Dig Voltage ,0
   
   

    '---------------------------------------------------------------------------
    ' BORRAR PANTALLA
    '---------------------------------------------------------------------------

    For p = 0 To 7

        HBusOut OLED_W,[$00,$B0 + p]
        HBusOut OLED_W,[$00,$00]
        HBusOut OLED_W,[$00,$10]

        For i = 0 To 3

            '---------------------------------------------------------------
            ' Dirección del dígito
            '---------------------------------------------------------------

            FontAddress = Digit[i] * 5

            '---------------------------------------------------------------
            ' Cinco columnas
            '---------------------------------------------------------------

            For c = 0 To 4

                DataByte = CRead8 Fonts[FontAddress + c]

                '-----------------------------------------------------------
                ' Extraer el BIT correspondiente a esta página
                '-----------------------------------------------------------

                If (DataByte & (1 << p)) <> 0 Then

                    DataByte = $FF

                Else

                    DataByte = $00

                EndIf


                '-----------------------------------------------------------
                ' Agrandar horizontalmente
                '-----------------------------------------------------------

                For w = 0 To 4

                    HBusOut OLED_W,[$40,DataByte]

                Next

            Next


            '---------------------------------------------------------------
            ' Espacio entre dígitos
            '---------------------------------------------------------------

            For w = 0 To 4

                HBusOut OLED_W,[$40,$00]

            Next

        Next

    Next


    DelayMS 100

GoTo Main


'===============================================================================
' FUENTE 5x8
'
' Cada dígito = 5 columnas
' Cada bit = una fila vertical
'
'===============================================================================

Dim Fonts As Code = As Byte _
    $3E,$51,$49,$45,$3E, _       ' 0
    $00,$42,$7F,$40,$00, _       ' 1
    $42,$61,$51,$49,$46, _       ' 2
    $21,$41,$45,$4B,$31, _       ' 3
    $18,$14,$12,$7F,$10, _       ' 4
    $27,$45,$45,$45,$39, _       ' 5
    $3C,$4A,$49,$49,$30, _       ' 6
    $01,$71,$09,$05,$03, _       ' 7
    $36,$49,$49,$49,$36, _       ' 8
    $06,$49,$49,$29,$1E          ' 9

End

tolyan249

#10
One more question: how can I remove the insignificant zeros at the front?
It needs to show 5 volts, but the indicator will show 005.

Thank you.

Pepe

#11
demo voltage with two decimals

'===============================================================================
' PIC12F1840
' OLED 128x64 I2C SSD1306 / SSD1315
' 3 DIGITOS GRANDES
'===============================================================================
;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 12F1840

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_OFF, STVREN_OFF, BORV_19, LVP_OFF

;**** End of Fuse Configurator Settings ****


Declare Xtal = 16
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog off
OSCCON = %01111010

'-------------------------------------------------------------------------------
' PUERTOS
'-------------------------------------------------------------------------------

TRISA = %00001001
ANSELA = %00000001
ADCON1.7 = 1
' RA0 = ADC

'-------------------------------------------------------------------------------
' ADC
'-------------------------------------------------------------------------------

Declare Adin_Res = 10
Declare Adin_Tad = 32_FOSC
Declare Adin_Stime = 50

'-------------------------------------------------------------------------------
' I2C
'-------------------------------------------------------------------------------

Declare Hbus_Bitrate = 400

Symbol OLED_W = $78

'-------------------------------------------------------------------------------
' VARIABLES
'-------------------------------------------------------------------------------

Dim vresult As Word
Dim Voltage As Dword


Dim Digito As Byte
Dim decimales As Byte = 2
Dim mostrar As Bit
Dim p As Byte
Dim i As Byte
Dim c As Byte
Dim w As Byte

Dim DataByte As Byte
Dim FontAddress As Word

'===============================================================================
' INICIALIZAR OLED
'===============================================================================

HBusOut OLED_W,[$00,$AE]       ' Display OFF

HBusOut OLED_W,[$00,$20]       ' Memory addressing mode
HBusOut OLED_W,[$00,$00]       ' Horizontal addressing

HBusOut OLED_W,[$00,$B0]       ' Page start

HBusOut OLED_W,[$00,$C8]       ' COM scan direction

HBusOut OLED_W,[$00,$00]       ' Low column

HBusOut OLED_W,[$00,$10]       ' High column

HBusOut OLED_W,[$00,$40]       ' Start line

HBusOut OLED_W,[$00,$81]       ' Contrast
HBusOut OLED_W,[$00,$7F]

HBusOut OLED_W,[$00,$A1]       ' Segment remap

HBusOut OLED_W,[$00,$A6]       ' Normal display

HBusOut OLED_W,[$00,$A8]       ' Multiplex
HBusOut OLED_W,[$00,$3F]

HBusOut OLED_W,[$00,$D3]       ' Display offset
HBusOut OLED_W,[$00,$00]

HBusOut OLED_W,[$00,$D5]       ' Clock
HBusOut OLED_W,[$00,$80]

HBusOut OLED_W,[$00,$D9]       ' Pre-charge
HBusOut OLED_W,[$00,$F1]

HBusOut OLED_W,[$00,$DA]       ' COM pins
HBusOut OLED_W,[$00,$12]

HBusOut OLED_W,[$00,$DB]       ' VCOM
HBusOut OLED_W,[$00,$40]

HBusOut OLED_W,[$00,$8D]       ' Charge pump
HBusOut OLED_W,[$00,$14]

HBusOut OLED_W,[$00,$AF]       ' Display ON

DelayMS 200


'===============================================================================
' PROGRAMA PRINCIPAL
'===============================================================================

Do

    '---------------------------------------------------------------------------
    ' LEER ADC
    '---------------------------------------------------------------------------

    vresult = ADIn 0

    Voltage = vresult * 500/1023

    If Voltage > 999 Then
                          Voltage = 999
    EndIf 

    For p = 0 To 7
       
        mostrar = 0
       
        HBusOut OLED_W,[$00,$B0 + p]
        HBusOut OLED_W,[$00,$00]
        HBusOut OLED_W,[$00,$10]

        For i = 2 To 0 Step -1

            '---------------------------------------------------------------
            ' Dirección del dígito
            '---------------------------------------------------------------
             If i + 1 = decimales  Then
                                        printpoint()
             EndIf
            
             Digito = Dig Voltage,i
            
             If Digito > 0 Then
                                mostrar = 1
             EndIf
            
             If mostrar = 1 Or i <= decimales Then 
                                                    printchar(Digito)
             EndIf
                              
        Next
       
        printchar(10)
    Next
   
    DelayMS 100

Loop

Proc printchar(chr As Byte)
 
 FontAddress = chr * 5

            '---------------------------------------------------------------
            ' Cinco columnas
            '---------------------------------------------------------------

            For c = 0 To 4

                DataByte = CRead8 Fonts[FontAddress + c]

                '-----------------------------------------------------------
                ' Extraer el BIT correspondiente a esta página
                '-----------------------------------------------------------

                If (DataByte & (1 << p)) <> 0 Then

                    DataByte = $FF

                Else

                    DataByte = $00

                EndIf


                '-----------------------------------------------------------
                ' Agrandar horizontalmente
                '-----------------------------------------------------------

                For w = 0 To 3

                    HBusOut OLED_W,[$40,DataByte]

                Next
              
            Next

            '---------------------------------------------------------------
            ' Espacio entre dígitos
            '---------------------------------------------------------------

            For w = 0 To 4
                HBusOut OLED_W,[$40,$00]
            Next
 EndProc          

Proc printpoint()
 
 If ($40 & (1 << p)) <> 0 Then
                                DataByte = $FF
                           Else
                                DataByte = $00

 EndIf

'-----------------------------------------------------------
' Agrandar horizontalmente
'-----------------------------------------------------------

 For w = 0 To 4
  HBusOut OLED_W,[$40,DataByte]
 Next

'---------------------------------------------------------------
' Espacio entre dígitos
'---------------------------------------------------------------

 For w = 0 To 4
  HBusOut OLED_W,[$40,$00]
 Next
 
EndProc                    
'===============================================================================
' FUENTE 5x8
'
' Cada dígito = 5 columnas
' Cada bit = una fila vertical
'
'===============================================================================

Dim Fonts As Code = As Byte _
    $3E,$51,$49,$45,$3E, _       ' 0
    $00,$42,$7F,$40,$00, _       ' 1
    $42,$61,$51,$49,$46, _       ' 2
    $21,$41,$45,$4B,$31, _       ' 3
    $18,$14,$12,$7F,$10, _       ' 4
    $27,$45,$45,$45,$39, _       ' 5
    $3C,$4A,$49,$49,$30, _       ' 6
    $01,$71,$09,$05,$03, _       ' 7
    $36,$49,$49,$49,$36, _       ' 8
    $06,$49,$49,$29,$1E, _       ' 9
    $00,$00,$00,$00,$00          ' " "
End

Pepe

#12
demo proteus with text

'===============================================================================
' PIC12F1840
' OLED 128x64 I2C SSD1306 / SSD1315
' 3 DIGITOS GRANDES + TEXTO POR FILA/COLUMNA
'===============================================================================

Device = 12F1840

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_OFF, STVREN_OFF, BORV_19, LVP_OFF

Declare Xtal = 16
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog off


'-------------------------------------------------------------------------------
' ADC
'-------------------------------------------------------------------------------

Declare Adin_Res = 10
Declare Adin_Tad = 32_FOSC
Declare Adin_Stime = 50

'-------------------------------------------------------------------------------
' I2C
'-------------------------------------------------------------------------------

Declare Hbus_Bitrate = 400

Symbol OLED_W = $78

'-------------------------------------------------------------------------------
' VARIABLES
'-------------------------------------------------------------------------------

Dim vresult As Word
Dim Voltage As Dword
Dim texto[10] As Byte ="VOLTIMETRO"
Dim Digito As Byte
Dim decimales As Byte = 2
Dim mostrar As Bit

Dim p As Byte
Dim i As Byte
Dim c As Byte
Dim w As Byte

Dim DataByte As Byte
Dim FontAddress As Word

' Variables para texto
Dim CharIndex As Byte
Dim TextPage As Byte
Dim TextColumn As Byte
Dim TextLow As Byte
Dim TextHigh As Byte


OSCCON = %01111010

'-------------------------------------------------------------------------------
' PUERTOS
'-------------------------------------------------------------------------------

TRISA = %00001001
ANSELA = %00000001
ADCON1.7 = 1

' RA0 = ADC

'===============================================================================
' INICIALIZAR OLED
'===============================================================================

HBusOut OLED_W,[$00,$AE]       ' Display OFF

HBusOut OLED_W,[$00,$20]       ' Memory addressing mode
HBusOut OLED_W,[$00,$00]       ' Horizontal addressing

HBusOut OLED_W,[$00,$B0]       ' Page start

HBusOut OLED_W,[$00,$C8]       ' COM scan direction

HBusOut OLED_W,[$00,$00]       ' Low column

HBusOut OLED_W,[$00,$10]       ' High column

HBusOut OLED_W,[$00,$40]       ' Start line

HBusOut OLED_W,[$00,$81]       ' Contrast
HBusOut OLED_W,[$00,$7F]

HBusOut OLED_W,[$00,$A1]       ' Segment remap

HBusOut OLED_W,[$00,$A6]       ' Normal display

HBusOut OLED_W,[$00,$A8]       ' Multiplex
HBusOut OLED_W,[$00,$3F]

HBusOut OLED_W,[$00,$D3]       ' Display offset
HBusOut OLED_W,[$00,$00]

HBusOut OLED_W,[$00,$D5]       ' Clock
HBusOut OLED_W,[$00,$80]

HBusOut OLED_W,[$00,$D9]       ' Pre-charge
HBusOut OLED_W,[$00,$F1]

HBusOut OLED_W,[$00,$DA]       ' COM pins
HBusOut OLED_W,[$00,$12]

HBusOut OLED_W,[$00,$DB]       ' VCOM
HBusOut OLED_W,[$00,$40]

HBusOut OLED_W,[$00,$8D]       ' Charge pump
HBusOut OLED_W,[$00,$14]

HBusOut OLED_W,[$00,$AF]       ' Display ON

DelayMS 200

'===============================================================================
' PROGRAMA PRINCIPAL
'===============================================================================
  PrintTextAt(2,4,texto)
    
   DelayMS 2000
  
   OLED_Clear ()
  
   PrintLargeCharAt(0,100,"V") 

Do

    '---------------------------------------------------------------------------
    ' LEER ADC
    '---------------------------------------------------------------------------

    vresult = ADIn 0

    Voltage = vresult * 500/1023

    If Voltage > 999 Then
        Voltage = 999
    EndIf
   
    '---------------------------------------------------------------------------
    ' MOSTRAR 3 DIGITOS GRANDES
    '---------------------------------------------------------------------------

    For p = 0 To 7

        mostrar = 0

        HBusOut OLED_W,[$00,$B0 + p]
        HBusOut OLED_W,[$00,$00]
        HBusOut OLED_W,[$00,$10]

        For i = 2 To 0 Step -1

            '-------------------------------------------------------------------
            ' Punto decimal
            '-------------------------------------------------------------------

            If i + 1 = decimales Then
                printpoint()
            EndIf

            Digito = Dig Voltage,i

            If Digito > 0 Then
                mostrar = 1
            EndIf

            If mostrar = 1 Or i <= decimales Then
                printchar(Digito)
            EndIf

        Next
       
    Next
   
    DelayMS 100

Loop

'===============================================================================
' BORRAR TODA LA PANTALLA OLED
'
' Borra las 8 páginas completas de 128 columnas.
'===============================================================================

Proc OLED_Clear()

    Dim ClearPage As Byte
    Dim ClearCol As Byte

    For ClearPage = 0 To 7

        HBusOut OLED_W,[$00,$B0 + ClearPage]
        HBusOut OLED_W,[$00,$00]
        HBusOut OLED_W,[$00,$10]

        For ClearCol = 0 To 127
            HBusOut OLED_W,[$40,$00]
        Next

    Next

EndProc
'===============================================================================
' IMPRIMIR CARACTER GRANDE
'
' Esta rutina es la que ya utilizaba el programa original.
'
' chr:
'   0..9  = numeros
'   10    = espacio
'   11..36 = A..Z
'
' p determina la fila de la fuente y tambien la pagina OLED.
'===============================================================================

Proc printchar(chr As Byte)

    FontAddress = chr * 5

    '---------------------------------------------------------------------------
    ' Cinco columnas
    '---------------------------------------------------------------------------

    For c = 0 To 4

        DataByte = CRead8 Fonts[FontAddress + c]

        '-----------------------------------------------------------------------
        ' Extraer el BIT correspondiente a esta pagina
        '-----------------------------------------------------------------------

        If (DataByte & (1 << p)) <> 0 Then
            DataByte = $FF
        Else
            DataByte = $00
        EndIf

        '-----------------------------------------------------------------------
        ' Agrandar horizontalmente
        '---------------------------------------------------------------------------

        For w = 0 To 3
            HBusOut OLED_W,[$40,DataByte]
        Next

    Next

    '---------------------------------------------------------------------------
    ' Espacio entre caracteres
    '---------------------------------------------------------------------------

    For w = 0 To 4
        HBusOut OLED_W,[$40,$00]
    Next

EndProc

'===============================================================================
' PUNTO DECIMAL GRANDE
'===============================================================================

Proc printpoint()

    If ($40 & (1 << p)) <> 0 Then
        DataByte = $FF
    Else
        DataByte = $00
    EndIf

    '---------------------------------------------------------------------------
    ' Agrandar horizontalmente
    '---------------------------------------------------------------------------

    For w = 0 To 4
        HBusOut OLED_W,[$40,DataByte]
    Next

    '---------------------------------------------------------------------------
    ' Espacio
    '---------------------------------------------------------------------------

    For w = 0 To 4
        HBusOut OLED_W,[$40,$00]
    Next

EndProc

'===============================================================================
' CONVERTIR CARACTER A NUMERO DE FUENTE
'
' 0..9  -> indices 0..9
' espacio -> 10
' A..Z -> 11..36
'===============================================================================

Proc CharToFont(chr As Byte), Byte

    If chr >= "0" And chr <= "9" Then

        Result = chr - "0"

    ElseIf chr >= "A" And chr <= "Z" Then

        Result = chr - "A" + 11

    ElseIf chr = " " Then

        Result = 10

    Else

        Result = 10

    EndIf

EndProc

'===============================================================================
' POSICIONAR CURSOR OLED
'
' Fila:
'   0..7
'
' Columna:
'   0..127
'
'===============================================================================

Proc OLED_Position(Fila As Byte, Columna As Byte)

    If Fila > 7 Then
        Fila = 7
    EndIf

    If Columna > 127 Then
        Columna = 127
    EndIf

    TextLow = Columna & $0F
    TextHigh = $10 | (Columna >> 4)

    HBusOut OLED_W,[$00,$B0 + Fila]
    HBusOut OLED_W,[$00,TextLow]
    HBusOut OLED_W,[$00,TextHigh]

EndProc

'===============================================================================
' IMPRIMIR UN CARACTER POR FILA Y COLUMNA
'
' Ejemplo:
'
' PrintCharAt(0,100,"V")
'
' Fila    = pagina OLED 0..7
' Columna = 0..127
'
' El caracter tiene 5x8 y se amplia 4 veces horizontalmente.
'===============================================================================

Proc PrintCharAt(Fila As Byte, Columna As Byte, chr As Byte)

    CharIndex = CharToFont(chr)

    OLED_Position(Fila,Columna)

    '---------------------------------------------------------------------------
    ' Imprimir caracter de 5x8
    '---------------------------------------------------------------------------

    FontAddress = CharIndex * 5

    For c = 0 To 4

        DataByte = CRead8 Fonts[FontAddress + c]

        If DataByte <> 0 Then

            ' El caracter se imprime normal dentro de la pagina.
            ' Cada bit representa una linea vertical.

            HBusOut OLED_W,[$40,DataByte]

        Else

            HBusOut OLED_W,[$40,$00]

        EndIf

    Next

EndProc

'===============================================================================
' IMPRIMIR TEXTO

' No se utiliza String.
'
'===============================================================================

Proc PrintTextAt(Fila As Byte, Columna As Byte, texto[10] As Byte)

    Dim ii As Byte = 0
    Columna=Columna*7
    Do 
   
    If texto[ii] <> 0 Then
                           PrintCharAt(Fila,Columna,texto[ii])
                           Columna = Columna + 7
                     Else
                           ExitProc
    EndIf
    Inc ii
    Loop
   

EndProc
'===============================================================================
' IMPRIMIR CARACTER GRANDE POR FILA Y COLUMNA
'
' Caracter de fuente 5x8 ampliado 4 veces horizontalmente.
' Ocupa aproximadamente 20 columnas x 8 filas.
'
' Ejemplo:
'
'   PrintLargeCharAt(0,100,"V")
'
'===============================================================================

Proc PrintLargeCharAt(Fila As Byte, Columna As Byte, chr As Byte)
    Dim bp As Byte
    CharIndex = CharToFont(chr)

    FontAddress = CharIndex * 5

    For bp = Fila To 7

        OLED_Position(bp,Columna)

        For c = 0 To 4

            DataByte = CRead8 Fonts[FontAddress + c]

            If (DataByte & (1 << (bp - Fila))) <> 0 Then
                DataByte = $FF
            Else
                DataByte = $00
            EndIf

            For w = 0 To 3
                HBusOut OLED_W,[$40,DataByte]
            Next

        Next

        ' Espacio después del carácter
        For w = 0 To 2
            HBusOut OLED_W,[$40,$00]
        Next

    Next

EndProc
'===============================================================================
' FUENTE 5x8
'
' Indices:
'
'  0 = 0
'  1 = 1
'  ...
'  9 = 9
' 10 = espacio
'
' 11 = A
' 12 = B
' 13 = C
' ...
' 36 = Z
'
'===============================================================================

Dim Fonts As Code = As Byte _

    $3E,$51,$49,$45,$3E, _       ' 0
    $00,$42,$7F,$40,$00, _       ' 1
    $42,$61,$51,$49,$46, _       ' 2
    $21,$41,$45,$4B,$31, _       ' 3
    $18,$14,$12,$7F,$10, _       ' 4
    $27,$45,$45,$45,$39, _       ' 5
    $3C,$4A,$49,$49,$30, _       ' 6
    $01,$71,$09,$05,$03, _       ' 7
    $36,$49,$49,$49,$36, _       ' 8
    $06,$49,$49,$29,$1E, _       ' 9

    $00,$00,$00,$00,$00, _       ' espacio

    $7E,$11,$11,$11,$7E, _       ' A
    $7F,$49,$49,$49,$36, _       ' B
    $3E,$41,$41,$41,$22, _       ' C
    $7F,$41,$41,$22,$1C, _       ' D
    $7F,$49,$49,$49,$41, _       ' E
    $7F,$09,$09,$09,$01, _       ' F
    $3E,$41,$49,$49,$7A, _       ' G
    $7F,$08,$08,$08,$7F, _       ' H
    $00,$41,$7F,$41,$00, _       ' I
    $20,$40,$41,$3F,$01, _       ' J
    $7F,$08,$14,$22,$41, _       ' K
    $7F,$40,$40,$40,$40, _       ' L
    $7F,$02,$0C,$02,$7F, _       ' M
    $7F,$04,$08,$10,$7F, _       ' N
    $3E,$41,$41,$41,$3E, _       ' O
    $7F,$09,$09,$09,$06, _       ' P
    $3E,$41,$51,$21,$5E, _       ' Q
    $7F,$09,$19,$29,$46, _       ' R
    $46,$49,$49,$49,$31, _       ' S
    $01,$01,$7F,$01,$01, _       ' T
    $3F,$40,$40,$40,$3F, _       ' U
    $1F,$20,$40,$20,$1F, _       ' V
    $3F,$40,$38,$40,$3F, _       ' W
    $63,$14,$08,$14,$63, _       ' X
    $07,$08,$70,$08,$07, _       ' Y
    $61,$51,$49,$45,$43          ' Z

End

Pepe

#13
with scroll

'===============================================================================
' PIC12F1840
' OLED 128x64 I2C SSD1306 / SSD1315
' 3 DIGITOS GRANDES + TEXTO POR FILA/COLUMNA
'===============================================================================

Device = 12F1840

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_OFF, STVREN_OFF, BORV_19, LVP_OFF

Declare Xtal = 16
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog off


'-------------------------------------------------------------------------------
' ADC
'-------------------------------------------------------------------------------

Declare Adin_Res = 10
Declare Adin_Tad = 32_FOSC
Declare Adin_Stime = 50

'-------------------------------------------------------------------------------
' I2C
'-------------------------------------------------------------------------------

Declare Hbus_Bitrate = 400

Symbol OLED_W = $78

'-------------------------------------------------------------------------------
' VARIABLES
'-------------------------------------------------------------------------------

Dim vresult As Word
Dim Voltage As Dword
Dim texto[10] As Byte ="VOLTIMETRO"
Dim Digito As Byte
Dim decimales As Byte = 2
Dim mostrar As Bit

Dim p As Byte
Dim i As Byte
Dim c As Byte
Dim w As Byte

Dim DataByte As Byte
Dim FontAddress As Word

' Variables para texto
Dim CharIndex As Byte
Dim TextPage As Byte
Dim TextColumn As Byte
Dim TextLow As Byte
Dim TextHigh As Byte
Dim veces As Byte
Dim scrollpos As Word
OSCCON = %01111010

'-------------------------------------------------------------------------------
' PUERTOS
'-------------------------------------------------------------------------------

TRISA = %00001001
ANSELA = %00000001
ADCON1.7 = 1

' RA0 = ADC

'===============================================================================
' INICIALIZAR OLED
'===============================================================================

HBusOut OLED_W,[$00,$AE]       ' Display OFF

HBusOut OLED_W,[$00,$20]       ' Memory addressing mode
HBusOut OLED_W,[$00,$00]       ' Horizontal addressing

HBusOut OLED_W,[$00,$B0]       ' Page start

HBusOut OLED_W,[$00,$C8]       ' COM scan direction

HBusOut OLED_W,[$00,$00]       ' Low column

HBusOut OLED_W,[$00,$10]       ' High column

HBusOut OLED_W,[$00,$40]       ' Start line

HBusOut OLED_W,[$00,$81]       ' Contrast
HBusOut OLED_W,[$00,$7F]

HBusOut OLED_W,[$00,$A1]       ' Segment remap

HBusOut OLED_W,[$00,$A6]       ' Normal display

HBusOut OLED_W,[$00,$A8]       ' Multiplex
HBusOut OLED_W,[$00,$3F]

HBusOut OLED_W,[$00,$D3]       ' Display offset
HBusOut OLED_W,[$00,$00]

HBusOut OLED_W,[$00,$D5]       ' Clock
HBusOut OLED_W,[$00,$80]

HBusOut OLED_W,[$00,$D9]       ' Pre-charge
HBusOut OLED_W,[$00,$F1]

HBusOut OLED_W,[$00,$DA]       ' COM pins
HBusOut OLED_W,[$00,$12]

HBusOut OLED_W,[$00,$DB]       ' VCOM
HBusOut OLED_W,[$00,$40]

HBusOut OLED_W,[$00,$8D]       ' Charge pump
HBusOut OLED_W,[$00,$14]

HBusOut OLED_W,[$00,$AF]       ' Display ON

DelayMS 200

'===============================================================================
' PROGRAMA PRINCIPAL
'===============================================================================
 
 
  PrintTextscrollAt(2,texto)

   
   OLED_Clear ()
   
   PrintLargeCharAt(0,100,"V") 

Do

    '---------------------------------------------------------------------------
    ' LEER ADC
    '---------------------------------------------------------------------------

    vresult = ADIn 0

    Voltage = vresult * 500/1023

    If Voltage > 999 Then
        Voltage = 999
    EndIf
   
    '---------------------------------------------------------------------------
    ' MOSTRAR 3 DIGITOS GRANDES
    '---------------------------------------------------------------------------

    For p = 0 To 7

        mostrar = 0

        HBusOut OLED_W,[$00,$B0 + p]
        HBusOut OLED_W,[$00,$00]
        HBusOut OLED_W,[$00,$10]

        For i = 2 To 0 Step -1

            '-------------------------------------------------------------------
            ' Punto decimal
            '-------------------------------------------------------------------

            If i + 1 = decimales Then
                printpoint()
            EndIf

            Digito = Dig Voltage,i

            If Digito > 0 Then
                mostrar = 1
            EndIf

            If mostrar = 1 Or i <= decimales Then
                printchar(Digito)
            EndIf

        Next
       
    Next
   
    DelayMS 100

Loop

'===============================================================================
' BORRAR TODA LA PANTALLA OLED
'
' Borra las 8 páginas completas de 128 columnas.
'===============================================================================

Proc OLED_Clear()

    Dim ClearPage As Byte
    Dim ClearCol As Byte

    For ClearPage = 0 To 7

        HBusOut OLED_W,[$00,$B0 + ClearPage]
        HBusOut OLED_W,[$00,$00]
        HBusOut OLED_W,[$00,$10]

        For ClearCol = 0 To 127
            HBusOut OLED_W,[$40,$00]
        Next

    Next

EndProc
'===============================================================================
' IMPRIMIR CARACTER GRANDE
'
' Esta rutina es la que ya utilizaba el programa original.
'
' chr:
'   0..9  = numeros
'   10    = espacio
'   11..36 = A..Z
'
' p determina la fila de la fuente y tambien la pagina OLED.
'===============================================================================

Proc printchar(chr As Byte)

    FontAddress = chr * 5

    '---------------------------------------------------------------------------
    ' Cinco columnas
    '---------------------------------------------------------------------------

    For c = 0 To 4

        DataByte = CRead8 Fonts[FontAddress + c]

        '-----------------------------------------------------------------------
        ' Extraer el BIT correspondiente a esta pagina
        '-----------------------------------------------------------------------

        If (DataByte & (1 << p)) <> 0 Then
            DataByte = $FF
        Else
            DataByte = $00
        EndIf

        '-----------------------------------------------------------------------
        ' Agrandar horizontalmente
        '---------------------------------------------------------------------------

        For w = 0 To 3
            HBusOut OLED_W,[$40,DataByte]
        Next

    Next

    '---------------------------------------------------------------------------
    ' Espacio entre caracteres
    '---------------------------------------------------------------------------

    For w = 0 To 4
        HBusOut OLED_W,[$40,$00]
    Next

EndProc

'===============================================================================
' PUNTO DECIMAL GRANDE
'===============================================================================

Proc printpoint()

    If ($40 & (1 << p)) <> 0 Then
        DataByte = $FF
    Else
        DataByte = $00
    EndIf

    '---------------------------------------------------------------------------
    ' Agrandar horizontalmente
    '---------------------------------------------------------------------------

    For w = 0 To 4
        HBusOut OLED_W,[$40,DataByte]
    Next

    '---------------------------------------------------------------------------
    ' Espacio
    '---------------------------------------------------------------------------

    For w = 0 To 4
        HBusOut OLED_W,[$40,$00]
    Next

EndProc

'===============================================================================
' CONVERTIR CARACTER A NUMERO DE FUENTE
'
' 0..9  -> indices 0..9
' espacio -> 10
' A..Z -> 11..36
'===============================================================================

Proc CharToFont(chr As Byte), Byte

    If chr >= "0" And chr <= "9" Then

        Result = chr - "0"

    ElseIf chr >= "A" And chr <= "Z" Then

        Result = chr - "A" + 11

    ElseIf chr = " " Then

        Result = 10

    Else

        Result = 10

    EndIf

EndProc

'===============================================================================
' POSICIONAR CURSOR OLED
'
' Fila:
'   0..7
'
' Columna:
'   0..127
'
'===============================================================================

Proc OLED_Position(Fila As Byte, Columna As Byte)

    If Fila > 7 Then
        Fila = 7
    EndIf

    If Columna > 127 Then
        Columna = 127
    EndIf

    TextLow = Columna & $0F
    TextHigh = $10 | (Columna >> 4)

    HBusOut OLED_W,[$00,$B0 + Fila]
    HBusOut OLED_W,[$00,TextLow]
    HBusOut OLED_W,[$00,TextHigh]

EndProc

'===============================================================================
' IMPRIMIR UN CARACTER POR FILA Y COLUMNA
'
' Ejemplo:
'
' PrintCharAt(0,100,"V")
'
' Fila    = pagina OLED 0..7
' Columna = 0..127
'
' El caracter tiene 5x8 y se amplia 4 veces horizontalmente.
'===============================================================================

Proc PrintCharAt(Fila As Byte, Columna As Byte, chr As Byte)

    CharIndex = CharToFont(chr)

    OLED_Position(Fila,Columna)

    '---------------------------------------------------------------------------
    ' Imprimir caracter de 5x8
    '---------------------------------------------------------------------------

    FontAddress = CharIndex * 5

    For c = 0 To 4

        DataByte = CRead8 Fonts[FontAddress + c]

        If DataByte <> 0 Then

            ' El caracter se imprime normal dentro de la pagina.
            ' Cada bit representa una linea vertical.

            HBusOut OLED_W,[$40,DataByte]

        Else

            HBusOut OLED_W,[$40,$00]

        EndIf

    Next

EndProc

'===============================================================================
' IMPRIMIR TEXTO

' No se utiliza String.
'
'===============================================================================

Proc PrintTextAt(Fila As Byte, Columna As Byte, texto[10] As Byte)

    Dim ii As Byte = 0
    Columna=Columna*7
    Do 
   
    If texto[ii] <> 0 Then
                           PrintCharAt(Fila,Columna,texto[ii])
                           Columna = Columna + 7
                     Else
                           ExitProc
    EndIf
    Inc ii
    Loop
   

EndProc
'===============================================================================
' IMPRIMIR CARACTER GRANDE POR FILA Y COLUMNA
'
' Caracter de fuente 5x8 ampliado 4 veces horizontalmente.
' Ocupa aproximadamente 20 columnas x 8 filas.
'
' Ejemplo:
'
'   PrintLargeCharAt(0,100,"V")
'
'===============================================================================

Proc PrintLargeCharAt(Fila As Byte, Columna As Byte, chr As Byte)
    Dim bp As Byte
    CharIndex = CharToFont(chr)

    FontAddress = CharIndex * 5

    For bp = Fila To 7

        OLED_Position(bp,Columna)

        For c = 0 To 4

            DataByte = CRead8 Fonts[FontAddress + c]

            If (DataByte & (1 << (bp - Fila))) <> 0 Then
                DataByte = $FF
            Else
                DataByte = $00
            EndIf

            For w = 0 To 3
                HBusOut OLED_W,[$40,DataByte]
            Next

        Next

        ' Espacio después del carácter
        For w = 0 To 2
            HBusOut OLED_W,[$40,$00]
        Next

    Next

EndProc

'===============================================================================
' IMPRIMIR TEXTO CON DESPLAZAMIENTO HACIA LA IZQUIERDA
'
' Cada vez que se llama a PrintTextAt(), el texto avanza 1 columna.
'
'===============================================================================

Proc PrintTextscrollAt(Fila As Byte, texto[10] As Byte)
    Dim ii As Byte
    Dim posicion As Word
    Dim FontIndex As Byte
    Dim FontPos As Word
    Dim FontData As Byte
    Dim xx As Byte
    Dim PosChr As Word
    Dim AnchoTexto As Word
    Dim Repeticiones As Byte
    Dim nn As Byte

    AnchoTexto = 1
    Repeticiones = 3

    For nn = 1 To Repeticiones

        For posicion = 128 To -AnchoTexto Step -1

            ' Clear text page
            OLED_Position(Fila,0)

            For xx = 0 To 127
                HBusOut OLED_W,[$40,$00]
            Next

            ' Draw scrolling text
            PosChr = posicion

            For ii = 0 To 9

                FontIndex = CharToFont(texto[ii])
                FontPos = FontIndex * 5

                For xx = 0 To 4

                    If PosChr >= 0 And PosChr < 128 Then
                        FontData = CRead8 Fonts[FontPos + xx]

                        OLED_Position(Fila,PosChr)
                        HBusOut OLED_W,[$40,FontData]
                    EndIf

                    Inc PosChr
                Next

                ' Space between characters
                Inc PosChr
            Next

            DelayMS 50

        Next

    Next
EndProc

'===============================================================================
' FUENTE 5x8
'
' Indices:
'
'  0 = 0
'  1 = 1
'  ...
'  9 = 9
' 10 = espacio
'
' 11 = A
' 12 = B
' 13 = C
' ...
' 36 = Z
'
'===============================================================================

Dim Fonts As Code = As Byte _

    $3E,$51,$49,$45,$3E, _       ' 0
    $00,$42,$7F,$40,$00, _       ' 1
    $42,$61,$51,$49,$46, _       ' 2
    $21,$41,$45,$4B,$31, _       ' 3
    $18,$14,$12,$7F,$10, _       ' 4
    $27,$45,$45,$45,$39, _       ' 5
    $3C,$4A,$49,$49,$30, _       ' 6
    $01,$71,$09,$05,$03, _       ' 7
    $36,$49,$49,$49,$36, _       ' 8
    $06,$49,$49,$29,$1E, _       ' 9

    $00,$00,$00,$00,$00, _       ' espacio

    $7E,$11,$11,$11,$7E, _       ' A
    $7F,$49,$49,$49,$36, _       ' B
    $3E,$41,$41,$41,$22, _       ' C
    $7F,$41,$41,$22,$1C, _       ' D
    $7F,$49,$49,$49,$41, _       ' E
    $7F,$09,$09,$09,$01, _       ' F
    $3E,$41,$49,$49,$7A, _       ' G
    $7F,$08,$08,$08,$7F, _       ' H
    $00,$41,$7F,$41,$00, _       ' I
    $20,$40,$41,$3F,$01, _       ' J
    $7F,$08,$14,$22,$41, _       ' K
    $7F,$40,$40,$40,$40, _       ' L
    $7F,$02,$0C,$02,$7F, _       ' M
    $7F,$04,$08,$10,$7F, _       ' N
    $3E,$41,$41,$41,$3E, _       ' O
    $7F,$09,$09,$09,$06, _       ' P
    $3E,$41,$51,$21,$5E, _       ' Q
    $7F,$09,$19,$29,$46, _       ' R
    $46,$49,$49,$49,$31, _       ' S
    $01,$01,$7F,$01,$01, _       ' T
    $3F,$40,$40,$40,$3F, _       ' U
    $1F,$20,$40,$20,$1F, _       ' V
    $3F,$40,$38,$40,$3F, _       ' W
    $63,$14,$08,$14,$63, _       ' X
    $07,$08,$70,$08,$07, _       ' Y
    $61,$51,$49,$45,$43          ' Z

End

tolyan249

Thank you very much for your help.