Pages: [1]   Go Down
Author Topic: My first project needs some help  (Read 483 times)
0 Members and 1 Guest are viewing this topic.
Albuquerque , NM USA
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.






Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31448
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Albuquerque , NM USA
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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();
}

« Last Edit: June 15, 2011, 11:44:20 am by lostOne » Logged

Albuquerque , NM USA
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
// 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();
  }
 }
   











« Last Edit: June 15, 2011, 11:26:59 am by lostOne » Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 179
Posts: 8070
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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:
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();
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Albuquerque , NM USA
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31448
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Albuquerque , NM USA
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Pages: [1]   Go Up
Jump to: