Serial

From Pico-8 Wiki
Jump to navigation Jump to search
serial( channel, address, [length] )
Sends or receives data from a serial "channel."
channel
The channel ID.

address
The memory address to read from / write to.

length
The number of bytes to read / write. Use 1/8th values to send partial bit strings. The default length is 1.

serial() can read or write streams of data from and to various "channels" that interact with the host environment. Channels can:

  • Communicate a precisely timed sequence of bits via GPIO pins (Raspberry Pi) or a JavaScript array (web player)
  • Pause using precise timing (microseconds), such as to tune GPIO serial communication
  • Read from and write to the host operating system's input and output streams
  • Read from and write to a file named on the PICO-8 command line
  • Read a file dragged into the PICO-8 window by the user
  • Read an image file dragged into the PICO-8 window by the user, converted automatically to PICO-8's image format and color palette
  • (Undocumented:) Play a digital PCM audio sample at 5 KHz

Process stream and file I/O are limited to the PICO-8 development environment and do not work in exported carts or the BBS.

Drag-and-drop is supported in exported carts, limited to files of size 256 Kb or images of pixel size 128x128.

Reading and writing

To read from a serial channel, call serial() in an expression context. The return value is the number of bytes read. The data read from the channel is written to memory starting at the specified address, up to address + size.

size = serial(0x804, 0x4300, 0x1000)

To read an arbitrary amount of data until all data is exhausted, call serial() repeatedly until it returns a size of 0.

repeat
 size = serial(0x804, 0x4300, 0x1000)
 for i=0,size do
  b = peek(0x4300 + i)
  -- ...process byte b...
 end
until(size == 0)

To write to a serial channel, call serial() in a statement context, i.e. not assigned to a variable or used in an expression.

poke(0x4300, 72)
poke(0x4301, 73)
serial(0x805, 0x4300, 2)

GPIO serial communication

Channels 0x000 through 0x0fe correspond to Raspberry Pi GPIO pins. Values 0x00 and 0xff are off and on, respectively.

GPIO pin values are also available to the browser JavaScript environment of the web player, in a global named pico8_gpio that you declare with: var pico8_gpio = Array(128);

Channel 0x0ff is a delay register. Pass the duration of the delay as the "length" parameter, as a number of microseconds.

Channels 0x400 and 0x401 are specifically for a WS281X addressable LED light string.

Drag-and-drop files

A PICO-8 cart can accept files dragged into the PICO-8 window by the user. If the file is an image file, PICO-8 attempts to convert the image to the PICO-8 color palette and present it to the cart as PICO-8 image data.

When the user drops a non-image file, stat(120) returns true, and the data can be read from channel 0x800.

When the user drops an image file, stat(121) returns true, and the converted image data can be read from channel 0x802. The first 4 bytes are the image's width and height (2 bytes each little-endian, like peek2()), followed by the image in reading order, one byte per pixel, color-fitted to the display palette at the time the file was dropped.

The maximum transfer rate for drag-and-dropped files is 64 Kb/second. The serial() command blocks the CPU until completed. Note that the stat() call will not block, so you can detect when a file is ready, do something else, then call serial() to read the file when appropriate.

Host OS streams and files

The host OS in which PICO-8 runs can pass data to the process using the "standard input" stream, and receive data from the process using the "standard output" stream. A cart can access these streams for the PICO-8 process using channel 0x804 for STDIN (readable) and 0x805 for STDOUT (writable). This typically requires invoking PICO-8 from the command line.

For example, to run the cart mycart.p8 and pour the contents of the file myfile.txt into STDIN, invoke PICO-8 from the command line this way:

pico8 < myfile.txt -run mycart.p8

PICO-8 can also accept the name of a file as a command line argument to be either an input file or an output file, independent of the standard I/O streams. To read an input file, use the -i filename command line argument when invoking PICO-8, then read it from channel 0x806. To write to an output file, use the -o filename command line arugment, then write to it from channel 0x807.

pico8 -i myfile.txt -run mycart.p8

The maximum transfer rate for streams and files is 64 Kb/second. The serial() command blocks the CPU until completed.

Play PCM audio samples

You can play a 5 KHz (5512.5 Hz, specifically) PCM digital audio sample by writing the audio data to channel 0x808. The playback buffer can hold up to 2048 bytes.

stat(108) and stat(109) return information about the audio playback.

Examples

APA102 LED string

To send a byte one bit at a time to a typical APA102 LED string:

val = 42          -- value to send
dat = 16 clk = 15 -- data and clock pins depend on device
poke(0x4300,0)    -- data to send (single bytes: 0 or 0xff)
poke(0x4301,0xff)
for b=0,7 do
  -- send the bit (high first)
  serial(dat, band(val, shl(1,7-b))>0 and 0x4301 or 0x4300, 1)
  -- cycle the clock
  serial(clk, 0x4301)
  serial(0xff, 5) -- delay 5
  serial(clk, 0x4300)
  serial(0xff, 5) -- delay 5
end

Reading a file from stdin

To read a file from the host operating system's standard input stream in blocks of 4,096 (0x1000) bytes, and print it to the screen one character at a time:

cls()
repeat
 size = serial(0x804,0x4300,0x1000)
 for i=0,size do
  print(chr(peek(0x4300+i)).."\0")
 end
until(size == 0)

Run this example from the host operating system's command line:

pico8 < myfile.txt -run mycart.p8

See Also