Jump to content
43oh

Solar Driveway Light to MSP430 Wireless Sensor Node


Recommended Posts

Greetings!  I am new to the forum and this is my first solo microcontroller project.  Please be kind to me as I am a Geographer and by no means a programmer or electrical engineer.  Stupid questions should be expected.    
 
The basic idea of this project is to convert a $3-4 solar light found at Lowes and Home Depot hardware store (here in the US) into a wireless remote sensor node.  The node will utilize an MSP430G2553 MCU and a nRF24L01+(w/ spirilis library) wireless module to send light intensity (photoresitor that came with solar driveway light), soil moisture (design from http://gardenbot.org), and soil temperature data (10k thermistor coated in silicon) wirelessly from my garden to another MSP430G2553 and nRF24L01+ sitting on top of a Raspberry Pi.  This data will then be sent over the Raspberry Pi UART to a python script running on the Raspberry Pi which logs the data into a CSV and JSON file (code inspired by Uberfridge).  An Apache server will also run on the Rapsberry Pi and the JSON data will be displayed via the Javascript Flot chart library.  The node on the Raspberry Pi will also have a transistor that switches a water Solenoid attached to my garden hose based upon the soil moisture.        
 
Photo 1.  The $4 light from Lowes Hardware.  Portfolio Landscape brand Model #0379420 (http://tinyurl.com/cn4e684)
post-3-0-74508300-1363834948_thumb.jpg
 
Photo 2.  I like that it has a nice battery compartment and comes with a 800Mah AA Battery.  
post-3-0-68239100-1363834947_thumb.jpg
 
 
Photo 3.  The inside of the light.  Contains a chip which boosts the 1.2v battery to 5.0v to power the LED.  Comes with an inductor and diode that can be reused.
post-3-0-64357800-1363834946_thumb.jpg
 
I taught myself Eagle Autocad and created a schematic/board to replace the stock board inside the solar light.  My board utilizes a Texas Instrument TPS61097 (free sample) which converts the 1.2v from the batter to 3.3v to power the MSP430.  Version 1 of the board is shown below with just the power circuitry populated (Photo 6).   I put a jumper wire on the TPS61097 between the EN and VIN because I wasn't able to get the bypass switch (Page 16 of the schematic http://www.ti.com/lit/ds/symlink/tps61097-33.pdf ) to work correctly.  I had 200k resistors on R1 and R2 (actually 2x100k 1% in series each...didn't have any 200k on hand) which didn't work (bypass switch stays on) so I jumpered EN and VIN and now get the full 3.3v.  I would like to get this bypass feature enabled.  Any ideas where I am going wrong here?  I assume the resistor values are incorrect for the 1.2v battery.    
 
Photos 4 and 5.  Board Mockups from OSHPark
          post-3-0-59529600-1363834945_thumb.pngpost-3-0-48414200-1363834944_thumb.png
 
Photo 6.  V1.0 of the board received 3/20/2013. Partially populated (no time!!!).  Two green wires are from stock photoresistor (not yet connected).
post-3-0-52972700-1363834943_thumb.jpg
 
Photo 7.  Schematic for v1.0
post-3-0-78557000-1363834938_thumb.png
 
Current Project Status:  Basic code for Raspberry Pi done (python and Flot charting), code written that reads sensors and sends comma delimited sensor data over Raspberry Pi UART,  v1.0 solar light board done and receive today from OSHPark (3/20/2013).
 
Current Activities:  Waiting for my second child to be born and testing the charging and booster circuit. 
 
Still to do:  Get nRF24L01+code working with my existing code and design Raspberry Pi Node (current version on rough protoboard board).   I did start playing with my nRF24L01+ modules and was able to send my name through the character buffer array.  I need to find the best way to send this data through the nRF24L01+ module and print it to the UART attached to the Raspberry Pi.     
 
I hope you guys enjoy my project idea and with your help I will hopefully finish.  I will post schematics/boards, code, etc when it is more complete.  My wife is due next week so things will likely progress slowly.   
 
The code I do post will likely be messy.  If you like my project feel free to help me clean it up but please do explain whatever you do in layman terms.  I am not as lay as I use to be with electronics/programming but much more lay than most of you folks!  Cheers!

Edited by geodave
Images uploaded.to 43oh. Please upload to 43oh next time.
Link to post
Share on other sites
  • Replies 42
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Greetings!  I am new to the forum and this is my first solo microcontroller project.  Please be kind to me as I am a Geographer and by no means a programmer or electrical engineer.  Stupid questions s

Nice project & code!  One word of caution with the nRF24 handler code (your main while(1) loop)--   w_tx_payload(32, buf); msprf24_activate_tx(); LPM4; // Put the RF transceiver back

