Solar Tracker Sensor Reading

Hello All,

I am trying to program an arduino for a solar tracker project. I am following the approach taken by Mike Cook at ( LED Sensing ) to sense the direction of the light.

In his program Mike sends the data from the arduino, to a computer through the USB port. I however wish to display it on an LCD display. Following program based on a modified version of Mike’s program is being used.

The problems I have encountered are:

  1. The arduino keeps sending data from the serial port despite there being no program lines to do so.
  2. Data is not displayed on the LCD screen (which I have tested with other programs and works OK).

Please help.

TIA.

Azhaque


// include the library code.
#include <LiquidCrystal.h>
LiquidCrystal lcd(53,51,49,47,45,43);

#define numSensors 2    // Number of LED sensors - 2

//variables setup

 byte anodePin[] =  { 41,39};
 byte cathodePin[] = { 0, 1}; // the analogue input pins 0 to 5 when used digitally
 int results[2];
 int refLevel[2];

void setup() { 
   
_SFR_IO8(0x35) |= 0x10;   // global disable pull up resistors
 
 lcd.begin(16, 4);
   
   for(int i=0; i<numSensors; i++){
   digitalWrite(anodePin[i],LOW); // ensure pins go low immediately after initializing them to outputs
   pinMode(anodePin[i],OUTPUT);   // declare the anode pins as outputs
   pinMode(cathodePin[i],INPUT); // declare the cathode pins as inputs
 }          
}

//loop: light and then read LEDs 

void loop () {
 // turn all LEDs on
   for(int i=0; i<numSensors; i++){
     digitalWrite(anodePin[i],HIGH);
     pinMode(cathodePin[i],OUTPUT);    // Enable cathode pins as outputs
     digitalWrite(cathodePin[i],LOW);  // Turn ON LED
 } 
  // charge up LEDs cathode = HIGH, anode = LOW
    for(int i=0; i<numSensors; i++){
    digitalWrite(cathodePin[i],HIGH); 
    digitalWrite(anodePin[i],LOW);    
 }
    // Put cathode pins into measuring state (analogue input)
   for(int i=0; i<numSensors; i++){
   pinMode(cathodePin[i],INPUT);
 }

 // Take a reading of the voltage level on the inputs to get a reference level before discharge
   for(int i=1; i<=numSensors; i++){
    results[i] = analogRead(i);  // Store the reference level
 }
 //**********************************************************
 delay(40);  // LED discharge time or photon integration time
             // The larger this is, the more sensitive is the system
 //**********************************************************

// Read the sensors after discharge to measure the incident light
     
     for(int i=0; i<numSensors; i++){
      results[i] -= analogRead(i);     
      pinMode(cathodePin[i],OUTPUT);   // by discharging the LED immediately the charge on the A/D input is removed and
      digitalWrite(cathodePin[i],LOW); // the cross talk between sensors is reduced
 }

   // print out the results.
   
  
   lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("East=");
     lcd.setCursor(6,0);
     lcd.print(results[1]);
    delay(3000); 
     lcd.setCursor(0,1);
     lcd.print("West=");
     lcd.setCursor(6,1);
     lcd.print(results[2]);
     
     delay(3000); 
    //for(int i = 0; i<numSensors; i++)
  
}

http://forum.arduino.cc/index.php/topic,148850.0.html

read #7

please come back and edit you post.

azhaque: The problems I have encountered are:

  1. The arduino keeps sending data from the serial port despite there being no program lines to do so.
  2. Data is not displayed on the LCD screen (which I have tested with other programs and works OK).

I would question if you were successful to up-load the sketch.

since you are having problems displaying on the LCD, load a very basic 'Hello World'

if that is successful, your program should at least not try to communicate with the USB.

byte cathodePin[] = { 0, 1}; // the analogue input pins 0 to 5 when used digitally

This line is using pins 0 and 1 which are the pins for serial comms.

If it is intended to be using pins A0 and A1 it must say so.

Here is the complete code (unchanged)

// include the library code.
#include <LiquidCrystal.h>
LiquidCrystal lcd(53,51,49,47,45,43);

#define numSensors 2    // Number of LED sensors - 2

//variables setup

  byte anodePin[] =  { 41,39};
  byte cathodePin[] = { 0, 1}; // the analogue input pins 0 to 5 when used digitally
  int results[2];
  int refLevel[2];
 
void setup() {
   
 _SFR_IO8(0x35) |= 0x10;   // global disable pull up resistors
 
  lcd.begin(16, 4);
   
    for(int i=0; i<numSensors; i++){
    digitalWrite(anodePin,LOW); // ensure pins go low immediately after initializing them to outputs
    pinMode(anodePin,OUTPUT);   // declare the anode pins as outputs
    pinMode(cathodePin,INPUT); // declare the cathode pins as inputs
  }         
}

//loop: light and then read LEDs

