Attribute VB_Name = "BX24_byork"

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'        TAB Electronics Build Your Own Robot Kit BX24 Interface Module
'                  by  Dr. J (Juliano@csuChico.edu)
'                  and Matt Bauer (MBauer1@csuChico.edu)
'                  California State University, Chico
'                  Intelligent Systems Laboratory
'                  http://isl.ecst.csuchico.edu
'
'  This module contains the RobotSend() and RobotSendReceive() subroutines for
'  communication with the PIC 16C505 which is the onboard co-processor for the
'  Build Your Own Robot Kit by TAB Robotics.
'
'  The code in this module is based on the BS2 programming template written by
'  Myke Predko to facilitate any BS2 to BX24 code migration.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


Option Explicit

' Predefined Robot Commands

Public  Const RobotStop     As Byte =  0  '  Stop the Robot
Public  Const Behavior1     As Byte =  1  '  Random Movement
Public  Const Behavior2     As Byte =  2  '  Photovore
Public  Const Behavior3     As Byte =  3  '  Photophobe
Public  Const Behavior4     As Byte =  4  '  Wall Hugger/Maze Solver
Public  Const RobotForward  As Byte =  5  '  Move Forward for 200 msecs
Public  Const RobotReverse  As Byte =  6  '  Move Reverse for 200 msecs
Public  Const RobotLeft     As Byte =  7  '  Turn Left for 200 msecs
Public  Const RobotRight    As Byte =  8  '  Turn Right for 200 msecs
Public  Const RobotLEDOn    As Byte =  9  '  Turn on the Robot's LED
Public  Const RobotLEDOff   As Byte = 10  '  Turn off the Robot's LED
Public  Const RobotPWM0     As Byte = 11  '  PWM = 0% Duty Cycle
Public  Const RobotPWM1     As Byte = 12  '  PWM = 1st "Notch"
Public  Const RobotPWM2     As Byte = 13  '  PWM = 2nd "Notch"
Public  Const RobotPWM3     As Byte = 14  '  PWM = 3rd "Notch"
Public  Const RobotPWM4     As Byte = 15  '  PWM = 100% Duty Cycle
Public  Const RobotPWM      As Byte = 16  '  Return the Current PWM Value
Public  Const RobotState    As Byte = 17  '  Return the Executing State
Public  Const RobotWhiskers As Byte = 18  '  Return State of the "Whiskers"
					  '   Bit 0 - Left "Whisker"
					  '   Bit 1 - Right "Whisker"
Public  Const RobotCDSL     As Byte = 19  '  Return Value of Left CDS Cell
Public  Const RobotCDSR     As Byte = 20  '  Return Value of Right CDS Cell
Public  Const RobotButton   As Byte = 21  '  Return the Last Remote Button Press
					  '   0 - No Buttons Pressed
					  '   1 - Leftmost Button Pressed
					  '   2 - Middle Button Pressed
					  '   3 - Rightmost Button Pressed
					  '  After "RobotButton" Operation,  
					  '   Button Save is Cleared
'  Robot Serial Interface Pins

Public  Const SC As Byte = 19		  '  Default BX-24 clock pin
Public  Const SD As Byte = 20		  '  Default BX-24  data pin

'  BX-24 constants (for system calls)

Private Const NumberOfBits  As Byte =  8  '  for ShiftIn() and ShiftOut()

'  BX-24 private serial interface variables

Private ClockPin As Byte = SC
Private Data_Pin As Byte = SD


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Set the robot serial interface pin numbers to SC for the clock pin
' and SD for the data pin.


Public Sub SetSerialPins( _
    ByVal SC As Byte, _
    ByVal SD As Byte    )

    ClockPin = SC
    Data_Pin = SD

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Get the robot serial interface pin numbers, storing clock pin to SC and
' the data pin to SD.

