News:

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

Main Menu

Voltmeter with an OLED indicator

Started by tolyan249, Today at 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 Today at 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