Skip to content

11. Input devices#

This week's topics: Inputs, sensors for communication, switch, motion, distance, magnetic field, temperature, light, acceleration, orientation, rotation, sound, step response, vibration, force, position, pressure, angle, and image.

Group Assignment#

Probe an input device's analog levels and digital signals

Individual Assignment#

Measure something: add a sensor to a microcontroller board that you have designed, and read it

  1. Choose a sensor: I chose to use a temperature sensor because this is the main sensor I plan to use for my final project.
  2. Locate and download the footprint for the sensor if it doesn't exist in the fab footprints library. I found this lead-free temperature sensor in the Waag inventory, but I any luck finding a footprint for it in the FabAcademy, UltraLibrarian, or DigiKey footprint libraries. I decided to use a 10k Resistor footprint for it in my PCB design because they were similar enough in size.
  3. Create a schematic in KiCad. I had to do this twice. The first time I did it, I used elements from the symbol library to label the GND and VCC connections. I also labeled each connection with the name of the item is was going to connect to, rather than with the same name. In other words, If a resistor with the name R3 needed to connect to PB5, I labeled the resistor connection with PB5, and the PB5 connection with the name R3. This created a pcb layout with many missing connections. I did not realize this until after I had milled the first PCB. I resolved this by deleting all of the GND and VCC symbols, naming them manually, and setting all other schematic connections to have the same name.
  4. Lay out the traces for the PCB. Using the newest version of KiCad for OSX, I needed to re-import the Fab footprints libraries and set the design rules again. While doing this, I discovered a setting that will always show the trace clearance and I found this very helpful. This setting exists in Pcbnew > KiCad menu > Preferences > Display options > Clearance options > choose 'Show always' and select the checkbox next to Show pad clearance.
    The design rules settings moved to a new location in this version. It now exists under File > Board setup > Design Rules > Net classes.
    Once I adjusted settings, it was easy to lay out the board and set the traces. I decided to create two edge cut rectangles. I changed the grid settings to use 1mm. This was useful because the cursor was able to snap the edge cut corner points to whole mm points. The inner one was 6mm from all traces. The outer one was 2mm from the inner one. I did this because it has been difficult to get KiCad to create correct Edge Cut SVGs, so this was a workaround. I exported the and saved the files, and used the KiCad measure tool to measure the size of the outer rectangle so I could use it to set the image size in gimp in the next step.
  5. Export PCB as SVG.
  6. Edit SVG using Gimp. I opened the copper and edge cut SVGs in gimp, set the DPI to 1000. I first tried 10k, 5k, and 2k, but they were all to high for mods to work with. Mods would not recognize them. I set the dimensions to 45mm x 33mm, which was the size of the outer rectangle. I used the eraser tool to erase the outer rectangle. I right-clicked the image in the right hand pane and selected 'Remove alpha layer'. I selected File > Export as > and saved both files as PNG images.
  7. First attempt: Mill the PCB using mods and Roland MDX-20. There was a small space left on the existing copper plate in the mill that someone had left there and it looked like the previous user had success with their designs, so I decided to use the plate that was there. This turned out to be a bad idea because, although it milled correctly, the board became loose during the end of the edge cut milling, and it became stuck in the mill.
    Second attempt I replaced the plate and tried again. The first mill I used was not broken, but it caused a lot of frayed copper traces, so I switched mills and tried again.
    Third attempt Success! Unfortunately, I realized that my design was wrong. I returned to KiCad to fix my design.
    Fourth attempt Success!
  8. Solder the PCB. I had no issues with this step.
  9. Burn the bootloader onto the PCB. I double-checked the orientation of the ISP on the hello temp board, plugged it into my fabISP with the ribbon connector and connected the fabISP to my computer with a USB 2.0 hub. In the Arduino software, I set the following settings under the tools menu:
    Board: "ATtiny25/45/85" Processor: "ATtiny45" Clock: "Internal 8MHz" Programmer: USBTinyISP

