<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nick Fox</title>
	<atom:link href="http://quixand.co.uk/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://quixand.co.uk</link>
	<description>Blog taglines are so 2005...</description>
	<lastBuildDate>Mon, 10 Oct 2011 00:09:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Arduino Controlled Sun Tracking Solar Panel</title>
		<link>http://quixand.co.uk/?p=6</link>
		<comments>http://quixand.co.uk/?p=6#comments</comments>
		<pubDate>Sun, 09 Oct 2011 23:59:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[arduino solar tracker]]></category>

		<guid isPermaLink="false">http://quixand.co.uk/?p=6</guid>
		<description><![CDATA[So here it is, my Arduino controlled sun tracking solar panel. Ive spent the last few months building it and its been good fun. Im not going to bore you with details, you can email me or post a comment. Here are a pile of pictures, some brief descriptions of what I&#8217;ve done and most &#8230; </p><p><a class="more-link block-button" href="http://quixand.co.uk/?p=6">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>So here it is, my <a href="http://arduino.cc/">Arduino</a> controlled <a href="http://en.wikipedia.org/wiki/Solar_tracker">sun tracking solar panel</a>. Ive spent the last few months building it and its been good fun. Im not going to bore you with details, you can email me or post a comment. Here are a pile of pictures, some brief descriptions of what I&#8217;ve done and most importantly, things that went wrong! It&#8217;s certainly not the most refined project, there&#8217;s a chuppachups container and some duct tape in there somewhere, <a href="http://science.nasa.gov/science-news/science-at-nasa/2008/21apr_ducttape/">NASA would be proud</a>!</p>
<p>This is what the final product looks like, its mounted on my shed in the back garden and feeds a 96AH leisure battery through a solar charge controller(parts list at the bottom if your interested). The battery in turn feeds an inverter and also powers the Arduino and positioning motor(satellite dish linear actuator).</p>
<p style="text-align: center;"><img class="size-large wp-image-7 aligncenter" title="IMAG1080" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG1080-1024x613.jpg" alt="" width="584" height="349" /></p>
<p>So there was no specific design, I just had a general idea of a frame in my head, watched a few videos of solar trackers on Youtube and rummaged around in the shed for some wood. Found a few lengths of 2&#215;4, screwed them together so that the total outside width was the same as the solar panel. Of course I didn&#8217;t quite get that right the first time round. The triangle supports are just some cheap U-shaped aluminum, with a cross-brace to stop lateral movement of the wood frame and another aluminum brace to stop the panel moving laterally too.</p>
<p><a href="http://quixand.co.uk/?attachment_id=16" rel="attachment wp-att-16"><img class="aligncenter size-large wp-image-16" title="IMAG0089" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG0089-1024x613.jpg" alt="" width="590" height="353" /></a>Finally I added a 36v linear actuator that is designed for positioning satellite dishes, Ebay. This was not too difficult, though I had no idea how much movement I would need from the actuator. I just extended the actuator arm 50% out and mounted it on the frame so that the panel was flat, I figured that would give me equal movement in both directions. I then attached struts from the actuator arm to the panel at a length that would give the most movement without the panel bashing into the frame! This was not exact science.</p>
<p><a href="http://quixand.co.uk/?attachment_id=12" rel="attachment wp-att-12"><img class="aligncenter size-large wp-image-12" title="IMAG0981" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG0981-1024x613.jpg" alt="" width="590" height="353" /></a>I also waterproofed the frame with some leftover wood stain I used on my shed.</p>
<p><strong>Now for some electronics!</strong></p>
<p>The control mechanism is an arduino nano that is built onto a breadboard with a <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1202161385/1">SN754410 quad half bridge</a> and a 555 timer. The half bridge swaps the polarity output of power allowing the basic motor in the actuator to move in either direction based on the logic output from the ardiuno. The 555 timer deals with a reed sswitch in the actuator that engages as the linear screw turns, this allows indication when the actuator is moving, useful for detecting when the actuator is also at maximum or minimum extension. There are two 10k potentiometers that connect to 2 light dependent resistors allowing fine tuning of the light sensors once the frame is mounted on the shed roof. For detailed help there is a world of info on the arduino forum( <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1202161385/1">this should get you started</a> but a google search for &#8220;arduino dc motor control&#8221; should get you everything you need to know).</p>
<p><a href="http://quixand.co.uk/?attachment_id=20" rel="attachment wp-att-20"><img class="aligncenter size-large wp-image-20" title="IMAG0976_a" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG0976_a-1024x593.jpg" alt="" width="590" height="341" /></a>I was quite keen to understand what was happening and also have some control over the movement of the panel, not content with watching it move now and then I added a pile of LED&#8217;s and a few switches. The LEDs show the status of the controller and the switches allow me to change between auto and manual positioning and in manual mode I can move the panel one way or the other.</p>
<p style="text-align: center;"> <a href="http://quixand.co.uk/?attachment_id=23" rel="attachment wp-att-23"><img class="aligncenter size-large wp-image-23" title="IMAG0984" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG0984-613x1024.jpg" alt="" width="472" height="788" /></a></p>
<p> There are 2 industrial limit switches on the frame that detect the movement limit of the panel in either direction and feed back to the arduino.</p>
<p><a href="http://quixand.co.uk/?attachment_id=24" rel="attachment wp-att-24"><img class="aligncenter size-medium wp-image-24" title="IMAG0980" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG0980-300x179.jpg" alt="" width="300" height="179" /></a></p>
<p style="text-align: center;">This is the chupachups tube, it used to hold 6 lollies, my girlfriend had those. I drilled a hole in the bottom and threaded the two light dependent resistors through and seperated them with a slice of cardboard glued in place. Then sealed it with duct tape, which has another technical advantage of blocking out light from passing through the thin plastic and confusing the sensors.<a href="http://quixand.co.uk/?attachment_id=27" rel="attachment wp-att-27"><img class="aligncenter size-large wp-image-27" title="IMAG0979" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG0979-613x1024.jpg" alt="" width="590" height="985" /></a></p>
<p>So thats pretty much it for the panel, with all that stuffed on top the shed I had to reinforce the roof a bit, nothing special, found a few more planks of wood and braced the roof where the frame sits.</p>
<p>This is the setup inside the shed, the panel feeds into a solar charge controller which takes care of charging the battery and provides a stabilized 12v out. That then powers the Arduino which in turn feeds the actuator motor. I know the motor is 36v but it works fine on 12v, its not exactly lifting a heavy load. I also have a 1kw modified sine-wave inverter that provides 240v, though its not quite enough to handle the lawn mower, or the hoover.</p>
<p><a href="http://quixand.co.uk/?attachment_id=28" rel="attachment wp-att-28"><img class="aligncenter size-large wp-image-28" title="IMAG1078_a" src="http://quixand.co.uk/wp-content/uploads/2011/10/IMAG1078_a-1024x686.jpg" alt="" width="590" height="395" /></a></p>
<p>Parts List(not complete) pretty much all from Ebay!</p>
<ul>
<li>Arduino nano v3</li>
<li>2 x ip55 industrial limit switches</li>
<li>a few meters of U-shape aluminum</li>
<li>several meters of various electrical cable 4-core 2-core etc</li>
<li>sn754410 quad half bridge IC</li>
<li>555 timer IC</li>
<li>2&#215;4 wood for frame</li>
<li>project box (Maplin)</li>
<li>LEDs, switches</li>
<li>lots of screws, a few bolts</li>
<li>1 x 100w photovoltaic solar panel</li>
<li>solar charge controller generic 30A, there&#8217;s loads on Ebay</li>
</ul>
<p>You might also want to view the Arduino code:<br />
<code></p>
<p>#include <dht.h></p>
<p>dht DHT;</p>
<p>// =========<br />
// = Debug =<br />
// set to true to output extra debugging info,<br />
// will fill up the logs pretty quick though, not recommended for deployment<br />
const boolean debugOut = true;<br />
// const boolean debugOut = false;</p>
<p>// =========<br />
// ================<br />
// = Digital pins =<br />
// ================<br />
// digital pin for DHT11<br />
#define DHT11_PIN 4</p>
<p>// set pin numbers:<br />
// const int ledPin =  13;      // the number of the LED pin<br />
const int motorPWM =  12; // pwm control speed H-Bridge pin 1,2EN<br />
const int motor1 =  11; // motor out pins<br />
const int motor2 =  10; // motor out pins</p>
<p>// movement limit switchs<br />
const int limitSwitch1 = 2;<br />
const int limitSwitch2 = 3;</p>
<p>// low light indicator(orange)<br />
const int lowLightIndicatorLED = 9;</p>
<p>// Auto/manual<br />
const int autoManualSwitch = 5; // auto = HIGH manual = LOW<br />
const int autoManualMove1 = 6;<br />
const int autoManualMove2 = 7;</p>
<p>// =================<br />
// = Analogue pins =<br />
// =================<br />
// Analogue pins LDRs<br />
const int ldrA0 = 0;<br />
const int ldrA1 = 3;</p>
<p>// ================<br />
// = general vars =<br />
// ================<br />
// light limits 0 - 1023<br />
// const int equalLight = 800; not used<br />
const int lowLight = 200; // if either sensor registeres less than $lowLight no movement occurs<br />
const int tolerance = 50; // if the difference between each sensor is greater than $tolerance then reposition array</p>
<p>// movement resolution i.e. smalles amount of time between sensor readings while array is moving<br />
const int motorMoveFrame = 500; //  m'sec, more than 2 seconds could damage the array as it moves to close to the limit switches</p>
<p>// sub that sets the motor on/off bit on the H-Bridge, PWM<br />
String motorOnOff = String("off"); // or on </p>
<p>int ldrReadingA0;<br />
int ldrReadingA1;</p>
<p>void setup() {<br />
	// initialise motor pin out<br />
	pinMode(motor1, OUTPUT);<br />
	pinMode(motor2, OUTPUT);<br />
	// limit switches<br />
	pinMode(limitSwitch1, INPUT);<br />
	pinMode(limitSwitch2, INPUT);</p>
<p>	// low light<br />
	pinMode(lowLightIndicatorLED, OUTPUT);</p>
<p>	// Auto/Manual Switch<br />
	pinMode(autoManualSwitch, INPUT);<br />
	pinMode(autoManualMove1, INPUT);<br />
	pinMode(autoManualMove2, INPUT);</p>
<p>  // create serial output<br />
	Serial.begin(9600);<br />
	Serial.println("Begin Solar panel project, DC Motor H-Bridge Driver, LDRs");<br />
	Serial.println("Motor is " + motorOnOff);</p>
<p>	if(debugOut){<br />
		Serial.println("digitalRead(limitSwitch1):"); Serial.println(digitalRead(limitSwitch1));<br />
		Serial.println("digitalRead(autoManualSwitch):"); Serial.println(digitalRead(autoManualSwitch));<br />
		// Serial.println("lowLight:" + lowLight);<br />
		// Serial.println("tolerance:" + tolerance);<br />
		// Serial.println("motorMoveFrame:" + motorMoveFrame);</p>
<p>	}</p>
<p>}<br />
void loop(){<br />
	readSensors();</p>
<p>	while (digitalRead(autoManualSwitch) == LOW){<br />
		Serial.println("**Manual Movement Switch Engaged**");<br />
		// Manual: check manual switch selection<br />
		if (digitalRead(autoManualMove1) == HIGH || digitalRead(autoManualMove2) == HIGH){<br />
			ManualMove();<br />
		}<br />
		delay(1000); // 0.5sec<br />
	}<br />
	// Auto: got enough light?<br />
	if (ldrReadingA0 > lowLight &#038;&#038; ldrReadingA1 > lowLight){<br />
		digitalWrite(lowLightIndicatorLED,LOW);<br />
		moveArray();<br />
	}else{<br />
		Serial.println("Light level too low");<br />
		digitalWrite(lowLightIndicatorLED,HIGH);<br />
	}</p>
<p>	// motor off<br />
	analogWrite(motorPWM, 0);<br />
	Serial.println("Motor off");</p>
<p>	// read DHT11 temperature and humidity<br />
	readDHT11();</p>
<p>	delay(500); // 0.5sec<br />
}</p>
<p>void ManualMove(){</p>
<p>	if (digitalRead(autoManualMove1) == HIGH){<br />
		motorForwards();<br />
		while(digitalRead(autoManualMove1) == HIGH &#038;&#038; digitalRead(limitSwitch1) == LOW){<br />
			delay(motorMoveFrame);<br />
			readSensors();<br />
		}<br />
		analogWrite(motorPWM, 0);<br />
		Serial.println("Motor off");<br />
	}<br />
	if (digitalRead(autoManualMove2) == HIGH){<br />
		motorBackwards();<br />
		while(digitalRead(autoManualMove2) == HIGH &#038;&#038; digitalRead(limitSwitch2) == LOW){<br />
			delay(motorMoveFrame);<br />
			readSensors();<br />
		}<br />
		analogWrite(motorPWM, 0);<br />
		Serial.println("Motor off");<br />
	}</p>
<p>}</p>
<p>void moveArray(){</p>
<p>	if (ldrReadingA0 > ldrReadingA1){<br />
		// might need to move array..<br />
		if ((ldrReadingA0 - ldrReadingA1) > tolerance){<br />
			// yep, ldrReadingA0 is above tolerance so move it!<br />
			if (stillOkToMoveForwards()){ motorForwards(); }<br />
			// poop, this is too sensitive, need to move array so sensors match then exit "move" sub back to wider tollerance, other wise array will keep moving<br />
			// while((ldrReadingA0 - ldrReadingA1) > tolerance  &#038;&#038; digitalRead(limitSwitch1) == LOW &#038;&#038; ldrReadingA0 > lowLight &#038;&#038; ldrReadingA1 > lowLight){<br />
			while(stillOkToMoveForwards()){<br />
				delay(motorMoveFrame);<br />
				readSensors();<br />
			}<br />
		}<br />
	}<br />
	if (ldrReadingA0 < ldrReadingA1){<br />
		// might need to move array..<br />
		if ((ldrReadingA1 - ldrReadingA0) > tolerance){<br />
			// yep, ldrReadingA0 is above tolerance so move it!<br />
			if (stillOkToMoveBackwards()){ motorBackwards(); }<br />
			// while((ldrReadingA1 - ldrReadingA0) > tolerance  &#038;&#038; digitalRead(limitSwitch2) == LOW &#038;&#038; ldrReadingA0 > lowLight &#038;&#038; ldrReadingA1 > lowLight){<br />
			while(stillOkToMoveBackwards()){<br />
				delay(motorMoveFrame);<br />
				readSensors();<br />
			}<br />
		}<br />
	}<br />
}<br />
boolean stillOkToMoveForwards(){<br />
	if (ldrReadingA0 > ldrReadingA1<br />
		&#038;&#038; digitalRead(limitSwitch1) == LOW<br />
		&#038;&#038; ldrReadingA0 > lowLight<br />
		&#038;&#038; ldrReadingA1 > lowLight<br />
		&#038;&#038; (digitalRead(autoManualSwitch))){<br />
			if(debugOut){ Serial.println("stillOkToMoveForwards():true"); }<br />
			return true;</p>
<p>		}<br />
		if(debugOut){ Serial.println("stillOkToMoveForwards():false"); }<br />
		return false;<br />
}<br />
boolean stillOkToMoveBackwards(){<br />
	if (ldrReadingA1 > ldrReadingA0<br />
		&#038;&#038; digitalRead(limitSwitch2) == LOW<br />
		&#038;&#038; ldrReadingA0 > lowLight<br />
		&#038;&#038; ldrReadingA1 > lowLight<br />
		&#038;&#038; (digitalRead(autoManualSwitch))){<br />
			if(debugOut){ Serial.println("stillOkToMoveBackwards():true"); }<br />
			return true;</p>
<p>		}<br />
		if(debugOut){ Serial.println("stillOkToMoveBackwards():false"); }<br />
		return false;<br />
}<br />
void motorForwards(){<br />
	// movement limit in this direction reached?<br />
	if(digitalRead(limitSwitch1) == LOW){<br />
		analogWrite(motorPWM, 240);<br />
		Serial.println("Motor on, moving forwards");<br />
		digitalWrite(motor1, LOW);<br />
		digitalWrite(motor2, HIGH);<br />
		Serial.println("Motor pins 0 1");<br />
	}else{ Serial.println("--- limitSwitch1 engaged ---"); }<br />
}<br />
void motorBackwards(){<br />
	// movement limit in this direction reached?<br />
	if(digitalRead(limitSwitch2) == LOW){<br />
		analogWrite(motorPWM, 240);<br />
		Serial.println("Motor on, moving backwards");<br />
		digitalWrite(motor2, LOW);<br />
		digitalWrite(motor1, HIGH);<br />
		Serial.println("Motor pins 1 0");<br />
	}else{ Serial.println("--- limitSwitch2 engaged ---"); }<br />
}</p>
<p>void readSensors(){<br />
	ldrReadingA0 = analogRead(ldrA0);<br />
	ldrReadingA1 = analogRead(ldrA1);<br />
	Serial.print("read ldr0=");<br />
	Serial.print(ldrReadingA0);<br />
	Serial.print(" read ldr1=");<br />
	Serial.println(ldrReadingA1);<br />
}<br />
void readDHT11(){<br />
  // READ DATA, min 2 secs due to sensor output constraints<br />
  Serial.print("DHT11\t");<br />
  int chk = DHT.read11(DHT11_PIN);<br />
  switch (chk)<br />
  {<br />
    // case 0:  Serial.print("OK,\t"); break;<br />
    case 0: break; // ok? don't print anything<br />
    case -1: Serial.print("Checksum error,\t"); break;<br />
    case -2: Serial.print("Time out error,\t"); break;<br />
    default: Serial.print("Unknown error,\t"); break;<br />
  }<br />
 // DISPLAT DATA<br />
  Serial.print("DHT.humidity\%=\"");<br />
  Serial.print(DHT.humidity,1);<br />
  Serial.print("\"\tDHT.temperature (c)=\"");<br />
  Serial.print(DHT.temperature,1);<br />
  Serial.println("\"");</p>
<p>  delay(2000);<br />
}</p>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://quixand.co.uk/?feed=rss2&#038;p=6</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

