Week 11 – Input Devices – Thermistor(s)

Weekly Summary

Reading Temperature sounds straightforward, but I found a way to make it complex - and quite exciting.


Group Assignment

Group Assignment Page

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.

Probing an Analog Signal
Probing an Digital Signal
10s, 1.4MB

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.

My plan is the following:

Extra:

Work Plan

Identifying the Thermistor

The thermistor available in the FabLab is a NTC NHQ103B375T10, it's key specs are:

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.

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

More temperature sensors to explore in the the coming weeks.

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:

Sketching the Bridges

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

From ATTiny 3216 data sheet

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

Clear Visual Representation of the Bridge and Voltage Divider

Here are the corrected traces:

Corrected Wheatstone Bridge Board

I made another, correct version, with an additional I2C interface for the Output Week.

Corrected Wheatstone Bridge Board and I2C I2C interface with OLED

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.

  1. Name your nets in SCH ("GND")
  2. Draw a polygon in BRD over the part you want to cover.
  3. Name the polgyon also "GND"
  4. Click Ratsnet Button to render/show the filled-in ground. (This might be logical to some, but not to me.)
  5. Adjust spacing
  6. 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. ๐Ÿฅธ

Drawing a Ground Plane

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).

Setting the grid.

Milling the Board

The usual mods and Roland SRM-20 dance routine.

Tsuchiya-san & Roland SRM-20

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
Milling Machine and Reflections
Milled temperature board with GameBoy Cartridge form factor.

I also milled the board in GameBoy Cartridge form.

Stuffing the Breakout Board

Stuffing the Breakout Board
Stuffed

Connecting 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

10s, 2.5MB, No Audio

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:

Web Serial with Programmer at ATTiny 3216 Connections.

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.

Screenshots of the D3 Temperature Visualisation

D3 Visualisation Demo Video

Demo Screen Move of D3 Temperature Visualisation, 30s, 1.8MB

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

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.

Radio Department Store, Nishikawa Screws, Super Potato
Tokyo Radio Department Store Inside, Akitsuki Denshi

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.

https://gitlab.fabcloud.org/academany/fabacademy/2021/labs/kamakura/students/georg-tremmel/-/tree/master/files/w11

FabAcademy Documentation and Code at 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).