HyperChiicken
Published © MIT

Cloud-Based Ambient Light Data Logger

Log data to an online server (ThingSpeak.com) with a TIVA-C (TMC4123GXL) microcontroller, an ESP8266, and a TSL2591.

IntermediateShowcase (no instructions)5 hours1,608
Cloud-Based Ambient Light Data Logger

Things used in this project

Story

Read more

Schematics

Schematic

A block diagram with pinouts

Code

IOT_TSL2591_DataLogger.c

C/C++
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/fpu.h"
#include "driverlib/debug.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/pwm.h"
#include "driverlib/timer.h"
#include "driverlib/adc.h"
#include "driverlib/rom.h"
#include "driverlib/uart.h"
#include "driverlib/interrupt.h"
#include "driverlib/i2c.h"
#include "utils/uartstdio.h"
#include "DelayTimer.h"
//------------------------------------------------------------------------------
// DEFINE VARIABLES
//------------------------------------------------------------------------------

//
// Define TSL2591 Register Values
//
#define TSL2591_VISIBLE 2 //channel 0 - channel 1
#define TSL2591_INFRARED 1
#define TSL2591_FULLSPECTRUM 0
#define TSL2591_ADDR 0x29
#define TSL2591_READBIT 0x01
#define TSL2591_COMMAND_BIT 0xA0
#define TSL2591_CLEAR_INT 0xE7
#define TSL2591_TEST_INT 0xE4
#define TSL2591_WORD_BIT 0x20
#define TSL2591_BLOCK_BIT 0x10
#define TSL2591_ENABLE_POWEROFF 0x00
#define TSL2591_ENABLE_POWERON 0x01
#define TSL2591_ENABLE_AEN 0x02
#define TSL2591_ENABLE_AIEN 0x10
#define TSL2591_ENABLE_NPIEN 0x80
#define TSL2591_LUX_DF 408.0F
#define TSL2591_LUX_COEFB 1.64F
#define TSL2591_LUX_COEFC 0.59F
#define TSL2591_LUX_COEFD 0.86F

uint8_t
TSL2591_REGISTER_ENABLE = 0x00,
TSL2591_REGISTER_CONTROL = 0x01,
TSL2591_REGISTER_THRESHOLD_AILTL = 0x04,
TSL2591_REGISTER_THRESHOLD_AILTH = 0x05,
TSL2591_REGISTER_THRESHOLD_AIHTL = 0x06,
TSL2591_REGISTER_THRESHOLD_AIHTH = 0x07,
TSL2591_REGISTER_THRESHOLD_NPAILTL = 0x08,
TSL2591_REGISTER_THRESHOLD_NPAILTH = 0x09,
TSL2591_REGISTER_THRESHOLD_NPAIHTL = 0x0A,
TSL2591_REGISTER_THRESHOLD_NPAIHTH = 0x0B,
TSL2591_REGISTER_PERSIST_FILTER = 0x0C,
TSL2591_REGISTER_PACKAGE_PID = 0x11,
TSL2591_REGISTER_DEVICE_ID = 0x12,
TSL2591_REGISTER_DEVICE_STATUS = 0x13,
TSL2591_REGISTER_CHAN0_LOW = 0x14,
TSL2591_REGISTER_CHAN0_HIGH = 0x15,
TSL2591_REGISTER_CHAN1_LOW = 0x16,
TSL2591_REGISTER_CHAN1_HIGH = 0x17,
TSL2591_INTEGRATIONTIME_100MS = 0x00,
TSL2591_INTEGRATIONTIME_200MS = 0x01,
TSL2591_INTEGRATIONTIME_300MS = 0x02,
TSL2591_INTEGRATIONTIME_400MS = 0x03,
TSL2591_INTEGRATIONTIME_500MS = 0x04,
TSL2591_INTEGRATIONTIME_600MS = 0x05,
// bit 7:4:0
TSL2591_PERSIST_EVERY = 0x00,
TSL2591_PERSIST_ANY = 0x01,
TSL2591_PERSIST_2 = 0x02,
TSL2591_PERSIST_3 = 0x03,
TSL2591_PERSIST_5 = 0x04,
TSL2591_PERSIST_10 = 0x05,
TSL2591_PERSIST_15 = 0x06,
TSL2591_PERSIST_20 = 0x07,
TSL2591_PERSIST_25 = 0x08,
TSL2591_PERSIST_30 = 0x09,
TSL2591_PERSIST_35 = 0x0A,
TSL2591_PERSIST_40 = 0x0B,
TSL2591_PERSIST_45 = 0x0C,
TSL2591_PERSIST_50 = 0x0D,
TSL2591_PERSIST_55 = 0x0E,
TSL2591_PERSIST_60 = 0x0F,
TSL2591_GAIN_LOW = 0x00,
TSL2591_GAIN_MED = 0x10,
TSL2591_GAIN_HIGH = 0x20,
TSL2591_GAIN_MAX = 0x30;
uint8_t DevID;

