Weekly Summary
Reading Temperature sounds straightforward, but I found a way to make it complex - and quite exciting.
- I made a board comparing the Voltage Divider and Bridge Approach
- I used Chrome 89 and Web Serial to read the Serial Data
- I used D3 to visualise the time series temperature data.
- And I went to Akihabara!
Group Assignment
The Group Assignment is to probe an input device's analog levels and digital signals. We will make our board, and once they are done and working, probe them.
The Oscilloscope has two input channels, to compare and contrast data from 2 different sources.
The challenge was to zoom in/out of the signal, where difference can be observed. And auto-select mode is available, but it did not manage to home in onto the signal.
We could clearly see the serial data being sent as a burst of digital signals.
Individual Assignment
The Individual Assignment asks us to measure something: design and add a sensor to a microcontroller board, and the read it.
With the aim of producing something relevant for my Final Project, I will work with temperature sensors.
Assignment Work Plan
After the fun review session of the global fab machines, Neil's lecture in input devices was dense and packed with information. I am planning for this week(end) is to make an input board that shows out comprehension of input sensors.
Sensor: Temperature Sensor
I will only use the thermistors in the Fab Inventory, and 3 different ways of reading temperature with the 3216.
- 3216 Internal Temperature Sensor
- Single Thermistor
- Wheatstone Bridge Thermistor
My plan is the following:
- ๊ฉ 1: Sketch a thermistor breakout (daughter) board for my 3216 board.
- ๊ฉ 2: Draw it in Eagle
- ๊ฉ 3: Mill & Stuff
- ๊ฉ 4: Test
- ๊ฉ 5: Make a whole new board with button, LED & thermistor
- ๊ฉ 6: GOTO ๊ฉ2
Extra:
- ๊ฉ 7: Make the boards (FT230, 3216) with GameBoy Cartridge connectors.
Work Plan
Identifying the Thermistor
The thermistor available in the FabLab is a NTC NHQ103B375T10, it's key specs are:
- Typ: NTC (Negative Temperature Coefficient)
- Resistance in Ohms @ 25ยฐC: 10k
- Resistance Tolerance: ยฑ10%
- Resistance (R25): 10Kฮฉยฑ10%
- Operating Temperature: -40ยฐC ~ 125ยฐC
- Mounting Type: Surface Mount
- Package / Case: 1206 (3216 Metric)
- B Value Tolerance: ยฑ5%
- B25/85: 3750K
The B Values need some more exploration. What exactly is a B Value, and what does B25/85 mean?
B25/85 means the resistance difference between 25ยบC and 85ยบC.
In the datasheet table there are also entries for B0/50, B25/50, B25/75, B25/100, but none of them are populated.
Calculating Temperature from Resistance
Steinhart-Hart
The Steinhart-Hart Equation is a more complex transfer function. From a practical standpoint, three parameters, a, b and c - the SteinhartโHart parameters - must be specified to calculate the temperature.
Beta Parameter Equation
The Beta Parameter Equation is a slight simplified version of the Steinhart-Hart Equation, the a, b, c parameter can be derived from the B - or Beta Value - or B25/85 Value.
- R: resistance at absolute temperature
- T (K) R0: resistance at absolute temperature T0 (K)
- B: B Value
- *T (K) = t (ยบC) +273.15
From Neil's Python code, here is the C version for the Arduino IDE
float R25 = 10000;
float B = 3750; // B25/85 3750K
float V, R, T;
V = analogRead(Sensor1_PIN);
R = R25 * (1024.0 / V - 1.0);
T = 1.0 / ( log(R/R25) / B + (1/(25.0 + 273.15))) - 273.15;
For the complete file, see the Files section at the end.
NTCs vs PTCs
There are two types of thermistors: Negative Temperature Coefficient and Positive Temperature Coefficient. In NTCs, the resistance decreases when the temperature goes up, in PTCs the resistance increases with rising temperates.
With what materials are NTCs and PTCs actually made? And what is a Wax Motor?
NTCs vs PTCs vs RTDs
RTDs or Resistance Temperature Detectors are made of a pure element (mostly platinum), whereas thermistors are made of composite materials. RTDs have a higher temperature range, up to 600ยบC, the R/T relation is positive and linear. RTDs are also more expensive than thermistors.
Digital Temperature Sensors vs. NTC Thermistors
A related document of the data sheet compares Digital Temperature Sensors with NTC Thermistors
Sketching the Board
Neil's example NTC board uses an ATTiny45 in the bridge configuration for added accuracy.
Bridge vs Direct
I want to compare the values of a bridge and a non-bridge (path?) configuration:
More about the Wheatstone Bridge
The Wheatstone Bridgeโ๏ธ is a circuit to measure an unknown electrical resistance. Two legs of a bridge circuit are balanced, one leg is made up of two known resistors, the second leg is made from one known resistor and from one unknown resistor, in this case the unknown resistor is the thermistor.
The bridge circuit can also be seen as two parallel voltage dividers, where the leg with the known resistor provides a zero point, and the other leg is measured to this zero point.
This enhances the output, compared to a simple voltage divider. I want to compare these two approaches, therefore making both the bridge circuit and the voltage divider approach.
Invented in 1833 by Samuel Hunter Christie, popularised by Charles Wheatstone in 1843, interestingly one of the first uses was soil analysis.
The ATTiny 3216 Pinout
For the first ๊ฉ I will use my already made 3216 board - which I made with pin-out connectors. Pin 2 (PA4) is taken by a button, Pins 3,4,5 are free.
The Breakout Board Sketch
Here are the corrected traces:
I made another, correct version, with an additional I2C interface for the Output Week.
Working with Ground Planes
Instead of creating routing wires, ground planes are large areas that serve the same purpose. By creating larger areas for the most used connections, like GND and VCC, the routing wires from these ground planes can be shorter - and more easy to layout.
- Name your nets in SCH ("GND")
- Draw a polygon in BRD over the part you want to cover.
- Name the polgyon also "GND"
- Click Ratsnet Button to render/show the filled-in ground. (This might be logical to some, but not to me.)
- Adjust spacing
- Too much spacing can sever the GND connection
After I struggled through it, I discovered that Jun did a very nice tutorial on Ground Planes. ๐ฅธ
Milling Labels
Proper labeling of your boards becomes more and more important the more boards you make. The easy way is to add the graphic and text in Photoshop after the design work in Eagle.
Setting the Grid
The connectors for the GB cartridge are space 1.5mm apart, the connectors itself are 1mmm, the spacing between is 5mm. I therefore set the grid size to 1.5mm and the alt-spacing (the snapping size when the alt key is pressed to 0.25mm).
Milling the Board
The usual mods and Roland SRM-20 dance routine.
I used non-standard T1.0 FR-1 PCB, setting the cut depth accordingly (in inch).
cut depth: 0.015 // 0.381mm
max depth: 0.045 // 1.143mm
I also milled the board in GameBoy Cartridge form.
Stuffing the Breakout Board
Connecting the Breakout Board
Re-using my 3216 Board, I connected the breakout board. One thing I did not consider when making the break-out pins in Week 6 was to provide both GND and VCC on both sides of the break-out pins. That's why that black jumper had to come to the rescue.
Reading the Temperature
Reading the Resistance of the Thermistor, converting in into Temperature and printing a timestamp and temp to Serial.
Sending Data
ATTiny 3216 Code
int Sensor1_PIN = 2;
float R25 = 10000; // 10K O
float B = 3750; // B25/85 3750K
float V, R, T;
unsigned long timeStamp;
void setup() {
Serial.begin(9600);
}
void loop() {
timeStamp = millis();
V = analogRead(Sensor1_PIN);
V = 1024.0 - V; // invert V, wrong placement of the thermistor
R = R25 * (1024.0 / V - 1.0);
T = 1.0 / ( log(R/R25) / B + (1/(25.0 + 273.15))) - 273.15;
Serial.print(", ");
Serial.print(timeStamp);
Serial.print(": ");
Serial.print(T);
}
1024 โ 210 โ 10bit digital resolution
Subtracting the V from 1024 gives the same output as different Thermistor placement.
V = 1024.0 - V; // invert V, wrong placement of the thermistor
Receiving the Data with Serial Monitor
End of the Saturday, receiving data.
Physical Property and Measured Results
The physical properties of the thermistors vary their resistance depending on the temperate, resulting in temperature-depended voltage levels. These levels are read as an analog input, and converted to digital values.
Hero Video
Receiving the Data with WebSerial
Serial Data can be received by Arduino Serial Monitor any other program, Neil made a custom Python and Tkinter script to display data from the Serial Input.
Since Chrome 89 (Release date March 2, 2021) - i.e. last week - the Web Serial API launched to the wider public, enabling Serial communication directly from the (Chrome Browser).
Let's see if we can make it work here...
Checking if your browser supports Web Serial... Your browser
Web Serial.WebSerial Live Demo
(Yes, that's a button below. Click it.)
If your browser supports Web Serial (Chrome 89+), you are using a local server or https on a public server, a Serial Port Select Window will open.
WebSerial Demo Screenshot
It should look something like this:
More about WebSerial
Following the tutorial from Web Dev, I got it to work!
...
const port = await navigator.serial.requestPort();
const { usbProductId, usbVendorId } = port.getInfo();
console.log(port, usbProductId, usbVendorId);
// Wait for the serial port to open.
await port.open({ baudRate: 9600 });
// Open Text Decoder
const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable.getReader();
// Listen to data coming from the serial device.
while (true) {
const { value, done } = await reader.read();
if (done) {
// Allow the serial port to be closed later.
reader.releaseLock();
break;
}
addToData(value) // collection the data
}
...
It is very meta, that I am using this site in the FabCloud Repo to display the data.
Full example, and also in the view-source of this document. Very meta. Very, very meta.
Hmm.. a bit garbled.
Ok... that's better.
But I think we can do even better than that.
Visualizing Temperature Data as Time Series with D3
Visualising Temperature Data as Time Series with Zoom and Focus. This is a live visualisaton, click and drag to zoom. Made with d3.js
Open a New Window with this Visualisation.
D3 Visualisation Code
The code for the D3 visualisation is too long to be comfortably included this document. Please see the separate file, or do a view-source of this page.
Here is a commented overview of the code:
var ratio = 500 / 960
var svgWidth = 960
var svgHeight = 500
var svg = d3.select("svg")
.attr('width', svgWidth)
.attr('height', svgHeight)
var margin = {top: 20,right: 20, bottom: svgHeight*0.30,left: 40}
var margin2 = {top: svgHeight*0.75,right: 20,bottom: 30,left: 40}
var width = svgWidth - margin.left - margin.right
var height = svgHeight - margin.top - margin.bottom
var height2 = svgHeight - margin2.top - margin2.bottom
var x = d3.scaleTime().range([0,width]),
x2 = d3.scaleTime().range([0,width]),
y = d3.scaleLinear().range([height,0]),
y2 = d3.scaleLinear().range([height2,0])
var xAxis = d3.axisBottom(x),
xAxis2 = d3.axisBottom(x2),
yAxis = d3.axisLeft(y)
var brush = d3.brushX()
.extent([[0,0],[width,height2]])
.on("brush end",brushed)
var zoom = d3.zoom()
.scaleExtent([1,Infinity])
.translateExtent([[0,0],[width,height]])
.extent([[0,0],[width,height]])
.on("zoom",zoomed)
var line = d3.line()
.x(function(d) { return x(d.timestamp) })
.y(function(d) { return y(d.temp) })
// For more info, view the source.
For more info, view the source.
Live D3 Visualisation
Raw data, no smoothing or averaging.
D3 Visualisation Demo Screenshots
In case the above D3 script is for some reason not working in your browser, here are some screenshots how it should look like.
D3 Visualisation Demo Video
Exporting Browser Data from a JS Array
//Create a New Window
var w = window.open()
// Add a basic HTML header
w.document.writeln("<html><body><pre>")
// Add a CSV Header
w.document.writeln("timestamp, temp")
// array 'data', sub-array with 2 values.
data.forEach(d => { w.document.writeln(d[0] + ", " + d[1]) })
// Clears the output, if you need to start anew.
w.document.body.innerHTML = "";
Example Output Data
timestamp, temp
5135797, 19.88
5136797, 19.88
5137798, 19.88
5138799, 19.8
5139800, 19.88
5140800, 19.88
5142802, 19.8
5143803, 19.88
5144804, 19.88
...
Full example file in the download section.
Learning Outcome
I got very deep into Thermistors, I made a voltage divider and bridge circuit to have different ways of measuring the temperature.
Receiving the Serial Data with Web Serial a fun challenge, I really wanted to make it work, and got there in the end. I also spend some non-planned time to visualize the temperature as time series data, - and embed it in this page.
Despite finishing this week's assignment on Saturday - our first lab day - I went back to FabLab Kamakura on Sunday to work in a less pressure- and more curiosity driven context. Learning about
- Ground Planes
- Web Serial and doing
- D3 InfoVis was a direct outcome of that.
I failed to get the temperature reading from the internal temp sensor of the 3216, but as this is a software challenge, I can work on it outside lab opening times.
Next Steps
My next steps will be making more boards comparing the different analog and digital temperature sensors, to help me decide which ones to use in my Final Project.
It will probably be not so much about the absolute accuracy of the temp sensor (0.1ยบC is fine), more about the ease of network integration.
Appendix: Akihabara FabMap!
Akihabara is the center of Electronics and Geek culture in Tokyo, I made a pilgrimage last week, some picture and impressions.
Akihabara is very dense and very deep, and although I discovered many fab-related places, I am sure there are many places I don't know.
Following the regional meeting, and the shared interested of making an open, shared map with Fab-related places, I set up a Google FabMap - and also started a Mattermost channel. #FabMap Akihabara.
Code
The code for this project (and all the other weeks and assignments) is also openly available from GitLab.
Files
The Serial and Temp Vis Page show the respective example is a more isolated fashion. (In case you want to do an Inspect Element).