Bring back 12V DC worm gear motor to initial position?

Hello

Im new in this field. I have Pololu High-Power 18V, 15A motor driver, Arduino microcontroler and 12V DC worm gear Motor. Im building a prototype for tracking a solar panel. I would like to ask for a help regarding some sample code, that after tracking the panel with warm gear Motor it returns the panel in their initial position (horizontal).

I have this sample code: First I im doing sensor reading

[code]int readSensor1()
{
// interrupts();
int avg = 0;
/SHIFT DATA/
for (int i = 0; i < array_size; i++)
{
avg = avg + sensor1_data_hinge[i];
sensor1_data_hinge[i] = sensor1_data_hinge[i+1];
}
/ACCEPT NEW READING/
sensor1_data_hinge[array_size-1] = analogRead(sensor1);
avg = avg/array_size;

// noInterrupts();
return avg;
}[/code]

Than I have implemented procedure for motor control

[code]void check_motor1()
{
//read sensor
data1 = readSensor1();
//plan which movement to take
if (data1 >= upperthres)
{
planned_motor1 = 1;
}
else if (data1 <= lowerthres)
{
planned_motor1 = 2;
}
else planned_motor1 = 0;
}
//wait for a bit
//delay(2000); //MAYBE SPLIT THE PROCEDURE INTO 2 PHASES: CHECKING AND EXECUTING

void execute_motor1()
{
//read sensor again
data1 = readSensor1();
//check if planned movement is still correct after waiting
if (data1 >= upperthres && planned_motor1 == 1)
{
//enable motor timer
motor_time_flag = 1;
hingeCW();
//continually check sensor and count down to stop motor
while (data1 >= upperthres && time_out_flag == 0)
{
data1 = readSensor1();
}
motor_time_counter = 0;
motor_time_flag = 0;
time_out_flag = 0;
stopHingeMotor();
}
else if (data1 <= lowerthres && planned_motor1 == 2)
{
//enable motor timer
motor_time_flag = 1;
hingeCCW();
//continually check sensor and count down to stop motor
while (data1 <= lowerthres && time_out_flag == 0)
{
data1 = readSensor1();
}
//reset timer parameters incase the loop exits because hinge reaches correct position
motor_time_counter = 0;
motor_time_flag = 0;
time_out_flag = 0;
stopHingeMotor();
}
//if planned movement does not match, reset everything
else planned_motor1 = 0;
}

/END OF MOTOR CONTROL/[/code]

hingeCW(); and hingeCCW(); are procedure for turning the motor left and right respectively. My problem is how to turn the panel in the initial position (for example at the end of the day, when sun goes down and its dark, I like the motor turn the panel in the initial position).

Any help?
Thanks

What is a “warm gear”? You need to better explain the mechanical arrangement of the motor and the panel.

What is the sensor to which you refer and what does it do?

Look up “limit switch”, which is the most common (and a very cheap) way to set a zero or home location in an electromechanical device.

Sorry my mistake, its actually a worm gear motor. It is a 12V DC worm gear motor. Actually I would like to monitor and track the solar panel. So one worm gear motor moved the panel up and down and other motor rotate it.So, for test purpose I have a Light sensor module. So the idea is during the night the panel is in his initial (home, horizontal position). So during the day motor turn left and right tracjing the sun and at the end of the day needs to bring the panel in his initial , horizontal position,

Hope more clear now

You either need a position encoder that will tell you where the panel is (so you can change the position) or a limit switch to tell you where the home position is.

