CRONOGRAFO BALISTICO

...e sono di nuovo qui. Devo riuscire a fare anche sto "coso"...

Vorrei utilizzare questi

oppure farlo con due testine laser (link) e cercare di realizzare una barriera zigzag con gli specchi

https://www.ebay.it/itm/A75-LASER-650nm-5mW-6MM-PUNTATORE-ROSSO-ARDUINO-3V-diodo/232728144012?hash=item362fada88c:g:4AwAAOSwdPtay35F

guarda QUI che bello già pronto e fatto :smiley:

scherzo ovviamente, seguo con interesse perchè l'argomento mi interessa.
anch'io ho una 977 ma quelle sopra i 7.5J :slight_smile:

vince59:
...
oppure farlo con due testine laser (link) e cercare di realizzare una barriera zigzag con gli specchi
...

Se parli di quello da fissare sulla canna, la barriera a zig-zag non serve, basta usare dei normali fotodiodi e mettere sia il led che il fotodiodo in cavita' che si affacciano verso l'interno tramite dei forellini da 2.5 / 3 mm allineati con l'asse della canna ... il pallino interrompera' per forza i raggi, in quelle condizioni, perche' sono vincolati alla canna e piu stretti del pallino stesso ... :wink:

@ gianlucaf ...che gusto c'è a comprarlo già fatto? La 977 è bellissima ....sono tentato di fare un upgrade :smiling_imp: :smiling_imp: :smiling_imp: :smiling_imp: :smiling_imp:

@ etemenanki. Dunque sto smanettando ora con diodi IR e relativi ricevitori TSOP 34838 ma mi sembrano lenti nelle risposta. Ho fatto delle prove moooolto elementari sulla basetta millefori ma mi sembra che l'interruzione del fascio IR da parte di un oggetto molto piccolo e molto veloce non venga rilevata.
Ho ordinato nel frattempo laser e riceventi. Concordo che a questo punto ne bastano due messi in un tubo allineato longitudinalmenmte con la canna. Il piombino di sicuro interromperà il fascio.
Leggendo i tuoi post ho compreso che la risposta del ricevitore deve essere molto veloce - sto studiando - ma non mi è chiaro se il TSOP 34838 essendo un diodo PIN anche se a IR possa andare bene come caratteristiche.
In attesa di ricevere il materiale voglio provare a mettera a punto il codice e provare con gli IR.
Consigli ben accetti.

