CRONOGRAFO

Hola a tod@s y Feliz 2012!!!

Es mi primer post desde que empece con arduino, hasta ahora no habia tenido necesidad de abrir ninguno ya que mis proyectos eran de bajo nivel y todas mis dudas se resolvieron leyendo otros post pero he llegado a un punto que no encuentro nada relacionado con mi problema o no lo he sabido buscar.

Os comento:

Mi intencion es desarrollar un cronografo(para medir velocidad de una pistola de paintball)este medidor me tiene que dar lecturas de hasta 100m/s >>>300FPS.

Por el momento he desarrollado un codigo muy basico, 2 entradas digitales conectadas a 2 barreras laser que detectan el paso del proyectil(en este caso bola de pintura)al detectar el primer sensor asigno a una valiable el valor de Milis, al detectar el paso por el segundo sensor asigno a otra valiable el valor de Milis,hago la diferencia entre ellos con lo que obtengo el valor del tiempo total entre los 2 sensores, el problema me viene que el valor mas bajo de tiempo que puedo obtener es de 7milis y con la distancia que tengo actualmente entre los sensores 200mm me da una velocidad maxima de 30m/s.

Alguien tiene alguna idea de como disminuir el tiempo de procesamiento entre las 2 señales para evitar tener que ampliar la distancia entre sensores¿?

Un saludo y muchas gracias a tod@s

Hola,

¿Estás usando interrupciones?

Saludos!

Igor R.

Hice un primer codigo sin interrupciones que me daba un tiempo minimo entre sensores de 20milis, luego con el uso de una interrupcion baje este tiempo a 7Milis pero lo tengo que bajar aun hasta 2milis...Esta tarde subo el codigo que tengo cargado actualmente

Un saludo, gracias

7 milis me parece bastante tiempo, tienes el codigo y conexionado?

+1 algo raro hay.....

Pon el código, 2 ms son 500 Hz, que los mides sin problemas....

bueno aqui dejo el codigo

#include <LiquidCrystal.h>

long time1=0;  //Variable de tiempo para el inicio.
long time2=0;  //Variable de tiempo para el final.
LiquidCrystal lcd(12, 11, 5, 4, 13, 10);
float distancia=200;//valor distancia entre sensores en mm
int c1=2;//pin celula1
int c2=3;//pin celula2
int led1=8;//led celula 1 encendido si no detecta
int led2=9;//led celula 2 encendido si no detecta

float velocidad=0.0000;//velocidad en mm/ms-->m/s
float tiempo=0;
float FPS=0;
boolean f1=true;

