# IoT Design with Cypress PSoC® 6 MCUs and Wi-Fi/Bluetooth using Arm® Mbed™

# Lesson GitHub Project
0 Introduction
1 Developer Resources
6 WiFi & NTP Thread https://github.com/iotexpert/mouser-mbed-06.git
7 The CY8CKIT-062-WiFi-BT https://github.com/iotexpert/mouser-mbed-07.git
8 Amazon AWS MQTT Thread - Part1 https://github.com/iotexpert/mouser-mbed-08.git
9 Amazon AWS MQTT Thread - Part2 https://github.com/iotexpert/mouser-mbed-09.git

You can “mbed import https://github.com/iotexpert/mouser-mbed-09.git“ to make a copy of the project in your workspace.

The final architecture of the thermostat looks like this. # Summary

In Lesson 04 I will add temperature sensing to the system. The new thread called “temperatureThread” acts as the actual guts of the thermostat.  It reads the temperature sensor, keeps track of the setPoint of the system and turns on and off Heat and Cooling.  Notice that it doesn’t know anything about displaying information,  it just uses the functions calls we created for the displayThread.

To implement this I will:

1. Explain Thermistors
2. Import lesson03
6. Update main.cpp
7. Build, Program and Test

# Thermistor

On the wing of the CY8CPROTO-062-4343W there is a thermistor that you can use to measure temperature.   What is a thermistor?  It is simply a resistor that changes resistance in a known way based on temperature.

If you know the resistance you can calculate the temperature using the Steinhart-Hart equation.  Here is the Thermistor Wikipedia article.

When you look at the schematic for the development kit you can see how the circuit is attached to the PSoC.

Basically, a known 10K resistor in series with the thermistor with a measurement point between them.  To calculate the resistance of the thermistor you use Ohms low, V=IR.  Or even better R=V/I.

To use this circuit you need to assign a voltage to the THERM_VDD, use a DigialOut to drive 3.3v to that signal and a DigialOut to drive ground to the THERM_GND.

Then use the ADC to find the voltage for THERM_OUT

To do the calculation, first the Thermistor voltage is THERM_VDD-THERM_OUT.

Then you need to get the current.  To do this you calculate the current through the reference resistor I=V/R or I=(THERM_OUT/10K).  This will be the same current as the Thermistor.

Now you can calculate the thermistor resistance. Here is a picture of the thermistor on the board. Here is the code that implements the thermistor measurement.

```static DigitalOut thermVDD(P10_3,1);
static DigitalOut thermGND(P10_0,0);

{
float refCurrent = refVoltage  / 10000.0; // 10k Reference Resistor
float thermVoltage = 3.3 - refVoltage;    // Assume supply voltage is 3.3v
float thermResistance = thermVoltage / refCurrent;
float logrT = (float32_t)log((float64_t)thermResistance);

/* Calculate temperature from the resistance of thermistor using Steinhart-Hart Equation */
float stEqn = (float32_t)((0.0009032679) + ((0.000248772) * logrT) +
((2.041094E-07) * pow((float64)logrT, (float32)3)));

float temperatureC = (float32_t)(((1.0 / stEqn) - 273.15)  + 0.5);
temperatureF = (temperatureC * 9.0/5.0) + 32;
}
```

# Import Lesson 03

To build the project, start by importing Lesson 03:

https://github.com/iotexpert/mouser-mbed-03.git Give it a new name of “mouser-mbed-04”: As before we want a thread for the temperature system called “temperatureThread.h”.  Create the “dot h”: This file will just declare the thread and interface functions.

```#ifndef TEMPERATURE_H
#define TEMPERATURE_H

void tempSendDeltaSetpointF(float delta);

#endif
``` This thread will have two state variables.  One for temperatureF and one for the setPoint of the thermostat.

This thread will also have a queue just like the displayThread.  This queue will be used to let other parts of the system change the setPoint. One command to make a “delta” change  e.g. “go up 1 degree” and one command to make an absolute change e.g “set to 78 degrees”

```#include "mbed.h"

static float temperatureF;
static float setPoint = 75.0;

typedef enum {
CMD_setPointDelta,
CMD_setPoint,

} command_t;

typedef struct {
command_t cmd;
float    value;   /* AD result of measured voltage */
} msg_t;
```

As before to make things easier for the other parts of the system to send messages to the queue, I create functions to send the two commands.

```void tempSendDeltaSetpointF(float delta)
{
msg_t *message = mpool.alloc();
if(message)
{
message->cmd = CMD_setPointDelta;
message->value = delta;
queue.put(message);
}
}

{
msg_t *message = mpool.alloc();
if(message)
{
message->cmd = CMD_setPoint;
message->value = setPoint;
queue.put(message);
}
}```

Now you need the function to read the temperature and update the state variable temperatureF