Baby boy was born and I have been sick for a week and a half so that has slowed my progress.  I did play with the bypass switch on the DC booster and came to the conclusion that I need to reduce the t

Posted Images

This is a brilliant idea. What does the bypass feature allow you to do?

Thanks! Bypass feature turns off the voltage booster when battery power drops below a certain voltage (threshold determined by the resistors). Presumably this would save some power though I am not sure this will be an issue as I only plan to log data every half hour to an hour...so it won't use much power anyway.

Link to post
Share on other sites

Looks cool. Questions:

 

Could you provide voltage levels at EN when you had the resistors connected?

 

Also is your pushbutton switch condensation proof? A little water in there could hold your project in RESET.

Voltage level was equal to the battery which seems to indicate that it was enabled.

 

I suppose the button is a good point. Not sure how much condensation to expect. It is weatherproofed to a certain extent. Do you think it would be best to just remove the reset?

Link to post
Share on other sites

Geodave,

  I was actually wondering what you measure at EN (between the resistors). According to the datasheet, your if EN is < 0.65V bypass is enabled. So if your battery (VIN) is putting out only 1.2v and you divide it by 2, your bypass will always be enabled. I think you should just attach a pot in place of one of your resistors.

 

I'm not an expert on weather proofing but I know the devices my client puts underground all have conformal coating of some kind. I think you would want some kind of membrane sealed switch if you really wanted one out in the field.

Link to post
Share on other sites

Two things. Could you have simply modified the boost circuit instead of replacing it for a TPS61097? And Two, if you find a 2 battery solar light, it would probably be better/easier to convert. Last longer too, depending on the setup.

Link to post
Share on other sites

Nice project!

I figure JP4 is for programming, but be aware that you'd need to have common ground (GND) between the programmer and the target chip to get it working. I suggest you add a third pin and tie it to GND.

Most designs suggest using a 2.2nF capacitor from reset to ground (basically keeping the chip in reset a tiny amount of time to allow voltage to get more stable).

A reset button is not required in this case I guess, as the switch is just as accessible as the battery; removing the battery for a little while should also do the trick, though with very low power design it could take a while to actually discharge (the 10uF capacitors) to really switch off. Alternatively use a jumper which you "park" on a single pin, then short the pins to reset. Or have it directly in the MSP430 VCC line, so capacitor discharge isn't of importance anymore.

Link to post
Share on other sites

Thanks! Bypass feature turns off the voltage booster when battery power drops below a certain voltage (threshold determined by the resistors). Presumably this would save some power though I am not sure this will be an issue as I only plan to log data every half hour to an hour...so it won't use much power anyway.

 

Just one thing I am wondering about, and I am no expert. Couldn't you get away with checking the soil moister level once a day ? Say at noon-ish ?

 

We live in Arizona, ~6k feet above sea level, the wind here can be pretty busy at times, and it can also be fairly arid here. Needless to say, when the soil in our garden is not fully saturated, the combination of the wind, and general dryness of the air *can* suck moister right out of the soil. Once fully saturated however, the moister tends to stay in the ground ( 6 inches down ) for at least several days.

 

So, again no expert here, and very curious.

 

Definitely a cool / useful project.

Link to post
Share on other sites

Geodave,

  I was actually wondering what you measure at EN (between the resistors). According to the datasheet, your if EN is < 0.65V bypass is enabled. So if your battery (VIN) is putting out only 1.2v and you divide it by 2, your bypass will always be enabled. I think you should just attach a pot in place of one of your resistors.

 

I'm not an expert on weather proofing but I know the devices my client puts underground all have conformal coating of some kind. I think you would want some kind of membrane sealed switch if you really wanted one out in the field.

 

I will play with the bypass resistors tonight after work.  I like the pot idea.

 

A couple friends of mine have had a different model (same brand) of these controllers in their yards for about a year and they are still going strong.  I am not too concerned about the weather proofing as they are desgined to be outside.  I am a little concerned about the mechanical reset switch.  I don't think I really need the switch...it can just be handy to have.   

Link to post
Share on other sites

Two things. Could you have simply modified the boost circuit instead of replacing it for a TPS61097? And Two, if you find a 2 battery solar light, it would probably be better/easier to convert. Last longer too, depending on the setup.

Thanks for the feedback!  Maybe...it would required a way to step down the volatge 50.v to 3.6v or less (maybe using some diodes?)...or you could use an Arduino. 

 

What would be the advantage to two batteries?  I only plan to turn this on once or two times an hour if that so I don't expect a large power draw. 