void setup() {
  pinMode(c1,INPUT);
  pinMode(c2,INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  Serial.begin(9600);
  //attachInterrupt(0, ss1, FALLING);
  attachInterrupt(1, ss2, FALLING);
  lcd.begin(16, 2);
  lcd.print("---Cronografo---");
  lcd.setCursor(0, 1);
  lcd.print("------PIRO------");
}

void loop() {
  if (digitalRead(c1)==LOW && f1==true){
    time1 = millis();  //comprueba el tiempo al activar c1
    f1=false;
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
  }
}

void ss2() {
  Serial.println("celula 2");
      time2 = millis();  //comprueba el tiempo al activar c2
      tiempo=time2-time1;
      digitalWrite(led1, LOW);
      digitalWrite(led2, HIGH);
      velocidad=distancia/tiempo;
      FPS=velocidad/0.304;     
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("VELOCIDAD en FPS");
      lcd.setCursor(0, 1);
      lcd.print(velocidad);
      f1=true;

}

Hola,

De vistazo rápido:

  • Las variables que se modifican dentro de una interrupción tienen que estar declaradas como volatile (volatile (computer programming) - Wikipedia).
  • Las rutinas que se ejecutan dentro, tienes que intentar que sean lo más pequeñas posibles.
  • Podrías usar las dos entradas de interrupción que tiene Arduino (tiene pinta que lo intentaste asi por la linea comentada). Lo digo, porque digitalRead es lento.
  • Si esperas tiempos pequeños, puedes usar micros() para tener más precisión.
  • Yo cambiaría que velocidad=(float)distancia/(float)tiempo;
  • El Serial.println("celula 2"); antes de recoger el tiempo, te está metiendo mucho retraso, ya que se queda esperando hasta que termina de mandar dicha cadena a 9600 bps (8 +2 (CR+LF) bytes a 960 bytes/s). Sólo esa linea antes de recoger tiempo, te mete un error considerable....

Saludos

Igor R.

Muchas gracias,lo probare el proximo finde ya que lo tengo en el pueblo.Ya os contare

Djpiro a ver si me puedes hacer el favor de resubir el codigo con las modificaciones, y si has terminado el crono decir si esta bien o no.

gracias y saludos

Desenvolví e utilizo este código, este cronógrafo faz apresenta a cadencia dos disparos en BPM

#include <Adafruit_ST7735.h> // Hardware-specific library
#include <FreqCount.h>
#include <SPI.h>
#define TFT_CS     9
#define TFT_RST    7
#define TFT_DC     8
#define MPS2FPSCOEFF 3.28084
#define LENGTH 0.10
#define MICRO2SEKCOEFF 1000000
#define MASSA68T 0.0043
#define MASSA68C 0.0032
#define MASSA43T 0.0010
unsigned long startTime, stopTime, elapsed;
double fpsSpeed, mpsSpeed, E68t, E68c, E43t, bpsSpeed;
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

void front()
{
startTime = micros();
}

void rear()
{
stopTime = micros();
elapsed = stopTime - startTime;
  mpsSpeed = (LENGTH*MICRO2SEKCOEFF)/elapsed;
  fpsSpeed = mpsSpeed * MPS2FPSCOEFF;
  E68t = (pow(mpsSpeed, 2) * MASSA68T) / 2;
  E68c = (pow(mpsSpeed, 2) * MASSA68C) / 2;
  E43t = (pow(mpsSpeed, 2) * MASSA43T) / 2;
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(0, 15);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(1);
  tft.print("FPS: ");
  tft.setCursor(0, 30);
  tft.print("(J).68C:");
  tft.setCursor(0, 45);
  tft.print("(J).68T:");
  tft.setCursor(0, 60);
  tft.print("(J).43T:");
  tft.setCursor(60, 15);
  tft.print(fpsSpeed);
  tft.setCursor(60, 30);
  tft.print(E68c);
  tft.setCursor(60, 45);
  tft.print(E68t);
  tft.setCursor(60, 60);
  tft.print(E43t);
  delay(3000);
}


void setup()
{
attachInterrupt(0, front, RISING);
attachInterrupt(1, rear, RISING);
pinMode(4, INPUT);
pinMode(5, INPUT);
tft.initR(INITR_144GREENTAB);
tft.setTextWrap(false);
tft.fillScreen(ST7735_BLACK);
tft.setRotation(3);
tft.fillScreen(ST7735_BLACK);
tft.setTextColor(ST7735_WHITE);
tft.setCursor(20, 10);
tft.setTextWrap(false);
tft.println("Inicializando");
tft.setCursor(5, 25);
tft.setTextColor(ST7735_YELLOW);
tft.setTextSize(2);
tft.println("Cronografo");
delay(3000);
tft.setTextSize(2);
tft.setTextColor(ST7735_GREEN);
tft.setCursor(30, 60);
tft.println("PRONTO");
FreqCount.begin(1000);
delay(3500);
elapsed = 0;
fpsSpeed, bpsSpeed, mpsSpeed = 0;
}

void loop()
{
if(digitalRead(4) == HIGH) {
if (FreqCount.available()) {
  bpsSpeed = FreqCount.read();
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(0, 55);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(3);
  tft.println("BPS: ");
  tft.setCursor(70, 55);
  tft.print(bpsSpeed);   
}
}
  
}

Porque respondes un hilo que desde 13-02-2013, 19:33:53 no tiene movimientos?
Y ademas no usas etiquetas para el codigo.
Lee las normas del foro y no vuelvas a hacerlo.
Hilo cerrado