Cientificosaficionados.com

Los foros de los científicos aficionados de la red.
Fecha actual Vie Jul 10, 2020 8:46 pm

Todos los horarios son UTC [ DST ]




Nuevo tema Responder al tema  [ 13 mensajes ]  Ir a página 1, 2  Siguiente
Autor Mensaje
NotaPublicado: Dom Mar 04, 2018 5:49 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
tenia el profe un espectrometro viejo, que queria automatizar.

Hard: motor paso a paso, lectura del detector, y dos finales de carrera, el de cero muy curioso, el micro contacto alimenta al diodo IR, de forma que la muesca en el disco al eje, detectada por el foto diodo, clava la posicion, aumenta la precision del microcontacto.

se pudo haber hecho un programilla que a golpe de pulsador se resetease y enviase un espectro, pero no tendria opciones.

y entonces me lie de mala manera, demasiado para lo que se necesitaba.
Si queremos atender a la vez: el puerto de comunicaciones, el motor, y la lectura,,,, no queda otra que usar interrupciones para los 3.

la cosa resulto bastante enorme, como tal espectrometro no creo que interese a nadie, pero por trocitos si.
de todas formas podeis simular su funcionamiento, 4 leds en vez de motor, dos pulsadores como finales carrera, y tocais con el dedito para simular la lectura.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 5:53 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
test7.ino

Código:
//aqui poner cualquier tonteria,
//
//el .ino lo usa el entorno arduino para arrancar el proyecto.
//
//el arduino es para niños
//el wiring  es para niños pequeños
//los hombres usamos c

pues eso, yo no uso wiring, me parece una kk, es lento como vimos en la flecha del anajesusa, sentencias potentes a costa de perder flexibilidad, memoria, y rapidez.

parece que el IDE necesita una carpeta unica, llamada como el proyecto, dentro lo demas, Y EL .ino. da igual lo que ponga, pero que ponga algo.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 6:00 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
MAIN.c
Código:
#include <avr/io.h>
#include <string.h>
#include "usart2.h"
#include "interprete.h"    //
#include "salto.h"    //
#include "motor.h"    //
#include "adc2.h"    //
#include "landas.h"    //


int   main(void){
   SerialInit();
   TXdirec_s("test de TXdirec_s.  ");
   TX_s_n("type h para help ");
   MotorReset();   
   LandaReset();   
   ADCInit();
   
   while (1){
      if (RXstatus==1){
         if(eco){
            strcpy(bufTX,bufRX);
            TXLanza();
            while(bitRead(UCSR0B,UDRIE0)){}         //espera a terminar, hasta no interrupcion
            }
         Interprete(bufRX);
         RXReset();
         }
      if(RXerror){TXdirec_s("* * * ERROR EN RX ");TXdirec(RXerror);   TXdirec_s(" \n"); RXerror=0;}
      if(TXerror){TXdirec_s("* * * ERROR EN TX ");TXdirec(TXerror);   TXdirec_s(" \n"); TXerror=0;}
      if(motorerror=='E'){   MotorTexto(3);   motorerror=0;}//FC inesperado
      if(motorerror){         TX_s(str[1].str);   TX(motorerror);   TX('\n'); motorerror=0;}
      }
   }


esta es la main, el bucle principal que lo controla todo,
los includes,
las inicializaciones de todo, (el setup() de arduino), usart, motor, lector.

entra en bucle, si recibio un parrafo (RXstatus==1) si esta en eco lo reenvia,
lo pasa al interprete, (y alli,,,,)
lo borra,
si hay errores los canta.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 6:17 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
usart2.h
Código:
#ifndef usart2   
#define usart2

#ifndef Arduino_h      //para compatib AVStudio
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitXor(value, bit) ((value) ^= (1UL << (bit)))
#endif

#define UBRRn 103             // 16MHz, 9600 BAUD rate
#define BUF_SIZE 50
//#define PINLED 0x20 //del puerto  B, en placa D13  //ESTA ES LA  MASCARA, no el nº de bit
#define PINLED 5             //del puerto  B, en placa D13

char   bufRX[BUF_SIZE+3];     //le da un poco mas de bufer, porsi
char   *ptrRXfin;
char   *ptrRXin;
char   *ptrRXout;
char   volatile  RXstatus;      //EL STATUS ES LO QUE HAY QUE MIRAR POR SI LLEGO PARRAFO
char   volatile  RXerror;       //volatiles porque pas puede cambiar interrupcion
char   volatile  RXllegoc;

char   bufTX[BUF_SIZE+3];
char   *ptrTXfin;
char   *ptrTXin;
char   *ptrTXout;
char   volatile  TXstatus;
char   volatile  TXerror;


void   SerialInit(void);
void   RXReset(void);
void   TXReset(void);
char   RXBuferMete(char c);
char   RXBuferMete_s(char *s);
char   RXBuferSaca(void);

char   TXuferMete(char c);
char   TXuferMete_s(char *s);
char   TX(char c);            //ABREVIACION DE BUFER METER c// ESTAS SON LAS QUE HAY QUE USAR,
char   TX_s(char *s);         //ABREVIACION DE BUFER METER s
char   TX_s_n(char *s);      //ABREVIACION DE BUFER METER s, + salto linea
char   TXBuferSaca(void);

void   TXLanza(void);         //una vez lleno el bufer TX, lo lanza, mediante interrupciones
char   TXLanzaTest(void);
void   TXLanzaEspera(void);   //ESPERA A TERMINAR

void   TXdirec(char dato);         //ENVIA DATO A CAÑON //USADO EN DEBUG
void   TXdirec_s(char *s);         //ENVIA PARRAFO, por libre, no bufer

//ISR(USART_RX_vect);
//ISR(USART_UDRE_vect);

#endif


usart2.c
Código:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usart2.h"

void   SerialInit(void) {                     //INICIO DE USART
   UBRR0H = (unsigned char)(UBRRn>>8);      UBRR0L = (unsigned char)UBRRn;   //baudios

   DDRD |= (1<<DDD3);   //puerto out
   UCSR0B = (1<<RXEN0) | (1<<TXEN0);
   UCSR0C = (1<<USBS0) | (3<<UCSZ00);
   
   cli();
   UCSR0B |= (1<<RXCIE0);// | (1<<UDRIE0);// | (1<<TXCIE0);
   sei();

   ptrRXfin=bufRX + BUF_SIZE;               //puntero fin, usado para ver si se desmadro
   ptrTXfin=bufTX + BUF_SIZE;               //se pone aqui para ahorrar tiempo en resets
   RXReset();      TXReset();               //reset de variables
   }
//-------------------   
void   RXReset(void) {                     //RX reset
   ptrRXin=bufRX;      ptrRXout=bufRX;         //punteros de meter y sacar a inicio
   *ptrRXin=0;                           //pone 0 como marca de final
   RXstatus=0;         RXerror=0;            //status y error a 0
//   RXllegoc=0;                           //usado en interrup motor  para parar
   }
void   TXReset(void) {                     //TX reset
   ptrTXin=bufTX;      ptrTXout=bufTX;         //lo mismo
   *ptrTXin=0;
   TXstatus=0;         TXerror=0;
   }
//-------------------   
char   RXBuferMete(char c){               //METE UN c EN EL BUFER
   if(ptrRXfin<ptrRXin){                  //si se desmadro
      RXReset();      RXerror='1';   return(RXstatus);
      }                              //lo resetea, y marca error
   switch(c){                           //segun lo que llegue
      case 0:      case '\n':      case '\r':   //si 0 cr lf
               if(ptrRXin==bufRX){         //si no habia nada en el bufer
                  RXstatus=0;   return(RXstatus);   //lo ignora, seguramente un cr y lf
                  }
               RXstatus=1;               //fin de parrafo, lo marca.
               break;
      default:   RXstatus=0;               // caracter normal,
               *ptrRXin=c;   ptrRXin++;   *ptrRXin=0; //pone, incrementa, y marca final
               break;
      }   
   return(RXstatus);                     //retorna el status.
   }
