ev3dev / ev3dev

ev3dev meta - bug tracking, wiki and releases
http://www.ev3dev.org
GNU General Public License v2.0
630 stars 85 forks source link

DexterIndustries dGPS implementation questions #465

Open bmegli opened 8 years ago

bmegli commented 8 years ago

I got dGPS as a gift and almost finished the driver. I have some questions. Probably to @dlech since he has implemented the whole I2C architucture.

dGPS is I2C device designed for NXT with some quirks:

  1. It doesn't follow LEGO guidelines (reports UTC time in LEGO firmware version register etc.)
  2. It should not be polled more often than 500 ms (or even 1000 ms).
  3. It has 2 commands with 4 byte data where one writes target longitude/latitude and device reports also heading/distance to this place
  4. It has command that enables extended firmware which enables 3 additional "modes"

Here's dGPS manual, just in case:

http://www.dexterindustries.com/manual/dgps-2/

This is how I did it/would do it:

  1. Driver can be loaded only manually.
  2. In nxt_i2c_sensor_info.ops.probe_cb set correct initial polling or even replace nxt_i2c_sensor_data->sensor.set_poll_ms to custom function implementation
  3. I would just leave it for direct attribute use. The other idea is to add command_data sys fs attribute which can be written to and may be used when using commands. This would be only for this sensor so not the best idea.
  4. If the extended firmware is not enabled those I2C registers return UTC time so I made EXT (e.g. EXT_ALT for altitude) modes that, for instance, return altitude if extended firmware is enabled and UTC time if it is not not.

My main question here is to polling time. How does slow work for I2C devices? I can't find the code for EV3 but can can for BrickPI for example. Can it be used for limiting polling time? Is the aproach I want to use ok (setting correct polling in ops.probe_cb or replacing the set_poll_ms pointer)?

bmegli commented 8 years ago

One more thing: my dGPS unit is unable to get sattellites signal for some reason so I am going to hold the driver until I get this working or the unit replaced.and can test everything in action.

dlech commented 8 years ago

Since this sensor does not fit the usual LEGO sensor format at all, I would be tempted to just label this as "Other/I2C" instead of "NXT/I2C" and not provide a driver.

Instead, I would suggest making a tutorial page (in Python and/or C) showing how to use the sensor using an smbus library.

You can add the sensor here so that is show up on the ev3dev.org website in the list of sensors.

bmegli commented 8 years ago

@dlech

Yes, thanks. That is one option.

Since this sensor does not fit the usual LEGO sensor format at all, I would be tempted to just label this as "Other/I2C" instead of "NXT/I2C" and not provide a driver

It is not that bad actually. The documentation tells about sending/receiving messages on I2C bus but this is not true. It only looks like that because it was written from NXT I2C programming framework perspective (like one would do it from NXT).

In fact you just read from I2C registers. It is somewhat confusing - the memory areas seem to overlap but the data returned on I2C is simply generated "on demand" as you read from the register.

Instead, I would suggest making a tutorial page (in Python and/or C) showing how to use the sensor using an smbus library.

Possible but only few persons would use it. To make it harder it's big endian and one mode is 32 bit signed int where only 3 bytes should be read from I2C.


To sum up - it fits the framework but not perfectly. It was enough to add signed 32 bit big endian data type, fill the "template" in your I2C kernel driver architecture and add custom poll callback (to handle 3 bytes read for 4 bytes big endian int). One last thing to be done would be setting initial polling time to 1000 ms in optional probe callback.

I already have it working on my EV3 through NXT/I2C on custom kernel. The readings are correct (I had GPS signal the first day) but I haven't tested velocity and angle when it was working.

