diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,12 @@
+arduino-copilot (1.5.5) unstable; urgency=medium
+
+  * Added ButtonHold example, which shows how to accumulate state.
+    Thanks, Tom Hoffman
+  * Update to copilot-3.5.
+  * stack.yaml: Update to lts-18.9.
+
+ -- Joey Hess <id@joeyh.name>  Tue, 07 Sep 2021 14:18:39 -0400
+
 arduino-copilot (1.5.4) unstable; urgency=medium
 
   * Update to copilot-3.3.
diff --git a/Examples/Blink/stack.yaml b/Examples/Blink/stack.yaml
--- a/Examples/Blink/stack.yaml
+++ b/Examples/Blink/stack.yaml
@@ -1,24 +1,27 @@
 packages:
 - '.'
 - '../..'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps: 
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/Examples/Button/stack.yaml b/Examples/Button/stack.yaml
--- a/Examples/Button/stack.yaml
+++ b/Examples/Button/stack.yaml
@@ -1,24 +1,27 @@
 packages:
 - '.'
 - '../..'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps: 
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/Examples/ButtonHold/Demo.cabal b/Examples/ButtonHold/Demo.cabal
new file mode 100644
--- /dev/null
+++ b/Examples/ButtonHold/Demo.cabal
@@ -0,0 +1,10 @@
+Name: Demo
+Cabal-Version: >= 1.10
+Build-Type: Simple
+Version: 0.0
+
+Library
+  GHC-Options: -Wall -fno-warn-tabs
+  Default-Language: Haskell2010
+  Exposed-Modules: Demo
+  Build-Depends: arduino-copilot, base (>= 4.5 && < 5)
diff --git a/Examples/ButtonHold/Demo.hs b/Examples/ButtonHold/Demo.hs
new file mode 100644
--- /dev/null
+++ b/Examples/ButtonHold/Demo.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE RebindableSyntax #-}
+
+module Examples.ButtonHold.Demo where
+
+import Copilot.Arduino.Uno
+
+{- 
+This example uses as button and an led.
+When you press the button, on the leading edge of the press 
+the LED changes state (off to on or vice versa).
+This works like a record button (that's what it is for).  
+Press once to activate, press again to deactivate.
+-}
+
+ledState :: Behavior Bool -> Behavior Bool
+-- This function looks at the current and previous states of the button 
+-- to determine if it has changed from false to true.  If so, it toggles
+-- the state of the LED.
+ledState button = v where
+    pressed = (button == constant True) && 
+              (previous button == constant False)
+    new = if pressed then not v else v
+    v = [False] ++ new
+
+main :: IO ()
+main = arduino $ do
+    pullup pin4
+    buttonState <- input' pin4 [False, True,  True, True, False, False,
+                                False, False, True, True, False, False]
+    led =: ledState buttonState
diff --git a/Examples/ButtonHold/Makefile b/Examples/ButtonHold/Makefile
new file mode 100644
--- /dev/null
+++ b/Examples/ButtonHold/Makefile
@@ -0,0 +1,127 @@
+# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile
+BOARD_TAG    = uno
+include /usr/share/arduino/Arduino.mk
+
+# --- leonardo (or pro micro w/leo bootloader)
+#BOARD_TAG    = leonardo
+#MONITOR_PORT = /dev/ttyACM0
+#include /usr/share/arduino/Arduino.mk
+
+# --- mega2560 ide 1.0
+#BOARD_TAG    = mega2560
+#ARDUINO_PORT = /dev/ttyACM0
+#include /usr/share/arduino/Arduino.mk
+
+# --- mega2560 ide 1.6
+#BOARD_TAG    = mega
+#BOARD_SUB    = atmega2560
+#MONITOR_PORT = /dev/ttyACM0
+#ARDUINO_DIR  = /where/you/installed/arduino-1.6.5
+#include /usr/share/arduino/Arduino.mk
+
+# --- nano ide 1.0
+#BOARD_TAG    = nano328
+#MONITOR_PORT = /dev/ttyUSB0
+#include /usr/share/arduino/Arduino.mk
+
+# --- nano ide 1.6
+#BOARD_TAG   = nano
+#BOARD_SUB   = atmega328
+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5
+#include /usr/share/arduino/Arduino.mk
+
+# --- pro mini
+#BOARD_TAG    = pro5v328
+#MONITOR_PORT = /dev/ttyUSB0
+#include /usr/share/arduino/Arduino.mk
+
+# --- sparkfun pro micro
+#BOARD_TAG         = promicro16
+#ALTERNATE_CORE    = promicro
+#BOARDS_TXT        = $(HOME)/arduino/hardware/promicro/boards.txt
+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders
+#BOOTLOADER_PATH   = caterina
+#BOOTLOADER_FILE   = Caterina-promicro16.hex
+#ISP_PROG     	   = usbasp
+#AVRDUDE_OPTS 	   = -v
+#include /usr/share/arduino/Arduino.mk
+
+# --- chipkit
+#BOARD_TAG = mega_pic32
+#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test
+#include /usr/share/arduino/chipKIT.mk
+
+# --- pinoccio
+#BOARD_TAG         = pinoccio256
+#ALTERNATE_CORE    = pinoccio
+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders
+#BOOTLOADER_PATH   = STK500RFR2/release_0.51
+#BOOTLOADER_FILE   = boot_pinoccio.hex
+#CFLAGS_STD        = -std=gnu99
+#CXXFLAGS_STD      = -std=gnu++11
+#include /usr/share/arduino/Arduino.mk
+
+# --- fio
+#BOARD_TAG = fio
+#include /usr/share/arduino/Arduino.mk
+
+# --- atmega-ng ide 1.6
+#BOARD_TAG    = atmegang
+#BOARD_SUB    = atmega168
+#MONITOR_PORT = /dev/ttyACM0
+#ARDUINO_DIR  = /where/you/installed/arduino-1.6.5
+#include /usr/share/arduino/Arduino.mk
+
+# --- arduino-tiny ide 1.0
+#ISP_PROG     	    = usbasp
+#BOARD_TAG          = attiny85at8
+#ALTERNATE_CORE     = tiny
+#ARDUINO_VAR_PATH   = $(HOME)/arduino/hardware/tiny/cores/tiny
+#ARDUINO_CORE_PATH  = $(HOME)/arduino/hardware/tiny/cores/tiny
+#AVRDUDE_OPTS 	    = -v
+#include /usr/share/arduino/Arduino.mk
+
+# --- arduino-tiny ide 1.6
+#ISP_PROG       = usbasp
+#BOARD_TAG      = attiny85at8
+#ALTERNATE_CORE = tiny
+#ARDUINO_DIR    = /where/you/installed/arduino-1.6.5
+#include /usr/share/arduino/Arduino.mk
+
+# --- damellis attiny ide 1.0
+#ISP_PROG       = usbasp
+#BOARD_TAG      = attiny85
+#ALTERNATE_CORE = attiny-master
+#AVRDUDE_OPTS   = -v
+#include /usr/share/arduino/Arduino.mk
+
+# --- damellis attiny ide 1.6
+#ISP_PROG       = usbasp
+#BOARD_TAG      = attiny
+#BOARD_SUB      = attiny85
+#ALTERNATE_CORE = attiny
+#F_CPU          = 16000000L
+#ARDUINO_DIR    = /where/you/installed/arduino-1.6.5
+#include /usr/share/arduino/Arduino.mk
+
+# --- teensy3
+#BOARD_TAG 	 = teensy31
+#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6
+#include /usr/share/arduino/Teensy.mk
+
+# --- mighty 1284p
+#BOARD_TAG         = mighty_opt
+#BOARDS_TXT        = $(HOME)/arduino/hardware/mighty-1284p/boards.txt
+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders
+#BOOTLOADER_PATH   = optiboot
+#BOOTLOADER_FILE   = optiboot_atmega1284p.hex
+#ISP_PROG     	   = usbasp
+#AVRDUDE_OPTS 	   = -v
+#include /usr/share/arduino/Arduino.mk
+
+# --- atmega328p on breadboard
+#BOARD_TAG    = atmega328bb
+#ISP_PROG     = usbasp
+#AVRDUDE_OPTS = -v
+#BOARDS_TXT   = $(HOME)/arduino/hardware/breadboard/boards.txt
+#include /usr/share/arduino/Arduino.mk
diff --git a/Examples/ButtonHold/README b/Examples/ButtonHold/README
new file mode 100644
--- /dev/null
+++ b/Examples/ButtonHold/README
@@ -0,0 +1,25 @@
+This is a demo program using arduino-copilot. 
+
+To build the C code:
+
+	stack build arduino-copilot
+	stack runghc Demo.hs
+
+The resulting `.ino` sketch can be loaded into the Arduino IDE and flashed
+to an Arduino Uno board using the IDE.
+
+## Arduino-Makefile integration
+
+The `Makefile` and `pre-build-hook.sh` show how to integrate arduino-copilot
+with <https://github.com/sudar/Arduino-Makefile>. This automates generating
+the C code, compiling that, and flashing it onto an Arduino Uno board,
+with a single command
+
+	make upload
+
+Note that you will need to manually build the C code once, as shown above,
+since the Arduino-Makefile expects to find a `.ino` file.
+
+The path in the `Makefile` to `Arduino.mk` may need to be adjusted (the
+default is the location where on a Debian system, `apt-get install
+arduino-mk` will install it).
diff --git a/Examples/ButtonHold/pre-build-hook.sh b/Examples/ButtonHold/pre-build-hook.sh
new file mode 100644
--- /dev/null
+++ b/Examples/ButtonHold/pre-build-hook.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec stack runghc Demo.hs
diff --git a/Examples/ButtonHold/stack.yaml b/Examples/ButtonHold/stack.yaml
new file mode 100644
--- /dev/null
+++ b/Examples/ButtonHold/stack.yaml
@@ -0,0 +1,27 @@
+packages:
+- '.'
+- '../..'
+resolver: lts-18.9
+extra-deps: 
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
+- ansi-terminal-0.9.1
+- bimap-0.3.3
+- language-c99-0.1.2
+- language-c99-simple-0.1.2
+- language-c99-util-0.1.1
+- optparse-applicative-0.15.1.0
+- panic-0.4.0.1
+- parameterized-utils-2.1.3.0
+- random-1.1
+- what4-1.1
+- bitwise-1.0.0.1
+- config-value-0.8.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/Examples/EEPROM/stack.yaml b/Examples/EEPROM/stack.yaml
--- a/Examples/EEPROM/stack.yaml
+++ b/Examples/EEPROM/stack.yaml
@@ -1,24 +1,27 @@
 packages:
 - '.'
 - '../..'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps: 
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/Examples/EEPROMrange/stack.yaml b/Examples/EEPROMrange/stack.yaml
--- a/Examples/EEPROMrange/stack.yaml
+++ b/Examples/EEPROMrange/stack.yaml
@@ -1,24 +1,27 @@
 packages:
 - '.'
 - '../..'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps: 
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/Examples/Random/stack.yaml b/Examples/Random/stack.yaml
--- a/Examples/Random/stack.yaml
+++ b/Examples/Random/stack.yaml
@@ -1,24 +1,27 @@
 packages:
 - '.'
 - '../..'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps: 
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/Examples/SerialPort/stack.yaml b/Examples/SerialPort/stack.yaml
--- a/Examples/SerialPort/stack.yaml
+++ b/Examples/SerialPort/stack.yaml
@@ -1,24 +1,27 @@
 packages:
 - '.'
 - '../..'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps: 
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/Examples/WaterHeater/stack.yaml b/Examples/WaterHeater/stack.yaml
--- a/Examples/WaterHeater/stack.yaml
+++ b/Examples/WaterHeater/stack.yaml
@@ -1,24 +1,27 @@
 packages:
 - '.'
 - '../..'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps: 
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
+
diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -5,6 +5,10 @@
   and we wonder if eg pin10 can really handle PWM. Some documentation seems
   to say not. It would be good to check it's basically working.
 
