Alternativas a digitalRead()

Hola, quisiera saber cuales son las alternativas a digitalRead()? He visto que dicen que es muy lento para cálculos rápidos. Pues prácticamente estoy haciendo alrededor de 1 000 000 de cálculos por minuto.
Por cierto estoy usando Teensy 3.5, gracias por sus respuestas.

La alternativa es trabajar a nivel Byte con las instrucciones del microprocesador, como por ejemplo DDRB y PORTB, y hacer cálculos también a nivel Byte. Esto te da un código mas rápido al utilizar menos ciclos de reloj.

1 Like

Teensy tiene otras 2 funciones, digitalReadFast() y digitalWriteFast() que puede utilizar para obtener el rendimiento más rápido posible

1 Like

Sabes en donde puedo ver un ejemplo practico de eso, la verdad eso nunca lo he utilizado. Gracias

como con digitalRead () o digitalWrite ()

tienes la velocidad más alta si el número de pin es una constante (#define, constexpr)

Aca puedes ver un tutorial , pero hay muchos en Internet, busca las palabras claves Arduino Port.

Teensy 3.5 está usando un ARM Cortex-M4 @ 120 MHz… Los tutoriales de AVR PORT no ayudarán

No estoy 100% seguro, pero creo que el tratamiento es el mismo.

es más complejo de configurar

1 Like

Este es el codigo que estoy usando, es un encoder de 1000 ppr y a velocidades de 150 metros por minutos funciona bien pero cuando le subo la velocidad este deja de contar o se reinicia, entonces no se cual es el problema. Se supone que teensy es un microcontrolador muy rápido para hacer cálculos.

#include <LiquidCrystal_I2C.h>
#include<Wire.h>

#define CHA 25
#define CHB 28
#define BTN 24

volatile long int ticks = 0;
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int LEDR = 33;
const int LEDA = 34;
void setup() {

Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.setCursor(2, 1);
lcd.print("BIENVENIDOS");
delay(2500);
pinMode(CHA, INPUT_PULLUP);
pinMode(CHB, INPUT_PULLUP);
pinMode(BTN, INPUT);
attachInterrupt(digitalPinToInterrupt(CHA), conteo, CHANGE);
attachInterrupt(digitalPinToInterrupt(BTN), imprimir, RISING);

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Metros Contados: "); // Mensaje a despegar

lcd.setCursor(0, 1);
lcd.print(" m");
pinMode(LEDR, OUTPUT);
pinMode(LEDA, OUTPUT);

}
void imprimir() {
if (ticks != 0) {

Serial.println((ticks * 0.02) / 100);
ticks = 0;

}
}
void conteo() {

if (digitalRead(CHA) == HIGH) {
if (digitalRead(CHB) == LOW) {
ticks++;
} else {
ticks--;
}
} else {
if (digitalRead(CHB) == LOW) {
ticks--;
} else {
ticks++;
}
}

}

void loop() {
if (ticks < 0) {
ticks = 0;

}

lcd.setCursor(1, 1);
lcd.print((ticks * 0.02) / 100);

if (ticks >= 1) { //Encendido de leds
digitalWrite(LEDA, HIGH);
digitalWrite(LEDR, LOW);

} else {
digitalWrite(LEDA, LOW);
digitalWrite(LEDR, HIGH);

}
if (ticks == 0) {
lcd.setCursor(1, 1);
lcd.print(ticks);
lcd.print("    ");
lcd.setCursor(12, 1);
lcd.print("STOP");
} else {
lcd.setCursor(12, 1);
lcd.print("RUN ");
}

}

attachInterrupt(digitalPinToInterrupt(BTN), imprimir, RISING);
Esto no tiene sentido. dentro de una interrupcion no puedes utilizar un serial.print (no se como te funciona algo) .

Pensaba exactamente lo mismo.

en el loop() debe trabajar en una copia de tick (copia realizada en una sección crítica)

más simple y más eficiente: Usa la encoder library

Todo el problema es el que menciona @J-M-L, un enconder a alta velocidad debe manejarse por interrupciones. La librería lo hace con mucha facilidad. No te compliques.
Investiga siempre que opciones hay para cada cosa y no te quedes con la primera que encuentres.
Si algo debe ser rápido, se usa interrupciones pero dentro de una interrupción no se puede invocar cosas lentas. Como bien dice @PeterKantTropus un Serial.print en una interrupción es un despropósito en si mismo.
Me corrijo, @PeterKantTropus hace mención al inconveniente yo digo que es un despropósito en si mismo.

cual podria ser una solucion para ese serialprint? ya que ese esta ahi porque yo solo quiere que me muestre el valor solo cuando presione el boton, no me interesa ver el conteo en tiempo real, solo cuando yo presione el boton, gracias por sus respuestas

La solución siempre ha sido la misma. Cuando se da cierta condición levantas un flag o sea una variable bool byte o int lo que gustes. Le pones 1 o 0 y en tu loop fuera de las interrupciones cuando esta en determinado valor imprimes sabiendo que se ha dado la condicion para hacerlo, y luego de imprimir le cambias el valor para que de nuevo la rutina de interrupciones cuando se de nuevamente la condición la vuelva a levantar.
Nada complicado.

Un botón activado por el usuario realmente no necesita ser interrumpido...