The commands with longitude/latitude data can be ignored (left for direct use). This is in fact what Dexter Industries did for EV3 LabView software as far as I know (one can't use this feature).

Anyway - it's you to decide. I have it working for myself anyway ;-) (or will have when I resolve GPS signal issues with Dexter Industries)

dlech commented 8 years ago

Another option would be to use the new "user-mode" sensors system. I presume that you are reading all of the values at once, which requires many I2C messages, which in turn makes the polling time so long. If you went with the user-mode sensor option, the use could select exactly which values they want to read via a configuration file instead of having to read all values.

bmegli commented 8 years ago

Another option would be to use the new "user-mode" sensors system. I presume that you are reading all of the values at once, which requires many I2C messages, which in turn makes the polling time so long

Currently one value at a time mode dependent. Dexter Industries claims (John) on its forum in many threads that it musn't be polled too often. My experiements support that. If polling too often it either doesn't update or I get garbage every now and then.

I suppose it has something to do with generating data in response to I2C read. When polled too often it doesn't seem to be doing what it should internally.

From my inspection of other drivers (RobotC for NXT, arduino dgps shield code by Dexter Ind which seems similiar IC) it is ok to read more values one by one and wait 500/1000 ms before next batch read.

Anyway, I am not going to post it anytime soon (untiI I resolve signal problems and test everything).

kortschak commented 6 years ago

@bmegli I've just had a go at providing a type for handling this with ev3go, without success (this is the first time I've delved into I²C). I've taken details from the python that Dexter Industries provide. The code fails at the first call to the underlying library's transaction method with the following:

$ ./gps -port in3
2017/09/27 21:43:33 error getting satellite link status: sysfs-i2c: no such device or address
$ ls -l /dev/i2c-*
crw-rw---- 1 root i2c  89, 1 Jan  1  1970 /dev/i2c-1
crw-rw---- 1 root i2c  89, 5 Jan  1  1970 /dev/i2c-5
lrwxrwxrwx 1 root root     5 Jan  1  1970 /dev/i2c-in3 -> i2c-5

The failure there happens in the library here which ends up here with parameters as follows:

syscall.Syscall(syscall.SYS_IOCTL, 0x3, uintptr(0x707), 0x10439d74)

returning

errno=6

This is a representation of the data being sent in the transaction sysfs.rdwrIoctlData{msgs:0x104120e0, nmsgs:0x2} which points to these two messages:

[{addr:6 flags:0 length:3 buf:272670804} {addr:6 flags:1 length:1 buf:272670811}]

Inserting i2c-dev makes no difference.

Can you see anything wildly wrong before I ask the authors of the periph.io library since they won't likely have an EV3 or a dGPS - so I'd like to get the hardware details sorted before I go there to ask what I'm doing wrong with the library setup.

dlech commented 6 years ago

It could the that the I2C adapter on the EV3 doesn't support I2C_RDWR. Try using the SMBus functions instead.

dlech commented 6 years ago

Also, where did you get the address of 6?

kortschak commented 6 years ago

It could the that the I2C adapter on the EV3 doesn't support I2C_RDWR. Try using the SMBus functions instead.

I'm unable to find any SMBus-supporting libs for Go.

Also, where did you get the address of 6?

From this code.

dlech commented 6 years ago

Use 6 >> 1 for the address.

I2C addresses are 7-bit. Bit 0 is a flag for read/write. In Linux, the address is >> 1 to drop that bit.

dlech commented 6 years ago

This might be a useful reference

https://github.com/botbench/robotcdriversuite/blob/master/include/dexterind-gps.h

kortschak commented 6 years ago

Changing the address to 3 fixed the problem. Thanks.

Now just waiting for it to find satellites.

kortschak commented 6 years ago

Even with satellites (according to the status LED) the results it returns are not meaningful. Without fear of doxing my location I can post this:

$ ./gps -port in3
GPS-X response: [8 67 99]
satellite link ok=false
satellites in view: 82044
satellite HDOP=82044
satellite time=2017-09-28 08:20:44 +0000 UTC
82044° 82044° 82044m 320cm/s 1°
82047m 1° 1°

What appears to be happening is that a single set of bytes (that seems to monotonically increases) is being returned. I think now it's time to head over to the dexter forum.

kortschak commented 6 years ago

