News:

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

Main Menu

Suggestion for new DEC modifiers

Started by kcsl, Mar 18, 2024, 09:29 AM

Previous topic - Next topic

kcsl

I do a lot of PIC data displaying on dumb terminals.
It would be great to have variants of the DEC modifiers that would output leading spaces instead of leading zeros as this would make reading lists of figures on the screen easier.

Just a thought.

Regards,
Joe
There's no room for optimism in software or hardware engineering.

top204

That is where procedures come into play.

A new procedure can be written by a user to perform a certain task, instead of relying on the compiler's built in functions. For example, a procedure I have just knocked together to add leading spaces to an integer to ASCII conversion is listed below, and it can be elaborated or reduced to suite by any user:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' A demonstration of a procedure to convert a decimal value to an ASCII String
'
' Written for the Positron8 compiler by Les Johnson.
'
    Device = 18F25K20                           ' Tell the compiler what device to compile for
    Declare Xtal = 16                           ' Tell the compiler what frequency the device will be operating at (in MHz)
'
' Setup USART1
'
    Declare Hserial1_Baud = 9600                ' Set the Baud rate to 9600
    Declare HRSOut1_Pin   = PORTC.6             ' Set the TX pin

    Dim MyDword As Dword
   
'-------------------------------------------------------------------------
' The main program starts here
'
Main:
    MyDword = 1234567           
    HRSOutLn DecToASCII(MyDword, 7)        
    HRSOutLn DecToASCII(MyDword, 6)         
    HRSOutLn DecToASCII(MyDword, 5)        
    HRSOutLn DecToASCII(MyDword, 4)
  
'-----------------------------------------------------------------------------
' Convert an unsigned decimal value to a string with leading spaces
' Input     : pValue holds the unsigned value to convert (upto 32-bits)
'           : pDigits holds the amount of digits to convert to ASCII
' Output    : Returns the conversion as a string
' Notes     : None
'
Proc DecToASCII(pValue As Dword, pDigits As Byte), String * 10
    Dim bDigits[10] As Byte
    Dim bIndex      As Byte
    Dim bVal        As Byte   
    Dim wDigAddr    As Word
    Dim wResAddr    As Word
   
    wDigAddr = AddressOf(bDigits)               ' Get the address of the array
    wResAddr = AddressOf(Result)                ' Get the address of the return string
    Clear Result                                ' Clear the return string
    bIndex = 0                                  ' Reset the array index
    Repeat                                      ' Create a loop
        If bIndex >= pDigits Then               ' Have enough digits been converted
            bVal = " "                          ' Yes. So replace the others with a space
        Else                                    ' Otherwise...
            bVal = pValue // 10                 ' Get a digit from the value
            bVal = bVal + 48                    ' Convert the value character to ASCII
        EndIf
        pValue = pValue / 10                    ' Move down the value       
        Ptr8(wDigAddr++) = bVal                 ' Add the character to the array and increment its RAM address
        Inc bIndex                              ' Increment the index
    Until pValue = 0                            ' Until the value is 0
'
' Transfer the array into the returned String
'
    While bIndex > 0
        Ptr8(wResAddr++) = Ptr8(--wDigAddr)
        Dec bIndex
    Wend
EndProc

With the above procedure, the texts below will be displayed on a serial terminal:

1234567
 234567
  34567
  4567


In order to make it so that sometimes all the digits of an integer value are required to be converted, the line below can be replaced:

If bIndex >= pDigits And pDigits <> 0 Then ' Have enough digits been converted, or all the digits not required
Then whenever the pDigits parameter is 0, all the integer's digits will be converted.

That is how flexible procedures can be.

top204

Another method of the conversion is to automatically transmit the ASCII value from a USART:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' A demonstration of a procedure to convert a decimal value to ASCII and transmit it via USART1
'
' Written for the Positron8 compiler by Les Johnson.
'
    Device = 18F25K20                           ' Tell the compiler what device to compile for
    Declare Xtal = 16                           ' Tell the compiler what frequency the device will be operating at (in MHz)
'
' Setup USART1
'
    Declare Hserial1_Baud = 9600                ' Set the Baud rate to 9600
    Declare HRSOut1_Pin   = PORTC.6             ' Set the TX pin
'
' Create any global variables for the demo here
'
    Dim MyDword As Dword
    Dim MyWord As Word
   
'-------------------------------------------------------------------------
' The main program starts here
'
Main:
    MyDword = 1234567
    MyWord = 60123          
    Xmit_ASCII(MyDword, 7)        
    Xmit_ASCII(MyDword, 6)         
    Xmit_ASCII(MyDword, 5)
    Xmit_ASCII(MyWord, 4)
    Xmit_ASCII(MyWord, 3)        
    Xmit_ASCII(MyDword, 0)
  
'-----------------------------------------------------------------------------
' Convert an unsigned decimal value to ASCII and transmit it via USART1
' Input     : pValue holds the unsigned value to convert (upto 32-bits)
'           : pDigits holds the amount of digits to convert to ASCII (0 if all digits to be transmitted)
' Output    : None
' Notes     : Terminates the line by transmitting a CR after the value has been transmitted
'
Proc Xmit_ASCII(pValue As Dword, pDigits As Byte)
    Dim bDigits[10] As Byte
    Dim bIndex      As Byte
    Dim bVal        As Byte   
    Dim wDigAddr    As Word
   
    wDigAddr = AddressOf(bDigits)               ' Get the address of the array
    bIndex = 0                                  ' Reset the array index
    Repeat                                      ' Create a loop
        Select pDigits           
            Case > bIndex, 0                    ' Have enough digits been converted, or all the digits required
                bVal = pValue // 10             ' Yes. So extract a digit from the value
                bVal = bVal + 48                ' Convert the value character to ASCII
            Case Else                           ' Otherwise...
                bVal = " "                      ' Replace the digit with a space
        EndSelect
        pValue = pValue / 10                    ' Move down the value       
        Ptr8(wDigAddr++) = bVal                 ' Add the digit's character to the array and auto increment its RAM address
        Inc bIndex                              ' Increment the index
    Until pValue = 0                            ' Until the value is 0
'
' Transmit the array
'
    While bIndex > 0
        bVal = Ptr8(--wDigAddr)                 ' Decrement the RAM address and read an array element into bVal
        HRSOut bVal                             ' Transmit the digit's character
        Dec bIndex
    Wend
    HRSOut 13                                   ' Terminate the line with a Carriage Return
EndProc

keytapper

I did something like this before in a rudimentary manner, because I wanted to align the output to the right side of an LCD. That's a reason when a Print At, x,y may cause strange visualization.

Probably using DIG can adjust a result, when it comes to check which digit is a zero, but it takes to remember whether the previous digit, to the left, was a zero, as well. But it's not possible for negative numbers.

Sorry that I can't remember where I left it.
Ignorance comes with a cost

top204

For signed values, set a flag if the value is negative, then abs it to make it a positive value, perform the ASCII conversion on the positive value, add a negative character if the negative flag was set, and then perform spacings.