void loop () {
  // turn all LEDs on
    for(int i=0; i<numSensors; i++){
      digitalWrite(anodePin,HIGH);
      pinMode(cathodePin,OUTPUT);    // Enable cathode pins as outputs
      digitalWrite(cathodePin,LOW);  // Turn ON LED
  }
   // charge up LEDs cathode = HIGH, anode = LOW
     for(int i=0; i<numSensors; i++){
     digitalWrite(cathodePin,HIGH);
     digitalWrite(anodePin,LOW);   
  }
     // Put cathode pins into measuring state (analogue input)
    for(int i=0; i<numSensors; i++){
    pinMode(cathodePin,INPUT);
  }

  // Take a reading of the voltage level on the inputs to get a reference level before discharge
    for(int i=1; i<=numSensors; i++){
     results = analogRead(i);  // Store the reference level
  }
  //**********************************************************
  delay(40);  // LED discharge time or photon integration time
              // The larger this is, the more sensitive is the system
  //**********************************************************

 // Read the sensors after discharge to measure the incident light
     
      for(int i=0; i<numSensors; i++){
       results -= analogRead(i);     
       pinMode(cathodePin,OUTPUT);   // by discharging the LED immediately the charge on the A/D input is removed and
       digitalWrite(cathodePin,LOW); // the cross talk between sensors is reduced
  }

    // print out the results.
   
   
    lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("East=");
      lcd.setCursor(6,0);
      lcd.print(results[1]);
     delay(3000);
      lcd.setCursor(0,1);
      lcd.print("West=");
      lcd.setCursor(6,1);
      lcd.print(results[2]);
     
      delay(3000);
     //for(int i = 0; i<numSensors; i++)
   
}

…R

Robin2: byte cathodePin[] = { 0, 1}; // the analogue input pins 0 to 5 when used digitally

If it is intended to be using pins A0 and A1 it must say so.

...R

Robin2,

Thanks for the response.

I am a newbie and am using the Mega2560.

Is your observation valid for the Mega2560?

azhaque

dave-in-nj: since you are having problems displaying on the LCD, load a very basic 'Hello World'

Dave,

As I mentioned in my first post, I have already tried a Hello World type program and it worked.

Azhaque

Thanks all round. I figured out the problem. I need to keep in mind that arrays are indexed to 0 and not 1. Here is the amended code.

 lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("East=");
     lcd.setCursor(6,0);
     lcd.print(results[0]);
    delay(3000); 
     lcd.setCursor(0,1);
     lcd.print("West=");
     lcd.setCursor(6,1);
     lcd.print(results[1]);
     
     delay(3000);

I was using results[1] and results[2] instead of results[0] and results[1].

azhaque

azhaque:
Is your observation valid for the Mega2560?

Yes.
I figured you were using a Mega because you had pins 53 etc.

…R

azhaque: Hello All,

I am trying to program an arduino for a solar tracker project. I am following the approach taken by Mike Cook at ( http://www.thebox.myzen.co.uk/Workshop/LED_Sensing.html ) to sense the direction of the light.

Having solved the display issue I would like the forum's advice on the way fwd.

Mike uses the following approach in his program.

  1. Forward bias all leds one by one to discharge the junction capacitance.

  2. Charge each led junction capacitance by reverse biasing each led, one by one.

  3. Measure the light level by measuring the voltage of each led, One by one.

The alternate to the above is to take each led through the full cycle of discharge-recharge-measure cycle. The apparent advantage is that there would be little or no time gaps between the various stages of the cycle thus minimizing the effect of other factors i.e. leakage current temp etc.

I would like the forum's view as to which approach seems better.

Azhaque

Anyone?

azhaue

// include the library code.

 #include <LiquidCrystal.h>
 LiquidCrystal lcd(53,51,49,47,45,43);

//variables setup
 
 unsigned int East;
 unsigned int West;
 unsigned int Count=0;
 unsigned int Value=0;
 
void setup() { 
 
 _SFR_IO8(0x35) |= 0x10;   // global disable pull up resistors
 
 lcd.begin(16, 4);
}


void loop () {
 

// declare the pins as outputs

     pinMode(42,OUTPUT);
     pinMode(44,OUTPUT); 
   
     pinMode(46,OUTPUT);
     pinMode(48,OUTPUT);
    

// Light up LEDs to discharge junction caps by forward biasing the LED.  cathode = LOW anode = HIGH 
     
     digitalWrite(44,LOW);// Cathode
     digitalWrite(42,HIGH);// Anode
  
     digitalWrite(46,LOW);// Cathode
     digitalWrite(48,HIGH);// Anode

delay(10);     
  
// Charge up LEDs junction caps by reverse biasing the LED.  cathode = HIGH, anode = LOW
 
     
     digitalWrite(44,HIGH);// Cathode
     digitalWrite(42,LOW);// Anode
  
     digitalWrite(46,HIGH);// Cathode
     digitalWrite(48,LOW);// Anode
   
delay(50); 
// Isolate the Cathode end of the diode

      pinMode(44,INPUT);
      digitalWrite(44,LOW);
      
      pinMode(46,INPUT);
      digitalWrite(46,LOW);
      
      
      
             
 // Count how long it takes the diode to bleed back down to a logic zero
     for ( Count = 0; Count > 60000; Count++)
     {
       Value= digitalRead(44);
       if (Value == LOW)
        {
         East= Count;
         break;
        }
 
       Value= digitalRead(46);
       if (Value == LOW)
        {
         West=Count;
         break;
        }
     }
     
// print out the results.
    
  lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("East=");
     lcd.setCursor(6,0);
     lcd.print(East);
   
     lcd.setCursor(0,1);
     lcd.print("West=");
     lcd.setCursor(6,1);
     lcd.print(0);
     
    
  delay(3000);

}