Public Sub GetSerialPins( _
    ByRef SC As Byte, _
    ByRef SD As Byte    )

    SC = ClockPin
    SD = Data_Pin

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Set the robot interface pins as high.

Public Sub SetSerialPinsHi()

    Call PutPin( ClockPin , bxOutputHigh )
    Call PutPin( Data_Pin , bxOutputHigh )

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Set the robot interface pins as low.

Public Sub SetSerialPinsLo()

    Call PutPin( ClockPin , bxOutputLow )
    Call PutPin( Data_Pin , bxOutputLow )

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Set the robot interface pins as output and high; this subroutine needs
' to be called before any application code.

Public Sub InitSerialPins()

    Call SetSerialPinsHi()
    Call Sleep ( 0.001 )

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Reset the robot interface pins as output and high.

Public Sub ResetSerialPins()

    Call SetSerialPinsLo()
    Call SetSerialPinsHi()
    Call Sleep ( 0.001 )

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Thanks to Don Kinzer of groups.yahoo.com/group/basicx for his suggestions on
' how to slow down the BX-24's ShiftOut() operation using PutPin(), PulseOut(),
' GetBit(), and PutBit() commands.  The slow-down is needed to match the clock
' rate of the BS2 for effective communication with the BYORK PIC 16C505
' microcontroller ...
' (Implemented as a fully unrolled loop; FOR loop implementation slower still.)

' Shift out data bits in DataByte to the robot in serial fashion, LSB-first.
' Data is 'rightshifted' into a register making the first bit sent the LSB.

Private Sub ShiftOutSlowly( ByVal DataByte As Byte )

'   Hold ClockPin and Data_Pin low for 1 msec before shifting in data
    Call SetSerialPinsLo()
    Call Sleep( 0.001 )

'   Send "DataByte" to the co-processor in serial fashion, LSB first;
'   sends an 8 bit high (10-12us) going clock pulse to co-processor.
    Call PutPin( Data_Pin , GetBit( DataByte , 0 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutPin( Data_Pin , GetBit( DataByte , 1 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutPin( Data_Pin , GetBit( DataByte , 2 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutPin( Data_Pin , GetBit( DataByte , 3 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutPin( Data_Pin , GetBit( DataByte , 4 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutPin( Data_Pin , GetBit( DataByte , 5 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutPin( Data_Pin , GetBit( DataByte , 6 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutPin( Data_Pin , GetBit( DataByte , 7 ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )

'   Reset data and clock pins and wait for coprocessor
    Call ResetSerialPins()

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Shift in data bits to DataByte from the robot in serial fashion, LSB-first.

Private Sub ShiftInSlowly( ByRef DataByte As Byte )

'   Reset data and clock pins and wait for coprocessor
    Call SetSerialPinsLo()
    Call Sleep ( 0.001 )

' Read an 8-bit value from co-processor in serial fashion, LSB first.
' Puts an 8 bit high(10-12)ms going pulse on the clock pin.

    Call PutBit( DataByte , 0 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutBit( DataByte , 1 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutBit( DataByte , 2 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutBit( DataByte , 3 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutBit( DataByte , 4 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutBit( DataByte , 5 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutBit( DataByte , 6 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )
    Call PutBit( DataByte , 7 , GetPin( Data_Pin ) )
    Call PulseOut( ClockPin , 10 , bxOutputHigh )

'   Reset data and clock pins and wait for coprocessor
    Call ResetSerialPins()

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Send the byte in "DataByte" to the robot

Public Sub RobotSend( ByVal DataByte As Byte )

'   Shift out data bits to the robot LSB-first ...
    Call ShiftOutSlowly( DataByte )

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sends the byte in "DataByte" to the robot, using it for return value

Public Sub RobotSendReceive( ByRef DataByte As Byte )

'   Shift out data bits to the robot LSB-first and wait for completion ...
    Call ShiftOutSlowly( DataByte )

'   Read in result/status of requested operation
    Call ShiftInSlowly( DataByte )

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
