Brady Taylor
Published © GPL3+

CHARIoT (Chip Arrangement for Internet of Things)

Our device was a self-powered, wireless sensor node for use in Internet of Things applications.

AdvancedWork in progressOver 12 days654
CHARIoT (Chip Arrangement for Internet of Things)

Things used in this project

Hardware components

Texas Instruments BQ25570
×1
MSP-EXP430FR5994 MSP430 FRAM LaunchPad
Texas Instruments MSP-EXP430FR5994 MSP430 FRAM LaunchPad
×1
Texas Instruments CC2652R
×1

Software apps and online services

Code Composer Studio
Texas Instruments Code Composer Studio

Story

Read more

Schematics

Poster of Project from Senior Design Showcase at Rice University

This is our poster from our final showcase that shows how the device works, its applications, and all that it has accomplished.

Code

Main Code for the Project

C/C++
This is the main code. As this project is ongoing, I cannot post all of the code or the full schematic for the device.
#include <msp430.h> 
#include <stdio.h>
#include <stdlib.h>
#include "pwr_control.h"
#include "comms.h"
#include "sensor.h"
#include "p7_i2c.h"
#include "fram.h"
#include "fuel_gauge.h"

#define SEND_BYTES 4

void initClockTo16MHz() {
    /*
     * Code for this function from TI's I2C standard master example code.
     */

    // Configure one FRAM waitstate as required by the device datasheet for MCLK
    // operation beyond 8MHz _before_ configuring the clock system.
    FRCTL0 = FRCTLPW | NWAITS_1;

    // Clock System Setup
    CSCTL0_H = CSKEY_H;                     // Unlock CS registers
    CSCTL1 = DCOFSEL_0;                     // Set DCO to 1MHz

    // Set SMCLK = MCLK = DCO, ACLK = LFXTCLK (VLOCLK if unavailable)
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;

    // Per Device Errata set divider to 4 before changing frequency to
    // prevent out of spec operation from overshoot transient
    CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4;   // Set all corresponding clk sources to divide by 4 for errata
    CSCTL1 = DCOFSEL_4 | DCORSEL;           // Set DCO to 16MHz

    // Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
    __delay_cycles(60);
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;   // Set all dividers to 1 for 16MHz operation
    CSCTL0_H = 0;                           // Lock CS registers
}

static char num_str[3] = {0};
char *short_to_str(uint16_t data) {
    num_str[0] = (data & 0xFF00) >> 8;
    num_str[1] = data & 0x00FF;
    return num_str;
}

void main(void)
{
    uint8_t *res_data;
    uint16_t res;

    // Disable Watchdog Timer:
    WDTCTL = WDTPW | WDTHOLD;

    // Bump up clock speed:
    initClockTo16MHz();

    // Unlock pins:
    PM5CTL0 &= ~LOCKLPM5;

    // Globally enable interrupts:
    __bis_SR_register(GIE);

    // Call the code to initialize each subsystem, in order:
    p7_i2c_setup();
    pwr_control_setup();
    fuel_gauge_config_update();
    comms_setup();

    // Setup 1hz timer A0:
    TA0CCTL0 = CCIE;                        // TACCR0 interrupt enabled
    TA0CCR0 = 4000;
    TA0CTL = TASSEL__ACLK | ID_3 | MC__UP;        // ACLK, UP mode, 32khz/8 = 4khz

    uint8_t volt_data[6] = {0, 0, 0, 0, 0, 0};
    int first = 1;
    uint8_t *data_loc;

    while(1) {
        // Main while loop:
        __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0 w/ interrupt
        __no_operation();                       // For debugger

        // Do stuff here:
        res = fuel_gauge_read_soc();
        res = fuel_gauge_read_voltage();
        if (res > 10) {
            volt_data[0] = (uint8_t)(res >> 8);
            volt_data[1] = (uint8_t)(res & 0x00FF);

            sensor_start_measurement();
            __delay_cycles(250000);
            res_data = sensor_read_measurement();

            if (first == 0) {                   // load previous sensor data
                data_loc = curr - 4;
                volt_data[2] = *data_loc;
                volt_data[3] = *(data_loc+1);
                volt_data[4] = *(data_loc+2);
                volt_data[5] = *(data_loc+3);
            } else {
                first = 0;
            }

            // Transmit
            comms_sdep_packet(COMMS_SDEP_CMD_TX, 0, 6, &volt_data[0]);

            __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0 w/ interrupt (pause of 1 sec)
            __no_operation();                       // For debugger

            // WRITE NEW SENSOR DATA TO FRAM ALWAYS
            fram_write(res_data, 4);
        }
    }
}

// Timer0_A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
 {
     __bic_SR_register_on_exit(LPM0_bits);
 }

Credits

Brady Taylor

Brady Taylor

1 project • 1 follower
Thanks to Jennifer Hellar, Robby Flechas, Robyn Torregrosa, Rachel Nguyen, Nathaniel Morris, Gene Frantz, Ray Simar, Erik Welsh, and Gary Woods.

Comments