Arduino
Comunicación Serie por Software
Interrupciones
xsetaseta@gmail.com
Debía realizar un análisis de unas señales que transmitían códigos. Para obtener los datos de estas señales debía decodificar los diferentes impulsos de estas señales. El chip decodificador debía ser un arduino, y como nunca había realizado este trabajo, debía experimentar un patron de señales conocidas, y la mas conocida era la comunicación serie.
El estándar serie es bien conocido, su decodificación normalmente se hace vía hardware, aunque a baja velocidad también se puede decodificar vía Software. Esta es una práctica de decodificación mediante programa de una señal con el protocolo serie, (USART) universal synchronous and asynchronous receiver-transmitter.
Imagen de una señal serie.
Tiempo de la señal Start a una velocidad de 300bps.
Tiempo de la señal Stop a una velocidad de 300bps.
La señal representada corresponde a una señal serie de 8 bits y 1 bits de parada.
Para decodificar esta señal he utilizado dos métodos diferentes:
El primer método cheque continuamente un Pin del arduino, que debemos determinar en el Setup.
El segundo método solo se interrumpe la ejecución del programa si existe un cambio en el Pin2, el cual genera la interrupción 0.
Modo 1.
Creamos una interrupción que continuamente mira el estado del pin que se designa como entrada.
SRetardoStop = SRetardo * 10;
SRetardoMax = SRetardo * 14;
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCCR1B |= (1 << WGM12); // turn on CTC mode:
TCCR1B |= (1 << CS10); //sin prescaler
OCR1A = Scontador; //contador
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt:
sei(); // enable global interrupts
Vemos como utilizamos el Timer1, le asignamos un valor al contador, cuando el contador llegue a cero produce una interrupción, carga de nuevo el valor del contador, y se ejecuta la rutina de la interrupción.
La rutina de la interrupción es donde se estudia la señal del pin y se llama:
ISR(TIMER1_COMPA_vect)
{
}
Gráfica del chequeo de señal y la toma de valores de la señal.
Modo 2.
Para este caso no existe ninguna temporización, el programa utiliza la interrupción externa Int0 que se encuentra en el Pin 2 del arduino.
El programa solo se interrumpe cuando detecta un cambio de señal en el Pin 2 del arduino.
bool SetupSerie2(unsigned int baud)
{
pinMode(2, INPUT);
digitalWrite(2, HIGH); // Enable pull-up resistor
cli(); // Enable global interrupts
EIMSK |= (1 << INT0); // Enable external interrupt INT0
EICRA |= (1 << ISC00); // Trigger INT0 on Change
sei();
......
La rutina de la interrupción es donde se estudia los tiempos del cambio de señal del Pin 2 del arduino y se llama:
ISR(INT0_vect)
{
}
En los dos casos cuando se ha completado la lectura de un byte, se pone la variable SDatoEstado = 1; .
En el bucle del programa principal que chequea continuamente el SDatoEstado = 1; , mediante la rutina SerialAvailable() ,cuando detecta un carácter válido, se obtiene el byte mediante la rutina SerialGet().
Para esta práctica no he querido crear un buffer que sería lo normal, pues si se entretiene mucho el programa principal pudiera sobrescribirse los datos.
En ambos casos a velocidades superiores a 4800 bps, me producían errores, se mezclaban las interrupciones, no he querido profundizar en su posible solución.
Para entender la interrupciones en el arduino, estuve buscando en internet un tutorial, encontrando este:
https://arduinodiy.wordpress.com/2012/02/28/timer-interrupts/
en plan atrevido, realicé una traducción, espero que no sea muy mala. TRADUCCION
Las gráficas de la señales están realizadas mediante Osciloscopio Hantek6022BL y PulseView bajo Linux (Debian8_32bits).
PROGRAMAS
Hasta pronto.
JUAN GALAZ
Bibliografía:
https://aprendiendoarduino.wordpress.com/2016/11/13/interrupciones/
https://arduinodiy.wordpress.com/2012/02/28/timer-interrupts/
http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/
No hay comentarios:
Publicar un comentario