[SOLUCIONADO] Ayuda con el movimiento de un servo

Bueeenas a todos mis queridos, me he creado una cuenta porque realmente llegué a un callejón sin salida en este momento, espero realmente que entre quienes quieran, poder salir del problema en el cual me encuentro con un programa que estoy intentando hacer que compara la resistencia entre dos LDR para que un servo gire paso a paso (digamos, 1 grado por cada segundo que pasa cuando la comparación de resistencia entre ambos LDR es muy diferente) hasta que ambas resistencias igualan su intensidad.

Encontré esto en Ardutecka, que es bastante parecido a lo que busco:
http://www.arduteka.com/2012/12/sigueluz-con-s4a-y-arduino/
Pero mi idea es poder hacerlo sin tener que tenerlo conectado a una PC, además que mi Arduino es el Arduino Mega, que no es compatible con el S4A.

Los datos que les puedo brindar realmente son escasos, porque no se a donde apuntaría mi error, lo que si, les puedo dejar el código que hice (con ArduBlock, porque soy, realmente, pésimo con el C++, y ArduBlock al menos no me falló, hasta ahora).

Lo que si, les dejo el código que tengo (hecho por ArduBlock):

#include <Servo.h>

Servo servo_pin_22;

void setup()
{
servo_pin_22.attach(22);
}

void loop()
{
if (( ( ( analogRead(A1) - analogRead(A3) ) ) >= ( 100 ) ))
{
servo_pin_22.write( 0 );
}
if (( ( ( analogRead(A3) - analogRead(A1) ) ) >= ( 100 ) ))
{
servo_pin_22.write( 180 );
}
if (( ( ( analogRead(A1) - analogRead(A3) ) ) < ( 100 ) ))
{
servo_pin_22.write( 90 );
}
if (( ( ( analogRead(A3) - analogRead(A1) ) ) < ( 100 ) ))
{
servo_pin_22.write( 90 );
}
}

Nota: Esto lo hice en ArduBlock, por eso es probable que el código sea pésimo, pero es mas que nada lo que quise hacer es que en base a la comparación, si por ejemplo el LDR A es + que el LDR B, entonces el servo se vaya a 140° y se quede ahí, el problema, es que si bien se mueve, el servo se vuelve loco por alguna extraña razón y vibra.

Ojalá pudiese explicarme mas, pero ante cualquier duda que tengan estoy aquí para responderles.
Desde ya gracias, y un saludo grande.

El problema es que le estás diciendo a Arduino, que haga cosas diferentes, con situaciones iguales. Me explico.

Caso A: Si la diferencia entre A1 y A3 es mayor o igual a 100, pones el servo en 0º
Caso B: Si la diferencia entre A3 y A1 es mayor o igual a 100, pones el servo en 180º
Caso C: Si la diferencia entre A1 y A3 es menor que 100, pones el servo en 90º
Caso D: Si la diferencia entre A3 y A1 es menor que 100, pones el servo en 900º

Pongamos ejemplos:
A1=20
A3=90

Caso A: A1-A3=-70 No afecta
Caso B: A3-A1= 70 No afecta
Caso C: A1-A3=-70 Es menor que 100 y pone el servo a 90º
Caso D: A3-A1= 70 Es menor que 100 y también pone el servo a 90º

Pero si:
A1=200
A3=10

Caso A: A1-A3=190 Mayor que 100, pone el servo a 0º
Caso B: A3-A1=-190 Menor que 100, no afecta
Caso C: A1-A3= 190 Mayor que 100, no afecta
Caso D: A3-A1=-190 Menor que 100, pone el servo a 90º

En este caso, para los mismos valores de A1 y A3, Arduino quiere poner el servo a 0º y a 90º
Y podríamos poner muchos más ejemplos en los que pasa.

Explica exactamente qué quieres que pase en cada caso, y miramos de solucionar el problema.
Lo primero, si tiene que estar el servo en diferente posición si A1 es mayor que A3 que si A3 es mayor que A1, por ejemplo, y cosas así, o si solamente importa la diferencia entre ambos.

Si solo importa la diferencia entre ambos, un sketch que te puede funcionar es este:

#include <Servo.h>
Servo servo_pin_22;
void setup() {
  servo_pin_22.attach(22);
}
void loop()
{
  if (abs(analogRead(A1) - analogRead(A3)) >= 100) {
    servo_pin_22.write( 180 );
  }
  if (abs(analogRead(A3) - analogRead(A1)) < 100) {
    servo_pin_22.write( 90 );
  }
}

