Picoteando arduinidades

Todo cuanto tiene que ver con la obtención, almacenamiento y proceso de la información digital, sus aplicaciones y el software y hardware utilizado.
Mensaje
Autor
Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Picoteando arduinidades

#1 Mensaje por Rovellat »

Al final me he liado la manta a la cabeza, y he dado un pasito con los arduinos, he relaizado mi primer sketch mas o menos serio, pero ha sido recopilando datos de aquí y de alla, por eso lo titulo picoteando, pero también se podría haber llamado compilando arduinerías, o mi primer sketch.

Como todavía no he aprendido a subirlo correctamente, os lo dejo en modo texto, creo que se entiende y está exaustivamente comentado.

Saludos.
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Re: Picoteando arduinidades

#2 Mensaje por Rovellat »

/* TODO_LCD_NIBBLE 1.0.0 (PICOTEANDO)

Jaime - Peñalén, Agosto-Setiembre 2015

Integración en un solo sketch de:

Transmisión serie USB, display LCD en modo nibble, 5 pulsadores, 2 encoders rotativos, receptor de IR de mando a distancia de TV, potenciómetro, y LDR.

(y la utilización conjunta de cinco pines del display LCD para otros usos compatibles, por ejemplo:
encoders rotativos, LEDs, pulsadores, contactos, relés, TRIACs, Etc.

Asignación de los pines del Arduino:
A0 Ristra de pulsadores
A1 Cursor del potenciómetro de 10K-47K conectado entre +5V y masa
A2 Lectura de la LDR alimentada desde +5V y el otro extremo a masa a través de una resistencia de 12K
NOTA: se puede conectar la LDR usando la resistencia PullUp del Arduino, en este caso la LDR
irá entre la entrada analógica y tierra, dará la lectura invertida y diferente, pero
se ahorra una resistencia externa, y además se puede conectar solo antes de leer,
y después desconectar, lo que ahorra energía.
A3-A5 Libres (se pueden usar como entrada analógica, entrada digital, y como salida digital.
D0 En principio no se puede usar si se usan comunicaciones en serie, si no se usan está libre
D1 En principio no se puede usar si se usan comunicaciones en serie, si no se usan está libre
D2 Entrada de interrupciones del Pin A del encoder 1
D3* Entrada de interrupciones del Pin A del encoder 2
D4 Es el pin de datos DB4 del LCD y pin reciclado 4 (Pin B del encoder 1 Ver NOTA a continuación)
D5* Es el pin de datos DB5 del LCD y pin reciclado 5 (Pin B del encoder 2 Ver NOTA a continuación)
D6* Es el pin de datos DB6 del LCD y pin reciclado 6
D7 Es el pin de datos DB7 del LCD y pin reciclado 7
D8 Es el pin RS del LCD y pin reciclado 8
D9* Es el pin ENABLE del LCD, no se puede reciclar, pero se puede usar de LATCH para capturar los pines reciclados del 4 al 8
D10* Es la retroalimentación del display, pero si se deja fija la retroalimentación, queda libre.
D11* Es la entrada de datos del lector de IR (infrarojos)
D12 (Libre o Pin B del encoder 1 Ver NOTA a continuación)
D13 (Libre o Pin B del encoder 2 Ver NOTA a continuación)
NOTA:Se pueden usar los pines reciclados como entrada del pinB de los encoders, en este caso hay que poner la resistencia de 360 Ohm, y usar
LeePinReciclado() en la rutina de interrupción del encoder. El resultado es que se recuperan los pines 12, y 13 a costa de dos resistencias

CONCEPTO DE PIN RECICLADO El display LCD usa muchos pines, pero solo cuando escribe datos, si la escritura se hace muy corta, estos se pueden usar:
Como entrada de datos en polling, leyendo en un momento que no coincida con la escritura, (separar con una resistencia de 360 Ohm).
Como salida de datos capturando con un latch y ENABLE del LCD, pero aún sin latch se pueden usar como:
Salida de LED, da pequeños destellos cuando escribe, pero se pueden soportar.
Salida para TRIAC, cuando se use en paso por cero y en aplicaciones no críticas como una resistencia calefactora.
Salida para un relé si se temporiza al enclavamiento y a la caida con un condensador.
Etc.
Los pines reciclados como salida, se usan de forma habitual, la función RefrescaLCD() se encarga de todo.
Los pines reciclados como entrada, se leen a traves de la función LeePinReciclado(), y a través de una resistencia de 360 Ohm, La señal a
leer debe ser de baja impedancia (unos 150 Ohm).
====== SOLO SE PUEDE ESCRIBIR EN EL DISPLAY A TRAVÉS DE RefrescaLCD() Y LEER PINES RECICLADOS A TRAVÉS DE LeePinReciclado() ========

RESUMEN DE PINES LIBRES O LIBERABLES PARA EL PROGRAMA DE USUARIO:
A3-A5 Están libres, son polivalentes entrada analógica, entrada digital, salida digital
A0 Libre si no se emplea la ristra de pulsadores
A1 Libre si no se usa el potenciómetro
A2 Libre si no se emplea la LDR
D0-D1 Libres si no se emplea la comunicación en serie
D2 Libre si no se emplea el encoder rotatorio 1
D3* Libre si no se emplea el encoder rotatorio 2
D4-D5*-D6*-D7-D8-D9*-D10* Libres si no se emplea el display LCD (D10* es facilmente liberable)
D10* Libre si no se utiliza como iluminación PWM del display.
D11* Libre si no se emplea el deceptor de infrarojos
D12 Libre si no se usa el encoder rotatorio 1, (o si se usa un pin reciclado como pin B del encoder rotatorio 1)
D13 Libre si no se usa el encoder rotatorio 2, (o si se usa un pin reciclado como pin B del encoder rotatorio 2)
(el asterico indica las salidas PWM)

(----- En un futuro tengo que aprender a manejar los timers con objeto de liberar el pin del receptor de IR, y 2, y 3 de los encoders
rotatorios, lo que dejaría mas pines libres, y usaría seguramente menos memoria. -----)

NOTA:Los pines A0…A5 además de como entradas analógicas, también pueden utilizarse como
entradas y salidas digitales, y también permiten conectar la resistencia PullUp interna.
Para digital se referencian como pines despúes del 13, es decir: el 14, 15, 16, 17,
18, 19 (que corresponden al A0, A1, A2, A3, A4, A5 y también pueden referenciarse como A0,
A1, A2, A3, A4, A5 por ejemplo:
pinMode(16,OUTPUT); //utiliza el pin A2 como salida
pinMode(A2,OUTPUT); //utiliza el pin A2 como salida
son equivalentes.
A pesar de que en algunos textos indica que se pueden emplear las entradas analógicas, como
salidas PWM,y que el arduino acepta analogWrite(An,x) sin dar error, funciona como salida
digital, pasando de 0 a 1 según el valor de x.


El objeto de este sketch es partir de una base bien comprobada para múltiples aplicaciones prácticas sencillas, en las que pueden quitarse
cualquiera de los elementos que no se utilicen sin tener que modificar el programa.

El punto de partida es un conocido shield que incluye el display LCD y la ristra de pulsadores, que me ha condicionado de algún modo a
tomar como fijos algunos de los pines del Arduino. No he usado de momento el display funcionando con I2C, porque la idea base es realizar
montajes muy sencillos y económicos, pero en un futuro tengo pensado hacerlo.

Este sketch se ha probado con placa base Arduino Uno r3 con Atmega328, coraza Mango-DFRobot lcd keypad shield, y el "montaje-shield" que me he
preparado, se ha compilado y probado con Arduino IDE 1.0.6, y 1.6.5

RECONOCIMIENTOS:
A todos los que han desarrollado y ayudado a desarrollar la plataforma Arduino.
A los chinos que han bajado los precios.
A los que escriben librerías que facilitan los desarrollos.
A los que han publicado en Internet numerosas informaciones, ejemplos y tutoriales.

*/







