Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to read differents device modes #56

Closed
wants to merge 3 commits into from

Conversation

aileo
Copy link
Contributor

@aileo aileo commented Nov 21, 2019

This is not ready to be merged, working on #55 took me further than I expected and I ended trying to read every input mode from every device I have.

Now I need help/advice/review to check what I did wrong and test devices I don't have (WeDo2 hub and accessories, Duplo train base)

To handle different data from different mode I added several events:

  • BOOST_DISTANCE
    • count
    • reflectivity
    • luminosity
    • rgb
  • Motors
    • power
    • speed
    • absolutePosition
  • BOOST_TILT
    • angle
    • orientation
    • impact
    • accel

Using the debug output I summed up mode numbers and names for each hub.
The bad news is: the same device on different hubs does not expose exactly the same modes.

Color and distance

HUB 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a
WEDO2_SMART_HUB ? ? ? ? ? ? ? ? ? ? ?
BOOST_MOVE_HUB COLOR PROX COUNT REFLT AMBI COL_O RGB_I IR_Tx SPEC_1 DEBUG CALIB
POWERED_UP_HUB COLOR PROX COUNT REFLT AMBI COL_O RGB_I IR_Tx SPEC_1 DEBUG CALIB
CONTROL_PLUS_HUB COLOR PROX COUNT REFLT AMBI COL_O RGB_I IR_Tx SPEC_1 DEBUG CALIB

Motors

BASIC_MOTOR

HUB 0x00
WEDO2_SMART_HUB ?
BOOST_MOVE_HUB LPF2-MMOTOR
POWERED_UP_HUB LPF2-MMOTOR
CONTROL_PLUS_HUB LPF2-MMOTOR

BOOST_TACHO_MOTOR

HUB 0x00 0x01 0x02 0x03
WEDO2_SMART_HUB ? ? ? ?
BOOST_MOVE_HUB POWER SPEED POS TEST
POWERED_UP_HUB POWER SPEED POS
CONTROL_PLUS_HUB POWER SPEED POS

BOOST_MOVE_HUB_MOTOR

HUB 0x00 0x01 0x02
BOOST_MOVE_HUB POWER SPEED POS

CONTROL_PLUS_LARGE_MOTOR / CONTROL_PLUS_XLARGE_MOTOR

HUB 0x00 0x01 0x02 0x03 0x04 0x05
WEDO2_SMART_HUB ? ? ? ? ? ?
BOOST_MOVE_HUB POWER SPEED POS APOS CALIB STATS
POWERED_UP_HUB POWER SPEED POS APOS LOAD CALIB
CONTROL_PLUS_HUB POWER SPEED POS APOS LOAD CALIB

Tilt/accel sensors

Internal

HUB Port 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
BOOST_MOVE_HUB 0x3a ANGLE TILT ORINT IMPCT ACCEL OR_CF IM_CF CALIB
CONTROL_PLUS_HUB 0x62 ROT
CONTROL_PLUS_HUB 0x63 POS IMP CFG

WeDo tilt sensor

???

Copy link
Contributor

@nutki nutki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing this. I was thinking of doing similar extensions. Good job on investigating output of all those device modes.

break;
}

case Consts.BoostTiltModes.ACCEL: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes the API incompatible since previously this mode, which is the default mode for this sensor was reported as "tilt".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what should be done as it breaks but on the other hand, it use information from the lego side which should be "the truth".

There is a lot of changes in this PR and it definitly could not be merge without a new major version.