Ahhh. The UTC value is correct. This explains the monotonicity. I suspect that I'm sending the wrong bytes at some point.

bmegli commented 6 years ago

Hi @kortschak,

I have somewhere locally nxt_i2c_sensors_defs with filled dgps.

It was working and returning correct position. dGPS worked correctly only if polled slowly (e.g. once a second). Then my dGPS stopped finding satellites at all and I got distracted with other things.

I have found it:

/*
 * Dexter Industries dGPS related functions
 */

 static void di_dgps_poll_cb(struct nxt_i2c_sensor_data *data)
 {
    const struct nxt_i2c_sensor_mode_info *i2c_mode_info =
        &data->info->i2c_mode_info[data->sensor.mode];
    struct lego_sensor_mode_info *mode_info =
            &data->sensor.mode_info[data->sensor.mode];

    /* In SPEED mode only 3 big endian bytes should be read  */
    if(data->sensor.mode==4)
    {
        mode_info->raw_data[0]=0;
        i2c_smbus_read_i2c_block_data(data->client,
            i2c_mode_info->read_data_reg,
            3,
            mode_info->raw_data+1);
    }
    else
        i2c_smbus_read_i2c_block_data(data->client,
            i2c_mode_info->read_data_reg,
            lego_sensor_get_raw_data_size(mode_info),
            mode_info->raw_data);       

 }
    [DI_DGPS] = {
        /**
         * [^di_ids]: Dexter Industries dGPS doesn't follow LEGO guidelines by
         * returning vendor, product and firmware version values. As a
         * result, this sensor can't be automatically detected. Until
         * we find another way to identify the sensor, the driver has to
         * be loaded manually.
         *
         * Register I2C device:
         * <pre>
         * echo di-dgps 0x03 > /sys/bus/i2c/devices/i2c-<port+2>/new_device
         * </pre>
         *
         * @vendor_name: Dexter Industries
         * @vendor_part_number:
         * @vendor_part_name: dGPS for Lego Mindstorms NXT EV3
         * @vendor_website: http://www.dexterindustries.com/shop/dgps/
         * @default_address: 0x03
         * @vendor_id_footnote: [^di_ids]
         * @product_id_footnote: [^di_ids]
         */
        .name       = DI_DGPS_NAME,
        .vendor_id  = "dexind", /* The sensor doesn't return vendor_id, it can't be autodetected this way */
        .product_id = "dgps",  /* The sensor doesn't return product_id, it can't be autodetected this way */
        .num_modes  = 12,
        .ops        = &(const struct nxt_i2c_sensor_ops) {
            .poll_cb    = di_dgps_poll_cb,
        },      
        .mode_info  = (const struct lego_sensor_mode_info[]) {
            [0] = {
                /**
                 * [^utc]: The UTC time is encoded in integer value as HHMMSS
                 *
                 * @description: Time in UTC
                 * @value0: hhmmss
                 * @units_description: hhmmss
                 * @units_footnote: [^utc]
                 */
                .name       = "TIME",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,              
                .data_sets  = 1,
                .data_type  = LEGO_SENSOR_DATA_S32_BE,
                .decimals   = 0,
                .figures = 6,
            },
            [1] = {
                /**
                 * @description: GPS status
                 * @value0: connection status (0/1)
                 * @units_description: no/yes
                 */
                .name       = "STATUS",
                .raw_min = 0,
                .raw_max = 1,
                .si_min = 0,
                .si_max = 1,                
                .data_sets  = 1,
                .data_type  = LEGO_SENSOR_DATA_S8,
                .decimals   = 0,
                .units      = "0/1",
            },
            [2] = {
                /**
                 *[^integer-latitude-units]: to do
                 *
                 * @description: Latitude
                 * @value0: Integer Latitude (-90000000 to 90000000)
                 * @units_description: integer degrees 
                 * @units_footnote: [^integer-latitude-units]
                 */
                .name       = "LAT",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,              
                .data_sets  = 1,
                .units      = "deg",
                .data_type  = LEGO_SENSOR_DATA_S32_BE,
                .decimals   = 6, 
                .figures = 8,
            },
            [3] = {
                /**
                 *[^integer-longitude-units]: to do
                 *
                 * @description: Longitude
                 * @value0: Integer longitude (-180000000 to 180000000)
                 * @units_description: integer degrees 
                 * @units_footnote: [^integer-longitude-units]                  
                 */
                .name       = "LONG",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,              
                .data_sets  = 1,
                .units      = "deg",
                .data_type  = LEGO_SENSOR_DATA_S32_BE,
                .decimals   = 6, 
                .figures = 9,
            },
            [4] = {
                /**             
                 *
                 * @description: Speed
                 * @value0: Speed
                 * @units_description: centimeters per second                               
                 */
                .name       = "SPEED",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,              
                .data_sets  = 1,
                .units      = "cm/s",
                .data_type  = LEGO_SENSOR_DATA_S32_BE,
                .decimals   = 0, 
            },
            [5] = {
                /**             
                 *
                 * @description: Heading angle
                 * @value0: Heading angle (range to check)
                 * @units_description: degrees                              
                 */
                .name       = "ANG",
                .raw_min = SHRT_MIN,
                .raw_max = SHRT_MAX,
                .si_min = SHRT_MIN,
                .si_max = SHRT_MAX,             
                .data_sets  = 1,
                .units      = "deg",
                .data_type  = LEGO_SENSOR_DATA_S16_BE, 
                .decimals   = 0,
            },
            [6] = {
                /**             
                 *
                 * @description: Destination distance
                 * @value0: distance to destination
                 * @units_description: meters                       
                 */
                .name       = "DST-DIST",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,                              
                .data_sets  = 1,
                .units      = "m",
                .data_type  = LEGO_SENSOR_DATA_S32_BE, 
                .decimals   = 0, 
            },                      
            [7] = {
                /**             
                 *
                 * @description: Destination angle
                 * @value0: angle to destination
                 * @units_description: degrees                  
                 */
                .name       = "DST-ANG",
                .raw_min = SHRT_MIN,
                .raw_max = SHRT_MAX,
                .si_min = SHRT_MIN,
                .si_max = SHRT_MAX,                             
                .data_sets  = 1,
                .units      = "deg",
                .data_type  = LEGO_SENSOR_DATA_S16_BE, 
                .decimals   = 0, 
            },                      
            [8] = {
                /**             
                 *[^travelled-angle-units]: to do
                 * 
                 * @description: Angle travelled since last request
                 * @value0: angle traveled
                 * @units_description: degrees
                 * @units_footnote: [^travelled-angle-units]                
                 */
                .name       = "TRV-ANG",
                .raw_min = SHRT_MIN,
                .raw_max = SHRT_MAX,
                .si_min = SHRT_MIN,
                .si_max = SHRT_MAX,                             
                .data_sets  = 1,
                .units      = "deg",
                .data_type  = LEGO_SENSOR_DATA_S16_BE, 
                .decimals   = 0, 
            },                      
            [9] = {
                /**             
                 *[^extended-modes]: to do - extended mode only
                 * 
                 * @description: Altitude
                 * @value0: altitude (only in extended mode)
                 * @value0_footnote: [^extended-modes]
                 * @units_description: meters
                 */
                .name       = "EXT-ALT",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,                                              
                .data_sets  = 1,
                .units      = "m",
                .data_type  = LEGO_SENSOR_DATA_S32_BE, 
                .decimals   = 0, 
            },                      
            [10] = {
                /**                               
                 * 
                 * @description: HDOP
                 * @value0: hdop (only in extended mode)
                 * @value0_footnote: [^extended-modes]          
                 */
                .name       = "EXT-HDOP",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,                                              
                .data_sets  = 1,                
                .data_type  = LEGO_SENSOR_DATA_S32_BE, 
            },                      
            [11] = {
                /**                               
                 * 
                 * @description: Satellites in Vew
                 * @value0: sats in view (only in extended mode)
                 * @value0_footnote: [^extended-modes]          
                 */
                .name       = "EXT-SATS",
                .raw_min = INT_MIN,
                .raw_max = INT_MAX,
                .si_min = INT_MIN,
                .si_max = INT_MAX,                                              
                .data_sets  = 1,                
                .data_type  = LEGO_SENSOR_DATA_S32_BE,          
            },                      

        },
        .i2c_mode_info  = (const struct nxt_i2c_sensor_mode_info[]) {
            [0] = {
                .read_data_reg  = 0x00,
            },
            [1] = {
                .read_data_reg  = 0x01,
            },
            [2] = {
                .read_data_reg  = 0x02,
            },
            [3] = {
                .read_data_reg  = 0x04,
            },
            [4] = {
                .read_data_reg  = 0x06,
            },
            [5] = {
                .read_data_reg  = 0x07,
            },
            [6] = {
                .read_data_reg  = 0x08,
            },
            [7] = {
                .read_data_reg  = 0x09,
            },
            [8] = {
                .read_data_reg  = 0x0a,
            },
            [9] = {
                .read_data_reg  = 0x0e,
            },
            [10] = {
                .read_data_reg  = 0x0f,
            },
            [11] = {
                .read_data_reg  = 0x10,
            },          
        },
        .num_commands   = 2,
        .cmd_info   = (const struct lego_sensor_cmd_info[]) {
            [0] = {
                /**
                 * [^extended-firmware-description]: dGPS-X Extended Firmware blah blah blah
                 *
                 * @description: Extended Firmware Off
                 * @name_footnote: [^extended-firmware-description]
                 */
                .name       = "EXT-OFF",
            },
            [1] = {
                /**
                 * @description: Extended Firmware On
                 * @name_footnote: [^extended-firmware-description]
                 */
                .name       = "EXT-ON",
            },
        },
        .i2c_cmd_info   = (const struct nxt_i2c_sensor_cmd_info[]) {
            [0] = {
                .cmd_reg    = 0x0d,
                .cmd_data   = 0x00,
            },
            [1] = {
                .cmd_reg    = 0x0d,
                .cmd_data   = 0x01,
            },

        },
    },  
dlech commented 6 years ago

Could be an endianness problem. I assume there is a ntoh (network to host byte order) function in go. It looks like gGPS is big-endian and EV3 is little-endian

kortschak commented 6 years ago

The encoding/binary package is being used to encode words to []byte with BigEndian. The usual Go idiom is to avoid host endianness and use the binary encoder types.

kortschak commented 6 years ago

Thanks @bmegli. I will build a kernel with that and confirm that my device is working. From the face of it comparing with your code, it looks like I am doing the right thing, but I think I will have to check what bytes are actually being sent the the I²C bus by the periph library.

kortschak commented 6 years ago

Here is the log of transactions (captured just prior to and after the syscall):

robot@ev3dev:~$ ./gps -port in3
Tx
    before: [{Addr:3 Flags:write Length:4 Buf:[4 3 13 1]} {Addr:3 Flags:read Length:3 Buf:[0 0 0]}]
    after:  [{Addr:3 Flags:write Length:4 Buf:[4 3 13 1]} {Addr:3 Flags:read Length:3 Buf:[8 67 99]}]
GPS-X response: [8 67 99]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 1]} {Addr:3 Flags:read Length:1 Buf:[0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 1]} {Addr:3 Flags:read Length:1 Buf:[0]}]
satellite link ok=false
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 16]} {Addr:3 Flags:read Length:4 Buf:[0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 16]} {Addr:3 Flags:read Length:4 Buf:[0 3 103 176]}]
satellites in view: 223152
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 15]} {Addr:3 Flags:read Length:4 Buf:[0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 15]} {Addr:3 Flags:read Length:4 Buf:[0 3 103 177]}]
satellite HDOP=223153
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 0]} {Addr:3 Flags:read Length:4 Buf:[0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 0]} {Addr:3 Flags:read Length:4 Buf:[0 3 103 178]}]
satellite time=2017-09-28 22:31:54 +0000 UTC
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 2]} {Addr:3 Flags:read Length:4 Buf:[0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 2]} {Addr:3 Flags:read Length:4 Buf:[0 3 103 179]}]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 4]} {Addr:3 Flags:read Length:4 Buf:[0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 4]} {Addr:3 Flags:read Length:4 Buf:[0 3 103 180]}]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 14]} {Addr:3 Flags:read Length:4 Buf:[0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 14]} {Addr:3 Flags:read Length:4 Buf:[0 3 103 181]}]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 6]} {Addr:3 Flags:read Length:3 Buf:[0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 6]} {Addr:3 Flags:read Length:3 Buf:[0 3 103]}]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 7]} {Addr:3 Flags:read Length:2 Buf:[0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 7]} {Addr:3 Flags:read Length:2 Buf:[0 3]}]
223155° 223156° 223157m 871cm/s 3°
Tx
    before: [{Addr:3 Flags:write Length:7 Buf:[7 3 11 0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:7 Buf:[7 3 11 0 0 0 0]}]
Tx
    before: [{Addr:3 Flags:write Length:7 Buf:[7 3 12 0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:7 Buf:[7 3 12 0 0 0 0]}]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 8]} {Addr:3 Flags:read Length:4 Buf:[0 0 0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 8]} {Addr:3 Flags:read Length:4 Buf:[0 3 103 226]}]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 9]} {Addr:3 Flags:read Length:2 Buf:[0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 9]} {Addr:3 Flags:read Length:2 Buf:[0 3]}]