/********* DECLARACIÓN DE LIBERÍAS, ASIGNACION DE VARIABLES Y PINES ARDUINO *************/

//Esto afecta al display LCD y a los pines reciclados
//--------------------------------------------------
// está pensado para displays que sean comptatibles con LiquidCrystal, pero se ha realizado para un display 1602 (16 carácteres x 2 líneas)
// (para otros displays hay que realizar algunos cambios).
// se trata de la típica conexión nibble en paralelo, (4 hilos de datos + selector de registro + enable)
#include <LiquidCrystal.h>
# define DB4_LCD 4
# define DB5_LCD 5
# define DB6_LCD 6
# define DB7_LCD 7
# define RS_LCD 8
# define Enable_LCD 9
# define Luz_LCD 10
LiquidCrystal lcd(RS_LCD,Enable_LCD,DB4_LCD,DB5_LCD,DB6_LCD,DB7_LCD);
//char* Copia_LCD[2]={" "," "}; // NOTA no funciona al inicializar el array a espacios, confunde los indices
char* Copia_LCD[2]={"++++++++++++++++","----------------"}; // Array de dos dimensiones que
//tiene una copia de los carácteres que muestra el display LCD NOTA ESTO ES PARA UN DISPLAY DE 16X2 MODIFICAR EN CASO CONTRARIO
byte ValorAnterior[5]; //Array auxiliar de 5 variables para almacenar los valores de los pines reciclados
//(se pueden reciclar todos los pines excepto enable)

