May 17, 2024, 05:40:18 AM

News:

You can now use Vixen to program your Prop-1 and Prop-2 controllers!  Get started quickly and easily, without having to learn PBASIC.  Details in the Library forum.


Need Help Translating QTI/HB25 From Pbasic to SX/B

Started by randyaz, August 25, 2008, 11:46:05 PM

Previous topic - Next topic

randyaz

Hi Jon,

I struggled all weekend with trying to re-write this Pbasic program in SX/B.  I'm stumped... Would you please do the conversion?   


' -----[ I/O Definitions ]-------------------------------------------------

' qti r Output Connects To P0. w to Vdd

HB25      PIN        15
trigger    PIN        14

' -----[ Constants ]-------------------------------------------------------

T2400           CON     396
T9600           CON     84
T38K4           CON     6

Inverted        CON     $4000
Open            CON     $8000
Baud            CON     Open | T38K4            ' fast baud for accessories

IsOn            CON     1                             ' for active-high I/O
IsOff           CON     0



' -----[ Variables ]-------------------------------------------------------

oldBits           VAR     Nib                          ' Previous State Of I/O Pin 0
newBits         VAR     Nib                          ' Current State Of I/O Pin 0
counter         VAR     Byte                        ' Counter (0-255)...change to word if need more counts
index            VAR     Word                       ' for ramping motor, if used

' -----[ Initialization ]--------------------------------------------------

OUTS = %1000000000000000                  ' Set All Output Pins Low but 15
DIRS = %1111111111111110                   ' I/O Pin 0 is Input

newBits = INA

' -----[ Program Code ]----------------------------------------------------


main:
'DO WHILE trigger= IsOff: LOOP              ' un-comment if using a trigger


DO : LOOP UNTIL HB25 = 1                   ' Wait For HB-25 Power Up
LOW HB25                                           ' Make I/O Pin Output/Low
PAUSE 5                                              ' Wait For HB-25 To Initialize
PULSOUT HB25, 750
PAUSE 5000

Program:

counter = 0

PULSOUT HB25, 800                              'start motor

encoder:
DO WHILE counter < 62

     newBits = INA                                ' Get State Of I/O Pin 0
     IF newBits <> oldBits THEN              ' Have Bits Changed?
     counter = (counter + 1)                   'Start counter

      SELECT counter
        CASE = 10                                 'ccw
        PULSOUT HB25, 710

        CASE = 20
        PULSOUT HB25, 780                    'cw

        CASE = 40
        PULSOUT HB25, 600                    'ccw

        CASE = 61
        PULSOUT HB25, 750                    'stop
      ENDSELECT

  DEBUG HOME, ? counter                    ' Show New Counter On Screen

oldBits = newBits                                ' Update oldBits

   ENDIF

LOOP

RETURN


JonnyMac

August 26, 2008, 08:48:21 AM #1 Last Edit: August 26, 2008, 09:00:47 AM by JonnyMac
Okay, Randy, here's how I would do it.  And, BTW, you didn't give me a name for your program -- I need that so I can save it and compile it (right now, its name is your name).

Keep in mind that SX/B is similar to PBASIC but doesn't always translate directly.  You might want to go back over my Nuts & Volts articles with SX/B projects; you've got enough PBASIC experience that if you see a few SX/B programs developed it will start to make sense.  Yes, it's a bit of a learning curve, but the advantage is that the SX gives monster horsepower that will never come out of a BS2.


' =========================================================================
'
'   File...... Randy_AZ.SXB
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2008 EFX-TEK
'              Some Rights Reserved
'              -- see http://creativecommons.org/licenses/by/3.0/
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Conditional Compilation Symbols
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSCXT2, TURBO, STACKX, OPTIONX, BOR42
FREQ            20_000_000
ID              "RandyAZ"


' -------------------------------------------------------------------------
' I/O Pins
' -------------------------------------------------------------------------

HB25            PIN        RC.7 INPUT
Trigger         PIN        RC.6 INPUT


' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

IsOn            CON     1
IsOff           CON     0


' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

oldBits         VAR     Byte
newBits         VAR     Byte
counter         VAR     Byte
index           VAR     Word


' =========================================================================
' INTERRUPT
' =========================================================================


' RETURNINT


' =========================================================================
  PROGRAM Start
' =========================================================================


' -------------------------------------------------------------------------
' Subroutine / Function Declarations
' -------------------------------------------------------------------------

DELAY_MS        SUB     1, 2
SET_HB25        SUB     1, 2


' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  PLP_A = %0000_0000                            ' pull-ups on unused pins
  PLP_B = %0000_0000
  PLP_C = %1100_0000


