THE MECHANICS
The mechanic I mad is just an example, I used a CNC to carve MDF wood.
One of the most important part of the project is the mechanic, thanks to that, the panel will turn wherever we want it to turn.
To design the mechanic of Solarturn, I used Solidworks. In order to move the panel, we will make a wooden structure in two parts :
The first one is basically a box, it’s where we will hide wires, components and the battery.
The goal of the second one is to be able to move the panel vertically and horizontally. Like so, the solar panel could be under solar radiation all the day long.
To make your own design you have two choices :
- You can modelize with a 3D software like Solidworks or Autodesk Fusion and then export it to a vector graphic edition software (like Illustrator or Inkscape).
- You can directly draw your designs into your graphic software.
I recommend you to use the first solution, the second one is a little bit risky for the rate of your draws.
After realising your shematics i used a CNC laser to carve wood into mecanical pieces.
The box ;
Firstly you will need a box to hide all the components and support and rotate the panel.
The “hole” on one side of the box is a for placing a hand-knob, for it i advise you to make tree parts (trapdoor, a magnet support and cotter pin).
The upper side of the box is maintaining the upper structure.
The upper structure;
The upper structure is holding the panel and the photo-resistor and it's rotative in two ways.
One to tilt the panel thanks to two wooden gears and the other to rotate the entire upper structure.
To help the rotation I used few ball bearings
Two side of the box
The “hole” on one side of the box is a for placing a handknob, here are the parts of it (trapdoor, magnet support and cotter pin).
The upper side of the box is maintaining the upper structure.
For reinforce the part I designed two little pieces.
Here are some photos to understand how it's made :
The upper structure is holding the panel and moving it :
The files I made are in attachments.
THE SOFTWARE
For the development of the project we will use Energia. Energia is an Arduino based software for TI LaunchPad Development kit. The code is basically C with Arduino library, as if it would be on Arduino.
In this tutorial we’ll use Energia 1.6.10E18 for OSX and the drivers for the MSP432P401R.
Link to download Energia : http://energia.nu/download/
Drivers are available to download on the Board Manager (Tools>Board>Board Manager).
RECEIVE DATA FROM PHOTOSENSORS
The first step to make a solar tracker is to know where the sun is. In order to get that, you should get photoconductive cell from the VT800 series. We will use the simplest way to know where the sun is : an array of four sensors.
To get to know where there is the most of light on the system we will just get the difference between the sensors.
I named them from 0 to 3 :
THE WIRING
You just have to make a tension divider bridge to receive data to the MSP432. Thanks to the datasheet of the cells we know that I should use a resistance of 1,5kOhm.
Here is the schematics :
Beware of where you plug your sensors to the MSP, I choosed the A13/A11/A9 and A5 pins because they are analog pins (we will use them to read the data with analogRead() function).
THE CODE
First we”ll make a simple code to check if all the wiring is correct, it is just basically read and print into the serial monitor the data received by the MSP.
int p0 = A14, p1 = A6, p2 = A8, p3 = A13;
int photocellReading0 = 0, photocellReading1 = 0, photocellReading2 = 0, photocellReading3 = 0;
int d0, d1, d2, d3;
int tolerance = 200;
void setup(void) {
// We'll send debugging information via the Serial monitor
Serial.begin(9600);
}
void loop(void) {
photocellReading0 = analogRead(p0);
photocellReading1 = analogRead(p1);
photocellReading2 = analogRead(p2);
photocellReading3 = analogRead(p3);
Serial.print("Analog reading0 = ");
Serial.println(photocellReading0); // the raw analog reading
Serial.print("Analog reading1 = ");
Serial.println(photocellReading1); // the raw analog reading
Serial.print("Analog reading2 = ");
Serial.println(photocellReading2); // the raw analog reading
Serial.print("Analog reading3 = ");
Serial.println(photocellReading3); // the raw analog reading
Serial.println("-----------------------------------------------------------------");
delay(500);
}
You should get into the monitor data like this :
MOTORIZING THE PROJECT
The structure is motorised by two stepper motors (NEMA17) drived by two (DRV8825).
The DRV8825 will control nema steppers.
To use them correctly you have to set the current limit on “Vref/2”, here Vref is equal to 1,2V. To set the current limit to 0,6V you have to turn the screw on the top of the component like so :
When you finished to set your driver current limit, you will need to wire it to the MSP. Following the datasheet I wired like so :
On the project we have two stepper motors, you will just have to make the same wiring for the second motor.
Like for the photoconductive cells, beware of the wiring to the MSP432, here is a pin map of the project :
CONTROL NEMA 17 THANKS TO DRV8825 & MSP432
Now, we can receive data from the photoconductive cells and the panel is motorized, we will make the code.
It is basically a comparison of the difference like in the schematics below :
When the MSP gets the most lightened photocell, it will turn both nema motors toward the light till every photocell is equally lightened.
Here is the code :
CODE
#define stepPinh 5 // step pin from the upper motor
#define dirPinh 2 // direction pin from the upper motor
#define stepPinb 8 // step pin from the lower motor
#define dirPinb 6 // direction pin from the lower motor
int p0 = A5, p1 = A13, p2 = A11, p3 = A9;
int pr0 = p0, pr1 = p1, pr2 = p2, pr3 = p3; //sensor lecture pins
int d0, d1, d2, d3; // difference
int t = 200; // tolerence
int pas = 900;
void setup(void){
Serial.begin(9600);
pinMode(dirPinh, OUTPUT);
pinMode(stepPinh, OUTPUT);
pinMode(dirPinb, OUTPUT);
pinMode(stepPinb, OUTPUT );
}
void loop(void) {
pr0 = analogRead(p0), pr1 = analogRead(p1), pr2 = analogRead(p2), pr3 = analogRead(p3);
d0 = pr0 - pr1, d1 = pr1 - pr3, d2 = pr3 - pr2, d3 = pr2 - pr1;
int i=0;
if ((abs(d0) <= t) && (abs(d1) <= t) && (abs(d0) <= t) && (abs(d1) <= t)){
// ne rien faire
Serial.println("Positionement bon");
digitalWrite(stepPinh, LOW); digitalWrite(stepPinb, LOW); // Initialisation of the step pins
}
else {
if( (pr0 > pr1) && (pr0 > pr2) && (pr0 > pr3)){ //The sensor 0 has the most of the light
digitalWrite(dirPinh, HIGH); digitalWrite(dirPinb, LOW); // Initialisation of the dir pins
for(i=0; i<pas;i++){
digitalWrite(stepPinh, HIGH); digitalWrite(stepPinb, HIGH); // we do a step
delay(5);
digitalWrite(stepPinh, LOW); digitalWrite(stepPinb, LOW); // we stop the motor
delay(5);
}
Serial.println("The sensor 0 has the most of the light");
}
else if((pr1 > pr0) && (pr1 > pr2) && (pr1 >pr3)){ //The sensor 1 has the most of the light
digitalWrite(dirPinh, LOW); digitalWrite(dirPinb,HIGH);
for(i=0; i<pas;i++){
digitalWrite(stepPinh, HIGH); digitalWrite(stepPinb, HIGH);
delay(5);
digitalWrite(stepPinh, LOW); digitalWrite(stepPinb, LOW);
delay(5);
}
Serial.println("The sensor 1 has the most of the light");
}
else if( (pr2 > pr0) && (pr2 > pr1) && (pr2 > pr3)){ //The sensor 2 has the most of the light
digitalWrite(dirPinh, HIGH); digitalWrite(dirPinb, LOW);
for(i=0; i<pas;i++){
digitalWrite(stepPinh, HIGH); digitalWrite(stepPinb, HIGH);
delay(5);
digitalWrite(stepPinh, LOW); digitalWrite(stepPinb, LOW);
delay(5);
}
Serial.println("The sensor 2 has the most of the light");
}
else if((pr3 >pr0) && (pr3 > pr1) && (pr3 > pr2)){ //The sensor 3 has the most of the light
digitalWrite(dirPinh, HIGH); digitalWrite(dirPinb, LOW);
for(i=0; i<pas;i++){
digitalWrite(stepPinh, HIGH); digitalWrite(stepPinb, HIGH);
delay(5);
digitalWrite(stepPinh, LOW); digitalWrite(stepPinb, LOW);
delay(5);
}
Serial.println("The sensor 3 has the most of the light");
}
else{
Serial.println("Sensor ERROR");
}
delay(1);
}
Serial.println("-----------------------------------------------------");
}
Serial prints are just helping for the debug
GET TENSION & CURRENT VALUE
In order to get an accurate voltage and tension with the MSP you will have to do two easy electronic assembly:
VOLTAGE MEASURE
To measure the voltage you will just have to make a voltage bridge divider to avoid a saturation of the analog pin of the MSP432.
There is a 10kOhm resistor linked to the ground and a 100kohm linked to the +5V.
CURRENT MEASURE
The current measuring is a little bit harder. To measure it, you just have to make an op amp differentiator, like so, the amp output is the difference between a know value and the value we are looking for. I will use in this tutorial the LF356N for the amplifier.
After measuring the voltage output of the differentiator, we will just have to make a table with the analog in of the MSP432 and the actual current measured. According to this table, you will just have to draw the graph between the current and the analog value and get the equation of the graph :
The “Calculated value” is the equation founded thanks to the graph, I just changed “x” by the Analog value.
Here is the graph :
Thanks to that equation we will associate the current and the voltage in the float variable.
PRINT TENSION & CURRENT
To print the current and the tension with the MSP, i’ll use the kentec K35 boosterpack.
The MSP cas do multithreading : it can run multiple loops in the same time. In order to do two loops for example you’ll only have to do two files in the same Document in your project file document.
Here is the test code fully commented for an easier understanding :
FIST FILE
CODE
// All the include and define to uste the Kentec K35 LCD Screen
#include <LCD_screen.h>
#include <LCD_screen_font.h>
#include <LCD_utilities.h>
#include <Screen_K35_SPI.h>
#include <Terminal12e.h>
#include <Terminal6e.h>
#include <Terminal8e.h>
#include "SPI.h"
#include "Screen_K35_SPI.h"
extern String stringCur ="";
extern String stringVin ="";
// Constants - Kentec K53
#define K35_SPI;
Screen_K35_SPI myScreen; //Creation of the screen object
int xAxis = 320; //The x axis in pixels
int yAxis = 240; //The y axis in pixels
uint16_t colours[16]; //Definition of the colour tab
uint16_t touch[2]; //Definition of the colour tab
void setuptestK35() {
Serial.begin(115200); //link files
/*------------------------------------------------LCD DISPLAY------------------------------------------------*/
myScreen.begin(); //Start the screen
myScreen.setOrientation(3); //Orientate all the data
myScreen.setPenSolid(true); // The rectangles will be full
/* The colour tab */
colours[0] = myScreen.calculateColour(226,48,48); //RED
colours[2] = myScreen.calculateColour(85,120,255); //BLUE
colours[3] = myScreen.calculateColour(255,255,255);
colours[4] = myScreen.calculateColour(255,255,0);
colours[5] = myScreen.calculateColour(255,247,90); //yellow
colours[6] = myScreen.calculateColour(69,184,69);
colours[7] = myScreen.calculateColour(133,255,137); // green power
}
void looptestK35() {
//txt
myScreen.gText(xAxis/8,yAxis/6, "- Voltage -", colours[4]);
myScreen.gText(xAxis/8,yAxis/2, "- Current -", colours[4]);
// rectangle
myScreen.dRectangle(xAxis/8 +75, yAxis/6-4,140,16, colours[6]); //Rectangle
myScreen.dRectangle(xAxis/8+75, yAxis/2-4,140,16, colours[6]); //Rectangle
// }
//}
}
SECOND FILE
// Constants - Measure
double vout = 0.0;
double vin = 0.0;
float R2 = 100000.0; // resistance 1
float R1 = 10000.0; // resistance 2
int voltageSensor = 1;
int ampSensor = 0;
const float Shunt = 60; //amp max of the shunt resistor
char outString[15];
void setupMeasure() {
Serial.begin(115200); //link files
}
void loopMeasure() {
/*------------------------------------------------ANALOG READING------------------------------------------------*/
voltageSensor = analogRead(A1);
ampSensor = analogRead(A0);
Serial.println(voltageSensor);
/*-----------------------------------------CALCULATE VOLTAGE & CURRENT--------------------------------------------*/
vout = (voltageSensor * 5.0) / 1024.0;
vin = vout / (R2/(R1+R2));
float current =-0.004*ampSensor+2.04;
if(-0.5<current<0.2){
current=0;
}
/*------------------------------------------------ANALOG READING------------------------------------------------*/
//Float
String sVin = dtostrf(vin,7,3,outString);
String sCur = dtostrf(current,7,3,outString);
//print
myScreen.gText(xAxis/7+100+125,yAxis/6, sVin , colours[4]);
myScreen.gText(xAxis/7+100+125,yAxis/2, sCur, colours[4]);
delay(10);
}
To link both files you will only need to put the into the same document named as the first document to compile.
POWER THE PROJECT
To power the project we'll use two components :
and the LM5118.
The BQ24650 is an MPPT (Maximum Power Point Tracking) charge controller and the LM5118 is a buck converter.
The battery charger will track the maximal power point of the solar panel.
It's controlling the maximal power output of the panel thanks to a resistance variator but-in to increase or tension or curent .
Here is the schematic to get how it works :
PCB DESIGN
For a better reliability of the project I made a circuit board with Designspark PCB.
This is a suggestion of what you can do, all the project files that i made are available in the attachment.
First you’ll have to draw a schematic and include all your components in the “.sch” file. Maybe you won’t have the library of the MSP432 and the Drivers, find it in the attachment.
You’ll only have to drag the libraries into your designspark library document.
Here is a sneak peak of the pcb of the project.
Here is the end of the tutorial here is a final picture of the project and some videos
Comments