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

Add feature to encode and decode MakeCode's infrared pulses #26

Open
kevinjwalters opened this issue Jun 4, 2019 · 8 comments
Open

Comments

@kevinjwalters
Copy link

kevinjwalters commented Jun 4, 2019

MakeCode has its own IR protocol/encoding for sending a list of one or more 16 bit unsigned numbers. To allow MakeCode devices to communicate with CircuitPython it would be useful to implement this niche protocol. CircuitPython users may also like to use it.

The protocol is described by @mmoskal on https://makecode.com/blog/timing-adventures-in-infrared but the actual implementation in https://github.com/microsoft/pxt-common-packages/blob/master/libs/pulse/pulse.cpp differs slightly, the start of frame being obviously different, for example.

I think this would be best implemented in a separate file so it is only import'ed by those that wish to use it to avoid memory bloat.

@kevinjwalters
Copy link
Author

kevinjwalters commented Jun 4, 2019

I'm currently about a quarter of the way through a python library implementation of this based on the c++ code ...

@kevinjwalters
Copy link
Author

There's some primitive field type encoding going on too, 12345 is sent with 0xcd prefix and 0xc1 suffix - see https://github.com/microsoft/pxt-common-packages/blob/2a109627f598f96e836eb2bd55745e9bf5ed3c17/libs/base/buffer.ts#L136

@mmoskal
Copy link

mmoskal commented Jun 4, 2019

We use https://msgpack.org/ as the format for messages, hence the 0xcd

@kevinjwalters
Copy link
Author

kevinjwalters commented Jun 4, 2019

It looks like you are following msgpack standard and transmitting data in big endian ("network order") but sending the 16 bit CRC in little endian?

I'm also seeing a consistent 6500 us start bit but your code has 25 1s (marks) which suggests that should be 6250us? I've not thoroughly gone through the MakeCode code yet but is that intentional? Minor possiblity the CircuitPython code adds 250us to the first pulse but that seems unlikely.

@kevinjwalters
Copy link
Author

kevinjwalters commented Jun 6, 2019

This is decode in tagFormat() but encode matches these (negative constants are one out two's complement (not defined in msgpack/msgpack#269), probably not dangerous) and for integer uses unsigned if possible then anything up to 32bit which will fit the value in.

            case 0xCB: return NumberFormat.Float64BE
            case 0xCC: return NumberFormat.UInt8BE
            case 0xCD: return NumberFormat.UInt16BE
            case 0xCE: return NumberFormat.UInt32BE
            case 0xD0: return NumberFormat.Int8BE
            case 0xD1: return NumberFormat.Int16BE
            case 0xD2: return NumberFormat.Int32BE

Data written in https://github.com/microsoft/pxt-common-packages/blob/2a109627f598f96e836eb2bd55745e9bf5ed3c17/libs/base/buffer.cpp#L248

The "combined" single byte msgpack format+data is used too: https://github.com/msgpack/msgpack/blob/master/spec.md#int-format-family visible in https://github.com/microsoft/pxt-common-packages/blob/2a109627f598f96e836eb2bd55745e9bf5ed3c17/libs/base/buffer.ts#L149 (-31 should be -32 here).

0xc1 is defined in spec as (never used).

0cx1 is appended over in https://github.com/microsoft/pxt-common-packages/blob/2a109627f598f96e836eb2bd55745e9bf5ed3c1/libs/infrared/ir.ts#L33 and looks to be true padding only added to create an even buffer size - no stated reason for this (namespace changed from pins to control in later version of that file).

@kevinjwalters
Copy link
Author

kevinjwalters commented Jun 6, 2019

Short string support might be a useful enhancement. Check how practical this is in terms of receiving in CircuitPython, e.g. required size pulseio object.

@kevinjwalters
Copy link
Author

kevinjwalters commented Jun 13, 2019

This requires a very simple implementation of msgpack encode/decode. Points to consider here:

  • separate library?
  • influence from https://github.com/msgpack/msgpack-python and https://github.com/vsergeev/u-msgpack-python (smaller library? name does not mean for micropython)
  • keep interface same if this doesn't make things weird (both msgpack and umsgpack use packb and unpackb (with **options) - umsgpack also has un/pack(obj, fp) (check equiv. in msgpack)
  • needs to run within memory limits of M0
  • useful to allow for importing the library in different lumps according to what's needed
  • need a name - nmsgpack?
  • check UTF-8 handling if going near strings and what compatibility is all about

@kevinjwalters
Copy link
Author

I did not finish this but adafruit/circuitpython#3659 looks like it implements msgpack inside CircuitPython.

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

No branches or pull requests

3 participants