Closed ross-inksmith closed 10 months ago
@ross-inksmith - please try swapping the order of the updates to servo1 and servo3 in the program, if you see that servo3 is responding and servo1 is not, then we likely have some packet loss on the STM side.
let _ = modules.servo1.angle()
_ = modules.servo2.angle()
_ = modules.servo3.angle()
basic.forever(function () {
modules.servo3.run(-50)
modules.servo1.run(50)
basic.pause(1000)
modules.servo3.run(0)
modules.servo1.run(0)
basic.pause(1000)
})
You can also try putting a pause between the updates to the two servos:
let _ = modules.servo1.angle()
_ = modules.servo2.angle()
_ = modules.servo3.angle()
basic.forever(function () {
modules.servo1.run(50)
basic.pause(10)
modules.servo3.run(-50)
basic.pause(1000)
modules.servo1.run(0)
basic.pause(10)
modules.servo3.run(0)
basic.pause(1000)
})
Also try this and look in console (when connected over WebUSB)
let _ = modules.servo1.angle()
_ = modules.servo2.angle()
_ = modules.servo3.angle()
basic.forever(function () {
console.log("servo 1 " + modules.servo1.isConnected())
console.log("servo 2 " + modules.servo2.isConnected())
console.log("servo 3 " + modules.servo3.isConnected())
modules.servo1.run(50)
modules.servo3.run(-50)
basic.pause(1000)
modules.servo1.run(0)
modules.servo3.run(0)
basic.pause(1000)
})
@ross-inksmith - I got the servos and am having issues with power on the round board. The green light is on but none of the lights on servos are on. I'm powering the board via its USB port (not Lipo) and power the microbit separately via battery. Any ideas?
Wait a second, the green light is on, with the switch in the OFF position. When I switch it ON, the led turns red.
I am very confused. I think we need a call.
Running the following program (observations follow) on the micro:bit, plugged into the round board, with no servos plugged in:
input.onButtonPressed(Button.A, function () {
modules.servo1.run(50)
modules.servo3.run(-50)
basic.pause(1000)
modules.servo1.run(0)
modules.servo3.run(0)
basic.pause(1000)
})
modules.servo1.start()
modules.servo2.start()
modules.servo3.start()
input.onButtonPressed(Button.B, function () {
console.log("servo 1 " + modules.servo1.isConnected())
console.log("servo 2 " + modules.servo2.isConnected())
console.log("servo 3 " + modules.servo3.isConnected())
})
When there is no power to the STM, on a press of B button, I get
binding: 3 servers
servo 1 false
servo 2 false
servo 3 false
which is expected.
When I give power to the STM, on press of B button, I get
binding: 3 servers
servo 1 true
servo 2 true
servo 3 true
This is expected, even without servos plugged in, because the STM is hard coded to advertised three servo services, per design, regardless of what is plugged in. So, it seems role management is working fine.
OK. All three servos are working with the following program (note the delay between commands) in code below. Make sure you are running micro:bit off of battery (not USB).
https://github.com/microsoft/jacdac/assets/10767146/6aef58da-c255-4668-bd5e-35953d6c3133
input.onButtonPressed(Button.A, function () {
modules.servo1.run(50)
basic.pause(100)
modules.servo2.run(50)
basic.pause(100)
modules.servo3.run(50)
})
input.onButtonPressed(Button.B, function () {
modules.servo1.run(0)
basic.pause(100)
modules.servo2.run(0)
basic.pause(100)
modules.servo3.run(0)
})
modules.servo1.start()
modules.servo2.start()
modules.servo3.start()
input.onButtonPressed(Button.AB, function () {
console.log("servo 1 " + modules.servo1.isConnected())
console.log("servo 2 " + modules.servo2.isConnected())
console.log("servo 3 " + modules.servo3.isConnected())
})
So, as I expected, we are losing packets somewhere. Based on the trace files provided before, which showed all expected packets on the bus, my bet is that the STM is dropping packets. But we should analyze more. In the meantime, we can figure out how much of a delay to introduce between commands to different servos.
I will send a video shortly. The other thing I discovered is that it seems that the servos are only powered by the Lipo. When I unplug the Lipo and put power on the round board's USB, there doesn't seem to be any power to the servo.
OK, now for bringing the delay between run commands down (run off of battery only):
const delay = 2
input.onButtonPressed(Button.A, function () {
modules.servo1.run(50)
basic.pause(delay)
modules.servo2.run(50)
basic.pause(delay)
modules.servo3.run(50)
})
input.onButtonPressed(Button.B, function () {
modules.servo1.run(0)
basic.pause(delay)
modules.servo2.run(0)
basic.pause(delay)
modules.servo3.run(0)
})
modules.servo1.start()
modules.servo2.start()
modules.servo3.start()
Note that when micro:bit is connected via USB, first servo often doesn't start. Seems like more packet loss. Works fine when micro:bit on battery.
Another thing to consider: if we want to send same command to all three servos, we can use a broadcast, which will use just a single packet.
@ross-inksmith - I got the servos and am having issues with power on the round board. The green light is on but none of the lights on servos are on. I'm powering the board via its USB port (not Lipo) and power the microbit separately via battery. Any ideas?
Wait a second, the green light is on, with the switch in the OFF position. When I switch it ON, the led turns red.
I am very confused. I think we need a call.
There are two LEDs by the port on the board. One is green to indicate a charge, the other is a low battery/low voltage light. When driving multiple power hungry devices (two servos and a LED ring, for example), or if the servos draw extra current to create more torque, or if some combination of those things happen when the battery isn't fully charged, that can also turn the red light on.
And that's right, the board only works when switched on regardless of whether or not it's charging - it only draws power from the battery or port; it won't charge through the microbit/edge connector.
So, as I expected, we are losing packets somewhere. Based on the trace files provided before, which showed all expected packets on the bus, my bet is that the STM is dropping packets. But we should analyze more. In the meantime, we can figure out how much of a delay to introduce between commands to different servos.
We were wondering if this was an issue in #1312, which is also STM
Try again; fix pushed.
It is working now - Peli made pxt-jacdac/servo last chatty - please update to latest pxt-jacdac
This was not a problem with the STM - pxt-jacdac was too chatty.
Initial tests seem good. Continuing to test.
I'm unexpectedly out of office today and can't test with our devices today. Reading the diff looks cool though
Creating a new project and adding the jacdac extension includes v1.9.19, but using our extension loads a cached version (in this case, v1.9.13). Emptying the cache via dev tools doesn't clear it. I can only get it by through chrome://settings/content/all?search=data
Unfortunately, a lot of classrooms use chromebooks that don't have access to chrome settings or incognito mode. Is there another way? I don't see anything on https://makecode.com/extensions/pxt-json or in https://github.com/microsoft/pxt/blob/master/pxtlib/package.ts to add a version annotation
how do you publish release of your extension? do you use mkc bump
? The mkc cli bumps the cloud to flush its caches otherwise the makecode cloud has a 24h cache for extensions.
I do use mkc bump
. I don't think the cloud cache is the issue, since it would use the current version of jacdac in incognito and the issue went away by clearing local data. I've created an issue with pxt https://github.com/microsoft/pxt/issues/9740
@ross-inksmith can you share again, it won't load
sorry, which?
i have the repro. THe makecode share link in your original description broke somehow.
I think it broke because I cleaned up the branch it was using. I've made this to the best of my memory https://makecode.microbit.org/_df5Udy6drWiE. It uses the version of our extension from two weeks ago but jacdac v1.9.20
In 1.9.23, the ?srvo=yy
hint is now used when binding roles. So you'll want to add those to your role names as such:
https://github.com/microsoft/pxt-jacdac/blob/master/servo/test.microbit.ts#L4
This gives me a stable assignment with 1, 2 or 3 servos when the shield is connected. Let's how far we go with this. Eventually we could also add the product id hint; it's just that i might not have at hand when assigning roles.
@ross-inksmith
This is excellent! Working as advertised for me so far
Let's see how far you get with testing with that fix.
If there are other problems, please file a separate issue for each problem.
In the attached video (https://github.com/microsoft/jacdac/assets/88154489/bf2d7dc8-3e97-45f6-be6d-22576faf6d69), I've already downloaded the code (https://makecode.microbit.org/_JKyP30b9TY8a) to the microbit. With the computer disconnected I turn the breakout board on. Only the left servo turns (in firmware they're created in order 0:left 1:middle 2:right). Once I connect the computer/Makecode, the left and middle servos start turning. They will keep doing this even if I disconnect the computer again. If I start with the microbit connected to Makecode, then both servos will work on startup.
Additional detail
In the above build, using our wrapper extension I've included code to wait for
roleManagerServer.isConnected()
in the extension's main.ts before querying (in order)left-
,middle-
, andrightServo.getAngle()
in an attempt to bias the roleManager's assignments. This seems to work in Makecode, but a disconnected microbit will assign "leftServo" to the first service, while the other two roles can be assigned in either order with no obvious pattern.Our issue has a lot in common with #1293; we can control the servos using the dashboard controls and they move within their full range without delay, but only the first service will respond to the first block (e.g.
servo1.run(x)
will always work). Other services on the board only start repsonding after the second block (e.g.servo2.run(x)
has no effect the first time, but subseuqent calls toservo2.anything
work as normal)There may be something in the physical init process that influences this; when the board is powered on any servo on the left pin (first one in firmware) moves to 0° while the others do not move. I can turn the servos easily so they're unpowered. Our board doesn't do any detection of servos, so sends signals based on pin regardless of what is plugged in.
Another demonstration is here (https://makecode.microbit.org/_e4UJXP23ER3j) using the MS jacdac extension. If I use the Add Simulators button, it will create three simulators and assign them like this:
Note that the simulators have a 0-180° range but alternate between servo1:0/45° and servo3:45/113° instead of servo1:90/135° and servo3:45/90°
Using the same code and plugging in our breakout board (which has 270° servos), it will now lay itself like this:
The same code now causes the servos to alternate between 0/90° and 90/180° instead of 67.5/135° and 135/202.5°
The above might be related to #1327? I've also found during testing that the starting ranges for our servos initially default to 0-180° before getting updated later.