digital Velocidad de muestreo de lectura para Arduino Uno

1

Estoy intentando enviar un carácter a través del puerto serie cuando presiono un botón externo, el botón está conectado al pin IO digital 3, usé el código del ejemplo de SerialCallResponse y reemplacé el "sensor" que estaba haciendo. en el bucle principal con lo siguiente:

void loop()
{
 // if we get a valid byte, read button in:
  if (Serial.available() > 0) {
   // read the state of the pushbutton value:
   buttonState = digitalRead(3);  
   if (buttonState == HIGH) {     
     // print B on serial port:    
      Serial.print('B', BYTE);   // send a T
    } 
  }
}

Sin embargo, recibí varias B enviadas, así que intenté poner un bucle while en la sección if buttonState == HIGH para esperar hasta que aparezca buttonState == LOW; sin embargo, si presiono el botón, luego lo suelto y luego lo presiono nuevamente, no La respuesta no fue tan rápida como hubiera esperado, parecía ser una respuesta de un segundo a un segundo y medio (aunque no está cronometrada con precisión).

¿Debe transcurrir una cierta cantidad de tiempo entre la lectura digital donde cambiará a otro valor? ¿Existe una forma de "rebote" interno de una señal en el IO digital?

Este es mi primer Arduino y lo obtuve hace dos días, ya está mucho más avanzado en mi proyecto y luego pude obtener mi foto debido a la placa de desarrollo completa, afortunadamente.

EDITAR: Así que estuve navegando en los tutoriales de adafruits antes, intentando averiguar si ella menciona algo sobre lo que estoy viendo. Probé este código como una prueba adicional:

int switchPin = 3;              // Switch connected to digital pin 2

void setup()                    // run once, when the sketch starts
{
  Serial.begin(115200);           // set up Serial library at 9600 bps
  pinMode(switchPin, INPUT);    // sets the digital pin as input to read     switch
}


void loop()                     // run over and over again
{
  Serial.print("Read switch input: ");
  Serial.println(digitalRead(switchPin));    // Read the pin and display the value
  delay(300);
}

Presiono el botón, luego de haberlo soltado, aproximadamente 15 1 aparecían inmóviles, lo que me dice que incluso si llamo digitalRead, en realidad solo está leyendo un búfer (o algo así) que muestrea el puerto IO digital en algunos Califique, ¿se espera esto, alguna idea donde pueda averiguar dónde está este número? ¿De dónde vino (como en por qué ese número)?

¿Tendría más sentido usar una interrupción? De esta manera, solo se le "notificará" cuando ocurra un nuevo evento.

EDIT # 2: Así que decidí probar las interrupciones, cambié mi código a lo siguiente:

int switchPin = 3;              // Switch connected to digital pin 2

void setup()                    // run once, when the sketch starts
{
  Serial.begin(115200);           // set up Serial library at 9600 bps
  pinMode(switchPin, INPUT);    // sets the digital pin as input to read switch
  attachInterrupt(1,handle_button,FALLING);
}

void loop()                     // run over and over again
{
}

void handle_button()
{
  Serial.print("Read switch input: ");
  Serial.println(digitalRead(switchPin));    // Read the pin and display the value
}

Este cambio ahora solo muestra cualquier cosa en el puerto serie cuando se activa una interrupción. Presioné el botón y obtuve "Leer la entrada del interruptor: 1", sin embargo, si presiono el botón en cualquier momento antes de que transcurran 30 segundos (un conteo aproximado de 30, es decir), no parece que se active la interrupción. Espero un conteo de 30 y recibo el mensaje "Leer entrada de interruptor: 1". Nuevamente, esto continúa diciéndome que el IO digital no se ha sondeado a una velocidad muy rápida, esto me parece sorprendente, me he metido con fotos en el pasado y no he notado este problema, y este es mi primer programa "real" con el Arduino, me pregunto si hay algo que deba configurar tal vez?

El problema sigue siendo y es que me pregunto a qué velocidad se aplica el arduino uno (y, más exactamente, el atmel atmega 328P) a los puertos de E / S digitales.

EDITAR # 3 Para ser más específico, es aproximadamente 12 segundos (usó un temporizador en línea y lo vigilé). Si presiono por segunda vez en 11 segundos, no se activa y todavía tengo que esperar otros 12 segundos desde la segunda pulsación.

    
pregunta onaclov2000

2 respuestas

3

En este momento tienes dos problemas que están separados uno del otro.

1) Botón de rebote

2) Cableado incorrecto del botón

Primero, debe introducir una demora en su función de interrupción para que no siga registrando cada subida y bajada del rebote como una presión de botón separada. Use "delayMicroseconds ()" porque aparentemente no puede usar "delay ()" dentro de las interrupciones. Id sugiero un retraso de 20,000 microsegundos.

En segundo lugar, debe colocar una resistencia desplegable en el pin digital que está muestreando.

El problema que tiene es que el pin está en modo de entrada y, por lo tanto, en alta impedancia (muy alta resistencia) y por lo tanto tiene una tenencia para "flotar". Si le pones una tensión, se carga como un condensador y, como el propio pin tiene una resistencia a tierra muy alta, la carga se disipará hasta el punto en que el Arduino volverá a registrar un nivel BAJO. Una resistencia de 10 k desde el pin al suelo obligará a que el "condensador" se descargue rápidamente después de que la corriente del botón haya dejado de fluir.

Finalmente, el Arduino es bastante rápido en sus operaciones de lectura / escritura (soy ingeniero mecánico, TODOS los componentes electrónicos ocurren "rápidamente" en comparación con los sistemas mecánicos, por lo que supongo que es relativo). Aquí hay un enlace a algunos resultados de las pruebas.

TL; DR verson:

What these values tell me, is that we can do about:

10 analog 10-bit readings per millisecond with analogRead()
128 pwm settings per millisecond with analogWrite()
220 pin reads per millisecond with digitalRead()
224 pin writes per millisecond with digitalWrite()
1056 pin reads per millisecond with direct port reads
1059 pin writes per millisecond with direct port writes
    
respondido por el Faken
1

La razón por la que obtienes múltiples B's es porque la función "loop" se llama en un bucle sin fin.

while (true) {
    loop();
}

Quizás ayude a ver su función de esta manera:

while (true) {
    if (Serial.available() > 0) {
        buttonState = digitalRead(3);  
        if (buttonState == HIGH) {     
            Serial.print('B', BYTE);   // send a T
        } 
    }
}

Tan pronto como esté disponible la entrada en serie, lea el estado del botón y envíe una 'B' en caso de que se presione el botón. La entrada en serie nunca se consume, porque Serial.read () nunca se llama, por lo que en la próxima pasada a través de su función de bucle, sucede lo mismo.

Si todo lo que desea es enviar una 'B' cuando se presiona el botón, esto podría hacer:

int buttonState = LOW;
int button0, button1;

void setup()
{
    Serial.begin(9600);
    pinMode(3, INPUT);
}

void loop()
{
    button0 = digitalRead(3);
    delay(10);
    button1 = digitalRead(3); // de-bounce

    if (button0 == button1) {
        if (button0 != buttonState) {
            buttonState = button0;
            if (buttonState == HIGH) {     
            Serial.println("B");
            } 
        }
    }
}

A continuación hay un enlace a un tutorial bastante completo para tratar con los botones. También explica el retraso de 10 ms para que el botón se estabilice.

enlace

    
respondido por el ubiyubix

Lea otras preguntas en las etiquetas