Menu

Bin2Ascii, not counting correctly over 999

Help
2010-01-07
2013-05-30
  • Nobody/Anonymous

    here is my code, working, except that it doesnt seem to display numbers correctly when the values roll over from 999 to 1000 and 9999 to 10000, here is what it shows when it rolls over:-

    ok until now…
    996
    997
    998
    999
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    1010
    1011
    ok after this…

    and then

    ok before this….
    9997
    9998
    9999
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    1010
    1011
    1012
    1013
    1014
    1015
    1016
    1017
    1018
    1019
    1020
    1021
    1022
    1023
    1024
    1025
    1026
    1027
    1028
    1029
    1030
    1031
    1032
    1033
    1034
    1035
    1036
    1037
    1038
    1039
    1040
    1041
    1042
    1043
    1044
    1045
    1046
    1047
    1048
    1049
    1050
    1051
    1052
    1053
    1054
    1055
    1056
    1057
    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    1095
    1096
    1097
    1098
    1099
    10100
    10101
    10102
    then ok again…

    'Chip model
    #chip 16f688,8
    #config Osc = Int

    Ser_Init

    Dim stamp as word
    stamp = 0

    Do

    Bin2ascii(stamp)
    XMIT_RS232 (13)
    XMIT_RS232 (10)

    stamp = stamp +1

    wait 4 ms
    Loop

    Sub Ser_Init
    #define baud 12
    #define halfbaud 6 ;place Read of SerRx in middle of bit

    #define SerTxHigh Set PortC.4 On
    #define SerTxLow Set PortC.4 Off
    #define SerRx PortC.5
    dir PortC.5 in ;Rx
    dir PortC.4 out ;Tx
    SerTxHigh ;Initial RS232 idle state
    end sub

    sub XMIT_PRINT (PrintData$)
    PrintLen = PrintData(0)
    if PrintLen = 0 then exit sub
    'Write Data
    for SysPrintTemp = 1 to PrintLen
    XMIT_RS232(PrintData(SysPrintTemp))
    next
    end sub

    Sub XMIT_RS232(Xmit_Byte)#NR
    SerTxLow
    wait baud us
    For cntr = 1 to 8
    Rotate Xmit_Byte Right
    If Status.C ON Then SerTxHigh
    If Status.C Off Then SerTxLow
    wait baud us
    Next
    SerTxHigh
    wait baud us
    end sub

    sub Bin2ascii(LCDValue as word )#NR
    dim LCDValueTemp as word
    SERDECMIL = 0
    SERMIL = 0
    SERCEN = 0
    SERDEC = 0
    SERUN = 0
    LCDValueTemp = 0

    IF LCDValue >= 10000 then
    LCDValueTemp = LCDValue / 10000
    SERDECMIL = LCDValueTemp + 48
    Xmit_RS232(SERDECMIL) 'SerSend (1,SERDECMIL)
    LCDValue = LCDValue - LCDValueTemp * 10000
    End if

    If LCDValueTemp > 0 Or LCDValue >= 1000 Then
    LCDValueTemp = LCDValue / 1000
    SERMIL = LCDValueTemp + 48
    Xmit_RS232(SERMIL) 'SerSend (1,SERMIL)
    LCDValue = LCDValue - LCDValueTemp * 1000
    End if

    IF LCDValueTemp > 0 OR LCDValue >= 100 then
    LCDValueTemp = LCDValue / 100
    SERCEN = LCDValueTemp + 48
    Xmit_RS232(SerCen) 'SerSend (1,SERCEN)
    LCDValue = LCDValue - LCDValueTemp * 100
    end if

    IF LCDValueTemp > 0 OR LCDValue >= 10 then
    LCDValueTemp = LCDValue / 10
    SERDEC = LCDValueTemp + 48
    Xmit_RS232(Serdec) 'SerSend (1,SERDEC)
    LCDValue = LCDValue - LCDValueTemp * 10
    end if

    SERUN = LCDValue + 48
    Xmit_RS232(Serun) 'SerSend (1,SERUN)
    end sub

     
  • kent_twt4

    kent_twt4 - 2010-01-07

    Bit errors due to slow clock and overhead of routines, is my guess.  To get a fast baudrate with the internal oscillator is pretty much a guessing game.  Some buadrates work while others will not.  I think I claimed that a 115200 baud rate was possible.  The conditions were a 16f648a with a 20Mhz crystal, buad = 7,halfbuad = 4, and the data was just a loop back test from a terminal key press.  So a fast clock and no word size maths, in addition to juggling baud wait states for overhead.  Even then,  other high baud rate(s) trys did not work out.

    You could try other buad rates, also see if using a string of nop instructions would work, in place of the wait buad/half buad us?  The 16f688 has a hardware usart, it should be used with the hardware usart routines, along with a faster crystal osc for reliable usart buad rates.  

     
  • kent_twt4

    kent_twt4 - 2010-01-07

    OOPs………Scratch the previous post…………!!!!

    I see what you mean.  Will have to dig deeper to see what is happening.

     
  • kent_twt4

    kent_twt4 - 2010-01-07

    The quick and kind of ugly work around is to change the conditionals in bin2ascii sub.  Works on rollovers of 999 to 1000 and 9999 to 10000.  Only problem is you've got leading zero's now.

    Looks like some sort of word size conditional problem, but not sure at the moment.

    If LCDValueTemp  >= 0 Or LCDValue >= 1000 Then
    ….

    IF LCDValueTemp >= 0 OR LCDValue >= 100 Then


    IF LCDValueTemp >= 0 OR LCDValue >= 10 Then

    Kent
      

     
  • kent_twt4

    kent_twt4 - 2010-01-08

    OK then,

    The answer was from Hugh in plain sight.  The maths have changed a bit as explained in this thread here.  So using that info, a new bin2asciiNew sub has been created.  No leading zero's and promises to be much more efficient.  The shadow registers, SERDECMIL, SERMIL, etc. seemed to work better at high bit rates.

    Tested with the latest update of 11/29/09 at 115,200kbs,  baud is 7 us, halfbaud is 4 us, on a 18f1330 PIC with a 20Mhz crystal,.  It will easily overrun the terminal display output without some  number of ms's of delay in the code.

    sub bin2asciiNew (LCDValue as word ) #NR
        Dim SysCalcTempX As Word
        LCDValueTemp = 0
        LCDShowChar = 0
        SERDECMIL = 0
        SERMIL = 0
        SERCEN = 0 
        SERDEC = 0 
        SERUN = 0
    
        If LCDValue >= 10000 then 
            LCDValueTemp = LCDValue / 10000 [word]
            LCDValue = SysCalcTempX
            SERDECMIL = LCDValueTemp + 48
            Xmit_RS232 (SERDECMIL)
            LCDShowChar = TRUE
        End If
        If LCDShowChar > 0 or LCDValue >= 1000 then 
            LCDValueTemp = LCDValue / 1000 [word]
            LCDValue = SysCalcTempX
            SERMIL = LCDValueTemp + 48
            Xmit_RS232 (SERMIL)
            LCDShowChar = TRUE
        End If
        If LCDShowChar > 0 or LCDValue >= 100 then 
            LCDValueTemp = LCDValue / 100 [word]
            LCDValue = SysCalcTempX
            SERCEN = LCDValueTemp + 48 
            Xmit_RS232 (SERCEN) 
            LCDShowChar = TRUE
        End If
        If LCDShowChar > 0 or LCDValue >= 10 then
            LCDValueTemp = LCDValue / 10 [word]
            LCDValue = SysCalcTempX
            SERDEC = LCDValueTemp + 48  
            Xmit_RS232 (SERDEC)
        End If
        SERUN = LCDValue + 48
        Xmit_RS232 (SERUN)
    End Sub
    
     
  • Nobody/Anonymous

    perfect, thanks, i wont even post my nasty code work around i have been using!

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.