//
// Define ESP8266 variables
// 
static char ReceivedData[512];
static char str[128];
bool ProcessRoutine();
char *Substring(char *src, char *dst, int start, int stop);
int SearchIndexOf(char src[], char str[]);
char* itoa(int i, char b[]);
#define Period 320000 //(16000000/50) 50Hz
#define IP "184.106.153.149" // IP address for thingspeak.com
#define PORT "80" // IP Address access port

//------------------------------------------------------------------------------
// TSL2591 FUNCTIONS
//------------------------------------------------------------------------------

//
// Initialize I2C for TSL2591
//
void InitI2C1()
{
  //Enable I2C module 1
  SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
  //Reset module
  SysCtlPeripheralReset(SYSCTL_PERIPH_I2C1);
  // Enable GPIO peripheral that contains I2C 1
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  // Configure the pin muxing for I2C1 functions on port PA6 and PA7.
  GPIOPinConfigure(GPIO_PA6_I2C1SCL);
  GPIOPinConfigure(GPIO_PA7_I2C1SDA);
  // Select the I2C function for these pins.
  GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
  GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
  // Enable and initialize the I2C1 master module. Use the system clock for
  // the I2C1 module. The last parameter sets the I2C data transfer rate.
  // If false the data rate is set to 100kbps and if true the data rate will
  // be set to 400kbps.
  I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false);
}

//
// I2C1 Write function
//
void I2C1_write(uint8_t slave_addr, uint8_t slave_reg)
{
  // Set address to be used by the master module when writing to the slave
  I2CMasterSlaveAddrSet(I2C1_BASE, slave_addr, false);
  while (I2CMasterBusy(I2C1_BASE));
  // Place command to be sent to the data register
  I2CMasterDataPut(I2C1_BASE, slave_reg);
  // Send data to slave register
  I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
  while (I2CMasterBusy(I2C1_BASE));
}

//
// I2C1 Read function
//
void I2C1_read(uint8_t slave_addr, uint8_t *RxData, uint8_t N)
{
  uint8_t i; //Set local variable for loop function
  // Set address to be read
  I2CMasterSlaveAddrSet(I2C1_BASE, slave_addr, true);
  if (N==1)
  {
    // Read 8-bit data
    I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    while (I2CMasterBusy(I2C1_BASE));
    // Place data into Rx array
    RxData[0]=I2CMasterDataGet(I2C1_BASE);
    while (I2CMasterBusy(I2C1_BASE));
  }
  else
  {
    // Start reading bursts of data
    I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
    while (I2CMasterBusy(I2C1_BASE));
    // Place data into RxData array
    RxData[0]=I2CMasterDataGet(I2C1_BASE);
    while (I2CMasterBusy(I2C1_BASE));
    
    // Continue reading data until N-1
    for (i=1;i<(N-1);i++)
    {
      I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
      while (I2CMasterBusy(I2C1_BASE));
      RxData[i]=I2CMasterDataGet(I2C1_BASE);
      while (I2CMasterBusy(I2C1_BASE));
    }
    
  // Read final data
  I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

  while (I2CMasterBusy(I2C1_BASE));
  // Place last piece of data into RxData array
  RxData[N-1]=I2CMasterDataGet(I2C1_BASE);
  while (I2CMasterBusy(I2C1_BASE));
  }
}