char   RXBuferMete_s(char *s){               //METE UN PARRAFO EN BUFER
   while(*s){RXBuferMete(*s);   s++;}
   return(RXstatus);
   }
char   RXBuferSaca(void){                  //SACA DEL BUFER
   if(ptrRXfin<ptrRXin){                  //si se desmadra leyendo
      RXReset();      RXerror='2';   return(0);   //lo resetea, marca error, sale diciendo que termino
      }
   char c=*ptrRXout;                     //lee segun puntero out
   ptrRXout++;                           //incrementa puntero
   return(c);                           //reorna caracter
}
//-------------------   
char   TXBuferMete(char c){               //METE UN c EN EL BUFER //   S I   \n   L A N Z A   A U T O M A T I C O
  TXLanzaEspera();                         //SI ESTA LANZANDO, ESPERA
   if(ptrTXfin<ptrTXin){                           //lo mismo que arriba,,,,
      TXReset();      TXerror='1';   return(TXstatus);
      }
   switch(c){
      case 0:      break;            //aqui distinto arriba, si entra 0 lo ignora
      case '\n':      case '\r':
               if(ptrTXin==bufTX){
                  TXstatus=0;   return(TXstatus);
                  }
               TXstatus=1;
               TXLanza();         // S I   L L E N A   L O   L A N Z A
               break;
      default:   TXstatus=0;
               *ptrTXin=c;      ptrTXin++;      *ptrTXin=0;
               break;
      }   
   return(TXstatus);
   }
char   TXBuferMete_s(char *s){
   while(*s){TX(*s);   s++;}
   return(TXstatus);
   }
char   TXBuferSaca(void){
   if(ptrTXfin<ptrTXin){   
      TXReset();      TXerror='2';   return(0);
      }
   char c=*ptrTXout;
   ptrTXout++;
   return(c);
   }

//-------------------   
void   TXLanza(void){                              //INICIA SALIDA DEL TX 
   TXLanzaEspera();
   while(!bitRead(UCSR0A,UDRE0)){   }                  //espera a libre
   UDR0 = TXBuferSaca();                           // a usart lo que lee
   UCSR0B |= (1<<UDRIE0);                           //enabla interrupcion de registro de salida libre
   }
char   TXLanzaTest(void){                           //PREGUNTA SI AUN ACTIVA
   return(bitRead(UCSR0B,UDRIE0));                     //pregunta si aun interrupcion
   }
void   TXLanzaEspera(void){                        //ESPERA A TERMINAR
   while(TXLanzaTest()) {}                            //pregunta si aun interrupcion
   }
//-------------------   
char   TX(char c){                                 //ABREVIACION DE BUFER METER c
   TXBuferMete(c);
   }
char   TX_s(char *s){                              //ABREVIACION DE BUFER METER s
   TXBuferMete_s(s);
   return(TXstatus);
   }
char   TX_s_n(char *s){                           //ABREVIACION DE BUFER METER s, + salto de linea
   TXBuferMete_s(s);
   TXBuferMete('\n');
   return(TXstatus);
   }
//-------------------   
//-------------------                              // U S A D O   E N   D E B U G 
void   TXdirec(char dato){                           //ENVIA DATO A CAÑON, sin interrupciones ni bufer
   while(!bitRead(UCSR0A,UDRE0)){   }                 //espera a libre
   UDR0 = dato;
   }
void  TXdirec_s(char *s){                              //ENVIA PARRAFO, por libre, no bufer
   while(*s){TXdirec(*s);   s++;}
   }   

//-------------------   
//-------------------   
ISR(USART_RX_vect) {                              //RUTINA DE INTERRUPCION DE RECEPCION
   RXBuferMete(UDR0);                              //mete en bufer lo que llega
   RXllegoc++;                                    //USADO PARA PARAR MOTOR
   }

ISR(USART_UDRE_vect) {                              //RUTINA DE INTERRUPCION DE REGISTRO LIBRE
   unsigned char c;   // M I R A R   L A   I N T   D A T O   E N V I A D O , esta tiene = prioridad que TXdirec(), no interesa
   c=TXBuferSaca();                              //saca del bufer
   switch(c){                                    //segun lo que sea
      case 0:      case '\n':      case '\r':            //si es algun final
               UDR0 = '\n';                     //envia un salto de linea
               UCSR0B ^= (1<<UDRIE0);               //inhabilita la interrupcion
               TXReset();                        //resetea el bufer
               break;
      default:   
               UDR0 = c;                        // si es c normal, lo envia.
               break;
      }   
   }   
   

lo 1º es comunicarse.
la gestion se hace por parrafos, no letrita a letrita,
letrita que llega, salta la interrupcion, y alli se encarga de ponerla en un bufer,
si llega un final, un caracter '\n', o '\r', levanta bandera de RXstatus que ya vimos, que indica parrafo listo para gestionar.
dependiendo los equipos, o llega "nueva linea", o "carri return", o los dos, lo que complica algo la cosa.

ES POR ESTO QUE DESDE LA CONSOLA DE ARDUINO HAY QUE SELECIONAR, \n COMO FINAL DE PARRAFO. (abajo derecha)

para emitir tambien, bufer,,, y \n, para decirle que ya lo puede enviar (con su interrupcio).

ademas de este metodo, contaba con otro que lanza a cañon sin interrupciones, el TXdirec(), esto lo use para depurar el metodo de interrupciones, y siempre viene bien tenerlo porsi,

cuando queremos transmitir, se escribe en una memoria, y el hard lo envia, si aun envia el anterior tiene que esperar, hay dos interrupciones, enviado y memoria libre, ahora mismo no se cual use, en otros micros esto me calento cabeza, no iba como dicen, la idea es que TXdirect tenga preferencia, pero me entran dudas.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 6:28 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
interprete.h
Código:
#ifndef interprete
#define interprete

#define   coman_ancho 16      // A Q U I   S E   D E F I N E   E L   A N C H O   D E   P A R R A F O   P A T R O N

//   typedef void (*pf)(void);   //void  *(pf) (void); ASI NO   
//   static    pf tabsal[2];      //ejemplo sencillo
   typedef struct {         //plantilla de un renglon de la tabla de saltos
      char coman[coman_ancho];//comando en prosa   
      void (*pf)(void);      //puntero a la funcion   
      }saltos_InitTypeDef;   //nombre de la plantilla

      
   char    *patron_ptr;      //puntero a parrafo patron
   char   k;               //numero de parrafo patron
   char   n;               //numero de letra
   char   c;               //letra de entrada comparando
   char   p;               //letra del patron
   
   char    Interprete(char *s);      //en s el string a comparar, ret 1 si encontro, 0 no
//   static    void    Ejemplo(void);   //P O N E R   S T A T I C,   O   L O C U R A //en SMT32, en arduino parece que no haace falta
   char    InterpreteBuscar(char *s);

   //-------------------   

char   bd[6];      //resultado de chart o int a asci decimal
char   hexa[5];   //resultado de chart o int a asci hexadecimal
int    di;         //resultado de decimal a int

char*   ByteDeci_cc(char ch,char cl);   //PASA 2 CHAR A 5 DECI
char*   ByteDeci_i(int i);      //PASA 1 INT A 5 DECI
char*   IntDeci(int i);      //PASA 1 INT A 5 DECI  //lo mismo de arriba con otro nombre
int      DeciInt(char c4,char c3,char c2,char c1,char c0);   //PASA 5 CHAR A INT
char   DeciInt2(unsigned char c); 
char   NibleHexa(char ni);
char*   CharHexa(char he);
char*   IntHexa(int in);

#endif



interprete.c
Código:
/**********************************************/
/*   I N T E R P R E T E   C O M A N D O S    */

#include "interprete.h"      //
#include "salto.h"      //
#include "usart2.h"

#include "saltostabla.c"   //  S I ,   S E   I N C L U D E   U N   . C ,,,, bueno,,, en fin,,,

