mbr386
30-03-2016, 02:51 AM
Hola, hace un par de días me disponía intentar escribir un código el cual pudiera transmitir una señal infrarroja sin utilizar librerías. Antes de arrancar leí el foro de arduino y me encontré con que otra persona ya lo habia intentado y tenia algunos problemas leyendo lo que recibia.
Lo que pensaba hacer ya estaba casi hecho!, claro, tenia algunos defectos. Pero se podía solucionar.
Bueno, este es el código original:
CODIGO EMISOR
#define ledIR 4
#define Hz 38000
unsigned long codigo;
int x;
void setup() {
pinMode(ledIR,OUTPUT);
pinMode(2,INPUT);
Serial.begin(9600);
}
void loop() {
if (digitalRead(2)){ //si aprieto un pulsador...
codigo=0x11111111; //asigno el código a enviar de 32 biits
tone(ledIR,Hz);
delayMicroseconds(9000); //envio un pulso de 9 mseg a 38 Khz
noTone(ledIR);
delayMicroseconds(4500);//envio una pausa de 4.5 mseg (inicio de código)
for (x=31;x>=0;x--){ //envio el pulso uno por uno de todos los 32 bits de 560 useg
tone(ledIR,Hz);
delayMicroseconds(560);
if (bitRead(codigo,x)){
noTone(ledIR);
delayMicroseconds(1690); //envio una pausa de 1690useg para asignar un bit en 1
}else{
noTone(ledIR);
delayMicroseconds(560);
Serial.print("0"); //envio una pausa de 1690useg para asignar un bit en 0
}
}
tone(ledIR,Hz); //envio el bit de parada
delayMicroseconds(560);
noTone(ledIR);
delay (1000);
}
}
CODIGO RECEPTOR
#define IR 11 //Pin al que va conectado nuestro receptor de infrarrojos.
long duracion[32]; //array que contiene la duracion de cada pulso en microsegundos (uS)
int x = 0; //Contador para moverse por las distintas variables de los arrays
int pulso_comienzo; //En esta variable se almacena el valor del pulso de inicio de 4,5mS
unsigned long codigo_tecla = 0; //Valor de la tecla pulsada convertido de binario a decimal
/********************************************************************************************/
/********************************************************************************************/
// CONFIGURACION DEL MICROPROCESADOR
void setup() {
Serial.begin(9600);
}
void loop() {
if (digitalRead(IR) == 0) //Esperamos que se pulse una tecla
{ //PASO 1: DETECCION DEL PULSO DE INICIO DE SECUENCIA (4,5mS)
pulso_comienzo = pulseIn(IR, HIGH);
if (pulso_comienzo > 4000 && pulso_comienzo < 5000) //...comprobamos si es el pulso de comienzo de 4,5mS (inicio de secuencia)
{
lecturaCodigoIr(); //Funcion que lee la tecla pulsada y la almacena en la variable (codigo_tecla)
}
}
//Accion a realizar segun la tecla pulsada.
Serial.println(codigo_tecla, HEX);
codigo_tecla = 0;
}
// SUBRUTINAS
//Subrutina que lee que tecla del mando a distancia se ha pulsado y
//la almacena en la variable codigo_tecla
void lecturaCodigoIr()
{ //PASO 2: CRONOMETRAJE DE TIEMPOS DE CADA PULSO(uS) (empezando desde el bit de la derecha)
for (x = 31; x >= 0; x--) {
duracion[x] = pulseIn(IR, HIGH); //Duracion de cada pulso (uS)
}
//PASO 3: SEGUN EL TIEMPO DE CADA PULSO, DETERMINAMOS SI ES UN 0 O UN 1 LOGICO (Ver protocolo NEC)
for (x = 31; x >= 0; x--)
{
if (duracion[x] > 500 && duracion[x] < 700) //Si el pulso dura entre 500 y 700uS...
{
bitClear(codigo_tecla, x); //... es un 0 logico
}
if (duracion[x] > 1500 && duracion[x] < 1750) //Si el pulso dura entre 1500 y 1750uS
{
bitSet(codigo_tecla, x); //... es un 1 logico
}
}
}
//FIN SUBRUTINAS ************************************************************************************/
Y estos son los códigos nuevos (no es el ultimo código), funcionan a medias, ya que no cumplen con el protocolo NEC enviando la señal de repetición (estoy en ello) y otro gran problema de esta versión del código es que tiene un delay en el emisor de 1800, si lo reduzco el programa receptor empieza a leer cualquier fruta.
No les paso el ultimo código porque no lo probé aun, aunque este no funcione del todo bien por lo menos el receptor infrarrojo lee lo mismo que envía el emisor. Y para probar sirve y continuar mejorandolo.
Código emisor
#define PIN 3
#define inicio 9000
#define pausa 4500
#define cero 560
#define uno 1690
#define Hz 38000
unsigned long mensaje=0x48B76C93; // 0x48b76c93 // H·l"
void setup() {
pinMode(PIN, OUTPUT);
}
void loop() {
escribepin(inicio);
delayMicroseconds(pausa);
escribepin(cero);
escribemsj();
delay (1800);
}
void escribepin(int microseg){
tone(PIN, Hz);
delayMicroseconds(microseg);
noTone(PIN);
}
void escribemsj(){/////////////////////// MENSAJE
for (int nbit = 31; nbit >= 0; nbit--) {
Serial.print(bitRead(mensaje, nbit));
if (bitRead(mensaje, nbit)) {
escribepin(uno);
} else {
escribepin(cero);
delayMicroseconds(cero);
}
delayMicroseconds(cero);
escribepin(cero);
}
}/////////////////////// FIN MENSAJE
/*
escribepin(39416);
escribepin(inicio);
escribepin(2210);
escribepin(cero);
*/
Código receptor
#define PIN 9
int pausas[32], cuentamsj;
unsigned long mensaje = 0;
void setup() {
Serial.begin(9600);
pinMode(PIN, INPUT);
}
void loop() {
pausas[0] = pulseIn(PIN, HIGH);
if (pausas[0] > 0) {
for (cuentamsj = 31; cuentamsj >= 0; cuentamsj--) {
pausas[cuentamsj] = pulseIn(PIN, HIGH);
}
for (cuentamsj = 31; cuentamsj >= 0; cuentamsj--) {
if (pausas[cuentamsj] > 500 && pausas[cuentamsj] < 700) {
bitSet(mensaje, cuentamsj);
} else {
bitClear(mensaje, cuentamsj);
}
}
Serial.print("Mensaje original: 0x48B76C93 Traducido: 0x"); // HEX(0x48B76C93) // TEXT(H·l") // BIN(01001000 10110111 01101100 10010011)
Serial.println(mensaje, HEX);
}
}
Quizás a alguien le pueda servir, para aprender ya que no esta funcional.
Para el que no sabe mucho de programación (como yo) y quiere aprender (como yo) el tratar de mejorar el código representa un desafío y gran aprendizaje. Así qué, ahí tienen.
Por cierto, quien tenga mas experiencia en programación o electrónica y en algún momento se haya topado con información al respecto de este protocolo me avisa porque no pude encontrar mucha información y tengo ciertas dudas en cuanto a que hacer en el código emisor.
Lo que pensaba hacer ya estaba casi hecho!, claro, tenia algunos defectos. Pero se podía solucionar.
Bueno, este es el código original:
CODIGO EMISOR
#define ledIR 4
#define Hz 38000
unsigned long codigo;
int x;
void setup() {
pinMode(ledIR,OUTPUT);
pinMode(2,INPUT);
Serial.begin(9600);
}
void loop() {
if (digitalRead(2)){ //si aprieto un pulsador...
codigo=0x11111111; //asigno el código a enviar de 32 biits
tone(ledIR,Hz);
delayMicroseconds(9000); //envio un pulso de 9 mseg a 38 Khz
noTone(ledIR);
delayMicroseconds(4500);//envio una pausa de 4.5 mseg (inicio de código)
for (x=31;x>=0;x--){ //envio el pulso uno por uno de todos los 32 bits de 560 useg
tone(ledIR,Hz);
delayMicroseconds(560);
if (bitRead(codigo,x)){
noTone(ledIR);
delayMicroseconds(1690); //envio una pausa de 1690useg para asignar un bit en 1
}else{
noTone(ledIR);
delayMicroseconds(560);
Serial.print("0"); //envio una pausa de 1690useg para asignar un bit en 0
}
}
tone(ledIR,Hz); //envio el bit de parada
delayMicroseconds(560);
noTone(ledIR);
delay (1000);
}
}
CODIGO RECEPTOR
#define IR 11 //Pin al que va conectado nuestro receptor de infrarrojos.
long duracion[32]; //array que contiene la duracion de cada pulso en microsegundos (uS)
int x = 0; //Contador para moverse por las distintas variables de los arrays
int pulso_comienzo; //En esta variable se almacena el valor del pulso de inicio de 4,5mS
unsigned long codigo_tecla = 0; //Valor de la tecla pulsada convertido de binario a decimal
/********************************************************************************************/
/********************************************************************************************/
// CONFIGURACION DEL MICROPROCESADOR
void setup() {
Serial.begin(9600);
}
void loop() {
if (digitalRead(IR) == 0) //Esperamos que se pulse una tecla
{ //PASO 1: DETECCION DEL PULSO DE INICIO DE SECUENCIA (4,5mS)
pulso_comienzo = pulseIn(IR, HIGH);
if (pulso_comienzo > 4000 && pulso_comienzo < 5000) //...comprobamos si es el pulso de comienzo de 4,5mS (inicio de secuencia)
{
lecturaCodigoIr(); //Funcion que lee la tecla pulsada y la almacena en la variable (codigo_tecla)
}
}
//Accion a realizar segun la tecla pulsada.
Serial.println(codigo_tecla, HEX);
codigo_tecla = 0;
}
// SUBRUTINAS
//Subrutina que lee que tecla del mando a distancia se ha pulsado y
//la almacena en la variable codigo_tecla
void lecturaCodigoIr()
{ //PASO 2: CRONOMETRAJE DE TIEMPOS DE CADA PULSO(uS) (empezando desde el bit de la derecha)
for (x = 31; x >= 0; x--) {
duracion[x] = pulseIn(IR, HIGH); //Duracion de cada pulso (uS)
}
//PASO 3: SEGUN EL TIEMPO DE CADA PULSO, DETERMINAMOS SI ES UN 0 O UN 1 LOGICO (Ver protocolo NEC)
for (x = 31; x >= 0; x--)
{
if (duracion[x] > 500 && duracion[x] < 700) //Si el pulso dura entre 500 y 700uS...
{
bitClear(codigo_tecla, x); //... es un 0 logico
}
if (duracion[x] > 1500 && duracion[x] < 1750) //Si el pulso dura entre 1500 y 1750uS
{
bitSet(codigo_tecla, x); //... es un 1 logico
}
}
}
//FIN SUBRUTINAS ************************************************************************************/
Y estos son los códigos nuevos (no es el ultimo código), funcionan a medias, ya que no cumplen con el protocolo NEC enviando la señal de repetición (estoy en ello) y otro gran problema de esta versión del código es que tiene un delay en el emisor de 1800, si lo reduzco el programa receptor empieza a leer cualquier fruta.
No les paso el ultimo código porque no lo probé aun, aunque este no funcione del todo bien por lo menos el receptor infrarrojo lee lo mismo que envía el emisor. Y para probar sirve y continuar mejorandolo.
Código emisor
#define PIN 3
#define inicio 9000
#define pausa 4500
#define cero 560
#define uno 1690
#define Hz 38000
unsigned long mensaje=0x48B76C93; // 0x48b76c93 // H·l"
void setup() {
pinMode(PIN, OUTPUT);
}
void loop() {
escribepin(inicio);
delayMicroseconds(pausa);
escribepin(cero);
escribemsj();
delay (1800);
}
void escribepin(int microseg){
tone(PIN, Hz);
delayMicroseconds(microseg);
noTone(PIN);
}
void escribemsj(){/////////////////////// MENSAJE
for (int nbit = 31; nbit >= 0; nbit--) {
Serial.print(bitRead(mensaje, nbit));
if (bitRead(mensaje, nbit)) {
escribepin(uno);
} else {
escribepin(cero);
delayMicroseconds(cero);
}
delayMicroseconds(cero);
escribepin(cero);
}
}/////////////////////// FIN MENSAJE
/*
escribepin(39416);
escribepin(inicio);
escribepin(2210);
escribepin(cero);
*/
Código receptor
#define PIN 9
int pausas[32], cuentamsj;
unsigned long mensaje = 0;
void setup() {
Serial.begin(9600);
pinMode(PIN, INPUT);
}
void loop() {
pausas[0] = pulseIn(PIN, HIGH);
if (pausas[0] > 0) {
for (cuentamsj = 31; cuentamsj >= 0; cuentamsj--) {
pausas[cuentamsj] = pulseIn(PIN, HIGH);
}
for (cuentamsj = 31; cuentamsj >= 0; cuentamsj--) {
if (pausas[cuentamsj] > 500 && pausas[cuentamsj] < 700) {
bitSet(mensaje, cuentamsj);
} else {
bitClear(mensaje, cuentamsj);
}
}
Serial.print("Mensaje original: 0x48B76C93 Traducido: 0x"); // HEX(0x48B76C93) // TEXT(H·l") // BIN(01001000 10110111 01101100 10010011)
Serial.println(mensaje, HEX);
}
}
Quizás a alguien le pueda servir, para aprender ya que no esta funcional.
Para el que no sabe mucho de programación (como yo) y quiere aprender (como yo) el tratar de mejorar el código representa un desafío y gran aprendizaje. Así qué, ahí tienen.
Por cierto, quien tenga mas experiencia en programación o electrónica y en algún momento se haya topado con información al respecto de este protocolo me avisa porque no pude encontrar mucha información y tengo ciertas dudas en cuanto a que hacer en el código emisor.