Después de un ratazo con el código manejo el motor dc 12v canijo de las fotos a una resolución de 10 pasos por vuelta a esta velocidad de giro con un código optimizado en lo posible para que mientras este buscando la posición que le diga no tenga que hacer mas procesos que leer el encoder, el arduino no da para mucho en este sentido.
Realmente el encoder con mi código tiene una resolución de 50 pasos con medios pasos, osease 100 efectivos, pongamos que el motor es capaz de darnos unas 1000rpm, 1000rpm/60= a 16,6rpm por segundo que * 100 pasos de resolución del encoder nos da 1660 pulsos por segundo recibidos del encoder, lo que nos obligaría a leer pulsos cada menos de medio mili segundo. No se si el arduino podrá leer a mas velocidad pero yo de momento no se programarlo para ello, directamente el código pasa de cierta cantidad de pulsos del encoder, proporcional a la velocidad.
Esquema del L293
En el montaje de los servos el disco del encoder podría ir despues de la reductora del motor, así que la velocidad de giro a máxima corriente entregada al motor, no superaría las 300rpm, 5 por segundo a máxima velocidad, que seria 1 segundo entre (5 rps * 10 pasos por ejemplo) cada 20 ms una lectura, y a bajas velocidades.
Sabiendo el tiempo entre paso y paso, se puede ajustar la tensión de modo que a mas carga mas voltaje enviado al motor y a menos carga lo inverso, de modo que se mantengan las rpm deseadas lo mas posible, pero esto lo implementare en la próxima atacada que le de al código, ademas no tengo nada con lo que hacer el puente h del motor gordo.
Este seria el codigo asta ahora:
#define velocidadRodillaI 3 // timer 2 (pines 3 y 11) a 31khz
#define extensionRodillaI 52
#define flexionRodillaI 50
int hope, posicion, optico1B, optico2B, optico1, optico2, conta, dir;
int dig2, valor, numBytes;
void setup()
{
posicion=0, optico1B=0, optico2B=0, conta=0;
byte mask = B11111000;
TCCR2B &= mask;
TCCR2B |= (0<<CS22) | (0<<CS21) | (1<<CS20);
pinMode(24, INPUT);
pinMode(26, INPUT);
pinMode(velocidadRodillaI, OUTPUT);
pinMode(extensionRodillaI, OUTPUT);
pinMode(flexionRodillaI, OUTPUT);
Serial.begin(9600);
}
void loop()
{
optico1B=optico1; // guardamos la posicion anterior del encoder
optico2B=optico2;
optico1=digitalRead(24); // leemos 0 o 1 del sensor optico en sus dos canales
optico2=digitalRead(26); // segun que canal sea primero uno y cual cero, sabremos la direccion de giro.
if(optico1==0 && optico2==0)
{
if(optico1B==1 && optico2B==0) posicion++;
else if(optico1B==0 && optico2B==1) posicion--;
}
else if(optico1==1 && optico2==1)
{
if(optico1B==0 && optico2B==1) posicion++;
else if(optico1B==1 && optico2B==0) posicion--;
}
if(hope < posicion) // avanza hasta
{
analogWrite(velocidadRodillaI, 255); // duty cicle al 50%
digitalWrite(extensionRodillaI, LOW);
digitalWrite(flexionRodillaI, HIGH);
}
else if(hope > posicion) // retroceso hasta
{
analogWrite(velocidadRodillaI, 255); // duty cicle al 50%
digitalWrite(extensionRodillaI, HIGH);
digitalWrite(flexionRodillaI, LOW);
}
else if(hope == posicion || hope==0) // ruitinas I/O cuando el micro queda "liberado" de cargas
{
analogWrite(velocidadRodillaI, 0); // duty cicle al 50%
digitalWrite(extensionRodillaI, LOW);
digitalWrite(flexionRodillaI, LOW);
Serial.print("Actual: ");
Serial.print(optico1, DEC); // por control de momento visualizamos los dos canales del encoder por serial
Serial.print(" / ");
Serial.print(optico2, DEC);
Serial.print(" anterior: ");
Serial.print(optico1B, DEC); // por control de momento visualizamos los dos canales del encoder por serial
Serial.print(" / ");
Serial.print(optico2B, DEC);
Serial.print(" Pos: ");
Serial.print(posicion, DEC);
Serial.print(" Hope: ");
Serial.println(hope);
numBytes=Serial.available();
if(numBytes>0 )
{
valor=Serial.read();
if(valor!=0) valor=valor-48;
dig2=Serial.read();
dig2=dig2-48;
Serial.flush();
hope=(valor*10)+dig2;
}
// posicionamos el motor en diferentes puntos una vuelta en un sentido y otra en el contrario
// asi que podemos borrar estos 4 if y posicionar por serial
if(conta==0) dir=1;
if(conta==10) dir=0;
if(dir==1)
{
hope=hope+2;
conta++;
delay(500);
}
else if(dir==0
)
{
hope=hope-2;
conta--;
delay(500);
}
}
} // FIN loop
#define velocidadRodillaI 3 // timer 2 (pines 3 y 11) a 31khz
#define extensionRodillaI 52
#define flexionRodillaI 50
int hope, posicion, optico1B, optico2B, optico1, optico2, conta, dir;
int dig2, valor, numBytes;
void setup()
{
posicion=0, optico1B=0, optico2B=0, conta=0;
byte mask = B11111000;
TCCR2B &= mask;
TCCR2B |= (0<<CS22) | (0<<CS21) | (1<<CS20);
pinMode(24, INPUT);
pinMode(26, INPUT);
pinMode(velocidadRodillaI, OUTPUT);
pinMode(extensionRodillaI, OUTPUT);
pinMode(flexionRodillaI, OUTPUT);
Serial.begin(9600);
}
void loop()
{
optico1B=optico1; // guardamos la posicion anterior del encoder
optico2B=optico2;
optico1=digitalRead(24); // leemos 0 o 1 del sensor optico en sus dos canales
optico2=digitalRead(26); // segun que canal sea primero uno y cual cero, sabremos la direccion de giro.
if(optico1==0 && optico2==0)
{
if(optico1B==1 && optico2B==0) posicion++;
else if(optico1B==0 && optico2B==1) posicion--;
}
else if(optico1==1 && optico2==1)
{
if(optico1B==0 && optico2B==1) posicion++;
else if(optico1B==1 && optico2B==0) posicion--;
}
if(hope < posicion) // avanza hasta
{
analogWrite(velocidadRodillaI, 255); // duty cicle al 50%
digitalWrite(extensionRodillaI, LOW);
digitalWrite(flexionRodillaI, HIGH);
}
else if(hope > posicion) // retroceso hasta
{
analogWrite(velocidadRodillaI, 255); // duty cicle al 50%
digitalWrite(extensionRodillaI, HIGH);
digitalWrite(flexionRodillaI, LOW);
}
else if(hope == posicion || hope==0) // ruitinas I/O cuando el micro queda "liberado" de cargas
{
analogWrite(velocidadRodillaI, 0); // duty cicle al 50%
digitalWrite(extensionRodillaI, LOW);
digitalWrite(flexionRodillaI, LOW);
Serial.print("Actual: ");
Serial.print(optico1, DEC); // por control de momento visualizamos los dos canales del encoder por serial
Serial.print(" / ");
Serial.print(optico2, DEC);
Serial.print(" anterior: ");
Serial.print(optico1B, DEC); // por control de momento visualizamos los dos canales del encoder por serial
Serial.print(" / ");
Serial.print(optico2B, DEC);
Serial.print(" Pos: ");
Serial.print(posicion, DEC);
Serial.print(" Hope: ");
Serial.println(hope);
numBytes=Serial.available();
if(numBytes>0 )
{
valor=Serial.read();
if(valor!=0) valor=valor-48;
dig2=Serial.read();
dig2=dig2-48;
Serial.flush();
hope=(valor*10)+dig2;
}
// posicionamos el motor en diferentes puntos una vuelta en un sentido y otra en el contrario
// asi que podemos borrar estos 4 if y posicionar por serial
if(conta==0) dir=1;
if(conta==10) dir=0;
if(dir==1)
{
hope=hope+2;
conta++;
delay(500);
}
else if(dir==0
)
{
hope=hope-2;
conta--;
delay(500);
}
}
} // FIN loop
Edito: dejo este link a pagina con brazo robotico y redes neuronales
hola miguel te felicito por tu blog. Mira precisamente tengo este motor con la tarjeta q tiene el encoder instalado y me gustaria controlar la velocidad de este motor, pero no he podido encontrar el datasheet del encoder para saber como conectarlo y no quisiera dañarlo. Me podrias dibujar un esquema de como conectar el encoder y el motor a la arduino. Te lo agradeceria mucho
ResponderEliminar