+1443 776-2705 panelessays@gmail.com

 Directions Begin your work by accessing the Project Thermostat Lab Guide PDF document. While this document was written for a Windows interface, the tools can be used on Mac or Linux as well. To accomplish the work outlined in the guide, you will need the following:  TI CC3220x LAUNCHXL TI Code Composer Studio (installed) USB connection between the PC and board Specifically, you must address the following rubric criteria:  Develop code for all of the specified functionality. Remember, the goals of this project include reading room temperature, indicating the result via LED output, increasing or decreasing the set temperature, and simulating the data being sent to a server. Create code that initializes the timer and uses it to drive specified actions. This involves two steps, both the initializing of the timer and then its use in running an action. Create code that uses interrupt to detect button presses. This involves two steps, both the detection of the button presses and then using the result to run an action. Create code to initialize the I2C peripheral and use it to read the temperature sensor. This code must both initialize the I2C peripheral and then read the temperature sensor correctly. Create code to initialize the GPIO peripheral and use it. Remember that the GPIO is involved in indicating the output of the temperature via LED and setting the temperature with two different buttons (one to increase and one to decrease temperature). Create code to initialize the UART peripheral and output specified data. The UART should be used to simulate data being sent to the server. Be careful to ensure that the UART is initialized to the correct baud rate and serial configuration. Implement (in code) the task scheduler functionality. This should match the specifications described by the Project Thermostat Lab Guide 

/*

* Copyright (c) 2015-2020, Texas Instruments Incorporated

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions

* are met:

*

* * Redistributions of source code must retain the above copyright

* notice, this list of conditions and the following disclaimer.

*

* * Redistributions in binary form must reproduce the above copyright

* notice, this list of conditions and the following disclaimer in the

* documentation and/or other materials provided with the distribution.

*

* * Neither the name of Texas Instruments Incorporated nor the names of

* its contributors may be used to endorse or promote products derived

* from this software without specific prior written permission.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,

* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR

* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;

* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR

* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/*

* ======== gpiointerrupt.c ========

*/

#include <stdint.h>

#include <stddef.h>

/* For usleep() */

#include <unistd.h>

/* Driver Header files */

#include <ti/drivers/GPIO.h>

/* Driver configuration */

#include "ti_drivers_config.h"

#include <ti/drivers/Timer.h>

#include <ti/drivers/I2C.h>

#include <ti/drivers/UART.h>

#include <ti/drivers/Timer.h>

// I2C Global Variables

static const struct {

uint8_t address;

uint8_t resultReg;

char *id;

} sensors[3] = {

{ 0x48, 0x0000, "11X" },

{ 0x49, 0x0000, "116" },

{ 0x41, 0x0001, "006" }

};

uint8_t txBuffer[1];

uint8_t rxBuffer[2];

I2C_Transaction i2cTransaction;

// Driver Handles – Global variables

I2C_Handle i2c;

// Make sure you call initUART() before calling this function.

void initI2C(void)

{

int8_t i, found;

I2C_Params i2cParams;

DISPLAY(snprintf(output, 64, "Initializing I2C Driver – "));

// Init the driver

I2C_init();

// Configure the driver

I2C_Params_init(&i2cParams);

i2cParams.bitRate = I2C_400kHz;

// Open the driver

i2c = I2C_open(CONFIG_I2C_0, &i2cParams);

if (i2c == NULL)

{

DISPLAY(snprintf(output, 64, "Failednr"));

while (1);

}

DISPLAY(snprintf(output, 32, "Passednr"));

// Boards were shipped with different sensors.

// Welcome to the world of embedded systems.

// Try to determine which sensor we have.

// Scan through the possible sensor addresses

/* Common I2C transaction setup */

i2cTransaction.writeBuf = txBuffer;

i2cTransaction.writeCount = 1;

i2cTransaction.readBuf = rxBuffer;

i2cTransaction.readCount = 0;

found = false;

for (i=0; i<3; ++i)

{

i2cTransaction.slaveAddress = sensors[i].address;

txBuffer[0] = sensors[i].resultReg;

DISPLAY(snprintf(output, 64, "Is this %s? ", sensors[i].id));

if (I2C_transfer(i2c, &i2cTransaction))

{

DISPLAY(snprintf(output, 64, "Foundnr"));

found = true;

break;

}

DISPLAY(snprintf(output, 64, "Nonr"));

}

if(found)

{

DISPLAY(snprintf(output, 64, "Detected TMP%s I2C address: %xnr", sensors[i].id, i2cTransaction.slaveAddress));

}

else

{

DISPLAY(snprintf(output, 64, "Temperature sensor not found, contact professornr"));

}

}

int16_t readTemp(void)

{

Int j;

int16_t temperature = 0;

i2cTransaction.readCount = 2;

if (I2C_transfer(i2c, &i2cTransaction))

{

/*

* Extract degrees C from the received data;

* see TMP sensor datasheet

*/

temperature = (rxBuffer[0] << 8) | (rxBuffer[1]);

temperature *= 0.0078125;

/*

* If the MSB is set '1', then we have a 2's complement

* negative value which needs to be sign extended

*/

if (rxBuffer[0] & 0x80)

{

temperature |= 0xF000;

}

}

else

{

DISPLAY(snprintf(output, 64, "Error reading temperature sensor (%d)nr",i2cTransaction.status));

DISPLAY(snprintf(output, 64, "Please power cycle your board by unplugging USB and plugging back in. nr"));

}

return temperature;

}

#define DISPLAY(x) UART_write(uart, &output, x);

// UART Global Variables

Char output[64];

Int bytesToSend;

// Driver Handles – Global variables

UART_Handle uart;

void initUART(void)

{

UART_Params uartParams;

// Init the driver

UART_init();

// Configure the driver

UART_Params_init(&uartParams);

uartParams.writeDataMode = UART_DATA_BINARY;

uartParams.readDataMode = UART_DATA_BINARY;

uartParams.readReturnMode = UART_RETURN_FULL;

uartParams.baudRate = 115200;

// Open the driver

uart = UART_open(CONFIG_UART_0, &uartParams);

if (uart == NULL) {

/* UART_open() failed */

while (1);

}

}

// Driver Handles – Global variables

Timer_Handle timer0;

volatile unsigned char TimerFlag = 0;

void timerCallback(Timer_Handle myHandle, int_fast16_t status)

{

TimerFlag = 1;

}

void initTimer(void)

{

Timer_Params params;

// Init the driver

Timer_init();

// Configure the driver

Timer_Params_init(&params);

params.period = 1000000;

params.periodUnits = Timer_PERIOD_US;

params.timerMode = Timer_CONTINUOUS_CALLBACK;

params.timerCallback = timerCallback;

// Open the driver

timer0 = Timer_open(CONFIG_TIMER_0, &params);

if (timer0 == NULL) {

/* Failed to initialized timer */

while (1) {}

}

if (Timer_start(timer0) == Timer_STATUS_ERROR) {

/* Failed to start timer */

while (1) {}

}

}

/*

* ======== gpioButtonFxn0 ========

* Callback function for the GPIO interrupt on CONFIG_GPIO_BUTTON_0.

*

* Note: GPIO interrupts are cleared prior to invoking callbacks.

*/

void gpioButtonFxn0(uint_least8_t index)

{

/* Toggle an LED */

GPIO_toggle(CONFIG_GPIO_LED_0);

}

/*

* ======== gpioButtonFxn1 ========

* Callback function for the GPIO interrupt on CONFIG_GPIO_BUTTON_1.

* This may not be used for all boards.

*

* Note: GPIO interrupts are cleared prior to invoking callbacks.

*/

void gpioButtonFxn1(uint_least8_t index)

{

/* Toggle an LED */

}

// the setup routine runs once when you press reset:

void setup() {

// initialize the digital pin as an output.

GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD);

}

/*

* ======== mainThread ========

*/

void *mainThread(void *arg0)

{

/* Call driver init functions */

GPIO_init();

/* Configure the LED and button pins */

GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

GPIO_setConfig(CONFIG_GPIO_BUTTON_0, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);

/* Turn on LED */

GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

/* Install Button callback */

GPIO_setCallback(CONFIG_GPIO_BUTTON_0, gpioButtonFxn0);

/* Enable interrupts */

GPIO_enableInt(CONFIG_GPIO_BUTTON_0);

/*

* If more than one input pin is available for your device, interrupts

* will be enabled on CONFIG_GPIO_BUTTON1.

*/

if (CONFIG_GPIO_BUTTON_0 != CONFIG_GPIO_BUTTON_1) {

/* Configure BUTTON1 pin */

GPIO_setConfig(CONFIG_GPIO_BUTTON_1, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);

/* Install Button callback */

GPIO_setCallback(CONFIG_GPIO_BUTTON_1, gpioButtonFxn1);

GPIO_enableInt(CONFIG_GPIO_BUTTON_1);

}

return (NULL);

}

,

CS 350 Project Thermostat Lab Guide It is important to note the distinct differences in the Cyber-Physical actions of a thermostat. When you select a button to increase or decrease the temperature in the room, what happens is the thermostat establishes a target temperature that is referred to as its 'set-point'. When the thermostat compares the temperature read from the sensor to the established set-point a decision is made. If the temperature is below the set-point, it turns the heater on. However, if the temperature is above the set-point, it turns the heater off. 1. Open TI Code Composer Studio (CCS). If you have not installed CCS, please install CCS by following

installation guidance in Module One of your course. After CCS is installed you can open it by clicking Code Composer Studio xxxx, which can be found in the Texas Instruments folder. The CCS installer also added a Code Composer Studio icon on your desktop. It looks like a red die. You can click on that icon to open CCS as well.

2. Select a workspace, then click Launch. It is very important that you take note of your workspace

location. You will need the information later in order to turn in your project.

3. Open the Getting Started Window in CCS. CCS takes about 30 seconds to fully open (it’s written in Java). You can review the loading process by looking at the lower right corner of the screen. You will see green progress bars popping up. After about 30 seconds, CCS should be fully loaded and you will not see any green progress bars.

4. Open the Resource Explorer by clicking on the Resource Explorer box (with the compass). In the Resource Explorer, find Software in the left pane. Click on the arrow to expand Software. Then, find the SimpleLink CC32xx SDK and expand it. Next, similarly locate and expand Examples, Development Tools, CC3220S Launchpad, and TI Drivers.

5. Verify you have the SDK installed. You should see a check mark by the SimpleLink CC32xx SDK.

6. Import the gpiointerrupt project. You should already have imported the gpiointerrupt project during

your work in a previous milestone, which would allow you to review the project from the Project Explorer window. If you still need to import the gpiointerrupt project, complete steps 7 through 9. If you already have the gpiointerrupt project, you may skip to step 10.

7. Begin by expanding the SimpleLink CC32xx SDK, then the Examples folder, Development Tools, CC3220S LaunchPad, and finally TI Drivers. From here, locate the gpiointerrupt folder. Then the No RTOS sub-folder followed by the CSS Compiler. In here you will find the gpiointerrupt item illustrated with a red die icon.

8. Click on the three dots icon next to gpiointerrupt then click Import to CCS IDE. From the Select a

target window that appears, choose CC3220S and click Apply to load the example into the CCS workspace.

9. Review the project. Note that you will only need to change the contents of gpiointerrupt.c for this lab.

10. Next, build the code by selecting Project from the top menu options. Then click Build All.

11. Add the appropriate drivers using system config. TI provides a tool called system config for adding and configuring drivers in your project. To open the tool, double-click on the gpiointerrupt.syscfg file in the project.

12. Your goal is to add the Timer and I2C drivers, but if you already had the gpiointerrupt project

imported, you may also already have the Timer driver imported from your previous milestone work. If that is the case, you will only need to add the I2C driver during the subsequent steps. Note that the I2C driver is connected to the temperature sensor. In the following example screenshot of the TI Drivers list, you can ignore the RTOS and POWER drivers. Both drivers are installed but disabled as part of the driver library default configuration. To add the Timer and I2C drivers click the plus signs next to Timer and I2C.

13. For this project we will need a timer that is 32 bits. The default will likely say 16 bits, and if that is the case, click the drop down next to Timer Type. Then select 32 bits.

14. Configure the I2C driver as shown in the following image. Under Use Hardware, LaunchPad I2C

should be selected. Under SDA Pin, P02/10 (LaunchPad I2C) should be selected.

15. When you return to the TI Drivers list, you will notice you have a resource conflict, indicated by a red X on the screen. Unfortunately, this is a very common occurrence in embedded system design. The I2C peripheral uses the same pins as one of the LED GPIOs. We will need to remove the driver for GPIO LED 1, which is the green LED.

16. Remove the driver by clicking on the trash can icon all the way to the right of the

CONFIG_GPIO_LED_1 item.

17. With the driver for LED 1 now removed, the TI Drivers list should display all green check marks.

18. Add the UART by clicking the plus icon next to UART. Then configure the UART by selecting XDS110 UART under the Use Hardware option.

19. Verify you have the GPIO, I2C, Timer, and UART drivers enabled. Do not make any changes to the

Power and RTOS driver configurations. Then save the configuration and build the project following the same instructions as shown in step 10.

20. Note that errors will appear when building the project. This is because we removed the driver in sysconfig but we did not remove references to the driver in the code. To solve this issue, delete the two lines referencing the LED 1 driver in the gpiointerrupt.c file. Then build the project one more time. Now you will have a clean build!

21. Open a serial console to communicate with the board. The USB connection to the board supports

