Open laurensvalk opened 1 year ago
> ### 4. BLE HID Peripherals
We may support connecting to generic HID devices over BLE (and possibly classic). Users could build on this to add specific mappings for certain devices like popular gaming consoles.
From https://github.com/pybricks/support/issues/191#issuecomment-1493256816 :
import binascii
import ubluetooth
from micropython import const
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)
_IRQ_GATTC_SERVICE_RESULT = const(9)
_IRQ_GATTC_SERVICE_DONE = const(10)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_READ_DONE = const(16)
_IRQ_GATTC_WRITE_DONE = const(17)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)
_IRQ_GATTS_INDICATE_DONE = const(20)
_IRQ_MTU_EXCHANGED = const(21)
_IRQ_L2CAP_ACCEPT = const(22)
_IRQ_L2CAP_CONNECT = const(23)
_IRQ_L2CAP_DISCONNECT = const(24)
_IRQ_L2CAP_RECV = const(25)
_IRQ_L2CAP_SEND_READY = const(26)
_IRQ_CONNECTION_UPDATE = const(27)
_IRQ_ENCRYPTION_UPDATE = const(28)
_IRQ_GET_SECRET = const(29)
_IRQ_SET_SECRET = const(30)
_ADV_IND = const(0x00)
_ADV_DIRECT_IND = const(0x01)
_ADV_SCAN_IND = const(0x02)
_ADV_NONCONN_IND = const(0x03)
_UART_SERVICE_UUID = ubluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
_UART_RX_CHAR_UUID = ubluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E")
_UART_TX_CHAR_UUID = ubluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")
class BLESimpleCentral:
def __init__(self, ble):
self.gamepad_name = None
self.gamepad_addr_type = None
self.gamepad_addr = None
self._ble = ble
self._ble.active(True)
self._ble.irq(self.bt_irq)
def bt_irq(self, event, data):
if event == _IRQ_SCAN_RESULT:
# A single scan result.
addr_type, addr, adv_type, rssi, adv_data = data
if find_adv_name(adv_data) is None:
return
print('Address-Type: ', addr_type)
print('Address: ', [hex(n) for n in addr])
print('ADV-Type: ', adv_type)
print('RSSI in dBm: ', rssi)
print('ADV-Data: ', [hex(n) for n in adv_data])
print('ADV-Data (Name): ', find_adv_name(adv_data)) # Xbox Wireless Controller
print()
if find_adv_name(adv_data) == "Xbox Wireless Controller":
self.gamepad_name = find_adv_name(adv_data)
self.gamepad_addr_type = addr_type
self.gamepad_addr = addr
self._ble.gap_scan(None)
self.connect()
elif event == _IRQ_SCAN_DONE:
# Scan duration finished or manually stopped.
pass
elif event == _IRQ_PERIPHERAL_CONNECT:
# A successful gap_connect().
conn_handle, addr_type, addr = data
print("connect")
print(data)
print('Address-Type: ', addr_type)
print('Address: ', [hex(n) for n in addr])
print()
elif event == _IRQ_PERIPHERAL_DISCONNECT:
# Connected peripheral has disconnected.
conn_handle, addr_type, addr = data
print("disconnect")
print(data)
print('Address-Type: ', addr_type)
print('Address: ', [hex(n) for n in addr])
print()
# Find a device advertising the environmental sensor service.
def scan(self):
self._ble.gap_scan(5000, 100000, 25000, True)
def connect(self):
print(self.gamepad_addr)
self._ble.gap_connect(self.gamepad_addr_type, self.gamepad_addr)
def find_adv(adv_type, data):
i = 0
while i + 1 < len(data):
ad_structure_len = data[i]
ad_structure_type = data[i + 1]
ad_structure_payload = data[i + 2: i + ad_structure_len + 1]
if ad_structure_type == adv_type:
return ad_structure_payload
i += ad_structure_len + 1
return None
def find_adv_name(data):
n = find_adv(9, data)
if n:
return str(n, 'UTF-8') # Text
return None
def demo():
ble = ubluetooth.BLE()
central = BLESimpleCentral(ble)
central.scan()
def demo_connect():
ble = ubluetooth.BLE()
central = BLESimpleCentral(ble)
central.connect()
if __name__ == "__main__":
demo()
@all @mwinkler @cubelegend ( https://github.com/pybricks/support/issues/140#issuecomment-782938904)
Originally posted by @westurner in https://github.com/pybricks/support/issues/262#issuecomment-1493260385
@westurner This seems to be especially for XBOX ONE controllers. I'm not 100% sure about the low level stuff, but as far as I know, XBOX controllers use XINPUT while most other controllers use DINPUT (DINPUT beeing HID based?). It won't work with the stadia controller as that one uses DINPUT and it won't work with a PS4 controller because those use BTC and not BLE.
I think that there is a button standard for XINPUT but not really for DINPUT. Of course, one could focus on the most popular gamepads. I don't think that there are many gamepads out there that use BLE.
Originally posted by @Tcm0 in https://github.com/pybricks/support/issues/262#issuecomment-1493262116
@westurner
Here is the output of the script (running on stock mindstorm firmware, ble xbox controller): So connection seems to work
Originally posted by @mwinkler in https://github.com/pybricks/support/issues/262#issuecomment-1493281515
- [ ] https://github.com/pybricks/support/issues/995
The controller also supports Bluetooth Low Energy, and can be paired to a Bluetooth device and an Xbox device simultaneously.
XInput XInput is Microsoft's API for Xbox 360-compatible controllers such as the official Xbox 360 Controller.
xboxdrv
bluetoothctl scan
Force feedback support for XBOX ONE S and X gamepads via Bluetooth
steam-devices
Originally posted by @westurner in https://github.com/pybricks/support/issues/262#issuecomment-1493283886
Does there need to be a *gamepad* Bluetooth HID in the pybricks firmware?
- https://github.com/adafruit/Adafruit_nRF52_Arduino/issues/228#issuecomment-463191651)
- https://github.com/sparkfun/circuitpython/blob/673d2fb4b7c5e077fc5579af1d249438d17d93ad/tools/hid_report_descriptors.py#L177-L207
- https://github.com/sparkfun/circuitpython/blob/673d2fb4b7c5e077fc5579af1d249438d17d93ad/tools/hid_report_descriptors.py#L246-L276
- https://learn.adafruit.com/custom-hid-devices-in-circuitpython?view=all#report-descriptors-3103536
- https://github.com/lemmingDev/ESP32-BLE-Gamepad
- https://github.com/DJm00n/ControllersInfo -- HID profiles for Xbox 360, Xbox One, PS4, PS4, Stadia, and Switch
- "HID over GATT Profile (HOGP) 1.0" https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=245141 : 1 Introduction The HID over GATT profile defines the procedures and features to be used by Bluetooth low energy HID Devices using GATT and Bluetooth HID Hosts using GATT. This profile is an adaptation of the USB HID specification [2] to operate over a Bluetooth low energy wireless link. This profile shall operate over an LE transport only. For BR/EDR, the Bluetooth Human Interface Device Profile Specification [9] shall be used. 1.1 Profile Dependencies This profile requires the Generic Attribute Profile (GATT), the Battery Service, the Device Information Service, and the Scan Parameters Profile. This specification can be used with Bluetooth Core Specification Version 4.0 [3] or later.
Originally posted by @westurner in https://github.com/pybricks/support/issues/262#issuecomment-1493287515
Nice to see this issue split off, and some investigation going on, still interested in this one.
@westurner, how far did you get with this? I remember concluding with the PyBricks guys (in a March maybe) that if some basic BT connectivity functionality would be cleaned up in the PyBricks code (along the lines of the code that connects to the lego remote), then we might be able to build on that to experiment with HID gamepad controllers.
In the above example ubluetooth
is a micropython module, right? Is that available on PyBricks? Could it be? I remember us discussing with @dlech that the bluetooth
module is not available and would be problematic, but maybe ubluetooth
could be, so that we can build on it? What's the essential difference?
In MicroPython, ubluetooth
is an alias for bluetooth
so they are both names for the same module.
Oh, that's a pity, so nothing new there. Has there been any restructuring lately about BLE device connectivity code to make it more generally applicable for other purposes than connecting the lego remote?
No, there haven't been any changes in that regard.
All is not lost though, we're always working on Bluetooth --- @dlech did make significant progress on Bluetooth, just in a different way :wink:
@laurensvalk thanks for the update! It seems to me that the whole ble
member is recently added in v3.3, right? Is that something that could gain more functionality in the future, such as some generic scan
/ connect
methods to connect to peripheral devices?
Yes, it's definitely a step in the right direction. Indeed, the scanning procedure has been prepared for more generic use in the future.
If someone can sort this out and support both Xbox series, and PlayStation 5 controllers at minimum. I would make a donation to both pybricks and the individual developer of $500.00 each. Must be completed no later then end of Q1 2024.
@mozts2005 that's a generous offer, thanks! @laurensvalk, any chance of giving this some priority? As I said earlier, if the base BLE connectivity code would be there in some generic reusable form, I'd be happy to help with sorting out higher level HID processing part and @westurner might also be interested in helping in. And I'd not be doing it for the money, would even be okay with donating my part (if any) to PyBricks developers.
I don't know if you guys follow this Eurobricks thread about improving Powered Up stuff, but one of the top things that many people complain about is the lack of proportional physical remote, or any kind of 3rd party alternative that can be used without a smart device, so I'd argue that there is more interest than visible from these discussions here on Github. https://www.eurobricks.com/forum/index.php?/forums/topic/195601-lets-fix-powered-up/
Thanks @mozts2005! Let's see if we can make this happen. Would you mind dropping a note at team@pybricks.com? I'd like to confirm a few details to be sure. Thanks!
Thanks also @gyenesvi for your kind follow-up. We are indeed aware of community comments about this. To drop a bit of a hint, we are actively working on a huge update behind the scenes. It will address another big request from the community (perhaps even more popular than Bluetooth). :smile:
That's promising and interesting to hear @laurensvalk, thanks, and keep us posted about the developments!
What's the resolution of this? I see it marked completed, but with what action? Is the investigation completed, or is the feature actually implemented?
Sorry, that must have happened accidentally as I was moving other linked issues around. Rest assured, this is still on our list :smile:
Okay, thanks!
If someone can sort this out and support both Xbox series, and PlayStation 5 controllers at minimum. I would make a donation to both pybricks and the individual developer of $500.00 each. Must be completed no later then end of Q1 2024.
Originally posted by @mozts2005 in https://github.com/pybricks/support/issues/1024#issuecomment-1712963131
I hope the current version meets your needs partially! No matter what you decide, I hope you enjoy the new update :slightly_smiling_face:
All Xbox series controllers since 2016 are supported. With Technic Hub, Spike Prime Hub, Spike Essential Hub, and Mindstorms Robot Inventor Hub.
Playstation 5 may have to wait until (if) Sony enables BLE in a future update.
Sorry, that must have happened accidentally as I was moving other linked issues around. Rest assured, this is still on our list 😄
So this happened... because the internal preview automatically closed this issue!
:tada: Go check it out! :tada:
FWIU, the 8bitdo USB adapters remap all of the supported controllers to an Xbox controller.
8BitDo controllers and arcade sticks
- Xbox Series X | S, Xbox One Bluetooth controllers
- PS5, PS4, PS4 Pro, PS3 controllers
- Switch Pro, Switch Joy-Con, Wii U Pro, Wiimote
Special Features
- Vibration support on X-input mode ³
- 6-axis motion on Switch X-input, D-input, Mac mode, Switch mode Upgradable firmware
- Virtually lag-free
Steam Input also remaps to what looks like an Xbox controller FWICS.
How much work is there to add additional BLE GATT HIDs so that other controllers work?
On Fri, Feb 16, 2024, 7:25 AM laurensvalk @.***> wrote:
If someone can sort this out and support both Xbox series, and PlayStation 5 controllers at minimum. I would make a donation to both pybricks and the individual developer of $500.00 each. Must be completed no later then end of Q1 2024.
Originally posted by @mozts2005 https://github.com/mozts2005 in #1024 (comment) https://github.com/pybricks/support/issues/1024#issuecomment-1712963131
I hope the current version meets your needs partially! No matter what you decide, I hope you enjoy the new update 🙂
All Xbox series controllers since 2016 are supported. With Technic Hub, Spike Prime Hub, Spike Essential Hub, and Mindstorms Robot Inventor Hub.
Playstation 5 may have to wait until (if) Sony enables BLE in a future update.
Sorry, that must have happened accidentally as I was moving other linked issues around. Rest assured, this is still on our list 😄
So this happened... because the internal preview automatically closed this issue!
🎉 Go check it out! 🎉
[image: preview] https://www.youtube.com/watch?v=fxInp9cutNg
— Reply to this email directly, view it on GitHub https://github.com/pybricks/support/issues/1024#issuecomment-1948294595, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAMNSYPM4SKF7AQFLIP7QTYT5F2LAVCNFSM6AAAAAAWQGT2TKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBYGI4TINJZGU . You are receiving this because you were mentioned.Message ID: @.***>
We've generalized the BLE code considerably, so I'm quite open to adding a few more gamepads. My preference would be gamepads that are somewhat mainstream and easy enough to get worldwide.
We had some serious challenges getting the Xbox Controller pairing/bonding process to work with the Technic Hub, and it could still be better. So having HID over BLE is no guarantee, but certainly worth a try.
This is a really nice addition to pybricks. Is rumble supported? I think that it would be funny as a "beeping" for driving backwards or as a distance sensor indication that some object is close to the vehicle. Or maybe for some interactive games that use the hubs.
Regarding future supported controllers: one that's probably widely available is the amazon luna controller. It's often on sale for about half the price. Other ones like the google stadia controller or the steam controller are discontinued. Another BLE controller that's pretty new and will be available for a while is the 8bitdo neogeo wireless controller.
Is rumble supported?
Not yet, but it could be. We have also generalized the internal "bluetooth write" function. We'd just need to figure out the right combination of commands to send. Same thing for the light, which should be full RGB.
Is rumble supported?
Not yet, but it could be. We have also generalized the internal "bluetooth write" function. We'd just need to figure out the right combination of commands to send. Same thing for the light, which should be full RGB.
I think that the light is RGB for the elite 2 controller but not for the other xbox controllers. I'm not sure tho. Some of them also have multiple rumble motors in different positions. This might be a bit too much, but in theory it should be possible to control the motors independently
So this happened... because the internal preview automatically closed this issue!
This is amazing news guys, thanks a lot for implementing this! On top of that the code blocks are also a very nice new feature that makes the use case of the Xbox controller even more easy to start using for many people :)
I have tested it and it works well, even though in the beginning I had some problems with the website; it was loading assets very slowly (images, icons, even text), not showing much (I don't think it was my internet connection, I did a speedtest), and on top of that it occasionally went completely blank, unable to recover, had to reload the page. But it seems it got stabilized over time, probably due to caching..
Anyways, the controller works fine. I'd have a few questions/suggestions though.
It seems currently that it is not supported on the city hub, is that due to HW limitation? Too small memory/processing power?
Its Bluetooth chip firmware (separate from the main firmware) does not appear to have certain security features enabled like bonding, which the Xbox Controller requires. Before I started this endeavor, I did not know that the Technic Hub would, either. I went for it anyway, and I'm glad about it now :)
It took me some time to remember that it disconnects from the Technic Hub when the Xbox controller is connected, and I loose print commands that I wanted to use for debugging
We hope to improve this in the future. Would you mind adding your findings to #1462? It would be great to have more data points.
I saw the motor class has accessible parameters for the pid controller. Can you give some hints what parameters I should tune (in which directions) if I wanted to make the steering more aggressive/responsive?
This would probably be worth asking in a different issue for more detail. You could print the current values and then set double the default kp as a starting point.
As for such calibration, does that need to run every time the hub is turned on?
Technically, no. But the Car
class is a new addition intended to make steering cars very easy to do, so we just initialize every time. But motors have an option during init to skip the reset. If your steering motor needs to run less than 360, you could also rely on the absolute encoder value. Feel free to make a dedicated issue about this with suggestions and ideas as well. The main thing would be to add some sort of UI for deciding when to calibrate or not. Only the first time after boot? Only if the button is pressed? And so on.
Would you mind adding your findings to https://github.com/pybricks/support/issues/1462?
Sure, I will do that, good to see that I can experiment with staying connected. Will post the results.
I'll create some issues with proposals for the rest then!
One thing I wonder though is how to use the absolute angle of the motor. There is only an 'angle' query method for the motor class as I see, and that one gets the accumulated position, is that right? Is there no way to directly get the absolute position? The only way I see is resetting the accumulated position to the absolute position, and then querying that..
Since support for other controllers comes up frequently, here is a good overview of BLE models.
The list isn't very long, so we'll probably just keep using Xbox.
Since support for other controllers comes up frequently, here is a good overview of BLE models.
The list isn't very long, so we'll probably just keep using Xbox.
It's not complete tho. As far as I know, other BLE controllers are Amazon Luna, 8Bitdo NeoGeo (the other 8Bitdo Controllers are BTC) and multiple mobile ones (Flydigi Apex 2, Steelseries Stratus+, Ipega 9078, Ipega 9083S, Nacon MG-X Pro, Razer Jaiju Mobile, PowerA Moga XP5-A, FlyDigi FeiZhi APEX, Saitake 7007f, asus rog kunai 4, Razer Junglecat, Mad Catz C.T.R.L.R. and more). I think that xbox controllers are by far the most common ones in that list. But there might be cheaper ones.
Good news, we can support the rumble/vibration function too!
The following example roughly covers all the functionality we can get. Suggestions for specific APIs or alternate commands are welcome.
from pybricks.iodevices import XboxController
from pybricks.tools import wait
# Set up all devices.
controller = XboxController()
# All actuators at 100% power for 250ms, delay 150ms, do this 3 times:
controller.rumble(power=100, duration=250, delay=150, count=3)
wait(2000)
# Left handle 10%, right handle 15%, left trigger 100%, right trigger 0%, do it once.
controller.rumble(power=[10, 15, 100, 0], duration=100, delay=0, count=1)
wait(2000)
That's a nice addition! Only wonder if there's a more intuitive/readable way to provide ramble power in an individual way for handles/triggers. Maybe a dictionary to name them explicitly? Also, the parameter 'number' sounds a bit too generic to me, could mean anything. I'd use 'count' or 'times', they sound more intuitive to me, but that may only be my preference.
Only wonder if there's a more intuitive/readable way to provide ramble power in an individual way for handles/triggers. Maybe a dictionary to name them explicitly?
Using a tuple for this sort of thing is common throughout the API, e.g. light brightness for the 4 lights on the ultrasonic sensor, and so on. We usually try to strike a balance between verbosity and ease of use. Tuples have other advantages too, since you can do something like:
# Your own feedback constants
COLLISION = [100, 100, 0, 0]
SPEED_FEEDBACK = [0, 0, 50, 50]
And then use these in different parts of your program with power=SPEED_FEEDBACK
instead of repeating left_handle_power=0, right_handle_power=0, left_trigger_power=50, right_trigger_power=50
everywhere.
number
is now updated to count
.
Tuples have other advantages too, since you can do something like:
Your own feedback constants COLLISION = [100, 100, 0, 0] SPEED_FEEDBACK = [0, 0, 50, 50]
number is now updated to count.
FUN
I tried to get all arguments for the rumble call into one constant. But I did not succeed. An example:
# use a constant tuple plus arguments: WORKS
controller.rumble(COLLISION, 250, 150, 3)
wait(2000)
# This one DOES NOT WORK
COLLISION_PLUS_3 = (COLLISION, 250, 150, 3)
controller.rumble(COLLISION_PLUS_3)
The second one complains:
Traceback (most recent call last):
File "xbox_rumble_issue_1024.py", line 64, in <module>
TypeError: 'duration' argument required
What obvious notation do I miss? A simple user function could provide defaults like
def do_rumble(power, duration=250, delay=0, count=1):
controller.rumble(power, duration, delay, count)
I tried toI tried to get all arguments for the rumble call into one constant. get all arguments for the rumble call into one constant.
Why would you like to do that? There is a way to do that in Python by unpacking kwargs with *, but this is unrelated to this rumble API.
A simple user function could provide defaults like
I considered leaving a few values at default, but I'm not sure what those should be in "most" cases.
Any suggestions? duration and delay at 150ms? count at 1 or two?
Using a tuple for this sort of thing is common throughout the API
Sure, if that's the convention then it's fine by me. By the way, that is a list not a tuple, but I guess they are interchangeable here, and in most places in the API?
My other suggestion would have been to add further keyword arguments like left_handle_power
as you mention, that would be None
by default and would override the power
for that one handle if it is provided. This way either or both notations could be used, whichever the user likes. But that might be a bit over-engineered..
number is now updated to count
Great, thanks!
I agree that some defaults could be useful. count
should definitely be 1, and in that case delay
is irrelevant. Maybe duration
and delay
both around 250ms, but I have not tested this yet, don't know how it feels.
BTW, where can I access the latest build? I mean not just this one, but in general, how do I find it? I tried yesterday but could not decide which one it is.
What obvious notation do I miss?
You need to write controller.rumble(*COLLISION_PLUS_3)
, but not sure this approach helps with readability..
Why would you like to do that? There is a way to do that in Python by unpacking kwargs with *, but this is unrelated to this rumble API.
OK, (thanks Victor)
I considered leaving a few values at default, but I'm not sure what those should be in "most" cases.
Any suggestions? duration and delay at 150ms? count at 1 or two?
No suggestions from me, Laurens. Just enjoying the new possibilities.
One more question about the rumble method. Does it wait for all iterations (counts) to be complete? If I do a ruble with count=5 at the end of a program, I feel only two. With a wait(5000) behind it I notice all 5 of them. An example:
ZIG = [100, 100, 0, 0]
controller.rumble(ZIG, 400, 200, 5)
Does it wait for all iterations (counts) to be complete?
That's a good question, and I think it could be useful to have a wait
parameter, like other methods. Could it? Otherwise, it may be harder to guess how much waiting is actually required to be inserted afterwards to get just enough to move on with the program after all the rumbles have been done.
that is a list not a tuple
Either will work.
This way either or both notations could be used, whichever the user likes.
As with most things, it's usually better if there is just one way to do one thing. I think you answered it very well :smile: :
But that might be a bit over-engineered..
Does it wait for all iterations (counts) to be complete?
I've been wondering about this, but I haven't decided what it should do.
I'll also have to check what the controller does if you send something before the previous one completes.
I'll also have to check what the controller does if you send something before the previous one completes.
Did a few more after each other:
print("do (ZIG, bla bla)", 1)
controller.rumble(ZIG, 400, 200, 25)
print("do (ZIG, bla bla)", 2)
controller.rumble(ZIG, 400, 200, 25)
print("do (ZIG, bla bla)", 3)
controller.rumble(ZIG, 400, 200, 25)
print("do (ZIG, bla bla)", 4)
controller.rumble(ZIG, 400, 200, 25)
print("do (ZIG, bla bla)", 5)
controller.rumble(ZIG, 400, 200, 25)
print("do (ZIG, bla bla) ready")
Results in one time two rumbles and the prints come out:
do (ZIG, bla bla) 1
do (ZIG, bla bla) 2
do (ZIG, bla bla) 3
do (ZIG, bla bla) 4
do (ZIG, bla bla) 5
do (ZIG, bla bla) ready
Conclude that (all?) rumbles are ignored and the program just runs on. Do you want more testing like this?
I will have a detailed look at it later, but you're probably seeing that the controller disconnects/turns off when the program ends :wink:
You might also want to use the four actuators separately to see if the commands are additive, ignored, or overriding the previous one.
I will have a detailed look at it later, but you're probably seeing that the controller disconnects/turns off when the program ends 😉
That is not the case, I think. The xbox button stays lit until the program ends. Feels like the following rumbles are just skipped. Will test with the separate actuators.
Laurens, make a separate (discuss) item of this rumble testing? This item is already long as it is.
BTW, where can I access the latest build? I mean not just this one, but in general, how do I find it? I tried yesterday but could not decide which one it is.
Victor, does this help you?
Go to pybricks-micropython and to the actions
tab.
There on the left side choose "Build" to see the build tasks on the right side.
You can take the build of your choice there.
Within the build task, browse down to Artifacts
and download the firmware for your hub(s)
Bert
Victor, does this help you?
Thanks, yes, found it. However, I don't see the artifact for the Inventor hub. Is that the same as for the Prime hub?
However, I don't see the artifact for the Inventor hub. Is that the same as for the Prime hub?
They are identical for 99.99999 % Only LEGO apps show the difference.
I have been testing on an Inventor hub, it works okay but here are my findings.
Setting power=100
does not make all actuators rumble (as said above), only the handles, but not the triggers. But that's okay that way I guess for a default, because the trigger rumble feels a bit too much for the base case.
250 ms duration feels like a good default for me.
However, I am getting a lot of connectivity errors:
Often I tried without turning the controller off and on again as it was still blinking. Maybe when I turn it off completely and then on again it becomes more stable, errors happen less often, but still happen.
Don't know if this is because now I am testing with an Inventor hub instead of a technic one (because I wanted to see things printed) and that one stays connected to the computer. Or maybe the same problems would arise on the Technic hub but I would not see the errors being printed.. I could test again when that connectivity issue with the Technic hub is resolved, maybe that solves some of these as well.
Victor, currently I (also) use a spikehub.
Often I tried without turning the controller off and on again as it was still blinking. Maybe when I turn it off completely and then on again it becomes more stable, errors happen less often, but still happen.
In my case the controller always switches off at the end of the program. Maybe you have a long way at the end of the program, or do you stop the program crtl-C in the log window? In the crtl-C case you go into the REPL so the controller knows the program is still running (has a connection) and the controller stays ON.
"RuntimeError: Unknown error": I realized that if I stop the program and restart it and turn on the controller then this can happen
Happens here from time to time.
[EDIT] Once I was wanted at the door and left the test situation unattended. When I came back the hub seemed running, was disconnected from the pc. The controller was OFF. So I needed to stop the hub by long pressing the center button. Resulted if fast blinking of the hub. So needed to remove the battery. Tried to recreate without success.
Maybe you have a long way at the end of the program, or do you stop the program crtl-C in the log window?
Yeah, my test program often contains an infinite loop for the controller, so I have to stop it with the stop button in the browser. I think the controller stays on if the program ends with an error, and then it fails with higher probability the next time when trying to connect then if the program is stopped properly, the controller shuts down and needs to be powered up again.
This is a spot for discussing gamepad connections, split off from https://github.com/pybricks/support/issues/262