Introduction to Design (2)
Microcontrollers and Interfacing
Week 12
input/output devices
project suggestions
using shields: the LoLShield
Department of Mechanical and Electrical System Engineering
devices: discrete sensors
for use with breadboard:
• temperature
• photocell (visible light)
• photodiode (infra-red light)
• momentary push switch (e.g., use many to make musical keyboard)
• potentiometer (rotary position with ≈ 300◦ range)
• electrostatic field
• rotary encoder
– 360◦ range (continuous rotation)
– 2-bit Gray code output (‘quadrature’)
outputs D0
D1
2
shield: game controller
joystick + four momentary switches
• analogue joystick on A0, A1
• buttons on D3, D4, D5, D6
• not quite ‘stackable’
– wires to connect headers to dis-
crete devices
– jumpers to connect headers to
breadboard
could be used above a stackable shield to make wireless controller...
3
shield: wi-fi
stackable shield; use with:
• game controller
• LCD display
• etc.
‘pairs’ with other XBee devices
• similar to Bluetooth
• but over real Wi-Fi
long range
• ≈ 100 m indoors
same interface as Serial device
• print(), write(), read(), etc.
• data exchanged with paired devices
4
shields: backplanes
‘Grove’ series of devices
• shield for Arduino (and many others)
• single connector type (4-pin header)
• many signals routed to connectors
– analogue inputs
– digital input/output (in pairs)
– I2 C bus
• many compatible devices
• libraries for ease of use
5
devices: sensors
angle (potentiometer) rotary encoder
3-axis gyroscope (I2 C)
3-axis accelerometer (I2 C)
6
devices: sensors
touch button
sound light
temperature distance
7
devices: actuators
relay (single-pole single-throw)
servo motor
8
devices: displays
simple LED buzzer
2-line LCD 4-digit
dot-matrix LED
display display
9
shields: displays
colour LCD touch screen
• 320 × 240 resolution
• access via library
• draw lines, rectangles, text
• read pressure input & position
10
shields: displays
LoLshield (Lots of LEDs)
• 14 × 9 array of LEDs
• uses 12 digital pins (D2 to D13)
• each LED individually addressable
– ‘Charlieplexing’ connects many LEDs to a few pins
(see Wikipedia entry for fascinating details)
• library hides complexity of addressing
– LedSign::Set(), LedSign::Clear(), etc.
– double-buffering for smooth scrolling
11
complete project suggestions: easy
1. electrostatic field detector
A0
4M7
GND
explore fields near
electrical equipment
• or your hand
display results on
• serial plotter [see week 2], or a
• self-calibrating [week 4] bar-graph display [week 7]
12
complete project suggestions: easy
2. toggle switch from push-button
microcontrollers are good at making simple components more versatile
the switches we have are only ‘on’ while they are pressed
use the microcontroller to convert a push-button into a toggle switch
push-button toggle
a toggle switch alternates between ‘on’ and ‘off’ switch switch
push on on
• to make it go on and then off, you have to press it twice release off on
push on off
• most light switches behave like this release off off
begin with a push-button switch [week 8] controlling an LED
• press to turn on, release to turn off (don’t forget to de-bounce)
then change the program to flip between on and off when the button is pressed
• press to turn on, release and then press again to turn off
13
complete project suggestions: easy
void setup(void) {
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, OUTPUT);
}
int state = 0; // light off
void loop(void) {
if (0 == digitalRead(2)) { // pressed
state = 1 - state; // toggle
digitalWrite(4, state);
while (0 == digitalRead(2))
delay(50);
}
}
3. two-way light switches
make a pair of light switches that control one LED
• pressing either switch should turn the light on
• pressing either switch again should turn the light off
(this is how switches at the top and bottom of stairs often work to control one light)
14
complete project suggestions: easy
4. electronic dice
use a 7-segment LED [week 8] to display a random value from 1 to 6
push button to ‘roll’ the dice
• don’t forget to de-bounce the button!
for extra realism:
• display a rapid sequence of random numbers until the dice stops ‘rolling’
while (buttonPressed) {
for (int i = 0; i < 10; i += 1) {
int digit = random(1, 7); // random number between 1 and 6
displayDigit(digit);
delay(100);
}
}
for extra satisfaction (medium difficulty): add a second button and second display
• you now have two electronic dice!
15
complete project suggestions: easy
5. musical instrument with a keyboard made of switches
6. four-digit clock using I2 C display
• with battery-backup to remember the time
+ with push buttons to set the time?
+ with alarm?
7. wireless chat (using wi-fi communication)
• use two Arduino microcontrollers
• connect a real terminal emulator to the USB serial
• exchange characters from one side to the other via wi-fi
16
complete project suggestions: easy
8. digital to analogue converter using resistors
ladder of resistors with values R and 2R
• e.g: R = 1.5 kΩ, 2R = 3 kΩ
• build at least 8 bits (your kit has 10 of each of these values)
• check the accuracy using external 12-bit SPI ADC
N-bit binary number
b0 b1 bN-2 bN-1
2R 2R 2R 2R
R R R VOUT
2R
GND
17
complete project suggestions: easy
18
complete project suggestions: medium
9. build a R-2R DAC with output buffer
the previous project cannot drive a loudspeaker
the loudspeaker resistance is too low and interferes with the the resistor ladder
add an output buffer with very high impedance to drive (e.g.) a loudspeaker
op-amp buffer transistor buffer
5V 5V
8
3
VIN + 1 1
2
150 VOUT
- 2
4
VIN
GND
3 150 VOUT
GND
VOUTA 1 8 5V
VINA- 2 7 VOUTB BC548
VINA+ 3 6 VINB- GND
GND 4 5 VINB+
MCP6002 1 collector
2 base
3 emittter
1 2 3
19
complete project suggestions: medium
op-amp buffer: more
complex, better
performance
transistor buffer: simpler,
worse performance (and
input must stay >0.7 V)
20
complete project suggestions: medium
10. morse code transmitter
rebuild the morse code transmitter from earlier
make it generate tones on the loudspeaker
control it by typing messages into the serial monitor
• use Serial.read() to read characters sent from the serial monitor
• ignore characters you don’t recognise
complete project suggestions: advanced
11. morse code receiver
connect some kind of input to the microcontroller
• push-button (don’t forget to de-bounce it)
• light-dependent resistor (use a threshold with hysteresis to determine on/off)
read morse code from the input device
decode the morse code and print the result on the serial monitor
21
complete project suggestions: advanced
12. SPI DAC
use an external SPI [week 11] DAC (MPC4822) to generate sine waves
this DAC circuit is designed to work alongside the SPI ADC circuit, if desired
• DAC and ADC can share SCK and MOSI, but need separate SSN signals
• make sure they are never enabled at the same time!
5V VDD
SCK 3
D13 SCK
MISO
D12
microcontroller
MCP4822
MOSI 4 8
D11 SDI VOUTA
analogue
D10
SSN1
VOUTB
6 outputs
SSN2 2
D9 CS
5
D8 LDAC
GND VSS
7
(the lab reference material from week 11 shows how to communicate with the DAC)
22
complete project suggestions: advanced
download sine.h from the ID2 Team, General channel, Files/Libraries section
• it contains a table of 4096 integers describing a sine wave
• it also defines a function for you: sine(N) = 2048 + 2047 sin(2πN ÷ 4096)
use a TimerOne interrupt [week 9] and sine() to output a sample every 50 µs
#include "sine.h" // download from the web site
const long rate = 20000; // number of output samples per second
void setup(void) {
Timer1.initialize(1000000L / rate); // microseconds between samples
Timer1.attachInterrupt(timer); // sample generator function
}
volatile unsigned int angle = 0, omega = 1000 * 4096L / rate;
void timer(void) {
setDAC(sine(angle)); // sine() is defined in "sine.h"
angle += omega;
}
omega controls the frequency f of sine wave that is generated
• if r is sample rate and there are 4096 entries in one cycle, omega = f × 4096 ÷ r
23
complete project suggestions: advanced
13. chord generator
extend the SPI DAC circuit to play major and minor chords
use the same sine wave table and sine() function to generate three sine waves
• use three pairs of ‘phase’ and ‘omega’ variables to scan the table
simultaneously
• add the three sample values together, divide the result by 3, send to DAC
• for major chords, use: f0 , f1 = 45 f0 , f2 = 32 f0
• for minor chords, use: f0 , f1 = 56 f0 , f2 = 32 f0
• use a push button to swap between major/minor
• use another push button to change f0 so that you can play several chords
– e.g., it might cycle f0 between 1000 Hz, 1333 Hz, and 1500 Hz
– then f1 and f2 are recalculated based on f0
– you should now be able to ‘play the blues’ on your microcontroller
24
complete project suggestions: advanced
14. waveform generator
use an external SPI (or R-2R) DAC to generate
• sine waves, triangle, or square waves
• with variable frequency, amplitude
use Serial interface to control the waveform
S 1000 100 sine wave, 1000 Hz, 100% amplitude
Q 1200 66 square wave, 1200 Hz, 66% amplitude
T 800 5 triangle wave, 800 Hz, 5% amplitude
void loop(void) {
if (Serial.available() > 0) {
int c = toupper(Serial.read());
int f = Serial.parseInt();
int a = Serial.parseInt();
if (’S’ == c) playSineWave(f, a);
else if (’Q’ == c) playSquareWave(f, a);
else if (’T’ == c) playTriangleWave(f, a);
else disableWave();
}
}
use an analogue input (or SPI ADC) to show the result on the serial plotter
25
complete project suggestions: advanced
15. pulse rate monitor
10 nF
150
5V
1M
1M
pulse detector
microcontroller
place next
to each other
- 560 nF
MCP6002 +
+ MCP6002 A0
cover with finger
-
to detect pulse
1M
10k
GND
1k
+
10 uF
26
complete project suggestions: advanced
challenge: add two 7-segment displays showing pulse rate in beats per minute
27
complete project suggestions: difficult
16. infra-red (IR) communication with ‘bit-banged’ serial protocol
implement your own serial communication (e.g., for text chat)
• IR LED ‘transmitter’, IR photo-diode ‘receiver’
• explicit encoding/decoding, e.g: 1 start bit, 8 data bits, 1 stop bit
one team member makes a transmitter, the other makes a receiver
first step: make sure you can make the photodiode detect pulses from the IR LED!
frame
transmitter
previous 1 x7 x6 x5 x4 x3 x2 x1 x0 1
digital time
output
330 GND
IR LED start data (8 bits, MSB first) stop
bit bit
receiver IR photodiode
1 x7 x6 x5 x4 x3 x2 x1 x0 1
analogue
input
4M7 5V read data bits
verify start bit verify stop bit
Note: the photodiode must be synchronise on start of frame (wait for rising edge)
connected ‘backwards’ to work!
1/2 bit time 1 bit time
last step: Serial.read() + IR transmit → IR receive + Serial.write()
28
complete project suggestions: flexible
challenges
• any of the challenges that you have not already completed
invent your own project!
• use any input/output devices to gather/display information
• perform any function in between
29
your project
work in teams of three (plus or minus one) people
• choose your team partner(s) today
choose a project you feel confident that you can finish
• an easy completed project is much better than an ambitious unfinished project
• use one of the suggested projects if you like
– possibly modified/extended: different input(s), output(s), etc.
• or invent your own project using parts that you have available
ask the instructors about anything you are having difficulty with
• time is short, and help is always available
• do not become blocked because you cannot understand something
• use e-mail to ask for help or advice: ian.piumarta@kuas.ac.jp
(or one of the channels in our MS Teams team)
30
next weeks
week 12 (today and homework):
• discuss within your team what project to complete
• tell me before Monday next week if you need special components
week 13, week 14:
• project work, consultation with instructors, ask questions!
week 15:
• project presentations: hard limit 5 (five) minutes per team
• send me slides (PDF) demo movies (avi, mov, mp4) before Week 15 class
• all team members must speak during the presentation
– what is the project (especially if you invented it)?
– why did you choose that project?
– video demonstration (optional but recommended)
– what was difficult?
– what did you learn?
31
exercises
look at (do not take, yet) some of the devices I have brought with me today
practice with a complex device: Lots of LEDs, ‘LoL Shield’
32
LoL Shield API
#include "Charliplexing.h"
LedSign::Init(uint8_t mode = 0)
initializes the library. The mode argument can be used to enable support for
double-buffering (DOUBLE_BUFFER) and/or greyscale (GRAYSCALE).
LedSign::SetBrightness(uint8_t brightness)
sets the overall brightness of the screen, between 0 and 127.
LedSign::Set(uint8_t x, uint8_t y, uint8_t c = 1)
turns on the LED at coordinates (x, y). To turn it on full brightness, the value 7 should be
passed as the third argument c.
LedSign::Clear(uint8_t c = 0)
sets the brightness of all the LEDs to c. (The default value 0 turns them all off.)
LedSign::Flip(bool blocking = false)
swaps the front and back buffers, if double-buffering is enabled.
LedSign::Horizontal(uint8_t y, uint8_t c = 0)
fills an entire row with the specified value (0 for off, 7 for full on).
LedSign::Vertical(uint8_t x, uint8_t c = 0)
fills an entire column with the specified value (0 for off, 7 for full on).
33