Problema con delayMicroseconds() en Arduino0022

Tengo un programa que maneja un display.. Dentro de las rutinas se utiliza delayMilliseconds. Resulta que pasé de Arduino0018 a Arduino0022 y el programa ya no funciona bien.

Descubrí que delayMilliseconds parece no funcionar. No importa el valor que ponga el programa no funciona. Si lo reemplazo por delay(1) sí funciona así que el problema evidentemente está ahí. ¿Alguna idea de lo que ha pasado? ¿Es un bug?

Hola,

delay(1) significa una espera de un milisegundo, la instrucción delay(x) te entrega una pausa de '(x)' milisegundos.
delayMicroseconds(1) significa una espera de un microsegundo, delayMicroseconds(x) te entrega una pausa de '(x)' microsegundos.

http://arduino.cc/en/Reference/Delay

espero te sirva, saludos!

Alcafuz:
delay(1) significa una espera de un milisegundo, la instrucción delay(x) te entrega una pausa de '(x)' milisegundos.
delayMicroseconds(1) significa una espera de un microsegundo, delayMicroseconds(x) te entrega una pausa de '(x)' microsegundos.

Tal vez no me expresé bien. Se lo que hace delay y delayMicroseconds. Tengo un programa que funcionaba perfectamente. Cuando lo compilé con la version 0022 dejó de funcionar. Probé volver a 0018 y funcionó bien de nuevo. Investigando descubrí que el problema estaba en los retardos. Al parecer la funcion delayMicroseconds de la 0022 no funciona. Como prueba, cambié delaymicroseconds por delay sabiendo que hace retardos muchísimo más largos pero sólo para probar que el problema era esa funcion. Por más que aumente el número de microsegundos en delayMicrosecods el programa no funciona, lo cual me hace sospechar que directamente no hace ningún retardo o algo así.

OK, ahora te entiendo bien.

Pero tu sketch compila bien? y luego no funciona en la placa?

Solo habia escuchado de algunos problemas de compatibilidad de codigos hechos en versiones antiguas del software arduino, a mi no me ha ocurrido.

Quizás si pones tu código te puedo ayudar en algo.

Saludos.

Alcafuz:
OK, ahora te entiendo bien.

Pero tu sketch compila bien? y luego no funciona en la placa?

Solo habia escuchado de algunos problemas de compatibilidad de codigos hechos en versiones antiguas del software arduino, a mi no me ha ocurrido.

Quizás si pones tu código te puedo ayudar en algo.

Sí, el programa compila correctamente y funciona todo. Lo que pasa es que no hace los retardos correctamente y falla la comunicación con el display serie.

El programa que me da problemas es la biblioteca que maneja este display: http://www.yerobot.com/arduino-lcd-shield.html y el software se descarga de: http://www.yerobot.com/products/manual/LCD4Bit_mod.zip

En particular la parte donde falla es esta:

void lcdanv::pulseEnablePin(){
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// send a pulse to enable
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
digitalWrite(Enable,LOW);
delay(1); // pause 1 ms. TODO: what delay, if any, is necessary here?
}

Las instrucciones DelayMicroseconds no hacen lo que deben hacer. Intenté subir el tiempo y siguen sin hacer efecto. Si las reemplazo por un delay normal funciona, pero los tiempos son altísimos y el programa se vuelve muy lento.

mmmm por ahora lo unico que se me ocurre es que exista un problema con la libreria que maneja el LCD, creo que es antigua y no oficial, tal vez ya no es soportada...

aqui esta la oficial

ojala te sirva de algo, Saludos!.

Alcafuz:
mmmm por ahora lo unico que se me ocurre es que exista un problema con la libreria que maneja el LCD, creo que es antigua y no oficial, tal vez ya no es soportada...

aqui esta la oficial
LiquidCrystal - Arduino Reference

Sí, es obvio que el problema es en la librería. Pero dado que antes compilaba y funcionaba bien y ahora no, con seguiridad es un cambio que han hecho y tiene olor a bug. La librería oficial no me sirve porque este hardware es un poco diferente. Pero miraré el código fuente de la librería oficial a ver si me da ideas. De todos modos insisto en que si antes funcionaba ahora debería seguir funcionando.

He estado haciendo pruebas sobre delayMicroseconds y realmente no veo diferencia en su comportamiento. De hecho he mirado el código fuente y es exactamente el mismo, así que el problema deberá estar en otro lado...

Aparentemente, delayMicroseconds() es util hasta delayMicroseconds(16383), si necesitas usar mas de ese parametro tienes que usar la funcion delay(millisecs).

Espero esta informacion sea util.

Staedtler:
Aparentemente, delayMicroseconds() es util hasta delayMicroseconds(16383), si necesitas usar mas de ese parametro tienes que usar la funcion delay(millisecs).

Espero esta informacion sea util.

Es bueno saber.o pero en este caso decía delayMicroseconds(1) así que no es ese el problema. Tendré que investigar un poco más. Lo que me molesta es que algo que estaba funcinando deje de funcionar.

Si te sirve de consuelo, yo tengo programas hechos con delay y millis que en Arduino0018 funcionan perfectamente y a partir de la 0019 ya no, tienen errores en los tiempos, directamente cuando compilo estos programas lo hago con la 0018 y fuera.

DRicote:
Si te sirve de consuelo, yo tengo programas hechos con delay y millis que en Arduino0018 funcionan perfectamente y a partir de la 0019 ya no, tienen errores en los tiempos, directamente cuando compilo estos programas lo hago con la 0018 y fuera.

Pues más que consuelo me parece preocupante. Has rastreado qué parte del programa tiene el problema? Son los delays o es otra cosa? Yo estuve haciendo un programa sencillo para probar el delayMicroseconds y parecía funcionar. Al menos obtenía el millis() antes y después de un retardo y los números cuadraban tanto en 0018 como en 0022.