//-------------------   
//-------------------   
char    Interprete(char *s){      // E N   * s   A P U N T A   A   P A R R A F O   A   C O M P A R A R
   char ret=InterpreteBuscar(s);
   if(ret){
      tabsal[k].pf();//DISPARA,  ASI, O NO VA   
      }
   else   {TX_s("COMANDO MAL, type h para help \n");   }
   return(ret);//
   }
//   @=comodin,   $=signo {+, -,' '}   %=decimal   #=hexade   |=fin obligado
char    InterpreteBuscar(char *s){      //en *s el parrafo a comparar
   char *patron_ptr;            //DEVUELVE 0=FRACASO, 1=ENCONTRO CADENA
   k=0;                  //1' parrafo
   while(1){
      n=0;                //1' letra
      patron_ptr=tabsal[k].coman;       //puntero a tabla saltos[k]
      while(1){            //
         c=*(s+n);         //c=letra comparar, matrices lentas
         p=*(patron_ptr+n);      //letra del patron
         n++;            //apunta a siguiente
         if(p==0){   if(n==1){   return(0);}  //acabo candidatos
               else{      return(1);}} //termino, OK
      //   if(p=='|'){   if(c!='\r'){   break;}   //no fin obligado  //version original co \r como final
         if(p=='|'){   if(c!=0){   break;}   //no fin obligado   
               else{      return(1);}}//sale por coincidir con final obligado
         if(p=='@'){   continue;}    //llego COMODIN, a por otra letra
         if(p=='$'){         //tiene que llegar un SIGNO
            if(c==' '){continue;}   //llego ' '
            if(c=='-'){continue;}   //llego -
            if(c=='+'){continue;}   //llego +
            }
         if(p=='%'){         //tiene que llegar un DECIMAL
            if(c<'0'){break;}   //menor que 0, no vale
            if(c>'9'){break;}   //mallor que 9, no vale
            continue;      //lo que queda vale
            }
         if(p=='#'){         //tiene que llegar un HEXADE
            if((c>='0')&(c<='9')){continue;} //entran numeros
            if((c>='A')&(c<='F')){continue;} //entran A,,F
            if((c>='a')&(c<='f')){continue;} //entran a,,f
            }
                  
         if(p!=c){   break;}      //no coincide, a por otro parrafo
         if(!c){      break;}      //fin llave
            
         }//fin de bucle, entonces es que coinciden letras, a por otra   
      k++;   //termino el patron, no salto, a por otro parrafo
      }
   }

   
//-------------------   
//-------------------   
char*   ByteDeci_cc(char ch,char cl){   //PASA 2 CHAR A 5 DECI
   unsigned char c0,c1,c2,c3,c4;
   c0=cl&0x0F;   c1=cl&0xF0;   c1=c1>>4;
   c2=ch&0x0F;   c3=ch&0xF0;   c3=c3>>4;//miro y corrijo desmadre
   c0+=6*c1;   while(c0>9){   c0-=10; c1++;}   c0+=6*(c2+c3);   
   c1+=5*c2 + 9*c3;   c2*=2;      c3*=4;   c4=0x00;     
   while(c0>9){   c0-=10; c1++;}   c0+=0x30;//+0x30 para tener el ascii   
   while(c1>9){   c1-=10; c2++;}   c1+=0x30;     
   while(c2>9){   c2-=10; c3++;}   c2+=0x30;   
   while(c3>9){   c3-=10; c4++;}   c3+=0x30;   c4+=0x30;   
   bd[0]=c4;   bd[1]=c3;   bd[2]=c2;   bd[3]=c1;   bd[4]=c0; bd[5]=0;   
   return(&bd);                              //devuelve la direcion de la conversion
   }

char*   ByteDeci_i(int i){      //PASA 1 INT A 5 DECI
   ByteDeci_cc((char)((i>>8)&0x00FF),(char) (i&0x00FF));
   return(&bd);                              //devuelve la direcion de la conversion
   }
char*   IntDeci(int i){      //PASA 1 INT A 5 DECI  //lo mismo de arriba con otro nombre
   ByteDeci_cc((char)((i>>8)&0x00FF),(char) (i&0x00FF));
   return(&bd);                              //devuelve la direcion de la conversion
   }
//-------------------   
int   DeciInt(char c4,char c3,char c2,char c1,char c0){   //PASA 5 CHAR A INT
   c4=DeciInt2(c4);   c3=DeciInt2(c3);   c2=DeciInt2(c2);   c1=DeciInt2(c1);   c0=DeciInt2(c0);
   di=c0 + (c1*10) + (c2*100) + (c3*1000) + (c4*10000);
   return(di);
   }
char   DeciInt2(unsigned char c){ 
   c=c-0x30; if(c>9){c=9;}
   return(c);
   }
//------------------- 
char   NibleHexa(char ni){                        //un nible lo pasa a ascii
   char c;
   ni=ni&0x0F;
   c=(ni+0x30);   if(c>0x39){c+=6;}
   return(c);                                 //return el ascii
   }

char*   CharHexa(char he){                        //un char lo pasa a 2 ascii
   char c;
   c=he&0xF0;   c=c>>4;   hexa[0]=NibleHexa(c);
   c=he&0x0F;         hexa[1]=NibleHexa(c);
   hexa[2]=0;
   return(&hexa);                              //devuelve la direcion de la conversion
   }
char*   IntHexa(int in){                        //un int lo pasa a 4 ascii
   int i;
   i=in&0xF000;   i=i>>12;   hexa[0]=NibleHexa((char)i);
   i=in&0x0F00;   i=i>>8;    hexa[1]=NibleHexa((char)i);
   i=in&0x00F0;   i=i>>4;    hexa[2]=NibleHexa((char)i);
   i=in&0x000F;             hexa[3]=NibleHexa((char)i);
   hexa[4]=0;
   return(&hexa);                              //devuelve la direcion de la conversion
   }



Despues de recibir parrafo, lo interpreta.
para eso este motorcillo interprete,
compara letrita a letrita del bufer de entrada con una tabla que veremos.
si coinciden todas debe de ser eso, y si no canta "mal comando".
hay comodines, para meter numeros, y signos,
y otro para forzar final, por ejemplo, hay comando "h" y "h2", escribes h2 y se cuela en el h, que es lo 1º que cumple.

tambien aqui un interprete de ascii a bytes, y al reves.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 6:39 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
salto.h
Código:
#ifndef salto   
#define salto

#ifndef Arduino_h      //para compatib AVStudio
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitXor(value, bit) ((value) ^= (1UL << (bit)))
#endif

char    eco;

void   SaltoLed0(void);
void   SaltoLed1(void);
void   SaltoLedx(void);

void   SaltoEco0(void);
void   SaltoEco1(void);

void   SaltoH(void);

void   SaltoPredefVer(void);
void   SaltoPredefinido(void);      //"predefinido %",

void   SaltoRetardo(void);         //"retardo %"
void   SaltoRetardoRap(void);      //"retardo rap %"
void   SaltoPasos_lectura(void);   //"pasos_lectura %%%"
void   SaltoNlecturas(void);      //"nlecturas %%"
void   SaltoCotah(void);         //"cotah %%%%%"
void   SaltoCotal(void);         //"cotal %%%%%"

void   SaltoPortCLeer(void);
void   SaltoMotorReset(void);
void   SaltoMotorPotencia(void);
void   SaltoMotorSube(void);
void   SaltoMotorBaja(void);
void   SaltoMotorSubeN(void);
void   SaltoMotorBajaN(void);
void   SaltoMotorAparca1(void);
void   SaltoMotorACotaA(void);
void   SaltoMotorACotaB(void);
void    SaltoMotorTestCarrera(void);
void    SaltoMotorEspectro1(void);

void   Debug1(void);         //
void   Debug2(void);         //

#endif

saltostabla.c
Código:
#include "interprete.h"    //
#include "salto.h"    //
#include "landas.h"   //

typedef void (*fptr) (void);    //define una funcion generica, entra void, sale void.
               
