Proyecto nuevo con TM1640 Ayuda plz...

Buenos dias a todos...

Despues de mucho tiempo sin contactar en el foro, he empezado de nuevo a moverme y he realizado la adaptacion del script siguiente...

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1226896251

Mi idea de momento es hacer aparecer un texto cuando muevo un rotary switch de doce posiciones, al que le he añadido resistencias a modo de divisores de voltaje, de modo que cada posición muestre un valor...

Para visualizar este valor empleo una tira de displays controlada por un tm1640...

No se que error cometo pero el resultado no es satisfactorio, comparto con vosotros el script que he adaptado,...

*/
Script para Arduino (AVR controller i/o board).
Proyecto de Panel de Radio genérico
para simulador de vuelo Xplane.
inigohe ;)
*/

///////////////////////////////////////////////////

#include <Bounce.h>
#include <Encoder.h>

Bounce buttonUp = Bounce(3, 5);      					// Pulsador en pin 3, 5ms debounce.
Bounce buttonDown = Bounce(4, 5);					// Pulsador en pin 4, 5ms debounce.
Encoder wheel.active = Encoder(5, 6);         			// Encoder en pines 5 y 6.
Encoder wheel.standby = Encoder(7, 8);				// Encoder en pines 7 y 8.

int val =0;										// Valor analogico, donde se almacena 
											// la lectura.
int stage =1;									// Paso en el que se encuentra el 
											// switch (1-12).
int ledPin = 9;      								// Led conectado a salida 
											// PWM.					
int analogPin = 0;   								// Pin analogico conectado al 
											// switch.					
char status[6];									// Opción dada por el switch en la 
											// posición elegida. 						
long encoder_prevActive=0;						// Para detectar cambio de posición 
											// en el encoder display Activo.
long encoder_prevStndby=0;						// Para detectar cambio de posición 
											// en el encoder display Standby.
long Com1FrequencyHzActive=0;
long Com1FrequencyHzStndby=0;
long Com2FrequencyHzActive=0;
long Com2FrequencyHzStndby=0;
long Nav1FrequencyHzActive=0;
long Nav1FrequencyHzStndby=0;
long Nav2FrequencyHzActive=0;
long Nav2FrequencyHzStndby=0;
long Adf1FrequencyHzActive=0;
long Adf1FrequencyHzStndby=0;
long Adf2FrequencyHzActive=0;
long Adf2FrequencyHzStndby=0;

elapsedMillis inactivityTimeout;                                                 // Midiendo tiempo de inactividad. 

///////////////////////////////////////////////////	
					
void setup()
{
  pinMode(ledPin, OUTPUT);   							// Se declarara el pin del led como 
												// salida digital.				
  pinMode(val, INPUT);								// Se declara el pin del Rotary como 
												// entrada analógica.
  pinMode(3, INPUT_PULLUP);							// Input_Pullup permite conectar 
												// switches y botones a tierra
  pinMode(4, INPUT_PULLUP);							// el chip proporciona la resistencia 
												// requerida para tal
  pinMode(5, INPUT_PULLUP);							// uso.
  pinMode(6, INPUT_PULLUP);							// ;)
  pinMode(7, INPUT_PULLUP);							// *******
  pinMode(8, INPUT_PULLUP);							// ;)
  
  //Serial.begin(4800);								// El puerto serie se emplea para el 
												// calibrado de 
}												// los valores del Rotary switch.

///////////////////////////////////////////////////