Ehm, no, la serie TSOP sono moduli ricevitori, non hanno nulla a che fare con i diodi pin (hanno piu o meno la stessa proporzione di velocita' che c'e' fra una lamborghini ed una ford "model A" :D)

Ora sto uscendo, oggi te ne cerco qualcuno sui datasheet, di diodi PIN o fotodiodi veloci "veri" :wink:

Guglielmo, aiutami sennò spacco il PC co na capocciata!!!!

Sono due giorni che sbatto la capoccia co sti caxxo di interrupt ma non riesco proprio a capire come lavorarci per creare il codice. Potresti, come hai già fatto per i millis, guidarmi un pò per come impostare il codice e soprattutto com egestire gli interrupts?

BPV10NF ... TEFD4300F ... SFH229FA ... QSD2030F ... I piu comuni che mi sono capitati a tiro, non SMD, dovrebbero essere tutti sotto l'euro l'uno ... questi sono PIN, quindi veloci, tempi di risposta medi 10nS ... SFH229FA e TEFD4300F sono da 3mm di diametro, quindi anche poco ingombranti ...

I TSOP essendo ricevitori per telecomandi, contengono anche l'AGC e l'elettronica di decodifica a volte, e sono progettati per frequenza di modulazione di 38KHz ... il loro diodo viaggia a microsecondi, a volte anche millisecondi , non si possono usare come normali diodi per applicazioni veloci ... ovviamente per leggere i normali fotodiodi devi fargli un minimo di circuito, ma e' una cosa piuttosto semplice da fare ...

Grazie Etemenanki,
prima o poi li trovo ora sono fuori roma con difficoltà logistiche.
Sto cominciando a ragionare sul codice ma non mi entrano in testa questi interrupts. Hoscaricato qualche esempio e sto provando a studiare.
Vorrei abbozzare l'ahardware ed il codice.
Per l'HW non ho problemi mi sembra di capire che:

  • i diodi IR vadano semplicemente alimetati mediante resistenza (già sto smanettando con gli IR ed i TSOP);
  • i diodi PIN (in packag T1) come andranno cablati?..immagino sui pin D2 e D3 visto che sono gli unici che lavorano con gli interrupt. Giusto? ...se si con quale polarizzazione?
    Per il codice cerco di arrivarci da solo...

Diodi IR: resistenza in serie, se usi i 5V di arduino, 680 ohm dovrebbero essere sufficenti (sono vicini ai fotodiodi e non devono servire come illuminatori, quindi dargli pochi mA dovrebbe bastare, al massimo si abbassano le resistenze a 470 ohm se si vede che non basta la corrente)

Fotodiodi: di solito si usano gli operazionali, ma anche un semplice paio di transistor BC337 dovrebbe bastare per un'applicazione simile ... tecnicamente, sarebbe possibile anche farne a meno ed usare un semplice paio di resistenze da 22K o valori simili, collegandoli polarizzati inversamente (catodi dei diodi al +5V, anodi ai pin di arduino, resistenze fra i pin e massa come pull-down e per polarizare inversamente il diodo), dato che gli ingressi di arduino sono ad alta impedenza, quindi anche l'uscita diretta del fotodiodo in teoria dovrebbe bastare a fargli cambiare stato ... e' comunque da provare, se non basta, si mettono anche i transistor ...

Nel fare i test, occhio che gli IR presenti nell'ambiente possono falsarti facilmente le letture ... usa dei tubetti di cartoncino o metallo (non plastica, a meno che tu non sia sicuro che e' opaca agli IR, perche' molte plastiche che alla luce visibile risultano nere o comunque opache, sono trasparenti o lasciano passare quasi tutta la banda IR) per schermare completamente i fotodiodi, anche dietro (senza mandarli in corto se usi il metallo) ... per lo stesso motivo, poi, il tubo finale andrebbe costruito in metallo, alluminio, ottone, quello che trovi piu facile da lavorare, e non in plastica, sempre se non hai plastica che sei sicuro sia completamente opaca agli IR ...

vince59:
Guglielmo, aiutami sennò spacco il PC co na capocciata!!!!

... prova a studiare QUI :wink:

Guglielmo

...dunque utilizzando il codice che segue ho fatto dei test cablando come segue:

  • TSOP34838: gnd, +v5, out ai pin 2(int 0) per il sensore front e pin 3(int 1) per il sensore posteriore;
  • diodo IR emettitore tramite R 100ohm al +v5 e gnd;
    Le barriere sono posizionate a 6 cm di distanza giusto per vedere se legge. Interrompendo il flusso n direzione ant-->post il monitor seriale visualizza dei lavori ma, ritengo pe ril cablaggio su millefori, le letture ogni tanto non avvengono.
    Ora passo al codice. L'ho trovato in rete e studiato. Non mi è del tutto chiaro però. L'architettura l'ho capita ni senso generale peroò non capisco quei led1 e led2 sui pin 12 e 13.
    Che ne pensate?
    Ovviamente il codice dovrà essere utilizzato con i componenti che devo ancora reperire laser e ricevitore laser e/o IR e fotodiodi PIN
/*
Fotodiodi o fototransistor sono nominati come attachInterrupt (0, front, CHANGE) collegato
con il pin digitale 2, e, attachInterrupt (1, posteriore, CHANGE) collegato al pin digitale 3
Coloro che vogliono provarlo possono collegare due pulsanti ai pin 2 e 3
I fotodiodi devono avere una resistenza tra 10k e 100kohm collegati al collettore (pin o gamba lunga) e questo al pin digitale
per assicurarsi che quando il raggio di luce viene interrotto, la tensione raggiunga 0 o massa
*/

// #include <LiquidCrystal.h>
 
#define MPS2FPSCOEFF 3.28084
#define LENGTH 0.159             
#define MICRO2SEKCOEFF 1000000

//LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

volatile int stateFront = HIGH;
volatile int stateRear = HIGH;

int led1 = 12;                             
int led2 = 13;                             
int startChrono;
unsigned long startTime, stopTime, elapsed;
double fpsSpeed, mpsSpeed; 
 
void setup()
{
  Serial.begin(9600);
  //lcd.begin(16, 2);
  //lcd.setCursor(0, 0);
  //lcd.print("Super Chrono");
  Serial.print("Cronografo");
  //lcd.setCursor(0, 1);
  //lcd.print("by nv");
  delay(700);
  //lcd.clear();
  //lcd.setCursor(0, 0);
  //lcd.print("Initializing...");
  Serial.println("Inizializando");
  delay(700);
 // lcd.clear();
 
  startChrono = 0;
  elapsed = 0;
  fpsSpeed = mpsSpeed = 0;
 
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  /*
  Se tutto ok non cambiare nulla. Diversamente provare a cambiare CHANGE in RISING o LOW in 
  attachInterrupt(0, front, "      ") ed in attachInterrup(1, rear, "     ");
  */
  attachInterrupt(0, front, CHANGE); //0 (on digital pin 2) kanske falling/rising/low
  attachInterrupt(1, rear, CHANGE);  //1 (on digital pin 3)
//  attachInterrupt(0, front, RISING); //0 (on digital pin 2) kanske falling/rising/low
//  attachInterrupt(1, rear, RISING);  //1 (on digital pin 3)
  //lcd.setCursor(0, 0);
  //lcd.print("Take a shot!");
  Serial.println("Pronto per sparare?");
}
 
void loop()
{
  //Start counting when interrupted
  if(stateFront == LOW && startChrono == 0)
  {
    startTime = micros();  // Count microseconds since start
    startChrono = 1;       // Set Chrono flag
    digitalWrite(led1, HIGH);
  }
 
  // Stop counting and calculate speed
  if(stateRear == LOW && startChrono == 1)
  {
    stopTime = micros();  // Count microseconds since start
    startChrono = 0;      // Clear Chrono flag
    elapsed = stopTime - startTime;  // Calculate elapsed time (in micros)
 
    digitalWrite(led2, HIGH); // pin 13
    mpsSpeed = (LENGTH*(MICRO2SEKCOEFF)) / elapsed;            // s = v * t, v = s / t
   // fpsSpeed = mpsSpeed * MPS2FPSCOEFF;

    //lcd.clear();
    //lcd.print("Fps: ");
    //lcd.print(fpsSpeed);
    Serial.println("PPS(Piedi al secondo) ");
    Serial.print(fpsSpeed);
    //lcd.setCursor(0, 1);
    //lcd.print("m/s: ");
    //lcd.print(mpsSpeed);
    Serial.println("Metri al secondo ");
    Serial.print(mpsSpeed);
   
    startChrono = 0;
   
    delay(500);
    digitalWrite(led2, LOW);
    digitalWrite(led1, LOW);
   
  }
 
}

void front()
{
  stateFront = !stateFront;
}

void rear()
{
  stateRear = !stateRear;
}

Non sono un programmatore, ma non mi sembra cosi complessa ... in pratica cambia lo stato di due variabili nelle due ISR, e poi le usa per definire nel loop l'inizio e la fine del conteggio in microsecondi (o per essere precisi, di 4 in 4 microsecondi, dato che se non ricordo male, la massima risoluzione di micros e' 4) ... mi chiedo se non sarebbe piu semplice e veloce impostare invece direttamente tali valori nelle ISR, cioe' usare due variabili volatile unsigned long e fare variabile = micros direttamente nella ISR, evitando cosi tutto il "giro" di controlli nel loop (ma qui serve qualcuno che se ne intende, uno a caso, tipo ad esempio Guglielmo :smiley: che ci dica quale delle due e' la piu veloce) ... led1 e led2 mi sembra che li usa semplicemente per accendere i due led quando premi il pulsante per fare la lettura e li spegne subito dopo, probabilmente solo per risparmiare batteria ...il resto, da controllare, sono solo calcoli per convertire i microsecondi in tempo e velocita', conoscendo ovviamente la distanza fra i due fotodiodi ... ed in energia conoscendo il peso del pallino ...

