Input Devices

QUOTE OF THE DAY

The way to succeed is to double your failure rate - Thomas J. Watson

Goals

I want to use a simple commercial thermistor to measure temperature. Ideally, the simplest form that includes no processing/abstraction by the manufacturer.

FabAcademy goals

Personal goals for this week

I want to use a raw input device to achieve various things:

  1. Where machines touch the real world:
    1. WHAT: This week, I’d like to use an input device that is a raw as possible (a device that has no processor built in). I hope this will help me understand how they work at the lowest level, without having to rely on any pre-processing done by a manufacturer/API/abstraction.
    2. WHY: As a software developer, we work in a “real world” that is always abstracted away from us. The machines we program (computers, mobile apps, web servers, … ) are always operating in a virtual world that is hidden behind dozens of layers of abstraction. That is, we don’t have to worry about debouncing signals when someone presses the ENTER key, we don’t even have to listen to keyboard events. This physical reality has been hidden away from us (for good reason) but this week I’d like to get a bit closer to it. I have reasonable expectations. I think that I will enjoy it, like what I did a few weeks ago, exploring the famous Interrupts. Wish me luck!
  2. Circuit Design: I want to understand how to design circuits to effectively extract the information I need, from the device being used.
  3. Circuit Optimization: I want to figure out how to design circuits to optimise the capabilities that my components already have:
    • Specifically: if the DAC has a 10-bit resolution, I want to understand how to design the circuit so that I have the best resolution for temperatures in an arbitrary range.
      • Specifically, If I know that the resistance of my probe never goes below/above a specific number, I want to design a circuit that will be able to use the full range of values that the sensors can give me. No more ( duh!), no less (the important part!)
      • And use this to understand, how to pick ranges, what happens if it were to measure a value outside that range, and any safety considerations I should keep in mind in the future.

The Sensor - IKEA Temperature Sensor - FANTAST

This is the sensor that I wanted to use this week.

It’s a thermal probe that you can find as part of this IKEA kitchen timer/temperature reader.

Yes, after so many weeks learning about the importance of reading the datasheet of the components we use, I decided to try to jump to the deep end and figure out what happens on ✨ the other side of the PDF ✨.

The only published material for this device is the commercial operator’s manual , written in 30 languages, but with no information about the thermal probe, its resistance, or any rated max current.

This week’s plan

This was my plan for this week:

  1. Figure out what the probe is, how it operates, and which of its properties change as the temperature changes.
  2. Figure out the relation between temperature and how to use a SAM-D11C to read this sensor.
  3. Figure out what the board/circuit should look like, so that the entire range of temperatures can be measured accurately.
    1. and so that the 10-bit ADC precision is fully utilized.
  4. Figure out how to visualize this data (find exciting alternatives to the ‘Serial Monitor’ in Arduino)
  5. Figure out how to properly calibrate and adjust the math to get precise readings (ideally within +/- 5°C).

About the device

As I have already revealed before, the thermal probe appears to be a simple thermistor with a Negative Temperature Coefficient.

The Datasheet

High Temperature is Low Resistance

This was an easy way to set the probe to around 40+ degrees, from the comfort of my table. The only cost: 2 minutes of my life, and 3 months off of the lifespan of my CPU! Win/Win!

Low Temperature is High Resistance

This was tested by putting the probe in the Lab’s freezer for 20 minutes.

The datasheet transcript

Space Temperature Resistance
Laptop heat exhaust (100% CPU) 40 °C 50K Ohm
Ambient Temperature 24 °C 150K Ohm
Cold Water 7 °C 300K Ohm
FabLab Fridge 5 °C 350K Ohm
Freezer -15 °C 800K Ohm

If we plot these values into a cartesian plane, we can see that the trend is clearly exponential and has a negative coefficient.

Measuring temperature by measuring resistance

The next question to answer was: “How can I measure these changes in resistance from my arduino-like board”?

The answer to this question has two parts:

  1. Our board (SAM-D11C) has an ADC that can be used to measure analog voltage on a given pin (compared to ground, this is what’s known as Single Ended).
    1. Yes, the SAM-D11C it also supports Differential measurements (D11 datasheet Section 31.1, page 770), but we are going to keep it simple. Single Ended mode works perfectly for our use case.
    2. Just… listen… just pay attention, the last thing I need right now is picky questions and unnecessary distractions from tiquismiquis lecturers who want to brag about their SAM-D11C Knowledge!
  2. In order to measure resistance, we have to design a circuit that will result in a specific range of voltages (0 to 3.3V) in the pin that we will use for measuring.

So this section is about doing item #2 from this list. How do we design a circuit that will result in a voltage between 0 and 3.3V on the given pin.

The way we do this is with math!

We can use a voltage divider, which allows us convert a large voltage to a smaller one.

This basic equation allow us to calculate the output voltage (Vout) given a known Vin, and the resistance of both our resistors (R1 and R2)

V_{out} = V_{in} * \frac {R2} {R_1 + R_2}

We will need to apply a bit of math, since we don’t know R_2, but we do know V_{out}.

If we get our notepad out, this is the equation we need to solve.

3.3 = 5 * \frac {R_2} {50000 + R_2}

3.3 * (50000 + R_2) = 5 * R2

165000 + 3.3 * R_2 = 5 * R_2

165000 = (5-3.3) * R_2

165000 = 1.7*R_2

\frac {165000} {1.7} = R_2 = 97058 Ω

The resistance of R2 (the one after our thermistor) will have to be of 97kΩ if we want to guarantee protection of our chip, when our thermistor is at its lowest resistance (the hottest temperature).