//Esto afecta a la ristra de pulsadores
//--------------------------------------------------
char* Pulsador[]={"NONE ","RIGHT ","UP ","DOWN ","LEFT ","SELECT"};

//Esto afecta al Encoder 1
//--------------------------------------------------
//El Pin C del encoder va a tierra
//Es conveniente poner un condensador de 10nF o mas entre el pinA y tierra, no es estrictamente necesario, pero si no se pone puede contar de mas.
# define Interrup_Enc_1 0 //Nº de interrupción attachInterrupt (OJO, esta ligado al PinA del encoder)
# define PinA_Enc_1 2 //Pin 2 del Arduino, este pin debe admitir interrupciones hardware (OJO, esta ligado al nº de interrupción attachInterrupt)
# define PinB_Enc_1 12 //Alternativa 1, Pin 12 del Arduino, (este pin no ocupa ninguna interrupción)
# define PinB_Enc_1_Reciclado 4 //Alternativa 2, es un pin reciclado compartido con el LCD, (usar con resistencia de 360 Ohm)
//Usar la línea apropiada en la rutina de interrupción según que alternativa se utilice.
# define RetardoRebote_1 6 //Retardo en milisegundos para evitar rebotes, se puede cambiar
volatile int Encoder_1 = 0; //Contador de pasos del encoder
volatile long TiempoRebote_1 = 0 ; // Variable global para controlar el tiempo y evitar rebotes

//Esto afecta al Encoder 2
//--------------------------------------------------
//El Pin C del encoder va a tierra
//Es conveniente poner un condensador de 10nF o mas entre el pinA y tierra, no es estrictamente necesario, pero si no se pone puede contar de mas.
# define Interrup_Enc_2 1 //Nº de interrupción attachInterrupt (OJO, esta ligado al PinA del encoder)
# define PinA_Enc_2 3 //Pin 2 del Arduino, este pin debe admitir interrupciones hardware (OJO, esta ligado al nº de interrupción attachInterrupt)
# define PinB_Enc_2 13 //Alternativa 1, Pin 13 del Arduino, (este pin no ocupa ninguna interrupción)
# define PinB_Enc_2_Reciclado 5 //Alternativa 2, es un pin reciclado compartido con el LCD, (usar con resistencia de 360 Ohm)
//Usar la línea apropiada en la rutina de interrupción según que alternativa se utilice.
# define RetardoRebote_2 6 //Retardo en milisegundos para evitar rebotes, se puede cambiar
volatile int Encoder_2 = 0; //Contador de pasos del encoder
volatile long TiempoRebote_2 = 0 ; // Variable global para controlar el tiempo y evitar rebotes



//Esto afecta a las comunicaciones serie
//--------------------------------------------------
// Si se usan comunicaciones serie no se pueden usar los pines digitales 0 y 1
// (por lo menos de la forma habitual)

//Esto afecta al lector de infrarojos (IR)
//--------------------------------------------------
// NOTA: consume bastante memoria, (pero tiene tantos botones......y sin tener que taladrar)
#include <IRremote.h>
#define irPin 11
IRrecv irrecv(irPin);
decode_results results;



//Esto afecta al programa del usuario
//--------------------------------------------------
#define Blinker DB6_LCD // (pin reciclado D6)
#define LuzDeNoche DB7_LCD // (pin reciclado D7)
int Delay = 250;
byte TeclaPulsada = 0;



