' Perpetual Ball Roller - (c) unigamer@gmail.com 16/07/09 ' RELEASE 1.1 ' This is the code for a little desktop toy. Hard to explain in words ' so visit http://www.ohthebanter.com/perpetual_ball_roller ' You are free to use and modify this code but it would be nice if ' you could attribute it to me (unigamer@gmail.com). If you make one ' of these or something similar please email me, address at top of this. #picaxe 08m ' Code is written for Picaxe 08m (costs less than £2) 'But code would be easily adapatable to other chips in the Picaxe Series 'and the principals adapted to other microcontrollers disablebod symbol servo1 = 1 symbol potentiometer = 2 symbol mode_switch = 4 symbol switch_value = w0 symbol pot_value = w1 symbol pot_value_adjusted = w2 'The positions are from 1 - 9 and relate to how far it's tilted. '1 is tilted to one side maximum '5 is neutral '9 is tilted to the other side to the maximum symbol pos_1 = 160 symbol pos_2 = 150 symbol pos_3 = 140 symbol pos_4 = 130 symbol pos_5 = 120 symbol pos_6 = 111 symbol pos_7 = 103 symbol pos_8 = 94 symbol pos_9 = 86 ' This routine is regularly called upon to select off (sleep), ' manual mode or automaticmode mode_select: if b13 = 1 then wake_position readadc mode_switch, switch_value if switch_value < 6 then start_sleep if switch_value > 200 then manual_mode if switch_value < 200 then automatic_mode wake_position: servo servo1, pos_6 pause 2000 b13 = 0 goto routine_1 power_save: readadc mode_switch, switch_value if switch_value > 6 then mode_select sleep 6 goto power_save 'This routine is called before powersave and gets the machine ready for sleep start_sleep: pause 1000 ' This delay and the next few commands are to prevent it from going into sleep mode as you flick the switch accross readadc mode_switch, switch_value if switch_value > 6 then mode_select pause 4000 servo servo1, pos_4 ' I have it left tilted to the side without the join pause 2000 b13 = 1 goto power_save ' Manual mode is controlled by a potentiometer manual_mode: readadc potentiometer, pot_value pot_value_adjusted = pot_value * 10 / 17 + 75 if pot_value_adjusted < pos_9 then set_maximum ' These stop you going past the maximum and minimum values of the servo and mechanically breaking it if pot_value_adjusted > pos_1 then set_minimum goto set_servo_position ' If the value is fine just set the postion set_servo_position: servo servo1, pot_value_adjusted goto mode_select ' go and check what mode it should be in '----------- 'These two for use in manual mode where a user may use the 'potentiometer to get a value for servo pulse that would 'cause it to mechanically break. The code prevents this 'from happening by setting value to maximum/minimum set_maximum: pot_value_adjusted = pos_9 goto set_servo_position set_minimum: pot_value_adjusted = pos_1 goto set_servo_position '----------- '------------------------------------------------------------------ ' Automatic Mode allows the machine to run without any user input ' There are a number of different routines that can be selected by ' Changing the potentiometer automatic_mode: readadc potentiometer, pot_value if pot_value < 50 then routine_1 if pot_value < 100 then routine_2 if pot_value < 150 then routine_3 if pot_value < 200 then routine_4 if pot_value > 200 then random_routine goto mode_select ball_rolling: 'This routine is the used as routine 1 and is used to servo servo1, pos_3 'get the ball moving so it won't fall off pause 375 servo servo1, pos_7 pause 375 return routine_1: gosub ball_rolling goto mode_select routine_2: gosub ball_rolling gosub ball_rolling servo servo1, pos_3 pause 1000 for b12 = pos_1 to pos_8 STEP -4 servo servo1, b12 pause 100 next b12 goto mode_select routine_3: for b12 = pos_9 to pos_1 STEP 4 servo servo1, b12 pause 200 next b12 for b12 = pos_1 to pos_6 STEP -4 servo servo1, b12 pause 200 next b12 goto mode_select routine_4: gosub ball_rolling servo servo1, pos_7 pause 1000 servo servo1, pos_4 pause 800 goto mode_select random_routine: random w3 b8 = b6 // 6 + 1 if b8 = 1 then routine_2 if b8 = 2 then routine_3 if b8 = 3 then routine_4 if b8 >= 4 then routine_1