diff --git a/examples/tsl4531/Makefile b/examples/tsl4531/Makefile
new file mode 100644
index 0000000..f52d04f
--- /dev/null
+++ b/examples/tsl4531/Makefile
@@ -0,0 +1,3 @@
+PROGRAM=tsl4531_example
+EXTRA_COMPONENTS = extras/i2c extras/tsl4531
+include ../../common.mk
diff --git a/examples/tsl4531/tsl4531_example.c b/examples/tsl4531/tsl4531_example.c
new file mode 100644
index 0000000..9b69b29
--- /dev/null
+++ b/examples/tsl4531/tsl4531_example.c
@@ -0,0 +1,55 @@
+/*
+ * This sample code is in the public domain.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "esp/uart.h"
+#include "FreeRTOS.h"
+#include "i2c/i2c.h"
+#include "task.h"
+#include "tsl4531/tsl4531.h"
+
+/* An example using the TSL4531 light sensor
+ * to read and print lux values from a sensor
+ * attached to GPIO pin 2 (SCL) and GPIO pin 0 (SDA)
+ * Connect 3.3v from the ESP to Vin and GND to GND
+ */
+
+#define SCL_PIN (2)
+#define SDA_PIN (0)
+
+void tsl4531MeasurementTask(void *pvParameters)
+{
+    tsl4531_t lightSensor;
+    lightSensor.i2c_addr = TSL4531_I2C_ADDR;
+    tsl4531_init(&lightSensor);
+
+    tsl4531_set_integration_time(&lightSensor, TSL4531_INTEGRATION_400MS);
+    tsl4531_set_power_save_skip(&lightSensor, true);
+
+    uint16_t lux = 0;
+
+    while (1)
+    {
+        if (tsl4531_read_lux(&lightSensor, &lux))
+        {
+            printf("Lux: %u\n", lux);
+        }
+        else
+        {
+            printf("Could not read data from TSL4531\n");
+        }
+
+        // 0.05 second delay
+        vTaskDelay(50 / portTICK_PERIOD_MS);
+    }
+}
+
+void user_init(void)
+{
+    uart_set_baud(0, 115200);
+    i2c_init(SCL_PIN, SDA_PIN);
+
+    xTaskCreate(tsl4531MeasurementTask, "tsl4531MeasurementTask", 256, NULL, 2, NULL);
+}
diff --git a/extras/tsl2561/tsl2561.c b/extras/tsl2561/tsl2561.c
index 991d803..f60825a 100644
--- a/extras/tsl2561/tsl2561.c
+++ b/extras/tsl2561/tsl2561.c
@@ -107,9 +107,9 @@ static uint8_t read_register(uint8_t i2c_addr, uint8_t reg)
     uint8_t data[1];
     reg = TSL2561_REG_COMMAND | reg;
 
-    if (i2c_slave_read(i2c_addr, &reg , data, 1))
+    if (i2c_slave_read(i2c_addr, &reg, data, 1))
     {
-        printf("Error in tsl261 read_register\n");
+        printf("Error in tsl2561 read_register\n");
     }
 
     return data[0];
diff --git a/extras/tsl4531/component.mk b/extras/tsl4531/component.mk
new file mode 100644
index 0000000..8752823
--- /dev/null
+++ b/extras/tsl4531/component.mk
@@ -0,0 +1,9 @@
+# Component makefile for extras/tsl4531
+
+# Include the TSL4531 driver as "tsl4531/tsl4531.h"
+INC_DIRS += $(tsl4531_ROOT)..
+
+# args for passing into compile rule generation
+tsl4531_SRC_DIR = $(tsl4531_ROOT)
+
+$(eval $(call component_compile_rules,tsl4531))
diff --git a/extras/tsl4531/tsl4531.c b/extras/tsl4531/tsl4531.c
new file mode 100644
index 0000000..54963e9
--- /dev/null
+++ b/extras/tsl4531/tsl4531.c
@@ -0,0 +1,166 @@
+/*
+ * Part of esp-open-rtos
+ * Copyright (C) 2017 Brian Schwind (https://github.com/bschwind)
+ * BSD Licensed as described in the file LICENSE
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "i2c/i2c.h"
+#include "task.h"
+#include "tsl4531.h"
+
+// Registers
+#define TSL4531_REG_COMMAND 0x80
+#define TSL4531_REG_CONTROL 0x00
+#define TSL4531_REG_CONFIG 0x01
+#define TSL4531_REG_DATA_LOW 0x04
+#define TSL4531_REG_DATA_HIGH 0x05
+#define TSL4531_REG_DEVICE_ID 0x0A
+
+// TSL4531 Misc Values
+#define TSL4531_ON 0x03
+#define TSL4531_OFF 0x00
+
+// Integration times in milliseconds
+#define TSL4531_INTEGRATION_TIME_100MS 120
+#define TSL4531_INTEGRATION_TIME_200MS 240
+#define TSL4531_INTEGRATION_TIME_400MS 480 // Default
+
+static int write_register(uint8_t i2c_addr, uint8_t reg, uint8_t value)
+{
+    reg = TSL4531_REG_COMMAND | reg;
+    return i2c_slave_write(i2c_addr, &reg, &value, 1);
+}
+
+static uint8_t read_register(uint8_t i2c_addr, uint8_t reg)
+{
+    uint8_t data[1];
+    reg = TSL4531_REG_COMMAND | reg;
+
+    if (i2c_slave_read(i2c_addr, &reg, data, 1))
+    {
+        printf("Error in tsl4531 read_register\n");
+    }
+
+    return data[0];
+}
+
+static uint16_t read_register_16(uint8_t i2c_addr, uint8_t low_register_addr)
+{
+    uint16_t value = 0;
+    uint8_t data[2];
+    low_register_addr = TSL4531_REG_COMMAND | low_register_addr;
+
+    if (i2c_slave_read(i2c_addr, &low_register_addr, data, 2))
+    {
+        printf("Error with i2c_slave_read in read_register_16\n");
+    }
+
+    value = ((uint16_t)data[1] << 8) | (data[0]);
+
+    return value;
+}
+
+static int enable(tsl4531_t *device)
+{
+    return write_register(device->i2c_addr, TSL4531_REG_CONTROL, TSL4531_ON);
+}
+
+static int disable(tsl4531_t *device)
+{
+    return write_register(device->i2c_addr, TSL4531_REG_CONTROL, TSL4531_OFF);
+}
+
+void tsl4531_init(tsl4531_t *device)
+{
+    if (enable(device))
+    {
+        printf("Error initializing tsl4531, the enable write failed\n");
+    }
+
+    uint8_t control_reg = read_register(device->i2c_addr, TSL4531_REG_CONTROL);
+
+    if (control_reg != TSL4531_ON) {
+        printf("Error initializing tsl4531, control register wasn't set to ON\n");
+    }
+
+    uint8_t idRegister = read_register(device->i2c_addr, TSL4531_REG_DEVICE_ID);
+    uint8_t id = (idRegister & 0xF0) >> 4;
+
+    if (id == TSL4531_PART_TSL45317) {
+        device->part_id = TSL4531_PART_TSL45317;
+    } else if (id == TSL4531_PART_TSL45313) {
+        device->part_id = TSL4531_PART_TSL45313;
+    } else if (id == TSL4531_PART_TSL45315) {
+        device->part_id = TSL4531_PART_TSL45315;
+    } else if (id == TSL4531_PART_TSL45311) {
+        device->part_id = TSL4531_PART_TSL45311;
+    } else {
+        printf("Unknown part id for TSL4531 sensor: %u\n", id);
+    }
+
+    disable(device);
+}
+
+void tsl4531_set_integration_time(tsl4531_t *device, tsl4531_integration_time_t integration_time_id)
+{
+    uint8_t power_save_bit = device->skip_power_save ? 0x08 : 0x00;
+    uint8_t integration_time_bits = 0x03 & integration_time_id;
+    uint8_t new_config_reg = power_save_bit | integration_time_bits;
+
+    enable(device);
+    write_register(device->i2c_addr, TSL4531_REG_CONFIG, new_config_reg);
+    disable(device);
+
+    device->integration_time_id = integration_time_id;
+}
+
+void tsl4531_set_power_save_skip(tsl4531_t *device, bool skip_power_save)
+{
+    uint8_t power_save_bit = skip_power_save ? 0x08 : 0x00;
+    uint8_t integration_time_bits = 0x03 & device->integration_time_id;
+    uint8_t new_config_reg = power_save_bit | integration_time_bits;
+
+    enable(device);
+    write_register(device->i2c_addr, TSL4531_REG_CONFIG, new_config_reg);
+    disable(device);
+
+    device->skip_power_save = skip_power_save;
+}
+
+bool tsl4531_read_lux(tsl4531_t *device, uint16_t *lux)
+{
+    bool success = true;
+    uint16_t multiplier = 1;
+
+    enable(device);
+
+    switch (device->integration_time_id)
+    {
+        case TSL4531_INTEGRATION_100MS:
+            multiplier = 4;
+            vTaskDelay(TSL4531_INTEGRATION_TIME_100MS / portTICK_PERIOD_MS);
+            break;
+        case TSL4531_INTEGRATION_200MS:
+            multiplier = 2;
+            vTaskDelay(TSL4531_INTEGRATION_TIME_200MS / portTICK_PERIOD_MS);
+            break;
+        case TSL4531_INTEGRATION_400MS:
+            multiplier = 1;
+            vTaskDelay(TSL4531_INTEGRATION_TIME_400MS / portTICK_PERIOD_MS);
+            break;
+        default:
+            multiplier = 1;
+            vTaskDelay(TSL4531_INTEGRATION_TIME_400MS / portTICK_PERIOD_MS);
+            break;
+    }
+
+    uint16_t lux_data = read_register_16(device->i2c_addr, TSL4531_REG_DATA_LOW);
+    
+    disable(device);
+
+    *lux = multiplier * lux_data;
+
+    return success;
+}
diff --git a/extras/tsl4531/tsl4531.h b/extras/tsl4531/tsl4531.h
new file mode 100644
index 0000000..3b57664
--- /dev/null
+++ b/extras/tsl4531/tsl4531.h
@@ -0,0 +1,56 @@
+/*
+ * Part of esp-open-rtos
+ * Copyright (C) 2017 Brian Schwind (https://github.com/bschwind)
+ * BSD Licensed as described in the file LICENSE
+ */
+
+#ifndef __TSL4531_H__
+#define __TSL4531_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// I2C Addresses
+typedef enum
+{
+    TSL4531_I2C_ADDR = 0x29
+} tsl4531_i2c_addr_t;
+
+// Integration time IDs
+typedef enum
+{
+    TSL4531_INTEGRATION_100MS = 0x02,
+    TSL4531_INTEGRATION_200MS = 0x01,
+    TSL4531_INTEGRATION_400MS = 0x00 // Default
+} tsl4531_integration_time_t;
+
+// Part IDs
+typedef enum
+{
+    TSL4531_PART_TSL45317 = 0x08,
+    TSL4531_PART_TSL45313 = 0x09,
+    TSL4531_PART_TSL45315 = 0x0A,
+    TSL4531_PART_TSL45311 = 0x0B
+} tsl4531_part_id_t;
+
+typedef struct {
+    tsl4531_i2c_addr_t i2c_addr;
+    uint8_t integration_time_id;
+    bool skip_power_save;
+    tsl4531_part_id_t part_id;
+} tsl4531_t;
+
+void tsl4531_init(tsl4531_t *device);
+void tsl4531_set_integration_time(tsl4531_t *device, tsl4531_integration_time_t integration_time_id);
+void tsl4531_set_power_save_skip(tsl4531_t *device, bool skip_power_save);
+bool tsl4531_read_lux(tsl4531_t *device, uint16_t *lux);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __TSL4531_H__