//Esto afecta a las entradas analógicas del potenciómetro y la LDR
//---------------------------------------------------------------------
int Valor_Pot = 0;
long Valor_LDR = 0;




void setup() {

//Esto afecta al display
lcd.begin(16, 2); // Inicializa la librería para un display 1602
pinMode(Luz_LCD,OUTPUT); digitalWrite(Luz_LCD, 1); //Enciende luz de fondo del display
//lcd.clear();



//Esto afecta al Encoder1
pinMode(PinA_Enc_1, INPUT);
pinMode(PinB_Enc_1, INPUT);
digitalWrite(PinA_Enc_1, HIGH); //Activa resistencia interna
digitalWrite(PinB_Enc_1, HIGH); //Activa resistencia interna
attachInterrupt(Interrup_Enc_1, InterrupcionEncoder_1, LOW); /*Llama a una rutina de interrupción
según la circustancia del pin A del rotary encoder (FALLING, LOW) que provoca la interrupción */

//Esto afecta al Encoder2
pinMode(PinA_Enc_2, INPUT);
pinMode(PinB_Enc_2, INPUT);
digitalWrite(PinA_Enc_2, HIGH); //Activa resistencia interna
digitalWrite(PinB_Enc_2, HIGH); //Activa resistencia interna
attachInterrupt(Interrup_Enc_2, InterrupcionEncoder_2, LOW); /*Llama a una rutina de interrupción
según la circustancia del pin A del rotary encoder (FALLING, LOW) que provoca la interrupción */



//Esto afecta a las comunicaciones serie
Serial.begin(9600);


//Esto afecta al lector de infrarojos (IR)
irrecv.enableIRIn();



//Esto afecta al programa del usuario
//-------------------------------------
//Esto afecta a los pines reciclados como salida, poner alto o bajo (o no usar) según sea necesario.
//Eliminar o poner como comentario los que no se utilicen, o no se utilicen como salida
//(NOTA si no se definen pueden iniciarse aleatoriamente)
digitalWrite(DB4_LCD, LOW);
digitalWrite(DB5_LCD, LOW);
digitalWrite(DB6_LCD, LOW);
digitalWrite(DB7_LCD, LOW);
//digitalWrite(RS_LCD, LOW);
//Esto afecta a las entradas analógicas del potenciómetro y la LDR
//(Son los valores de iniciación, se pueden suprimir según de que programa de usuario se trate)
//Valor_Pot = analogRead(1);
Valor_LDR = analogRead(2);

}



void loop() {

// ESTO YA SERÍA EL PROGRAMA DE USUARIO (es un ejemplo)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

// Esto es un ejemplo de uso del pin reciclado como salida, en este caso
// el led conectado al pin Blinker parpadea solo si Encoder_1 > Encoder_2
if (Encoder_1 > Encoder_2) { digitalWrite(Blinker, HIGH); }
delay(Delay);
digitalWrite(Blinker, LOW);
delay(Delay);

// Escribe en el display el valor de los encoders
Refresca_LCD(0,0,3,String(Encoder_1));
Refresca_LCD(3,0,3,String(Encoder_2));

// Escribe en el display el valor del potenciómetro
Valor_Pot = analogRead(1);
Refresca_LCD(6,0,4,String(Valor_Pot));

Valor_LDR = (Valor_LDR * 9 + analogRead(2))/10; // Hace un promedio de varias lecturas ya que es muy poco estable
if (Valor_LDR > Valor_Pot) { Refresca_LCD(10,0,5,"Dia"); digitalWrite(LuzDeNoche, LOW);}
if (Valor_LDR < Valor_Pot +20) { Refresca_LCD(10,0,5,"Noche"); digitalWrite(LuzDeNoche, HIGH); } // se ha hecho de noche,
// enciende la luz, (es otro ejemplo de pin reciclado como salida)
//Refresca_LCD(12,0,4,String(Valor_LDR));
analogWrite(Luz_LCD, 51+(Valor_LDR/5)); //Ajuste del brillo del display según la LDR

// Ejemplo de uso de un pin reciclado como entrada
Refresca_LCD(15,0,1,String(LeePinReciclado( 8 )));

// Gestiona el receptor de infrarojos
if (irrecv.decode(&results)) {
//Serial.print("0x");
//Serial.println(results.value, HEX);
// Serial.println(results.value);
Refresca_LCD(0,1,10,String(results.value)); // Escribe el código de la tecla oprimida del mando a distancia.
irrecv.resume();
}


//gestiona la ristra de pulsadores en la entrada analógica
TeclaPulsada = LeeRistraPulsadores();
Refresca_LCD(10,1,6,String(Pulsador[TeclaPulsada]));

// FIN DEL PROGRAMA DE USUARIO
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^



}
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Re: Picoteando arduinidades

#3 Mensaje por Rovellat »

/*=================FUNCIONES===========================*/
/*=====================================================*/
/*=====================================================*/

/*================= InterrupcionEncoder_1 =============*/
void InterrupcionEncoder_1() {
// Esta función de interrupción entra cada vez que el encoder gira (concretamente cada vez que se cierra el contacto A-C

// Primero rechaza las interrupciones que se repiten dentro del tiempo "RetardoRebote"
if ( millis() < TiempoRebote_1 + RetardoRebote_1 ) return;
TiempoRebote_1 = millis(); // Actualiza TiempoRebote para rechazar las interrupciones que se produzcan antes de que haya transcurrrido RetardoRebote

// Después para cada interrupción válida lee el pin B, y aumenta o disminuye el contador en consecuencia

if (digitalRead(PinB_Enc_1)) { //Alternativa 1 (usar esta línea para un pin normal)
// if (LeePinReciclado(PinB_Enc_1_Reciclado)) { //Alternativa 2 (usar esta línea para un pin reciclado)

Encoder_1++;
} else {
Encoder_1--;
}
}

/*================= InterrupcionEncoder_2 =============*/
void InterrupcionEncoder_2() {
// Esta función de interrupción entra cada vez que el encoder gira (concretamente cada vez que se cierra el contacto A-C

// Primero rechaza las interrupciones que se repiten dentro del tiempo "RetardoRebote"
if ( millis() < TiempoRebote_2 + RetardoRebote_2 ) return;
TiempoRebote_2 = millis(); // Actualiza TiempoRebote para rechazar las interrupciones que se produzcan antes de que haya transcurrrido RetardoRebote

// Después para cada interrupción válida lee el pin B, y aumenta o disminuye el contador en consecuencia

if (digitalRead(PinB_Enc_2)) { //Alternativa 1 (usar esta línea para un pin normal)
// if (LeePinReciclado(PinB_Enc_2_Reciclado)) { //Alternativa 2 (usar esta línea para un pin reciclado)

Encoder_2++;
} else {
Encoder_2--;
}
}