//   static    pf tabsal[2]={      //del ejemplo sencillo
   static    saltos_InitTypeDef tabsal[]={
//    #include "tabla.txt"    //!!! INCLUDE UN .TXT  //arruino = KK, no deja include un .txt
//#define  coman_ancho 20  O J O con el ancho, esta en el .h
//  @=comodin,  $=signo {+, -,' '}  %=decimal #=hexade  |=fin obligado
//  "comando ",   Salto.,
//  "012345678901234"  !       O J O con el ancho, tampoco pasarse, come mucha ram
//-------------------   
    "led 1",         SaltoLed1,  //con o sin &
    "led 0",         SaltoLed0,
    "led x",         SaltoLedx,
   
    "eco 1",         SaltoEco1,
    "eco 0",         SaltoEco0,
   
   "h2",            SaltoH,

   "predef ver",      SaltoPredefVer,
   "predefinido %",   SaltoPredefinido,
   
   "retardo %",      SaltoRetardo,
   "retardo rap %",   SaltoRetardoRap,
   "pasos/lect %%%",   SaltoPasos_lectura,
   "cotah %%%%%",      SaltoCotah,
   "cotal %%%%%",      SaltoCotal,
   "debug 1",         Debug1,
   "debug 2",         Debug2,
   
   "reset",         SaltoMotorReset,
   "potencia %",      SaltoMotorPotencia,
   "sube|",         SaltoMotorSube,
   "baja|",         SaltoMotorBaja,
   "sube %%%%",      SaltoMotorSubeN,
   "baja %%%%",      SaltoMotorBajaN,
   "aparca1",         SaltoMotorAparca1,
   "a cota baja",      SaltoMotorACotaB,
   "a cota alta",      SaltoMotorACotaA,
   "test carrera",      SaltoMotorTestCarrera,
   "espectro1",      SaltoMotorEspectro1,
//-------------------      usando landas
   "h|",            LandaHelp,
   "espectro",         LandaEspectro,
   "aparca",         LandaAparca,
   "landal %%%%",      LandaBaja,
   "landah %%%%",      LandaAlta,
   "ir a %%%%",      LandaIrA,
   "dump",            LandaDumpParametros,

      "",   0,//DEJAR SIEMPRE, MARCA EL FINAL !!!!
      };


como veis hay dos columnas, la izquierda son los parrafos a comparar, y derecha, la funcion asociada, que la dispara el propio interprete.

Me hubiese gustado ponerlo como un .txt sin mas historias por arriba, asi lo hice en el c++ de los STMs, mas limpio mas elegante, con el ardu no pude/supe.

LA tabla TERMINA como veis, es la marca de final, y hay que dejarla,
En ningun lado hay que decir cuantas lineas tiene, (ventaja).
pero cada parrafo tiene ancho fijo, no os paseis o machacais al vecino, y entonces lio.
tampoco pasarse de generosos, porque esto come memoria.

salto.c
Código:
#include <avr/io.h>
#include "usart2.h"
#include "salto.h"      //
#include "interprete.h"      //
#include "motor.h"      //
#include "help.h"      //

void   SaltoLed0(void){   bitClear(PORTB, PINLED);   TX_s("Led a 0\n");   }
void   SaltoLed1(void){   bitSet  (PORTB, PINLED);   TX_s("Led a 1\n");   }
void   SaltoLedx(void){   bitXor  (PORTB, PINLED);   TX_s("Led inv\n");   }

void   SaltoEco0(void){   eco=0;   TX_s("Eco 0\n");   }
void   SaltoEco1(void){   eco=1;  TX_s("Eco 1\n");   }

void   SaltoH(void){            TX_s_PGM(); }      //vuelca help

void   SaltoPredefVer(void){      DumpPredefinidos();   }
void   SaltoPredefinido(void){      CargaParametros(DeciInt('0','0','0','0',bufRX[12]));               DumpParametros();}   //"predefinido %",

void   SaltoRetardo(void){         motorretardo=   DeciInt('0','0','0','0',bufRX[8]);                  DumpParametros();}   //"retardo %"
void   SaltoRetardoRap(void){      motorretardorap=DeciInt('0','0','0','0',bufRX[12]);                  DumpParametros();}   //"retardo %"
void   SaltoPasos_lectura(void){   pasos_lectura=   DeciInt('0','0',bufRX[11],bufRX[12],bufRX[13]);         DumpParametros();}   //"pasos_lectura %%%"
void   SaltoCotah(void){         cotah=         DeciInt(bufRX[6],bufRX[7],bufRX[8],bufRX[9],bufRX[10]);   DumpParametros();}   //"cotah %%%%%"
void   SaltoCotal(void){         cotal=         DeciInt(bufRX[6],bufRX[7],bufRX[8],bufRX[9],bufRX[10]);   DumpParametros();}   //"cotal %%%%%"

void   SaltoMotorReset(void){      MotorReset();   }
void   SaltoMotorPotencia(void){   motorpotencia=   (char)DeciInt('0','0','0','0',bufRX[9]);            DumpParametros();}
void   SaltoMotorSube(void){      MotorSube();   }
void   SaltoMotorBaja(void){      MotorBaja();   }
void   SaltoMotorSubeN(void){      MotorSubeN(      DeciInt('0',bufRX[5],bufRX[6],bufRX[7],bufRX[8]));}
void   SaltoMotorBajaN(void){      MotorBajaN(      DeciInt('0',bufRX[5],bufRX[6],bufRX[7],bufRX[8]));}
void   SaltoMotorAparca1(void){   MotorAparca();   }         
void   SaltoMotorACotaB(void){      MotorA(cotal);   }
void   SaltoMotorACotaA(void){      MotorA(cotah);   }
void    SaltoMotorTestCarrera(void){MotorTestCarrera();   }
void    SaltoMotorEspectro1(void){   MotorEspectro();}

y estos son algunos saltos, que incluso interpretan numeros desde el bufer


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 6:52 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
motor.h
Código:
#ifndef motor   
#define motor

#ifndef Arduino_h      //para compatib AVStudio
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitXor(value, bit) ((value) ^= (1UL << (bit)))
#endif

#define MOTORMASCARA      0xF0 //del puerto  B, en placa marcado de D8,,,11,  a 0s los cables motor
#define PINLED         5 //del puerto  B, en placa D13


#define FCMASCARA      3
#define PINFINBAJO        1 //del puerto  C, en placa A0
#define PINFINALTO      2 //del puerto  C, en placa A1
#define PINFINADC      3 //del puerto  C, en placa A2

#define MOTORPARAR      0
#define MOTORNADA      1
#define MOTORSALIRFC      2
#define MOTORSUBIR      3
#define MOTORBAJAR      4
#define MOTORSUBIRN      5
#define MOTORBAJARN      6
#define MOTORAPARCA      7
#define MOTORA         8
#define MOTORHASTA      9
#define MOTORTESTCARR  10
#define MOTORESPECTRO  11
#define MOTORESPECTRO2 12

typedef struct {         //plantilla de string
   char str[32];
   }str_TypeDef;
static    str_TypeDef str[]={
//   "123456789012345678901234567890"
   "ANTES APARCAR",
   "UN ERROR O ABORTO",
   "enviar algo para parar",
   "FCx inesperado",
   };

int    pasos_lectura;    //
int    nlecturas;      //

int    cotah;
int    cotal;

//char potencia; char motorretardo; char motorretardorap; int pasos_lectura; int cotah; int cotal;
typedef struct {         //plantilla de parametros
      char    potencia;
      char    retardorap;         //
      char    retardo;         //
      int    cotal;
      int    cotah;
      int    pasos_lectura;      //
      }parametros_TypeDef;   //nombre de la plantilla

char   volatile   motorproceso;
char   motoraparco;
char   motorasalirfc;

char   motorcosahacer;
char   motorcosahacerbak;
char   PINCbak;
char   motorFCx;      //fin carrera, alguno de los dos
char   motorFCA;      //fin carrera ALTO
char   motorFCB;      //fin carrera BAJO
char   motorretardo;
char   motorretardorap;
char   motorerror;
char   trace;
char   trace2;

