' {$STAMP BS2}
' {$PBASIC 2.5}
' **************************************************************
' *                        Pongwriter                          *
' *       By Vern Graner SSE, Texas Information Services       *
' **************************************************************
' * Code for writing on Ping Pong Ball with Parallax Serial    *
' * Inkjet printer system                                      *
' **************************************************************
' * Created:  V0.1 11-29-2007                                  *
' **************************************************************

' ************************
' * Conditonal Compile   *
' *************************************************************************
#SELECT $STAMP
  #CASE BS2, BS2E, BS2PE
    T2400       CON     396
    T4800       CON     188
    T9600       CON     84
    T19K2       CON     32
    T38K4       CON     6
  #CASE BS2SX, BS2P
    T2400       CON     1021
    T4800       CON     500
    T9600       CON     240
    T19K2       CON     110
    T38K4       CON     45
  #CASE BS2PX
    T2400       CON     1646
    T4800       CON     813
    T9600       CON     396
    T19K2       CON     188
    T38K4       CON     84
#ENDSELECT

' ************************
' * Idea Cache           *
' *************************************************************************
' Switch to change text of message
' switch to change from 9 lines to three lines of text
' auto/manual switch for continuous OR one-shot print
' NOTE: Button is in parallel w/the switch
' need relay for agitator motor (gang ULN2803 channels for current?) ~1.5a at stall!
' Four PIN Connector for agitator motor and LEDs
' Mount LEDs in top w/hot melt
' make one more set of LEDs for exit tray area
' extra feature? maybe speed vs. looks?


' ************************
' * I/O Definitions      *
' *************************************************************************
  LightPrinter     PIN 0  ' Lights the indexer tube
  LightIndexer     PIN 1  ' Lights the print head & pedestal
  LightAgitator    PIN 2  ' Lights the ball jar
  LightTray        PIN 3  ' Lights the finished products
  'avail           PIN 4 '
  'avail           PIN 5 '
  'avail           PIN 6 '
  InkJet           PIN 7 ' Serial Inkjet Printer
  ServoIndexer     PIN 8 ' Allows a single ball to drop for printing
  ServoPrinthead   PIN 9 ' Positions Print Head
  ServoRotate      PIN 10 ' Rotates ball for printing
  ServoEject       PIN 11 ' Turns to eject ball
  'avail           PIN 12 '
  AltText          PIN 13 ' Alternate text message
  ThreeLine        PIN 14 ' Three Lines (less ink used)
  AutoMan          PIN 15 ' Switch and button for auto/maual feed


' ************************
' * Constants            *
' ************************
  Open            CON     $8000
  Baud            CON     Open + T9600
  Prompt          CON     ">"             ' ready prompt from HP driver
  STX             CON     2               ' start of text
  ETX             CON     3               ' end of text
  Esc             CON     27              ' OEM configuration command

  ServoEjectOut              CON  1100    '
  ServoEjectIn               CON  700

  ServoRotateStop            CON 760
  ServoRotateFwdSlow         CON 785
  ServoRotateFwdFast         CON 790

  ServoPrintheadTop          CON 1040
  ServoPrintheadCenter       CON 750
  ServoPrintheadBottom       CON 540

  ServoIndexerLoad           CON 825     '
  ServoIndexerRelease        CON 550     '

  LineFeed                   CON 63 'interval for one LF


  Speed       CON 10 ' Set the step rate

'  Right  CON 1100 ' PWN value to move servo to "right" position
'  Left   CON 250  ' PWM for Left

' ************************
' * Data Variables       *
' ************************
  cntI         VAR Word   ' index counter for subroutines
  cntX         VAR Byte   ' index counter for main
  cntY         VAR Byte   ' index counter # for main body
  LineNumber   VAR Word   'line number position variable

' ************************
' * Begin Main Program   *
' ********************************************************

' ************************
' * Initialization       *
' ************************
  ProgramBegin:
  DEBUG "Start Sequence!",CR
  IF ThreeLine = 1 THEN
      DEBUG "Three Line Mode", CR
  ELSE
      DEBUG "Nine Line Mode", CR
  ENDIF

  IF AltText = 1 THEN
      DEBUG "Alternate Text", CR
  ELSE
      DEBUG "Standard Text", CR
  ENDIF

  ' DEBUG"----------------",CR
   GOSUB PlaceInit ' Get all servos into start positions

' ************************
' * Agitate Hopper       *
' ************************
   ' Agitator operation code goes here
    HIGH LightAgitator
    PAUSE 2000
    LOW LightAgitator

