Go Down

Topic: My first project needs some help (Read 694 times) previous topic - next topic

lostOne

Hi everyone, I need some help.
After several versions I have created this monster to control a solar tracker. What you will see is from my 3 weeks of experience so please be nice. I wanted to learn something by doing this myself, in the future I will be controlling three trackers from this board. The issue I have is the program seems to run great on my work bench, but when I install on the tracker it runs great for a few hours then it seems to loss it. The LCD screen tends to blank out after the actuators have moved to a new position and sometimes the program does not shut the actuator down when it has reached its limit.
My assumption is I have a bit of "dirty code". If I can get some pointers on cleaning it up that would be great.
I am using a Uno for the board, a 4 relay control board and a 16 x 2 LCD screen. I have a single 20 amp 12 volt power supply reducing to 9 volts trough a regulator for the Adriano and a 5 volt regulator supplying power to the relay board and the LCD. The reason for this was to limit how much power the Adriano had to regulate.







Grumpy_Mike

Quote
My assumption is I have a bit of "dirty code"

My assumption is that you have a dirty supply. Give this a read:-
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Note:-
When posting code select the code and hit the # icon not the quote box next to it. That way you get a scrolling box and the forum software doesn't mess with it.

lostOne

#2
Jun 15, 2011, 06:22 pm Last Edit: Jun 15, 2011, 06:44 pm by lostOne Reason: 1
Thanks Grumpy Mike,
I was affraid of this sizing capcitors is very much new to me.
My concern was the motors for the actuator. They are using the 12 volt supply before it enters into the regulator to be reduced to 9 volts. Unfortunatly I do not have the data on the board doing the reduction but has capcitors on the board.

I am thinking trying to run the Uno on a battery and let the actuator work on the 12 volt power supply. I think this should show me if I am correct.




Code: [Select]
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


// adjustment varibles

// diff settings this the differance between the east IR sensors and the west nothing happens until it is larger than 125 either way.
int diffPw = 125;        // sets the spread between move west
int diffPe = -125;     // sets the spread between move east

// night time off sensor setting the sun is down so I want to move back to the east
int sensoroff = 20;

// set varibles
int sensorPinW = A0;      // IR sensor for the west
int sensorPinE = A1;      // IR sensor for the east
int ledPin = 13;          // select the pin for the LED
int sensorValueW = 0;     // variable to store the value coming from the sensor
int sensorValueE = 0;     // variable to store the value coming from the sensor
int mtrW =6;             // mtr engage west (turns on the west relay)
int mtrE =7;             // mtr engage west
int limitW = 8;          //  Limit switch west position
int limitE = 9;          // Limit switch east position
int diff = 0;            // diffreance between west IR sensor and the east


void setup() {
 // declare the ledPin as an OUTPUT:
 pinMode(ledPin, OUTPUT);  
 pinMode(mtrW, OUTPUT);
 pinMode(mtrE, OUTPUT);
 pinMode(limitW, INPUT);
 pinMode(limitE, INPUT);
 Serial.begin(9600);
 // set up the LCD's number of columns and rows:
 lcd.begin(20, 2);
 delay(5000);
}

// Functions -----------------------------
void Delay() // I do not need to go nuts checking the sensors so I have 15 min delay between checks
{

 byte minutes = 15;
 byte seconds = 60;
 
 lcd.setCursor(7, 1);
 lcd.print("Del:");
 
 for (int m=minutes; m>=0; m--)
 {
   Display();
   for (int s=seconds; s>=0; s--)
   {
     //print m and s to LCD
     lcd.leftToRight();
     lcd.setCursor(11, 1);
     if (m>9)
     {
      lcd.print(m);
      lcd.print(":");
     }
     else
     {
       lcd.print(" ");
       lcd.print(m);
       lcd.print(":");
     }
   
    if (s>9)
     {
       lcd.print(s);
     }
     else
     {
       lcd.print("0");
       lcd.rightToLeft();
       lcd.print(s);
     }
     delay(1000);
   }
 }
}
void Display() // creates the display for the LCD
{
 lcd.clear();
 delay(1000);
 lcd.print("E:");
 lcd.print(sensorValueE);
 lcd.setCursor(6, 0);
 lcd.print("W:");
 lcd.print(sensorValueW); //line one data
 lcd.setCursor(0, 1);
 lcd.print("D:");
 lcd.print(diff);
 delay(1000);
}
void caldiff()  
{
 // read the value from the sensor and create the diff then display to the lcd
 sensorValueW = analogRead(sensorPinW);
 sensorValueE = analogRead(sensorPinE);
 diff = sensorValueW -  sensorValueE;
 Display();
}

void movewest() // moves the array west
{
 if (digitalRead(limitW) == HIGH)
 {
   do
   {
     if (digitalRead(mtrW) == LOW)
     {
       lcd.setCursor(12, 0);
       lcd.print("GW ");
       digitalWrite(mtrW, HIGH); // turn on motor
     }
     caldiff();
   }
   while (diff > 5 && digitalRead(limitW) == HIGH);
   digitalWrite(mtrW, LOW);
   
   }

}
void moveeast()// moves the array east
{
 if (digitalRead(limitE) == HIGH)
 {
   do
   {
     if (digitalRead(mtrE) == LOW)
     {
       lcd.setCursor(12, 0);
       lcd.print("ME ");
       digitalWrite(mtrE, HIGH); // turn on motor
     }
     caldiff();
   }
   while (diff<-5 && digitalRead(limitE) == HIGH);
   digitalWrite(mtrE, LOW);
 
 }
}