Link to post
Share on other sites

Nice project!

I figure JP4 is for programming, but be aware that you'd need to have common ground (GND) between the programmer and the target chip to get it working. I suggest you add a third pin and tie it to GND.

Most designs suggest using a 2.2nF capacitor from reset to ground (basically keeping the chip in reset a tiny amount of time to allow voltage to get more stable).

A reset button is not required in this case I guess, as the switch is just as accessible as the battery; removing the battery for a little while should also do the trick, though with very low power design it could take a while to actually discharge (the 10uF capacitors) to really switch off. Alternatively use a jumper which you "park" on a single pin, then short the pins to reset. Or have it directly in the MSP430 VCC line, so capacitor discharge isn't of importance anymore.

 

 

Thanks @roadrunner84.  Yea, that was the intention of JP4.  I probably should have tested programming the chip outside the launchpad before I added the porgramming pins (it was a last minute thing and I have never done it before).  Thanks for the heads up!

 

I will revisit the reset switch based upon your comments and repost the schematic when I finish. 

Link to post
Share on other sites

Just one thing I am wondering about, and I am no expert. Couldn't you get away with checking the soil moister level once a day ? Say at noon-ish ?

 

We live in Arizona, ~6k feet above sea level, the wind here can be pretty busy at times, and it can also be fairly arid here. Needless to say, when the soil in our garden is not fully saturated, the combination of the wind, and general dryness of the air *can* suck moister right out of the soil. Once fully saturated however, the moister tends to stay in the ground ( 6 inches down ) for at least several days.

 

So, again no expert here, and very curious.

 

Definitely a cool / useful project.

Thanks for the comments @yyrkoon.  I haven't really decided on the timing yet.  You are probably correct that the sampling rate it too high.  My plan is trial and error once I get a working version going. 

 

There are lots of concerns I have with the crude soil sensor.  For example, resistance changes with temperature but I am not sure to what extent.  I have found some equations that take into account soil temp, resistance, and soil type to determine the soil moisture level.  You can adjust the coefficients in that equation based on the crop type to get an idea moisture value.  See http://www.usu.edu/cpl/PDF/WatermarkOperatingInstructions2.pdf   Not sure how well this will translate with my current setup.

Link to post
Share on other sites

I will play with the bypass resistors tonight after work.  I like the pot idea.

 

A couple friends of mine have had a different model (same brand) of these controllers in their yards for about a year and they are still going strong.  I am not too concerned about the weather proofing as they are desgined to be outside.  I am a little concerned about the mechanical reset switch.  I don't think I really need the switch...it can just be handy to have.   

 

For environments where moistire is a problem I've found that reed switches ( as per some alarm sytem semsors) are a good deal , hermetically sealed and water proof , only downside is, being glass envelope, they are not shock proof , although they generally need a fairly heavy shock to break , You also need a magnet to operate them :-) 

Link to post
Share on other sites
  • 2 weeks later...

Baby boy was born and I have been sick for a week and a half so that has slowed my progress.  I did play with the bypass switch on the DC booster and came to the conclusion that I need to reduce the total resistance over R2 and R3 to 340kohms down from 400kohms.  This seems to work well, though, I haven't been able to determine the exact switching voltage because the datasheet is confusing in that regard.  I think it is turning on the voltage bypass switch at between 1.1 and 1.2v.        

 

I have been reading about character arrays and sprintf and trying to come up with a good way to pass the sensor data to the nRF24L01+.  I have been able to successfully pass data using the tx code I wrote below.  I am using another MSP430 and  nRF24L01+ pair and Ike's basic rx example to display the buf char array in the Expression tab in CCS Debug mode.  I can see the correct data with the ; delimiter so I know it is working.  I am currently trying to figure out the most efficient way to simply echo the buffer data over the UART in comma delimited form.  I have been looking at spirilis code which sends temperature data over UART (http://forum.43oh.com/topic/2050-nrf24l01-registerscommands-and-functionswork-in-progress/).  It has been helpful but I still don't have a good idea of how I will accomplish this task.  

 

This is the tx code I came up with which works okay except I haven't been able to get my thermister code to work:

#include "msp430g2553.h"
#include "msprf24.h"
#include "nrf_userconfig.h"
#include "stdio.h" //for sprintf

const char txaddr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00};

void main(void)
{
	//Setup Clocks
  DCOCTL = CALDCO_1MHZ; //Internal oscillators frequency
  BCSCTL1 |= DIVA_1;                        // ACLK/8 - wake up about every 26 seconds (WHEN DIVA_3 - about 6 seconds for DIV 1)
  BCSCTL2 = DIVS_0;  // SMCLK = DCOCLK/0 - SPI (USCI) uses SMCLK, prefer SMCLK < 10MHz (SPI speed limit for nRF24 = 10MHz)
  BCSCTL3 |= LFXT1S_2;                      // ACLK = VLO

  //Initiate Watchdog Timer
  WDTCTL = WDT_ADLY_1000;                   // Interval timer - 1000ms
  IE1 |= WDTIE;                             // Enable WDT interrupt

  //Set inputs/outputs
  P2DIR = BIT0 + BIT1;  //2.0 and 2.1 Output

  //Initiate Wireless Module - Initial values for nRF24L01+ library config variables
  rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit
  rf_addr_width      = 5;
  rf_speed_power     = RF24_SPEED_1MBPS | RF24_POWER_0DBM;
  rf_channel         = 120;

  msprf24_init();  // All RX pipes closed by default
  msprf24_set_pipe_packetsize(0, 32);
  msprf24_open_pipe(0, 1);  // Open pipe#0 with Enhanced ShockBurst enabled for receiving Auto-ACKs

  //Main Loop
  while(1)
  {
    //Delay sensor read and transmission
    static int delay = 0;
	delay++;
	if (delay == 1){   // 26 seconds for each 1 delay - when BCSCTL1 |= DIVA_3
		char buf[32];

		// Online the nRF24L01+ transceiver
		msprf24_standby();
		flush_tx();

		//Compose RF Message
		int MCU = chip_temp();
		//int Temp = soil_temp(); //(ISSUE!)
		int Soil = soil_moist();
		int Sun = light_sensor();
		sprintf(buf, "%d;%d;%d;%d", Sun, Soil, Temp, MCU);

		//Setup radio and transmit message
		w_tx_addr( (char*)txaddr );
		w_rx_addr(0, (char*)txaddr );  // Pipe 0 receives auto-ack's, autoacks are sent back to the TX addr so the PTX node // needs to listen to the TX addr on pipe#0 to receive them.
		w_tx_payload(32, buf);
		msprf24_activate_tx();
		LPM4;

		// Put the RF transceiver back to sleep
		msprf24_powerdown();
		delay = 0;
	}

    _BIS_SR(LPM3_bits + GIE);               // Enter LPM3
  }
}

#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer (void)
{
  _BIC_SR_IRQ(LPM3_bits);                   // Clear LPM3 bits from 0(SR)
}

 

Here is my nRF24L01+ configuration code:

/* nrf_userconfig.h
 * User configuration of nRF24L01+ connectivity parameters, e.g.
 * IRQ, CSN, CE pin assignments, Serial SPI driver type
 *
 *
 * Copyright (c) 2012, Eric Brundick <spirilis@linux.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose
 * with or without fee is hereby granted, provided that the above copyright notice
 * and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
 * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _NRF_USERCONFIG_H
#define _NRF_USERCONFIG_H

/* CPU clock cycles for the specified amounts of time--accurate minimum delays
 * required for reliable operation of the nRF24L01+'s state machine.
 */
/* Settings for 1MHz MCLK.
#define DELAY_CYCLES_5MS       5000
#define DELAY_CYCLES_130US     130
#define DELAY_CYCLES_15US      15
 */

/* Settings for 8MHz MCLK.
#define DELAY_CYCLES_5MS       40000
#define DELAY_CYCLES_130US     1040
#define DELAY_CYCLES_15US      120
 */

/* Settings for 16MHz MCLK */
#define DELAY_CYCLES_5MS       80000
#define DELAY_CYCLES_130US     2080
#define DELAY_CYCLES_15US      240

/* Settings for 24MHz MCLK.
#define DELAY_CYCLES_5MS       120000
#define DELAY_CYCLES_130US     3120
#define DELAY_CYCLES_15US      360
 */

/* SPI port--Select which USCI port we're using.
 * Applies only to USCI devices.  USI users can keep these
 * commented out.
 */
//#define RF24_SPI_DRIVER_USCI_A 1
#define RF24_SPI_DRIVER_USCI_B 1

/* Define whether this library should use LPM0+IRQs during SPI I/O and whether this library should provide the ISR. */
#define RF24_SPI_DRIVER_USCI_USE_IRQ 1
#define RF24_SPI_DRIVER_USCI_PROVIDE_ISR 1


/* Operational pins -- IRQ, CE, CSN (SPI chip-select)
 */

/* IRQ */
#define nrfIRQport 2
#define nrfIRQpin BIT4

/* CSN SPI chip-select */
#define nrfCSNport 2
#define nrfCSNportout P2OUT
#define nrfCSNpin BIT3