' ************************
' * Drop a ball          *
' ************************
    HIGH LightIndexer ' Light the area
    GOSUB DropBall ' Drop a new ball into place
    LOW LightIndexer
    HIGH LightPrinter ' Light the area
    PAUSE 500 ' wait for ball to "settle"


' ************************
' * Print the ball       *
' ************************
   FOR CntX = 1 TO 3          ' Print 3 lines, 3 times

     IF ThreeLine = 1 THEN ' do three "line feeds"
       'DEBUG "Three Line Mode"
       FOR CntY = 1 TO 2
        GOSUB PrintHeadLineFeed
       NEXT
     ENDIF

     GOSUB PrintHeadLineFeed
     GOSUB PrintText
     GOSUB RotateBallFwdSlow

     GOSUB PrintHeadLineFeed
     GOSUB Start2
     GOSUB RotateBallFwdSlow

     GOSUB PrintHeadLineFeed
     GOSUB Start3
     GOSUB RotateBallFwdSlow

     IF ThreeLine = 1 THEN Done_Print
   NEXT

Done_Print:
   PAUSE 100  ' make discrete steps more visible to observers.

   GOSUB PrintHeadBottom ' Get the print head out of the way
   PAUSE 100 ' Aesthetics-- Wait for motion to stop

' ************************
' * Eject the ball       *
' ************************
   GOSUB EjectBall      'Eject the ball
   DEBUG "Done!",CR    'Cycle finished
   LOW  LightPrinter ' Light the area

' ************************
' * Light the Tray       *
' ************************
   HIGH  LightTray ' Light the exit area

   WaitForButton:
   IF AutoMan = 0 THEN WaitForButton

   LOW LightTray
   GOTO ProgramBegin


END ' Should never get here, but... :)


'SubRoutines
'*******************************************************************

' **************************
' * Print Text             *
' **************************
PrintText:

Reset: ' Reset InkJet
  SEROUT Inkjet, Baud, [Esc, "C", 25]           ' intercolumn delay values 1-25 15=1.5 ms
  SERIN  Inkjet, Baud, 500, No_Inkjet, [WAIT(Prompt)]

Start:
  ' DEBUG "Line 1",CR
  SEROUT Inkjet, Baud, [STX]
'  SEROUT Inkjet, Baud, ["   WWW.TheRobotGroup.ORG <*==-|-==*> First Night Austin 2007"]
  IF AltText = 0 THEN
      SEROUT Inkjet, Baud, ["     WWW.TheRobotGroup.ORG        First Night Austin 2007   "]
  ELSE
      SEROUT Inkjet, Baud, [" Bow Down Before Your New Robot Ping Pong Overlords!! "]
  ENDIF
  SEROUT Inkjet, Baud, [ETX]
RETURN

Start2:
  ' DEBUG "Line 2",CR
  SEROUT Inkjet, Baud, [STX]
  IF AltText = 0 THEN
      SEROUT Inkjet, Baud, ["   >-<  Happy New Year Austin!  >-<  Happy New Year Austin! "]
  ELSE
      SEROUT Inkjet, Baud, [" Puny Humans! PONGINATOR Rules! You will be swept aside!"]
  ENDIF
  SEROUT Inkjet, Baud, [ETX]
RETURN

Start3:
  ' DEBUG "Line 3",CR
  SEROUT Inkjet, Baud, [STX]
  IF AltText = 0 THEN
      SEROUT Inkjet, Baud, [" < - >  The Robot Group, Incorporated Austin, Texas  < - >  "]
  ELSE
      SEROUT Inkjet, Baud, [" Happy New Years! 2008 The Year of the Robot! Austin, Texas "]
  ENDIF
  SEROUT Inkjet, Baud, [ETX]
RETURN


No_Inkjet:
DEBUG "No Inkjet Detected",CR
RETURN


' **************************
' * Servo Positions INIT   *
' **************************

PlaceInit:
' DEBUG "Init Servo Positions",CR

LineNumber = ServoPrintheadBottom ' Set linenumber to bottom of ball

FOR cntI = 1 TO 50
  PULSOUT ServoEject, ServoEjectIn
  PULSOUT ServoRotate, ServoRotateStop
  PULSOUT ServoPrinthead, ServoPrintheadBottom
  PULSOUT ServoIndexer, ServoIndexerRelease
  PAUSE 18
NEXT
' DEBUG "Servos ready",CR
RETURN


' **************************
' * Rotate Ball            *
' **************************
   RotateBallStop:
   DEBUG "Rotate STOP",CR
   FOR cntI = 1 TO 100 ' Hold in place
     PULSOUT ServoRotate,ServoRotateStop
     PAUSE 20
   NEXT
   RETURN

   RotateBallFwdSlow:
   ' DEBUG "Rotate Slow",CR
   FOR cntI = 1 TO 95 ' Hold in place
     PULSOUT ServoRotate,ServoRotateFwdSlow
     PAUSE 20
   NEXT
   RETURN

   RotateBallFwdFast:
   ' DEBUG "Rotate Fast",CR
   FOR cntI = 1 TO 65 ' Hold in place
     PULSOUT ServoRotate,ServoRotateFwdFast
     PAUSE 20
   NEXT
   RETURN


' **************************
' * Load Ball Sequence    *
' **************************
  DropBall:
  'DEBUG "Load ball=",DEC ServoIndexerLoad,CR
   FOR cntI = ServoIndexerRelease TO ServoIndexerLoad STEP SPEED
     PULSOUT ServoIndexer,cntI
     PAUSE 20
    NEXT

   FOR cntI = 1 TO 25      ' Hold Position to stop overshoot
     PULSOUT ServoIndexer,ServoIndexerLoad
     PAUSE 20
    NEXT


   ' DEBUG "Release ball=",DEC ServoIndexerRelease,CR
   FOR cntI = ServoIndexerLoad TO ServoIndexerRelease STEP SPEED
     PULSOUT ServoIndexer,cntI
     PAUSE 20
    NEXT

   FOR cntI = 1 TO 10      ' Hold Position to stop overshoot
     PULSOUT ServoIndexer,ServoIndexerRelease
     PAUSE 20
    NEXT
  RETURN


' **************************
' * Print Head Top         *
' **************************
PrintHeadTop:
   ' DEBUG "Print Head Up",CR
   FOR cntI = ServoPrintHeadBottom TO ServoPrintHeadTop STEP SPEED
     PULSOUT ServoPrinthead,cntI
     PAUSE 20
    NEXT

   FOR cntI = 1 TO 20 ' Hold in place
     PULSOUT ServoPrinthead,ServoPrintHeadTop
     PAUSE 20
    NEXT
'    PAUSE 2000
  RETURN


' **************************
' * Print Head Center      *
' **************************
PrintHeadCenter:
   ' DEBUG "Print Head Center",CR
   FOR cntI = ServoPrintHeadTop TO ServoPrintHeadCenter STEP SPEED
     PULSOUT ServoPrinthead,cntI
     PAUSE 20
    NEXT

    FOR cntI = 1 TO 20 ' Hold in place
     PULSOUT ServoPrinthead,ServoPrintHeadCenter
     PAUSE 20
    NEXT
'    PAUSE 2000
  RETURN

' **************************
' * Print Head Bottom      *
' **************************
PrintHeadBottom:
   ' DEBUG "Print Head Bottom",CR
   FOR cntI = ServoPrintHeadTop TO ServoPrintHeadBottom STEP SPEED
     PULSOUT ServoPrinthead,cntI
     PAUSE 20
    NEXT

   FOR cntI = 1 TO 20 ' Hold in place
     PULSOUT ServoPrinthead,ServoPrintHeadBottom
     PAUSE 20
    NEXT
'    PAUSE 2000
  RETURN



' **************************
' * Print Head Line Feed   *
' **************************
PrintHeadLineFeed:
  ' DEBUG "Print Head LineFeed",CR

'     top to bottom is  1050-> 550

   ' DEBUG "LineNumber=", DEC LineNumber,CR
   FOR cntI = 1 TO 10
     PULSOUT ServoPrinthead,LineNumber
     PAUSE 20
   NEXT

'IF LineNumber < 1050 THEN            ' see if we are at last line
  LineNumber = Linenumber + LineFeed ' if not, the n move the head
'ELSE
'  GOTO NewBall                       ' if so, then start over again
'ENDIF

RETURN


' **************************
' * Eject Ball             *
' **************************

EjectBall:
   ' DEBUG "Eject ball",CR
   FOR cntI = ServoEjectIn TO ServoEjectOut STEP SPEED
     PULSOUT ServoEject,cntI
     PAUSE 20
    NEXT

  '  PAUSE 200

   ' DEBUG "Return to Catch",CR
   FOR cntI = ServoEjectOut TO ServoEjectIn STEP SPEED
     PULSOUT ServoEject,cntI
     PAUSE 20
    NEXT

  FOR cntI = 1 TO 25             ' Prevent overshoot
    PULSOUT ServoEject,ServoEjectIn
    PAUSE 20
  NEXT
  RETURN




