# Can I send serial data from Snap! to a USB connected microcontroller

I've got the new RaspberryPi Pico and I just want to control the pins by simply sending micropython commands to it over its REPL

Just for proof of concept to switch the onboard LED off and on

I've got Node-RED sending stuff

but I'd like to do it from Snap!

Yes. Use the Serial API: https://web.dev/serial/

I think that way beyond my pay grade to be the 1st person to implement that in Snap!
[edit
But I am making progress having enabled web-platform experimetal thing in my browser

const port = navigator.serial.requestPort();

You can't do this, the Serial API is asynchronous.
Here's how you would do it:

function encodeString(str) {
const buffer = new Uint8Array(str.length);
for (let i = 0; i < str.length; ++i) buffer[i] = str[i].charCodeAt(0);
return buffer;
}
async function writeString(writer, str) {
const buffer = encodeString(str);
await writer.write(buffer);
}
(async () => {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
const writer = port.writable.getWriter();
await writeString(writer, 'from machine import Pin');
})();


edit 2/13/2022: added quotes for the quoted code snippet

This is way beyond my JavaScript knowledge

There was a typo, try running the code now.

No error but what I need to do is send 3 strings one after each other so I tried this but my LED didn't light

I believe you need to add a newline (\r\n), but I'm not sure.

Tried it with this but is didn't make any difference

I think I'll need to replace the Pico with a Pi so I can see if any serial data is going out

function encodeString(str) {
...
return buffer;


We have a LED on

Eureka - 1st block sets it up
2nd and third switch the LED on and off

Many thanks @programmer_user (and @dardoro for his crucial addition)

webSerial

How did I not notice that? Thanks, I've edited my post.

You should probably encapsulate the functionality into a block that sends Python code to the Pi.

yep - that's the ultimate plan
Block to select and open the port
Block to close it

Then parameterised blocks to setup and read and write to the pins.

I've hit a bit of a problem (presumably due to the async code)

If I try to wrap the opening function in a custom block - my browser just starts eating up memory and have have to kill it using task manager

Any ideas on how to get around this?

While more complex, I prefer passing in a command to the custom block (in this case the one that is opening a port) and calling it when the asynchronous function (navigator.serial.requestPort in this case) returns a value.