both the debug command protocol and a virtual com port for serial communications. In order to determine which com port the board is assigned to, open the Windows Device Manager by right- clicking on the Windows start icon in the lower left corner. In the device manager select Ports(COM & LPT).

22. The USB connection to the TI board is called XDS110. For this lab, look for XDS110 Class Application/User UART. In the provided example, the UART interface is COM5. However, it may be a different COM port on your computer. Make note of the COMx port assigned to XDS110 Class Application/User UART for your PC.

23. In CCS, select the View tab to open the Terminal window.

24. From the Terminal window, select the Open a Terminal button which appears with a blue monitor

icon (shown first on the left of the row of icons in the upper right corner).

25. The Launch Terminal window will open. From here, choose Serial Terminal. Then select the COM port from earlier. Remember that while this example uses COM5, yours will likely be different. Every other field will remain as its default. Once complete, click Ok.

26. Integrate the driver code into gpiointerrupt.c. These drivers are installed with the Simplelink SDK.

You can locate these drivers at the following locations:  C:tisimplelink_cc32xx_sdk_4_30_00_06sourcetidrivers

 C:tisimplelink_cc32xx_sdk_4_30_00_06examplesnortosCC3220S_LAUNCHXLdrivers

 C:tisimplelink_cc32xx_sdk_4_30_00_06examplesrtosCC3220S_LAUNCHXLdrivers 27. For the I2C driver, copy the following code into CCS. You will need to call initUART() before calling

initI2C(). Note that initI2C() initializes the I2C peripheral and readTemp() uses the I2C peripheral to read the temperature sensor.

#include <ti/drivers/I2C.h>

// I2C Global Variables

static const struct {

uint8_t address;

uint8_t resultReg;

char *id;

} sensors[3] = {

{ 0x48, 0x0000, "11X" },

{ 0x49, 0x0000, "116" },

{ 0x41, 0x0001, "006" }

};

uint8_t txBuffer[1];

uint8_t rxBuffer[2];

I2C_Transaction i2cTransaction;

// Driver Handles – Global variables

I2C_Handle i2c;

// Make sure you call initUART() before calling this function.

void initI2C(void)

{

int8_t i, found;

I2C_Params i2cParams;

DISPLAY(snprintf(output, 64, "Initializing I2C Driver – "))

// Init the driver

I2C_init();

// Configure the driver

I2C_Params_init(&i2cParams);

i2cParams.bitRate = I2C_400kHz;

// Open the driver

i2c = I2C_open(CONFIG_I2C_0, &i2cParams);

if (i2c == NULL)

{

DISPLAY(snprintf(output, 64, "Failednr"))

while (1);

}

DISPLAY(snprintf(output, 32, "Passednr"))

// Boards were shipped with different sensors.

// Welcome to the world of embedded systems.

// Try to determine which sensor we have.

// Scan through the possible sensor addresses

/* Common I2C transaction setup */

i2cTransaction.writeBuf = txBuffer;

i2cTransaction.writeCount = 1;

i2cTransaction.readBuf = rxBuffer;

i2cTransaction.readCount = 0;

found = false;

for (i=0; i<3; ++i)

{

i2cTransaction.slaveAddress = sensors[i].address;

txBuffer[0] = sensors[i].resultReg;

DISPLAY(snprintf(output, 64, "Is this %s? ", sensors[i].id))

if (I2C_transfer(i2c, &i2cTransaction))

{

DISPLAY(snprintf(output, 64, "Foundnr"))

found = true;

break;

}

DISPLAY(snprintf(output, 64, "Nonr"))

}

if(found)

{

DISPLAY(snprintf(output, 64, "Detected TMP%s I2C address:

%xnr", sensors[i].id, i2cTransaction.slaveAddress))

}

else

{

DISPLAY(snprintf(output, 64, "Temperature sensor not found,

contact professornr"))

}

}

int16_t readTemp(void)

{

Int j;

int16_t temperature = 0;

i2cTransaction.readCount = 2;

if (I2C_transfer(i2c, &i2cTransaction))

{

/*

* Extract degrees C from the received data;

* see TMP sensor datasheet

*/

temperature = (rxBuffer[0] << 8) | (rxBuffer[1]);

temperature *= 0.0078125;

/*

* If the MSB is set '1', then we have a 2's complement

* negative value which needs to be sign extended

*/

if (rxBuffer[0] & 0x80)

{

temperature |= 0xF000;

}

}

else

{

DISPLAY(snprintf(output, 64, "Error reading temperature sensor

(%d)nr",i2cTransaction.status))

DISPLAY(snprintf(output, 64, "Please power cycle your board by

unplugging USB and plugging back in.nr"))

}

return temperature;

}

28. For the UART driver, copy the following code into CCS.

#include <ti/drivers/UART.h>

#define DISPLAY(x) UART_write(uart, &output, x);

// UART Global Variables

Char output[64];

Int bytesToSend;

// Driver Handles – Global variables

UART_Handle uart;

void initUART(void)

{

UART_Params uartParams;

// Init the driver

UART_init();

// Configure the driver

UART_Params_init(&uartParams);

uartParams.writeDataMode = UART_DATA_BINARY;

uartParams.readDataMode = UART_DATA_BINARY;

uartParams.readReturnMode = UART_RETURN_FULL;

uartParams.baudRate = 115200;

// Open the driver

uart = UART_open(CONFIG_UART_0, &uartParams);

if (uart == NULL) {

/* UART_open() failed */

while (1);

}

}

29. For the Timer driver, copy the following code into CCS. This should appear familiar to you because of

your practice with this course’s resources. Note that the driver defaults to calling timerCallback() every 1000000 microseconds (1 second). You will need to modify this to match your work.

#include <ti/drivers/Timer.h>

// Driver Handles – Global variables

Timer_Handle timer0;

volatile unsigned char TimerFlag = 0;

void timerCallback(Timer_Handle myHandle, int_fast16_t status)

{

TimerFlag = 1;

}

void initTimer(void)

{

Timer_Params params;

// Init the driver

Timer_init();

// Configure the driver

Timer_Params_init(&params);

params.period = 1000000;

params.periodUnits = Timer_PERIOD_US;

params.timerMode = Timer_CONTINUOUS_CALLBACK;

params.timerCallback = timerCallback;

// Open the driver

timer0 = Timer_open(CONFIG_TIMER_0, &params);

if (timer0 == NULL) {

/* Failed to initialized timer */

while (1) {}

}

if (Timer_start(timer0) == Timer_STATUS_ERROR) {

/* Failed to start timer */

while (1) {}

}

}

30. Modify the provided gpiointerrupt.c code. Your code needs to check the buttons every 200ms,

check the temperature every 500ms, and update the LED and report to the server every second (via the UART). If you push a button, it increases or decreases the temperature set-point by 1 degree every 200ms. If the temperature is greater than the set-point, the LED should turn off. If the temperature is less than the set-point, the LED should turn on (the LED controls a heater). You can simulate a heating or cooling room by putting your finger on the temperature sensor. The output to the server (via UART) should be formatted as <AA,BB,S,CCCC>. This can be broken down as follows:

 AA = ASCII decimal value of room temperature (00 – 99) degrees Celsius  BB = ASCII decimal value of set-point temperature (00-99) degrees Celsius

 S = ‘0’ if heat is off, ‘1’ if heat is on

 CCCC = decimal count of seconds since board has been reset

 <%02d,%02d,%d,%04d> = temperature, set-point, heat, seconds 31. To accomplish this work, you will need to use a task scheduler, as described in your course

resources. Note that some additional content from your course will be useful in helping you complete this project.

 Milestone Two covered how to turn an LED on or off.

 Milestone Three covered how to change the period for the timer interrupt.

 Milestone Three also showed you how to use the button interrupt callbacks.  zyBooks activities covered how to create a task scheduler.

32. Consider the following code to help you get started.

33. Make sure you pay attention to the button you use for this work. The button next to the USB cable

is the reset button and should not be pressed. Instead select either of the buttons located opposite each other near the middle of the board to use for the set-point. The LEDs are located in the corner diagonally opposite the USB cable.

34. The silver square next to the word TEMP is the temperature sensor. This is positioned in the lower

left corner of the board, when it is oriented so the USB is in the upper left.

35. As you work, remember: the easiest method to execute your code is to use the debug icon (green

bug). Clicking the debug icon will load the code into the board and put the tool into debug mode. Once in debug mode, six additional icons become live.

Debug your code

Execute your code

Exit debug mode

Step into

Step over

Step out

Halt the code 36. Remember that part of your submission will also involve creating a video that demonstrates the

functionality you have constructed. Make sure you push the button during the video so you can show what happens.

37. You will also need to zip your workspace and submit the ZIP file. Your workspace is the directory you

selected when opening CCS. In the provided example, you would zip the workspace_v10 folder and submit the resulting ZIP file.

38. Congratulations! You have now completed this lab guide. Remember to refer to the Project

Guidelines and Rubric in your course to ensure you have all the necessary components for your required submission to Brightspace.