+* Serial input/output can support types other than the current Int8.
+  For example, here's an implementation for Word8:
+  https://github.com/tom-hoffman/copilot-looper/blob/main/Word8IO.hs
+
 * analogReference()
   Takes one of a set of defines, which vary depending on board,
   so how to pass that through Copilot? Could write a C
diff --git a/arduino-copilot.cabal b/arduino-copilot.cabal
--- a/arduino-copilot.cabal
+++ b/arduino-copilot.cabal
@@ -1,5 +1,5 @@
 Name: arduino-copilot
-Version: 1.5.4
+Version: 1.5.5
 Cabal-Version: >= 1.10
 License: BSD3
 Maintainer: Joey Hess <id@joeyh.name>
@@ -43,6 +43,11 @@
   Examples/Button/pre-build-hook.sh
   Examples/Button/Demo.cabal
   Examples/Button/stack.yaml
+  Examples/ButtonHold/Makefile
+  Examples/ButtonHold/README
+  Examples/ButtonHold/pre-build-hook.sh
+  Examples/ButtonHold/Demo.cabal
+  Examples/ButtonHold/stack.yaml
   Examples/EEPROM/Makefile
   Examples/EEPROM/README
   Examples/EEPROM/pre-build-hook.sh
@@ -83,6 +88,7 @@
   Other-Modules:
     Examples.Blink.Demo
     Examples.Button.Demo