const mode = this._getModeForDeviceType(this._portLookup(port).type);
this._deactivatePortDevice(this._portLookup(port).value, this._portLookup(port).type, mode, 0x00, () => {
const { type, value, mode } = this._portLookup(port);
this._deactivatePortDevice(value, type, mode || this._getModeForDeviceType(type), 0x00, () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will switch the port mode to the default for type (_getModeForDeviceType) if the mode is 0 since 0 is falsy.
Technically it should be mode === null but this could only happen when you call unsubscribe before subscribe, so not sure if that should be handled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure to understand how subscriptions work: I don't get why mode is needed to unsubscribe...

@@ -17,6 +18,7 @@ export class Port {
this.id = id;
this.value = value;
this.type = Consts.DeviceType.UNKNOWN;
this.mode = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is mode also cleared on device reconnect? If not it could lead into one device "inheriting" the mode of the previous device if you don't use autoSubscribe (which will reset it to default for the device on attach).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not because the mode would be overwritten by the next subscribe (either auto or not, you have to recall subscribe when device change).

However, that's a good point regarding consistency so I fixed it in 3bc8404 . It can also be used to know if the devices already have a subscription.

@nutki
Copy link
Contributor

nutki commented Nov 21, 2019

Here is the mode info for WeDo 2.0 tilt sensor (it does not seem to be able to return the raw accelerometer reading like the boost internal sensor):

90842b0e7cad Port 01, type 0022 (WEDO2_TILT)
90842b0e7cad Port 01, hardware v1.0.00.0000, software v1.0.00.0000
90842b0e7cad Port 01, total modes 4, input modes 1111, output modes 0000
90842b0e7cad Port 01, mode combinations []
90842b0e7cad Port 01, mode 0, name LPF2-ANGLE
90842b0e7cad Port 01, mode 0, RAW min -45, max 45
90842b0e7cad Port 01, mode 0, PCT min -100, max 100
90842b0e7cad Port 01, mode 0, SI min -45, max 45
90842b0e7cad Port 01, mode 0, SI symbol DEG
90842b0e7cad Port 01, mode 0, Value 2 x 8bit, Decimal format 3.0
90842b0e7cad Port 01, mode 1, name LPF2-TILT
90842b0e7cad Port 01, mode 1, RAW min 0, max 10
90842b0e7cad Port 01, mode 1, PCT min 0, max 100
90842b0e7cad Port 01, mode 1, SI min 0, max 10
90842b0e7cad Port 01, mode 1, SI symbol DIR
90842b0e7cad Port 01, mode 1, Value 1 x 8bit, Decimal format 2.0
90842b0e7cad Port 01, mode 2, name LPF2-CRASH
90842b0e7cad Port 01, mode 2, RAW min 0, max 100
90842b0e7cad Port 01, mode 2, PCT min 0, max 100
90842b0e7cad Port 01, mode 2, SI min 0, max 100
90842b0e7cad Port 01, mode 2, SI symbol CNT
90842b0e7cad Port 01, mode 2, Value 3 x 8bit, Decimal format 3.0
90842b0e7cad Port 01, mode 3, name LPF2-CAL
90842b0e7cad Port 01, mode 3, RAW min -45, max 45
90842b0e7cad Port 01, mode 3, PCT min -100, max 100
90842b0e7cad Port 01, mode 3, SI min -45, max 45
90842b0e7cad Port 01, mode 3, SI symbol CAL
90842b0e7cad Port 01, mode 3, Value 3 x 8bit, Decimal format 3.0

And WeDo 2.0 distance sensor

90842b0e7cad Port 01, type 0023 (WEDO2_DISTANCE)
90842b0e7cad Port 01, hardware v1.0.00.0000, software v1.0.00.0000
90842b0e7cad Port 01, total modes 3, input modes 111, output modes 000
90842b0e7cad Port 01, mode combinations []
90842b0e7cad Port 01, mode 0, name LPF2-DETECT
90842b0e7cad Port 01, mode 0, RAW min 0, max 10
90842b0e7cad Port 01, mode 0, PCT min 0, max 100
90842b0e7cad Port 01, mode 0, SI min 0, max 10
90842b0e7cad Port 01, mode 0, SI symbol 
90842b0e7cad Port 01, mode 0, Value 1 x 8bit, Decimal format 3.0
90842b0e7cad Port 01, mode 1, name LPF2-COUNT
90842b0e7cad Port 01, mode 1, RAW min 0, max 100
90842b0e7cad Port 01, mode 1, PCT min 0, max 100
90842b0e7cad Port 01, mode 1, SI min 0, max 100
90842b0e7cad Port 01, mode 1, SI symbol CNT
90842b0e7cad Port 01, mode 1, Value 1 x 32bit, Decimal format 4.0
90842b0e7cad Port 01, mode 2, name LPF2-CAL
90842b0e7cad Port 01, mode 2, RAW min 0, max 1023
90842b0e7cad Port 01, mode 2, PCT min 0, max 100
90842b0e7cad Port 01, mode 2, SI min 0, max 1023
90842b0e7cad Port 01, mode 2, SI symbol RAW
90842b0e7cad Port 01, mode 2, Value 3 x 16bit, Decimal format 3.0


case Consts.BoostTiltModes.TILT: {
values.push(data[4]);
event = 'tilt';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this mode the sensor returns a discrete direction of tilt (1, 3, 5, or 7) for each major direction as far as I remember. This is not a very useful mode IMO, but previously the 'tilt' event was reporting acceleration (boost and control+ hubs) or angles (wedo sensor), so this is another change to the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to admit that I don't know either why this mode exists as it could be calculated from angle...

Maybe to save some power and require angle only when you have a tilt trigger ?

src/lpf2hub.ts Outdated Show resolved Hide resolved
@@ -7,3 +7,6 @@ export function toHex (value: number, length: number = 2) {
export function toBin (value: number, length: number = 8) {
return value.toString(2).padStart(length, "0");
}
export function toDistance(value: number, partial: number = 1) {
return Math.floor((value + 1 / Math.max(partial, 1)) * 25.4) - 20;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note this changes the result when partial is 0. In the old code nothing was added to the inch distance, now you add 1. I am not sure what is the source for the previous formula (I am guessing empirical reverse engineering). At least after the change the result is not negative as often.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just trying to make it a nice oneliner but I missed that is add 25.4 to the final result. It makes the result >5.4 in any case.

I did not understood that partial value so I tried to get more information. According to a comment on eurobricks from @dlech, the format would be:

<COLOR CODE> <DISTANCE> <LED COLOR> <REFLECTED LIGHT>

If this right, the result should differ by ~24.5 for obstacles with significant reflectivity gap at the same distance.

It also explain why that partial is not part of the distance mode data. So SPEC_1 and PROX mode does not get the same accuracy in this implementation. I guess the formula should be removed for consistency ?

@aileo
Copy link
Contributor Author

aileo commented Dec 6, 2019

this is outdated by #60

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants