Shop OBEX P1 Docs P2 Docs Learn Events
Solve and display Floating Point Values like 3.222 x 23.378E3 in a FIfth Order Poly — Parallax Forums

Solve and display Floating Point Values like 3.222 x 23.378E3 in a FIfth Order Poly

davekorpidavekorpi Posts: 20
edited 2013-12-29 22:00 in Propeller 1
Hi Propeller Wizards!

Happy New Year yall!

I made a video explaining what I am trying to do...
http://www.screencast.com/t/KHeWitl10
(It is also attached in the zipped file FifthOrder.mp4.zip (8.02 MB) case you do not have the BW to view..)

In short I want to be able to multiply floating point numbers and display them.. I am sure what I want is not the best in programming practices but I want to be able to multiply numbers like 3.123 E 5 * 21.345 which is the same as 312300 * 21.345 as an example...

For example, a Polynomial curve fit such as this....
I want to see how to solve a fifth order polynomial with Spin...I have the Coefficients A, B, C, D, E and F
for a fifth order and want to find y for a given value of x:


y = -3.467E+0 + 150.429E+4x - 136.520E-3x^2 + 247.626E+0x^3 - 71.985E+0x^4 + 7.264E+0x^5.

The code I attached is a good example of using many elements of the Propeller with the serial port, floats, Saving to EE and more.

I hope to see a number of forum Black Belt Wizards do some AWESOME stuff so we all can learn lots of cool stuff!

Here is the code I am using (Also attached in the ZIP file):

DAT programName         byte "_TestFifthOrderFit_DriveDAC 01234567", 0         {Keep versions up here, last 7 CHRS}
'====================================================    
{{ 
Polynomial curve fit..
I want to see how to solve a fifth order polynomial with Spin...I have the Coefficients A, B, C, D, E and F
for a fifth order and want to find y for a given value of x:


y = -3.467E+0 + 150.429E+4x - 136.520E-3x^2 + 247.626E+0x^3 - 71.985E+0x^4 + 7.264E+0x^5


Seems there are LOTS of FP Objects but I must say a
polynomial would be an EXCELLENT one for folks to deal with nasty transfer functions and drive those oh so common non-linear
systems!




}}
'====================================================    
CON                             'Constants. Set up pin assignments
'====================================================    
  '_clkmode = xtal1 + pll16x    'Config for Parallax demo boards using 5 MHz Xtals..            '
  '_xinfreq = 5_000_000


  _clkmode = xtal1 + pll8x      ' For 10 MHZ Xtal div by 8 on xtal1
  _xinfreq = 10_000_000


  ' _clkmode = xtal1            ' For 10 MHZ Xtal div by 8 on xtal1
  ' _clkfreq = 10_000_000       ' From Pg 66/399 of Propeller Manual Not sure why this does not work.


  RED_1 = 17   ' Any LED may be set to any pin. Just replace "led + 1" with the pin number.
   
  VERSION_SIZE = 7              ' Last characters of "ProgramName" string used as
                                ' version ID at line 1 of DAT above.
'serial port pins
  RX_PIN = 31
  TX_PIN = 30
  MODE = 0
  BAUDRATE = 115200
  CS = 16       'CHr 16 to Clear Screen
  QUOTE = 34    'Chr 34 for "


' 12 Bit DAC using 4822 or 4922.. Woth work GREAT!
  DAC_CS  = 2                   ' 12 Bit DAC Chip Sel
  DAC_SCK = 1                   ' 12 Bit DAC SCK
  DAC_SDI = 0                   ' 12 Bit DAC SDI 




  coeff = 0.7                   ' coeff = 0.07  DMK.. Why can not get 0.07 to work?
  dkval = 144
  ZeroVal = 0
  SpanVal = 4096                '4096
  SenserionSpan = 32700


'  iA = -3.467                  ' In the end I want to store these in EE and then read these out of EE
'  iB =  150429.0               ' I want to store big numbers in here.. Know how to do that??
'  iC = -0.13652
'  iD =  247.626
'  iE = -71.985
'  iaF = 7.264
                                ' Constants here cuz I could not figure out how to get LONGS anywhere else...
  iA =  2.0                     ' In the end I want to store these in EE and then read these out of EE
  iB =  2.0                     ' I want to store big numbers in here.. Know how to do that??
  iC =  2.0                     ' All 2's -> 126
  iD =  2.0
  iE =  2.0
  iaF = 2.0


 ' B     = 4000000.0             'Floating-point constants
 ' C     = 4414442.5
 ' D     = 4414442.5
   B     =  7.6654               'Floating-point constants
   C     = 38.7544
   D     = 12.5333


  
   MIN_PERIOD = 5                ' for blinkrate.. should be 100??
   MAX_PERIOD = 2000             ' for blinkrate.. Should be 1000??
   MAX_STRING_SIZE = 40           'set the maximum string length to be sent using terminal


   
'====================================================      
OBJ             ' External routines called by this program Must be in the same directory as this program
'====================================================
       Serial  : "Serial4PortFlag131029a"  'Serial that Smart guys LOVE! Supports <CR> termination
       Tv      : "Mirror_TV_Text"         ' Echo
       F       : "Float32"                ' 32 bit floats
       DAC     : "MCP4922"                ' 2 Chan 12 bit DAC
       FTS     : "FloatString"            ' Float routines
       Eeprom  : "dwd_PropellerEeprom"   
'====================================================    
VAR         'GLOBALS
'====================================================    
  long t100, RawTick, LSmooth, Smooth, FitVal, OutZS    'Global RawTick
  long rxFlag, previousRxFlag  
  long ms         ' delay in ms
  long periodAddress, countAddress 
  long commandPtr         
  long FirstFit, SecondFit, ThirdFit, FourthFit, FifthFit , SixthFit 
  long Scratch, Scratch1, Scratch2, Scratch3, Scratch4, Scratch5 , Scratch6 , ShowMe , SHowMeF
  byte parameterReceivedFlag
  byte keyBdLine[MAX_STRING_SIZE + 1]  'this is the line that holds the final info
  byte rawParameter[MAX_STRING_SIZE + 1]


'====================================================    
PUB Main   | coefficient
'====================================================    
   Initialize
   Serial.Str(0, string(13, "I Love Amara Dec 25, 2013 Line 103 Main")) 
  ' Pause(3000)     'HOW LONG IS THIS???It is 3 seconds in NORMAL time...  
   LSmooth := 2000      ' Init with something..
   RawTick := 3000      ' Init value
  repeat                                             
        
    
      
        'RawTick := 30000 'Stub in value...
        'Serial.Str(0, string(16, QUOTE, "CLS Issued.... ", QUOTE))    ' <<<CLEAR SCREEN>>>>
        if rxFlag <> previousRxFlag     'every time a CR is recd this executes
             previousRxFlag++
             'DisplayFlags("0")
             GetTermCmd
       
       Smooth := F.Fadd(F.Fmul(coeff,(F.Fsub(RawTick,LSmooth))),LSmooth)
       
       LSmooth := Smooth
 
      'FitVal := FifthOrder(Smooth)                     'FitVal := FifthOrder(f.ffloat(11))
       FitVal := FifthOrder(F.FFloat(Smooth))           'FitVal := FifthOrder(f.ffloat(11)) 
    ' FItVal := fahrenheit(100.00978)
    
         OutZS := F.FMul(F.Fsub(Smooth,ZeroVal),F.Fdiv(SpanVal,SenserionSpan))  ' Drive 0-4096
      
         if OutZS > 4096
               OutZS :=4096
         if OutZS < 0
                OutZS := 0


    '  DAC.Set(0, 4095)                         ' Channel A 0-5 VDC  half-range 2048 = 2.5V with 5V reference)
    '  DAC.Set(1, 4095) 
       
      DAC.Set(0, OutZS)                         ' Channel A 0-5 VDC  half-range 2048 = 2.5V with 5V reference)
      DAC.Set(1, OutZS)                         ' Channel B 4-20 mA  half-range 2048 = 2.5V with 5V reference)
      
      DisplayDMK
      DisplayValues
       waitcnt(80_000_000 + cnt)                ' waitcnt(80_000_000 + cnt)        1 second