+    Examples.ButtonHold.Demo
     Examples.EEPROM.Demo
     Examples.EEPROMrange.Demo
     Examples.Random.Demo
@@ -108,9 +114,9 @@
     Copilot.Arduino.Main
   Build-Depends:
     base (>= 4.5 && < 5),
-    copilot (== 3.3.*),
-    copilot-c99 (== 3.3.*),
-    copilot-language (== 3.3.*),
+    copilot (== 3.5.*),
+    copilot-c99 (== 3.5.*),
+    copilot-language (== 3.5.*),
     filepath,
     directory,
     mtl,
diff --git a/src/Copilot/Arduino/Library/Serial.hs b/src/Copilot/Arduino/Library/Serial.hs
--- a/src/Copilot/Arduino/Library/Serial.hs
+++ b/src/Copilot/Arduino/Library/Serial.hs
@@ -64,5 +64,10 @@
 -- The resulting `Behavior Int8` will be updated on each iteration
 -- of the sketch. When there is no new serial input available, it will
 -- contain `noInput`.
+--
+-- Note: When a Sketch that does serial output is sumulated (with -i),
+-- Copilot does not display the static strings (`Serial.str`)
+-- that are output to the serial port, but it does output the changing
+-- values.
 device :: SerialDevice
 device = SerialDevice dev
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,24 +1,26 @@
 packages:
 - '.'