/*==================== Refresca_LCD Larga =====================*/
void Refresca_LCD( byte PosicionInicial, byte Linea, byte PosicionesAEscribir, String Texto) {
// La misión de esta función es escribir en el display la cadena Texto, pero solamente los carácteres que hubiesen variado desde la
//escritura anterior; al minimizar las escrituras, se interfiere menos en las salidas de los pines reciclados.
// Esta es la función larga, que minimiza las escrituras, también se deja la corta, que es compatible con esta, pero no minimiza las escrituras,
// (es preferible la larga, pero en algunas circunstancias puede venir bien la corta)

boolean esigual = true ;
byte cabeza = 0;
byte cola = 0;

// Si el texto es mas corto que las posiciones a escribir, añade los espacios necesarios
// NOTA Poducía fallos con este código: Texto += " " ;
while ( Texto.length() < PosicionesAEscribir) { Texto += ' ' ; }

// Realiza un barrido para comprobar si los carácteres nuevos de Texto, coinciden con los
// ya escritos anteriormente (lo comprueba con copia_LCD). Usa dos punteros, cabeza y cola; solo mueve los punteros con los
// carácteres repetidos al principio, y al final, de forma que solo escribirá los carácteres que hayan variado, y alguno
// repetido que hubiese de por medio.
for ( byte i = 0; i < PosicionesAEscribir; i++ ){
if ( Copia_LCD[Linea][PosicionInicial + i ] != Texto ) { //Un caracter no coincide
Copia_LCD[Linea][PosicionInicial + i ] = Texto; //Actualiza copia_LCD
if (esigual) { //Solo la primera vez que encuentre un caracter diferente
esigual = false;
cabeza= i; // cabeza apunta al primer caracter diferente de Texto
}
cola = i ; // Esto lo hace con cada caracter diferente; si los últimos son iguales, cola ya no se mueve, y el resultado es que
//cola apunta al último caracter diferente.
}
}

if (esigual) {
return; // No hay nada nuevo que escribir, el nuevo texto coincide con el que ya había en el display y termina
}

Texto = Texto.substring(cabeza,cola+1); // Recorta Texto quitando los carácteres que ya estaban en el display por la derecha, y por la izquierda
PosicionInicial += cabeza ; // Reajusta la posición inicial, saltándose los carácteres que ya estaban escritos

// Ahora toma nota de los valores que había en los pines reciclados como salida
// NOTA, para los pines que no se utilicen como salida ponerlos como comentario o quitar la línea de programa
ValorAnterior[0] = digitalRead(DB4_LCD);
ValorAnterior[1] = digitalRead(DB5_LCD);
ValorAnterior[2] = digitalRead(DB6_LCD);
ValorAnterior[3] = digitalRead(DB7_LCD);
//ValorAnterior[4] = digitalRead(RS_LCD);

// Aquí realmente escribe en el display LCD, y es cuando los pines reciclados como salida varían por un corto espacio de tiempo
lcd.setCursor(PosicionInicial , Linea);
lcd.print(Texto); // imprime el texto

// Ahora reescribe los valores que había en los pines reciclados como salida.
// NOTA, para los pines que no se utilicen como salida ponerlos como comentario o quitar la línea de programa
digitalWrite(DB4_LCD, ValorAnterior[0]);
digitalWrite(DB5_LCD, ValorAnterior[1]);
digitalWrite(DB6_LCD, ValorAnterior[2]);
digitalWrite(DB7_LCD, ValorAnterior[3]);
//digitalWrite(RS_LCD, ValorAnterior[4]);

}


/*==================== Refresca_LCD Corta=====================*/
/*void Refresca_LCD( byte PosicionInicial, byte Linea, byte PosicionesAEscribir, String Texto) {
// Esta función es como Refresca_LCD Larga, pero no considera los carácteres repetidos, ecribe todo el texto, con lo cual
// los pines reciclados como salida tienen mas ruido. Ambas son compatibles, pero es preferible la larga; se deja esta
// por si hubiese algún problema, o para depurar un montaje, evidentemente solo puede estar una de las dos activa.
// (ver los comentarios de la función larga)
// IMPORTANTE Comentar una u otra para desactivarla

while ( Texto.length() < PosicionesAEscribir) { Texto += ' ' ; }
Texto = Texto.substring(0,PosicionesAEscribir);
ValorAnterior[0] = digitalRead(DB4_LCD);
ValorAnterior[1] = digitalRead(DB5_LCD);
ValorAnterior[2] = digitalRead(DB6_LCD);
ValorAnterior[3] = digitalRead(DB7_LCD);
//ValorAnterior[4] = digitalRead(RS_LCD);
lcd.setCursor(PosicionInicial , Linea);
lcd.print(Texto); // imprime el texto
digitalWrite(DB4_LCD, ValorAnterior[0]);
digitalWrite(DB5_LCD, ValorAnterior[1]);
digitalWrite(DB6_LCD, ValorAnterior[2]);
digitalWrite(DB7_LCD, ValorAnterior[3]);
//digitalWrite(RS_LCD, ValorAnterior[4]);

}*/


/*==================== LeePinReciclado =====================*/
byte LeePinReciclado( byte PinLeido) {
//digitalWrite(PinLeido, LOW);
pinMode(PinLeido,INPUT);
//digitalWrite(PinLeido, HIGH); //Activa resistencia PullUp interna necesaria para detectar contacatos a masa tales como un pulsador
// o un encoder. No parece ser estrictamente necesaria, de momento la quito, pero ojo por si da problemas.
byte DatoLeido = digitalRead(PinLeido);
pinMode(PinLeido,OUTPUT);
return DatoLeido;
}