'====================================================
PUB GetTermCmd  | tCommandChr, characterCount, negativeFlag, commandLong[2], longCount
'====================================================
'' commandLong will hold the first for non-numeric characters of the command.
'' This value will be used in various case statements to find the desired
'' branch of the program to follow.
'' This method converts uppercase characters to lowercase and the
'' method also extracts numeric characters to use as the command's
'' parameter.
'' "result" is a local variable cleared to zero no other locals are cleared
 
  parameterReceivedFlag := 0   'Local flags.. Need to know if parameters received cuz 0 is valid
  negativeFlag := 0            'if neg character cuz number may be 0.. wait till get all even though we do not use -
  characterCount := 0          'We are interested in first 4 characters of commands
  longfill(@commandLong, 0, 2) ' so string has a terminating zero local.. Threy do not get cleared.. So need to clear
  longCount := 0               ' clear local var
  
  repeat
    tCommandChr := Serial.rxcheck(0)   'We strip out the chrs...
    if tCommandChr == -1               'This should never happen.. Only if a bug...
      Serial.Str(0, string(13, "Input error characters expected."))
      Serial.Str(0, string(13, "No carriage return received."))
      return 0
    elseif tCommandChr == 13           'Now we have a CR
      KeyBdLine[characterCount++] := 0  'Storing message in KeyVdLine
      'Serial.Str(0, string(13, "String received = ", QUOTE))
      'Serial.Str(0, @KeyBdLine)
      'Serial.Str(0, string(13, "Command received = ", QUOTE))
      'Serial.Str(0, @commandLong)
      
      'Serial.Tx(0, QUOTE)
     
    elseif tCommandChr => "A" and tCommandChr =< "Z"    'to lowercase while we're looking anyway
      KeyBdLine[characterCount++] := tCommandChr + 32   'adding 32 goes to lowercase.. adding and convert to lc
      if longCount < 4                                  'adding to see if we are at a long yet.
        commandLong.byte[longCount++] := tCommandChr + 32  'this gets them in the right position to display long as string.
    elseif tCommandChr => "0" and tCommandChr =< "9"    'Checking for numbers 0-9 extract and parameters values
      result *= 10                                      'to shift over one digiit
      result += tCommandChr - "0"                       'this converts from ASCII to numeric..
      parameterReceivedFlag := 1                        ' now we have a number so set flag
      KeyBdLine[characterCount++] := tCommandChr        'add this to our KeyBdLine string...
    elseif tCommandChr == "-"                           ' check for neg flag to make a neg number later if we need
      negativeFlag := 1                                 'a negative sign anywhere in string will set flag
      KeyBdLine[characterCount++] := tCommandChr
    elseif tCommandChr > 32 and tCommandChr =< 127      'ignore space and non-printable ASCII   
      KeyBdLine[characterCount++] :=  tCommandChr
      if longCount < 4                                  'only want letters a space will mess it up . 32 cuz 32 is a space
        commandLong.byte[longCount++] := tCommandChr  
    {else
      Serial.Str(0, string(13, "Unexpected character = $"))
      Serial.Hex(0, tCommandChr, 2)
      Serial.Str(0, string(13, "The character has been ignored."))}
    if characterCount > MAX_STRING_SIZE               'make sure we do not blow up stringsize..
      tCommandChr := DumpRxBuffer                     'we show this in the rxbuffer...
      Serial.Tx(0, $0D)
      Serial.Dec(0, tCommandChr)
      Serial.Str(0, string(" additional characters received."))
      Serial.Str(0, string(13, "Terminal command not executed."))
      return 0
  while tCommandChr <> 13                              'while tCommandChr not CR cuz we do not need this...
                                                      
  if negativeFlag    'got in line 487 
    -result          'this NEGATES the result with -result..
  'Serial.Str(0, string(13, "Parameter received = "))
  'Serial.Dec(0, result)  
  ExecuteCmd(commandLong, result)   


'====================================================
PUB DumpRxBuffer | tCommandChr
'====================================================
'' Used to help track down bugs.
'' This method will only be used if a
'' string longer than "MAX_STRING_SIZE" is entered.


  Serial.Str(0, string(13, "DumpRxBuffer method"))
  Serial.Str(0, string(13, "rxFlag = "))
  Serial.Dec(0, rxFlag)
  Serial.Str(0, string(13, "previousRxFlag = "))
  Serial.Dec(0, previousRxFlag)
  repeat
    tCommandChr := Serial.rxcheck(0)
    if tCommandChr == -1
      Serial.Str(0, string(13, "Rx buffer is now empty."))
      quit ' quit loop
    elseif tCommandChr == 13
      Serial.Str(0, string(13, "Carriage return found at last."))
      result++
      quit
    else
      Serial.Tx(0, tCommandChr)
      result++ 
'====================================================
PUB ExecuteCmd(localCommand, parameter) | index, compare     'LocalC0mmand are letters Param is the number - or not                   
'====================================================
' Below is the current list of commands.
' redOn, greenOn, redAll, greenAll, bothOn, bothAll, altAll, allAlt, off, allOff, offAll
' rblink, gblink, rgblink, altblink, cmdL, setperiod


  commandPtr := FindCommandPtr(localCommand)    'This goes through and finds the string associated with command in DAT below.
  if commandPtr == @cmdNotFound
    Serial.Str(0, @cmdNotFound)
    Cmd
    return
  Serial.Str(0, string(13, "Command ", QUOTE))     'QUOTE = constant 34 for "
  Serial.Str(0, commandPtr)
  Serial.Str(0, string(QUOTE, " received."))
                
  case localCommand
    ledon,ledoff, { 
      } cmdL, help, dispdmk, version: 'A line break may be hidden in a comment.
    ' commands for all those don't require a parameter
      'Serial.Str(0, string(13, "Parameter not needed for this command."))
      parameterReceivedFlag := 0
      ' make sure it's not evaluated with parameter equals zero batch
      ' All the which don't apply to individual commands
      
    other:
      if parameterReceivedFlag
        'Serial.Str(0, string(13, "Parameter included with command = "))
        'Serial.Dec(0, parameter)
      else
        parameter := GetParameter(localCommand)
        ifnot parameterReceivedFlag
          DisplayParameterError(localCommand)
          Cmd
          return
      Serial.Str(0, string(13, "Parameter received = "))
      Serial.Dec(0, parameter)   'turn all on with 0...  
  if parameter == 0 and parameterReceivedFlag  'parameterReceivedFlag is global
    case localCommand     'CMDS with params Local Command no parameter. if typed ron may need to add it.
     
      setperiod:            'We set the period for the heartbeat LED
        Serial.Str(0, string(13, "Zero is not a valid heartbeat period."))
        Serial.Str(0, string(13, "Setting period to MINIMUM value..."))
        Serial.Str(0, string(13, "MIN_PERIOD = "))
        Serial.Dec(0, MIN_PERIOD)
       ' Led.SetPeriod(MIN_PERIOD)
       ' Eeprom.FromRam(@decLedMs, @decLedMs + 3, @decLedMs)
        Serial.Str(0, string(13, "Blink period has been backed up to EEPROM."))
      other:
        Serial.Str(0, string(13, "Command with parameter of zero not found."))
        Cmd
  else       
    case localCommand            'These are have no param or param that has been set to 0 Most will be here
    
      cmdL, help:
        Cmd
      dispdmk:  ' must be lc by golly!!
       DisplayDMK  
      version:
        DisplayVersion
      setrawtick:
         SetRawTickVal(parameter)
         RawTick := parameter 
      setperiod:
         SetPeriods(parameter)
        'Eeprom.FromRam(@decLedMs, @decLedMs + 3, @decLedMs)
        Serial.Str(0, string(13, "Blink period has been backup to EEPROM."))
      other:
        Serial.Str(0, @cmdNotFound)
        Cmd


'====================================================
PUB SetRawTickVal(count)
'====================================================


''How do I stub in a RawTick value??


  long[countAddress] := count 




'====================================================
PUB SetPeriods(timeInMs)
'====================================================


'' Set the half period of the LED flashing.
'' Use timeInMs for both on time and off time.


  long[periodAddress] := timeInMs 


'====================================================
PUB Cmd : localPtr
'====================================================


  Serial.Str(0, string(13, 13, "This is the Cmd method."))
  Serial.Str(0, string(13, "List of possible commands:", 13))
  localPtr := @ledon
  repeat
    if byte[localPtr]
      Serial.Tx(0, byte[localPtr++])
    else
      Serial.Tx(0, ",")
      Serial.Tx(0, " ")
      repeat while byte[localPtr] == 0
        localPtr++
  while localPtr < @setperiod + strsize(@setperiod)
    
  Serial.Tx(0, $0D)


'====================================================        
PUB Initialize                            'I start ALL the cogs in here
'====================================================    


  Serial.Init(@rxFlag)
  Serial.AddPort(0, RX_PIN, TX_PIN, -1, -1, -1, MODE, BAUDRATE)
  Serial.Start
   
 ' waitcnt(clkfreq + cnt )                    'Wait 1 sec.
   
  Serial.Str(0, String(13, "serial port started"))
  Serial.Str(0, String(13, "programName = "))
  Serial.Str(0, @programName)
  Serial.Tx(0, $0D )
  ' Show the version of the program that is currently
  ' loaded into the Propeller


 F.Start                                   'Start FP Cog
  'Pause(100)
 ' Tv.start(TvBasepin)                     'Start TV Cog
 ' Tv.out( $00  )                          'Clear Screen 




  'Init DAC
  DAC.Init(DAC_CS, DAC_SCK, DAC_SDI)        'CS, SCK, SDI respectively 
  DAC.Set(0, 1)                             'Set Channel A to 0 half-range 2048 (2.5V with 5V reference)
  DAC.Set(1, 1)                             'Stub in values for test
'====================================================
PUB DisplayVersion
'====================================================
'' Use the last 7 characters of the program name
'' as the version ID from the DAT on line 1 above..
'' Is there a way to use actual spin name??


  result := strsize(@ProgramName)
  Serial.Str(0, string(13,13, "Program Version = "))
  Serial.Str(0, @ProgramName + result - VERSION_SIZE)




'====================================================
PUB DisplayDMK        'use dispdmk to invoke...
'====================================================
       Serial.Str(0, string(16, QUOTE, "CLS Issued.... ", QUOTE, "Hi Amara!"))    ' <<<CLEAR SCREEN>>>>
       Serial.Str(0, string(13,  "RawTick ", QUOTE))     'QUOTE = constant 34 for " QUOTE character..
       Serial.Decl(0, RawTick,8,1)
     ' RawTick := ReadRawPressureHold
    
       Serial.Str(0, String(13, "Line 132 Versuion below..", 13))   
     '  DisplayVersion
       Serial.Str(0, String(13,QUOTE, "Serial.Decl(0,clkfreq,8,1 =", QUOTE)) 
       Serial.Decl(0,clkfreq,8,1)


       Serial.Str(0, String(13, " coeff = 0.07 -> 1 sec ")) 
       Serial.Decl(0, Coeff,8,8)
        'Pause(1_000)     'HOW LONG IS THIS???It is 3 seconds in NORMAL time...
        'waitcnt(80_000_000 + cnt)
       Serial.Str(0, string(QUOTE, " ...1 Sec..", 13))
        
       ' Pause(1_000)     'HOW LONG IS THIS???It is 3 seconds in NORMAL time...
       ' waitcnt(80_000_000 + cnt)
       Serial.Str(0, string(13, "Smooth ", QUOTE))     'QUOTE = constant 34 for "
       Serial.Decl(0, Smooth,8,1)
       


       Serial.Str(0, string(13, "LSmooth ", QUOTE))     'QUOTE = constant 34 for "
       Serial.Decl(0, LSmooth,8,1)
       


       Serial.Str(0, string(13, "SpanVal ", QUOTE))     'QUOTE = constant 34 for "
       Serial.Decl(0, SpanVal,8,1)
           ms := 1000
          FitVal := clkfreq/1000*ms          'FitVal "10_000_000


       Serial.Str(0, string(13, "FitVal ", QUOTE))     'QUOTE = constant 34 for "
       Serial.Decl(0, FitVal,8,1)
       
     
       Serial.Str(0, string(13, "Out ZS Before ", QUOTE))     'QUOTE = constant 34 for "
       Serial.Decl(0, OutZS,8,1)
            
        Scratch :=   F.Pow(2,2)                          'How can I print out a number line 2.32984 or 0.00002938
       Serial.Str(0, string(13, " Scratch ", QUOTE))     'QUOTE = constant 34 for "
       Serial.Decl(0, Scratch,8,1)


        
return      
'====================================================      
PUB  FifthOrder(InVal)
'====================================================


      ShowMe := InVal                                  ' TEST.. Replace InVal with the iB..iaF
      ShowMeF := F.FFloat(InVal)


      FirstFit := (iA)                                 ' the A constant adder


      SecondFit := F.Fmul(iB,InVal)                    ' Should be B * X     iB =  150429.0  >>OK!!


      Scratch :=   F.Pow(InVal,2.0)
      'ThirdFit := F.FMul( iC, Scratch)                 ' Should be C * X^2   iC := -0.13652    0.0186377104 -> -0.00254442    >>OK
     ' ThirdFit :=Tv.Str(FTS.FloatToString(F.FMul( iC, Scratch)))  
      Scratch :=   F.Pow(InVal,3.0) 
      FourthFit := F.FMul( iD, Scratch)                ' Should be D * X^3   iD :=  247.626    15,184,088.5274


      
      Scratch :=   F.Pow(InVal,4.0)                   
      FifthFit := F.FMul( iE, Scratch)                  ' Should be E * X^4   iE = -71.985     26,851,468.117


      Scratch :=   F.Pow(InVal,5.0)                     
      SixthFit := F.FMul( iaF, Scratch)                 ' Should be F * X^5   iaF := 7.264     22,224.5644
      
       Scratch1 := F.Fadd(FirstFit,SecondFit)            ' Smarter way?
        Scratch2 := F.Fadd(Scratch1,ThirdFit)            ' Should I use result like this?
         Scratch3 := F.Fadd(Scratch2,FourthFit)          ' Am I doing the right thing in indentation?
          Scratch4 := F.Fadd(Scratch3,FifthFit)
           Scratch5 := F.Fadd(Scratch4,SixthFit)
            result := Scratch5                           ' Need RESULT!
 return                                                 ' Do I need Return?   
'====================================================    
PUB DisplayValues
'====================================================
    Serial.Str(0,string(13, "Display Values for Fifth Order Fit..)"))  
     Serial.decl(0,RawTick,8,1)


     Serial.Str(0,string(13, "Serial.decl(0,RawTick,8,1)"))   
 
     
     Serial.decL(0,Smooth,8,1)
     Serial.Str(0, string(13, "Serial.decL(0,Smooth,8,1)"))


     
     Serial.decl(0,FitVal,8,1)
     Serial.Str(0, string(13, "Serial.decl(0,FitVal,8,1"))   'display Raw Value 
     
     Serial.decl(0,OutZS,8,1)


     Serial.Str(0,string(13, "Serial.decl(0,OutZS,8,1) "))
     
     Serial.decl(0,ThirdFit,8,1)


     Serial.Str(0,string(13, "Serial.decl(0,ThirdFit,8,1)  "))
     
     Serial.decl(0,ShowMe,8,1)




     Serial.Str(0,string(13, "Serial.decl(0,ShowMe,8,1) "))
     
  
     return


'====================================================    
PUB fahrenheit(t)    'Showing math works
'====================================================    
  ' fahrenheit = (celsius * 1.8) + 32
  return f.FAdd(f.FMul(t, 1.8), 32.0)


'====================================================      
PUB Pause(xms)                        ' waitcnt(80_000_000 + cnt) = 1 sec          FitVal "80_000_000
'====================================================    
  waitcnt(clkfreq/1000*ms+cnt)         'waitcnt(clkfreq/8000*ms+cnt)  80,000,000/1000   *1000


'====================================================  
PUB GetParameter(parameterType) | characterCount, negativeFlag, tCommandChr
'====================================================  


  parameterReceivedFlag := 0
  negativeFlag := 0
  
  Serial.Str(0, string(13, "Please enter parameter for this command."))
  case parameterType
    ledon, ledoff:
      Serial.Str(0, string(13, "Please enter parameter for individual puck control."))
      Serial.Str(0, string(13, "Enter ID of puck to control."))
      Serial.Str(0, string(13, "(", QUOTE, "1", QUOTE, " - ", QUOTE, "6", QUOTE, ")"))
      Serial.Str(0, string(13, "Or enter ", QUOTE, "0", QUOTE))
      Serial.Str(0, string(" to apply command to all pucks.", 13))
      result := ReceiveNumber
      result := 0 #> result <# 4  ' Led#PUCKS_IN_USE
    
    setperiod:
      Serial.Str(0, string(13, "Please enter Heartbeat blink time in milliseconds."))
      Serial.Str(0, string(13, "Please enter a number between ", QUOTE))
      Serial.Dec(0, MIN_PERIOD)
      Serial.Str(0, string( QUOTE, " and ", QUOTE))
      Serial.Dec(0, MAX_PERIOD)
      Serial.Str(0, string(QUOTE, ".", 13))
      result := ReceiveNumber
      result := MIN_PERIOD #> result <# MAX_PERIOD  


'====================================================
PUB DisplayParameterError(localCommand)
'====================================================
''if they type something illegal...
  Serial.Str(0, string(13, "You entered ", QUOTE))
  Serial.Str(0, @rawParameter)
  Serial.Str(0, string(QUOTE, " which is not a valid parameter"))
  Serial.Str(0, string(13, "for the command ", QUOTE))
  Serial.Str(0, commandPtr)  
  Serial.Tx(0, QUOTE)
  Serial.Str(0, string(13, "Terminating Command"))
  Serial.Str(0, string(13, "Please enter new command."))
  
'====================================================
PUB FindCommandPtr(localCommand) : localPtr
'====================================================
'' Finds the command string associated with the
'' first four bytes having a value equal to
'' that of "localCommand".  ie ron


  localPtr := @ledon      'Start looking.. ledon first command.. Check lonng or bytes.. if the same


  repeat
    if byte[localPtr]
      if long[localPtr] == localCommand
        quit
      else
        repeat while byte[localPtr]
          localPtr++    
    else
      repeat while byte[localPtr] == 0
        localPtr++
  while localPtr =< @setperiod  ' the last in the DAT array..


  if localPtr > @setperiod
    localPtr := @cmdNotFound
  
'====================================================
'====================================================  
PUB ReceiveNumber | localCharacter, characterCount, negativeFlag, rawCount
'====================================================  


  characterCount := 0
  negativeFlag := 0
  rawCount := 0
  
  repeat while rxFlag == previousRxFlag
  previousRxFlag++
  
  repeat  
    localCharacter := Serial.rxcheck(0)
    if localCharacter == -1
      Serial.Str(0, string(13, "Input error characters expected."))
      Serial.Str(0, string(13, "No carriage return received."))
      DisplayFlags("3") ' Used to aid in debugging. If this portion of the code
                        ' is used, something is wrong.
      return 0
    elseif localCharacter == 13
      KeyBdLine[characterCount++] := 0
      'Serial.Str(0, string(13, "String received = ", QUOTE))
      'Serial.Str(0, @KeyBdLine)
      'Serial.Tx(0, QUOTE)
      quit
    elseif localCharacter == "-"
      negativeFlag := 1 ' a negative sign anywhere in string will set flag
      KeyBdLine[characterCount++] := localCharacter
    elseif localCharacter => "0" and localCharacter =< "9" ' extract and parameters values
      result *= 10
      result += localCharacter - "0"
      parameterReceivedFlag := 1
      KeyBdLine[characterCount++] := localCharacter
    rawParameter[rawCount++] := localCharacter 
  while localCharacter <> 13


  if negativeFlag
    -result


  rawParameter[rawCount] := 0
  
  'Serial.Str(0, string(13, "Parameter received = "))
  'Serial.Dec(0, result)