Anche gli interrupt io personalmente userei rising o falling, quello che viene letto meglio, e non change, perche' tecnicamente e' scorretto usare change ... con change ogni pallino viene letto due volte da ciascun fotodiodo, quando interrompe il raggio e quando lo libera, e se il pallino e' sufficentemente lento questo introduce un'ulteriore errore, cambiando due volte lo stato della variabile ... in pratica rischi di invertirla due volte, riportandola allo stato iniziale e bloccando il tutto ...

Grazie dei preziosi consigli. In effetti anche a me non sembra complessa; dopo averla studiata l'ho compresa ma mi manca la capacità di realizzarla autonomamente. Sentiamo i consigli di qualche esperto di programmazione.
Un istruzione che non mi è chiara è la condizione LOW di questo rigo.

 if(stateFront == LOW && startChrono == 0)

O meglio l'ho compresa ma ho dubbi sul reale stato LOW.

Le prove fatte con i TSOP non sono soddisfacenti. Le letture non coerenti e si stranmisce e genera letture a caso.
Vorrei provare con due fotodiodi a due piedini visto che il TSOP ne ha tre...come collego il fotodiodo?

Etemenanki:
... uno a caso, tipo ad esempio Guglielmo ...

Io collegherei i due fotodiodi a due pin INT facendo si, come hai detto, che scatti solo su uno dei due fronti (se normalmente il segnale è HIGH e va LOW al passaggio del pallino, lo farei sul fronte di discesa, in caso contrario sul fronte di salita).