/*==================== LeeRistraPulsadores =====================*/
int LeeRistraPulsadores() {
/* Los pulsadores cortocircuitan una ristra de resistencias
a tierra y se leen las resistencias en una entrada analógica.
Los valores de lectura obtenidos han sido:
None 1023
Right 0
Up 131
Down 308
Left 481
Select 722
Pero se pone un valor intermedio para evitar lecturas incorrectas
*/
int Valor_Leido = analogRead(0);
if (Valor_Leido < 60) return 1; //RIGHT
if (Valor_Leido < 200) return 2; //UP
if (Valor_Leido < 390) return 3; //DOWN
if (Valor_Leido < 600) return 4; //LEFT
if (Valor_Leido < 850) return 5; //SELECT
return 0; //NONE (ningún botón)
}
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Avatar de Usuario
Alfon
Mensajes: 1432
Registrado: Dom Mar 04, 2007 10:44 pm
País: España
Ciudad: Figueres
Ubicación: Gerona/España
Contactar:

Re: Picoteando arduinidades

#4 Mensaje por Alfon »

Hola Robellat.

Muy bien, te has puesto a tope con el arduino.
Como siempre aconsejo, cuando no salen los programas, es tomarse-lo con más calma y probar cada bloque o sensor por separado y luego cuando todas las partes funcionan por separado, unirlo en el megaprograma.

Saludos
El saber no ocupa lugar, pero sí tiempo ^_^
-- Personal --> www.bitacoradealfon.es <--
-- Comercial --> www.altortech.es <--

Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Re: Picoteando arduinidades

#5 Mensaje por Rovellat »

Se ve que la clase String no está muy depurada, me daba fallos por todos lados, lo mas dificil ha sido detectarlos, he tenido que inventarme "puntos de ruptura" para ir parando el programa y ver que es lo que pasaba, se ve que los espacios no los digiere bién, confundía los punteros del array, mezclaba las cadenas.....

Realmente lo que he hecho es juntar cosas de diseño ajeno, luego me he dado cuenta que me quedaba sin pines, y me he metido en la reutilización de los pines que usa el LCD, esto ha sido diseño propio. Lo del hardware sin problemas, a ver si esta vez arranco.

Picoteando es el punto de partida de algunas cosillas que tengo en mente:

Temporizador de luz de escalera avanzado.
Voltimetro-Amperímetro-Vatímetro para continua.
Otro para alterna con arranque en paso por cero (para el variac, a ver si asi no fundo los plomos).
Variador de frecuencia.

Lo que pasa es que muchos de los montajes van con el arduino directamente a la red, y con el portatil no me atrevo a jugar, tendré que esperar un poco.

Saludos.
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Re: Picoteando arduinidades

#6 Mensaje por Rovellat »

Alfon, por cierto, en el dibujo que pusiste del encoder en lo del medidor perimetral, creo que están mal los pines.

Además mis encoders en reposo no hacen ninguno de los contactos, se produce la secuencia en cada paso, pero solo durante el paso, luego quedan ambos contactos aislados, eso también me llevó algunos quebraderos de cabeza.

Saludos.
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Avatar de Usuario
Alfon
Mensajes: 1432
Registrado: Dom Mar 04, 2007 10:44 pm
País: España
Ciudad: Figueres
Ubicación: Gerona/España
Contactar:

Re: Picoteando arduinidades

#7 Mensaje por Alfon »

Rovellat escribió:Alfon, por cierto, en el dibujo que pusiste del encoder en lo del medidor perimetral, creo que están mal los pines.

Además mis encoders en reposo no hacen ninguno de los contactos, se produce la secuencia en cada paso, pero solo durante el paso, luego quedan ambos contactos aislados, eso también me llevó algunos quebraderos de cabeza.

Saludos.
Hola Robellat.
Pues deben ser encoders diferentes, el del mouse que usé mantiene el estado abierto o cerrado en cada paso, y el segundo switch es el que va retardado y es como la imagen que puse en el foro.

Lo mejor es ver con osciloscopio como funciona y luego diseñar el software para que lo detecte,, también importante ver si hay rebotes y darle un pequeño delay o timmer para evitarlos, o simplemente un pequeño condensador y ver con osciloscopio que no haya rebotes.

