x = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.X),
0, 1023, -100, 100)
y = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.Y),
0, 1023, -100, 100)
if x >= -10 and x <= 10:
x = 0
if y >= -10 and y <= 10:
y = 0
# 搖桿端:提出配對要求
radio.send_value("pair", pairId)
# 小車端:確認同一組後回覆
if name == "pair" and value == pairId:
paired = True
radio.send_value("ack", pairId)
七、第五個關鍵:回饋讓系統真正可用
無線系統不能只「送出去」。V5 讓小車將狀態回傳給搖桿,並以蜂鳴器與震動告訴使用者目前情況:
配對成功:短音+震動一次。
慢、中、快:分別以 1、2、3 次提示確認。
前方接近障礙物:提示減速;距離過近:連續提示並停止。
F 緊急停止:低音與震動,直到按 C、D、E 之一才解除。
def feedback(times, tone):
for index in range(times):
music.play_tone(tone, music.beat(BeatFraction.SIXTEENTH))
joystickbit.Vibration_Motor(80)
basic.pause(60)
除錯提醒:Joystick:bit 的震動函式名稱為 Vibration_Motor,其中 V 與 M 必須大寫。
x = 0
y = 0
speed = 70
radio.set_group(51)
basic.show_number(2) # 開機預設為一般速度
def on_button_pressed_a():
global speed
speed = 40
basic.show_number(1) # 慢速
input.on_button_pressed(Button.A, on_button_pressed_a)
def on_button_pressed_b():
global speed
speed = 70
basic.show_number(2) # 一般速度
input.on_button_pressed(Button.B, on_button_pressed_b)
def on_button_pressed_ab():
global speed
speed = 100
basic.show_number(3) # 快速
input.on_button_pressed(Button.AB, on_button_pressed_ab)
def on_forever():
global x, y
x = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.X),
0, 1023, -100, 100)
y = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.Y),
0, 1023, -100, 100)
# 搖桿死區:回到中央時停止
if x >= -10 and x <= 10:
x = 0
if y >= -10 and y <= 10:
y = 0
# 依速度模式縮放輸出值
x = x * speed / 100
y = y * speed / 100
radio.send_value("x", x)
radio.send_value("y", y)
basic.pause(50)
basic.forever(on_forever)
(二)Q霸小車端:V3 超音波安全避障
xValue = 0
yValue = 0
lastReceiveTime = -1000
distance = 0
radio.set_group(51)
basic.show_number(51)
cuteBot.motors(0, 0)
def on_received_value(name, value):
global xValue, yValue, lastReceiveTime
if name == "x":
xValue = value
elif name == "y":
yValue = value
lastReceiveTime = control.millis()
radio.on_received_value(on_received_value)
def on_forever():
global distance
# 優先保護 1:逾 0.5 秒未收到訊號,立即停車
if control.millis() - lastReceiveTime > 500:
cuteBot.motors(0, 0)
else:
distance = cuteBot.ultrasonic(cuteBot.SonarUnit.Centimeters)
leftSpeed = Math.constrain(yValue + xValue, -100, 100)
rightSpeed = Math.constrain(yValue - xValue, -100, 100)
# 優先保護 2:僅在向前時啟用前方避障
if yValue > 0 and distance > 0 and distance <= 15:
cuteBot.motors(0, 0)
basic.show_icon(IconNames.NO)
elif yValue > 0 and distance > 15 and distance <= 30:
cuteBot.motors(leftSpeed * 0.4, rightSpeed * 0.4)
basic.show_icon(IconNames.SMALL_DIAMOND)
else:
cuteBot.motors(leftSpeed, rightSpeed)
basic.clear_screen()
basic.pause(30)
basic.forever(on_forever)
x = 0
y = 0
speed = 70
radio.set_group(51)
basic.show_number(2) # 開機預設為一般速度
def on_button_pressed_a():
global speed
speed = 40
basic.show_number(1) # 慢速
input.on_button_pressed(Button.A, on_button_pressed_a)
def on_button_pressed_b():
global speed
speed = 70
basic.show_number(2) # 一般速度
input.on_button_pressed(Button.B, on_button_pressed_b)
def on_button_pressed_ab():
global speed
speed = 100
basic.show_number(3) # 快速
input.on_button_pressed(Button.AB, on_button_pressed_ab)
def on_forever():
global x, y
x = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.X),
0, 1023, -100, 100)
y = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.Y),
0, 1023, -100, 100)
# 搖桿死區:回到中央時停止
if x >= -10 and x <= 10:
x = 0
if y >= -10 and y <= 10:
y = 0
# 依速度模式縮放輸出值
x = x * speed / 100
y = y * speed / 100
radio.send_value("x", x)
radio.send_value("y", y)
basic.pause(50)
basic.forever(on_forever)
(二)Q霸小車端:V3 超音波安全避障
xValue = 0
yValue = 0
lastReceiveTime = -1000
distance = 0
radio.set_group(51)
basic.show_number(51)
cuteBot.motors(0, 0)
def on_received_value(name, value):
global xValue, yValue, lastReceiveTime
if name == "x":
xValue = value
elif name == "y":
yValue = value
lastReceiveTime = control.millis()
radio.on_received_value(on_received_value)
def on_forever():
global distance
# 優先保護 1:逾 0.5 秒未收到訊號,立即停車
if control.millis() - lastReceiveTime > 500:
cuteBot.motors(0, 0)
else:
distance = cuteBot.ultrasonic(cuteBot.SonarUnit.Centimeters)
leftSpeed = Math.constrain(yValue + xValue, -100, 100)
rightSpeed = Math.constrain(yValue - xValue, -100, 100)
# 優先保護 2:僅在向前時啟用前方避障
if yValue > 0 and distance > 0 and distance <= 15:
cuteBot.motors(0, 0)
basic.show_icon(IconNames.NO)
elif yValue > 0 and distance > 15 and distance <= 30:
cuteBot.motors(leftSpeed * 0.4, rightSpeed * 0.4)
basic.show_icon(IconNames.SMALL_DIAMOND)
else:
cuteBot.motors(leftSpeed, rightSpeed)
basic.clear_screen()
basic.pause(30)
basic.forever(on_forever)
x = 0
y = 0
speed = 70
radio.set_group(51)
basic.show_number(2) # 開機預設為一般速度
def on_button_pressed_a():
global speed
speed = 40
basic.show_number(1) # 慢速
input.on_button_pressed(Button.A, on_button_pressed_a)
def on_button_pressed_b():
global speed
speed = 70
basic.show_number(2) # 一般速度
input.on_button_pressed(Button.B, on_button_pressed_b)
def on_button_pressed_ab():
global speed
speed = 100
basic.show_number(3) # 快速
input.on_button_pressed(Button.AB, on_button_pressed_ab)
def on_forever():
global x, y
x = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.X),
0, 1023, -100, 100)
y = Math.map(joystickbit.get_rocker_value(joystickbit.rockerType.Y),
0, 1023, -100, 100)
# 搖桿死區:回到中央時停止
if x >= -10 and x <= 10:
x = 0
if y >= -10 and y <= 10:
y = 0
# 依速度模式縮放輸出值
x = x * speed / 100
y = y * speed / 100
radio.send_value("x", x)
radio.send_value("y", y)
basic.pause(50)
basic.forever(on_forever)