Tx
    before: [{Addr:3 Flags:write Length:3 Buf:[3 3 10]} {Addr:3 Flags:read Length:2 Buf:[0 0]}]
    after:  [{Addr:3 Flags:write Length:3 Buf:[3 3 10]} {Addr:3 Flags:read Length:2 Buf:[0 3]}]
223202m 3° 3°
dlech commented 6 years ago

Shouldn't you just be writing one byte?

kortschak commented 6 years ago

In which case? The docs are unclear to me, but I am working from this

dGPS bytes dGPS requests

kortschak commented 6 years ago

I think the "Default" comment explains it, so I am obviously sending the wrong bytes, but how evades me.

dlech commented 6 years ago

Try just writing one byte, the Data Request/Sending value. Then reading the number of bytes in the Receiving Size column.

I'm hoping that the docs are explaining what goes on internally in the NXT and not what goes over the wire. If that is what actually goes over the wire, it is not valid I2C protocol at all.

kortschak commented 6 years ago

Yeah, that makes sense. I'll truncate the first two bytes off the situation I have at the moment (so either 1, 2 or 5 bytes will be sent depending on the request).

dlech commented 6 years ago

The 2 and 5 bytes might need to be separate messages. Write one byte, then one or four bytes.

kortschak commented 6 years ago

Working - with single message. Thanks for your help.

kortschak commented 6 years ago

With a view to pick up @bmegli's work, I've got his code above working. One thing that I think needs to be added is the capacity to set the destination latitude and longitude. I don't see a way to do that with the sensor defs as they stand. Am I missing something or is it not currently possible to send a value to a sensor other than a command byte?

dlech commented 6 years ago

That is what the direct attribute is for. This sensor doesn't really fit the LEGO model, so using it via the lego-sensor class will be awkward.

kortschak commented 6 years ago

Do you think it is worth adding in then?

dlech commented 6 years ago

Personally, no I don't think it is worth it, but I don't really have any strong feelings either way. If you think you will use it, then, sure, add it.

kortschak commented 6 years ago

I'd be retaining the API I have in ev3go's otheri2c package, and the work needed to attach a sensor via the I2C sysfs device interface wouldn't make that easier, so I'm happy to not bother.