void TSL2591_disable(void)
{
  I2C1_write(TSL2591_ADDR, TSL2591_COMMAND_BIT|TSL2591_REGISTER_ENABLE|TSL2591_ENABLE_POWEROFF);
}

void TSL2591_enable(void)
{
  //
  // Set integration time and sensor gain
  //
  // Specify that we want to communicate to device address with an intended write to bus
  I2CMasterSlaveAddrSet(I2C1_BASE, TSL2591_ADDR, false);
  // Place command in the register
  I2CMasterDataPut(I2C1_BASE, TSL2591_COMMAND_BIT|TSL2591_INTEGRATIONTIME_100MS);
  // Send control byte and register address byte to slave device
  I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
  while (I2CMasterBusy(I2C1_BASE));
  I2CMasterDataPut(I2C1_BASE, TSL2591_GAIN_MED);
  I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
  while (I2CMasterBusy(I2C1_BASE));
  //
  // Power ON, and enable ALS, ALS Interrupts, and No Persist Interrupts
  //
  // Specify that we want to communicate to device address with an intended
  // write to bus
  I2CMasterSlaveAddrSet(I2C1_BASE, TSL2591_ADDR, false);
  // Place command in the register
  I2CMasterDataPut(I2C1_BASE, TSL2591_COMMAND_BIT|TSL2591_REGISTER_ENABLE);
  // Send control byte and register address byte to slave device
  I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
  while (I2CMasterBusy(I2C1_BASE));
  I2CMasterDataPut(I2C1_BASE,TSL2591_ENABLE_POWERON|TSL2591_ENABLE_AEN|
  TSL2591_ENABLE _AIEN|TSL2591_ENABLE_NPIEN);
  I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
  while (I2CMasterBusy(I2C1_BASE));
}

//
// Initialize Light Sensor
//
void InitTSL2591()
{
  uint8_t temp_data[0];
  I2C1_write(TSL2591_ADDR, TSL2591_COMMAND_BIT|TSL2591_REGISTER_DEVICE_ID);
  I2C1_read(TSL2591_ADDR, temp_data, 1);
  DevID = temp_data[0];
  if (DevID == 0x50)
  {
    UARTprintf("Device Found...");
  }
  else
  {
    UARTprintf("\n Device Not Found");
  }
  TSL2591_enable(); //turn on light sensor
}

//
// Calculate for Luminosity (refer to TSL2561 datasheet)
//
uint32_t getLuminosity (uint8_t channel)
{
  float atime = 100.0F, again=25.0F; //for 100ms integration time and medium
//gain
  float cpl, lux1, lux2, lux;
  uint16_t ch0, ch1;
  uint16_t temp_data1[2], temp_data2[2];
  //Get full luminosity
  uint32_t x, y;
  I2C1_write(TSL2591_ADDR, TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW);
  I2C1_read(TSL2591_ADDR, temp_data1, 2);
  ch1 = temp_data1[0];
  x = ch1;
  y = x << 16; //bitshift left 16bits
  I2C1_write(TSL2591_ADDR, TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW);
  I2C1_read(TSL2591_ADDR, temp_data2, 2);
  ch0 = temp_data2[0];
  y |= ch0; //bitwise OR => shortcut for adding ch0 to y
  cpl = (atime * again) / TSL2591_LUX_DF;
  lux1 = ((float)ch0 - (TSL2591_LUX_COEFB * (float)ch1)) / cpl;
  lux2 = ((TSL2591_LUX_COEFC * (float)ch0) - (TSL2591_LUX_COEFD * (float)ch1))
/ cpl;
  lux = lux1 > lux2 ? lux1 : lux2; //if lux1 greater than lux2 then lux == lux1
  //else lux2
  
  return y;
}

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// ESP8266 FUNCTIONS
//------------------------------------------------------------------------------