Thanks. Any code help when using encoder or limit switch?Is this switch a good option (http://www.jaycar.com.au/Electromechanical-Components/Switches/Micro-Switches/Microswitch-SPDT-ON-ON/p/SM1039 or better this one https://www.sparkfun.com/products/retired/12742)?

And how will the position encoder knows where the initial (home ) position is?

Hi

I have Pololu High-Power 18V 15A motor driver, Arduino Uno microcontroler, 12V DC worm gear Motor and light sensor module. Im building a prototype for tracking a solar panel. So , from example in the morning the panels are in their initial (home, horizontal position) and start tracking the sun and motor start moving. I include the code but when testing the motor is moving always when light is bigger than upper thresh. Which is not correct as I wont that motor stop moving and panel stops when sun reach its maximum and at the end of the day panel comes back (motor runs in other direction).

Include the sample code. So what Im missing here?

[code]/*
WIRING INSTRUCTION: includes 1 motor (hinge motor) and 1 sensor.

pin 8: hinge motor direction pin
pin 11: hinge motor speed pin (PWM)
sensor 1 pin a: pin A0

*/

#include <TimerOne.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
#include <SPI.h>
#include <Wire.h>

#define BRAKE1 12
#define BRAKE2 7

#define sensor1 A0 //Purple cable
#define motor_speed 750 //default motor speed @ 0.3rpm
#define array_size 30 //10 samples

volatile long data1 = 0;
volatile int check_counter = 0;
volatile int execute_counter = 0;
volatile int motor_time_counter = 0;
volatile byte check_flag = 0;
volatile byte time_out_flag = 0;
volatile byte motor_time_flag = 0;

char upperthres = 40; //CW tolerance, upper threshold
char lowerthres = 17; //CCW tolerance, lower threshold
int sensor1_data_hinge[array_size];
int planned_motor1 = 0; //Planned motion: 0-no rotation; 1-CW; 2-CCW
int lightLevel;

/* SENSOR PROCESSING */
int readSensor1()
{
// interrupts();
int avg = 0;
/SHIFT DATA/
for (int i = 0; i < array_size; i++)
{
avg = avg + sensor1_data_hinge[i];
sensor1_data_hinge[i] = sensor1_data_hinge[i+1];
}
/ACCEPT NEW READING/
sensor1_data_hinge[array_size-1] = analogRead(sensor1);
avg = avg/array_size;

// noInterrupts();
return avg;
}
///

/MOTOR CONTROL/
void hingeCW () //turn RIGHT
{
digitalWrite(8, HIGH); //set direction for hinge motor
analogWrite(11, motor_speed); //set speed for hinge motor
}

void hingeCCW () //turn LEFT
{
digitalWrite(8, LOW); //set direction for hinge motor
analogWrite(11, motor_speed); //set speed for hinge motor
}

void stopHingeMotor ()
{
analogWrite(11, 0); //set 0 speed for hinge motor
}

//-------------MOTOR 1 Operations-------------
void check_motor1()
{
//read sensor
data1 = readSensor1();
//plan which movement to take
if (data1 >= upperthres)
{
planned_motor1 = 1;
}
else if (data1 <= lowerthres)
{
planned_motor1 = 2;
}
else planned_motor1 = 0;
}
//wait for a bit
//delay(2000); //MAYBE SPLIT THE PROCEDURE INTO 2 PHASES: CHECKING AND EXECUTING

void execute_motor1()
{
//read sensor again
data1 = readSensor1();
//check if planned movement is still correct after waiting
if (data1 >= upperthres && planned_motor1 == 1)
{
//enable motor timer
motor_time_flag = 1;
hingeCW();
//continually check sensor and count down to stop motor
while (data1 >= upperthres && time_out_flag == 0)
{
data1 = readSensor1();
}
motor_time_counter = 0;
motor_time_flag = 0;
time_out_flag = 0;
stopHingeMotor();
}
else if (data1 <= lowerthres && planned_motor1 == 2)
{
//enable motor timer
motor_time_flag = 1;
hingeCCW();
//continually check sensor and count down to stop motor
while (data1 <= lowerthres && time_out_flag == 0)
{
data1 = readSensor1();
}
//reset timer parameters incase the loop exits because hinge reaches correct position
motor_time_counter = 0;
motor_time_flag = 0;
time_out_flag = 0;
stopHingeMotor();
}
//if planned movement does not match, reset everything
else planned_motor1 = 0;
}

/END OF MOTOR CONTROL/

ISR(WDT_vect)
{
check_counter++;
if (check_counter == 2)
{
check_counter = 0;
check_flag = 1;
}
}

void timerIsr()
{
if (motor_time_flag == 1)
{
motor_time_counter++;
//Motor rotation time out parameter
if (motor_time_counter == 45) //15 ~ 1 second
{
motor_time_counter = 0;
motor_time_flag = 0;
time_out_flag = 1;
}
}
}

void enterSleep(void)
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
sleep_enable();

/* Now enter sleep mode. */
sleep_mode();

/* The program will continue from here after the WDT timeout*/
sleep_disable(); /* First thing to do is disable sleep. */

/* Re-enable the peripherals. */
power_all_enable();
}

void setup()
{

pinMode(8, OUTPUT); //hinge direction pin
pinMode(11, OUTPUT); //hinge speed pin
Serial.begin (9600);

Timer1.initialize(100000); // 100000 = 100ms
Timer1.attachInterrupt( timerIsr );

MCUSR &= ~(1<<WDRF);
/* In order to change WDE or the prescaler, we need to

  • set WDCE (This will allow updates for 4 clock cycles).
    */
    WDTCSR |= (1<<WDCE) | (1<<WDE);

/* set new watchdog timeout prescaler value /
WDTCSR = 1<<WDP0 | 1<<WDP3; /
8.0 seconds */

/* Enable the WD interrupt (note no reset). */
WDTCSR |= _BV(WDIE);

//initiate sensor data
for (int i = 0; i < 20; i++)
{
data1 = readSensor1();

}

}

void loop()
{
if (check_flag == 1 && (analogRead(sensor1) >= 5))
{
//=====Track hinge======
check_motor1();
delay(200);
execute_motor1();

}
lightLevel = analogRead(A0);
Serial.println(lightLevel, DEC);
//Serial.println(“sleep active”);
Serial.println(“sleep active”);
delay(50);
enterSleep();
Serial.println(“wake up”);
//execute_motor1();
delay(50);
}[/code]

hingeCW(); and hingeCCW(); are procedure for turning the motor left and right respectively.

Hello.

I have moved your post to this thread because it seems like your questions are still about getting your solar panel to go to its initial position at the end of the day.

You would need to create a variable in your code defining the initial or home position.

I suggest that you simplify your code to the simplest thing that should work, but does not, and post your entire code here. For example, you could try simplifying your code to just move your motor to a set position when the light sensor value falls below the minimum threshold.

- Amanda