Pero, según las lecturas que obtengas de los LDR’s, quizá sea necesario usar map o constrain. Expón lo que necesitas que haga en cada caso, y los valores máximos y mínimos obtenidos en las lecturas de los pins A1 y A3, y miramos cómo solucionarlo.

Hace tiempo programé un seguidor solar. Es con tres LDR en triangulo para movimiento horizontal y vertical.
No esta depurado al 100%, pero creo te servirá de ayuda

//Solar tracking con tres LDR
//Joaquín Paredes 2014
//www.jopapa.me

#include <Servo.h>
Servo myservoh; // create servo object to control a servo
Servo myservov; // create servo object to control a servo

int sensorPinA0 = A0; // LDR superior-derecha
int sensorPinA1 = A1; // LDR superior-izquierda
int sensorPinA2 = A2; // LDR inferior
int valorA0 = 0; // variable para valores del sensor en A0
int valorA1 = 0;
int valorA2 = 0;
int posh=90;
int posv=60;

void setup() {
Serial.begin(9600);
myservoh.attach(9);
myservov.attach(10);
myservoh.write(posh); delay(15);
myservov.write(posv); delay(15);
}

void loop() {
// leer valores de las LDR
valorA0 = analogRead(sensorPinA0)+ 20;
valorA1 = analogRead(sensorPinA1);
valorA2 = analogRead(sensorPinA2);
Serial.print(valorA0); Serial.print("—");
Serial.print(valorA1); Serial.print("—");
Serial.println(valorA2);
delay(2000);

if (valorA0 < 600) {
//Movimiento horizontal
if ((valorA1 - valorA0) > 10) {
if (posh > 2) posh=posh-2;
Serial.print(valorA0 - valorA1);Serial.print(“RestaH”); Serial.println(posh);
myservoh.write(posh); delay(15);}

if ((valorA1 - valorA0) < -10) {
if (posh < 126) posh=posh+2;
Serial.print(valorA1 - valorA0);Serial.print(“SumaH”); Serial.println(posh);
myservoh.write(posh); delay(15);}
// Serial.println(“VERTICAL VERTICAL”);

//movimiento vertical
if ((valorA2 - (valorA0+valorA1)/2) > 10) {
if (posh > 2) posv=posv-2;
Serial.print(valorA2 - valorA1);Serial.print(“RestaV”); Serial.println(posv);
myservov.write(posv); delay(15);}

if ((valorA2 - (valorA0+valorA1)/2) < -10) {
if (posh < 126) posv=posv+2;
Serial.print(valorA2 - valorA0);Serial.print(“SumaV”); Serial.println(posv);
myservov.write(posv); delay(15);}
// Serial.println(“HORIZONTAL HORIZONTAL”);
}

}

Jopapa
www.jopapa.me

Bueno, gracias por los comentarios, intentaré ver que tal va con lo que me sugieren.

Bueno, les actualizo la situación actual, el código que me diste tu @carmeloco me sirvió bien, al menos no vibra como loca cuando le pongo mas luz a una LDR que a la otra. Por otra parte @Jopapa , tu código esta bueno, pero como tiene 3 resistencias se me hace mas complicado hacerlo, pero tu proyecto apunta a lo mismo que al mio, salvo que en vez de seguir la luz solar de manera vertical, el mio lo sigue solo por una línea horizontal, me sirvió bien lo de los serial print, porque realmente me facilita eso, solo quisiera saber donde van los datos de los Serial.print(), al IDE del arduino?

Bueno, les actualizo. Logré, con el S4A, hacer funcionar el motor tal cual necesito que funcione, mi pregunta ahora sería si, usando el modelo que tiene el link de arduteka que dejé, lograr hacer el mismo código en el IDE de Arduino, realmente estoy bastante desorientado en ese asunto, y si me pueden ayudar, pues les estaría agradecido, yo seguiré intentando resolver el asunto, pero les dejo el pedido de ayuda porque quizá tienen ganas de hacerlo o saben como, o tienen algún código por ahí que se le parezca. Desde ya muchas gracias de todas formas. Y saludos también por que no jaja!

el codigo que pides es mas o menos asi en la parte

int posicion = 90;
int diferencia;

void setup() {
    // incializar lo que corresponda
}

void loop() {
diferencia = analogRead(A2) - analogRead(A1);
if (diferencia > 50) posicion -= 2;
if (diferencia > 100) posicion -= 4;
if (diferencia < -50) posicion += 2;
if (diferencia < -100) posicion += 4;
if (diferencia > 189) posicion = 189;
if (diferencia < -189) posicion = -189;
if (diferencia < 2) posicion = 0;
//comandar el motor con la posicion
delay(300);
}

surbyte:
el codigo que pides es mas o menos asi en la parte

