News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

LCD indicator 3 segments

Started by tolyan249, Sep 06, 2026, 06:25 AM

Previous topic - Next topic

tolyan249

There's an indicator like this on AliExpress, but it doesn't have a name and there's no model for it in Proteus. Does anyone know what kind of indicator it is and where I can get its model?

https://aliexpress.ru/item/1005003745628043.html?sku_id=12000027017468402&spm=a2g2w.productlist.search_results.7.6487603cqvaP9h

trastikata

Looks like nice little display 1/4 duty, 1/2 bias panel.

You'd need a LCD driver or PIC with LCD driver like the PIC16F913 family.




tolyan249

' Processor Settings
Device = 16F819
Config INTRC_IO, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
Xtal = 4

' ADC (Analog-to-Digital Converter) Settings
Declare Adin_Res 10        ' 10-bit resolution (0-1023)
Declare Adin_Tad FRC        ' ADC clock source
Declare Adin_Stime 50      ' Sampling time in microseconds



ADCON1 = %10001110          ' RA0 as analog input, others as digital

' Variables
Dim ADC_Raw As Word          ' Raw value from ADC
Dim Voltage As Word          ' Calculated voltage (e.g., 500 for 5.00V)
Dim Digit1 As Byte          ' Units (Right Digit)
Dim Digit2 As Byte          ' Tens (Middle Digit)
Dim Digit3 As Byte          ' Hundreds (Left Digit)
Dim Step_COM As Byte        ' Current multiplexing step (0-3)
Dim Segments As Byte        ' Data byte for PORTB
Dim I As Byte                ' Loop counter for display refresh
Dim Temp_P As Byte          ' Temporary pattern storage

' Patterns Table (4 steps per digit)
' Indexes 0-9: Digits, Index 10: BLANK (Zero Suppression)
' Bit 0: Line A,B,C | Bit 1: Line D,E,F,G
DigitsTable:
CData $02, $03, $01, $03, _ ' 0
      $00, $01, $01, $00, _ ' 1
      $02, $02, $03, $01, _ ' 2
      $02, $01, $03, $01, _ ' 3
      $00, $01, $03, $02, _ ' 4
      $02, $01, $02, $03, _ ' 5
      $02, $03, $02, $03, _ ' 6
      $00, $01, $01, $01, _ ' 7
      $02, $03, $03, $03, _ ' 8
      $02, $01, $03, $03, _ ' 9
      $00, $00, $00, $00    ' 10 - BLANK (All segments OFF)

' Port Initialization
TRISB = %00000000            ' Set PORTB as output (segments)
TRISA = %00000001            ' RA0 as input (ADC), others as output (COM lines)
PORTA = 0
PORTB = 0

Main:
    ' 1. Read the input voltage
    ADC_Raw = ADIn 0
    ' Scale: 0-1023 -> 0-500 (represents 0.00V - 5.00V)
    Voltage = (ADC_Raw * 500) / 1023

    ' 2. Split the value into individual digits
    Digit3 = Voltage / 100        ' Hundreds (Leftmost digit)
    Digit2 = (Voltage / 10) // 10  ' Tens (Middle digit)
    Digit1 = Voltage // 10        ' Units (Rightmost digit)

    ' --- LEADING ZERO SUPPRESSION LOGIC ---
    If Digit3 = 0 Then
        Digit3 = 10                ' If hundreds = 0, set to BLANK
        If Digit2 = 0 Then
            Digit2 = 10            ' If tens are also 0, set to BLANK
        End If
    End If
    ' Digit1 is never blanked, so "0" is shown if voltage is 0.00
    ' ---------------------------------------

    ' 3. Dynamic Display Multiplexing
    For I = 0 To 30
        For Step_COM = 0 To 3
            ' Clear ports before switching to the next COM line
            PORTA = PORTA & %00000001 ' Keep RA0, clear RA1-RA4
            PORTB = 0

            Segments = 0
           
            ' Construct the PORTB byte (Bits 0-1: D3, 2-3: D2, 4-5: D1)
            ' Digit 3 (Left)
            Temp_P = CRead DigitsTable + (Digit3 * 4) + Step_COM
            Segments = Segments | Temp_P
           
            ' Digit 2 (Middle)
            Temp_P = CRead DigitsTable + (Digit2 * 4) + Step_COM
            Segments = Segments | (Temp_P << 2)
           
            ' Digit 1 (Right)
            Temp_P = CRead DigitsTable + (Digit1 * 4) + Step_COM
            Segments = Segments | (Temp_P << 4)

            ' Output segment data
            PORTB = Segments

            ' Activate the corresponding COM line (RA1 to RA4)
            Select Case Step_COM
                Case 0
                  Set PORTA.1 ' Activate COM1
                Case 1
                  Set PORTA.2 ' Activate COM2
                Case 2
                  Set PORTA.3 ' Activate COM3
                Case 3
                  Set PORTA.4 ' Activate COM4
            End Select

            DelayMS 2 ' Glow time for each step
        Next Step_COM
    Next I
GoTo Main


I've roughly written the program, but I can't test it in Proteus — there's no model for such an indicator.

CPR

As it's cheap on AliExpress, perhaps just buy one and test it out ? That'll give you real results and perhaps uncover some other things -  rather than trying to find a simulator model?

Pepe

#4
demo proteus with lcd 3 digits

and program fixed