char   motorpotencia;
char   motorpalabra0;   // asi mas rapido que con matrices                  
char   motorpalabra1;                     
char   motorpalabra2;                     
char   motorpalabra3;                     

char   motorruleta;
unsigned int   motorpaso;

int    motorcuentaatras;
int    cota;

void   DumpParametros(void);
void   CargaParametros(char n);

void   PortCLeer(void);
void   MotorReset(void);
void   MotorPotencia(char pot);
void   MotorSube(void);
void   MotorBaja(void);
void   MotorSubeN(int n);
void   MotorBajaN(int n);
void   MotorAparca(void);
void   MotorA(int posicion);
void   MotorHasta(int posicion);
int    MotorTestCarrera(void);
void    MotorEspectro(void);
void   MotorComunFinal(char cosa, char retar);
void   MotorDescansa(char veces);

void   T2On(void);
void   PreparaTemporizador(char intervalo);
void   EnablaInterrup(void);
void   DisablaInterrup(char err);
char   ProcesoTest(void);
void   ProcesoEsperaFin(void);
void   PortCLeer(void);
void   Paso(char p);                           //MUEVE MOTOR

#endif

motor.c
Código:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usart2.h"
#include "interprete.h"
#include "motor.h"
#include "debug.h"   //
#include "adc2.h"   //
#include "landas.h"   //

/*static    str_TypeDef str[]={
//   "123456789012345678901234567890"
   "ANTES APARCAR",
   "UN ERROR O ABORTO",
   "enviar algo para parar",
   "FCx inesperado",
   };*/

static    parametros_TypeDef parametro[]={
//char potencia; char motorretardorap; char motorretardo; int cotal; int cotah; int pasos_lectura;
   0, 1, 2,  100, 18900, 20,   // 1 ยบ predefinido
   0, 7, 9,   10,  1000, 10,   //
   0, 5, 7,    1, 10000, 20,   //
   1, 9, 9,   10,  1000, 30,   //
   };

//-------------------   
void   MotorReset(void){
   DDRC=0x00;         //PUERTO C: todo in
   DDRB=0x2F;         //PUERTO B: led y motor en out
   motorproceso=0;
   motorcosahacer=0;
   motorcosahacerbak=0;
   motorruleta=0;
   motorpaso=0x8000;
   motoraparco=0;
//   DumpPredefinidos();
   CargaParametros(0);
//   DumpParametros();
   T2On();
   }
void   DumpPredefinidos(void){
   TX_s_n("Parametros predefinidos:");
   TX_s_n("Pot\tret rap\tretar\tcotaA\tcotaB\tpasos lect");
   for(char n=0;n<4;n++){
      TX_s(IntDeci(parametro[n].potencia)+4);         TX_s("    \t");
      TX_s(IntDeci(parametro[n].retardorap)+4);      TX_s("    \t");
      TX_s(IntDeci(parametro[n].retardo)+4);         TX_s("    \t");
      TX_s(IntDeci(parametro[n].cotal));            TX_s("\t");
      TX_s(IntDeci(parametro[n].cotah));            TX_s("\t");
      TX_s_n(IntDeci(parametro[n].pasos_lectura)+2);
      }
   }
void   CargaParametros(char n){
   if(n>3){n=0;}                  //por seguridad
   motorpotencia   =parametro[n].potencia;         //mas comodo y rapido usar variables  simple
   motorretardo     =parametro[n].retardo;      //mas comodo y rapido usar variables  simple
   motorretardorap   =parametro[n].retardorap;      //mas comodo y rapido usar variables  simple
   cotal         =parametro[n].cotal;
   cotah         =parametro[n].cotah;
   pasos_lectura   =parametro[n].pasos_lectura;
   }
void  DumpParametros(void){
   TX_s_n(" ");
   TX_s_n("Dump Motor:");
   TX_s("potencia \%      \t    ");   TX_s_n(IntDeci(motorpotencia)+4);      
//   TX_s("motorretardo    \t");   TX_s_n(IntDeci(motorretardo));      
//   TX_s("motorretardorap \t");   TX_s_n(IntDeci(motorretardorap));      
   TX_s("pasos/lect \%\%\%  \t  ");   TX_s_n(IntDeci(pasos_lectura)+2);      
   TX_s("cotal \%\%\%\%\%     \t");   TX_s_n(IntDeci(cotal));            
   TX_s("cotah \%\%\%\%\%     \t");   TX_s_n(IntDeci(cotah));            
   TX_s_n(" ");
   }

//-------------------   
void   MotorPotencia(char pot){   //define las palabras al motor, NO le da ca?a
   if(pot){   motorpalabra0=0x03;   motorpalabra1=0x06;   motorpalabra2=0x0C;   motorpalabra3=0x09;   }
   else{      motorpalabra0=0x01;   motorpalabra1=0x02;   motorpalabra2=0x04;   motorpalabra3=0x08;   }
   }
//-------------------   
void   MotorSube(void){
   MotorTexto(2);   //enviar para parar
   MotorComunFinal(MOTORSUBIR,motorretardorap);
   }
void   MotorBaja(void){
   MotorTexto(2);   //enviar para parar
   MotorComunFinal(MOTORBAJAR,motorretardorap);
   }
void   MotorSubeN(int n){
   motorcuentaatras=n;
   MotorComunFinal(MOTORSUBIRN,motorretardorap);
   }
void   MotorBajaN(int n){
   motorcuentaatras=n;
   MotorComunFinal(MOTORBAJARN,motorretardorap);
   }
void   MotorAparca(void){
   PortCLeer();   if(motorFCx){
      MotorComunFinal(MOTORSALIRFC,motorretardorap);   ProcesoEsperaFin();}
   MotorComunFinal(MOTORAPARCA,motorretardorap);   ProcesoEsperaFin();
   if(motorerror=='A'){   MotorTexto(1);      motorerror=0;   return;}//error o abort
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   MotorDescansa(8);
   MotorComunFinal(MOTORSALIRFC,motorretardorap);   ProcesoEsperaFin();
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   TX_s("APARCA: PasosMotor ahora = 0 : antes = ");   TX_s_n(IntDeci(motorpaso));   
   motorpaso=0;
   motoraparco=1;
   }
void   MotorA(int posicion){   //A cotal
   if(!motoraparco){MotorTexto(0);   return;}   //necesita aparcar
   cota=posicion;
   MotorComunFinal(MOTORA,motorretardorap);
   }
int    MotorTestCarrera(void){
   if(!motoraparco){MotorTexto(0);   return;}   //necesita aparcar
   MotorComunFinal(MOTORTESTCARR,motorretardorap);      ProcesoEsperaFin();
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   MotorDescansa(8);
   MotorComunFinal(MOTORSALIRFC,motorretardorap);   ProcesoEsperaFin();
   if(motorerror){         MotorTexto(1);      motorerror=0;   return;}//error o abort
   TX_s("TEST CARRERA: PasosMotor = ");            TX_s_n(IntDeci(motorpaso));   
   //TEST CARRERA: PasosMotor = 19001 , 18996
   }
void    MotorEspectro(void){
   if(!pasos_lectura){   TX_s_n("ERROR: ! pasos_lectura");      return;}
   if(cotal>cotah){   TX_s_n("ERROR: cotal>cotah");         return;}
   if(!motoraparco){   MotorAparca();}
   ProcesoEsperaFin();
   if(!motoraparco){      MotorTexto(0);                  return;}   //necesita aparcar
   MotorDescansa(8);
//   MotorA(cotal);
   MotorA(cotah);
   ProcesoEsperaFin();
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   if(motorerror){         MotorTexto(1);      motorerror=0;   return;}   //error o abort
//   cota=cotah;
   cota=cotal;
   DumpParametros();   //cabecera antes de los numeros.
   ADCOn();      //arranca el ADC
   MotorDescansa(8);
   MotorComunFinal(MOTORESPECTRO,motorretardo);
   ProcesoEsperaFin();
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   if(motorerror){         MotorTexto(1);      motorerror=0;   return;}   //error o abort
   ADCOff();      //apaga el ADC
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   if(motorerror){         MotorTexto(1);      motorerror=0;   return;}   //error o abort
   MotorDescansa(8);
   MotorA(cotah);
//   MotorAparca();
   ProcesoEsperaFin();
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   if(motorerror){         MotorTexto(1);      motorerror=0;   return;}   //error o abort
   }
