Shop OBEX P1 Docs P2 Docs Learn Events
There has got to be a better way!! — Parallax Forums

There has got to be a better way!!

SarielSariel Posts: 182
edited 2012-03-13 10:01 in Propeller 1
Hi folks!

I have a device that has a set of 8 cascaded 74HC165's that are all set up to be active low. The idea is that I want to be able to probe any one of the inputs with a grounded probe tip and have that pin show up on the TV screen. I have some working code, but I have always hated it, and I am looking for a better way of doing this. Here is what I have:
PUB GetProbe
''Probe check section 
  repeat 
    ifnot ina[PRB_Sw]                                                           ' Exit if PRB_Sw := 0
      Green                                                                     ' "Ready" LED on
      disp.clean                                                                ' Clean up the display  
      Main                                                                      ' Return to main testing loop
      
    ShowTime(1)                                                                 ' Refresh time from RTC                                                          
    InData[0] := !SerIO.ShiftIn1                                                ' Poll input register set #1   
    InData[1] := !SerIO.ShiftIn2                                                ' Poll input register set #2        
                                                                    
    if InData[0] == %1000_0000_0000_0000_0000_0000_0000_0000                    ' Scan for first Input active
      TPData := 1                                                               ' Assign the variable    
      disp.Point(TPData)                                                        ' Display it on the TV
    if InData[0] == %0100_0000_0000_0000_0000_0000_0000_0000
      TPData := 2  
      disp.Point(TPData)   
    if InData[0] == %0010_0000_0000_0000_0000_0000_0000_0000
      TPData := 3   
      disp.Point(TPData)   
    if InData[0] == %0001_0000_0000_0000_0000_0000_0000_0000
      TPData := 4    
      disp.Point(TPData)

and so on, until you reach the end at:
    if InData[1] == %0000_0000_0000_0000_0000_0000_0000_0001
      TPData := 64 
      disp.Point(TPData)

Here is the snippet from my other object that does the displaying. What is going on there is it is taking the reference number from the top file and looking in a DAT block to display a label, not just the pin number:
PUB Point(TestPoint)
  text.str(string($0A, 23,{     ' Probe Flag B
                 }$0B, 06,{
                 }$0C, 03, {
                 }"       "))  
  text.str(string($0A, 23,{     ' Disp. Point Number
                 }$0B, 06,{
                 }$0C, 05))
                                                                     
  text.str(@labels + (MAX_CHARS+1)*(TestPoint-1))


What I am trying is a lot more compact, and in my head, it should work... but it won't. It just cycles the pins on the screen endlessly, even if there is nothing grounded out.
repeat
    
    ifnot ina[PRB_Sw]                                                           ' Exit if PRB_Sw := 0
      Green                                                                     ' "Ready" LED on
      disp.clean                                                                ' Clean up the display  
      Main                                                                      ' Return to main testing loop
      
    ShowTime(1)                                                                 ' Refresh time from RTC                                                          
    InData[0] := !SerIO.ShiftIn1                                                ' Poll input register set #1   
    InData[1] := !SerIO.ShiftIn2                                                ' Poll input register set #2 
    repeat x from 1 to 32
      if InData[0] > %1000_0000_0000_0000_0000_0000_0000_000
        disp.Point(x)
        InData[0] <<= 1
    repeat x from 33 to 64
      if InData[1] > %1000_0000_0000_0000_0000_0000_0000_000
        disp.Point(x)
        InData[1] <<= 1

Does anyone have any suggestions on how I can clean and speed this up? I have been thinking on it for a while, and cannot figure out why the 2nd gen code is not working.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-03-08 16:32
    SPIN comparisons are signed. i.e. $8000_0000 (-ve) would never be greater than $4000_0000 (%1000_0000_0000_0000_0000_0000_0000_000). Try this:
    repeat x from 1 to 32
        if (InData[0] <-= 1) & 1
          disp.Point(x)
      repeat x from 33 to 64
        if (InData[1] <-= 1) & 1
          disp.Point(x)
    
    The expression (InData[?] <-= 1) & 1 rotates the top bit into position 0 and checks there. There are other ways to achieve this, e.g. checking for < 0 then shift/rotate etc. HTH
  • kwinnkwinn Posts: 8,697
    edited 2012-03-08 19:27
    Why not use a single loop to shift in all 64 bits, check each bit as it comes in, and use the loop count to look up the data in your table and display it? If SerIO.ShiftIn1 and SerIO.ShiftIn2 is a PASM object it should not be too hard to modify it so it stops when it encounters a 0 and returns the loop count instead of the actual bits.
  • SarielSariel Posts: 182
    edited 2012-03-09 05:02
    @ kuroneko
    SPIN comparisons are signed.

    Hrmm... good point. that is most likely the bug right there. I had to clear off my work bench and switch gears to a different project, but hopefully I will be able to check this out soon. I will get back to you as soon as I know for sure.

    @kwinn
    If SerIO.ShiftIn1 and SerIO.ShiftIn2 is a PASM object

    They are not PASM. just good 'ole spin.... and I would like to keep them intact as much as possible becuase they are used pretty heavily elsewhere in the program, and I would hate to have to re-write a large chunk of this just to clean up my crappy code writing in one spot.
  • kwinnkwinn Posts: 8,697
    edited 2012-03-09 17:03
    It would only be a few lines of spin code to shift in up to 64 bits, a single comparison to see if each bit is 0, and 1 or 2 lines of code to return the loop counter. You could have a separate subroutine for that and leave the other code alone. That would allow you to simplify the look up and display of messages and more than likely result in less code overall and faster execution.
  • SarielSariel Posts: 182
    edited 2012-03-13 10:01
    @ kuroneko

    Works like a charm. Thank you very much for this quick drop in snippet.

    @ kwinn
    Also an excellent idea. I can use something like that to display multiple connections at the same time, if I get crafty with the code. Maybe I'll work on integrating that feature later on... and I will retain that idea for other projects down the road.

    But for now, on to the next assignment.
Sign In or Register to comment.