Then I selected 'Tools > Burn Bootloader'. It worked. Arduino output:

/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -pattiny45 -cusbtiny -e -Uefuse:w:0xff:m -Uhfuse:w:0xdf:m -Ulfuse:w:0xe2:m 

avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch

System wide configuration file is "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
User configuration file is "/Users/heidihansen/.avrduderc"
User configuration file does not exist or is not a regular file, skipping

Using Port                    : usb
Using Programmer              : usbtiny
avrdude: usbdev_open(): Found USBtinyISP, bus:device: 020:040
AVR Part                      : ATtiny45
Chip Erase delay              : 4500 us
PAGEL                         : P00
BS2                           : P00
RESET disposition             : possible i/o
RETRY pulse                   : SCK
serial program mode           : yes
parallel program mode         : yes
Timeout                       : 200
StabDelay                     : 100
CmdexeDelay                   : 25
SyncLoops                     : 32
ByteDelay                     : 0
PollIndex                     : 3
PollValue                     : 0x53
Memory Detail                 :

Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom        65     6     4    0 no        256    4      0  4000  4500 0xff 0xff
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
flash         65     6    32    0 yes      4096   64     64  4500  4500 0xff 0xff
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

Programmer Type : USBtiny
Description     : USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp
avrdude: programmer operation not supported

avrdude: Using SCK period of 10 usec
CMD: [ac 53 00 00] [00 00 53 00]
avrdude: AVR device initialized and ready to accept instructions

Reading | CMD: [30 00 00 00] [00 30 00 1e]
CMD: [30 00 01 00] [00 30 00 92]
################CMD: [30 00 02 00] [00 30 00 06]
################################## | 100% 0.01s

avrdude: Device signature = 0x1e9206 (probably t45)
avrdude: erasing chip
CMD: [ac 80 00 00] [00 ac 80 00]
avrdude: Using SCK period of 10 usec
CMD: [ac 53 00 00] [00 ac 53 00]
avrdude: reading input file "0xff"
avrdude: writing efuse (1 bytes):

Writing | CMD: [50 08 00 00] [00 50 08 ff]
################################################## | 100% 0.00s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xff:
avrdude: load data efuse data from input file 0xff:
avrdude: input file 0xff contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | CMD: [50 08 00 00] [00 50 08 ff]
################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xdf"
avrdude: writing hfuse (1 bytes):

Writing | CMD: [58 08 00 00] [00 58 08 df]
################################################## | 100% 0.00s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xdf:
avrdude: load data hfuse data from input file 0xdf:
avrdude: input file 0xdf contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | CMD: [58 08 00 00] [00 58 08 df]
################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xe2"
avrdude: writing lfuse (1 bytes):

Writing | CMD: [50 00 00 00] [00 50 00 62]
CMD: [ac a0 00 e2] [00 ac a0 00]
CMD: [50 00 00 00] [e2 50 00 ff]
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude CMD: [50 00 00 00] [00 50 00 ff]
-C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v CMD: [50 00 00 00] [00 50 00 e2]
-v -v -v ################################################## | 100% 0.01s
-pattiny45 -cusbtiny 

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xe2:
avrdude: load data lfuse data from input file 0xe2:
avrdude: input file 0xe2 contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | CMD: [50 00 00 00] [00 50 00 e2]
################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude done.  Thank you.


avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch

System wide configuration file is "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
User configuration file is "/Users/heidihansen/.avrduderc"
User configuration file does not exist or is not a regular file, skipping