```static DigitalOut thermVDD(P10_3,1);
static DigitalOut thermGND(P10_0,0);

{
float refCurrent = refVoltage  / 10000.0; // 10k Reference Resistor
float thermVoltage = 3.3 - refVoltage;    // Assume supply voltage is 3.3v
float thermResistance = thermVoltage / refCurrent;
float logrT = (float32_t)log((float64_t)thermResistance);

/* Calculate temperature from the resistance of thermistor using Steinhart-Hart Equation */
float stEqn = (float32_t)((0.0009032679) + ((0.000248772) * logrT) +
((2.041094E-07) * pow((float64)logrT, (float32)3)));

float temperatureC = (float32_t)(((1.0 / stEqn) - 273.15)  + 0.5);
temperatureF = (temperatureC * 9.0/5.0) + 32;
}
```

The temperatureThread listens for messages to be put into the queue.  It then processes them by either increment/decrement of the setPoint or by setting an absolute setPoint.

Also, the queue wait will timeout every 200ms and when that happens it will read the temperature and update the display.

It will also send the cool, heat or off based on a +- 0.5 degree difference from the setPoint.  In other words:

• temperatureF > setPoint + 0.5 = cool
• temperatureF < setPoint -0.5 = heat
• Otherwise OFF
```void temperatureThread()
{

char buffer;
displaySendUpdateTemp(temperatureF);

while(1)
{
osEvent evt = queue.get(200);
if (evt.status == osEventMessage) {
msg_t *message = (msg_t*)evt.value.p;
switch(message->cmd)
{
case CMD_setPointDelta:
setPoint += message->value;
displaySendSetPoint(setPoint);
break;
case CMD_setPoint:
setPoint = message->value;
break;

}
mpool.free(message);

}
else
{

// Control the HVAC system with +- 0.5 degree of Hystersis
if(temperatureF < setPoint - 0.5)
displaySendUpdateMode(-1.0);
else if (temperatureF > setPoint + 0.5)
displaySendUpdateMode(1.0);
else
displaySendUpdateMode(0.0);

displaySendUpdateTemp(temperatureF);
}
}

}```

The whole file (to make the copy/paste easier):

```#include "mbed.h"
static float temperatureF;
static float setPoint = 75.0;
typedef enum {
CMD_setPointDelta,
CMD_setPoint,
} command_t;
typedef struct {
command_t cmd;
float    value;   /* AD result of measured voltage */
} msg_t;
static Queue<msg_t, 32> queue;
static MemoryPool<msg_t, 16> mpool;
void tempSendDeltaSetpointF(float delta)
{
msg_t *message = mpool.alloc();
if(message)
{
message->cmd = CMD_setPointDelta;
message->value = delta;
queue.put(message);
}
}
{
msg_t *message = mpool.alloc();
if(message)
{
message->cmd = CMD_setPoint;
message->value = setPoint;
queue.put(message);
}
}
{
char buffer;
displaySendUpdateTemp(temperatureF);
while(1)
{
osEvent evt = queue.get(200);
if (evt.status == osEventMessage) {
msg_t *message = (msg_t*)evt.value.p;
switch(message->cmd)
{
case CMD_setPointDelta:
setPoint += message->value;
break;
case CMD_setPoint:
setPoint = message->value;
break;
}
mpool.free(message);
}
else
{
// Control the HVAC system with +- 0.5 degree of Hystersis
if(temperatureF < setPoint - 0.5)
displaySendUpdateMode(-1.0);
else if (temperatureF > setPoint + 0.5)
displaySendUpdateMode(1.0);
else
displaySendUpdateMode(0.0);
displaySendUpdateTemp(temperatureF);
}
}
}
static DigitalOut thermVDD(P10_3,1);
static DigitalOut thermGND(P10_0,0);
{
float refCurrent = refVoltage  / 10000.0; // 10k Reference Resistor
float thermVoltage = 3.3 - refVoltage;    // Assume supply voltage is 3.3v
float thermResistance = thermVoltage / refCurrent;
float logrT = (float32_t)log((float64_t)thermResistance);
/* Calculate temperature from the resistance of thermistor using Steinhart-Hart Equation */
float stEqn = (float32_t)((0.0009032679) + ((0.000248772) * logrT) +
((2.041094E-07) * pow((float64)logrT, (float32)3)));
float temperatureC = (float32_t)(((1.0 / stEqn) - 273.15)  + 0.5);
temperatureF = (temperatureC * 9.0/5.0) + 32;
}
```

Now edit the blinkThread.cpp to remove the test code from Lesson 03:

```#include "mbed.h"
static DigitalOut led1(LED1);
{
while (true)
{
led1 = !led1;
displaySendUpdateTime();
}
}
```

# Update main.cpp

Then update main.cpp to start the new temperatureThread:

```#include "mbed.h"
int main()
{
printf("Started System\n");
}
```

# Build, Program and Test

When you program the development kit you should be able to change the temperature by putting your finger on the thermistor: And your terminal should look something like this: 