For my sound level project I am considering using inexpensive RGB Strip LEDs. So to try some code out I did a trial from this Adafruit post:
https://learn.adafruit.com/rgb-led-strips/overview
The differences are:
* used Adafruit's circuit for the TIP120 except except that I used 5mm LEDs to stand in for the strip (also put a resistor in front of each LED so it wouldn't burn out)
* used Adafruit's sketch except I substituted pins 11, 12, and 13 for the Arduino PWM (used a MSP430G2553)
* used a 4.5V battery pack for external power to the LEDs
It is working:
For
my project I am thinking I'll need at least 2 strips running 2
different colors so 6 TIP120s. I only have 5. Even better would be to
have 3 strips and 3 colors - then I'll have the added complication of
not enough PWM pins. It looks like there is another order in my future.
Learning to use microcontrollers with an emphasis on the Texas Instruments Launchpads / Energia
Showing posts with label Adafruit. Show all posts
Showing posts with label Adafruit. Show all posts
Friday, June 26, 2015
Wednesday, June 24, 2015
Wednesday, April 8, 2015
DHT 22 Humidity and Temperature Sensor
I bought a DHT 22 a while back from Adafruit for use on the Arduino and just got around to trying it on the MSP-EXP430F5529LP. They supply a good write-up and a library for using it as well but it is another one of those libraries that almost, but not quite, works with Energia. To make it work you need to do the following:
Inside the sketch itself you will need to adjust the "threshold for cycled for cycle counts". The remarks state that the default is 6 which works with a 16mhz AVR. It definitely does not work with the 430F5529. I played around and ended up assigning with the following statement and seemed to get good results:
DHT dht(DHTPIN, DHTTYPE, 12);
It does bother me that I'm not really sure what this is doing or how it impacts results. I compared it to what my local weather station was reporting and was within 1% but that is just one data point.
You will also need to make a change to DHT.cpp in the library. There are function that attempt to return NAN (not a number). The gcc compiler for the 430 does not like this. I fixed it in a way I'm not too proud of. Instead of return NAN, I used return 0/0 which of course is "not a number". I could have used a negative number outside of normal values but that didn't seem right either since I didn't explore what the consequences of that might be. This code needs to be cleaned up.
The Adafruit library does not calculate dew point and I wanted that. It can be calculated from the August-Roche-Magnus approximation as follows:
td =243.04*(logf(h/100)+((17.625*t)/(243.04+t)))/(17.625-logf(h/100)-((17.625*t)/(243.04+t)));
Where:
td = dew point, degrees C
h = relative humidity, % from the DHT 22
t = air temperature, degrees C from the DHT 22
Inside the sketch itself you will need to adjust the "threshold for cycled for cycle counts". The remarks state that the default is 6 which works with a 16mhz AVR. It definitely does not work with the 430F5529. I played around and ended up assigning with the following statement and seemed to get good results:
DHT dht(DHTPIN, DHTTYPE, 12);
It does bother me that I'm not really sure what this is doing or how it impacts results. I compared it to what my local weather station was reporting and was within 1% but that is just one data point.
You will also need to make a change to DHT.cpp in the library. There are function that attempt to return NAN (not a number). The gcc compiler for the 430 does not like this. I fixed it in a way I'm not too proud of. Instead of return NAN, I used return 0/0 which of course is "not a number". I could have used a negative number outside of normal values but that didn't seem right either since I didn't explore what the consequences of that might be. This code needs to be cleaned up.
The Adafruit library does not calculate dew point and I wanted that. It can be calculated from the August-Roche-Magnus approximation as follows:
td =243.04*(logf(h/100)+((17.625*t)/(243.04+t)))/(17.625-logf(h/100)-((17.625*t)/(243.04+t)));
Where:
td = dew point, degrees C
h = relative humidity, % from the DHT 22
t = air temperature, degrees C from the DHT 22
Sunday, April 5, 2015
Adafruit TSL2591 Lux Sensor
This post is about the Adafruit TSL2591 Lux Sensor which I have also used with the Arduino. Adafruit has a good write-up and it ports very easily to the MSP-EXP430F5529. I am using the Adafruit library, however there is one thing that keeps their library from compiling on the LaunchPads...
In the Adafruit library for the TL2591, the cpp file (Adafruit_TSL2591.cpp)has a preprocessor directive for delay.h. Either remove it or comment the line out.
One thing the example code Adafruit supplies does not do is auto-range the gain on the sensor. If the light is too bright it can saturate and if too dim you may not get good readings. I've written a function named configureSensor(void) below. The magic numbers are experimental results that seem to work well for me. It needs an iteration or two to make this adjustment. I've not added code to discard bad readings but that could be easily done.
Here is the sketch...
/*
PURPOSE:
This sketch uses the Adafruit TLS2591 light sensor to display lux values
on the serial monitor. It also "autoranges" the gain and time photons
are collected on the sensor to keep the sensor in range. In order to
get a good reading after a bad reading due to a drastic light change it
will be necessary to let it iterate two times or so. Try covering the
sensor and watching what happens. Then remove the cover and shine a
bright light on it.
PORT TO MSP-EXP430F5529:
In order for this to compile, comment out or remove the following
line of Adafruit_TSL2591.cpp in the library
=========================================================================
#include <util/delay.h>
=========================================================================
SENSOR:
TSL2591 Digital Light Sensor
Dynamic Range: 600M:1
Range: 188 ulux up to 88,000 lux
The lux (symbol: lx) is the SI unit of illuminance and luminous emittance,
measuring luminous flux per unit area. It is equal to one lumen per square
meter. The table below gives examples:
0.0001 lux Moonless, overcast night sky (starlight)
0.002 lux Moonless clear night sky with airglow
0.27–1.0 lux Full moon on a clear night
3.4 lux Dark limit of civil twilight under a clear sky
50. lux Family living room lights
80. lux Office building hallway/toilet lighting
100. lux Very dark overcast day
320–500. lux Office lighting
400. lux Sunrise or sunset on a clear day.
1000. lux Overcast day; typical TV studio lighting
10000–25000. lux Full daylight (not direct sun)
32000–100000. lux Direct sunlight
Source: Wikipedia
HARDWARE AND CONNECTIONS:
Adafruit TLS2591 connections for MSP-EXP430F5529LP
======================================================================
SCL to Pin 14 (P3.1) Must be I2C Pin
SDA to Pin 15 (P3.0) Must be I2C Pin
connect Vin to 3.3 DC
GND to common ground
3Vo (no connection)
Int (no connection)
*/
//============================ G L O B A L ============================
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // sensor identifier
float luxVal = 10000;
void setup(void)
{
//============================== S E T U P =============================
Serial.begin(9600);
Serial.println("Starting Adafruit TSL2591 Test!");
if (tsl.begin())
{
Serial.println("Found a TSL2591 sensor");
}
else
{
Serial.println("No sensor found ... check your wiring?");
while (1);
}
/* Display some basic information on this sensor */
displaySensorDetails();
}
void loop(void)
{
//============================== L O O P ==================================
configureSensor();
unifiedSensorAPIRead();
delay (1000);
}
void unifiedSensorAPIRead(void)
{
//============== U N I F I E D S E N S O R A P I R E A D =============
// Performs a read using the Adafruit Unified Sensor API
// Updates the lux value in the global variable luxVal
// Get a new sensor event
sensors_event_t event;
tsl.getEvent(&event);
if ((event.light == 0) |
(event.light > 4294966000.0) |
(event.light <-4294966000.0))
{
// If event.light == 0 lux the sensor is probably saturated
// and no reliable data could be generated!
// if event.light is +/- 4294967040 there was a float over/underflow
Serial.println("Invalid data - auto adjusting gain gain and timing)");
luxVal = 10000.0; // Set luxVal to get minimum time and gain for next pass
// so as to get a valid starting point
}
else
{
int f; // format number for decimal places in the print statement
if (luxVal >= 100.0)
{
f = 0;
}
else if (luxVal < 100.0 && luxVal >= 100.0)
{
f = 1;
}
else if (luxVal < 100.0 && luxVal >= 1.0)
{
f = 2;
}
else
{
f = 3;
}
Serial.print(event.light,f); Serial.println(" lux");
Serial.println("------------------");
Serial.println("");
luxVal = event.light;
}
}
void displaySensorDetails(void)
{
//============= D I S P L A Y S E N S O R D E T A I L S ================
// Displays some basic information on this sensor from the unified
// sensor API sensor_t type (see Adafruit_Sensor for more information)
sensor_t sensor;
tsl.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
Serial.println("------------------------------------");
Serial.println("");
delay(2000);
}
void configureSensor(void)
{
//================== C O N F I G U R E S E N S O R =====================
//
// Configures the gain and integration time for the TSL2561 depending
// on luxVal
// NOTE: The variable luxVal is global. The following calls are valid:
//
// Set gain according to the light level
// tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
// tsl.setGain(TSL2591_GAIN_MED); // 25x gain
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
// tsl.setGain(TSL2591_GAIN_MAX); // 9876x gain (extremely low light)
//
// Changing integration time gives you a longer time over which to sense light
// Longer timelines are slower, but improve accuracy in low light situations
// tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
//
// The values used below are empirical ones that seemed to get things in
// a good range for accurate measurement... F Milburn
//
Serial.println("------------------");
Serial.print ("Gain: ");
if (luxVal > 200.0)
{
tsl.setGain(TSL2591_GAIN_LOW);
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
Serial.println("1x (Low)");
Serial.println("Timing: 100 ms");
}
else if (luxVal <=200.0 && luxVal > 40.0)
{
tsl.setGain(TSL2591_GAIN_MED);
tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
Serial.println("25x (Med)");
Serial.println("Timing: 200 ms");
}
else if (luxVal <=40.0 && luxVal > 10.0)
{
tsl.setGain(TSL2591_GAIN_MED);
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
Serial.println("25x (Med)");
Serial.println("Timing: 600 ms");
}
else if (luxVal <=10.0 && luxVal > 0.1)
{
tsl.setGain(TSL2591_GAIN_HIGH);
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
Serial.println("428x (High)");
Serial.println("Timing: 600 ms");
}
else
{
tsl.setGain(TSL2591_GAIN_MAX);
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
Serial.println("9876x (Max)");
Serial.println("Timing: 600 ms");
}
}
In the Adafruit library for the TL2591, the cpp file (Adafruit_TSL2591.cpp)has a preprocessor directive for delay.h. Either remove it or comment the line out.
One thing the example code Adafruit supplies does not do is auto-range the gain on the sensor. If the light is too bright it can saturate and if too dim you may not get good readings. I've written a function named configureSensor(void) below. The magic numbers are experimental results that seem to work well for me. It needs an iteration or two to make this adjustment. I've not added code to discard bad readings but that could be easily done.
Here is the sketch...
/*
PURPOSE:
This sketch uses the Adafruit TLS2591 light sensor to display lux values
on the serial monitor. It also "autoranges" the gain and time photons
are collected on the sensor to keep the sensor in range. In order to
get a good reading after a bad reading due to a drastic light change it
will be necessary to let it iterate two times or so. Try covering the
sensor and watching what happens. Then remove the cover and shine a
bright light on it.
PORT TO MSP-EXP430F5529:
In order for this to compile, comment out or remove the following
line of Adafruit_TSL2591.cpp in the library
=========================================================================
#include <util/delay.h>
=========================================================================
SENSOR:
TSL2591 Digital Light Sensor
Dynamic Range: 600M:1
Range: 188 ulux up to 88,000 lux
The lux (symbol: lx) is the SI unit of illuminance and luminous emittance,
measuring luminous flux per unit area. It is equal to one lumen per square
meter. The table below gives examples:
0.0001 lux Moonless, overcast night sky (starlight)
0.002 lux Moonless clear night sky with airglow
0.27–1.0 lux Full moon on a clear night
3.4 lux Dark limit of civil twilight under a clear sky
50. lux Family living room lights
80. lux Office building hallway/toilet lighting
100. lux Very dark overcast day
320–500. lux Office lighting
400. lux Sunrise or sunset on a clear day.
1000. lux Overcast day; typical TV studio lighting
10000–25000. lux Full daylight (not direct sun)
32000–100000. lux Direct sunlight
Source: Wikipedia
HARDWARE AND CONNECTIONS:
Adafruit TLS2591 connections for MSP-EXP430F5529LP
======================================================================
SCL to Pin 14 (P3.1) Must be I2C Pin
SDA to Pin 15 (P3.0) Must be I2C Pin
connect Vin to 3.3 DC
GND to common ground
3Vo (no connection)
Int (no connection)
*/
//============================ G L O B A L ============================
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // sensor identifier
float luxVal = 10000;
void setup(void)
{
//============================== S E T U P =============================
Serial.begin(9600);
Serial.println("Starting Adafruit TSL2591 Test!");
if (tsl.begin())
{
Serial.println("Found a TSL2591 sensor");
}
else
{
Serial.println("No sensor found ... check your wiring?");
while (1);
}
/* Display some basic information on this sensor */
displaySensorDetails();
}
void loop(void)
{
//============================== L O O P ==================================
configureSensor();
unifiedSensorAPIRead();
delay (1000);
}
void unifiedSensorAPIRead(void)
{
//============== U N I F I E D S E N S O R A P I R E A D =============
// Performs a read using the Adafruit Unified Sensor API
// Updates the lux value in the global variable luxVal
// Get a new sensor event
sensors_event_t event;
tsl.getEvent(&event);
if ((event.light == 0) |
(event.light > 4294966000.0) |
(event.light <-4294966000.0))
{
// If event.light == 0 lux the sensor is probably saturated
// and no reliable data could be generated!
// if event.light is +/- 4294967040 there was a float over/underflow
Serial.println("Invalid data - auto adjusting gain gain and timing)");
luxVal = 10000.0; // Set luxVal to get minimum time and gain for next pass
// so as to get a valid starting point
}
else
{
int f; // format number for decimal places in the print statement
if (luxVal >= 100.0)
{
f = 0;
}
else if (luxVal < 100.0 && luxVal >= 100.0)
{
f = 1;
}
else if (luxVal < 100.0 && luxVal >= 1.0)
{
f = 2;
}
else
{
f = 3;
}
Serial.print(event.light,f); Serial.println(" lux");
Serial.println("------------------");
Serial.println("");
luxVal = event.light;
}
}
void displaySensorDetails(void)
{
//============= D I S P L A Y S E N S O R D E T A I L S ================
// Displays some basic information on this sensor from the unified
// sensor API sensor_t type (see Adafruit_Sensor for more information)
sensor_t sensor;
tsl.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
Serial.println("------------------------------------");
Serial.println("");
delay(2000);
}
void configureSensor(void)
{
//================== C O N F I G U R E S E N S O R =====================
//
// Configures the gain and integration time for the TSL2561 depending
// on luxVal
// NOTE: The variable luxVal is global. The following calls are valid:
//
// Set gain according to the light level
// tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
// tsl.setGain(TSL2591_GAIN_MED); // 25x gain
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
// tsl.setGain(TSL2591_GAIN_MAX); // 9876x gain (extremely low light)
//
// Changing integration time gives you a longer time over which to sense light
// Longer timelines are slower, but improve accuracy in low light situations
// tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
//
// The values used below are empirical ones that seemed to get things in
// a good range for accurate measurement... F Milburn
//
Serial.println("------------------");
Serial.print ("Gain: ");
if (luxVal > 200.0)
{
tsl.setGain(TSL2591_GAIN_LOW);
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
Serial.println("1x (Low)");
Serial.println("Timing: 100 ms");
}
else if (luxVal <=200.0 && luxVal > 40.0)
{
tsl.setGain(TSL2591_GAIN_MED);
tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
Serial.println("25x (Med)");
Serial.println("Timing: 200 ms");
}
else if (luxVal <=40.0 && luxVal > 10.0)
{
tsl.setGain(TSL2591_GAIN_MED);
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
Serial.println("25x (Med)");
Serial.println("Timing: 600 ms");
}
else if (luxVal <=10.0 && luxVal > 0.1)
{
tsl.setGain(TSL2591_GAIN_HIGH);
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
Serial.println("428x (High)");
Serial.println("Timing: 600 ms");
}
else
{
tsl.setGain(TSL2591_GAIN_MAX);
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
Serial.println("9876x (Max)");
Serial.println("Timing: 600 ms");
}
}
Saturday, April 4, 2015
Adafruit BMP183 Sensor and MSP430 using Energia
I finally got the Adafruit BMP183 sensor to work with a MSP-EXP430F5529LP and Energia. I am using the Adafruit library and it almost works but not quite for the LaunchPad. The following changes are necessary:
#define BMP183_SDO P4_2 // AKA MISO
#define BMP183_SDI P4_1 // AKA MOSI
#define BMP183_CS P4_0
Adafruit_BMP183 bmp = Adafruit_BMP183(BMP183_CLK, BMP183_SDO,
BMP183_SDI,BMP183_CS);
- As you would expect, it is necessary to change pins for SPI. I used the following in the test sketch provided as an example by the library:
#define BMP183_SDO P4_2 // AKA MISO
#define BMP183_SDI P4_1 // AKA MOSI
#define BMP183_CS P4_0
Adafruit_BMP183 bmp = Adafruit_BMP183(BMP183_CLK, BMP183_SDO,
BMP183_SDI,BMP183_CS);
- The sketch won't compile as is because of a call to _delay_ms in Adafruit.BMP183.cpp provided in the library. I replaced all instances with the delay function.
- The sketch won't compile as is because of a call to the pow function in Adafruit.BMP183.cpp. The offending error is in the altitude calculation and occurs because of a bug in the gcc compiler used by Energia for the MSP430. Replace pow with powf and it should work.
Wednesday, March 11, 2015
Sites I Frequent
These are sites I frequently visit and can recommend. Here they are, in the order I more or less discovered them:
Arduino: The educational / hobbyist / maker movement has benefited greatly from Arduino. There is a lot of good stuff on their site and the internet is full of good (and not so good) support. This is a very good place to start if you are new to microcontrollers (but this is a blog about the TI LaunchPad series so let's move on)
SparkFun: I got started in microcontrollers with a "SparkFun Inventor's Kit" and SparkFun RedBoard (an Arduino Uno compatible). They have a large selection of hobbyist material and documentation for their products.
Adafruit: Great products. Great documentation. Great service. This is a really good place to go for Arduino, Raspberry Pi, and Beaglebone Black. Many of their products can also be used with the Texas Instrument Launchpads.
Texas Instruments: The Texas Instrument LaunchPad lineup offers incredible value and capability. Read more about them here.
Energia: Energia is a fork of Wiring and Arduino for various Texas Instruments LaunchPads - if you have some experience with the Arduino, this site is going to look familiar. And the great thing is that moving to Code Composer Studio, TI's full featured development environment, is available if you need the additional capability.
Mouser: I love these guys. If you need one 10 cent resistor they will ship it to you. And they carry an amazing array of products, all with datasheets - including the TI LaunchPad series.
Pololu: I recently started using Pololu for robot components and have been pleased. They have some interesting products with good range - especially in motors and motor controllers.
Addicore: They don't have as large a selection as the companies above but what they do have is great value (free shipping on orders larger than $25 too!). They are very quick and responsive - the best service I have received. You will also find some of their items on Amazon (at a slightly higher price).
Arduino: The educational / hobbyist / maker movement has benefited greatly from Arduino. There is a lot of good stuff on their site and the internet is full of good (and not so good) support. This is a very good place to start if you are new to microcontrollers (but this is a blog about the TI LaunchPad series so let's move on)
SparkFun: I got started in microcontrollers with a "SparkFun Inventor's Kit" and SparkFun RedBoard (an Arduino Uno compatible). They have a large selection of hobbyist material and documentation for their products.
Adafruit: Great products. Great documentation. Great service. This is a really good place to go for Arduino, Raspberry Pi, and Beaglebone Black. Many of their products can also be used with the Texas Instrument Launchpads.
Texas Instruments: The Texas Instrument LaunchPad lineup offers incredible value and capability. Read more about them here.
Energia: Energia is a fork of Wiring and Arduino for various Texas Instruments LaunchPads - if you have some experience with the Arduino, this site is going to look familiar. And the great thing is that moving to Code Composer Studio, TI's full featured development environment, is available if you need the additional capability.
Mouser: I love these guys. If you need one 10 cent resistor they will ship it to you. And they carry an amazing array of products, all with datasheets - including the TI LaunchPad series.
Pololu: I recently started using Pololu for robot components and have been pleased. They have some interesting products with good range - especially in motors and motor controllers.
Addicore: They don't have as large a selection as the companies above but what they do have is great value (free shipping on orders larger than $25 too!). They are very quick and responsive - the best service I have received. You will also find some of their items on Amazon (at a slightly higher price).
Subscribe to:
Comments (Atom)