'====================================================
PRI DisplayFlags(locationId)
'====================================================
'' Used for debugging...
'' I should have a debug boolean to turnt hese on and off...


  Serial.Tx(0, $0D)
  Serial.Tx(0, QUOTE)
  Serial.Tx(0, locationId)
  Serial.Str(0, string(QUOTE, " rxFlag = "))
  Serial.Dec(0, rxFlag)
  Serial.Str(0, string(13, "previousRxFlag = "))
  Serial.Dec(0, previousRxFlag) 


'====================================================    
DAT  
'====================================================
'' The first four characters of each string needs to be unique.
'' Strings should be at least three characters long. If
'' a string is less than three characters add additional
'' zeros so each string has at least four bytes when
'' terminating zero are included in the count.


ledon         long              'Because we need to use a CASE we need to create a long aligned string
              byte "lon", 0     'Character strings in byte arrays.. use 1 char after another. Use 2 different types with same variable
ledoff       long
              byte "ledoff", 0     'the 0 is a terminating tring for the string.      
cmdL          long
              byte "cmd", 0
help          long
              byte "help", 0
version       long
              byte "version", 0
setrawtick    long
              byte "setrawtick" , 0              
dispdmk       long
              byte "dispdmk" , 0                                        
setperiod     long
              byte "setperiod", 0
'' If commands are added before "redOn" or after "setperiod" the method "Cmd"
'' and the method "FindCommandPtr" will need to be modified.
'' Commands entered between "redOn" and "setperiod" will be included in the
'' list generated by "Cmd".             
              
' ledon, ledoff, cmdL, help, version, dispdmk, setperiod


cmdNotFound   byte "Command Not Found", 0


 


I would LOVE to see how to output floating point numbers for display. I am so spoiled with LabVIEW that all this is automatic and I am also driving a DAC to drive a 0-5 Output for a linear representation of the input variable, X, that drives the Polynomial scaled to 0-4096 that is scaled to drive a 12 bit DAC.

I have absolutely no pride of authorship on any of my code and TOTALLY welcome anyone to make it all it can be so everyone can benefit.

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-29 20:33
    Hi Dave,

    I watched your video. What stuck out to me is you mixed integers with floats. The example of two squared had "2" instead of "2.0". You either need a decimal point included with the constant (2.0) or use the float command (float(2)).

    It really important not to mix integers and floating point numbers (if you want correct results).

    Once I saw this common error I didn't keep looking.

    There's a better floating point object called "F32". It looks like the OBEX does have the latest version.

    Holler back if using "2.0" instead of "2" doesn't fix things.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-29 20:44
    Some of those numbers look like they're right at the edge of what can be done with 32-bit floating point math. I think 32-bit floats only have about 6 significant digits since some of the 32-bits are used for the exponent.

    I don't know if you're aware of a math coprocessor that does 64-math or not.

    I haven't used the 64-bit version but the 32-bit coprocessor wasn't too hard to use. I know there's an object to make it easier to interface with the 64-bit version. If you're interested in it, I could help you find the object (if you have trouble finding it yourself).
  • davekorpidavekorpi Posts: 20
    edited 2013-12-29 21:52
    Duane:

    I did try the 2.0 by golly... I think I hamburgured more up than just that.
  • davekorpidavekorpi Posts: 20
    edited 2013-12-29 21:53
    Duane:
    I will work within whatever the 32 bit can do without the coprocessor. I remember having to use those for the old IBM PC when I had to do nasty hard math!
  • davekorpidavekorpi Posts: 20
    edited 2013-12-29 22:00
    Playing with the F32! AWESOME!

    I think I will be able to figure it out and will post how to do it...

    Not sure on the polynomial but working on it!
Sign In or Register to comment.