10. Input devices¶
Individual Assignment:
- measure something: add a sensor to a microcontroller board that you have designed and read it
Group Assignment:
- Probe an input device’s analog levels and digital signals
Since the HC-SR501 pyroelectric sensor was the only sensor at hand, I decided to read the pyroelectric sensor using the ATTiny412 MCU.
Eagle¶
Pyroelectric Sensor¶
The pinout of the sensor was relatively simple as the output was a single pin that is HIGH when motion is detected and LOW when motion is not detected. In Eagle, I connected the SMD pad for the output pin directly to a pin on the MCU.
Then, I switched over to board file and imported the 1/64th Bantam Tools DRC file into Design Rules.
When placing the pads, I made sure that the SMD pads for the sensor was far enough from other components to give clearance for mounting the sensor.
Next, I used autorouter to generate the traces.
I had to fix a portion of the traces as it encroached on the top right pad for the MCU.
Accelerometer¶
Even though I had no access to an accelerometer, I designed the board for the acclerometer as well. The accelerometer that I designed for was the MPU-6050 and it uses i2c communications. The pinout on the accelerometer was more complicated than the pyroeletric sensor as there are two data pins: Serial Clock (SCL) and Serial Data (SDA).
At first, I simply connected the data pins to the closest on the MCU.
However, the ATTiny412 datasheet reveals that only two specific pins on the MCU support hardware i2c communcations. Now, the first design was doable as Neil provided code for software i2c communication, however, I wanted the faster hardware support. As a result, I rewired the connections to make the SDA and SCL pins connect to the SDA and SCL pins on the MCU.
Reading this article> backed up the theoretical functionality of my design. In addition, the article specifies the use of the TinyMegaI2C library.
Soldering¶
Since I couldn’t access the lab due to the fact that the school was shutdown in the face of the coronavirus, I sent the board and schematic files to Mr. Rudolph so that he could mill them at the lab and send the board to me.
Here is the board with the components soldered on:
However, William pointed out that the sensor pins were crossing over traces running beside the SMD pads. I had to unsolder the sensor and place tape on the traces in order to insulate the traces.
Unfortunately, I also realized that the board design was wrong as the the VCC and Ground was switched for the sensor SMD pads. Instead, I soldered pins to the sensor SMD pads so that I could correct the problem with jumper wires.
Code¶
The code was relatively simple as I repurposed the button code from last week and made slight changes. I also added serial communication in order to communicate with the computer.
#define F_CPU 20000000
#include <avr/io.h>
#define setInputPin(pin) PORTA.DIRCLR |= (1 << pin)
#define setOutputPin(pin) PORTA.DIRSET |= (1 << pin)
#define setPinHigh(pin) VPORTA.OUT |= (1 << pin)
#define setPinLow(pin) VPORTA.OUT &= ~(1 << pin)
#define readPin(pin) VPORTA.IN & (1 << pin)
#define led_pin 6
#define input_pin 7
#define max_buffer 25
static int index = 0;
static char chr;
static char buffer[max_buffer] = {0};
void setup() {
setInputPin(input_pin);
setOutputPin(led_pin);
Serial.begin(115200);
}
void loop() {
if (readPin(input_pin)) {
setPinHigh(led_pin);
Serial.println("Motion Detected");
}
else {
setPinLow(led_pin);
Serial.println("Motion Undetected");
}
}
GUI¶
Inspired by Neil’s GUI for his sensor, I decided to create a simple GUI for my sensor. I used CEF Python to create a web based UI that would have Python bindings for serial communications. I used the PySerial package for serial communications.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/lux/bootstrap.min.css" rel="stylesheet" integrity="sha384-oOs/gFavzADqv3i5nCM+9CzXe3e5vXLXZ5LZ7PplpsWpTCufB7kqkTlC9FtZ5nJo" crossorigin="anonymous">
</head>
<body>
<h1 id="text" class="display-1 text-center"></h1>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<script>
$( document ).ready(function() {
console.log( "ready!" );
var interval = setInterval(function(){
tick();
}, 100);
});
function motion_detected() {
print_func("Motion");
document.body.style.backgroundColor = "red";
$("#text").html("Detected");
}
function motion_undetected() {
print_func("No Motion");
document.body.style.backgroundColor = "green";
$("#text").html("Undetected");
}
</script>
</body>
</html>
from cefpython3 import cefpython as cef
import sys
import serial.tools.list_ports
serial2usb_description = "FT232R USB UART"
baud_rate = 115200
ports = serial.tools.list_ports.comports()
serial_port = None
for port in ports:
print(port.description)
print(port.device)
if serial2usb_description in port.description:
serial_port = port
device = serial.Serial(serial_port.device, baud_rate)
sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error
cef.Initialize()
browser = cef.CreateBrowserSync(url="file:/.../interface.html",
window_title="Motion Detection")
def print_func(text, js_callback=None):
print(text)
def tick():
status = device.readline().strip().decode("utf-8")
print(status)
if "Motion Detected" in status:
browser.ExecuteJavascript("motion_detected()")
else:
browser.ExecuteJavascript("motion_undetected()")
bindings = cef.JavascriptBindings(bindToFrames=False, bindToPopups=False)
bindings.SetFunction("print_func", print_func)
bindings.SetFunction("tick", tick)
browser.SetJavascriptBindings(bindings)
cef.MessageLoop()
device.close()
cef.Shutdown()