' =============================================================================== ' ' File....... PizzaPack.bsp ' Purpose.... Prototype This: Pizza Pie Pack ' Author..... Joe Grand ' ' {$STAMP BS2p} ' {$PBASIC 2.5} ' {$PORT COM3} ' ' =============================================================================== ' -----[ Program Description ]--------------------------------------------------- ' This BASIC Stamp BS2p code is for the Pizza Pie Pack circuitry that ' performs a number of different functions: ' ' * Reads serial data from Magtek 21040082 Magnetic Stripe Reader ' ' * Reads keypad buttons for order loading/configuration ' ' * Display UI (customer name, tray number, etc.) on Optrex C-51847NFQJ-LW-AAN ' 4 x 20 white on black LCD ' ' * Control four HB-25 motor controllers for the four pizza trays ' ' * Read end-of-travel and start-of-travel switches for each pizza tray ' ' * Read photo interrupter/reflector for pizza removal detection from the tray ' ' -----[ I/O Definitions ]----------------------------------------------------- LCDpin CON 0 ' connect LCD to OutL MS_FROM PIN 8 ' data FROM credit card/magnetic stripe reader MS_TO PIN 9 ' data TO credit card/magnetic stripe reader Key_Data PIN 13 HB25_TRAY12 PIN 14 ' HB-25 motor controller for Pizza Tray 1 & 2 HB25_TRAY34 PIN 15 ' HB-25 motor controller for Pizza Tray 3 & 4 ' Auxiliary I/O port Key_A PIN 12 Key_B PIN 13 Key_C PIN 14 Key_D PIN 15 TRAY1_ST PIN 11 ' Start-of-travel switch (Tray 1) TRAY1_END PIN 10 ' End-of-travel switch (Tray 1) TRAY1_PZ PIN 3 ' Pizza removal detection (Tray 1) TRAY2_ST PIN 9 TRAY2_END PIN 8 TRAY2_PZ PIN 2 TRAY3_ST PIN 7 TRAY3_END PIN 6 TRAY3_PZ PIN 1 TRAY4_ST PIN 5 TRAY4_END PIN 4 TRAY4_PZ PIN 0 ' -----[ Constants ]------------------------------------------------------- #SELECT $STAMP #CASE BS2, BS2E, BS2PE T1200 CON 813 T2400 CON 396 T4800 CON 188 T9600 CON 84 T19K2 CON 32 T38K4 CON 6 #CASE BS2SX, BS2P T1200 CON 2063 T2400 CON 1021 T4800 CON 500 T9600 CON 240 T19K2 CON 110 T38K4 CON 45 #CASE BS2PX T1200 CON 3313 T2400 CON 1646 T4800 CON 813 T9600 CON 396 T19K2 CON 188 T38K4 CON 84 #ENDSELECT SevenBit CON $2000 Inverted CON $4000 Open CON $8000 MS_Baud CON T9600 ' LCD NoCmd CON $00 ' No command in LCDOUT ClrLCD CON $01 ' clear the LCD CrsrHm CON $02 ' move cursor to home position DispLf CON $18 ' shift displayed chars left DispRt CON $1C ' shift displayed chars right DDRam CON $80 ' Display Data RAM control CGRam CON $40 ' Custom character RAM Line1 CON $80 ' DDRAM address of line 1 Line2 CON $C0 ' DDRAM address of line 2 Line3 CON $94 ' DDRAM address of line 3 Line4 CON $D4 ' DDRAM address of line 4 ' Motor control pulses for PULSOUT/HB-25 ' (0.8uS per unit for BS2p) Motor_Idle CON 1875 ' 1500uS Motor_Rev CON 2375 ' 1900uS Motor_Fwd CON 1375 ' 1100uS ' -----[ Variables ]------------------------------------------------------- x VAR BYTE y VAR BYTE idx VAR BYTE tmp VAR BYTE ' -----[ EEPROM Data ]----------------------------------------------------- Card0 DATA "1122334455667788" ' credit card number for Master Chef Card (for administration) Card1 DATA "2233445566778899" Card2 DATA "3344556677889900" Card3 DATA "0011223344556677" Card4 DATA "1234567812345678" LastCard CON 4 ' -----[ Initialization ]-------------------------------------------------- Init: PAUSE 100 ' let the system settle DEBUG CLS, "Prototype This Pizza Pie Pack!", CR, CR ' HB25s need to be initialized immediately upon power-up to avoid latching in improper ' state, which could cause the units to not respond to incoming pulses ' In the Pizza Pie Pack, the motor controllers have a separate power switch to ensure ' the BS2 is up and running first. Total hack! Init_HB25: DEBUG "Init HB-25s..." DO : LOOP UNTIL HB25_TRAY12 = 1 ' wait for HB-25 power up LOW HB25_TRAY12 ' make I/O pin output/low LOW HB25_TRAY34 PAUSE 20 ' wait for HB-25 to initialize PULSOUT HB25_TRAY12, Motor_Idle ' stop motor 1 (tray 1) PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY12, Motor_Idle ' stop motor 2 (tray 2) PAUSE 20 PULSOUT HB25_TRAY34, Motor_Idle ' stop motor 1 (tray 3) PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY34, Motor_Idle ' stop motor 2 (tray 4) DEBUG "DONE!", CR, CR Init_LCD: 'DEBUG "Initializing LCD..." LCDCMD LCDpin,%00110000 : PAUSE 5 ' 8-bit mode LCDCMD LCDpin,%00110000 : PAUSE 0 LCDCMD LCDpin,%00110000 : PAUSE 0 LCDCMD LCDpin,%00100000 : PAUSE 0 ' 4-bit mode LCDCMD LCDpin,%00101000 : PAUSE 0 ' 2-line mode LCDCMD LCDpin,%00001100 : PAUSE 0 ' no crsr, no blink LCDCMD LCDpin,%00000110 ' inc crsr, no disp shift 'DEBUG "DONE!", CR, CR ' -----[ Program Code ]---------------------------------------------------- Main: LCDOUT LCDpin,ClrLCD,["PIZZA PIE PACK"] LCDOUT LCDpin,Line3,["Please swipe card"] ReadMagStripe: SERIN MS_FROM, MS_Baud, [WAIT("%"), SPSTR 63] ' wait until we see the track 1 start sentinel and store the resulting string in scratchpad RAM LCDOUT LCDpin, Line3, [REP " "\20] ' clear lines LCDOUT LCDpin, Line4, [REP " "\20] FOR idx = 0 TO 62 ' get entire contents of scratchpad RAM GET idx, x ' read char from SPRAM DEBUG x ' and print to debug terminal NEXT DEBUG CR ' display data ' card/account number FOR idx = 1 TO 62 ' start reading after track 1 format code GET idx, x IF (x <> "^") THEN ' while we don't see the end sentinel ' LCDOUT LCDpin, Line4 + idx - 1, [x] ' display data to LCD ELSE GOTO CardDisplayDone ENDIF NEXT CardDisplayDone: ' name tmp = idx + 1 FOR idx = tmp TO 62 GET idx, x IF (x <> "^") THEN ' while we don't see the end sentinel LCDOUT LCDpin, Line3 + idx - tmp, [x] ' display data to LCD ELSE GOTO NameDisplayDone ENDIF NEXT NameDisplayDone: ' compare account number of swiped card to our table of valid cards (4 cards, 4 pizza trays) FOR y = 0 TO 4 FOR idx = 1 TO 16 ' start reading after track 1 format code GET idx, x READ (y * 16 + idx - 1), tmp ' get master card data from table IF (x <> tmp) THEN Not_This_Card NEXT GOTO Card_Found Not_This_Card: NEXT ' try the next card in the table GOTO No_Card_Match ' if none of the cards match, no pizza for you! Card_Found: 'DEBUG "Card match!", CR, CR IF (y = 0) THEN 'DEBUG "Entering pizza administration mode!", CR GOTO Pizza_Admin_Mode ELSE LCDOUT LCDpin, Line4, ["Tray ", DEC y] GOTO Deliver_Pizza ENDIF PAUSE 4000 GOTO Main END ' -----[ Subroutines ]----------------------------------------------------- Open_Tray1: DEBUG "T1: Open..." ' drive motor via HB-25 until end-of-travel switch is closed DO MAINIO PULSOUT HB25_TRAY12, Motor_Fwd ' tray 1 motor forward PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY12, Motor_Idle ' tray 2 motor idle PAUSE 20 ' 20ms smoothing delay AUXIO LOOP UNTIL TRAY1_END = 1 MAINIO PULSOUT HB25_TRAY12, Motor_Idle ' tray 1 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY12, Motor_Idle ' tray 2 motor idle DEBUG "DONE!", CR RETURN Close_Tray1: DEBUG "T1: Close..." ' drive motor via HB-25 in reverse until start-of-travel switch is closed DO MAINIO PULSOUT HB25_TRAY12, Motor_Rev ' tray 1 motor forward PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY12, Motor_Idle ' tray 2 motor idle PAUSE 20 ' 20ms smoothing delay AUXIO LOOP UNTIL TRAY1_ST = 1 MAINIO PULSOUT HB25_TRAY12, Motor_Idle ' tray 1 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY12, Motor_Idle ' tray 2 motor idle DEBUG "DONE!", CR RETURN Open_Tray2: DEBUG "T2: Open..." DO MAINIO PULSOUT HB25_TRAY12, Motor_Idle PAUSE 1 PULSOUT HB25_TRAY12, Motor_Fwd PAUSE 20 AUXIO LOOP UNTIL TRAY2_END = 1 MAINIO PULSOUT HB25_TRAY12, Motor_Idle ' tray 1 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY12, Motor_Idle ' tray 2 motor idle DEBUG "DONE!", CR RETURN Close_Tray2: DEBUG "T2: Close..." DO MAINIO PULSOUT HB25_TRAY12, Motor_Idle PAUSE 1 PULSOUT HB25_TRAY12, Motor_Rev PAUSE 20 AUXIO LOOP UNTIL TRAY2_ST = 1 MAINIO PULSOUT HB25_TRAY12, Motor_Idle ' tray 1 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY12, Motor_Idle ' tray 2 motor idle DEBUG "DONE!", CR RETURN Open_Tray3: DEBUG "T3: Open..." DO MAINIO PULSOUT HB25_TRAY34, Motor_Fwd ' tray 3 motor forward PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY34, Motor_Idle ' tray 4 motor idle PAUSE 20 ' 20ms smoothing delay AUXIO LOOP UNTIL TRAY3_END = 1 MAINIO PULSOUT HB25_TRAY34, Motor_Idle ' tray 3 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY34, Motor_Idle ' tray 4 motor idle DEBUG "DONE!", CR RETURN Close_Tray3: DEBUG "T3: Close..." DO MAINIO PULSOUT HB25_TRAY34, Motor_Rev PAUSE 1 PULSOUT HB25_TRAY34, Motor_Idle PAUSE 20 AUXIO LOOP UNTIL TRAY3_ST = 1 MAINIO PULSOUT HB25_TRAY34, Motor_Idle ' tray 3 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY34, Motor_Idle ' tray 4 motor idle DEBUG "DONE!", CR RETURN Open_Tray4: DEBUG "T4: Open..." DO MAINIO PULSOUT HB25_TRAY34, Motor_Idle PAUSE 1 PULSOUT HB25_TRAY34, Motor_Fwd PAUSE 20 AUXIO LOOP UNTIL TRAY4_END = 1 MAINIO PULSOUT HB25_TRAY34, Motor_Idle ' tray 3 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY34, Motor_Idle ' tray 4 motor idle DEBUG "DONE!", CR RETURN Close_Tray4: DEBUG "T4: Close..." DO MAINIO PULSOUT HB25_TRAY34, Motor_Idle PAUSE 1 PULSOUT HB25_TRAY34, Motor_Rev PAUSE 20 AUXIO LOOP UNTIL TRAY4_ST = 1 MAINIO PULSOUT HB25_TRAY34, Motor_Idle ' tray 3 motor idle PAUSE 1 ' 1ms delay PULSOUT HB25_TRAY34, Motor_Idle ' tray 4 motor idle DEBUG "DONE!", CR RETURN Deliver_Pizza: ' y contains tray number to control SELECT (y) CASE 1 GOSUB Open_Tray1 AUXIO DO : LOOP UNTIL TRAY1_PZ = 0 ' wait until optical sensor detects that the pizza has been removed from tray MAINIO DEBUG "T1: Pizza Removed!", CR PAUSE 4000 GOSUB Close_Tray1 CASE 2 GOSUB Open_Tray2 AUXIO DO : LOOP UNTIL TRAY2_PZ = 0 ' wait until optical sensor detects that the pizza has been removed from tray MAINIO DEBUG "T2: Pizza Removed!", CR PAUSE 4000 GOSUB Close_Tray2 CASE 3 GOSUB Open_Tray3 AUXIO DO : LOOP UNTIL TRAY3_PZ = 0 ' wait until optical sensor detects that the pizza has been removed from tray MAINIO DEBUG "T3: Pizza Removed!", CR PAUSE 4000 GOSUB Close_Tray3 CASE 4 GOSUB Open_Tray4 AUXIO DO : LOOP UNTIL TRAY4_PZ = 0 ' wait until optical sensor detects that the pizza has been removed from tray MAINIO DEBUG "T4: Pizza Removed!", CR PAUSE 4000 GOSUB Close_Tray4 ENDSELECT ' all done! PAUSE 4000 GOTO Main ' pizza adminstration mode where pizza chef can enter in the credit card ' number to match an associated pizza tray Pizza_Admin_Mode: LCDOUT LCDpin,ClrLCD,["PIZZA PIE PACK"] LCDOUT LCDpin,Line2,["Administration Mode"] FOR y = 1 TO 4 ' for each of the four pizza trays LCDOUT LCDpin, Line3, ["Tray ", DEC y] LCDOUT LCDpin, Line4, [REP " "\20] ' clear line LCDCMD LCDpin,%00001101 ' turn on LCD blinking cursor LCDOUT LCDpin, Line2+19, [" "] ' position the cursor at the beginning of line 4 ' open corresponding tray to allow chef to load in pizza SELECT (y) CASE 1 GOSUB Open_Tray1 CASE 2 GOSUB Open_Tray2 CASE 3 GOSUB Open_Tray3 CASE 4 GOSUB Open_Tray4 ENDSELECT FOR idx = 0 TO 15 ' chef must enter in 16 character credit card number DO : LOOP UNTIL Key_Data = 1 ' wait for button press PAUSE 100 DO : LOOP UNTIL Key_Data = 1 ' poor man's debounce x = 0 AUXIO x.BIT0 = Key_A x.BIT1 = Key_B x.BIT2 = Key_C x.BIT3 = Key_D 'DEBUG BIN4 x, " " MAINIO LOOKDOWN x, [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14], x ' map keypad value returned from 74C922 LOOKUP x, ["1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"], x ' to actual keypad number 'DEBUG x, CR DO : LOOP UNTIL Key_Data = 0 ' wait for button release to avoid repeating digits PAUSE 100 DO : LOOP UNTIL Key_Data = 0 ' poor man's debounce IF (x = "#") OR (x = "*") THEN ' if # or * pressed, abort mission! LCDCMD LCDpin,%00001100 ' no crsr, no blink LCDOUT LCDpin, Line4, [REP " "\20] ' clear line LCDOUT LCDpin, Line3, ["Aborted!"] PAUSE 1750 ' close corresponding tray SELECT (y) CASE 1 GOSUB Close_Tray1 CASE 2 GOSUB Close_Tray2 CASE 3 GOSUB Close_Tray3 CASE 4 GOSUB Close_Tray4 ENDSELECT PAUSE 1000 GOTO Main ELSE ' if a number was pressed LCDOUT LCDpin, Line4 + idx, [x] WRITE (y * 16 + idx), x ' write digit into EEPROM table for card y (overwrites default values) ENDIF NEXT LCDCMD LCDpin,%00001100 ' no crsr, no blink PAUSE 1750 ' close corresponding tray SELECT (y) CASE 1 GOSUB Close_Tray1 CASE 2 GOSUB Close_Tray2 CASE 3 GOSUB Close_Tray3 CASE 4 GOSUB Close_Tray4 ENDSELECT PAUSE 1000 ' add a little delay before going to the next tray NEXT LCDCMD LCDpin,%00001100 ' no crsr, no blink LCDOUT LCDpin, Line4, [REP " "\20] ' clear line LCDOUT LCDpin, Line3, ["Success!"] PAUSE 4000 GOTO Main No_Card_Match: 'DEBUG "No card match!", CR, CR LCDOUT LCDpin, Line4, ["No pizza for you!"] PAUSE 4000 GOTO Main 'CheckSwitch: ' AUXIO ' DEBUG BIN TRAY1_ST ' DEBUG BIN TRAY1_END ' DEBUG BIN TRAY2_ST ' DEBUG BIN TRAY2_END ' DEBUG BIN TRAY3_ST ' DEBUG BIN TRAY3_END ' DEBUG BIN TRAY4_ST ' DEBUG BIN TRAY4_END ' DEBUG CR ' MAINIO ' GOTO CheckSwitch 'CheckOptical: ' AUXIO ' DEBUG BIN TRAY1_PZ ' DEBUG BIN TRAY2_PZ ' DEBUG BIN TRAY3_PZ ' DEBUG BIN TRAY4_PZ ' DEBUG CR ' MAINIO ' GOTO CheckOptical 'CheckOptical2: ' AUXIO ' IF (TRAY4_PZ = 1) THEN ' MAINIO ' LCDOUT LCDpin,ClrLCD,["Pizza detected!"] ' ELSE ' MAINIO ' LCDOUT LCDpin,ClrLCD,["Pizza removed!"] ' ENDIF ' PAUSE 500 ' GOTO CheckOptical2