# Declare reads and writes

# Declare reads and writes

List the channels your program reads and writes, by the paths you see on **Live**.

```python
ch = channels()
ch.read("/dut/signal", unit="V", range={"min": 0, "max": 24})
ch.write("/out/enable", dtype="bool", safe=False)
```

| | |
|---|---|
| **`ch.read(path, unit=, range=)`** | a sensor to watch. `unit` and `range` set up gauges and charts |
| **`ch.read(..., limits=limits(hi=, hihi=), checks=True)`** | the same, with warning levels. `checks=True` makes `hihi`/`lolo` a [stop condition](https://phloem.ai/docs/trellis/checks/) |
| **`ch.read(..., cadence="episodic")`** | a value that arrives only now and then, such as from a step's [script](https://phloem.ai/docs/trellis/scripts/) or a once-a-minute poll. The setup arms without it and never calls it stale. It can't carry `checks=` or an interlock. Leave out `cadence=` for a stream |
| **`ch.write(path, dtype=, safe=)`** | an output to command. `safe` is its value when the setup stops |

Both return a reference; `ch["/dut/signal"]` gets the same one by path. Use it
to read a value anywhere, and `set(...)` to drive an output. If nothing is
publishing a channel you read, the document still compiles but shows
**not ready** and names the channel. Add `peer="<device>"` to reach a channel on
another machine (see [Peers](https://phloem.ai/docs/trellis/peers/)).