Qué dicen los desarrolladores al respecto? Supongo que estará reportado, pero no he encontrado el hilo donde se discute el asunto.

anv:
Qué dicen los desarrolladores al respecto? Supongo que estará reportado, pero no he encontrado el hilo donde se discute el asunto.

Las funciones si han cambiado. Sobre todo con respecto a interrupts, y muchas funciones referente a tiempos.

Mi pregunta seria saber que es lo que quieres controlar con ese codigo. Motores?

Staedtler:

anv:
Qué dicen los desarrolladores al respecto? Supongo que estará reportado, pero no he encontrado el hilo donde se discute el asunto.

Las funciones si han cambiado. Sobre todo con respecto a interrupts, y muchas funciones referente a tiempos.

Mi pregunta seria saber que es lo que quieres controlar con ese codigo. Motores?

No. Como dije más arriba, tengo un display de estos: http://www.yerobot.com/arduino-lcd-shield.html

El display no es exactamente igual al que está soportado por la biblioteca que viene en Arduino. Este utiliza sólo 4 bits para comunicarse dejando muchas más patitas libres así que tiene una version modificada de la biblioteca que lo maneja: http://www.yerobot.com/products/manual/LCD4Bit_mod.zip

Según entiendo, es una versión modificada de este: Arduino Playground - LCD4BitLibrary que usa otras patitas diferentes. Las he estado comparando y en lo referente al acceso al display sólo difieren en las patitas, lo cual me hace pensar que el código que hay en el playground tampoco funciona.

Funciona perfectamente con 0018 pero con 0021 a veces no sale nada en la pantalla y otras veces sale algo de basura. Parecía un problema con los tiempos y aumentando muchísimo algunos tiempos se soluciona.

Tal vez el problema es que ahora los programas corren mucho más rápido y necesita retardos donde antes no los había. Tengo que revisar bien el código.

Es que el codigo que has puesto no se parece nada a LCD.
No tengo idea de que se trata esa rutina, y porque necesitas "delayMicroseconds()" . Si puedes poner todo el codigo aca va a ser simple entender el contexto.

Yo tengo ese LCD-Keypad Shield y lo uso bastante.

Prueba si esto te funciona:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

//Key message
char msgs[5][15] = {"Right Key OK ", 
                    "Up Key OK    ", 
                    "Down Key OK  ", 
                    "Left Key OK  ", 
                    "Select Key OK" };
int  adc_key_val[5] ={30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;

void setup() { 
  pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat

  lcd.clear();
  lcd.begin(16,2);
  lcd.print("KEYPAD test   ... pressing");

}

void loop() {

	adc_key_in = analogRead(0);    // read the value from the sensor  
  digitalWrite(13, HIGH);  
  key = get_key(adc_key_in);		        // convert into key press
	
	if (key != oldkey)				    // if keypress is detected
	{
    delay(50);		// wait for debounce time
		adc_key_in = analogRead(0);    // read the value from the sensor  
    key = get_key(adc_key_in);		        // convert into key press
    if (key != oldkey)				
    {			
      oldkey = key;
      if (key >=0){
      lcd.setCursor(0, 0);  //line=2, x=0
  			lcd.print(msgs[key]);
      }
    }
  }
  

  digitalWrite(13, LOW);
  

 
  
  
}

// Convert ADC value to key number
int get_key(unsigned int input)
{
	int k;
    
	for (k = 0; k < NUM_KEYS; k++)
	{
		if (input < adc_key_val[k])
		{
           
    return k;
        }
	}
    
    if (k >= NUM_KEYS)
        k = -1;     // No valid key pressed
    
    return k;
}

... pero la verdad que si quieres buena ayuda, tienes que poner todo el codigo aqui para que veamos cual es el problema.
Todavia no entiendo porque necesitas usar "delayMicroseconds()" solo para un LCD.

Staedtler:
Es que el codigo que has puesto no se parece nada a LCD.
No tengo idea de que se trata esa rutina, y porque necesitas "delayMicroseconds()" . Si puedes poner todo el codigo aca va a ser simple entender el contexto.

Es que yo no sabía que LiquidCrystal ahora maneja también 4 bits. Estaba usando la que indican en la pagina para este display, que es derivada de esta: Arduino Playground - LCD4BitLibrary Si miras, verás que el autor ha agregado ahora un aviso de que no se use esta biblioteca. Es fue porque le escribí avisándole que con las versiones nuevas de Arduino no funcionaba.

Staedtler:
Yo tengo ese LCD-Keypad Shield y lo uso bastante.

Prueba si esto te funciona:

Muchas gracias. Y ya que tienes un lcd-keypad te paso por si te sirve, mi biblioteca para manejar el teclado. Tiene autorepetición de teclas y evita rebotes de contactos.

Deberías ponerlo en donde tengas las bibliotecas de Arduino y el uso es así:

#include <keyb.h>

void loop(){

int k=KEYB.getkey(1);

if (k==KEY_SELECT) ...

El parametro de la funcion KEYB.getkey indica si va a permitir repetición (manteniendo la tecla presionada) o no.

keyb.zip (3.04 KB)

Voy a probar esa libreria, gracias.
Tienes una pagina donde den ejemplos de como implemantar esa libreria?

Entonces ya esta resuelto el problema de delayMicroseconds() ?

Staedtler:
Voy a probar esa libreria, gracias.
Tienes una pagina donde den ejemplos de como implemantar esa libreria?

Sí, puedes descargar la última versión y un ejemplo aquí:

Staedtler:
Entonces ya esta resuelto el problema de delayMicroseconds() ?

Pues... sencillamente cambié de biblioteca. Todavía quisiera saber por qué dejó de funcionar la otra.