In entrambe la ISR farei solo l'assegnazione di una variabile volatile (intendo una diversa variabile per ogni ISR) al valore di micros() al momento dello scatto dell'interrupt.

Nel loop() se trovo entrambe le variabili diverse da zero, faccio la differenza per calcolare il tempo e le azzero di nuovo in attesa della nuova misura.

La parte software è molto semplice, quella più delicata è quella hardware ... ::slight_smile:

Guglielmo

P.S.: Convermo che su un AVR a 16MHz la risoluzione di micros() è 4 μsec.

Guglielmo: quindi mi confermi anche tu che, come da mia impressione, sarebbe meglio fare direttamente le assegnazioni nelle ISR, invece che come in quel programma ? ... a me dava l'idea di una complicazione inutile fatta cosi, ma non ero sicuro se fosse stato fatto perche' assegnare il valore di micros ad una unsigned long richiedesse piu tempo che invertire uno stato di una byte, o per chissa' quale altra ragione ...

Pensavo, come hai detto anche tu, che si puo far fare al loop solo il confronto finale ... magari come "finezza" e per risparmiare batterie, ci si potrebbe aggiungere un pulsante che azzera le due variabili ed accende i led, come "start" per la lettura ... tipo, nel setup le definisci entrambe a valore 1 (valore che sara' molto improbabile abbiano mai in seguito), per cui il micro puo stampare il messaggio iniziale, o la richiesta di premere start, eccetera, quando le trova cosi ... quando premi start, le azzeri, accendi i due led, aspetti un mezzo secondo, dai la conferma dello start (magari si aggiunge anche un buzzer piezo per i vari bip) ed inizia un conteggio di, mettiamo, 30 o 60 secondi ... se nulla succede entro quel tempo, resetti tutto al valore iniziale e spegni i led (cosi risparmia anche batteria), se invece passa il pallino, quando non valgono piu zero entrambe il loop puo spegnere i led, fare i calcoli e visualizzarli, e mettersi in attesa di un'altra pressione del pulsante per la successiva lettura ... ci sta ?

vince59:
...
Le prove fatte con i TSOP non sono soddisfacenti...

Non lo saranno mai ... i TSOP non sono fotodiodi, ma ricevitori integrati con anche altra elettronica dentro ... sono tipo 10000 volte piu "lenti" di un vero fotodiodo, se usati in quel modo ...

Etemenanki:
... ci sta ?

... se si ha necessità di alimentare il tutto a batterie e di risparmiare corrente, sicuramente si può fare una cosa come quella che dici :slight_smile:

Guglielmo

Ho immaginato di si, perche' in fondo parla di un'oggetto da collegare alla volata della carabina, probabilmente in poligono o su un campo di tiro sportivo, dove non e' che ti mettano a disposizione tante prese di corrente :wink:

gpb01:
Io collegherei i due fotodiodi a due pin INT facendo si, come hai detto, che scatti solo su uno dei due fronti (se normalmente il segnale è HIGH e va LOW al passaggio del pallino, lo farei sul fronte di discesa, in caso contrario sul fronte di salita).

La parte software è molto semplice, quella più delicata è quella hardware ... ::slight_smile:

Guglielmo

P.S.: Convermo che su un AVR a 16MHz la risoluzione di micros() è 4 μsec.

Comincerei a stabilire qualche punto fermo:
HARDWARE:
utilizzare due led IR e due fotodiodi PIN (int 0 ed int 1). A livello elettrico i led IR alimentati continuamente magari con una resistenza verso il positivo per limitare l'assorbimento..diciamo 100ohm.
Per i fotodiodi posso provare il collegamento a polarizzazione inversa suggerito da etemenanki ((catodi dei diodi al +5V, anodi ai pin di arduino, resistenze fra i pin e massa come pull-down e per polarizzare inversamente il diodo). Io credo che il segnale sia sufficente altrimenti amplifico con un BC337 o simile.
Ricordate che sono cmq in attesa di ricevere i laser tx e rx. Provo a buttare giù uno schema elettrico

SOFTWARE:
qui vi chiedo di farmi comprendere le vostre osservazioni perchè non mi sono del tutto chiare laddove Guglielmo recita:

In entrambe la ISR farei solo l'assegnazione di una variabile volatile (intendo una diversa variabile per ogni ISR) al valore di micros() al momento dello scatto dell'interrupt.

Nel loop() se trovo entrambe le variabili diverse da zero, faccio la differenza per calcolare il tempo e le azzero di nuovo in attesa della nuova misura.

vince59:
SOFTWARE:
qui vi chiedo di farmi comprendere le vostre osservazioni perchè non mi sono del tutto chiare ...

... cosa non ti è chiaro ? ? ?

Guglielmo