Using Port                    : usb
Using Programmer              : usbtiny
avrdude: usbdev_open(): Found USBtinyISP, bus:device: 020:040
AVR Part                      : ATtiny45
Chip Erase delay              : 4500 us
PAGEL                         : P00
BS2                           : P00
RESET disposition             : possible i/o
RETRY pulse                   : SCK
serial program mode           : yes
parallel program mode         : yes
Timeout                       : 200
StabDelay                     : 100
CmdexeDelay                   : 25
SyncLoops                     : 32
ByteDelay                     : 0
PollIndex                     : 3
PollValue                     : 0x53
Memory Detail                 :

Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom        65     6     4    0 no        256    4      0  4000  4500 0xff 0xff
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
flash         65     6    32    0 yes      4096   64     64  4500  4500 0xff 0xff
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

Programmer Type : USBtiny
Description     : USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp
avrdude: programmer operation not supported

avrdude: Using SCK period of 10 usec
CMD: [ac 53 00 00] [ff fe 53 00]
avrdude: AVR device initialized and ready to accept instructions

Reading | CMD: [30 00 00 00] [00 30 00 1e]
CMD: [30 00 01 00] [00 30 00 92]
################CMD: [30 00 02 00] [00 30 00 06]
################################## | 100% 0.01s

avrdude: Device signature = 0x1e9206 (probably t45)

avrdude done.  Thank you.
  1. Configure development environment to run hello.temp program. This involved installation and configuration of many dependencies. First, I downloaded neils hello.temp.c, hello.temp.py, and hello.temp.make files from this week's site. Note: I am intentionally not linking to each individual file here because there are bugs in the files and I think Neil might change/update them.
    In Terminal:
    avrdude -c usbtiny -p t45 returned
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9206 (probably t45)
avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)
avrdude done.  Thank you.

In the directory that contained the hello temp files:


♥ make program-usbtiny
returned
make: *** No targets specified and no makefile found. Stop.


♥ avrdude -p t45 -P usb -c usbtiny -U flash:w:hello.temp.45.c.hex
returned

avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e9206 (probably t45)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "hello.temp.45.c.hex"
avrdude: error opening hello.temp.45.c.hex: No such file or directory
avrdude: can't determine file format for hello.temp.45.c.hex, specify explicitly
avrdude: read from file 'hello.temp.45.c.hex' failed
avrdude: safemode: Fuses OK (E:FF, H:DF, L:E2)
avrdude done.  Thank you.

make program-usbtiny
returned
make: *** No rule to make target 'program-usbtiny'. Stop.


make -f hello.temp.45.make
returned

avr-gcc -mmcu=attiny45 -Wall -Os -DF_CPU=8000000 -I./ -o hello.temp.45.out hello.temp.45.c
avr-objcopy -O ihex hello.temp.45.out hello.temp.45.c.hex;\
avr-size --mcu=attiny45 --format=avr hello.temp.45.out
AVR Memory Usage
----------------
Device: attiny45
Program:     478 bytes (11.7% Full)
(.text + .data + .bootloader)
Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)

avrdude -p t45 -P usb -c usbtiny -U flash:w:hello.temp.45.c.hex
returned

avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9206 (probably t45)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "hello.temp.45.c.hex"
avrdude: input file hello.temp.45.c.hex auto detected as Intel Hex
avrdude: writing flash (478 bytes):
Writing | ################################################## | 100% 0.58s
avrdude: 478 bytes of flash written
avrdude: verifying flash memory against hello.temp.45.c.hex:
avrdude: load data flash data from input file hello.temp.45.c.hex:
avrdude: input file hello.temp.45.c.hex auto detected as Intel Hex
avrdude: input file hello.temp.45.c.hex contains 478 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.84s
avrdude: verifying ...
avrdude: 478 bytes of flash verified
avrdude: safemode: Fuses OK (E:FF, H:DF, L:E2)

avrdude done.  Thank you.

Then I got the error that the python file needed parentheses around line 68 print line, so I edited the python file to add parentheses around the print line, saved, and ran it again.
♥ python hello.temp.45.py /dev/ttyUSB0

