045 Project 45: TinyGo I2C Realtime Monitor
045 TinyGo: I2C Device + Realtime Status Monitor
Wire an I2C sensor or peripheral (or a mock if no hardware), read it on a fixed schedule, and publish a compact status line over UART—combining bus IO, timing, and error handling for embedded Go.
Hardware options
| Path | Hardware | Notes |
|---|---|---|
| A | BME280 / SHT30 / MPU6050 etc. | Real I2C; check address + pull-ups |
| B | I2C EEPROM / expander | Simpler register IO |
| C | Mock | Software sensor if no bus |
Many boards: machine.I2C0 with SDA/SCL pins—read your pinout.
Step 1: Bus init sketch
package main
import (
"fmt"
"machine"
"time"
)
func main() {
machine.Serial.Configure(machine.UARTConfig{BaudRate: 115200})
i2c := machine.I2C0
err := i2c.Configure(machine.I2CConfig{
Frequency: 100_000, // 100 kHz start; 400 kHz if stable
})
if err != nil {
fmt.Fprintf(machine.Serial, "i2c configure: %v\n", err)
// continue with mock if desired
}
const addr uint16 = 0x76 // example — change per device
ticker := time.NewTicker(200 * time.Millisecond)
defer ticker.Stop() // if supported; else ignore
for range ticker.C {
// Real read example (device-specific registers!):
// buf := make([]byte, 2)
// err := i2c.ReadRegister(uint8(addr), 0xD0, buf)
// Mock:
v := int(time.Now().UnixNano()%500) / 5
ok := true
fmt.Fprintf(machine.Serial, "ok=%v val=%d t=%d\n", ok, v, time.Now().Unix())
_ = addr
_ = i2c
}
}Replace mock with one real register read for your chip using the datasheet.
Step 2: Error budget (soft RT)
type Monitor struct {
Period time.Duration
Failures int
LastOK time.Time
}
func (m *Monitor) Sample(read func() (int, error)) {
v, err := read()
if err != nil {
m.Failures++
return
}
m.LastOK = time.Now()
// publish v
_ = v
}Rules:
- Cap consecutive failures before
SAFEmode (LED pattern / UART alert).
- Do not block forever on bus errors—timeout if API allows.
- Keep allocations out of the 200 ms path if RAM is tight (
bufreused).
Step 3: Status LED semantics
| LED | Meaning |
|---|---|
| Slow blink | Healthy samples |
| Fast blink | Bus errors |
| Solid | Fatal / halt (optional) |
Step 4: Host-side plot (optional)
Log UART to file and plot with any tool:
picocom -b 115200 /dev/ttyACM0 | tee samples.logLearning Goals
- I2C configure + address/register mindset
- Timed sampling with failure counts
- Operator-visible status (UART + LED)
- Datasheet-driven integration
Extensions
- Two sensors on one bus.
- Change sample rate over UART.
- Simple threshold alarm relay pin.
Safety
- 3.3 V vs 5 V logic levels—do not overvolt pins.
- Shared GND; pull-ups usually 4.7k on SDA/SCL.
Checkpoint
- Bus init or explicit mock path
- Fixed-rate samples with failure counter
- UART status lines
- Datasheet note or mock justification