Sinceramente los primeros programas con interrupciones me fueron muy mal, pero a base de probar y trastear vas encontrando el truco o el código que mejor va, luego como dices es reciclar o rescatar partes de otros programas que hayas guardado.
También cuando voy diseñando el programa, voy guardando versiones, y así puedes volver atrás o quedarte con el código mejor.

Saludos
El saber no ocupa lugar, pero sí tiempo ^_^
-- Personal --> www.bitacoradealfon.es <--
-- Comercial --> www.altortech.es <--

Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Re: Picoteando arduinidades

#8 Mensaje por Rovellat »

Arrojando un poco de luz sobre los encoders:

Me he encontrado está paginita que lo explica bastante bién:
https://www.pjrc.com/teensy/td_libs_Encoder.html

La imagen de partida sería esta:

https://www.pjrc.com/teensy/td_libs_Encoder_pos3.png

La parte azul del disco es metálica y conectada al pin C del encoder, (el central), que en mi caso y habitualmente se conecta a masa.

Las zonas blancas del disco están aisladas, como tenemos resistencias pull-up (internas de micro en mi caso), los terminales Pin1 y Pin2 (A y B en mi caso), están en zona aislada, con lo que habrá un nivel alto en ambas, y por descontado los tres pines aislados entre si.

Esta es la posición de partida, y cada paso va a ejecutar la secuencia que pongo a continuación, pero vuelve a quedar en la posición de reposo, que es la misma del punto de partida.
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Re: Picoteando arduinidades

#9 Mensaje por Rovellat »

Ahora ejecutamos un paso a derecha, primero pasa esto:

https://www.pjrc.com/teensy/td_libs_Encoder_pos4.png

El pin A se conecta con el C (masa), y provoca una interrupción por bajada (o por nivel), interrupción que lee el estado del pin B, que es alto, y por lo tanto incrementa el contador.

Después pasa esto en el encoder:

https://www.pjrc.com/teensy/td_libs_Encoder_pos1.png

Pero como A no ha variado, no hay interrupción, ni cambio de contador.

Después pasa esto en el encoder:

https://www.pjrc.com/teensy/td_libs_Encoder_pos2.png

Ahora A ha variado, pero como es flanco de subida o nivel alto, tampoco hay interrupción ni cambio de contador.

Y volvemos de nuevo a la posición de reposo:

https://www.pjrc.com/teensy/td_libs_Encoder_pos3.png

Y como A no ha cambiado, tampoco sucede nada.

Y todo esto ha sido un solo paso, y un solo incremento del contador. el encoder tiene posiciones estables que coinciden con la que figura en la última imagen, las otras posiciones son inestables y transitorias.

Es facil ver que al girar a izquierdas, cuando se produce la interrupción (en A) el pin B está bajo, y se decrementa el contador.

La secuencia sería:

Reposo:

https://www.pjrc.com/teensy/td_libs_Encoder_pos3.png

Se inicia el giro:

https://www.pjrc.com/teensy/td_libs_Encoder_pos2.png

(No pasa nada porque el pin A no ha cambiado)

Continúa girando:

https://www.pjrc.com/teensy/td_libs_Encoder_pos1.png

(Ahora el pin A provoca la interrupción, dicha interrupción lee el pin B, y como está bajo, se decrementa el contador)

Gira un poco mas:

https://www.pjrc.com/teensy/td_libs_Encoder_pos4.png

(no hay interrupción, no pasa nada)

Y de nuevo en la posición de reposo:

https://www.pjrc.com/teensy/td_libs_Encoder_pos3.png

(aquí si que ha habido un cambio del pin A, pero no provoca interrución al ser una subida)

Saludos.
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Avatar de Usuario
Rovellat
Mensajes: 9688
Registrado: Mar May 26, 2009 9:39 pm
Ubicación: Palma de Mallorca (España)

Re: Picoteando arduinidades

#10 Mensaje por Rovellat »

Ahora ando muy liado con otros temas, pero he encontrado una paginita que parece interesante, no tengo ni tiempo de mirarla, y si la apunto aquí, no se me perderá.

Seguro que es una de las muchísimas que hay, pero está en castellano, y orientada a la educación.

http://josemanuelruizgutierrez.blogspot.com/

Saludos.
Cielo azul sobre campo de mieses, ánimo.
Constitución Española:
Todos los españoles tienen el deber de trabajar y el derecho al trabajo.
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada.

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados