Well, that's a coincidence with a recent project I've been working on...

I've recently been playing with hermes agent on a Raspberry Pi, and a $20 
Ollama subscription.

The intention was to create a Picomite/Picocalc MMBASIC programming expert. I 
first got it to consume the Picomite manual, and put it into a wiki, that had 
pages small enough to not overwhelm its context window. Next step was asking it 
to review the whole structure, and identify design patterns and programming 
techniques and to document them in the wiki it created. At this stage I also 
got it to create its own skills for programming, and for the design patterns.

I then grabbed about 125 Picocalc BASIC programs from github, and then asked 
the agent to do the same again, design patterns and techniques; but also add 
code examples to the wiki. At all steps, reminding it that it was the consumer 
of the documentation, and to format it for itself.

The outcome was about 117 files and 28 skills. I have not asked it to write 
code yet, but I'm pretty confident it'd create something mostly sane. That all 
used less than 5% of my weekly allowance for tokens (< $1).

I've attached an example of one of the pages it created. My guess is it hasn't 
extensively expanded the manual into its own documentation, but as hermes is 
designed to learn, it can expand on what it has.

On a side note, this is one of about 5 agents I've created. One is doing a 
great job of managing my calendar and tasks, and sending me the latest news and 
weather every morning. All created by just asking it to do it for me in mostly 
plain language. 

Regards,
Marcus B


On Thu, 16 Apr 2026, at 10:02, Kenneth Pettit wrote:
> On 4/15/26 3:14 PM, [email protected] wrote:
>> On Wed, 15 Apr 2026, Joshua O'Keefe wrote:
>>
>>>> On Apr 14, 2026, at 10:39 AM, John R. Hogerhuis <[email protected]> 
>>>> wrote:
>>>>
>>>> Anyone interested in collaborating on that? Ideally someone who has 
>>>> created a local model so we don't get stuck spinning our wheels.
>>>>
>>>
>>> Hi John. Reach out, LLMs are an area I've done and am doing work. I'd 
>>> love to talk.
>>
>> If you guys stand up a dedicated LLM for our community, it would be a 
>> monster help. I would be hella willing to donate funds to the cause. 
>> It would definitely help with my PC-2 project (which is a monster 
>> effort) as well as my back-burner M100 project (also a monster effort).
>>
>> I'm not rich, just saying
>
> Hmm, I *did* buy a loaded Macbook Pro (think 128GB Unified memory) three 
> months ago.  Maybe it is time to put all that memory to good use 
> training an LLM for Model100 programming!. :)  I bought the extra RAM 
> for that very thing but just haven't had time yet.
>
> Ken
---
title: Serial Communications
created: 2026-04-15
updated: 2026-04-17
type: concept
tags: [serial, i/o, communications]
sources: [raw/papers/picomite-user-manual-raw.txt]
---

# Serial Communications

Two serial interfaces are available for asynchronous communications: **COM1:** and **COM2:**. These are commonly used to communicate with GPS modules, sensors, and other TTL-level devices. See [[using-io-pins]] for more on I/O pin configuration.

## I/O Pin Assignment

Assign pins before using a serial port:

```basic
SETPIN rx, tx, COM1
SETPIN rx, tx, COM2
```

**COM1 valid pins:**

| Direction | Valid Pins |
|-----------|-----------|
| RX | GP1, GP13, GP17 |
| TX | GP0, GP12, GP16, GP28 |

**COM2 valid pins:**

| Direction | Valid Pins |
|-----------|-----------|
| RX | GP5, GP9, GP21 |
| TX | GP4, GP8, GP20 |

> **WebMite:** COM1 and COM2 are not available on GP20 to GP28.

TX is data from the Pico; RX is data to the Pico. The signal polarity is standard TTL: idle is voltage high, start bit is low, data uses high for logic 1, stop bit is high. This allows direct connection to TTL-level devices like GPS modules.

## Opening a Serial Port

```basic
OPEN comspec$ AS #fnbr
```

`fnbr` is the file number (1-10). `comspec$` has the form:

```
"COMn: baud, buf, int, int-trigger, EVEN, ODD, S2, 7BIT"
```

| Parameter | Description | Default |
|-----------|-------------|---------|
| `n` | Serial port number (COM1: or COM2:) | Required |
| `baud` | Baud rate (1200 to 921600) | 9600 |
| `buf` | Receive buffer size in bytes | 256 |
| `int` | Interrupt subroutine name | None |
| `int-trigger` | Characters received to trigger interrupt | None |
| `EVEN` | Even parity bit (9-bit unless 7BIT set) | Off |
| `ODD` | Odd parity bit (9-bit unless 7BIT set) | Off |
| `S2` | Two stop bits | Off |
| `7BIT` | 7 data bits (normally used with EVEN/ODD) | Off |
| `INV` | Inverted output signals / assumed inverted input | Off |

All parameters after the port name are optional. If one is omitted, all following must also be omitted.

### Examples

```basic
' Default settings (9600, 8N1)
OPEN "COM1:" AS #2

' 4800 baud
OPEN "COM1:4800" AS #1

' 9600 baud, 1KB buffer
OPEN "COM2:9600, 1024" AS #8

' 9600 baud, 1KB buffer, two stop bits
OPEN "COM2:9600, 1024, S2" AS #8

' Full specification with interrupt
OPEN "COM2:19200, 1024, ComIntLabel, 256, S2" AS #5
```

## Reading and Writing

Once open, use any file-number commands to read/write:

```basic
SETPIN GP13, GP16, COM1
OPEN "COM1:4800" AS #5
PRINT #5, "Hello"                     ' Send string
dat$ = INPUT$(20, #5)                 ' Read up to 20 characters
CLOSE #5
```

- **`INPUT$(n, #fnbr)`** reads up to `n` characters from the receive buffer. Returns immediately with whatever is available (possibly an empty string).
- **`LOC(#fnbr)`** returns the number of characters waiting in the receive buffer.
- **`PRINT #fnbr, ...`** sends data. Output is buffered; MMBasic continues executing unless the buffer is full.
- **`LOF(#fnbr)`** returns the free space in the transmit buffer (max 256 bytes). Useful to avoid stalling.

If the receive buffer overflows, the oldest data is automatically discarded.

Close the port with `CLOSE #fnbr`. This waits for the transmit buffer to empty, frees the buffer memory, and cancels any interrupt. Ports are also closed by `RUN` and `NEW`. See [[subroutines-and-functions]] for more on interrupt handling in MMBasic.

## Interrupts

The interrupt subroutine (if specified) works like a general I/O pin interrupt (see [[using-io-pins]]). At high baud rates, more characters may arrive before the interrupt handler reads them. Use a buffer larger than the interrupt trigger level to avoid data loss.

For example, with an interrupt level of 200 characters and a 256-byte buffer, the buffer could overflow before the handler runs. Increase the buffer size accordingly.

## Related Commands

- `SETPIN rx, tx, COM1` / `SETPIN rx, tx, COM2` — Assign I/O pins for serial communication
- `OPEN "COMn:..." AS #fnbr` — Open a serial port with configuration parameters
- `CLOSE #fnbr` — Close an open serial port
- `PRINT #fnbr, ...` — Send data via serial port

## Related Functions

|| Function | Description ||
||----------|-----------|-|
|| `EOF(#fnbr)` | Test for end of file on an open serial port ||
|| `INPUT$(n, #fnbr)` | Read up to n characters from the receive buffer ||
|| `LOC(#fnbr)` | Number of characters waiting in the receive buffer ||
|| `LOF(#fnbr)` | Free space in the transmit buffer ||

## Skill Reference

- **mmbasic-programming** (skill) — MMBasic programming fundamentals
- **i2c-communication** (skill) — similar communications pattern for I2C devices

## See Also

- [[i2c-communications]] — Two-wire bus protocol
- [[spi-communications]] — High-speed serial peripheral interface
- [[1-wire-communications]] — Single-wire Dallas protocol
- [[using-io-pins]] — General I/O pin configuration and interrupts
- [[options]] — `OPTION SERIAL CONSOLE`, `OPTION BAUDRATE`

Reply via email to