void moverest() // moves it to the east when the sun is down
{
 digitalWrite (ledPin, HIGH);
 do
 {
   digitalWrite(mtrE, HIGH); // turn on motor
 }
 while (digitalRead(limitE) == HIGH);
 digitalWrite(mtrE, LOW);
 caldiff();
}


lostOne

#3
Jun 15, 2011, 06:22 pm Last Edit: Jun 15, 2011, 06:26 pm by lostOne Reason: 1
Code: [Select]
// Loop ---------------------------------------------------------------------------------

void loop()
{
  caldiff();
  if (sensorValueW > 20 && sensorValueE > 20 )
  {
    if (diff > diffPw)// check sensor if true wait and recheck
    {
      lcd.setCursor(12, 0);
      lcd.print("VW ");
      delay(5000);
      caldiff();
    }
    if (diff > diffPw)  // double check the sensor
    {
      movewest(); // call the move west function
    }
    if (diff < diffPe) // check sensor
    {
      lcd.setCursor(12, 0);
      lcd.print("VE ");
      delay(5000);
      caldiff();
    }
    if (diff < diffPe) // double check the sensor
    {
      moveeast();
    }
  }
  if (digitalRead(limitE) == HIGH && sensorValueW < sensoroff && sensorValueE < sensoroff )
  {
    lcd.setCursor(12, 0);
    lcd.print("MR ");
    moverest();
  }
  if (digitalRead(limitE) == LOW && sensorValueW < sensoroff && sensorValueE < sensoroff )
  {
    lcd.setCursor(4, 3);
    lcd.print("AR ");
    Delay();
  }
   else
  {
   Delay();
  }
}
   












johnwasser

I don't see any problems in your code that would cause it to fail.  There are a few learning opportunities:

Your Delay() function counts down 16 minutes (15..0) of 61 seconds each (60..0).  Perhaps should be changed?

You can declare many of your variables as 'const' so the compiler can tell you don't intend to change them.  That will allow the compiler to better optimize the code and protect you from writing code that changes variables you intended to be constants.
Code: [Select]

// diff settings this the differance between the east IR sensors and the west nothing happens until it is larger than 125 either way.
const int diffPw = 125;        // sets the spread between move west
const int diffPe = -125;     // sets the spread between move east

// night time off sensor setting the sun is down so I want to move back to the east
const int sensoroff = 20;

// set varibles
const int sensorPinW = A0;      // IR sensor for the west
const int sensorPinE = A1;      // IR sensor for the east
const int ledPin = 13;          // select the pin for the LED
int sensorValueW = 0;     // variable to store the value coming from the sensor
int sensorValueE = 0;     // variable to store the value coming from the sensor
const int mtrW =6;             // mtr engage west (turns on the west relay)
const int mtrE =7;             // mtr engage west
const int limitW = 8;          //  Limit switch west position
const int limitE = 9;          // Limit switch east position
int diff = 0;            // diffreance between west IR sensor and the east


When you are running the motors there should be no need to repeatedly turn the motor pin ON or to check to see if it is ON before turning it on.  The only pre-check you should need is the limit switch check:
Code: [Select]

void movewest() // moves the array west
{
  if (digitalRead(limitW) == HIGH)
  {
    lcd.setCursor(12, 0);
    lcd.print("GW ");
    digitalWrite(mtrW, HIGH); // turn on motor
    while (diff > 5 && digitalRead(limitW) == HIGH)
        caldiff();
    digitalWrite(mtrW, LOW);
  }
}

void moveeast()// moves the array east
{
  if (digitalRead(limitE) == HIGH)
  {
     lcd.setCursor(12, 0);
     lcd.print("ME ");
     digitalWrite(mtrE, HIGH); // turn on motor
     while (diff<-5 && digitalRead(limitE) == HIGH)
         caldiff();
     digitalWrite(mtrE, LOW);  // turn off motor
  }
}

void moverest() // moves it to the east when the sun is down
{
  digitalWrite (ledPin, HIGH);
  if (digitalRead(limitE) == HIGH)
  {
      digitalWrite(mtrE, HIGH); // turn on motor
      while (digitalRead(limitE) == HIGH);  // Wait to hit limit
      digitalWrite(mtrE, LOW); // turn off motor
  }
  caldiff();
}
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

lostOne

Thanks for the response on the code, I understand the recomendations I belive. The const means that the varible will not ever change where as the int is a varible the will change.


Grumpy_Mike

Motors often need a bit more decoupling, a 0.1uF capacitor soldered directly across the motor contacts will help. You can't really add too much decoupling, too much doesn't do any harm either.
Also 0.1uF across the power input of the LCD would be good, again right on the display board with as short leads as possible.
I doubt if it is your code making things go wrong.

lostOne

I will give it a shot, Until now I have never played with capcitors diodes and all of this fun stuff. My only code is on VB for excel. So I think I will stuble my way through this. Its kinda fun.


Go Up