Closed ross-inksmith closed 10 months ago
Trying to understand. I made a simple example two jacdac buttons - the assignments stay the same when connected and disconnect: https://makecode.microbit.org/_hf6CaPE1Jf3r
try 3 buttons
Sent from Outlookhttp://aka.ms/weboutlook
From: Tom Ball @.> Sent: Wednesday, October 18, 2023 9:16 AM To: microsoft/jacdac @.> Cc: Assign @.>; Subscribed @.> Subject: Re: [microsoft/jacdac] Role manager (servo?) assignment behaviour is different when Makecode is/isn't connected (Issue #1335)
Trying to understand. I made a simple example two jacdac buttons - the assignments stay the same when connected and disconnect: https://makecode.microbit.org/_hf6CaPE1Jf3r
— Reply to this email directly, view it on GitHubhttps://github.com/microsoft/jacdac/issues/1335#issuecomment-1768881698 or unsubscribehttps://github.com/notifications/unsubscribe-auth/AA73QKJKND57QMYEO5CM2PDX776GJBFKMF2HI4TJMJ2XIZLTSSBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDUOJ2WLJDOMFWWLLTXMF2GG2C7MFRXI2LWNF2HTAVFOZQWY5LFUVUXG43VMWSG4YLNMWVXI2DSMVQWIX3UPFYGLAVFOZQWY5LFVIZDCMBXG4YDMNJWGOSG4YLNMWUWQYLTL5WGCYTFNSWHG5LCNJSWG5C7OR4XAZNMJFZXG5LFINXW23LFNZ2KM5DPOBUWG44TQKSHI6LQMWVHEZLQN5ZWS5DPOJ42K5TBNR2WLKJSGY4TCMJQGMYTJAVEOR4XAZNFNFZXG5LFUV3GC3DVMWVDCOJUGU3TONJXGE2IFJDUPFYGLJLMMFRGK3FFOZQWY5LFVIZDCMBXG4YDMNJWGOTXI4TJM5TWK4VGMNZGKYLUMU. You are receiving this email because you were assigned.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
There seems to be another issue addressed above:
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: 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 https://github.com/microsoft/jacdac/issues/1327? I've also found during testing that the starting ranges for our servos initially default to 0-180° before getting updated later.
Three buttons seems to work as well: https://makecode.microbit.org/_DYD4RA6rpCK0
The assignment issue does seem to be unique to the servos. I haven't seen it so far with our reflected light/line follower board which also has 3 otherwise identical services on them.
Attached is a packet trace demonstrating the issue similar to #1293, where only one servo responds at first; only one packet is actually sent.
Yes, I am looking now into program you gave above: https://makecode.microbit.org/_e4UJXP23ER3j
@ross-inksmith, you said:
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.
Right. I forgot that the servos are connected via jacdac cables which PWM is being sent over. Where is the code that manages initialization? This must be special-purpose for your board, correct?
so the difference is that you have 3 servos on the same devices; rather than 3 individual devices with 1 servo service.
@ross-inksmith, you said:
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.
Right. I forgot that the servos are connected via jacdac cables which PWM is being sent over. Where is the code that manages initialization? This must be special-purpose for your board, correct?
Not quite. Similar to the kittenbot device in #1293, we have one jacdac connection to a device with multiple servo services on it. Instead of having it as a separate board, it's on the same board as the edge connector/microbit. If you were to swap the connector to a standard 3 pin connector, it would work identically
can you share a packet trace? (link in the jacdac-docs footer)
it's the same code as here (https://makecode.microbit.org/_e4UJXP23ER3j), except that I moved the code from forever to input.onButtonPressed
so I could record the trace
looks like makecode wants to have 0-180 at start
@ross-inksmith, you said:
Not quite. Similar to the kittenbot device in https://github.com/microsoft/jacdac/issues/1293, we have one jacdac connection to a device with multiple servo services on it.
I understand. Where is the firmware for that device?
But just to be clear, your hypothesis is that this is something in the Jacdac stack above the firmware, due to the similar problem Kittenbot has?
@pelikhan - so you think that the makecode defaults for the servo could be leading to the problem?
@pelikhan - so you think that the makecode defaults for the servo could be leading to the problem?
https://github.com/ross-inksmith/pxt-jacdac/commit/cde16a82eac6182e1e2c45471d0e7ecebf613bc6 https://makecode.microbit.org/_1i0EJDXobWj2 Doesn't seem to have changed it
{
"name": "remove defaults",
"description": "",
"dependencies": {
"core": "*",
"radio": "*",
"microphone": "*",
"jacdac": "github:microsoft/pxt-jacdac",
"jacdac-servo": "github:ross-inksmith/pxt-jacdac/servo#cde16a82eac6182e1e2c45471d0e7ecebf613bc6"
},
"files": [
"main.blocks",
"main.ts",
"README.md"
],
"preferredEditor": "tsprj"
}
@ross-inksmith, you said:
Not quite. Similar to the kittenbot device in https://github.com/microsoft/jacdac/issues/1293, we have one jacdac connection to a device with multiple servo services on it.
I understand. Where is the firmware for that device?
https://github.com/Forward-Education/firmware/tree/main/BreakoutBoard270
Ok. in jacdac-c servo.c, init() is
SRV_DEF(servo, JD_SERVICE_CLASS_SERVO);
void servo_init(const servo_params_t *params) {
SRV_ALLOC(servo);
state->params = *params;
state->params0 = params;
}
So nothing happens on init to set the servo to an initial position/state?
@ross-inksmith - I see that servo_0 has a different power pin than the other two servos. Correct?
const servo_params_t servo_0 = {
.pin = PA_6,
.fixed = 0,
.min_angle = 0 << 16,
.min_pulse = 600,
.max_angle = 270 << 16,
.max_pulse = 2500,
.power_pin = PB_7
};
const servo_params_t servo_1 = {
.pin = PA_7,
.fixed = 0,
.min_angle = 0 << 16,
.min_pulse = 600,
.max_angle = 270 << 16,
.max_pulse = 2500,
.power_pin = PC_15
};
const servo_params_t servo_2 = {
.pin = PA_4,
.fixed = 0,
.min_angle = 0 << 16,
.min_pulse = 600,
.max_angle = 270 << 16,
.max_pulse = 2500,
.power_pin = PC_15
//NO_PIN
};
@brian-inksmith is double checking the schematics, but the pins are fed from the same rail. (I asked a similar question)
OK. So buttons and light sensors are input modules that generate events, so let me try with something that generates output instead.
OK. I think I have a program with 3 dot matrixes (for which I have modules too): https://makecode.microbit.org/_a2vhjoLqxbEW
https://github.com/microsoft/pxt-jacdac/blob/master/servo-server/server.microbit.ts#L13
For the min/max issues, it's also defined here for the servos. It doesn't explain how the math in servo.run()
comes up with 0/90 and 90/180 though
Oops spoke too soon... it's working when plugged in, and when I unplug and put on battery power. So this seems to be specific to servos.
The issue is that the servo clients has partially received the ranges from the servo services; and then applies the computation for converting the speed into an angle. Since the current default in the client is -90, 90, you could end up with a combination of [-90,0] x [90, 180].
and in restrospect, .... 0 || 90 -> 90
so that explains it.
So the problem is initialization between service and client!
and in restrospect, ....
0 || 90 -> 90
so that explains it.
Oh that's funny. For the majority of development we were using -90/90
silly silly me.
Servo range fix deployed. Please test.
Thanks, Peli!
Servo range fix deployed. Please test.
Also works if I detach the board and add simulators instead :+1:
I don't think this solves the role manager issue. @ross-inksmith ?
While the angle now reports as accurate, still having issues getting multiple servos to respond. Attached is the video of the exact same code above running without makecode connected. Only servo1 responds. On the first click it goes to it's end range. On the second and subsequent clicks it moves in its normal range. servo3 does not move
https://github.com/microsoft/jacdac/assets/88154489/1475a350-2507-4c9b-9930-77cb273c3a00
Longer video now, behaviour with makecode attached is different. tl;dw: With makecode attached, servo3 will eventually start responding
https://github.com/microsoft/jacdac/assets/88154489/8f018c26-109f-41d7-8bb2-9d4c4d4a3b3a
I recorded this trace without going to the dashboard, so there were no simulated devices. It behaved as the first video with makecode disconnected. When I opened the dashboard to record a second trace it worked as with makecode connected but only recorded 18 packets :thinking:
OK. This also seems specific to servo.
In the past, I have seen this sort of behavior where the hardware works differently when the Jacdac device is connected through WebUSB to the dashboard....
@ross-inksmith you said:
When I opened the dashboard to record a second trace it worked as with makecode connected but only recorded 18 packets 🤔
Did the program work correctly or not when connected to the dashboard? I'm not sure how to interpret the above comment.
In the last trace you gave, all the servo messages are tagged with "(usb)":
9222.700 b75b1803dc445b97ac759af1133e00e800000000000000000391fc1200736572766f31ff
[ack:0x5bb7] to SB67/PIPE: port:464 cnt:0; sz=19; CMD 0xe800 { _:
00000000000000000391fc1200736572766f31 | .............servo1 } (usb)
Yeah I realized that would be a bit hard to follow so I did it again here's the trace.jd.txt
and here's a full video https://github.com/microsoft/jacdac/assets/88154489/5beceef8-bd41-44c3-be64-8a5aa91a2cf6
@pelikhan - Is it possible to see the log messages that pxt-jacdac sends to the console? That might help more than the Jacdac trace.
You can turn on the "passive" mode in the jacdac-docs so that the browser does not emit any packets; and you should have the same behavior as without being connected.
Ah, very good
I'm not sure this is a role manager problem - seems like the three servos get recognized
device:
id: TQ01 (0x54cf1386c74a3cdd)
product: TQ01 (0x3412171b)
firmware_version: v0.20.3-16-g7e9e119-20230726-1434
uptime: 72652.17000000224
stats: announce 103, drop 0, restart 0
services:
servo (0x12fc9103)
const instance_name: "Left" (4c656674)
last data: 33726, last get: 33726, last set: , last gets attempts: 0,
rw angle: 135° (00008700)
last data: 80616, last get: 80616, last set: , last gets attempts: 0,
rw enabled: true (01)
last data: 84317, last get: 84317, last set: , last gets attempts: 0,
rw offset: 0° (00000000)
last data: 84322, last get: 84322, last set: , last gets attempts: 0,
const min_angle: 0° (00000000)
last data: 40191, last get: 40191, last set: , last gets attempts: 0,
const max_angle: 270° (00000e01)
last data: 40195, last get: 40195, last set: , last gets attempts: 0,
servo (0x12fc9103)
const instance_name: "Middle" (4d6964646c65)
last data: 33729, last get: 33729, last set: , last gets attempts: 0,
rw angle: 0° (00000000)
last data: 84571, last get: 84571, last set: , last gets attempts: 0,
rw enabled: false (00)
last data: 84365, last get: 84365, last set: , last gets attempts: 0,
rw offset: 0° (00000000)
last data: 84370, last get: 84370, last set: , last gets attempts: 0,
const min_angle: 0° (00000000)
last data: 34061, last get: 34061, last set: , last gets attempts: 0,
const max_angle: 270° (00000e01)
last data: 34067, last get: 34067, last set: , last gets attempts: 0,
servo (0x12fc9103)
const instance_name: "Right" (5269676874)
last data: 33740, last get: 33740, last set: , last gets attempts: 0,
rw angle: 135° (00008700)
last data: 80622, last get: 80622, last set: , last gets attempts: 0,
rw enabled: true (01)
last data: 82413, last get: 82413, last set: , last gets attempts: 0,
rw offset: 0° (00000000)
last data: 84414, last get: 84414, last set: , last gets attempts: 0,
const min_angle: 0° (00000000)
last data: 40204, last get: 40204, last set: , last gets attempts: 0,
const max_angle: 270° (00000e01)
last data: 40212, last get: 40212, last set: , last gets attempts: 0,
relay (0x183fe656)
const instance_name: "Pump" (50756d70)
last data: 33751, last get: 33751, last set: , last gets attempts: 0,
rw active: false (00)
last data: 84264, last get: 84264, last set: , last gets attempts: 0,
My current hypothesis is that we are seeing packet loss. I see something similar here: https://github.com/microsoft/jacdac/issues/1336
@ross-inksmith - what chip is driving the servos? Is that an STM?
@tballmsft Yes, specifically it's STM32G030F6P6TR
Right, just figured that out:
MCU = STM32g030x6 include $(PLATFORM)/mk/stm32g0.mk
From what I see in the trace, the packets GET/SET of angle for both servos1 and servo3 always happen together
See TQ01(1) and TQ01/(3) below
12442.900 0896040154cf1386c74a3cdd00011011 to TQ01/(1): GET[minvalue]; sz=0; GET 0x110 (usb)
12447.100 39a5040154cf1386c74a3cdd00011111 to TQ01/(1): GET[maxvalue]; sz=0; GET 0x111 (usb)
12450.400 ff53080154cf1386c74a3cdd0101012001ffffff to TQ01/(1): SET[intensity]; sz=1; SET 0x1: 01 | . (usb)
12454.900 bcb3080154cf1386c74a3cdd040102200080ca00 to TQ01/(1): SET[value]; sz=4; SET 0x2: 0080ca00 | .... (usb)
12457.800 87e50c0154cf1386c74a3cdd06010920636f6e743d31ffff to TQ01/(1): SET[clientvariant]; sz=6; SET 0x9: 636f6e743d31 | cont=1 (usb)
12460.600 68f8040154cf1386c74a3cdd00031011 to TQ01/(3): GET[minvalue]; sz=0; GET 0x110 (usb)
12464.800 59cb040154cf1386c74a3cdd00031111 to TQ01/(3): GET[maxvalue]; sz=0; GET 0x111 (usb)
12468.300 1c33080154cf1386c74a3cdd0103012001ffffff to TQ01/(3): SET[intensity]; sz=1; SET 0x1: 01 | . (usb)
12472.600 5f72080154cf1386c74a3cdd0403022000804300 to TQ01/(3): SET[value]; sz=4; SET 0x2: 00804300 | ..C. (usb)
12475.600 34450c0154cf1386c74a3cdd06030920636f6e743d31ffff to TQ01/(3): SET[clientvariant]; sz=6; SET 0x9: 636f6e743d31 | cont=1 (usb)
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.