Traceback (most recent call last):
File "hello.temp.45.py", line 15, in <module>
from Tkinter import *
ModuleNotFoundError: No module named 'Tkinter'`
  • After some research, I found that the module Tkinter had changed to be lowercase for python 3.
  • I modified the import statement to use the lowercase tkinter and ran it again.
  • There were a few times I ended up inside the python interpreter in the terminal, and I had to learn how to close the interpreter without closing the terminal window (and thus losing all my terminal output logs). The command for quitting the python interpreter on a mac is Command-D.
  • I discovered that I needed to declare commands using python3 instead of python because my development envriornment has many versions of python.

♥ brew upgrade python3 to update python3 to pull down the newest version of tkinter


Finally tried to install tcl-tk (the homebrew package that contains tkinter for python3)
♥ brew install tcl-tk
returned

==> Downloading https://homebrew.bintray.com/bottles/tcl-tk-8.6.9.mojave.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring tcl-tk-8.6.9.mojave.bottle.1.tar.gz
==> Caveats
tcl-tk is keg-only, which means it was not symlinked into /usr/local,
because tk installs some X11 headers and macOS provides an (older) Tcl/Tk.

If you need to have tcl-tk first in your PATH run:
echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' >> ~/.bash_profile

For compilers to find tcl-tk you may need to set:
export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"

For pkg-config to find tcl-tk you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"

I added the suggested exports to my path:

♥ echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' >> ~/.bash_profile
♥ export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
♥ export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
♥ export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"

Tried to run the python script:
♥ python3 hello.temp.45.py /dev/ttyUSB0
returned

Traceback (most recent call last):
File "hello.temp.45.py", line 16, in <module>
from numpy import log
ModuleNotFoundError: No module named 'numpy'

Installed numpy:
♥ pip3 install numpy
returned

Collecting numpy
Downloading https://files.pythonhosted.org/packages/a6/6f/cb20ccd8f0f8581e0e090775c0e3c3e335b037818416e6fa945d924397d2/numpy-1.16.2-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (13.9MB)
100% |████████████████████████████████| 13.9MB 2.8MB/s 
Installing collected packages: numpy
Successfully installed numpy-1.16.2

Tried to run the python script again:
♥ python3 hello.temp.45.py /dev/ttyUSB0
returned

Traceback (most recent call last):
File "hello.temp.45.py", line 17, in <module>
import serial
ModuleNotFoundError: No module named 'serial'

Installed serial:
♥ pip3 install pyserial
returned

Collecting pyserial
Downloading https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl (193kB)
100% |████████████████████████████████| 194kB 9.7MB/s 
Installing collected packages: pyserial
Successfully installed pyserial-3.4

Tried to run the python script again:
♥ python3 hello.temp.45.py /dev/ttyUSB0
returned

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/serial/serialposix.py", line 265, in open
self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
FileNotFoundError: [Errno 2] No such file or directory: '/dev/ttyUSB0'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "hello.temp.45.py", line 74, in <module>
ser = serial.Serial(port,9600)
File "/usr/local/lib/python3.7/site-packages/serial/serialutil.py", line 240, in __init__
self.open()
File "/usr/local/lib/python3.7/site-packages/serial/serialposix.py", line 268, in open
raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
serial.serialutil.SerialException: [Errno 2] could not open port /dev/ttyUSB0: [Errno 2] No such file or directory: '/dev/ttyUSB0'

Finally, I corrected my script to use the right serial port:
python3 hello.temp.45.py /dev/cu.SLAB_USBtoUART
returned

hello.temp.45.py:55: RuntimeWarning: invalid value encountered in log
T = 1.0/(log(R/R25)/B+(1/(25.0+273.15))) - 273.15
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 749, in callit
func(*args)
File "hello.temp.45.py", line 57, in idle
x = int(.2*WINDOW + (.9-.2)*WINDOW*(filter-20.0)/10.0)
ValueError: cannot convert float NaN to integer

It worked! The python project opened and I was able to view the temperature slider. There are still some errors that need to be fixed, likely due to the migration from python 2 to python 3, but I am very happy that I got the board working after all these software issues.