-resolver: lts-17.12
+resolver: lts-18.9
 extra-deps:
-- copilot-3.3
-- copilot-c99-3.3
-- copilot-core-3.3
-- copilot-language-3.3
-- copilot-libraries-3.3
-- copilot-theorem-3.3
+- copilot-3.5
+- copilot-c99-3.5
+- copilot-core-3.5
+- copilot-language-3.5
+- copilot-libraries-3.5
+- copilot-theorem-3.5
 - ansi-terminal-0.9.1
 - bimap-0.3.3
-- bv-sized-1.0.2
 - language-c99-0.1.2
 - language-c99-simple-0.1.2
 - language-c99-util-0.1.1
-- libBF-0.6.2
+- optparse-applicative-0.15.1.0
 - panic-0.4.0.1
 - parameterized-utils-2.1.3.0
+- random-1.1
 - what4-1.1
 - bitwise-1.0.0.1
 - config-value-0.8.1
-- zenc-0.1.1
+- versions-4.0.3
+- zenc-0.1.2
+- bv-sized-1.0.2
 explicit-setup-deps:
diff --git a/test.hs b/test.hs
--- a/test.hs
+++ b/test.hs
@@ -16,6 +16,7 @@
 import qualified Examples.Robot.Demo
 import qualified Examples.SerialPort.Demo
 import qualified Examples.WaterHeater.Demo
+import qualified Examples.ButtonHold.Demo
 
 data TestCase = TestCase
 	{ desc :: String
@@ -35,6 +36,7 @@
 	, TestCase "Robot" Examples.Robot.Demo.main True
 	, TestCase "SerialPort" Examples.SerialPort.Demo.main True
 	, TestCase "WaterHeater" Examples.WaterHeater.Demo.main True
+	, TestCase "ButtonHold" Examples.ButtonHold.Demo.main True
 	]
 
 main :: IO ()
