diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+arduino-copilot (1.7.0) upstream; urgency=medium
+
+  * Added the Arduino data type, which replaces the PinId type used in the
+    last release.
+
+ -- Joey Hess <id@joeyh.name>  Mon, 14 Feb 2022 21:07:09 -0400
+
 arduino-copilot (1.6.0) unstable; urgency=medium
 
   * Refactored non-Arduino-specific code into sketch-frp-copilot.
diff --git a/Examples/Blink/stack.yaml b/Examples/Blink/stack.yaml
--- a/Examples/Blink/stack.yaml
+++ b/Examples/Blink/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
diff --git a/Examples/Button/stack.yaml b/Examples/Button/stack.yaml
--- a/Examples/Button/stack.yaml
+++ b/Examples/Button/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
diff --git a/Examples/ButtonHold/stack.yaml b/Examples/ButtonHold/stack.yaml
--- a/Examples/ButtonHold/stack.yaml
+++ b/Examples/ButtonHold/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
diff --git a/Examples/EEPROM/stack.yaml b/Examples/EEPROM/stack.yaml
--- a/Examples/EEPROM/stack.yaml
+++ b/Examples/EEPROM/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
diff --git a/Examples/EEPROMrange/stack.yaml b/Examples/EEPROMrange/stack.yaml
--- a/Examples/EEPROMrange/stack.yaml
+++ b/Examples/EEPROMrange/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
diff --git a/Examples/Random/stack.yaml b/Examples/Random/stack.yaml
--- a/Examples/Random/stack.yaml
+++ b/Examples/Random/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
diff --git a/Examples/SerialPort/Demo.hs b/Examples/SerialPort/Demo.hs
--- a/Examples/SerialPort/Demo.hs
+++ b/Examples/SerialPort/Demo.hs
@@ -21,7 +21,7 @@
 userIsTyping :: Behavior Int8 -> Behavior Bool
 userIsTyping userinput = userinput /= constant Serial.noInput
 
-getSerial :: Input PinId o Int8 => Bool -> o -> Sketch (Behavior Int8)
+getSerial :: Input Arduino o Int8 => Bool -> o -> Sketch (Behavior Int8)
 getSerial True i = input' i (repeat Serial.noInput)
 getSerial False _ = return (constant Serial.noInput)
 
diff --git a/Examples/SerialPort/stack.yaml b/Examples/SerialPort/stack.yaml
--- a/Examples/SerialPort/stack.yaml
+++ b/Examples/SerialPort/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
diff --git a/Examples/WaterHeater/stack.yaml b/Examples/WaterHeater/stack.yaml
--- a/Examples/WaterHeater/stack.yaml
+++ b/Examples/WaterHeater/stack.yaml
@@ -3,7 +3,7 @@
 - '../..'
 resolver: lts-18.9
 extra-deps: 
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
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.6.0
+Version: 1.7.0
 Cabal-Version: >= 1.10
 License: BSD3
 Maintainer: Joey Hess <id@joeyh.name>
@@ -114,7 +114,7 @@
     Copilot.Arduino.Main
   Build-Depends:
     base (>= 4.5 && < 5),
-    sketch-frp-copilot (== 1.0.0),
+    sketch-frp-copilot (== 1.0.1),
     copilot (== 3.7.*),
     copilot-c99 (== 3.7.*),
     copilot-language (== 3.7.*),
diff --git a/src/Copilot/Arduino.hs b/src/Copilot/Arduino.hs
--- a/src/Copilot/Arduino.hs
+++ b/src/Copilot/Arduino.hs
@@ -18,6 +18,7 @@
 	arduino,
 	Sketch,
 	Pin,
+	Arduino,
 	-- * Functional reactive programming
 	Behavior,
 	TypedBehavior(..),
@@ -49,7 +50,6 @@
 	IsDigitalIOPin,
 	IsAnalogInputPin,
 	IsPWMPin,
-	PinId,
 	-- * Utilities
 	blinking,
 	firstIteration,
@@ -106,10 +106,10 @@
 data ClockMillis = ClockMillis
 data ClockMicros = ClockMicros
 
-instance Input PinId ClockMillis Word32 where
+instance Input Arduino ClockMillis Word32 where
 	input' ClockMillis = inputClock "millis"
 
-instance Input PinId ClockMicros Word32 where
+instance Input Arduino ClockMicros Word32 where
 	input' ClockMicros = inputClock "micros"
 
 inputClock :: [Char] -> [Word32] -> Sketch (Behavior Word32)
@@ -139,7 +139,7 @@
 
 -- | The on-board LED.
 led :: Pin '[ 'DigitalIO ]
-led = Pin (PinId 13)
+led = Pin (Arduino 13)
 
 -- | Normally when a digital value is read from a `Pin`, it is configured
 -- without the internal pullup resistor being enabled. Use this to enable
@@ -152,6 +152,6 @@
 pullup :: IsDigitalIOPin t => Pin t -> Sketch ()
 pullup (Pin p) = tell [(\_ -> return (), \_ -> f)]
   where
-	f = (emptyFramework @PinId)
+	f = (emptyFramework @Arduino)
 		{ pinmodes = M.singleton p (S.singleton InputPullupMode)
 		}
diff --git a/src/Copilot/Arduino/Internals.hs b/src/Copilot/Arduino/Internals.hs
--- a/src/Copilot/Arduino/Internals.hs
+++ b/src/Copilot/Arduino/Internals.hs
@@ -32,10 +32,10 @@
 --
 -- While it is a monad, a Sketch's outputs are not updated in any
 -- particular order, because Copilot does not guarantee any order.
-type Sketch = GenSketch PinId
+type Sketch = GenSketch Arduino
 
 -- | The framework of a sketch.
-type Framework = GenFramework PinId
+type Framework = GenFramework Arduino
 
 -- | A pin on the Arduino board.
 --
@@ -45,16 +45,21 @@
 --
 -- A type-level list indicates how a Pin can be used, so the haskell
 -- compiler will detect impossible uses of pins.
-newtype Pin t = Pin PinId
+newtype Pin t = Pin Arduino
 	deriving (Show, Eq, Ord)
 
-newtype PinId = PinId Int16
+-- | Indicates that you're programming an arduino, and not some
+-- other kind of hardware. The similar library zephyr-copilot allows
+-- programming other embedded boards in a very similar style to this one.
+newtype Arduino = Arduino Int16
 	deriving (Show, Eq, Ord)
 
-instance IsDigitalIOPin t => Output PinId (Pin t) (Event () (Stream Bool)) where
-	(Pin p@(PinId n)) =: (Event b c) = do
+instance Context Arduino
+
+instance IsDigitalIOPin t => Output Arduino (Pin t) (Event () (Stream Bool)) where
+	(Pin p@(Arduino n)) =: (Event b c) = do
 		(f, triggername) <- defineTriggerAlias' ("pin_" <> show n) "digitalWrite" $
-			(emptyFramework @PinId)
+			(emptyFramework @Arduino)
 				{ pinmodes = M.singleton p (S.singleton OutputMode)
 				}
 		tell [(go triggername, const f)]
@@ -63,8 +68,8 @@
 			let c' = addTriggerLimit tl c
 			in trigger triggername c' [arg (constant n), arg b]
 