//-------------------   
void   MotorComunFinal(char cosa, char retar){
   motorcosahacer=cosa;
   MotorPotencia(motorpotencia);      //se entera palabras motor, NO LE DA POTENCIA
   PreparaTemporizador(retar);
   EnablaInterrup();
   }
void   MotorDescansa(char veces){
   while(veces){
      veces--;
      MotorComunFinal(MOTORPARAR,motorretardorap);   ProcesoEsperaFin();
      }
   }
//-------------------   
void   MotorTexto(char txt){
   TX_s_n(str[txt].str);
   }

motorint.c
Código:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usart2.h"
#include "motor.h"
#include "debug.h"   //
#include "adc2.h"   //

void  T2On(void){
//   bitSet(PRR,PRTIM2);//enciende el temporizador 2, (estaba a 0 para ahorrar ) NO EN EJEMPLO
//   bitSet(ASSR,AS2); // T2 a reloj interno   NO EN EJEMPLO
   TCCR2B = 0x07;   // DON'T FORCE COMPARE, 1024 PRESCALER
   TCCR2A = 0x02;   // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
   OCR2A  = 0XFF;   // SET THE TOP OF THE COUNT                  sera cambiado en PreparaTemporizador()
   }
//-------------------   
void  PreparaTemporizador(char intervalo){
   switch(intervalo){
      case 9:   OCR2A=0xFF;   break;//contador a 0, tarda maximo en overflou
      case 8:   OCR2A=0xE0;   break;//
      case 7:   OCR2A=0xC0;   break;//
      case 6:   OCR2A=0xA0;   break;//
      case 5:   OCR2A=0x80;   break;//
      case 4:   OCR2A=0x50;   break;//
      case 3:   OCR2A=0x40;   break;//
      case 2:   OCR2A=0x35;   break;//
      case 1:   OCR2A=0x30;   break;//
      case 0:   OCR2A=0x25;   break;//
      }   
   }   
//-------------------   
void   EnablaInterrup(void){
   ProcesoEsperaFin();
   motorproceso=1;
   RXllegoc=0;            //esta en USART2.H si llega caracter para,
   bitSet(GTCCR,PSRSYNC);   //preescaler reset
   TCNT2=0;            //reset contador T2
   cli();               //no se porque se hace esto, lo hacen todos
//   TIFR2 = bit (OCF2A);   // clear any pending interrupt
   bitClear(TIFR2,OCF2A);// clear any pending interrupt
   TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
   sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED     
   }
void   DisablaInterrup(char err){
   motorerror=err;
   cli();
   bitClear(TIMSK2,OCIE2A);   //disabla interrupcion T2_OCA
   sei();
   PORTB&=MOTORMASCARA;      //apaga motor
   motorcosahacerbak=motorcosahacer;   //para saber que es lo ultimo que hizo
   motorcosahacer=0;               //motorcosahacer a 0
   motorproceso=0;
//   Debug1();
   }
//-------------------   
char   ProcesoTest(void){
   return(motorproceso);
   }
void   ProcesoEsperaFin(void){
//   if(motorproceso){   TX_s("en espera,,,\n");}
   while(motorproceso){}
   }
//-------------------   
void   PortCLeer(void){
   PINCbak=PINC;         //lee finales de carrera
   PINCbak&=FCMASCARA;
   switch(PINCbak){
      case  0x00:   motorFCA=1;      motorFCB=1;   motorerror='B';      break;
      case  0x01:   motorFCA=1;      /*motorFCB=0;*/               break;//como nunca las dos, pa q?
      case  0x02:   /*motorFCA=0;*/   motorFCB=1;                  break;
      case  0x03:   motorFCA=0;      motorFCB=0;                  break;
      }
   motorFCx = motorFCA + motorFCA + motorFCB;
   }
//-------------------   
void   Paso(char p){                           //MUEVE MOTOR
   switch(p){
      case  1:
         switch(motorruleta){
            case 0:   motorruleta++;   PORTB|=motorpalabra0;   break;
            case 1:   motorruleta++;   PORTB|=motorpalabra1;   break;
            case 2:   motorruleta++;   PORTB|=motorpalabra2;   break;
            case 3:   motorruleta=0;   PORTB|=motorpalabra3;   break;
            }
         motorpaso++;
         break;
      case -1:
         switch(motorruleta){
            case 0:   motorruleta=3;   PORTB|=motorpalabra0;   break;
            case 1:   motorruleta--;   PORTB|=motorpalabra1;   break;
            case 2:   motorruleta--;   PORTB|=motorpalabra2;   break;
            case 3:   motorruleta--;   PORTB|=motorpalabra3;   break;
            }
         motorpaso--;
         break;
      }
   }
 