'***********************************************************************
'      LCD 3 DIGITS - 4 COM
'
'      PIC16F819
'
'     
'
'      RB0 = pin 1 = 3C
'      RB1 = pin 2 = 3D
'      RB2 = pin 3 = 2C
'      RB3 = pin 4 = 2D
'      RB4 = pin 5 = 1C
'      RB5 = pin 6 = 1D
'
'      RA1 = pin 10 = COM1
'      RA2 = pin 9  = COM2
'      RA3 = pin 8  = COM3
'      RA4 = pin 7  = COM4
'
'      RA0 = ADC
'
'      Muestra 0 ... 500
'
'***********************************************************************

Device = 16F819

Config FOSC_INTOSCIO, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, _
      BOREN_OFF, LVP_OFF, CPD_OFF, WRT_OFF, DEBUG_OFF, _
      CCPMX_RB2, CP_OFF

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

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

Declare Adin_Res 10
Declare Adin_Tad FRC
Declare Adin_Stime 50

ADCON1 = %10001110

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

Dim ADC_Raw As Dword
Dim Voltage As Word

Dim Digit1 As Byte
Dim Digit2 As Byte
Dim Digit3 As Byte

Dim Step_COM As Byte
Dim Segments As Byte
Dim Temp_P As Byte

Dim LCD_Phase As Bit

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

TRISA = %00000001
TRISB = %00000000

PORTA = 0
PORTB = 0

LCD_Phase = 0

'***********************************************************************
' PROGRAMA PRINCIPAL
'***********************************************************************

Do

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

    ADC_Raw = ADIn 0

    '0 ... 1023 -> 0 ... 500

    Voltage = (ADC_Raw * 500) / 1023
 
    '-------------------------------------------------------------------
    ' SEPARAR LOS TRES DIGITOS
    '-------------------------------------------------------------------

    Digit3 = Dig Voltage, 2
    Digit2 = Dig Voltage, 1
    Digit1 = Dig Voltage, 0

    '-------------------------------------------------------------------
    ' SUPRESION DE CEROS A LA IZQUIERDA
    '-------------------------------------------------------------------

    If Digit3 = 0 Then

        Digit3 = 10

        If Digit2 = 0 Then
            Digit2 = 10
        End If

    End If

    '-------------------------------------------------------------------
    ' MOSTRAR UNA TRAMA COMPLETA
    '-------------------------------------------------------------------

    For Step_COM = 0 To 3

        '---------------------------------------------------------------
        ' APAGAR COM
        '---------------------------------------------------------------

        Clear PORTA
     

        '---------------------------------------------------------------
        ' CONSTRUIR LOS SEGMENTOS
        '
        ' DIGITO 3 -> RB0/RB1
        ' DIGITO 2 -> RB2/RB3
        ' DIGITO 1 -> RB4/RB5
        '---------------------------------------------------------------

        Temp_P = CRead LCD_Table + (Digit3 * 4) + Step_COM

        Segments = Temp_P

        Temp_P = CRead LCD_Table + (Digit2 * 4) + Step_COM

        Segments = Segments | (Temp_P << 2)

        Temp_P = CRead LCD_Table + (Digit1 * 4) + Step_COM

        Segments = Segments | (Temp_P << 4)

        '---------------------------------------------------------------
        ' FASE NORMAL
        '---------------------------------------------------------------

        If LCD_Phase = 0 Then

            PORTB = Segments

            Select Case Step_COM

                Case 0
                    Set PORTA.1

                Case 1
                    Set PORTA.2

                Case 2
                    Set PORTA.3

                Case 3
                    Set PORTA.4

            End Select

        Else

            '-----------------------------------------------------------
            ' FASE INVERTIDA
            '-----------------------------------------------------------

            PORTB = ~Segments

            Select Case Step_COM

                Case 0
                    PORTA = $1C

                Case 1
                    PORTA = $1A

                Case 2
                    PORTA = $16

                Case 3
                    PORTA = $E

            End Select

        End If

        '---------------------------------------------------------------
        ' TIEMPO DE CADA COM
        '---------------------------------------------------------------

        DelayMS 2

    Next Step_COM

    '-------------------------------------------------------------------
    ' INVERTIR POLARIDAD
    '-------------------------------------------------------------------

    Toggle LCD_Phase

Loop


'***********************************************************************
' TABLA DEL LCD
'
' Cada dígito tiene 4 bytes:
'
'              COM1  COM2  COM3  COM4
'
' DIGITO 1:
'              1D    1C/E  1B/G  1A/F
'
' DIGITO 2:
'              2D    2C/E  2B/G  2A/F
'
' DIGITO 3:
'              3D    3C/E  3B/G  3A/F
'
' BIT 0 = primer segmento de cada par
' BIT 1 = segundo segmento de cada par
'
'***********************************************************************

LCD_Table:

CData $02, $03, $01, $03, _    ' 0
      $00, $01, $01, $00, _    ' 1
      $02, $02, $03, $01, _    ' 2
      $02, $01, $03, $01, _    ' 3
      $00, $01, $03, $02, _    ' 4
      $02, $01, $02, $03, _    ' 5
      $02, $03, $02, $03, _    ' 6
      $00, $01, $01, $01, _    ' 7
      $02, $03, $03, $03, _    ' 8
      $02, $01, $03, $03, _    ' 9
      $00, $00, $00, $00        ' BLANK

tolyan249

#5
The whole problem is that these LCD indicators don't work with direct voltage, but with alternating voltage; the square wave must be in antiphase, with COM1, COM2, COM3, COM4, and the segments. I don't know yet how to do this.

Pepe

#6
look post #5 with square wave antiphase

Mapo

In the past, I have used LCD displays, driving them with standard PICs and PICs with dedicated peripherals. I achieved the best results with dedicated peripherals such as the PIC16F946.

tolyan249

Thank you all for your help.