-instance IsPWMPin t => Output PinId (Pin t) (Event 'PWM (Stream Word8)) where
-	(Pin (PinId n)) =: (Event v c) = do
+instance IsPWMPin t => Output Arduino (Pin t) (Event 'PWM (Stream Word8)) where
+	(Pin (Arduino n)) =: (Event v c) = do
 		(f, triggername) <- defineTriggerAlias' ("pin_" <> show n) "analogWrite" mempty
 		tell [(go triggername, const f)]
 	  where
@@ -73,8 +78,8 @@
 			in trigger triggername c' [arg (constant n), arg v]
 		-- analogWrite does not need any pinmodes set up
 
-instance IsDigitalIOPin t => Input PinId (Pin t) Bool where
-	input' (Pin p@(PinId n)) interpretvalues = mkInput $ InputSource
+instance IsDigitalIOPin t => Input Arduino (Pin t) Bool where
+	input' (Pin p@(Arduino n)) interpretvalues = mkInput $ InputSource
 		{ defineVar = mkCChunk [CLine $ "bool " <> varname <> ";"]
 		, setupInput = mempty
 		, inputPinmode = M.singleton p InputMode
@@ -91,8 +96,8 @@
 -- | Value read from an Arduino's ADC. Ranges from 0-1023.
 type ADC = Int16
 
-instance IsAnalogInputPin t => Input PinId (Pin t) ADC where
-	input' (Pin (PinId n)) interpretvalues = mkInput $ InputSource
+instance IsAnalogInputPin t => Input Arduino (Pin t) ADC where
+	input' (Pin (Arduino n)) interpretvalues = mkInput $ InputSource
 		{ defineVar = mkCChunk [CLine $ "int " <> varname <> ";"]
 		, setupInput = mempty
 		, inputPinmode = mempty
@@ -121,7 +126,7 @@
 instance ShowCType Float where showCType _ = "float"
 instance ShowCType Double where showCType _ = "double"
 
-instance Output PinId Delay MilliSeconds where
+instance Output Arduino Delay MilliSeconds where
 	Delay =: (MilliSeconds n) = do
 		(f, triggername) <- defineTriggerAlias "delay" mempty
 		tell [(go triggername, \_ -> f)]
@@ -130,7 +135,7 @@
 			let c = getTriggerLimit tl
 			in trigger triggername c [arg n]
 
-instance Output PinId Delay MicroSeconds where
+instance Output Arduino Delay MicroSeconds where
 	Delay =: (MicroSeconds n) = do
 		(f, triggername) <- defineTriggerAlias "delayMicroseconds" mempty
 		tell [(go triggername, \_ -> f)]
diff --git a/src/Copilot/Arduino/Library/EEPROMex.hs b/src/Copilot/Arduino/Library/EEPROMex.hs
--- a/src/Copilot/Arduino/Library/EEPROMex.hs
+++ b/src/Copilot/Arduino/Library/EEPROMex.hs
@@ -192,7 +192,7 @@
 
 data Location t = Location UniqueId
 
-instance EEPROMable t => Output PinId (Location t) (Event () (Stream t)) where
+instance EEPROMable t => Output Arduino (Location t) (Event () (Stream t)) where
 	Location i =: (Event v c) = do
 		(f, triggername) <- defineTriggerAlias (eepromWriterName i) mempty
 		tell [(go triggername, \_ -> f)]
@@ -257,10 +257,10 @@
 -- instead they loop back to the start of the Range.
 type RangeIndex = Word16
 
-instance EEPROMable t => Output PinId (Range t) (RangeWrites t) where
+instance EEPROMable t => Output Arduino (Range t) (RangeWrites t) where
 	(=:) = writeRange true
 
-instance EEPROMable t => Output PinId (Range t) (Event () (RangeWrites t)) where
+instance EEPROMable t => Output Arduino (Range t) (Event () (RangeWrites t)) where
 	range =: Event ws c = 
 		writeRange c range ws
 
@@ -356,7 +356,7 @@
 	cnt = [startidx+1] ++ rest
 	rest = cnt + 1
 
-instance (ShowCType t, EEPROMable t) => Input PinId (RangeReads t) t where
+instance (ShowCType t, EEPROMable t) => Input Arduino (RangeReads t) t where
 	input' (RangeReads range startidx idx) interpretvalues = do
 		-- This trigger writes value of idx
 		-- to indexvarname. The next time through the loop,
diff --git a/src/Copilot/Arduino/Library/Random.hs b/src/Copilot/Arduino/Library/Random.hs
--- a/src/Copilot/Arduino/Library/Random.hs
+++ b/src/Copilot/Arduino/Library/Random.hs
@@ -43,11 +43,11 @@
 
 data RandomSeed = RandomSeed
 
-instance Output PinId RandomSeed (Event () (Stream Word8)) where
+instance Output Arduino RandomSeed (Event () (Stream Word8)) where
 	RandomSeed =: e = randomSeedWith e
 
 -- Seeds with the first 8 bits read from the ADC, discarding the rest.
-instance Output PinId RandomSeed (Event () (Stream ADC)) where
+instance Output Arduino RandomSeed (Event () (Stream ADC)) where
 	RandomSeed =: e = randomSeedWith e
 
 randomSeedWith :: Typed a => Event p (Stream a) -> Sketch ()
@@ -82,7 +82,7 @@
 randomR :: (Word32, Word32) -> RandomInput
 randomR (lo, hi) = RandomInput lo hi
 
-instance Input PinId RandomInput Word32 where
+instance Input Arduino RandomInput Word32 where
 	input' (RandomInput lo hi) interpretvalues = do
 		i <- getUniqueId "random"
 		let varname = uniqueName "randomval" i
diff --git a/src/Copilot/Arduino/Library/Serial/Device.hs b/src/Copilot/Arduino/Library/Serial/Device.hs
--- a/src/Copilot/Arduino/Library/Serial/Device.hs
+++ b/src/Copilot/Arduino/Library/Serial/Device.hs
@@ -46,7 +46,7 @@
 	-> Pin tx
 	-> Baud
 	-> Sketch ()
-configureD d@(SerialDeviceName devname) (Pin (PinId rxpin)) (Pin (PinId txpin)) (Baud n) = do
+configureD d@(SerialDeviceName devname) (Pin (Arduino rxpin)) (Pin (Arduino txpin)) (Baud n) = do
 	baudD d n
 	tell [(\_ -> return (), \_ -> f)]
   where
@@ -67,7 +67,7 @@
 
 newtype SerialDevice = SerialDevice SerialDeviceName
 
-instance Input PinId SerialDevice Int8 where
+instance Input Arduino SerialDevice Int8 where
 	input' (SerialDevice (SerialDeviceName devname)) interpretvalues =
 		mkInput s
 	  where
@@ -89,10 +89,10 @@
 noInput :: Int8
 noInput = -1
 
-instance Output PinId SerialDevice [FormatOutput] where
+instance Output Arduino SerialDevice [FormatOutput] where
 	sdn =: l = sdn =: (Event l true :: Event () [FormatOutput])
 
-instance Output PinId SerialDevice (Event () [FormatOutput]) where
+instance Output Arduino SerialDevice (Event () [FormatOutput]) where
 	SerialDevice sdn@(SerialDeviceName devname) =: (Event l c) = do
 		u <- getUniqueId "serial"
 		let outputfuncname = uniqueName ("output_" <> devname) u
diff --git a/src/Copilot/Arduino/Main.hs b/src/Copilot/Arduino/Main.hs
--- a/src/Copilot/Arduino/Main.hs
+++ b/src/Copilot/Arduino/Main.hs
@@ -141,7 +141,7 @@
 		mapMaybe setuppinmode (M.toList $ pinmodes f)
 	in f { setups = pinsetups <> setups f }
   where
-	setuppinmode (PinId n, s)
+	setuppinmode (Arduino n, s)
 		| s == S.singleton OutputMode =
 			setmode n "OUTPUT"
 		| s == S.singleton InputMode =
diff --git a/src/Copilot/Arduino/Nano.hs b/src/Copilot/Arduino/Nano.hs
--- a/src/Copilot/Arduino/Nano.hs
+++ b/src/Copilot/Arduino/Nano.hs
@@ -33,32 +33,32 @@
 
 pin2, pin4, pin7, pin8, pin12, pin13 :: Pin '[ 'DigitalIO ]
 pin3, pin5, pin6, pin9, pin10, pin11 :: Pin '[ 'DigitalIO, 'PWM ]
-pin2 = Pin (PinId 2)
-pin3 = Pin (PinId 3)
-pin4 = Pin (PinId 4)
-pin5 = Pin (PinId 5)
-pin6 = Pin (PinId 6)
-pin7 = Pin (PinId 7)
-pin8 = Pin (PinId 8)
-pin9 = Pin (PinId 9)
-pin10 = Pin (PinId 10)
-pin11 = Pin (PinId 11)
-pin12 = Pin (PinId 12)
+pin2 = Pin (Arduino 2)
+pin3 = Pin (Arduino 3)
+pin4 = Pin (Arduino 4)
+pin5 = Pin (Arduino 5)
+pin6 = Pin (Arduino 6)
+pin7 = Pin (Arduino 7)
+pin8 = Pin (Arduino 8)
+pin9 = Pin (Arduino 9)
+pin10 = Pin (Arduino 10)
+pin11 = Pin (Arduino 11)
+pin12 = Pin (Arduino 12)
 -- | This pin is connected to the `led`
-pin13 = Pin (PinId 13)
+pin13 = Pin (Arduino 13)
 
 a0, a1, a2, a3, a4, a5 :: Pin '[ 'AnalogInput, 'DigitalIO ]
-a0 = Pin (PinId 14)
-a1 = Pin (PinId 15)
-a2 = Pin (PinId 16)
-a3 = Pin (PinId 17)
-a4 = Pin (PinId 18)
-a5 = Pin (PinId 19)
+a0 = Pin (Arduino 14)
+a1 = Pin (Arduino 15)
+a2 = Pin (Arduino 16)
+a3 = Pin (Arduino 17)
+a4 = Pin (Arduino 18)
+a5 = Pin (Arduino 19)
 
 -- | Limited to analog input.
 a6, a7 :: Pin '[ 'AnalogInput ]
-a6 = Pin (PinId 20)
-a7 = Pin (PinId 21)
+a6 = Pin (Arduino 20)
+a7 = Pin (Arduino 21)
 
 -- | Different versions of Arduino Nano have different EEPROM sizes.
 -- This is a safe value that will work on all versions.
diff --git a/src/Copilot/Arduino/Uno.hs b/src/Copilot/Arduino/Uno.hs
--- a/src/Copilot/Arduino/Uno.hs
+++ b/src/Copilot/Arduino/Uno.hs
@@ -31,27 +31,27 @@
 
 pin2, pin4, pin7, pin8, pin12, pin13 :: Pin '[ 'DigitalIO ]
 pin3, pin5, pin6, pin9, pin10, pin11 :: Pin '[ 'DigitalIO, 'PWM ]
-pin2 = Pin (PinId 2)
-pin3 = Pin (PinId 3)
-pin4 = Pin (PinId 4)
-pin5 = Pin (PinId 5)
-pin6 = Pin (PinId 6)
-pin7 = Pin (PinId 7)
-pin8 = Pin (PinId 8)
-pin9 = Pin (PinId 9)
-pin10 = Pin (PinId 10)
-pin11 = Pin (PinId 11)
-pin12 = Pin (PinId 12)
+pin2 = Pin (Arduino 2)
+pin3 = Pin (Arduino 3)
+pin4 = Pin (Arduino 4)
+pin5 = Pin (Arduino 5)
+pin6 = Pin (Arduino 6)
+pin7 = Pin (Arduino 7)
+pin8 = Pin (Arduino 8)
+pin9 = Pin (Arduino 9)
+pin10 = Pin (Arduino 10)
+pin11 = Pin (Arduino 11)
+pin12 = Pin (Arduino 12)
 -- | This pin drives the `led`
-pin13 = Pin (PinId 13)
+pin13 = Pin (Arduino 13)
 
 a0, a1, a2, a3, a4, a5 :: Pin '[ 'AnalogInput, 'DigitalIO ]
-a0 = Pin (PinId 14)
-a1 = Pin (PinId 15)
-a2 = Pin (PinId 16)
-a3 = Pin (PinId 17)
-a4 = Pin (PinId 18)
-a5 = Pin (PinId 19)
+a0 = Pin (Arduino 14)
+a1 = Pin (Arduino 15)
+a2 = Pin (Arduino 16)
+a3 = Pin (Arduino 17)
+a4 = Pin (Arduino 18)
+a5 = Pin (Arduino 19)
 
 sizeOfEEPROM :: Word16
 sizeOfEEPROM = 512
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -2,7 +2,7 @@
 - '.'
 resolver: lts-18.9
 extra-deps:
-- sketch-frp-copilot-1.0.0
+- sketch-frp-copilot-1.0.1
 - copilot-3.7
 - copilot-c99-3.7
 - copilot-core-3.7