void loop() {
	flightSim.update();
	readSwitch();									// Lectura del sensor
	if (stage == 1) {
		readEncoderCom1()}
	if (stage == 2){
		readEncoderCom2()}
	if (stage == 3){
		readEncoderNav1()}
	if (stage == 4){
		readEncoderNav2()}
	if (stage == 5){
		readEncoderAdf1()}
	if (stage == 6){
		readEncoderAdf2()}
	
		
	// printLine();									// Usado solo para calibrado y 
												// pruebas del Rotary switch y encoders.
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////

void readSwitch();{
	val =analogRead(analogPin);							// Almacena el valor leido en 0 
												// analog, en val.
	//serial.print(val);								// Usado solo para calibrado 
												// y pruebas del Rotary switch.
	
	if(val>=972 && val< 1024) {							// Lectura entrada analógica 1023.
    stage =  1; 
    status = "Com 1";} 									// Com 1.
  if(val>=828  && val< 928) {							// Lectura entrada analógica 878.
    stage =  2; 
    status = "Com 2";} 									// Com 2.
  if(val>=682  && val< 782) {							// Lectura entrada analógica 732.
    stage =  3; 
    status = "Nav 1";} 									// Nav 1.
  if(val>=535  && val< 635) {							// Lectura entrada analógica 585.
    stage =  4; 
    status = "Nav 2";} 									// Nav 2.
  if(val>=387  && val< 487) {							// Lectura entrada analógica 437.
    stage =  5; 
    status = "Adf 1";}									// Adf 1.
  if(val>=241  && val< 341) {							// Lectura entrada analógica 291.
    stage =  6; 
    status = "Adf 2";}									// Adf 2.
  if(val>=94  && val< 194) {							       // Lectura entrada analógica 144.
    stage =  7; 
    status = "Trspdr";} 								       // Transponder.
  if(val>=0 && val< 94) {								// Lectura entrada analógica 0.
    stage =  8; 
    status = "Hdg";} 									// Heading.
  }
  
///////////////////////////////////////////////////
///////////////////////////////////////////////////

 void readEncoderCom1();
{
	long encActive=wheel.Active.read();			   		// Leer el encoder y si ha cambiado
												// escribir Com1FrequencyHz Activo y 
												// Standby.
	long encStndby=wheel.Stndby.read();
	if (encActive != encoder_prevActive) {
	Com1FrequencyHzActive=Com1FrequencyHzActive+(encActive-encoder_prevActive);
	encoder_prevActive=encActive;
	}
	if (encStndby != encoder_prevStndby9 {
	Com1FrequencyHzStndby=Com1FrequencyHzStndby+(enStndby-encoder_prevStndby);
	encoder_prevStndby=encStndby;
    }
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////

void readEncoderCom2();
{
	long encActive=wheel.Active.read();			   		// Leer el encoder y si ha cambiado
												// escribir Com2FrequencyHz Activo y 
												// Standby.
	long encStndby=wheel.Stndby.read();
	if (encActive != encoder_prevActive) {
	Com2FrequencyHzActive=Com2FrequencyHzActive+(encActive-encoder_prevActive);
	encoder_prevActive=encActive;
	}
	if (encStndby != encoder_prevStndby9 {
	Com2FrequencyHzStndby=Com2FrequencyHzStndby+(enStndby-encoder_prevStndby);
	encoder_prevStndby=encStndby;
    }
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////

void readEncoderNav1();
{
	long encActive=wheel.Active.read();			   		// Leer el encoder y si ha cambiado
												// escribir Nav1FrequencyHz Activo y
												// Standby.
	long encStndby=wheel.Stndby.read();
	if (encActive != encoder_prevActive) {
	Nav1FrequencyHzActive=Nav1FrequencyHzActive+(encActive-encoder_prevActive);
	encoder_prevActive=encActive;
	}
	if (encStndby != encoder_prevStndby9 {
	Nav1FrequencyHzStndby=Nav1FrequencyHzStndby+(enStndby-encoder_prevStndby);
	encoder_prevStndby=encStndby;
    }
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////

void readEncoderNav2();
{
	long encActive=wheel.Active.read();			   		// Leer el encoder y si ha cambiado
												// escribir Nav2FrequencyHz Activo y
												// Standby.
	long encStndby=wheel.Stndby.read();
	if (encActive != encoder_prevActive) {
	Nav2FrequencyHzActive=Nav2FrequencyHzActive+(encActive-encoder_prevActive);
	encoder_prevActive=encActive;
	}
	if (encStndby != encoder_prevStndby9 {
	Nav2FrequencyHzStndby=Nav2FrequencyHzStndby+(enStndby-encoder_prevStndby);
	encoder_prevStndby=encStndby;
    }
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////

void readEncoderAdf1();
{
	long encActive=wheel.Active.read();			   		// Leer el encoder y si ha cambiado
												// escribir Adf1FrequencyHz Activo y
												// Standby.
	long encStndby=wheel.Stndby.read();
	if (encActive != encoder_prevActive) {
	Adf1FrequencyHzActive=Adf1FrequencyHzActive+(encActive-encoder_prevActive);
	encoder_prevActive=encActive;
	}
	if (encStndby != encoder_prevStndby9 {
	Adf1FrequencyHzStndby=Adf1FrequencyHzStndby+(enStndby-encoder_prevStndby);
	encoder_prevStndby=encStndby;
    }
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////

void readEncoderAdf2();
{
	long encActive=wheel.Active.read();			   		// Leer el encoder y si ha cambiado
												// escribir Adf2FrequencyHz Activo y
												// Standby.
	long encStndby=wheel.Stndby.read();
	if (encActive != encoder_prevActive) {
	Adf2FrequencyHzActive=Adf2FrequencyHzActive+(encActive-encoder_prevActive);
	encoder_prevActive=encActive;
	}
	if (encStndby != encoder_prevStndby9 {
	Adf2FrequencyHzStndby=Adf2FrequencyHzStndby+(enStndby-encoder_prevStndby);
	encoder_prevStndby=encStndby;
    }
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////

El problema es que los valores que aparecen en el puerto serie, no se corresponden con su valor que supuestamente he definido...
Gracias por los comentarios.

inigohe

Hola,

Cuando te refieres a

inigohe:
El problema es que los valores que aparecen en el puerto serie, no se corresponden con su valor que supuestamente he definido...

Supongo que estas haciendo referencia a la línea de código que está comentada en la función

void readSwitch();{
	val =analogRead(analogPin);							// Almacena el valor leido en 0 
												// analog, en val.
	//serial.print(val);								// Usado solo para calibrado 
												// y pruebas del Rotary switch.
	
	if(val>=972 && val< 1024) {							// Lectura entrada analógica 1023.
    stage =  1; 
    status = "Com 1";} 									// Com 1.
...
...
  }

Y cuando dices que no coinciden con el valor que has definido te refieres al valor que esperas según las resistencias que has puesto.

Si todo esto es así, el problema que tienes es que no has "definido" bien el valor de esas resistencias. Tendrás que poner el esquema del circuito que has montado para que lo podamos comprobar.

Por otro lado, estaría bien que pusieses el código que realmente estabas probando (a parte de no enviar nada por puerto serie, el código que has puesto no compila ya que has puesto un "9" en lugar de un ")" en todas las funciones readEncoder...(), maldito copy&paste!!! ;)) que supongo que será una parte de este con el resto comentado.

Buenas tardes Jorge..

Ante todo gracias por la respuesta y disculpa por el retraso en contestarte, he estado unos dias de viaje con la familia fuera.

He estado trabajando en el script y he localizado algunos errores, por ello actualizo este...

Tienes razon con el cortar y pegar y con los cambios de formato (tabuladores y demas).. me estoy creando mas de un problema, de todos modos creo que ahora esta un poco mas claros.

En principio mi idea era crear un void loop con una serie de comandos en funcion de la orden seleccionada por el rotary switch, la lectura del circuito divisor de voltage es correcta, lo he comprobado haciendo un sencillo script de lectura a traves del puerto serie.

He incluido un rango +/- 50 el valor visto en pantalla, como puedes observar.

He puesto el skecht adjunto con este, para que este claro :wink: con este solo deciros que los errores que me presenta son..

sketch_aug31b.cpp: In function 'void loop()':
sketch_aug31b:71: error: 'readSwitch' was not declared in this scope (solucionado)
sketch_aug31b:73: error: 'readEncoderCom1' was not declared in this scope (solucionado)
sketch_aug31b:73: error: expected `;' before '}' token
sketch_aug31b:75: error: 'readEncoderCom2' was not declared in this scope (solucionado)
sketch_aug31b:75: error: expected `;' before '}' token
sketch_aug31b:77: error: 'readEncoderNav1' was not declared in this scope (solucionado)
sketch_aug31b:77: error: expected `;' before '}' token
sketch_aug31b:79: error: 'readEncoderNav2' was not declared in this scope (solucionado)
sketch_aug31b:79: error: expected `;' before '}' token
sketch_aug31b:81: error: 'readEncoderAdf1' was not declared in this scope (solucionado)
sketch_aug31b:81: error: expected `;' before '}' token
sketch_aug31b:83: error: 'readEncoderAdf2' was not declared in this scope (solucionado)
sketch_aug31b:83: error: expected `;' before '}' token
sketch_aug31b.cpp: At global scope:
sketch_aug31b:93: error: expected unqualified-id before '{' token

Es como si no identificara elementos del bucle void loop...

El objetivo es lograr con los encoders mover tanto los digitos de un lado como el otro... estos seran modo activo y standby luego en medio tendremos la variable que corresponde a estos por ejemplo Com 1, que seria seleccionada con el rotary switch con divisores de voltaje.

Este es un faceplate para el panel de control, como veis es una version digamos Beta...

Bueno no se si me he explicado del todo.

Un saludo.

inigohe

sketch_aug31b.ino (9.19 KB)

Buenas a todos...

Parece ser que no he definido correctamente las funciones readSwitch(); readEncoderCom1() readEncoderCom2() readEncoderNav1() readEncoderNav2() readEncoderAdf1() readEncoderAdf2().

En este momento estoy bloqueado, porque creia haber definido correctamente estas funciones llamandolas desde el void loop y luego ejecutandolas, segun los bloques void que se encuentran en la parte inferior al void loop...

void loop() {
	// flightSim.update();                                                                      // Data from Flight simulator Xplane
	readSwitch();									    // Lectura del sensor
	if (stage == 1) {
		readEncoderCom1();}
	if (stage == 2){
		readEncoderCom2();}
	if (stage == 3){
		readEncoderNav1();}
	if (stage == 4){
		readEncoderNav2();}
	if (stage == 5){
		readEncoderAdf1();}
	if (stage == 6){
		readEncoderAdf2();}
        if (stage == 7)
	        readEncoderTrpdr();}
		
	// printLine()										    // Usado solo para calibrado y 
												    // pruebas del Rotary switch y encoders.
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////

 void readEncoderCom1()
{
	long encActive=wheelActive.read();			   		                    // Leer el encoder y si ha cambiado
												    // escribir Com1FrequencyHz Activo y 
												    // Standby.
	long encStndby=wheelStndby.read();
	if (encActive != encoder_prevActive) {
	Com1FrequencyHzActive=Com1FrequencyHzActive+(encActive-encoder_prevActive);
	encoder_prevActive=encActive;
	}
	if (encStndby != encoder_prevStndby) {
	Com1FrequencyHzStndby=Com1FrequencyHzStndby+(encStndby-encoder_prevStndby);
	encoder_prevStndby=encStndby;
    }
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////
el resto es similar en el script...

Link del script en pdf
http://www.4shared.com/office/mWsqssuj/sketch_aug31b_5.html

Errores que persisten...

sketch_aug31b.cpp: In function 'void readSwitch()':
sketch_aug31b:104: error: invalid array assignment
sketch_aug31b:107: error: invalid array assignment
sketch_aug31b:110: error: invalid array assignment
sketch_aug31b:113: error: invalid array assignment
sketch_aug31b:116: error: invalid array assignment
sketch_aug31b:119: error: invalid array assignment
sketch_aug31b:122: error: invalid array assignment
sketch_aug31b:125: error: invalid array assignment

He corregido todas las coladas que eran bastantes, solo me queda la asignacion del array... que seguramente sea igualmente facil de resolver.

Gracias a todos por las respuestas...

inigohe

Buenas a todos, actualizado post...

inigohe

menudo programón, me cuesta mucho mirar programas tan largos pero está mal el ; que hay en la función readSwitch por lo que creo que al ver ; no entrará a la función.

void readSwitch();{

Salu2

Kaixo...

Muchas gracias por la respuesta, al igual que tu Norman Elliot del Google Group Tronixstuff, me dijo lo mismo pero cuando pongo el puñetero ; y compilo me aparece el siguiente mensaje de error...

sketch_aug31b.cpp: In function 'void loop()':
sketch_aug31b:74: error: expected `;' before 'if'
sketch_aug31b:76: error: 'else' without a previous 'if'
sketch_aug31b.cpp: In function 'void readSwitch()':
sketch_aug31b:104: error: invalid array assignment
sketch_aug31b:107: error: invalid array assignment
sketch_aug31b:110: error: invalid array assignment
sketch_aug31b:113: error: invalid array assignment
sketch_aug31b:116: error: invalid array assignment
sketch_aug31b:119: error: invalid array assignment
sketch_aug31b:122: error: invalid array assignment
sketch_aug31b:125: error: invalid array assignment

No se el motivo, pero cuando pongo el "puñetero" ;, el error if desaparece dandome solamente los siguientes errores...

sketch_aug31b.cpp: In function 'void readSwitch()':
sketch_aug31b:104: error: invalid array assignment
sketch_aug31b:107: error: invalid array assignment
sketch_aug31b:110: error: invalid array assignment
sketch_aug31b:113: error: invalid array assignment
sketch_aug31b:116: error: invalid array assignment
sketch_aug31b:119: error: invalid array assignment
sketch_aug31b:122: error: invalid array assignment
sketch_aug31b:125: error: invalid array assignment

Como comprenderas estoy bloqueado, ante esta situacion.

Respecto a la longitud del script, es consecuencia de mis carencias en el lenguaje de programacion, seguro que empleando algun tipo de array, char o similar seria posible abreviarlo.

Un saludo desde Urnieta.

Inigohe

Saludos,...

Por fin he conseguido compilar el script, a ver si hago el montaje con los dos encoders rotativos, el rotary switch y la tira Tm1640.

A ver que sale.... :~

Os adjunto el fichero en formato pdf y punto ino, para que podais abrirlo con el compilador...

https://dl.dropbox.com/u/58726056/sketch_sep06c/video%20stack.avi
https://dl.dropbox.com/u/58726056/sketch_sep06c/panel_inigo_02.pdf
https://dl.dropbox.com/u/58726056/sketch_sep06c/panel_inigo_02.ino

He incluido las librerias Tm1640 de Ricardo Batista y compilado el conjunto satisfactoriamente.

Se ha simplificado mucho el script empleando arrays,... eneste punto ha sido decisivo Alvaro Alea, que me aconsejo y me facilito enormemente la faena.


Como podeis observar, no me he rascado mucho la cabeza con el proto... esto no deberia alterar el resultado final :wink:

Muchisimas gracias a Alvaro Alea, Norman Elliot y el resto de compañeros...

Muchas gracias a todos, seguro que os seguire dando la tabarra;))

inigohe

con los errores:

sketch_aug31b.cpp: In function 'void loop()':
sketch_aug31b:74: error: expected `;' before 'if'
sketch_aug31b:76: error: 'else' without a previous 'if'

Entiendo que te dice que en la función loop falta algún ; antes que un if y que falta un if porque hay un else (antes que un else siempre va un if)

He mirado un poco y tienes un loop y he visto que en el primer programa tienes hasta stage ==6 pero en otro post has cambiado algo y he visto que has puesto stage ==7 donde te falta una llave de apertura {

Lo del ; que comentas supongo que será porque al poner void readSwitch();{ no compilará el contenido de las llaves por lo que no ve el error de compilación. Pero poner ese ; es engañarte a ti mismo porque quiere decir que no se va ejecutar nunca el contenido de las llaves.

Por cierto el código esta bien, limpiamente extructurado y está bien programado. Soy yo al que le cuesta meterse en la mente de la gente para entender que quiere hacer. Agur

Actualizado contenido con script depurado y video de funcionamiento.

inigohe

Buenas...
Aqui estoy de nuevo... estoy tratando de recoger los datos que envia arduino a traves del puerto serie pero cuando hago el siguiente script
de phyton y me da error, algun compañero podria decirme donde meto el cazo...

import serial
ser = serial.Serial(‘com3’, 9600)
dato = ser.readline()
print dato

el mensaje de error

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    print dato
NameError: name 'dato' is not defined

Gracias de antemano.

inigohe

Saludos a todos...

Aqui estoy de nuevo, tengo un pequeño problemilla...

De una parte tengo que hacer numerosos giros del encoder para incrementar el valor de la frecuencia, bien Active como StandBy, habria algun tipo de formula que permitiera de algun modo poder incrementar los valores de 10 en 10 o 100 en 100 en funcion de la velocidad de giro, teniendo en cuenta que el valor maximo es 999,99 hz.

Y de otra parte, mi idea es que al girar la frecuencia que sea la que sea hacia la izquierda el valor correspondiente minore, cosa que no me sucede... creo que he cometido algun tipo de error.

Aunque seguramente no sea el que me los vendio las especificaciones de los encoders son las siguientes...

Electrical Characteristics
Output .........................2-bit gray code
Closed Circuit Resistance ......3 ohms maximums
Contact Rating .................1 mA @ 5 VDC
Insulation Resistance ..........10 megohms @ 250 VDC
Dielectric Withstanding Voltage
Sea Level ......................50 VAC minimum
Electrical Travel ..............Continuous
Contact Bounce (15 RPM).........5.0 ms. maximum
RPM (Operating) ................100 maximum
Environmental Characteristics
Operating Temperature Range .....-30 °C to +70 °C (-22 °F to +158 °F)
Storage Temperature Range .......-40 °C to +85 °C (-40 °F to +185 °F)
Humidity.........................MIL-STD-202, Method 103B, Condition B
Vibration .......................30 G
Contact Bounce ..................10~55~10 Hz / 1 min. / Amplitude 1.5 mm
Shock ...........................100 G
Rotational Life..................30,000 cycles minimum
Switch Life .....................20,000 cycles minimum
IP Rating........................IP 40
Mechanical Characteristics
Mechanical Angle ................360 ° continuous
Running Torque ..................30.6 to 204 g-cm (0.42 to 2.83 oz.-in.)
Shaft Side Load (Static) ........2.04 kgf (4.5 lbs.) minimum
Weight ..........................3 gm (0.1 oz.) maximum
Terminals .......................Printed circuit board terminals
Terminals .......................Printed circuit board terminals
Soldering Condition
Wave Soldering...................Sn95.5/Ag2.8/Cu0.7 solder with no-clean flux: 260 °C max. for 3-5 seconds
Hand Soldering...................Not recommended
Hardware.........................Konb
Switch Characteristics
Switch Type .....................Contact Push ON Momentary SPST
Power Rating (Resistive Load) ...10 mA at 5 V DC
Switch Travel....................0.5 +0.4/-0.3 mm
Switch Actuation Force ..........360 +153/-102 gf (5 +2.1/-1.4 oz.-in.)


Igualmente me he topado con el blog de Ben Buxton, donde habla de los rotary encoders problematicas y soluciones... pero sinceramente no me entero demasiado...

Gracias a todos por las respuestas.
]inigohe

Para la primera cuestión que planteas, yo utilizaría un timer para controlar el número de pasos por segundo que estás generando con el encoder y si supera cierta "velocidad", aumentar el contador de 10 en 10, o de 100 en 100, en lugar de 1 en 1.

En cuanto al tema de disminuir al girar a la izquierda, ¿puedes poner el código y las librerías que utilizas en el post?

Saludos Jorge...

Ante todo gracias por contestar...

Te pongo el enlace publico dropbox donde tengo el .ino... en el aparecen las librerias empleadas y sus enlaces correspondientes...

https://dl.dropbox.com/u/58726056/sketch_sep06c/panel_inigo_02/panel_inigo_02.ino

Cuando te refieres a un timer, es a un ic??? o un modulo que cuente los ciclos de giro dentro del script???

He cargado el script de comprobacion de dos encoders que hay en el link de encoder.h y el resultado es el siguiente, con cada ciclo del encoder a derecha o izquierda sube 4 unds.

Es probable que el hecho de que sean 2-bit gray code sea el motivo por el cual ese funcionamiento digamos erroneo.

Luego estos funcionan bien y hay que modificar el script... digo yo!!!!

Un saludo.

inigohe

Buenas a todos...

He estado mirando en el blog Buxtronics... y he encontrado el siguiente script para el funcionamiento de encoders...

/* Rotary encoder handler for arduino.
 *
 * Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3.
 * Contact: bb@cactii.net
 *
 * Quick implementation of rotary encoder routine.
 *
 * More info: http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
 *
 */

// Half-step mode?
#define HALF_STEP
// Arduino pins the encoder is attached to. Attach the center to ground.
#define ROTARY_PIN1 5
#define ROTARY_PIN2 6
// define to enable weak pullups.
#define ENABLE_PULLUPS

#define DIR_CCW 0x10
#define DIR_CW 0x20

#ifdef HALF_STEP
// Use the half-step state table (emits a code at 00 and 11)
const unsigned char ttable[6][4] = {
  {0x3 , 0x2, 0x1,  0x0}, {0x23, 0x0, 0x1,  0x0},
  {0x13, 0x2, 0x0,  0x0}, {0x3 , 0x5, 0x4,  0x0},
  {0x3 , 0x3, 0x4, 0x10}, {0x3 , 0x5, 0x3, 0x20}
};
#else
// Use the full-step state table (emits a code at 00 only)
const unsigned char ttable[7][4] = {
  {0x0, 0x2, 0x4,  0x0}, {0x3, 0x0, 0x1, 0x10},
  {0x3, 0x2, 0x0,  0x0}, {0x3, 0x2, 0x1,  0x0},
  {0x6, 0x0, 0x4,  0x0}, {0x6, 0x5, 0x0, 0x10},
  {0x6, 0x5, 0x4,  0x0},
};
#endif
volatile unsigned char state = 0;

/* Call this once in setup(). */
void rotary_init() {
  pinMode(ROTARY_PIN1, INPUT);
  pinMode(ROTARY_PIN2, INPUT);
#ifdef ENABLE_PULLUPS
  digitalWrite(ROTARY_PIN1, HIGH);
  digitalWrite(ROTARY_PIN2, HIGH);
#endif
}

/* Read input pins and process for events. Call this either from a
 * loop or an interrupt (eg pin change or timer).
 *
 * Returns 0 on no event, otherwise 0x80 or 0x40 depending on the direction.
 */
unsigned char rotary_process() {
  unsigned char pinstate = (digitalRead(ROTARY_PIN2) << 1) | digitalRead(ROTARY_PIN1);
  state = ttable[state & 0xf][pinstate];
  return (state & 0x30);
}

void setup() {
  Serial.begin(9600);
  rotary_init();
}

void loop() {
  unsigned char result = rotary_process();
  if (result) {
    Serial.println(result == DIR_CCW ? "LEFT" : "RIGHT");   
  }

}

https://dl.dropbox.com/u/58726056/sketch_sep06c/rotary3.ino
https://dl.dropbox.com/u/58726056/sketch_sep06c/test%20encoders%20radio%20panel2.avi

Como veis tengo una empanada en este momento que no se que hacer para salir de esta situacion...

Inigohe

Buenas...

Tras estar rebuscando los numerosos scripts que hay circulando al respecto he encontrado este que se adapta a mis especiales encoders;)

#include <Bounce.h>

// This code increments or decrements a counter based on
// the status of a rotaty encoder

#define pin1 5
#define pin2 6
#define LED 13
int counter = 0;

// Instantiate a Bounce object with a 5 millisecond debounce time
// Only pin1 needs to be debounced. It is assumed that pin2
// will be stable when reading pin1
Bounce bouncer1 = Bounce( pin1,6 ); 

void setup() {
  pinMode(pin1,INPUT);
  pinMode(pin2,INPUT);
  pinMode(LED,OUTPUT);
  Serial.begin(9600);
}

void loop() {
 // Update the debouncer
  bouncer1.update ( );

 // Turn on or off the LED and
 // increment or decrement the counter
 if ( bouncer1.risingEdge()) {
   if (digitalRead(pin2)){
     digitalWrite(LED, HIGH );
     counter++;
     Serial.println(counter*10);
   }else{
     counter--;
     Serial.println(counter*10);
   }
 } else {
    digitalWrite(LED, LOW );
 }

}
A modo de prueba he modificado la asignacion de pines y el bounce lo he pasado a 6 milisegundos... y para hacer incrementos de 10 he multiplcado counter por ese digito...

El resultado...

Bueno, ahora a por el script principal a ver si consigo hacerlo sin meter mucho la pata.

Un saludo.

inigohe