HB25_Hold:
  IF HB25 = 1 THEN HB25_Hold
  LOW HB25
  SET_HB25 750
  DELAY_MS 5000

  oldBits = RB & %0000_1111                     ' oldBits = INA


Main:
  IF Trigger = IsOff THEN Main
  counter = 0
  SET_HB25 800


Encoder:
  IF counter >= 62 THEN Main

  newBits = RB & %0000_1111                      ' newBits = INA
  IF newBits <> oldBits THEN
    INC counter

    IF counter = 10 THEN
      SET_HB25 710
    ELSEIF counter = 20 THEN
      SET_HB25 780
    ELSEIF counter = 40 THEN
      SET_HB25 600
    ELSEIF counter = 61 THEN
      SET_HB25 750
    ELSE
    ENDIF

    oldBits = newBits
  ENDIF

  GOTO Encoder


' -------------------------------------------------------------------------
' Subroutine / Function Code
' -------------------------------------------------------------------------

' Use: DELAY_MS duration
' -- duration in milliseconds
' -- shell for PAUSE

SUB DELAY_MS
  duration      VAR     __WPARAM12

  \ SB    __PARAMCNT.1                          ' skip if word parameter
  \ CLR   duration_MSB                          '  else clear for byte

  PAUSE duration
  ENDSUB

' -------------------------------------------------------------------------

' Use: SET_HB25 speed
' -- speed is in 2 uS units
' -- compatible with BS2 PULSOUT

SUB SET_HB25
  pWidth        VAR     __WPARAM12

  \ SB    __PARAMCNT.1                          ' skip if word parameter
  \ CLR   pWidth_MSB

  HIGH HB25
  PAUSEUS pWidth
  HB25 = IsOff
  ENDSUB


' -------------------------------------------------------------------------
' User Data
' -------------------------------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office

randyaz

Hey Jon,

Thanks for the "Rosetta Stone".  I'm grasping everything but the

oldBits = RB & %0000_1111                     ' oldBits = INA

I found that RB is a port, the "&" is a bitwise AND, and presuming the %0000_1111 is a memory location

What I think its doing is taking input from the QTI sensor on any RB pin and storing it in a register. But I cant figure out whats taking place.

Would you please explain what going on here? 

JonnyMac

Here's the deal, Randy, 8-bit micros like the SX and those used in the BASIC Stamp have just two native variable types: bits (1 bit) and bytes (8 bits).  In the BASIC Stamp, Nibs and Words are a programmer's creation.  Words are two bytes and easy to manufacture, hence they showed up in SX/B about a year into its release.

Let's talk about Nibs; four-bit variables.  Again, they don't exist within the processor so we have to synthesize them.  In your PBASIC program you have this line of code:

  newBits = INA

... where INA is a 4-bit port alias corresponding to P0-P3.  In SX/B we can duplicate exactly what the BASIC Stamp is doing "under the hood" with this line of code:

  newBits = RB & %0000_1111

Here's what's going on: The IO points for P0-P3 are located on the SX port RB (also on the PIC port RB in the BASIC Stamp's interpreter).  As RB is an 8-bit port we have to get rid of the bits we don't need and we do that with a process called masking.  With the & operator the rule is as follows: If A and B are both 1, the result is 1, otherwise the result is 0.  What you'll find in the PBASIC and SX/B help files is a truth table that looks like this:

  0 & 0 = 0
  0 & 1 = 0
  1 & 0 = 0
  1 & 1 = 1


Back to the line above, the code makes a copy of RB (all eight bits) and then masks off the upper four bits using the & operator -- what we're left with is a 4-bit result.  Let's say that RB has %0011_1010 on it when we read it:

  %0011_1010  (RB)
  %0000_1111  (mask)
  ----------
  %0000_1010  (newBits)


As you can see, the mask is applied -- using the rule illustrated in the truth table -- on a bit-by-bit basis.  Masking is an important skill and frequently used in programming, and you can find it in PBASIC 1, PBASIC 2, and SX/B.  You'll find examples of masking used in some of my Prop-1 programs, especially those where I want to play a bunch of segments in the AP-8 randomly and without repeating before starting again (I use masking to check to see if a segment has already played).

PS: Just a hint for your PBASIC 2 programs: if you have plenty of memory space, stick with bytes over nibs; your code will be a little faster as bytes are a native variable type for the micro and don't require extra processing.

PSS: One of the great features of the SX and SX/B is the ability to use the underscore character in numbers as we please; when using binary numbers as above I will often use the underscore to separate the bits into nib-sized groups.
Jon McPhalen
EFX-TEK Hollywood Office