Object "s2" Interface: PUB start PUB start_motors PUB start_tones PUB start_mic_env PUB stop_all PUB get_mic_env PUB begin_path PUB end_path PUB set_speed(spd) PUB move_to(x, y) PUB arc_to(x, y, radius) PUB move_by(dx, dy) PUB arc_by(dx, dy, radius) PUB align_with(heading) PUB turn_to_deg(heading) PUB turn_to(heading) PUB turn_by_deg(dw) PUB turn_by(dw) PUB here_is(x, y) PUB heading_is_deg(w) PUB heading_is(w) PUB go_left(dist) PUB go_right(dist) PUB go_forward(dist) PUB go_back(dist) PUB turn_deg(ccw_degrees) PUB arc_deg(ccw_degrees, radius) PUB turn(ccw_units) PUB arc(ccw_units, radius) PUB move(left_distance, right_distance, move_time, max_speed, no_stop) PUB wheels_now(left_velocity, right_velocity, move_time) PUB move_now(left_distance, right_distance, move_time, max_speed, no_stop) PUB stop_now PUB wait_stop PUB stalled PUB moving PUB motion PUB motion_addr PUB move_ready PUB run_motors(command, left_distance, right_distance, timeout, max_speed, end_speed) PUB obstacle(side) PUB line_sensor(side, threshold) PUB light_sensor(side) PUB light_sensor_raw(side) PUB get_adc_results(index) PUB button_press PUB button_count PUB reset_button_count PUB button_mode(led_enable, reset_enable) PUB set_leds(left_color, center_color, right_color, power_color) PUB set_led(index, color) PUB beep PUB command_tone(cmd_tone) PUB set_volume(vol) PUB set_voices(v1, v2) PUB play_sync(value) PUB play_pause(value) PUB get_sync PUB play_tone(time, frq1, frq2) PUB play_tones(addr) PUB wait_sync(value) PUB start_timer(number) PUB get_timer(number) PUB delay_tenths(time) PUB ee_read_byte(addr) PUB ee_write_byte(addr, data) Program: 1,537 Longs Variable: 0 Longs -------[ Start and stop methods ]-------------------------------------------- Start and stop methods are used for starting individual cogs or stopping all of them at once. __________ PUB start Main start routine for S2 object. Stops ALL cogs, so IT MUST BE CALLED FIRST, before starting other cogs. Example: s2.start 'Start s2 object. _________________ PUB start_motors Start motor control cog. Example: s2.start_motors 'Start the motor controller. ________________ PUB start_tones Start tone sequencer. Example: s2.start_tones 'Start the tone sequencer/generator. __________________ PUB start_mic_env Start microphone Envelope detector. Example: s2.start_mic_env 'Start the microphone Envelope detector. _____________ PUB stop_all Stop ALL cogs. Example: s2.stop_all 'Stop all S2 cogs. -------[ Microphone methods ]------------------------------------------------ Microphone methods provide data from the S2's built-in microphone. ________________ PUB get_mic_env Get the average loudness (Envelope) value of the microphone input. Example: loudness := s2.get_mic_env 'Set loudness equal to current mic level. -------[ Drawing methods ]--------------------------------------------------- Drawing methods can be used for drawing with the S2 or for any application that requires keeping track of the robot's position and heading. _______________ PUB begin_path Begin a path of connected movements. Example: s2.begin_path _____________ PUB end_path Output the last movement in the path, if there is one, and end the path. NOTE: Omitting this statement may cause the last path segment not to be drawn. Example: s2.end_path ___________________ PUB set_speed(spd) Set the speed (0 - 15) for the drawing methods, along with the "go_", "turn_", and "arc_" motion methods. Example: set_speed(7) 'Set the speed to half of maximum velocity. __________________ PUB move_to(x, y) Move directly to the point (x, y). Units are approximately 0.5mm. Example: s2.move_to(1000, 50) 'Move to a point 500 mm to the right and 25mm above the origin. _________________________ PUB arc_to(x, y, radius) Move to the point (x, y) via an arc of the specified radius (+radius is CCW; -radius is CW). The Cartesian distance from the current location to the target position must be no more than 2 * radius. If it's greater than that, the robot will move in a straight line to the target position first to make up the difference, then perform the arc. Units are approximately 0.5mm. Example: s2.arc_to(1000, 50, -100) 'Move to the point 500 mm to the right and 25mm above the origin ' in a clockwise arc of radius 25mm. ____________________ PUB move_by(dx, dy) Move from the current location by the displacement (dx, dy). Units are approximately 0.5mm. Example: s2.move_by(100, 50) 'Move to a point 50 mm to the right and 25mm above the current location. ___________________________ PUB arc_by(dx, dy, radius) Move from the current location byt the displacement (dx, dy) via an arc of the specified radius (+radius is CCW; -radius is CW). The Cartesian length of the displacement must be no more than 2 * radius. If it's greater than that, the robot will move in a straight line to the target position first to make up the difference, then perform the arc. Units are approximately 0.5mm. Example: s2.arc_by(50, 50, -100) 'Move to the point 25 mm to the right of and 25mm above the ' current location in a clockwise arc of radius 50mm. ________________________ PUB align_with(heading) Turn so that the robot is pointed parallel to the desired heading (S2 angle units), either in the selected direction (returns 1) or opposite the selected direction (returns -1), whichever requires the shortest turn to achieve. Example: dir := s2.align_with(150) 'Point the robot to angle 150 (S2 angle units) ' or opposite that angle. Set dir to ±1, accordingly. _________________________ PUB turn_to_deg(heading) Turn the robot to the desired heading (degrees). Example: s2.turn_to(135) 'Point the robot to an angle of 135 degrees. _____________________ PUB turn_to(heading) Turn the robot to the desired heading (S2 angle units). Example: s2.turn_to(500) 'Point the robot to an angle of 500 S2 angle units. ____________________ PUB turn_by_deg(dw) Turn the robot by the desired amount (degrees). +dw is CCW; -dw is CW. If the net turn angle is greater than 180 degrees, the shorter rotation in the opposite direction is used instead. Example: s2.turn_by_deg(90) 'Rotate the robot by an angle of 90 degrees CCW. ________________ PUB turn_by(dw) Turn the robot by the desired amount (S2 angle units). +dw is CCW; -dw is CW. If the net turn angle is greater than FULL_CIRCLE / 2, the shorter rotation in the opposite direction is used instead. Example: s2.turn_by(500) 'Rotate the robot by an angle of 500 S2 angle units CCW. __________________ PUB here_is(x, y) Reset the current position to (x,y). Units are approximately 0.5mm. Example: s2.here_is(0, 0) 'Reset the origin to the current location. ______________________ PUB heading_is_deg(w) Reset the current heading to w degrees. Example: s2.heading_is_deg(90) 'Reset the current heading to 90 degrees. __________________ PUB heading_is(w) Reset the current heading to w degrees. Example: s2.heading_is_deg(90) 'Reset the current heading to 90 degrees. -------[ Motion methods ]---------------------------------------------------- Motion methods control the movement of the S2 robot. MOTION METHODS DO NOT KEEP TRACK OF THE S2'S POSITION AND HEADING, unless called from one of the drawing methods. As such, they should NOT be mixed with calls to drawing methods. __________________ PUB go_left(dist) Turn left and go forward from there by the indicated distance. Units are approximately 0.5mm. Example: s2.go_left(500) 'Turn left and move forward 250mm. ___________________ PUB go_right(dist) Turn right and go forward from there by the indicated distance. Units are approximately 0.5mm. Example: s2.go_right(500) 'Turn right and move forward 250mm. _____________________ PUB go_forward(dist) Go forward by the indicated distance. Units are approximately 0.5mm. Example: s2.go_forward(500) 'Move forward 250mm. __________________ PUB go_back(dist) Go backward by the indicated distance. Units are approximately 0.5mm. Example: s2.go_back(500) 'Move back 250mm. __________________________ PUB turn_deg(ccw_degrees) Turn in place counter-clockwise by the indicated number of degrees. Negative values will turn clockwise. Example: s2.turn_deg(-90) 'Turn right. _________________________________ PUB arc_deg(ccw_degrees, radius) Move in a counter-clockwise arc of the indicated radius by the specified number of degrees. Radius units are approximately 0.5mm. Negative angles result in a clockwise arc. Example: s2.arc_deg(90, 500) 'Make a sweeping left turn with a radius of 250mm. ____________________ PUB turn(ccw_units) Turn in place counter-clockwise by the indicated number of degrees. Negative values will turn clockwise. Example: s2.turn(-50) 'Turn a bit to the right by 50 S2 angle units. ___________________________ PUB arc(ccw_units, radius) Move in a counter-clockwise arc of the indicated radius by the specified number of S2 angle units. Radius units are approximately 0.5mm. Negative angles result in a clockwise arc. Example: s2.arc(100, 50) 'Arc a bit to the left by 100 S2 angle units with ' a 25mm radius. _______________________________________________________________________ PUB move(left_distance, right_distance, move_time, max_speed, no_stop) Base-level non-reactive user move routine. Does not interrupt motion in progress. If called during path construction, velocities will blend. If no path, velocity ramps to zero at end. This method may not return right away if it has to wait for current motion to complete. left_distance: Amount to move left wheel (-32767 - 32767) in 0.5mm (approx.) increments. right_distance: Amount to move right wheel (-32767 - 32767) in 0.5mm (approx.) increments. move_time: If non-zero, time (ms) after which to stop, regardless of distance traveled. max_speed (0 - 15): Maximum speed (after ramping). no_stop: If non-zero, keep running, regardless of distance traveled unless/until timeout or a preemptive change. Example: s2.move(10000, 5000, 10000, 7, 0) 'Move in a clockwise arc for 10000/2 mm on outside, or until 10 seconds elapse, ' whichever occurs first, at half speed. _________________________________________________________ PUB wheels_now(left_velocity, right_velocity, move_time) Set the wheel speeds preemptively to left_velocity and right_velocity (-255 to 255). If move_time > 0, time out after move_time ms. Interrupts any movement in progress and deletes all path information. This method always returns immediately. Example: s2.wheels_now(-255, 255, 5000) 'Turn left, in place, at maximum speed, for five seconds. ___________________________________________________________________________ PUB move_now(left_distance, right_distance, move_time, max_speed, no_stop) Base-level preemptive user routine for reactive movements (e.g. for line following). Interrupts any movement in progress and deletes all path information. This method always returns immediately. left_distance: Amount to move left wheel (-32767 - 32767) in 0.5mm (approx.) increments. right_distance: Amount to move right wheel (-32767 - 32767) in 0.5mm (approx.) increments. move_time: If non-zero, time (ms) after which to stop, regardless of distance traveled. max_speed (0 - 15): Maximum speed (after ramping). no_stop: If non-zero, keep running, regardless of distance traveled unless/until timeout or another preemptive change. Example: s2.move_now(1000, -1000, 0, 15, 1) 'Rotate in place clockwise at full speed until preempted. _____________ PUB stop_now Stops movement immediately and deletes all path information. Example: s2.stop_now. ______________ PUB wait_stop Wait for all current and pending motions to complete. Example: s2.wait_stop ____________ PUB stalled Checks whether the S2 is stalled by testing both the motor current and the activitity of the idler wheel encoder. Returns true if stalled; false if not. ___________ PUB moving Return TRUE if motion in progress or pending, FALSE if stopped with no pending motions. Example: repeat while s2.moving 'Continuously execute the following repeat block until motions are finished. ___________ PUB motion Return current motion status: 31 24 23 16 15 8 7 2 1 0 +---------------------------------------------------------------+ ¦± Left wheel ¦± Right wheel ¦ Idler timer ¦ Idler spd ¦Mov¦ , where +---------------------------------------------------------------+ Left wheel and right wheel are signed, twos complement eight bit velocity values, Idler timer is the time in 1/10 second since the last idler edge, Idler spd is an unsigned six-bit velocity value, and Mov is non-zero iff one or more motors are turning. Left and right wheel velocities are instanteous encoder counts over a 1/10-sceond interval. Idler wheel wheel velocity is updated every 1/10 second and represents the idler encoder count during the last 1.6 seconds. Example: left_vel := s2.motion ~> 24 'Get the current left wheel velocity as a signed 32-bit value. ________________ PUB motion_addr Return the address of the status and debug array. Example: longmove(@my_stats, s2.motion_addr, 6) 'Copy all status data to the local array my_stats. _______________ PUB move_ready Return TRUE if a new motion command can be accepted without waiting, FALSE if a command is still pending. Example: repeat until s2.move_ready 'Continuously execute the following repeat block until a new move can be accepted. ______________________________________________________________________________________ PUB run_motors(command, left_distance, right_distance, timeout, max_speed, end_speed) Base level motor activation routine. Normally, this method is not called by the user but is called by the several convenience methods available to the user. command: the OR of any or all of the following: MOT_IMM: Commanded motion starts immediately, without wating for prior motion to finish. MOT_CONT: Commanded motion will continue to run at wheel ratio given by left and right distances, even after distances are covered. left_distance, right_distance (-32767 to 32767): are the distances to be covered by the left and right wheels, respectively. Units are approximately 0.5mm. timeout (0 - 65535): If non-zero, time limit (ms) after which motion stops, regardless of distance covered. max_speed (0 - 15): Peak velocity to be reached during motion profile. end_speed (0 - 15): Velocity to be attained at end of motion profile. If non-zero, this is the velocity needed to segue smoothly into the next motion profile. end_speed should never be greater than max_speed. Example: s2.run_motors(s2#MOT_CONT | s2#MOT_TIMED, 100, -100, 5000, 8, 0) 'Turn in place clockwise for 5 seconds at half speed. -------[ Sensor methods ]---------------------------------------------------- Sensor methods return information about the S2's various onboard sensors. ___________________ PUB obstacle(side) Return the value of the obstacle detection for side: (LEFT or RIGHT). Return: FALSE == no obstacle; TRUE == obstacle. Example: obstacle_both := s2.obstacle(s2#LEFT) and s2.obstacle(s2#RIGHT) 'Obstacle_both set on left AND right obstacles. _________________________________ PUB line_sensor(side, threshold) If threshold => 0 Return the value of the line sensor on side (LEFT or RIGHT), compared to the threshold. (If threshold is zero, substitute 64.) Return: false == dark; true == light If threshold < 0 Return analog value of line sensor. Example: if (s2.line_sensor(s2#LEFT, 0)) 'IF block executed if left line sensor seeing default bright reflection. _______________________ PUB light_sensor(side) ___________________________ PUB light_sensor_raw(side) Return the value of the light sensor on side (LEFT, CENTER, or RIGHT). Example: if (s2.light_sensor(s2#LEFT) > s2.light_sensor(s2#RIGHT)) 'IF block executed if left is brighter than right. ___________________________ PUB get_adc_results(index) General accessor for ADC Results array. Example: battery_level := s2.get_adc_results(s2#ADC_VBAT) 'Query the battery voltage and save in battery_level. -------[ Button methods ]---------------------------------------------------- Button methods control and sense the user's interaction with the S2's push button. _________________ PUB button_press Return true if button is down, false if button is up. Example: if(s2.button_press) 'IF block executed if button is down. _________________ PUB button_count Get the last count of button presses (0 - 8). Then zero the count. Example: button_presses := s2.button_count 'Button_presses is set to the recent button press count, which is then zeroed. _______________________ PUB reset_button_count Return the reset button count (0- 8). Zero indicates a power-on or PC-initiated reset. Example: reset_button_presses := s2.reset_button_count 'Reset_button_presses is set to the button press count that caused the reset. __________________________________________ PUB button_mode(led_enable, reset_enable) Set button LED and reset modes: led_enable == TRUE: Take over LEDs to echo button press number. reset_enable == TRUE: Record number of presses in EEPROM (up to 8), and reset Propeller after 1 second of no presses. Example: s2.button_mode(TRUE, FALSE) 'Set the button mode, enabling the LED indicator, but disabling resets. -------[ LED methods ]------------------------------------------------------- LED methods control the red/green user LEDs and blue power LED. _________________________________________________________________ PUB set_leds(left_color, center_color, right_color, power_color) Sets all LEDs for which the color argument <> NO_CHANGE (-1). See the above constants for predefined indices and colors. Example: s2.set_leds(s2#RED, s2#NO_CHANGE, s2#BLINK_GREEN, s2#OFF) 'Set LEDs (L to R): RED, same, blinking GREEN, off. __________________________ PUB set_led(index, color) Light up a user LED using color value as follows: Index = 0 or 4:Power, 1:Left, 2:Right, 3:Center Color: +-------------------------------+ ¦ Red ¦ Green ¦ +-------------------------------+ 7 6 5 4 3 2 1 0 Each nybble represents the intensity (0-15) of the chosen color. If Red + Green =< 15, the colors are blended. If red + green => 15, they're alternated at about 2 Hz. An intensity value of 1 is the same as 0. This allows blinking a single color, e.g. $1f or $f1. The power LED lights blue whenever red > 0. See the above constants for predefined indices and colors. Example: s2.set_led(s2#CENTER, s2#YELLOW) 'Set center LED to yellow. -------[ Sound methods ]----------------------------------------------------- Sound methods control the output from the S2's built-in speaker. _________ PUB beep Set volume level to 50%, and send a 150ms 1 KHz tone, followed by a 350ms pause. Example: s2.beep 'Make the speaker beep. ___________________________ PUB command_tone(cmd_tone) Send an immediate command (cmd_tone) to the sound cog: STOP: Stops sound production immediately, then clears the sound queue. PAUSE: Pauses sound production after the note currently being played. PLAY: Resumes sound production from the queue. Example: s2.command_tone(STOP) 'Cause sounds to cease immediately. ____________________ PUB set_volume(vol) Set the current volume level to vol (0 - 100) percent. Example: s2.set_volume(50) 'Set volume level to 50%. _______________________ PUB set_voices(v1, v2) Set voices for both channels (SQU, SAW, TRI, SIN) Example: s2.set_voices(s2#SIN, s2#TRI) 'Set voice 1 to sine wave; voice 2 to triangle wave. _____________________ PUB play_sync(value) Insert a SYNC command into the sound queue. When the sound processor encounters it, it writes value (0 - 255) to the hub variable Tone_sync, then continues. This method can use to synchronize motion to the sound being played. Example: s2.play_sync(12) 'Insert a SYNC 12 into the tone queue. 'When encountered during play, player will set the sync value to 12 '(for get_sync) and continue with the next command. ______________________ PUB play_pause(value) Insert a PAUS command into the sound queue. When the sound processor encounters it, it writes value (0 - 255) to the hub variable Tone_sync, then pauses. Example: s2.play_pause(12) 'Insert a PAUS 12 into the tone queue. 'When encountered during play, player will set the sync value to 12 '(for get_sync) and wait for a PLAY command to resume. _____________ PUB get_sync Get the current Tone_sync value. Example: current_sync := s2.get_sync 'Get the latest sync value written from tone queue while playing, 'then zero the value if it was non-zero. ________________________________ PUB play_tone(time, frq1, frq2) Send sound to speaker, mixing frq1 & frq2 (1 - 10000 Hz), using current voices and volume for time (0 - 8191 milliseconds). Example: s2.play_tone(1000, 440, 880) 'Play an A440 and A880 for 1000 milliseconds. _____________________ PUB play_tones(addr) Add a command sequence to the tone queue. Commands are of the following format: 15 13 12 0 +-------------------------------+ ¦ Cmd ¦ Data ¦ +-------------------------------+ Cmd: %000 Play tone for duration Data (0 - 8192ms),using the following TWO words as the voices, each having the following format: 15 14 13 0 +-------------------------------+ ¦Voc¦ Frequency ¦ +-------------------------------+ Voc (voice): 00 = square wave 01 = sawtooth wave 10 = triangle wave 11 = sine wave Frequency : 0 (no sound) to 16363 Hz. Cmd: %001 Set volume to Data << 3 (range 0 - 0.9998) Cmd: %010 Set sync to Data & $ff Cmd: %011 Set sync to Data & $ff, then PAUSE. Example: s2.play_tones(@tone_buffer) 'Add tones from tone_buffer (word array) to tone queue until a zero word is encountered. _____________________ PUB wait_sync(value) Wait for sync in queue to echo or for queue to become empty. Example: s2.wait_sync(12) 'Wait until a sync value of 12 is returned from the tone queue. -------[ Time methods ]------------------------------------------------------ Time methods control and sense the S2's built-in millisecond timers and provide a convenient delay function. ________________________ PUB start_timer(number) Start a 1 KHz count-up timer number (0 - 7), which counts up from zero by one every millisecond. Example: s2.start_timer(4) 'Restarts timer number four from zero. ______________________ PUB get_timer(number) Return the time (in milliseconds, up to 2 million seconds ~ 24 days) from the 1 KHz count-up timer number (0 - 7). If number is outside the range 0 - 7, return the value of the master timer, which starts at 0 when s2 is started. Example: elapsed_time := s2.get_timer(4) 'Get time elapsed since Propeller reset or timer restart. _______________________ PUB delay_tenths(time) Time delay in tenths of a second. Example: s2.delay_tenths(20) 'Wait a couple seconds. -------[ EEPROM methods ]---------------------------------------------------- EEPROM methods allow read/write access to the auxilliary 32Kbyte EEPROM. _______________________ PUB ee_read_byte(addr) Read byte from aux EEPROM at addr. Example: my_data := s2.ee_read_byte($2000) 'Set my_data equal to byte at location $2000 in auxilliary EEPROM. ______________________________ PUB ee_write_byte(addr, data) Write byte to aux EEPROM at addr, if addr is in user area. Example: s2.ee_write_byte(s2#USER_AREA + 5, 35) 'Write the value 35 to the sixth byte in the auxilliary EEPROM's user area.