[UPDATE] Solar tracking with Photosensors

Nomadic0Nomadic0 Posts: 14
Good evening!

In the execution of this program, the servos execute well when I block light from 1 section (2 photo-sensors) (4 sensors in total). However, when I block one of those same sensors as well as one adjacent to it, BOTH servos move, and then continue to move together no matter which sections I block afterward.

It's executing well (according to the terminal), but it's like the servos are storing energy(?) for the next execution of the while loop.

I am using RCTIME to measure the 'darkness' in these 4 sensors.

Any help would be appreciated. Apologies for the novice code.

Nomad
#include "simpletools.h"                      // Include simple tools
#include "servo.h"    

int main()                                    // main function
{
    
   int rf,lf,rb,lb,tilt,spin,frontsum,backsum,leftsum,rightsum=0;
  
  while(1)                                    // Endless loop
  {
    
    
    
    high(4);                                  // Set P4 high
    pause(1);                                 // Wait for circuit to charge
    rf = rc_time(4, 1);                    // Measure decay time on P4
    print("rf = %d\n", rf);                     // Display decay time
    //pause(100); 
    
           
    high(5);                                  // Set P5 high
    pause(1);                                 // Wait for circuit to charge
    lf = rc_time(5, 1);                    // Measure decay time on P5
    print("lf = %d\n", lf);                     // Display decay time
    //pause(100);  
    
    high(8);                                  // Set P8 high
    pause(1);                                 // Wait for circuit to charge
    rb = rc_time(8, 1);                    // Measure decay time on P8
    print("rb = %d\n", rb);                     // Display decay time
    //pause(100); 
    
           
    high(9);                                  // Set P9 high
    pause(1);                                 // Wait for circuit to charge
    lb = rc_time(9, 1);                    // Measure decay time on P9
    print("lb = %d\n", lb);                     // Display decay time
    //pause(100);  
    
    frontsum=lf+rf;
 
  printf("FRONTSUM %d\n", frontsum);
  
   backsum=rb+lb;
    
  printf("BACKSUM %d\n", backsum);
  
   leftsum=lf+lb;
  printf("LEFTSUM %d\n", leftsum);
  
  rightsum=rf+rb;
  printf("RIGHTSUM %d\n", rightsum);
 
  spin=leftsum-rightsum;
  printf("SPIN %d\n", spin);
 
 tilt=frontsum-backsum; 
  printf("TILT %d\n", tilt);
  
  //I then compare each labeled section to determine where the servos should move the panels (X and Y axis)
  
  
if(tilt<-30000)
  {           
                       
   servo_angle(25, 900);                       // P25 servo to 90 degrees
 pause(20);                              
  servo_stop();    
  printf("Clockwise tilt\n");                                      
  }
    else if (tilt>30000)
    {               
                    
   servo_angle(25, 1800);                       // P25 servo to 180 degrees
    pause(20);                              
    servo_stop();
     printf("CounterClockwise tilt\n");                                           
      }
  
 
  if(spin<-30000)
  {       
                         
   servo_angle(26, 900);                       // P26 servo to 90 degrees
  pause(20);                              
  servo_stop(); 
   printf("Clockwise\n");                                          
  
  }  else if (spin>30000)
    {                
          
   servo_angle(26, 1800);                       // P26 servo to 180 degrees
    pause(20);                              
    servo_stop(); 
   
     printf("CounterClockwise\n");                                          
      }
 
  pause(5000);     //Long pause to examine the results
      
}

Comments

  • 10 Comments sorted by Date Added Votes
  • For two servos you will get a much simpler reading if you use four photo-sensors instead of two.
    Make the right two read as positive for the LeftRight servo and the left two negative, then sum for LR motion.
    Make the top two read as positive for the UpDown axis and the bottom two negative, then sum for UD motion.

    There was a user who did something like this with visible lasers recently if anyone can link the post, please.
    Any com port in a storm.
    Floating point numbers will be our downfall; count on it.
    Imagine a world without hypothetical situations.
  • For two servos you will get a much simpler reading if you use four photo-sensors instead of two.
    Make the right two read as positive for the LeftRight servo and the left two negative, then sum for LR motion.
    Make the top two read as positive for the UpDown axis and the bottom two negative, then sum for UD motion.

    There was a user who did something like this with visible lasers recently if anyone can link the post, please.

    That did need clarification! I am using 4 (1 on each corner)

    Thank you
  • More meaningful variable names might help with understanding the code.

    We have to assume that P4, P5, P8, & P9 are the photo-sensors but which is which?

    Assumptions I'm making:

    P4 Front Left
    P5 Rear Left
    P8 Front Right
    P9 Rear Right

    This allows variable name transformations of:
    s becomes fl
    t becomes rl
    u becomes fr
    v becomes rr

    a becomes leftsum
    b becomes rightsum
    c becomes frontsum
    d becomes rearsum

    x becomes leftright
    y becomes frontrear

    It also helps to identify what range of values are expected, and in your test case what values you are measuring.

    That alone may help you understand what is happening.
  • AJL wrote: »
    More meaningful variable names might help with understanding the code.

    We have to assume that P4, P5, P8, & P9 are the photo-sensors but which is which?

    Assumptions I'm making:

    P4 Front Left
    P5 Rear Left
    P8 Front Right
    P9 Rear Right

    This allows variable name transformations of:
    s becomes fl
    t becomes rl
    u becomes fr
    v becomes rr

    a becomes leftsum
    b becomes rightsum
    c becomes frontsum
    d becomes rearsum

    x becomes leftright
    y becomes frontrear

    It also helps to identify what range of values are expected, and in your test case what values you are measuring.

    That alone may help you understand what is happening.

    I've updated this, and the results are clearer; that the program runs correctly, but the servos are still misbehaving
  • Nomadic0 wrote: »

    I've updated this, and the results are clearer; that the program runs correctly, but the servos are still misbehaving

    Can you post some pictures so others can help examine the configuration? :smile:
    Any com port in a storm.
    Floating point numbers will be our downfall; count on it.
    Imagine a world without hypothetical situations.
  • I updated your code to use a cog for the sensors.

    I noticed that you are doing a servo_stop which kills the servos. so you want them to go lifeless.

    If the sensors are on the board that the servo is moving isn't going to change the readings and cause the servos to continue to move?

    I would shut the servos off and then record reading as you move the sensor board around to get a list of values returned by the sensors. The rc_time function has a time limit that may be expiring.

    Anyway here is the updated code:
    #include "simpletools.h" // Include simple tools
    #include "servo.h"
    
    void doSensors(void *par);
    
    
    int volatile rf, lf, rb, lb;
    int *cog;
    
    
    int main() // main function
    {
    
      *cog = cognew(&doSensors, 40);
      
      while(1) // Endless loop
      {
    
        int tilt,spin,frontsum,backsum,leftsum,rightsum=0;
    
    
        print("rf = %d\n", rf); // Display decay time
    
        print("lf = %d\n", lf); // Display decay time
      
        print("rb = %d\n", rb); // Display decay time
    
        print("lb = %d\n", lb); // Display decay time
      
        frontsum=lf+rf;
        
        printf("FRONTSUM %d\n", frontsum);
        
        backsum=rb+lb;
        
        printf("BACKSUM %d\n", backsum);
        
        leftsum=lf+lb;
        printf("LEFTSUM %d\n", leftsum);
        
        rightsum=rf+rb;
        printf("RIGHTSUM %d\n", rightsum);
        
        spin=leftsum-rightsum;
        printf("SPIN %d\n", spin);
      
        tilt=frontsum-backsum;
        printf("TILT %d\n", tilt);
      
        //I compare each labeled section to determine where the servose should move the panels (X and Y axis)
      
        if(tilt<-30000)
        {
        
          servo_angle(25, 900); // P26 servo to 90 degrees
          pause(20);
          servo_stop();
          printf("Clockwise tilt\n");
        }
        else if (tilt>30000)
        {
        
          servo_angle(25, 1800); // P26 servo to 180 degrees
          pause(20);
          servo_stop();
          printf("CounterClockwise tilt\n");
        }
      
      
        if(spin<-30000)
        {
        
          servo_angle(26, 900); // P26 servo to 90 degrees
          pause(20);
          servo_stop();
          printf("Clockwise\n");
      
        } else if (spin>30000)
        {
      
          servo_angle(26, 1800); // P26 servo to 180 degrees
          pause(20);
          servo_stop();
          printf("CounterClockwise\n");
        }
    
        pause(5000);
    
      }
    }
    
    void doSensors(void *par)
    {
      
      while (1)
      {
        high(4); // Set P4 high
        pause(1); // Wait for circuit to charge
        rf = rc_time(4, 1); // Measure decay time on P4
    
        high(5); // Set P5 high
        pause(1); // Wait for circuit to charge
        lf = rc_time(5, 1); // Measure decay time on P5
    
        high(8); // Set P8 high
        pause(1); // Wait for circuit to charge
        rb = rc_time(8, 1); // Measure decay time on P8
    
        high(9); // Set P9 high
        pause(1); // Wait for circuit to charge
        lb = rc_time(9, 1); // Measure decay time on P9
    
        pause(100);
      }
    }
    
  • iseries wrote: »
    I updated your code to use a cog for the sensors.

    I noticed that you are doing a servo_stop which kills the servos. so you want them to go lifeless.

    If the sensors are on the board that the servo is moving isn't going to change the readings and cause the servos to continue to move?

    I would shut the servos off and then record reading as you move the sensor board around to get a list of values returned by the sensors. The rc_time function has a time limit that may be expiring.

    Anyway here is the updated code:

    I really appreciate your input to help me out! I have the servos just off to the side for now (for testing the sensors with shadows).

    Setup aside, I am not completely sure I understand the cog function.

    The rl,fl,rb,lb in the new code are returned as 0 when I tried to execute it. (I took away the int = 0 also, same thing showed.)
  • One of the best features of the propeller chip is it's multiple processors feature so you can run multiple functions at the same time.

    By placing the input function in a cog it runs all the time no mater what other functions your doing so you can always have fresh values from the sensors. In order to get values from that cog you need to tell the compiler that the variables in that cog are changing outside the normal process by using the "volatile" key word. They also have to be declared outside the main function where I have them so that all of the code has access to those variables.

    Also if you want to read your sensors at an exact time frame such as every 20 milliseconds you can adjust the cog functions to have that timing even though the reset of the program is stopped waiting for input.

    I don't have your sensors or what R/C time function your using so I'm not able to test the code.

    Mike

  • May be that this is just bad form and the compiler will do the right thing, but defining your variables within the while loop seems problematic, to me...
    ...
    while(1) // Endless loop
    {
    
    int rf,lf,rb,lb,tilt,spin,frontsum,backsum,leftsum,rightsum=0;
    ...
    

    It might just be my thinking, as the compiler might optimize and only create the variable space once, but I avoid creating vars other than simple indexes in for-loops, within while/until loops.

    Maybe, this would help:
    ...
    int rf,lf,rb,lb,tilt,spin,frontsum,backsum,leftsum,rightsum;
    
    while(1) // Endless loop
      rightsum=0;
    ...
    {
    
    
    

    dgately
    Livermore, CA (50 miles SE of San Francisco)
  • iseries wrote: »
    One of the best features of the propeller chip is it's multiple processors feature so you can run multiple functions at the same time.

    By placing the input function in a cog it runs all the time no mater what other functions your doing so you can always have fresh values from the sensors. In order to get values from that cog you need to tell the compiler that the variables in that cog are changing outside the normal process by using the "volatile" key word. They also have to be declared outside the main function where I have them so that all of the code has access to those variables.

    Also if you want to read your sensors at an exact time frame such as every 20 milliseconds you can adjust the cog functions to have that timing even though the reset of the program is stopped waiting for input.

    I don't have your sensors or what R/C time function your using so I'm not able to test the code.

    Mike

    Shouldn't what I'm trying to do still be possible with my code? I'm just not seeing why it doesn't clear the values.

    I would code it using the cog function if I understood how to troubleshoot it.

Sign In or Register to comment.