This also solves one of the questions we wanted to answer originally: What will happen if the temperature we are measuring exceeds that maximum we calculated?

  1. The resistance of our thermistor will drop further
  2. It will consume less V than we anticipated.
  3. The measured Voltage on our measuring pin will exceed 3.3V, and we risk burning our SAMD chip. 😱

As bonus resources:

Measuring resistance by measuring voltage

Now that we know what components we will need in our circuit to protect our sensitive components, as well as to guarantee that the readings are accurate and that they provide values that our ADC can measure correctly, it’s time to jump to the next step.

How do we measure the resistance of our thermistor from our microcontroller, if it can only measure voltage?

Well, we know that the ADC of the SAM-D11C has a resolution of 10 bits. This means that it will give us a reading and convert it to a number between 0-1023 (1024 different values is (2^{10\text{ bits}})).

Designing the board

Creating a custom symbol and footprint

This week I had to create a custom KiCad Symbol and Footprint for the new component that I wanted to use.

Check out the cheatsheet on how to create custom kicad symbols and footprints

Lessons learned when designing symbols/cheatsheets.

  1. When you have a simple design, and you feel brave enough to do all the traces manually instead of using FreeRouting ( like in previous weeks), don’t forget to add all traces!
  2. When you have a new component, and you are designing its symbol, its pads/ports and its footprints, don’t forget to validate your assumptions about the components that you do not know!
    1. It might be that your initial idea needs reconsidering.
    2. If the component is a pluggable thing, remember to plug it and replicate the measurements you will actually do when it is soldered.

Progress soldering

This week I was really happy with the process of actually soldering. I feel like I improved a lot, and it has been a lot more satisfying than the first few weeks.

I wanted to celebrate this because persistence truly is a blessing.

Programming the board

One of the issues I had while trying to program the board was this:

 edu@deneb  ~  cd Downloads         
 edu@deneb  ~/Downloads  edbg -ebpv -t samd11 -f sam_ba_SAMD11C14A.bin
Debugger: Alex Taradov Generic CMSIS-DAP Adapter 170CD3AA v0.1 (S)
Clock frequency: 16.0 MHz
Target: SAM D11C14A (Rev B)
Erasing... done.
Programming...Error: invalid response during transfer (count = 0/3, status = 7)
  edu@deneb  ~/Downloads 

Root cause: I forgot to add a trace for VDD 🤦

Fixed by adding a jumper cable to the right place.

Once this was solved, the board worked smoothly and could be programmed without issue.

Creating a simple program that reports voltage reads

The next step was to flash it with a small that could read the voltage on Pin 5, and report it to us via Serial.

The entire code for the program was this:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(analogRead(5));
  delay(100);
}

Unfortunately the reading when we inserted the probe were far from ideal:

We were getting the MAX reading, and yet the probe was far from any extreme temperature. It was sitting on the table at normal room temp.

Something was wrong.

The answer turned out to be this:

Can you see it? The two pads that near the entrance of the jack are actually shorting out because they both touch the same sleeve when you insert the connector all the way in.

For some reason, when I was designing the jack’s symbol and footprints I made an incorrect assumption: that the 2 pads at the top were the “data reading” pads, and that the pad at the opposite side must be a grounding pad (or similar). This is why I connected that bottom one to ground and those two as the “sensing” pads.

This is what happens when you don’t test your components that do not come with datasheets!

Anyway, a couple knife cuts and a short jumper cable later, my board was rocking some stylish 1990s hoop earrings.

After this, the readings were spot on:

These were the readings once the data started coming in.

And these are the readings once we subjected the probe to an increasing temperature.

Unexpected Problem: Using doubles in Arduino/FabSam results in enormous programs

Changing the double type to int somehow solves the problem… but it makes absolutely no sense!

It is, at least, very counter-intuitive, unless the double type is not native to the board and the FabSAM library has to somehow create a wrapper/custom type for it and all that code uses up several KB of memory.

In the end, I decided to go for floats and ignore any problems with low precision.

Using Processing to visualize the data from my board

The next thing I wanted to do was to visualize this data a bit better.

I had heard of Processing, but I had no idea what it was, or why would anyone use it.

A quick glance a some tutorials seemed to indicate that it supported reading data from Serial port, which was excellent, as it would allow me to use this to display the board’s reading in the computer screen.

Installing processing for Linux

Math time - Properly calibrating the sensor to display accurate temperatures

The way I calibrated the software to perform the temperature calculation correctly was the following:

Among the most important calculations, we can find:

void draw(){
  drawThermometer();
  if(arduinoSerial.available() > 0){
    String volt = arduinoSerial.readStringUntil(lf);
    float actualVolt = (3.3 / 1024) * float(volt);
float calculateResistanceOfProbe(float realVolt){
  return (5 - realVolt) * 100000 / realVolt;
}
float convertResistanceToTemperature(float resistance){
  return ((-19.89212 * log(resistance)) + 257.7);
}
float getYforNormalizedVoltage(float temp){
  float position = map(temp, 0, 90, 600, 150);
  return position;
}

Other tips used this week

So, if you want to keep the voltage (on your thermistor) as close to X as possible (theoretical Voltage before connecting our measuring microchip), you should only use a device where the internal resistance is a lot greater than R1 and R2. If it’s significantly greater, then the voltage won’t change as much.

So if you want to design a voltage divider circuit and you dont want your voltage to change more than 1%, you should design a circuit with an internal resistance (of your measuring equipment) x100 higher than the R2 resistance.

$ for i in $(seq $(getconf _NPROCESSORS_ONLN)); do yes > /dev/null & done

Useful References

Group Project

Assets