Log In  

Hello~~
I have just found about PICO-8 recently and I must say this is a neat little platform to play around :D

So after scrolling the manual a few times, I realize that PICO-8 got the 128 bytes of GPIO, which begs to be used for all sort of external communication. However, I haven't found someone who has made a wrapper library for this, all of the examples I found are simply examples of how someone use the GPIO for their specific communication requirements.

I tinkered for a while in my free time and thought that I might as well just create my own. The requirements that I had in mind is simply:

  • able use the GPIO without race condition between the Host and PICO-8
  • able to send a message of arbitrary length, even more than 128 bytes
  • is configurable, doesn't take all of the GPIO space
  • enable user to create their own protocol on top for their own usage
  • reliable

A little bit of details:


So after (not so) much consideration, I choose to implement a packet based protocol design. The header is 8 bytes long (actually can shrink to 4 bytes, but eh) with these fields:
0 - packet type
1 - sequence number
2 - context id
3 - packet length
4 - packet crc
5, 6, 7 - empty, reserved
8 - [up to]127 - body

by default the packet length is set to be 96 bytes

In order to send a message, the flow would be like this:

  • sender: send message start packet (includes the total message length in body)
  • client: ack
  • sender: send message part packet
  • client: ack
  • sender: send message end packet
  • client: ack, call the user registered callback for this message type

The IPC class have several states:

  • noop: nothing to do
  • wait_msg_start_ack: sent start message, wait for ack
  • send_msg_in_progress
  • receive_msg_in_progress

To make it race condition free, we simply define which packets sent by which system by a convention:

  • if packet_type % 2 == 0 then pico sent it
  • if packet_type % 2 == 1 then the external host sent it

currently, it has several built in packet_types:

  • pico_noop = 0
  • ext_noop = 1
  • pico_ping = 2
  • ext_ping = 3
  • pico_pong = 4
  • ext_pong = 5
  • pico_ack = 6
  • ext_ack = 7
  • pico_reject = 8
  • ext_reject = 9
  • pico_start_msg = 10
  • ext_start_msg = 11
  • pico_end_msg = 12
  • ext_end_msg = 13

If anyone is interested, you can check the code here
I have added a few simple examples on how you can use it. Simply copy paste the picoipc.p8 and the example script to your cart directory, create the input/output file, and run

pico8 -i input -o output -p picoweb

(the flag is necessary to indicate that you're using the library)

Please note that this code is still POC quality, the naming is not consistent yet, and a lot of features are missing such as:

  • sequence number checks and wrap around
  • randomized sequence number start
  • packet buffer update (for progress bar purposes)
  • context switching
  • javascript library
  • nice GUI for the adapter
  • reduce token usage

Later on, as the repository name suggest, I will build a protocol on top of this IPC to support:

  • HTTP calls
  • Websocket connections

Let me know what you think, I'll continue working on this on the next weekend. Happy tinkering!

P#95550 2021-08-01 15:39 ( Edited 2021-08-01 15:46)

1

Good to see more experimentation in this area!

There are some generic javascript libs for gpio-js communication that can be found here on the bbs and/or github.

I am a little confused by your post; pico8 has access to real GPIO pins when running on raspberry pis, or uses that memory area as a shared byte array when embedded in HTML. You seem to say that your lib uses GPIO on all platforms, and the examples seem to use the -i/-o serial streams. Can you clarify?

P#95551 2021-08-01 16:28
1

@merwok ok so actually the current implementation has 2 steps, depending on the platform it is running on:

  • read from serial file input and dump into GPIO (if -p picoweb is defined, which means it's a standalone client)
  • do it's thing with the data from GPIO
  • dump back from GPIO to serial file output, with the same condition above

so the implementation on standalone client will use serial file io, while on web it will use direct GPIO

That behavior is a simple shortcut for my testing purposes and ofc I totally forgot about raspberry PI lol, I was simply thinking desktop and web xD. Later on I will simply dump from GPIO / serial file into a byte table and use that instead of poking each GPIO directly. I believe this will solve the issue if it's run on raspberry pi / CHIP.

(hmm but probably it will be cool as well to see a real physical adapter lol)

P#95552 2021-08-01 16:44 ( Edited 2021-08-01 16:54)
1

interesting starting point but the token cost is really really high.
oop is interesting but not really the best option on pico - a C api would be much more efficient .
message size could also be encoded using the full 32bits, using 0x.0001 as increment.
I also don’t understand why crc code is part of the pico knowing that it
needs a ‘host’ in practical situations (read html page).
not sure building http or any other complex protocol really make sense either.

P#95562 2021-08-01 19:20 ( Edited 2021-08-01 19:28)
1

@freds72 haha I will consider this as a novelty rather than practicality. The whole IPC thing is actually designed for apps or games with not-so-real time requirements. As for the complex protocols, it's really "just because". Like it would be cool to see let's say, a web server running in PICO-8 xD

Ah yeah the OOP... I was carried away during implementation xD. Picked up Lua just for this and thought I want to experiment with metatables.

P#95563 2021-08-01 19:29 ( Edited 2021-08-01 19:33)

New, and also weird bot to post links as small as possible as if that won't make me flag them any less. Unless it's somehow not supposed to format them like this.
At least it also doesn't try to make sense I guess

P#110562 2022-04-20 10:45
1

These spambots don't care what humans think, they're just happy to post links (benign or otherwise) on irrelevant websites just for the SEO juice.

on topic: Using the GPIO pins to allow Pico-8 access to networked multiplayer (via WebSocket, WebRTC, or two physical wires connecting two Pis together) has been my ideal use case for it since the day it was added. :3 The serialization API should help a lot.

P#110599 2022-04-20 20:58

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2022-12-05 13:28:48 | 0.026s | Q:20