int posicion = 90;

int diferencia;

void setup() {
   // incializar lo que corresponda
}

void loop() {
diferencia = analogRead(A2) - analogRead(A1);
if (diferencia > 50) posicion -= 2;
if (diferencia > 100) posicion -= 4;
if (diferencia < -50) posicion += 2;
if (diferencia < -100) posicion += 4;
if (diferencia > 189) posicion = 189;
if (diferencia < -189) posicion = -189;
if (diferencia < 2) posicion = 0;
//comandar el motor con la posicion
delay(300);
}

Perdón por mi ignorancia desde ya, pero la parte de:

if (diferencia < -189) posicion = -189;
if (diferencia < 2) posicion = 0;

No debería ser:

if (posicion < -189) posicion = -189;
if (posicion < 2) posicion = 0;

O sea, esa parte está para que el servo no explote en pedacitos porque supera el límite de los 180º de giro que tiene, en realidad el tipo del tutorial lo hizo mal y debería ser en vez de 189, 179, y establecer la posición a 179 sin importar que pase alrededor.

Al menos, yo cuando lo hice en el S4A lo establecí así.
En cuanto pueda probaré el código que me pasaste, modificando eso que creo que es distinto, y te cuento.
Desde ya gracias!
Saludos!

Creo que tienes razón pero no lo analicé simplemente lo transcribí aunque es coherente lo que dices. Es un limite para el movimiento del servo.

Porque usas LDR y no un par de FOTOTRANSISTORES que son mucho mas coincidentes en sus respuestas?. Las LDR son muy disimiles vs los fototransistores o fotodiodos que respondan al espectro de luz visible claro está. Yo hice algo en la secundaria con dos fototransistores y era justamente un seguidor solar que movia un panel solar. Eran dos transistores que alimentaban un AO AMplificador operacional que amplficaba la diferencia y movía a un lado u otro un motor DC.

En fin.. solo un comentario,ya tienes las LDR y estas encaminado.

surbyte:
Creo que tienes razón pero no lo analicé simplemente lo transcribí aunque es coherente lo que dices.
Es un limite para el movimiento del servo.

Porque usas LDR y no un par de FOTOTRANSISTORES que son mucho mas coincidentes en sus respuestas?.
Las LDR son muy disimiles vs los fototransistores o fotodiodos que respondan al espectro de luz visible claro está.
Yo hice algo en la secundaria con dos fototransistores y era justamente un seguidor solar que movia un panel solar.
Eran dos transistores que alimentaban un AO AMplificador operacional que amplficaba la diferencia y movía a un lado u otro un motor DC.

En fin… solo un comentario,ya tienes las LDR y estas encaminado.

Solo para que quede asentado:
FUNCIONAAAAAAA, Estoy feliz, muy feliz jajaja

Les dejo el código final:

/*
El sistema consta de una placa Arduino MEGA2560 con un servo motor de 2kg conectado al PIN 22 de la placa.
Posee además 2 fotoresistencias que utilizan la salida de 5V y cierran su circuito en los pines A1 y A3 de
la placa, con una resistencia de 1k cada una para evitar que la placa se queme en caso que la FotoRes llegue
a tener una resistencia de 0 Ohms.
*/
#include <Servo.h>
Servo servo_pin_22;

int posicion = 90; //Define la variable posición del servo, 90°.
int diferencia; //Define la variable diferencia que se verifica en la comparacion de los LDR.
void setup() {
  servo_pin_22.attach(22); //El Arduino utiliza el PIN 22 para el mov del servo (hacia el cable amarillo).
}
void loop()
{
  diferencia = analogRead(A1) - analogRead(A3);
  if (diferencia > 100) posicion -= 4; //Si la comparación da a traves de A1 > A3 entonces el servo vuelve.
  if (diferencia < -100) posicion += 4; //Si la comparación da a traves de A3 > A1 entonces el servo aumenta.
  if (posicion > 178) posicion = 178; //Esto evita que el servo fuerze sus grados por encima de 178°.
  if (posicion < 2) posicion = 2 ; //Esto evita que el servo fuerze sus grados por debajo de 2°.
  servo_pin_22.write(posicion); //Mueve el Servo a la posición que dan las variables.
  delay (300); //Tiempo entre cada movimiento del servo.
}

Les agradezco mucho la ayuda!

De nada seguro que ahora que ves la traducción, la entiendes y con el tiempo y los programas te iras familiarizando.

A disfrutar!!!

Hola a todos los que siguen el tema, he actualizado el código (en realidad nada mas le he agregado comentarios) para que sea más facil comprenderlo. Saludos!

Ponle solucionado al titulo.