//-------------------   
ISR(TIMER2_COMPA_vect){
   PORTB&=MOTORMASCARA;   //comun a todo, apaga motor
   if(RXllegoc){   DisablaInterrup('A');   goto fin;}
   PortCLeer();   //lee finales de carrera,
   TCNT2=0; //reset contador,
   switch(motorcosahacer){
      case MOTORPARAR:   //NO hace nada, pierde un tiempo
         DisablaInterrup(0);
         break;
      case MOTORSALIRFC:
         switch(motorFCx){
            case  0x00:   switch(motorasalirfc){   //le da dos pasos de mas, porsi
                  case  2:   case  1: Paso( 1);   motorasalirfc--;   break;
                  case -2:   case -1: Paso(-1);   motorasalirfc++;   break;
                  case  0:   DisablaInterrup(0);   goto fin;      break;}
                                             break;
            case  0x01:   Paso( 1);   motorasalirfc= 2;   break;
            case  0x02:   Paso(-1);   motorasalirfc=-2;   break;
            case  0x03:   DisablaInterrup('E');         break;
            }
         break;
      case MOTORSUBIR:
         if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         Paso(1);                  //TXdirec(NibleHexa(PINB));
         break;
      case MOTORBAJAR:   
         if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         Paso(-1);
         break;
      case MOTORSUBIRN:
         if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         if(motorcuentaatras){
            Paso(1);
            motorcuentaatras--;
            }
         else{         DisablaInterrup(0);      goto fin;   }         //si termino
         break;
      case MOTORBAJARN:
         if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         if(motorcuentaatras){
            Paso(-1);
            motorcuentaatras--;
            }
         else{         DisablaInterrup(0);      goto fin;   }         //si termino
         break;
      case MOTORAPARCA:
         if(motorFCB){   DisablaInterrup(0);    goto fin;}//si llego a FCB, termina
         if(motorFCA){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         Paso(-1);
         break;
      case MOTORTESTCARR:            //tes carrera es lo mismo que subir
         if(motorFCA){   DisablaInterrup(0);    goto fin;}//si llego a FCA, termina
         if(motorFCB){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         Paso(1);                  //TXdirec(NibleHexa(PINB));
         break;
      case MOTORA:
         if(cota==motorpaso){DisablaInterrup(0);      goto fin;}   //ya son los dos iguales
         if(cota<motorpaso){   //tiene que bajar
            if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
            Paso(-1);
            }
         if(cota>motorpaso){   //tiene que subir
            if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
            Paso(1);
            }      
         break;
      case MOTORESPECTRO:
         if(adc_cerrado){      //si hay un balance cerrado, lo lanza
            adc_cerrado=0;      //limpia la orden
            TX_s_n(IntDeci(adc_resul));      //aqui lanza el resultado
            }
         adc_ruleta++;
         if(adc_ruleta==pasos_lectura){
            adc_ruleta=0;
            adc_cerrar=1;   //ordena a ADC cerrar balance,
            }
         if(cota>motorpaso){      ADCOff();   DisablaInterrup(0);   goto fin;   }//
         if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         Paso(-1);
         break;
      case MOTORESPECTRO2:
         if(adc_cerrado){      //si hay un balance cerrado, lo lanza
            adc_cerrado=0;      //limpia la orden
            }
         adc_ruleta++;
         if(adc_ruleta==pasos_lectura){
            adc_ruleta=0;
            adc_cerrar=1;   //ordena a ADC cerrar balance,
            }
         if(cota>motorpaso){      ADCOff();   DisablaInterrup(0);   goto fin;   }//
         if(motorFCx){   DisablaInterrup('E');   goto fin;}//FCx inesperado
         Paso(-1);
         break;
      }   
fin:
   sei();         // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED  seguramente no hace falta.   
   }

y ya por fin vemos algo de movimiento.

el motor siempre se mueve desde la interupcion, por un temporizador.
cuando salta la interrup, ella sabe que tiene que hacer, porque desde fuera se ha programado un codigo.
el "desde fuera" son las distintas opciones: motor a,,, motro subir,,, busca final carrera,,, vete a abajo,,,,
cuando de la int le parece que termino, pone "proceso" a 0, y desde afuera saben que termino.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 7:19 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
adc2.h
Código:
#ifndef adc2   
#define adc2

volatile   unsigned char    adcl;
volatile   unsigned char    adch;
volatile   unsigned int    adcVal;
volatile   unsigned int    adc_lecturas;
volatile   unsigned long   adc_acum;
volatile   unsigned int    adc_resul;      //esto es lo unico que interesa
volatile          char   adc_cerrar;      //orden de hacer balance
volatile          char   adc_cerrado;   //balance hecho
volatile          char adc_ruleta;      //usada para contar pasos lectura
volatile          char adc_listo;      //usada para decir a capa motor que ya tiene un resltado,

void   ADCInit(void);   //inicia el asunto
void   ADCOn(void);   //arranca las interupciones
void   ADCOff(void);   //para de leer

#endif

adc2.c
Código:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "adc2.h"   //

void   ADCInit(void){   //inicia el asunto ADC
//   ADMUX=0x42;   //ADC Multiplexer Selection Register, Vdd, derecha, A2
   ADMUX  =0b11000101;   //ADC Multiplexer Selection Register, 1v1, derecha, A2
//   ADCSRA =0b10101111;   //Control and Status Register A,  ON, no dispara, auto, ?,interup, /128
   ADCSRA=0b11101111;
//  ADCSRA = B10011111; // ADC enable, manual trigger mode, ADC interrupt enable, prescaler = 128
//  ADCSRA = B11001111;   // ADC enable, ADC start, manual trigger mode, ADC interrupt enable, prescaler = 128
//   ADCSRB=0x00;   //,,?,,fre run
   DIDR0=0x04;      //Digital Input Disable Register 0 , analogico el pin A2
   }
void   ADCOn(void){   //se dispara la lectura continua
   adc_acum=0;      adc_lecturas=0;      adc_ruleta=0;   adc_listo=0;//reset de variables
//   ADCSRA=0b11101111;
   }
void   ADCOff(void){   //se para la lectura  continua
//   ADCSRA=0b10101111;
   }

ISR(ADC_vect){
   adcl = ADCL;               //lo saque de un ejemplo ???
   adch = ADCH;               //lo saque de un ejemplo ???
   adcVal = (adch << 8) | adcl;   //lo saque de un ejemplo, esto lo entiendo
   adc_acum+=adcVal;
   adc_lecturas++;
   if(adc_cerrar){
//      adc_acum=adc_acum<<2;      //multiplica x4, sin perder info,
      adc_acum=adc_acum<<1;      //multiplica x2, sin perder info,
      adc_resul=(int)(adc_acum/adc_lecturas);
      adc_acum=0;      adc_lecturas=0;      adc_cerrar=0;   adc_cerrado=1;   adc_listo=1;
      }
   }

esto es lo de las lecturas, del ADC,
¿1 lectura / paso?, ¿varias?, ¿muchas?.
al final se puso leyendo continuo,

desde la interrupcion de motor modo espectro, le da orden de cerrar el balance, con "adc_cerrar", en la interrupcion del ADC (a caada nueva lectura) multiplica x2 para mas precision, como hizo un porron de ellas no es solo oner un cero a derecha, haya la media, lo pone en resultado, borra la orden de cerrar, y pone un cerrado y listo, cada uno se usara en una parte del programa.

el detector es como una peseta, y da unos dos voltios, el jefe dijo, "leer 2000 cuando 2 voltios", por lo que la referencia se cambio a 1.1v de ref interna, y se puso un potenciometro en la entrada, sin amplis ni gaitas.

tras hacer el espectro tenia idea de apagar el ADC, pero se me colgaba, asi que aun debe seguir leyendo.

la ventaja de lecturas continuas con media, es mas precision, y que no varia la salida dependiendo de cuantas se hagan.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 7:31 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
landas.h
Código:
#ifndef debug   
#define debug

//carrera 18952, ->   15nm, (  10 de contador)
//0 pasos motor, -> 1500nm, (1000 de contador)

#define CTEx        13.33
#define CTEoffset   19143  ///REPASAR OFFSET

void   LandaReset(void);
//-------------------   
int    SaberLanda(int paso);
int    SaberPaso (int land);
//-------------------   
void   LandaHelp(void);   
//-------------------   
void   LandaAparca(void);   
void   LandaBaja(void);               //"landa baja %%%%"
void   LandaAlta(void);               //"landa alta %%%%"
void   LandaIrA(void);                  //"ir a %%%%"
void   LandaEspectro(void);
void   LandaDumpParametros(void);

int    landal;   //"landal %%%%"
int    landah;   //"landah %%%%"

#endif

landas.c
Código:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usart2.h"
#include "motor.h"
#include "adc2.h"   //
#include "landas.h"   //

void   LandaReset(void){
   landal=240;
   landah=1200;
   LandaDumpParametros();
   }
//-------------------   

int    SaberLanda(int paso){   return((int)((CTEoffset-paso)/CTEx));   }
int    SaberPaso (int land){   return((int)(CTEoffset-(CTEx*land)));   }
//-------------------   
void   LandaHelp(void){   TX_s_PGM2();   }   //saca help de capa landas
//-------------------   
void   LandaAparca(void){   MotorAparca();   }   //
void   LandaBaja(void){landal=   DeciInt('0',bufRX[7],bufRX[8],bufRX[9],bufRX[10]);   LandaDumpParametros();}//"landal %%%%"
void   LandaAlta(void){landah=   DeciInt('0',bufRX[7],bufRX[8],bufRX[9],bufRX[10]);   LandaDumpParametros();}//"landah %%%%"
/*void   LandaAlta(void){
   LandaDumpParametros();
   landah=   DeciInt('0',bufRX[7],bufRX[8],bufRX[9],bufRX[10]);   
   TX_s_n(bufRX);
   LandaDumpParametros();}//"landah %%%%"*/
void   LandaIrA(void){   MotorA(SaberPaso(DeciInt('0',bufRX[5],bufRX[6],bufRX[7],bufRX[8])));}//"ir a %%%%"
//-------------------   
void   LandaEspectro(void){
   if(!pasos_lectura){   TX_s_n("ERROR: ! pasos_lectura");      return;}
   if(landal>landah){   TX_s_n("ERROR: landal>landah");         return;}
   if(!motoraparco){   MotorAparca();}
   ProcesoEsperaFin();
   if(!motoraparco){      MotorTexto(0);                  return;}   //necesita aparcar
   MotorDescansa(8);
   MotorA(SaberPaso(landal));
   ProcesoEsperaFin();
   if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   if(motorerror){         MotorTexto(1);      motorerror=0;   return;}   //error o abort
   cota=SaberPaso(landah);
   LandaDumpParametros();   //cabecera antes de los numeros.
   ADCOn();      //arranca el ADC
   MotorDescansa(8);
   MotorComunFinal(MOTORESPECTRO2,motorretardo);

   while(motorproceso){
      if(adc_listo){
         adc_listo=0;
         TX_s(IntDeci(SaberLanda(motorpaso))+1);   TX_s("\t");   TX_s_n(IntDeci(adc_resul)+1);
         }
      if(motorerror=='E'){   MotorTexto(3);      motorerror=0;   return;}//FC inesperado
      if(motorerror){         MotorTexto(1);      motorerror=0;   return;}   //error o abort
      }
   if(adc_listo){      //otra vez por si quedaba despistado.
      adc_listo=0;
      TX_s(IntDeci(SaberLanda(motorpaso))+1);   TX_s("\t");   TX_s_n(IntDeci(adc_resul)+1);
      }
   
   ADCOff();      //apaga el ADC
   MotorDescansa(8);
   MotorA(SaberPaso(landal));
   ProcesoEsperaFin();
   if(motorerror=='E'){      MotorTexto(3);      motorerror=0;   return;}//FC inesperado
   if(motorerror){            MotorTexto(1);      motorerror=0;   return;}   //error o abort
   }

void   LandaDumpParametros(void){
   TX_s_n(" ");
   TX_s_n("Dump:");
   TX_s("retardo rap \%   \t    ");   TX_s_n(IntDeci(motorretardorap)+4);      
   TX_s("retardo \%       \t    ");   TX_s_n(IntDeci(motorretardo)+4);      
   TX_s("pasos/lect \%\%\%  \t  ");   TX_s_n(IntDeci(pasos_lectura)+2);      
   TX_s("landal \%\%\%\%     \t ");   TX_s_n(IntDeci(landal)+1);            
   TX_s("landah \%\%\%\%     \t ");   TX_s_n(IntDeci(landah)+1);      
   TX_s("landa actual    \t ");   TX_s_n(IntDeci(SaberLanda(motorpaso))+1);      
   TX_s("en pasos motor  \t");   TX_s_n(IntDeci(motorpaso));         
   TX_s_n(" ");
   }


"CREO" que esto es la version de hacer espectro, lo ultimo que se puso en el programa, el añadir la lectura cuando ya se controlaba el rollo del motor, en hoja aparte,

segun el paso motor calcula landa, y lo pone a izquierda de la lectura,
en la consola arduino se recogen filas con los dos numeros, hay que copiarlos y pegarlos en hoja de calculo para sacar la grafica.

un lio con el profe, un quisqui, no se conformo con el proograma, tambien queria que lo afinase.
al principio no sabiamos donde estaba el rojo ni el azul,,, lamparas de mercurio,,, laseres,,, abrir, tripas mirar,,,,

al final parece que ya mide bien.


Arriba
 Perfil  
 
NotaPublicado: Dom Mar 04, 2018 7:35 pm 
Desconectado
Avatar de Usuario

Registrado: Vie Dic 23, 2005 7:54 pm
Mensajes: 1401
Ubicación: Galicia
País: españa
Ciudad: coruña y madrid
help.h
Código:
#ifndef help   
#define help

void   TX_s_PGM(void);
void   TX_s_PGM2(void);

#endif

help.c
Código:
#include <avr/pgmspace.h>
#include "usart2.h"
#include "help.h"

const char help_00[] PROGMEM = "COMANDOS PRINCIPALES:\n";   
const char help_01[] PROGMEM = "PONER TAL CUAL. LITERAL.  \% es plantilla de numero\n";   
const char help_02[] PROGMEM = "led x          (invierte led, usado como test\n";
const char help_A3[] PROGMEM = "predef ver     (ver que predefinidos hay\n";
const char help_03[] PROGMEM = "predefinido \%  (de 0 a 3, carga parametros prede\n";
const char help_04[] PROGMEM = "aparca         (se va a fin carrera baja, y 0\n";
const char help_05[] PROGMEM = "espectro       (hace un espectro\n";
const char help_06[] PROGMEM = "retardo rap \%  (del motor cuando se posiciona\n";
const char help_07[] PROGMEM = "retardo \%      (cuando hace un espectro\n";
const char help_08[] PROGMEM = "pasos/lect \%\%\% (cada cuantos pasos lee\n";
//const char help_09[] PROGMEM = "  Type h2 o h3 para mas opciones\n";

const char help_09[] PROGMEM = "   otros comandos utiles\n";
const char help_10[] PROGMEM = "potencia \%     (0 una bobi mot, 1 dos\n";
const char help_11[] PROGMEM = "cotah \%\%\%\%\%    (fija una cota alta, en pasos mot\n";
const char help_12[] PROGMEM = "cotal \%\%\%\%\%    (la baja\n";
const char help_13[] PROGMEM = "a cota baja    (se mueve a cota baja\n";
const char help_14[] PROGMEM = "a cota alta\n";
const char help_15[] PROGMEM = "test carrera   (mide la carrera max\n";

const char help_20[] PROGMEM = "   usados por el programador\n";
const char help_21[] PROGMEM = "sube           (sube hasta recibir algo\n";
const char help_22[] PROGMEM = "baja\n";
const char help_23[] PROGMEM = "sube \%\%\%\%      (sube tantos pasos mot\n";
const char help_24[] PROGMEM = "baja \%\%\%\%\n";
const char help_25[] PROGMEM = "led 1\n";
const char help_26[] PROGMEM = "led 0\n";
const char help_27[] PROGMEM = "eco 0\n";
const char help_28[] PROGMEM = "eco 1\n";
const char help_29[] PROGMEM = "reset          (de parametros motor\n";
const char help_30[] PROGMEM = "debug 1\n";
const char help_31[] PROGMEM = "debug 2\n";   //

void    TX_s_PGM(void){
   char c;   char k;
   TX_s(" \n");
   k=0; do{c = pgm_read_byte_near(help_00 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_01 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_02 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_A3 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_03 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_04 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_05 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_06 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_07 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_08 + k);   TX(c);   k++;} while(c!='\n');
   TX_s(" \n");
   k=0; do{c = pgm_read_byte_near(help_09 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_10 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_11 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_12 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_13 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_14 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_15 + k);   TX(c);   k++;} while(c!='\n');
   TX_s(" \n");
   k=0; do{c = pgm_read_byte_near(help_20 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_21 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_22 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_23 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_24 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_25 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_26 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_27 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_28 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_29 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_30 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help_31 + k);   TX(c);   k++;} while(c!='\n');
   }

help2.c
Código:
#include <avr/pgmspace.h>
#include "usart2.h"
#include "help.h"

const char help2_00[] PROGMEM = "COMANDOS PRINCIPALES DE CAPA LANDAS:\n";   
const char help2_01[] PROGMEM = "PONER TAL CUAL. LITERAL.  \% es plantilla de numero\n";   
const char help2_02[] PROGMEM = "espectro       (hace espectro entre cotas landas\n";
const char help2_03[] PROGMEM = "aparca         (se va a fin carrera baja, y 0\n";
const char help2_04[] PROGMEM = "landal \%\%\%\%    (fija cota baja\n";
const char help2_05[] PROGMEM = "landah \%\%\%\%    (fija cota\n ";
const char help2_06[] PROGMEM = "ir a \%\%\%\%      (se mueve hasta ,,,\n";
const char help2_07[] PROGMEM = "dump           (muestra parametros\n";
const char help2_08[] PROGMEM = "h2             (otro help de debug\n";


void    TX_s_PGM2(void){
   char c;   char k;
   TX_s(" \n");
   k=0; do{c = pgm_read_byte_near(help2_00 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_01 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_02 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_03 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_04 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_05 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_06 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_07 + k);   TX(c);   k++;} while(c!='\n');
   k=0; do{c = pgm_read_byte_near(help2_08 + k);   TX(c);   k++;} while(c!='\n');
   }


que menos que poner una ayuda.
como la parrafada ya no cabia en RAM, hubo que ponerla en ROM.
la 1º era la que prepare al principio.
pero tan larga que necesito un resumen de principales.


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 13 mensajes ]  Ir a página 1, 2  Siguiente

Todos los horarios son UTC [ DST ]


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro

Buscar:
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpbb-es.com