/* CE Chip-Enable (used to put RF transceiver on-air for RX or TX) */
#define nrfCEport 2
#define nrfCEportout P2OUT
#define nrfCEpin BIT5

#endif

 

I put my ADC code into a separate c file to keep things clean on my main.c:

 

#include  "msp430g2553.h"
#include "math.h"

void disable_adc(void)
{
	ADC10CTL0 &= ~ENC;
	ADC10CTL0 &= ~ADC10IFG;
	ADC10CTL0 &= ~REFON + ADC10ON;
}

void config_adc(void)
{
  // Use Vcc/Vss for Up/Low Refs, 16 x ADC10CLKs, turn on ADC
    ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10ON;
}

int light_sensor() {
	unsigned adc;

	disable_adc();
	config_adc();
	// A1 input, use ADC10CLK div 1, single channel mode
	ADC10CTL1 =  INCH_0 + ADC10DIV_3;
	ADC10AE0 = BIT0;      // Enable ADC input on P1.0
	ADC10CTL0 |= ENC + ADC10SC;     // Enable conversions.start a new conversion

	while (!(ADC10CTL0 & ADC10IFG))
			        /* wait until conversion is completed */ ;

	adc = ADC10MEM;

	while (ADC10CTL1 & ADC10BUSY);   // wait for conversion to end
	disable_adc();

	return adc;
}

int soil_temp() {
	unsigned adc;

	disable_adc();
	config_adc();
	// A1 input, use ADC10CLK div 1, single channel mode
	ADC10CTL1 =  INCH_4 + ADC10DIV_3;
	ADC10AE0 = BIT4;      // Enable ADC input on P1.4
	ADC10CTL0 |= ENC + ADC10SC;     // Enable conversions.start a new conversion

	while (!(ADC10CTL0 & ADC10IFG))
			        /* wait until conversion is completed */ ;

	adc = ADC10MEM;

	//while (ADC10CTL1 & ADC10BUSY);   // wait for conversion to end
	disable_adc();

	double R, T;

	// These were calculated from the thermister data sheet
	//	A = 2.3067434E-4; Vishay A: 1.14061e-3
	//	B = 2.3696596E-4; Vishay B: 2.32134e-4
	//	C = 1.2636414E-7; Vishay C: 9.63666e-8
	//
	// This is the value of the other half of the voltage divider
	int Rknown = 10000;

	// Do the log once so as not to do it 4 times in the equation
	//	R = log(((1024/(double)aval)-1)*(double)22200);
	//R = log((1 / ((1024 / (double) raw) - 1)) * (double) 10000);

	R = log(Rknown / ((1023.0f / (float)adc) - 1.0f));

	// Compute degrees K
	 T = 1.0f / ((9.63666e-8 * R * R + 2.32134e-4) * R + 1.14061e-3);

	 // return degrees F
	 int Temp = ((T - 273.15f) * (9.0f / 5.0f)) + 32.0f;

	 return Temp;
}

int chip_temp() {
	unsigned adc;

	disable_adc();
	config_adc();
	// A1 input, use ADC10CLK div 1, single channel mode
	ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON;
	ADC10CTL1 = INCH_10 + ADC10DIV_3;
	ADC10CTL0 |= ENC + ADC10SC;


	while (!(ADC10CTL0 & ADC10IFG))
			        /* wait until conversion is completed */ ;

	adc = ADC10MEM;
	disable_adc();

	// return degrees F
	return (int)((adc * 48724L - 30634388L) >> 16);
}

void setSensorPolarity(int flip){
  if(flip == 0){
    P2OUT |= BIT0;
    P2OUT &= ~BIT1;
  }else{
	P2OUT |= BIT1;
	P2OUT &= ~BIT0;
  }
}

int soil_moist(){

		unsigned adc;

		disable_adc();
		config_adc();
		// A1 input, use ADC10CLK div 3
		ADC10CTL1 =  INCH_3 + ADC10DIV_3;
		ADC10AE0 = BIT3;      // Enable ADC input on P1.3
		ADC10CTL0 |= ENC + ADC10SC;     // Enable conversions.start a new conversion
		while (!(ADC10CTL0 & ADC10IFG))
		        /* wait until conversion is completed */ ;

		adc = ADC10MEM;

		while (ADC10CTL1 & ADC10BUSY);   // wait for conversion to end
		disable_adc();

		setSensorPolarity(0);
		__delay_cycles(2500);
		setSensorPolarity(1);
		__delay_cycles(2500);

		return adc;
}

 

 

Any questions, concerns, comments would be greatly appreciated.  Be kind as I am a lowly geographer and I just started to teach myself programming.   

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...