Skip to content

Commit 0972daa

Browse files
committed
First commit of servo_motor_rotate() API
1 parent 6e5dcf9 commit 0972daa

File tree

2 files changed

+92
-20
lines changed

2 files changed

+92
-20
lines changed

neopia/neosoco.py

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,29 @@ class Neosoco(Robot):
229229
'0': 0
230230
}
231231

232+
_SERVO_MOTOR_PERCENT_CVT = {
233+
'100': 100,
234+
'90': 90,
235+
'80': 80,
236+
'70': 70,
237+
'60': 60,
238+
'50': 50,
239+
'40': 40,
240+
'30': 30,
241+
'20': 20,
242+
'10': 10,
243+
'0': 0
244+
}
245+
232246
_MOTOR_DIR = {
233247
'forward': 16,
234248
'backward': 32
235249
}
250+
251+
_SERVO_MOTOR_DIR = {
252+
'forward': 192,
253+
'backward': 208
254+
}
236255

237256
_robots = {}
238257

@@ -446,7 +465,14 @@ def motor_move(self, direction='forward'):
446465
raise TypeError
447466
Runner.wait(100) # Since broadcast from controller is per 100ms
448467

449-
def _convert_input_port_scale(self, port, limit_val):
468+
def _convert_sacle_within_100(self, value, cvt_max_val):
469+
# Map to 0~limited_val from 0~100(max), it's same as Entry
470+
value = max(value, 0)
471+
value = min(value, 100)
472+
value = math.ceil(value / 100 * cvt_max_val)
473+
return value
474+
475+
def _convert_scale_from_input_port(self, port, cvt_max_val):
450476
if port.lower() =='in1':
451477
value = self.read(Neosoco.INPUT_1)
452478
elif port.lower() =='in2':
@@ -457,16 +483,13 @@ def _convert_input_port_scale(self, port, limit_val):
457483
raise ValueError('Wrong value of port')
458484

459485
if value:
460-
value = max(value, 0)
461-
value = min(value, 100)
462-
value = math.ceil(value / 100 * limit_val)
463-
return value
486+
value = self._convert_sacle_within_100(value, cvt_max_val)
487+
return value
464488

465489
def motor_rotate(self, motor='both', direction='forward', speed='100'):
466490
if isinstance(motor, str) and isinstance(direction, str) and isinstance(speed, str):
467491
if speed == 'in1' or speed == 'in2' or speed == 'in3' :
468-
# Map to 0~15 from 0~100(max), it's same as Entry
469-
speed = self._convert_input_port_scale(speed, 15)
492+
speed = self._convert_scale_from_input_port(speed, 15)
470493
elif speed in self._MOTOR_PERCENT_CVT.keys():
471494
speed = self._MOTOR_PERCENT_CVT[speed]
472495
else:
@@ -499,6 +522,44 @@ def motor_rotate(self, motor='both', direction='forward', speed='100'):
499522
else:
500523
raise TypeError
501524

525+
def servo_motor_rotate(self, port='out1', direction='forward', speed='100'):
526+
if isinstance(port, str) and isinstance(direction, str) and isinstance(speed, str):
527+
if speed == 'in1' or speed == 'in2' or speed == 'in3' :
528+
speed = self._convert_scale_from_input_port(speed, 10)
529+
elif speed in self._SERVO_MOTOR_PERCENT_CVT.keys():
530+
speed = self._SERVO_MOTOR_PERCENT_CVT[speed]
531+
speed = self._convert_sacle_within_100(speed, 10)
532+
else:
533+
raise ValueError('Wrong value of speed')
534+
535+
if direction.lower() =='forward':
536+
direction = self._SERVO_MOTOR_DIR['forward']
537+
elif direction.lower() =='backward':
538+
direction = self._SERVO_MOTOR_DIR['backward']
539+
else:
540+
raise ValueError('Wrong value of direction')
541+
542+
outValue = direction + speed
543+
if outValue == direction:
544+
outValue = 254
545+
else:
546+
outValue = outValue - 1
547+
548+
if port.lower() == 'out1':
549+
self.write(Neosoco.OUTPUT_1, outValue)
550+
elif port.lower() == 'out2':
551+
self.write(Neosoco.OUTPUT_2, outValue)
552+
elif port.lower() == 'out3':
553+
self.write(Neosoco.OUTPUT_3, outValue)
554+
elif port.lower() == 'all':
555+
self.write(Neosoco.OUTPUT_1, outValue)
556+
self.write(Neosoco.OUTPUT_2, outValue)
557+
self.write(Neosoco.OUTPUT_3, outValue)
558+
else:
559+
raise ValueError('Wrong value of out port')
560+
else:
561+
raise TypeError
562+
502563
def buzzer(self, pitch='3', note='c', beats='4'):
503564
self.write(Neosoco.NOTE, 0) # init
504565
if not isinstance(pitch, str) or not (int(pitch) >= 1 and int(pitch) <= 6):
@@ -535,7 +596,7 @@ def buzzer(self, pitch='3', note='c', beats='4'):
535596
def buzzer_by_port(self, port='in1'):
536597
if isinstance(port, str):
537598
# Map to 0~65 from 0~100(max), it's same as Entry
538-
value = self._convert_input_port_scale(port, 65)
599+
value = self._convert_scale_from_input_port(port, 65)
539600
self.write(Neosoco.NOTE, value)
540601
else:
541602
raise TypeError

