#define debounce_time 200 // 200 ms es un valor muy conservador
hw_timer_t *timer = NULL;
volatile int array[6];
const int motor_A = 23;
const int motor_B = 22;
const int motor_C = 19;
const int motor_D = 18;
const int horario=5;
const int antihorario=4;
volatile int i=0;
volatile int j=0;
volatile int k=0;
volatile int w=0;
volatile int p=0;
const int ADC=34;
const int INTERRUPTOR=35;
const int PULSADOR=32;
const int seta=15;
const int salida_seta=13;
float duracion=10;
#define NUMSEC 4 // 4 u 8 # lineas de secuencia de movimiento
int tabla_pasos[NUMSEC][4]={ // A B C D
// {HIGH,LOW, LOW, LOW},
{HIGH,HIGH, LOW, LOW},
// {LOW, HIGH, LOW, LOW},
{LOW, HIGH, HIGH,LOW},
// {LOW, LOW, HIGH,LOW},
{LOW, LOW, HIGH,HIGH},
// {LOW, LOW, LOW, HIGH},
{HIGH,LOW, LOW, HIGH}
};
#define NPASOS_VUELTA_INTERNA 32 // 32 paso completo, 64 semipaso
#define RELACION_VUELTAS_ENGRANAJE 64 // VUELTAS INTERNAS PARA HACER 1 VUELTA EXTERNA
int npasos=0; // llega a NPASOS_VUELTA_INTERNA y cuenta vuelta interna ++
int nvueltas_internas=0; // llega a RELACION_VUELTAS_ENGRANAJE y cuenta vuelta externa ++
int nvueltas_externas=0; // lleva la cuenta de vueltas del eje externo
// funcion que proporciona el movimiento del siguiente paso
void sgte_paso(){
static int idsec=0; // va recorriendo la siguiente tabla
// escribimos los valores nuevos de la tabla en los pines ABCD
digitalWrite(motor_A, tabla_pasos[idsec][0]);
digitalWrite(motor_B, tabla_pasos[idsec][1]);
digitalWrite(motor_C, tabla_pasos[idsec][2]);
digitalWrite(motor_D, tabla_pasos[idsec][3]);
if( (++idsec)==NUMSEC) idsec=0;
return;
}
void sgte_paso_inverso(){
static int idsec=0; // va recorriendo la siguiente tabla
// escribimos los valores nuevos de la tabla en los pines ABCD
digitalWrite(motor_D, tabla_pasos[idsec][0]);
digitalWrite(motor_C, tabla_pasos[idsec][1]);
digitalWrite(motor_B, tabla_pasos[idsec][2]);
digitalWrite(motor_A, tabla_pasos[idsec][3]);
if( (++idsec)==NUMSEC) idsec=0;
return;
}
volatile unsigned long current_millis1 = 0;
volatile unsigned long last_interrupt_time1 = 0;
void IRAM_ATTR ISR_SETA(){
current_millis1 = millis();
if (current_millis1 - last_interrupt_time1 > debounce_time && j==0){
digitalWrite(salida_seta,LOW);
i=10;
j=1;
timerAlarmEnable(timer);
k=0;
for(w=0;w<6;w++){
array[w]=0;
}
}
last_interrupt_time1 = current_millis1;
}
void IRAM_ATTR finTimer(){
if(digitalRead(seta)==HIGH){
array[k]=1;
if(k>=5){
for(w=0;5>w;w++){
array[w]=array[w+1];
}
}
else{
k++;
}
}
if(digitalRead(seta)==LOW){
array[k]=0;
if(k>=5){
for(w=0;5>w;w++){
array[w]=array[w+1];
}
}
else{
k++;
}
}
p=0;
for(w=0;6>w;w++){
p=p+array[w];
}
if(p==6){
i=0;
j=0;
}
}
volatile unsigned long current_millis = 0;
volatile unsigned long last_interrupt_time = 0;
void IRAM_ATTR ISR(){
current_millis = millis();
if (current_millis - last_interrupt_time > debounce_time){
int adcVal = analogRead(ADC);
duracion =(-4/819)*adcVal+25;
if(digitalRead(INTERRUPTOR)==HIGH){
i=0;
}
else{
i=1;}
last_interrupt_time = current_millis;
}
}
void setup()
{
// pines de salida del motor
pinMode(motor_A, OUTPUT);
pinMode(motor_B, OUTPUT);
pinMode(motor_C, OUTPUT);
pinMode(motor_D, OUTPUT);
pinMode(horario,OUTPUT);
pinMode(antihorario,OUTPUT);
pinMode(seta,INPUT);
pinMode(INTERRUPTOR, INPUT);
pinMode(salida_seta,OUTPUT);
pinMode(PULSADOR,INPUT);
digitalWrite(salida_seta,HIGH);
// initialize the serial port
Serial.begin(9600);
delay(100);
Serial.println("----------------");
Serial.println("Comienzo programa control motor paso a paso");
Serial.printf("Pasos de secuencia de movimiento -> %d\n", NUMSEC);
Serial.printf("Npasos 32 paso completo, 64 semipasode -> %d\n", NPASOS_VUELTA_INTERNA);
Serial.printf("Relacion engranaje - %d vueltas internas para dar 1 vuelta externa \n \n", RELACION_VUELTAS_ENGRANAJE);
attachInterrupt(digitalPinToInterrupt(PULSADOR),ISR,RISING);
attachInterrupt(digitalPinToInterrupt(seta),ISR_SETA,RISING);
analogReadResolution(12);
analogSetAttenuation(ADC_11db);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, & finTimer, true);
timerAlarmWrite(timer, 500000, true);
delay(1000);
}
unsigned long t1=0;
void loop()
{
delay(duracion);
if(i==0){
digitalWrite(horario,HIGH);
digitalWrite(antihorario,LOW);
npasos++; //si llega a NPASOS_VUELTA_INTERNA -> cuenta nvueltas interna ++
if(npasos == NPASOS_VUELTA_INTERNA){
npasos=0;
nvueltas_internas++;
if(nvueltas_internas==RELACION_VUELTAS_ENGRANAJE){ // llega a RELACION_VUELTAS_ENGRANAJE y cuenta vuelta externa ++
nvueltas_internas=0;
nvueltas_externas++; // lleva la cuenta de vueltas del eje externo
}
}
sgte_paso(); // mueve el motor
}
else if(i==1){
digitalWrite(antihorario,HIGH);
digitalWrite(horario,LOW);
npasos--; //si llega a NPASOS_VUELTA_INTERNA -> cuenta nvueltas interna ++
if(npasos == -NPASOS_VUELTA_INTERNA){
npasos=0;
nvueltas_internas--;
if(nvueltas_internas==RELACION_VUELTAS_ENGRANAJE){ // llega a RELACION_VUELTAS_ENGRANAJE y cuenta vuelta externa ++
nvueltas_internas=0;
nvueltas_externas--; // lleva la cuenta de vueltas del eje externo
}
}
sgte_paso_inverso(); // mueve el motor
}
else{
digitalWrite(horario,HIGH);
digitalWrite(antihorario,HIGH);
delay(500);
digitalWrite(horario,LOW);
digitalWrite(antihorario,LOW);
}
if(i==0 || i==1){
// cada dos segundos imprime mensaje de información
if(millis()>t1+2000){ // 1*32 en paso completo para una vuelta, 2*32=64 si se va de medio paso
t1=millis();
Serial.printf("Vueltas externas %d internas %d npasos: %d \n",
nvueltas_internas, nvueltas_externas, npasos);
}
}
}