{{ Audio code by By: Kwabena W. Agyeman - 9/27/2013 Spin code by Clock Loop, made to only test 1 motor on the M1 pins, and the axle sensor to trigger the wav file chuff. The code communicates with the wx module, and the index.html motor control VERY BASIC webpage. As usual upload the index html to your wx module: Visit http://192.168.4.1/files/index.html }} CON _CLKMODE=XTAL1 + PLL16X ' The system clock spec _XINFREQ = 5_000_000 ' Crystal Rx = 31 'serial in from wx device Tx = 30 'serial out to wx device HeadLight = 0 'Pin 0 output for headlight led RearLight = 1 'Pin 1 output for rearlight led Smoker = 2 'Pin 2 output for smoke maker AxleSense = 3 ' High means sensor not active. Sensor goes low twice per revolution of the axle. INV = 4 ' A logical high value inverts the meaning of IN1 and IN2 for both motor drivers SLEW = 5 ' Output slew rate selection input. A logical LOW results in a slow output rise time (1.5 us - 6 us). ' A logical HIGH selects a fast output rise time (0.2 us - 1.45 us). ' This pin should be set HIGH for high-frequency (over 10 kHz) PWM. This pin determines the slew rate mode for both motor driver ICs. EN = 6 ' Enable input: when EN is LOW, both motor ICs are in a low-current sleep mode. M1SF = 7 ' Status flag output: an over-current (short circuit) or over-temperature event will cause SF to be latched LOW. ' If either of the disable pins (D1 or D2) are disabling the outputs, SF will also be LOW. ' Otherwise, this pin is weakly pulled high. ' This allows the two SF pins on the board to be tied together and connected to a single MCU inpu. M1D1 = 8 ' Disable input: when D1 is high, OUT1 and OUT2 are set to high impedance. ' A D1 PWM duty cycle of 70% gives a motor duty cycle of 30%. ' Typically, only one of the two disable pins is used, but the default is for both disable pins to be active. M1D2 = 9 ' Disable input: when D1 is high, OUT1 and OUT2 are set to high impedance. ' A D1 PWM duty cycle of 70% gives a motor duty cycle of 30%. ' Typically, only one of the two disable pins is used, but the default is for both disable pins to be active M1IN1 = 10 ' The logic input control of OUT1. PWM can be applied to this pin (typically done with both disable pins inactive) M1IN2 = 11 ' The logic input control of OUT2. PWM can be applied to this pin (typically done with both disable lines inactive) VDD = 12 ' VDD Only used for pullup resistors, safe to control with prop, NEVER connect this to VIN. M1fbDI = 18 '(Feedback of current draw - not used in this basic demo) M1fbDO = 19 '(Feedback of current draw - not used in this basic demo) M1fbSCL = 20 '(Feedback of current draw - not used in this basic demo) M1fbCS = 21 '(Feedback of current draw - not used in this basic demo) lPin = 26 'left audio output rPin = 27 'right audio output doPin = 22 'sd card DO pin clkPin = 23 'sd card CLK pin diPin = 24 'sd card DI pin csPin = 25 'sd card CS pin wpPin = -1 'Needed for sound code - unused cdPin = -1 'Needed for sound code - unused max_duty = 40 'My motor goes too fast higher. These drastically change when using slew 1 min_duty = 10 'My motor dosen't turn lower. These drastically change when using slew 1 MotorFreq = 1000 'Lower than 10k is a more quiet motor. These drastically change when using slew 1 OBJ ser: "Parallax Serial Terminal.spin" wav1: "V2-WAV_DACEngine.spin" pwm1 : "pwmasm" pwm2 : "pwmasm" VAR byte Handle, ReplyStatus, MotorListener, LedsListener long SmokeStack1[100] long SmokeStack2[100] long SmokeStack3[100] Pub Main 'Cog #1 'if(wav1.begin(lPin, rPin, doPin, clkPin, diPin, csPin, wpPin, cdPin)) 'Cog #2 'ser.Str(string("Start: Success", 10, 13)) 'else 'ser.Str(string("Start: Failure", 10, 13)) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[4;3f")) 'Set Position 'ser.Str(string("Current Duty Cycle:")) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[5;3f")) 'Set Position 'ser.Str(string("Current Chuff Count:")) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[6;3f")) 'Set Position 'ser.Str(string("WaitTime:")) 'wav1.setLeftVolume(3) 'wav1.setRightVolume(3) 'cognew(Chuff, @SmokeStack1) ' Startup sound system. 'Cog #3 SOUND WAS TURNED OFF, NOT ENOUGH COGS. waitcnt(80_000_000 + cnt) 'Wait for 1 s 'cognew(AxleRotation, @SmokeStack2) ' Axle sensor. 'Cog #4 NO NEED FOR AXLE SENSOR WITH NO SOUND. cognew(Comms, @SmokeStack3) 'Cog #5 MotorFwdFull 'Start motor drive. (Cog #1) PUB MotorFwdFull dira[M1IN1]~~ ' Set direction to output (Controls for Motor 1) dira[M1IN2]~~ ' Set direction to output (Controls for Motor 1) dira[M1D1]~~ ' Set direction to output (Controls for Motor 1) dira[M1D2]~~ ' Set direction to output (Controls for Motor 1) dira[SLEW]~~ ' Set direction to output (Slew Controls for Motor 1 and 2) dira[EN]~~ ' Set direction to output (Enable Carrier Board) dira[VDD]~~ ' Set direction to output (Enable Carrier Board) outa[VDD] := 1 ' Set Pin VDD to high to enable PULL up resistors, NEVER connect this to VIN. ' outa[Slew] := 1 ' Set Pin SLEW Output slew rate selection input. A logical LOW results in a slow output rise time (1.5 us - 6 us). ' A logical HIGH selects a fast output rise time (0.2 us - 1.45 us). ' This pin should be set HIGH for high-frequency (over 10 kHz) PWM. This pin determines the slew rate mode for both motor driver ICs. ' Setting this to a 1 with a duty of 1000 also works. outa[M1IN1] := 0 ' The logic input control of OUT2. PWM can be applied to this pin (typically done with both disable lines inactive) Reversing the setings on Pins M1IN1 & M1IN2 will reverse motor direction outa[M1IN2] := 1 ' The logic input control of OUT1. PWM can be applied to this pin (typically done with both disable pins inactive) Reversing the setings on Pins M1IN1 & M1IN2 will reverse motor direction 'outa[M1D1] := 1 ' Disable input: when D1 is high, OUT1 and OUT2 are set to high impedance. ' A D1 PWM duty cycle of 70% gives a motor duty cycle of 30%. ' Typically, only one of the two disable pins is used, but the default is for both disable pins to be active. 'outa[M1D2] := 1 ' Disable input: when D1 is high, OUT1 and OUT2 are set to high impedance. 'A D1 PWM duty cycle of 70% gives a motor duty cycle of 30%. 'Typically, only one of the two disable pins is used, but the default is for both disable pins to be active outa[EN] := 1 ' Set Pin (EN)to high to enable carrier board pwm1.start(M1D1) 'Cog #6 pwm2.start(M1D2) 'Cog #7 pwm1.SetPeriod(MotorFreq) pwm2.SetPeriod(MotorFreq) repeat waitcnt(80_000_000 + cnt) 'wait 1 second before next update If Speed > 100 Speed := 0 If CurrentSpeed > 100 CurrentSpeed := 0 If CurrentDuty > 100 CurrentDuty := 0 If Speed <> CurrentSpeed repeat CurrentDuty from CurrentSpeed to Speed 'linearly advance speed pwm1.SetDuty(CurrentDuty) pwm2.SetDuty(CurrentDuty) 'repeat 1 waitcnt(80_000_000 + cnt) 'wait 1 second before next update CurrentSpeed := Speed Pub Comms dira[TX]~~ ' Set direction to output outa[TX]:= 0 ' Set TX low. waitcnt(1_000_000 + cnt) 'wait 1/10 second for command mode to start in the module. dira[TX]~ ' Set direction to input ser.StartRxTx(RX, TX, 0, 115200) 'Cog #8 Parallax Serial Terminal does NOT work at receiving data 230400 for some reason. waitcnt(1_000_000 + cnt) 'wait 1/10 second for serial to start. ' ser.rxflush ser.char(254) 'Begin marker ser.str(string("LISTEN:HTTP,/motor")) 'Tell the module to listen to a specific path on http port 80. ser.char(13) 'End marker waitcnt(1_000_000 + cnt) 'Wait for 1/10 s Let buffer fill. Reply[0] := ser.rxcheck ' should be 254 Reply[1] := ser.rxcheck ' should be = Reply[2] := ser.rxcheck ' should be S Reply[3] := ser.rxcheck ' should be , Reply[4] := ser.rxcheck ' should be 1 Use this returned listener id with PATH or CLOSE commands. ' There are a maximum of four listeners available. ' Issuing additional LISTEN commands when all four listeners are already established, ' will result in a response of b = E,4 E (NO_FREE_LISTENER) until a CLOSE command is used to free a listener. Reply[5] := ser.rxcheck ' should be 13 If Reply[0] == 254 And Reply[1] == "=" And Reply[2] == "S" And Reply[3] == "," And Reply[4] == "1" And Reply[5] == 13 MotorListener := Reply[4] Else ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[2;3f")) 'Set Position in putty. ser.str(string("ERROR, wrong motor listener returned.")) 'Tell putty error. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[1;1f")) 'Set Position in putty to put cursor at 0 Repeat waitcnt(80_000_000 + cnt) 'Wait for 1s forever. Reply[0] := 0 ' clear data Reply[1] := 0 ' clear data Reply[2] := 0 ' clear data Reply[3] := 0 ' clear data Reply[4] := 0 ' clear data Reply[5] := 0 ' clear data ser.rxflush ser.char(254) 'Begin marker ser.str(string("LISTEN:HTTP,/leds")) 'Tell the module to listen to a specific path on http port 80. ser.char(13) 'End marker waitcnt(1_000_000 + cnt) 'Wait for 1/10 s Let buffer fill. Reply[0] := ser.rxcheck ' should be 254 Reply[1] := ser.rxcheck ' should be = Reply[2] := ser.rxcheck ' should be S Reply[3] := ser.rxcheck ' should be , Reply[4] := ser.rxcheck ' should be 2 Use this returned listener id with PATH or CLOSE commands. ' There are a maximum of four listeners available. ' Issuing additional LISTEN commands when all four listeners are already established, ' will result in a response of b = E,4 E (NO_FREE_LISTENER) until a CLOSE command is used to free a listener. Reply[5] := ser.rxcheck ' should be 13 If Reply[0] == 254 And Reply[1] == "=" And Reply[2] == "S" And Reply[3] == "," And Reply[4] == "2" And Reply[5] == 13 LedsListener := Reply[4] Else ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[2;3f")) 'Set Position in putty. ser.str(string("ERROR, wrong leds listener returned.")) 'Tell putty error. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[1;1f")) 'Set Position in putty to put cursor at 0 Repeat waitcnt(80_000_000 + cnt) 'Wait for 1s forever. Reply[0] := 0 ' clear data Reply[1] := 0 ' clear data Reply[2] := 0 ' clear data Reply[3] := 0 ' clear data Reply[4] := 0 ' clear data Reply[5] := 0 ' clear data ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[2;3f")) 'Set Position in putty. ser.str(string("Prop Communication Started")) 'Tell putty command mode is on. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[1;1f")) 'Set Position in putty to put cursor at 0 Repeat 10 ' wait 10 seconds to help determine if motor reset prop. waitcnt(80_000_000 + cnt) 'wait 1 second Repeat 'The main repeat loop. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[2J")) 'Clear putty telnet screen. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[2;3f")) 'Set Position in putty. ser.str(string("Command Mode is On. ")) 'Tell putty command mode is on. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[1;1f")) 'Set Position in putty to put cursor at 0 ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[4;3f")) 'Set Position in putty If ReplyStatus == 1 ser.str(string("Good reply.")) 'If last reply was good, put it back up on putty which was cleared. Else ser.str(string(" No reply.")) 'If last reply was bad, put it back up on putty which was cleared. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[5;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("Speed that the webpage sent: ")) ' ser.dec(Speed) ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[6;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("Current Duty: ")) ' ser.dec(CurrentDuty) ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[7;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("Headlight is: ")) ' If outa[Headlight] == 1 ser.str(string("On ")) ' Else ser.str(string("Off")) ' ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[8;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("Rearlight is: ")) ' If outa[Rearlight] == 1 ser.str(string("On ")) ' Else ser.str(string("Off")) ' ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[9;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("Smoker is: ")) ' If outa[Smoker] == 1 ser.str(string("On ")) ' Else ser.str(string("Off")) ' ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[10;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("Whistle is: ")) ' If Whistle == 1 ser.str(string("On ")) ' Else ser.str(string("Off")) ' ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[11;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("Bell is: ")) ' If Bell == 1 ser.str(string("On ")) ' Else ser.str(string("Off")) ' ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[12;3f")) 'Set Position in putty to put cursor at 0 ser.str(string("StackTalk is: ")) ' If StackTalk == 1 ser.str(string("On ")) ' Else ser.str(string("Off")) ' ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[1;1f")) 'Set Position in putty to put cursor at 0 ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[1;1f")) 'Set Position in putty to put cursor at 0 ser.char(13) 'End marker ReplyStatus := 0 'Set the reply to bad so it can recheck for a new reply. Reply[0] := 0 ' clear data Reply[1] := 0 ' clear data Reply[2] := 0 ' clear data Reply[3] := 0 ' clear data Reply[4] := 0 ' clear data Reply[5] := 0 ' clear data Reply[6] := 0 ' clear data Reply[7] := 0 ' clear data Repeat 200 Reply[0] := 0 ' clear data Reply[1] := 0 ' clear data Reply[2] := 0 ' clear data Reply[3] := 0 ' clear data Reply[4] := 0 ' clear data Reply[5] := 0 ' clear data Reply[6] := 0 ' clear data Reply[7] := 0 ' clear data ser.rxflush ser.char(254) 'Begin marker ser.str(string("POLL:")) 'Tell the module to listen to a ANY protocol/path. ser.char(13) 'End marker waitcnt(1_000_000 + cnt) 'Wait for 1/10 s Let buffer fill. Reply[0] := ser.rxcheck ' should be 254 Reply[1] := ser.rxcheck ' should be = Reply[2] := ser.rxcheck ' should be P Reply[3] := ser.rxcheck ' should be , Reply[4] := ser.rxcheck ' should be 5 (this could change) The connection identifier to use for this request Reply[5] := ser.rxcheck ' should be , Reply[6] := ser.rxcheck ' should be 1 or a 2. Use this returned listener id with PATH or CLOSE commands. ' There are a maximum of four listeners available. ' Issuing additional LISTEN commands when all four listeners are already established, ' will result in a response of b = E,4 E (NO_FREE_LISTENER) until a CLOSE command is used to free a listener. Reply[7] := ser.rxcheck ' should be 13 If Reply[0] == 254 And Reply[1] == "=" And Reply[2] == "P" And Reply[6] == MotorListener And Reply[7] == 13 ReplyStatus := 1 'Set the reply to good so it can be shown in putty. Handle := Reply[4] 'Store connection identifier. Reply[0] := 0 ' clear data Reply[1] := 0 ' clear data Reply[2] := 0 ' clear data Reply[3] := 0 ' clear data Reply[4] := 0 ' clear data Reply[5] := 0 ' clear data Reply[6] := 0 ' clear data Reply[7] := 0 ' clear data ser.rxflush ser.char(254) 'Begin marker ser.str(string("ARG:")) 'Retrieve HTTP GET/POST’s name argument (in query or body) on connection handle. ser.char(Handle) 'An active connection handle; returned by POLL ser.str(string(",")) 'Required for a reply ser.str(string(" Speed ")) 'The argument name to retrieve. ser.char(13) 'End marker waitcnt(1_000_000 + cnt) 'Wait for 1/10 s Let buffer fill. Reply[0] := ser.rxcheck ' should be 254 Reply[1] := ser.rxcheck ' should be = Reply[2] := ser.rxcheck ' should be S Reply[3] := ser.rxcheck ' should be , Reply[4] := ser.rxcheck ' should be argument value (this could change) -1 no reply Reply[5] := ser.rxcheck ' should be argument value (this could change) -1 no reply. This could also be 13 Reply[6] := ser.rxcheck ' should be argument value (this could change) -1 no reply. This could also be 13 Reply[7] := ser.rxcheck ' should be 13 If Reply[0] == 254 And Reply[1] == "=" And Reply[2] == "S" If Reply[5] == 13 'The end marker Reply[5] := 0 'Zero terminate the string so it can be converted to decimal. Elseif Reply[6] == 13 'The end marker Reply[6] := 0 'Zero terminate the string so it can be converted to decimal. Else 'The end marker all other conditions the end marker is a byte 7 Reply[7] := 0 'Zero terminate the string so it can be converted to decimal. Speed := ser.StrToBase(@word[@Reply[4]], 10) ' store and convert string angle in byte variable angle. ser.char(254) 'Begin marker ser.str(string("REPLY:")) 'Tell the module to send a reply to the poll response. ser.char(Handle) 'Should be a number. An active connection handle; returned by POLL. ser.str(string(",")) 'Required for a reply ser.str(string("200")) 'The desired HTTP response code for the reply. ser.str(string(",")) 'Required for a reply ser.str(string("2")) 'Tell the module how many bytes? (or is this digits?) the reply is. ser.char(13) 'End marker ser.str(string("OK")) 'Send OK to the webpage. If Reply[0] == 254 And Reply[1] == "=" And Reply[2] == "P" And Reply[6] == LedsListener And Reply[7] == 13 ReplyStatus := 1 'Set the reply to good so it can be shown in putty. Handle := Reply[4] 'Store connection identifier. Reply[0] := 0 ' clear data Reply[1] := 0 ' clear data Reply[2] := 0 ' clear data Reply[3] := 0 ' clear data Reply[4] := 0 ' clear data Reply[5] := 0 ' clear data Reply[6] := 0 ' clear data Reply[7] := 0 ' clear data ser.rxflush ser.char(254) 'Begin marker ser.str(string("ARG:")) 'Retrieve HTTP GET/POST’s name argument (in query or body) on connection handle. ser.char(Handle) 'An active connection handle; returned by POLL ser.str(string(",")) 'Required for a reply ser.str(string("io")) 'The argument name to retrieve. ser.char(13) 'End marker waitcnt(1_000_000 + cnt) 'Wait for 1/10 s Let buffer fill. Reply[0] := ser.rxcheck ' should be 254 Reply[1] := ser.rxcheck ' should be = Reply[2] := ser.rxcheck ' should be S Reply[3] := ser.rxcheck ' should be , Reply[4] := ser.rxcheck ' should be p. Argument value (this could change) -1 no reply Reply[5] := ser.rxcheck ' should be i. Argument value (this could change) -1 no reply. Reply[6] := ser.rxcheck ' should be n. Argument value (this could change) -1 no reply. Reply[7] := ser.rxcheck ' should be #. 0 to 6 Argument value (this could change) -1 no reply Reply[8] := ser.rxcheck ' should be s. Argument value (this could change) -1 no reply. Reply[9] := ser.rxcheck ' should be t. Argument value (this could change) -1 no reply. Reply[10] := ser.rxcheck ' should be a. Argument value (this could change) -1 no reply Reply[11] := ser.rxcheck ' should be t. Argument value (this could change) -1 no reply. Reply[12] := ser.rxcheck ' should be e. Argument value (this could change) -1 no reply. Reply[13] := ser.rxcheck ' should be #. 1 or 0 Argument value (this could change) -1 no reply. ' Reply[14] := ser.rxcheck ' should be 13 If Reply[0] == 254 And Reply[1] == "=" And Reply[2] == "S" If Reply[7] == "0" 'The pin number. Headlight If Reply[13] == "0" 'The state of the pin outa[Headlight] := 0 Else outa[Headlight] := 1 Elseif Reply[7] == "1" 'The pin number. Rearlight If Reply[13] == "0" 'The state of the pin outa[RearLight] := 0 Else outa[RearLight] := 1 Elseif Reply[7] == "2" 'The pin number. Smoker If Reply[13] == "0" 'The state of the pin outa[Smoker] := 0 Else outa[Smoker] := 1 Elseif Reply[7] == "3" 'The pin number. If Reply[13] == "0" 'The state of the pin Whistle := 0 Else Whistle := 1 Elseif Reply[7] == "4" 'The pin number. If Reply[13] == "0" 'The state of the pin Bell := 0 Else Bell := 1 Elseif Reply[7] == "5" 'The pin number. If Reply[13] == "0" 'The state of the pin StackTalk := 0 Else StackTalk := 1 Else ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[2;3f")) 'Set Position in putty. ser.str(string("ERROR, wrong leds pin returned.")) 'Tell putty error. ser.str(string(27)) 'Set ansi command mode in putty. ser.str(string("[1;1f")) 'Set Position in putty to put cursor at 0 Repeat waitcnt(80_000_000 + cnt) 'Wait for 1s forever. ser.char(254) 'Begin marker ser.str(string("REPLY:")) 'Tell the module to send a reply to the poll response. ser.char(Handle) 'Should be a number. An active connection handle; returned by POLL. ser.str(string(",")) 'Required for a reply ser.str(string("200")) 'The desired HTTP response code for the reply. ser.str(string(",")) 'Required for a reply ser.str(string("2")) 'Tell the module how many bytes? (or is this digits?) the reply is. ser.char(13) 'End marker ser.str(string("OK")) 'Send OK to the webpage. 'ser.char(13) 'End marker 'Repeat 5 'waitcnt(10_000_000 + cnt) 'Wait for 1/10 s 'Repeat 5 'waitcnt(10_000_000 + cnt) 'Wait for 1/10 s 'Repeat 5 'waitcnt(20_000_000 + cnt) 'Wait for 1 s 'ser.Str(string("WAV Error: ")) 'ser.Str(result) 'ser.Tx(10) 'ser.Tx(13) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[3;3f")) 'Set Position 'ser.Str(string("/ Chuff ")) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[1;1f")) 'Set Position 'ser.str(string(27)) 'Set command mode 'ser.str(string("[3;3f")) 'Set Position 'ser.Str(string("- Chuff")) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[1;1f")) 'Set Position 'ser.str(string(27)) 'Set command mode 'ser.str(string("[3;3f")) 'Set Position 'ser.Str(string("\ Chuff ")) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[1;1f")) 'Set Position 'ser.str(string(27)) 'Set command mode 'ser.str(string("[3;3f")) 'Set Position 'ser.Str(string("| Chuff")) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[1;1f")) 'Set Position 'ser.str(string(27)) 'Set command mode 'ser.str(string("[4;23f")) 'Set Position 'ser.str(string(" ")) 'Set Position 'ser.str(string(27)) 'Set command mode 'ser.str(string("[4;23f")) 'Set Position 'ser.dec(CurrentDuty) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[5;24f")) 'Set Position 'ser.str(string(" ")) 'Set Position 'ser.str(string(27)) 'Set command mode 'ser.str(string("[5;24f")) 'Set Position 'ser.dec(ChuffCount) 'ser.str(string(27)) 'Set command mode 'ser.str(string("[6;13f")) 'Set Position 'ser.str(string(" ")) 'Set Position 'ser.str(string(27)) 'Set command mode 'ser.str(string("[6;13f")) 'Set Position 'ser.dec(WaitTime) Pub AxleRotation | a, Time1, Time2 'Axle sensor routine. MY AXLE SENSOR SUCKS! IT BOUNCES WAYYYY TOO MUCH. ChuffCount := 1 dira[AxleSense]~ 'Set axle sensor direction to input Repeat If Entry == 1 ChuffCount++ Entry := 0 If ChuffCount > 4 ChuffCount := 1 WaitTime := 0 Repeat while WaitTime < 5_000_000 Time1 := cnt 'grab clock tick counter value ' 'waitpeq(%0000, |< 3, 0) 'Then wait for Pin 5 to go low ' waitpeq(%1000, |< 3, 0) 'Wait for Pin 5 to go high 'waitpeq(%0000, |< 3, 0) 'Then wait for Pin 5 to go low ' Time2 := cnt WaitTime := Time2 - Time1 { Time1 := cnt 'Get current system counter value waitpeq(|< AxleSense, |< AxleSense, 0) 'Wait for Pin to go high waitpeq(|< AxleSense, |< AxleSense, 0) 'Wait for Pin to go low Time2 := cnt 'Get current system counter value WaitTime := Time2 - Time1 } PUB Chuff repeat If ChuffCount == 1 And Entry == 0 wav1.overrideSong(true) wav1.overrideSong(false) result := \wav1.play(string("chuff1.wav")) Entry := 1 If ChuffCount == 2 And Entry == 0 wav1.overrideSong(true) wav1.overrideSong(false) result := \wav1.play(string("chuff2.wav")) Entry := 1 If ChuffCount == 3 And Entry == 0 wav1.overrideSong(true) wav1.overrideSong(false) result := \wav1.play(string("chuff3.wav")) Entry := 1 If ChuffCount == 4 And Entry == 0 wav1.overrideSong(true) wav1.overrideSong(false) result := \wav1.play(string("chuff4.wav")) Entry := 1 If(wav1.playErrorNum) Repeat DAT Whistle byte 0 'this byte holds the whisle on or off Bell byte 0 'this byte holds the bell on or off StackTalk byte 0 'this byte holds the stacktalk on or off Speed byte 0 CurrentDuty byte 0 CurrentSpeed byte 0 ChuffCount long 0 Entry byte 0 WaitTime long 0 'Byte[#] '0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 18 20 Reply byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 {{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TERMS OF USE: MIT License /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the // Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}