test.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@
2020
# n.led_off('out1')
2121

2222
## Motors
23-
# case4-1) Move forth and back during 1s and stop
23+
# case4) Move forth and back during 1s and stop
2424
# n.motor_move('forward')
2525
# wait(500)
2626
# n.motor_move('backward')
2727
# wait(500)
2828
# n.motor_move('stop')
2929

30-
# case4-2) Moving control by direction keys on the keyboard
30+
# case5) Moving control by direction keys on the keyboard
3131
# while True:
3232
# key = Keyboard.read()
3333

@@ -42,15 +42,15 @@
4242
# elif key == ' ':
4343
# n.motor_move('stop')
4444

45-
# case5) Move forth and back with speed 30% during 1s and stop
45+
# case6) Move forth and back with speed 30% during 1s and stop
4646
# n.motor_rotate('both', 'forward', '30')
4747
# wait(500)
4848
# n.motor_rotate('both', 'backward', '30')
4949
# wait(500)
5050
# n.motor_move('stop')
5151

5252
## Buzzer
53-
# case6) Play same note by pitch, sharp and flat, and a length of note
53+
# case7) Play same note by pitch, sharp and flat, and a length of note
5454
# n.buzzer('3', n.NOTE_NAME_C)
5555
# n.buzzer('3', 'c')
5656

@@ -60,19 +60,30 @@
6060
# n.buzzer('5', n.NOTE_NAME_D_FLAT, '16')
6161
# n.buzzer('5', 'db', '16')
6262

63-
# case7) Play a sound by value from input port
63+
# case8) Play a sound by value from input port
6464
# while True:
6565
# n.buzzer_by_port('in1')
6666

6767
## Color LED, distance sensor
68-
# case8) Color LED on with variable color by input port
68+
# case9) Color LED on with variable color by input port
6969
# r = g = b = n.convert_scale('in1', 0, 255, 85, 170) # Limit to middle brightness
7070
# color_led_on('out1', r, g, b)
7171

7272
## LED, Angle sensor
73-
# case9) # Turn on LED when a degree of the angle sensor is under 90 degrees
74-
while True:
75-
if n.get_angle('in1') < 90:
76-
n.led_on('out1', '100')
77-
else:
78-
n.led_off('out1')
73+
# case10) # Turn on LED when a degree of the angle sensor is under 90 degrees
74+
# while True:
75+
# if n.get_angle('in1') < 90:
76+
# n.led_on('out1', '100')
77+
# else:
78+
# n.led_off('out1')
79+
80+
# Servo Motor
81+
# case 11) Rotate servo motor forth and back with speed 50% during 5s and stop
82+
n.servo_motor_rotate('out2', 'forward', '50')
83+
wait(2000)
84+
n.servo_motor_rotate('out2', 'forward', '0')
85+
wait(1000)
86+
n.servo_motor_rotate('out2', 'backward', '50')
87+
wait(2000)
88+
n.servo_motor_rotate('out2', 'forward', '0')
89+
wait(1000)

0 commit comments

Comments
 (0)