//
// Initialize UART for ESP8266 use
//
void InitESPUART(void)
{
  // Enable the GPIO Peripheral port B
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  // Enable UART port 1
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
  // Configure the pin muxing for I2C1 functions on port PB0 and PB1.
  GPIOPinConfigure(GPIO_PB0_U1RX);
  GPIOPinConfigure(GPIO_PB1_U1TX);
  GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
  // Use the internal 16MHz oscillator as the UART clock source.
  UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC);
  // Enable and initialize the UART1 master module. Use the system clock for
  // the UART1 module.
  UARTConfigSetExpClk(UART1_BASE, 16000000, 115200, (UART_CONFIG_WLEN_8 |
  UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
  // Enable UART1
  UARTEnable(UART1_BASE);
}

//
// Send a direct AT command line to ESP8266
//
void SendATCommand(char *cmd)
{
  while(UARTBusy(UART1_BASE));
  while(*cmd != '\0')
  {
    UARTCharPut(UART1_BASE, *cmd++);
  }
  UARTCharPut(UART1_BASE, '\r'); //CR
  UARTCharPut(UART1_BASE, '\n'); //LF
}

int recvString(char *target, char *data, int timeout, bool check)
{
  int i=0;
  char a;
  unsigned long start = millis();
  while (millis() - start < timeout)
  {
    while(UARTCharsAvail(UART1_BASE))
    {
      a = UARTCharGet(UART1_BASE);
      if(a == '\0') continue;
      data[i]= a;
      i++;
    }
    if(check)
    {
      if (SearchIndexOf(data, target) != -1)
      {
        break;
      }
    }
  }
  
  return 0;
}

bool recvFind(char *target, int timeout,bool check)
{ 
  recvString(target, ReceivedData, timeout, check);
  if (SearchIndexOf(ReceivedData, target) != -1)
  {
    return true;
  }
  
  return false;
}

bool recvFindAndFilter(char *target, char *begin, char* end, char *data, int timeout)
{ 
  recvString(target, ReceivedData, timeout, true);
  if (SearchIndexOf(ReceivedData, target) != -1)
  { 
    int index1 = SearchIndexOf(ReceivedData, begin); int index2 = SearchIndexOf(ReceivedData, end);
    if (index1 != -1 && index2 != -1)
    {
      index1 += strlen(begin); Substring(ReceivedData,data,index1, index2);
      return true;
    }
  }
  data = "";
  
  return false;
}

// General test command
bool ATesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT");
  
  return recvFind("OK",5000, true);
}

// Restart module command
bool RSTesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+RST");
  
  return recvFind("OK",5000, false);
}

// WIFI mode command
bool CWMODEesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CWMODE=1"); //Station Mode (client)
  //SendATCommand("AT+CWMODE=2"); //AP Mode (host)
  //SendATCommand("AT+CWMODE=3"); //AP + Station Mode
  
  return recvFind("OK",5000, true);
}

// Join the AP command
bool CWJAPesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CWJAP=\"ENTERYOURSSIDHERE\",\"ENTERYOURPASSWDHERE\""); //Your Wifi: NetworkName, Password
  
  return recvFind("OK",10000, true);
}

// Quit the AP command
bool CWQAPesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CWQAP");
  
  return recvFind("OK",10000, true);
}

// Set multiple connection command
bool CIPMUXesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CIPMUX=0"); //single connection
  SendATCommand("AT+CIPMUX=1"); 
  
  return recvFind("OK",5000, true);
}

// Check firmware version command
bool ATGMResp(char *version)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+GMR");
  
  return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", version,10000);
}

// List the AP command
bool aCWLAPesp(char *list)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CWLAP");
  
  return recvFindAndFilter("OK","\r\r\n", "\r\n\r\nOK", list,15000);
}

// Get IP address command
bool aCIFSResp(char *list)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CIFSR");
  
  return recvFindAndFilter("OK","\r\r\n", "\r\n\r\nOK", list,15000);
}

// Set the server timeout command
bool CIPSTOesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CIPSTO=10000");
  
  return recvFind("OK",2000, true);
}

// Set up TCP or UDP connection command
bool CIPSTARTesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CIPSTART=\"TCP\",\""IP"\","PORT""); //Server IP and Port: such as 192.255.0.100, 9999
  
  return recvFind("OK",2000, true);
}

// Close TCP or UDP connection command
bool CIPCLOSEesp(void)
{ 
  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand("AT+CIPCLOSE");
  
  return recvFind("OK",5000, true);
}

// Send data command
bool CIPSENDesp(char *text)
{
  int len = strlen(text)+2; //find text length plus 2 to include "\r" and "\n"
  itoa(len,str); //converts int len into string str
  char* AT_CMD_SEND = "AT+CIPSEND=";
  char CMD_TEXT[128];
  strcpy(CMD_TEXT,AT_CMD_SEND); //copies string pointed to by CMD_SEND to
  //CMD_TEXT
  strcat(CMD_TEXT,str); //appends string point to by str to the end of the
  //string pointed to by CMD_TEXT

  memset(ReceivedData, 0, sizeof(ReceivedData));
  SendATCommand(CMD_TEXT); //sends "AT+CIPSEND=" + str (which is the text
//length)
  delay(5); //wait for AT pointer
  SendATCommand(text);
  
  return recvFind("SEND OK",2000, true);
}

// Reset hardware pins
void HardwareReset()
{
  GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0); //Output
  GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_4, 0x00); //LOW ->Reset to ESP8266
  delay(50);
  GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0); //Output ->// Open drain;
  //reset -> GND
  delay(10);
  GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_0); //Input ->// Back to high-
  //impedance pin state
  delay(3000);
}
//------------------------------------------------------------------------------

//
// Initialize UART for general purpose sending & receiving
//
void InitUART(void)
{
  // Enable the GPIO Peripheral port A
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  // Enable UART port 0
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  // Configure the pin muxing for for UART mode.
  GPIOPinConfigure(GPIO_PA0_U0RX);
  GPIOPinConfigure(GPIO_PA1_U0TX);
  GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
  // Use the internal 16MHz oscillator as the UART clock source.
  UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
  // Initialize the UART for console I/O.
  UARTStdioConfig(0, 115200, 16000000);
}

//
// Initialize GPIO port F pins for LED use
//
void InitLED(void)
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
  GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x00); //turn off LED
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x00); //turn off LED
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x00); //turn off LED
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
  GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);
  GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0x00);
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x02); //turn on red LED
}

//------------------------------------------------------------------------------
// MAIN
//------------------------------------------------------------------------------
int main(void)
{
  // Set local variable
  bool TaskStatus;
  // Set the clocking to run directly from the external crystal/oscillator.
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
  InitLED(); //initialize LEDs
  timerInit(); //set timer clock and interrupt
  InitI2C1(); //initialize I2C
  InitUART(); //initialize UART
  HardwareReset(); //reset pins

  UARTprintf("Initializing TSL2591...");
  InitTSL2591(); //initialize light sensor
  UARTprintf("COMPLETE \n");
  UARTprintf("Initializing ESP8266...");
  InitESPUART();
  UARTprintf("COMPLETE \n");
  UARTprintf("Starting ESP8266...\n");
  delay(1000);
  TaskStatus = ATesp();
  if (TaskStatus)
  {
    UARTprintf("ATesp OK!\n");
  }
  else
  {
    UARTprintf("ATesp FAIL!\n");
  }

  TaskStatus = RSTesp();
  if (TaskStatus)
  {
    UARTprintf("RSTesp OK!\n");
  }
  else
  {
    UARTprintf("RSTesp FAIL!\n");
  }
  
  TaskStatus = CWMODEesp();
  if (TaskStatus)
  {
    UARTprintf("CWMODEesp OK!\n");
  }
  else
  {
    UARTprintf("CWMODEesp FAIL!\n");
    while(true)
    {
      UARTprintf("Trying to connect to WI-FI...");
      TaskStatus = CWJAPesp();
      if(TaskStatus)
      {
        UARTprintf("COMPLETE\n");
        break;
      }
      else
      {
        UARTprintf("FAILED\n");
      }
    }
    
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x00); //turn off LED
  TaskStatus = CIPMUXesp();
  while(true)
  {
  TaskStatus = ProcessRoutine();
    if(TaskStatus)
    {
      CIPCLOSEesp();
      GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x00); //turn off LED
      GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x04); //turn on blue LED
      delay(1000); //wait for 1 second refresh
    }
    else
    {
      delay(10);
      CWQAPesp();

      GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x00); //Turn off Blue
//Led
      GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x02); //Turn on Red
//Led
    }
  }
}

//
// Process routine containing TSL2591 data and ESP8266 transfer
//
bool ProcessRoutine()
{
  // Set local variables
  bool status;
  uint32_t raw_data;
  uint16_t IR, FULL, VISIBLE;
  char UPDATE_str[128],
  str_raw_data[128],
  str_FULL[128],
  str_IR[128],
  str_VISIBLE[128];
  UARTprintf("Trying to connect to server...");
  while(true)
  {
    status = CIPSTARTesp(); //connect to IP address
    if(status)
    {
      UARTprintf("COMPLETE\n");
      break;
    }
  delay(50);
  }
  
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x00);
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x08); //turn on green LED -> READY
  // Get light data from TSL2591
  raw_data = getLuminosity(TSL2591_FULLSPECTRUM);
  itoa(raw_data, str_raw_data);
  FULL = raw_data & 0xFFFF;
  itoa(FULL, str_FULL);
  //FULL = getLuminosity(TSL2591_FULL);
  IR = raw_data >> 16;
  itoa(IR, str_IR);
  //IR = getLuminosity(TSL2591_INFRARED);
  VISIBLE = FULL - IR;
  itoa(VISIBLE,str_VISIBLE);
  //VISIBLE = getLuminosity(TSL2591_VISIBLE);
  TSL2591_disable(); //turn off light sensor

  // Display TSL2591 data
  UARTprintf("\n-------- TSL2591 DATA ----------");
  UARTprintf("\n Raw_data: %i", raw_data);
  UARTprintf("\n FULL: %i", FULL);
  UARTprintf("\n IR: %i", IR);
  UARTprintf("\n VISIBLE: %i", VISIBLE);
  UARTprintf("\n------------------------------------\n");
  memset(ReceivedData, 0, sizeof(ReceivedData)); //clear
  // Send data to thingspeak server to field 1-4
  UARTprintf("\nSending Data...");
  char *UPDATE_url =
"GEThttps://api.thingspeak.com/update?api_key=INSERTYOURTHINGSPEAKAPIKEYHERE";
  strcpy(UPDATE_str, UPDATE_url);
  strcat(UPDATE_str, "&field1="); //raw_data graph
  strcat(UPDATE_str, str_raw_data);
  strcat(UPDATE_str, "&field2="); //full-spectrum graph
  strcat(UPDATE_str, str_FULL);
  strcat(UPDATE_str, "&field3="); //infrared graph
  strcat(UPDATE_str, str_IR);
  strcat(UPDATE_str, "&field4="); //visible graph
  strcat(UPDATE_str, str_VISIBLE);
  CIPSENDesp(UPDATE_str);
  UARTprintf("Complete\n");
  
  return true;
}
//------------------------------------------------------------------------------

char *Substring(char *src, char *dst, int start, int stop)
{
  int len = stop - start;
  strncpy(dst, src + start, len);
  
  return dst;
}

int SearchIndexOf(char src[], char str[])
{
  int i, j, firstOcc;
  i = 0, j = 0;
  while (src[i] != '\0')
  {
    while (src[i] != str[0] && src[i] != '\0')
      i++;
      
    if (src[i] == '\0')
      return (-1);
      
    firstOcc = i;

    while (src[i] == str[j] && src[i] != '\0' && str[j] != '\0')
    {
      i++;
      j++;
    }
  
    if (str[j] == '\0')
      return (firstOcc);
    
    if (src[i] == '\0')
      return (-1);
    
    i = firstOcc + 1;
    j = 0;
  }
  
  return (-1);
}

//
// INT to String Function
//
char* itoa(int i, char b[])
{
  char const digit[] = "0123456789";
  char* p = b;
  if(i<0)
  {
    *p++ = '-';
    i *= -1;
  }
  
  int shifter = i;
  do
  {
    ++p;
    shifter = shifter/10;
  }while(shifter);
  
  *p = '\0';
  do
  {
    *--p = digit[i%10];
    i = i/10;
  }while(i);
  
  return b;
}

Credits

HyperChiicken

HyperChiicken

11 projects • 27 followers
I cobble things together :]

Comments