[HECHO] espectroduino, automatizacion de espectrometro.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
[HECHO] espectroduino, automatizacion de espectrometro.
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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
//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
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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#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;}
}
}
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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#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
Código: Seleccionar todo
#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;
}
}
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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#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
Código: Seleccionar todo
/**********************************************/
/* 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
}
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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#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
Código: Seleccionar todo
#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 !!!!
};
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: Seleccionar todo
#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();}
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#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
Código: Seleccionar todo
#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);
}
Código: Seleccionar todo
#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.
}
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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#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
Código: Seleccionar todo
#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;
}
}
¿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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#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
Código: Seleccionar todo
#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(" ");
}
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.
- baldo
- Mensajes: 1514
- Registrado: Vie Dic 23, 2005 7:54 pm
- País: españa
- Ciudad: coruña y madrid
- Ubicación: Galicia
- Contactar:
Re: [HECHO] espectroduino, automatizacion de espectrometro.
Código: Seleccionar todo
#ifndef help
#define help
void TX_s_PGM(void);
void TX_s_PGM2(void);
#endif
Código: Seleccionar todo
#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');
}
Código: Seleccionar todo
#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');
}
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.
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados