sketch per "chiudicontatto" infrarosso

Buonasera a tutti, vi spiego quello che vorrei realizzare.

Sono un motociclista e frequento le piste. La mia nuova moto dispone di cronometro integrato nel cruscotto (si aziona tramite tasto del lampeggio abbaglianti).

La mia idea era quella di mettere una torretta infrarossi nella corsia box, e un ricevitore con un relè che và a chiudermi il contatto quando passo davanti la torretta.

Userò 2 arduino micro.

Per la trasmittente vorrei usare 4 led infrarossi e pilotarli dandogli un pacchetto di dati in modo che poi il ricevitore "chiuda il circuito" solo quando riconosce quel codice.

Ho già trovato uno sketch e caricato sull'arduino. Questo codice dà 3 pacchetti di impulsi a 38Khz di 468micro secondi intervallati da 1200 microsecondi, e poi una pausa di 6000 microsecondi

Ho bisogno di un codice corto e che il ricevitore riconosca velocemente visto che indicativamente passerà ad una velocità di 70mt/s (250Km/h)

Eccolo :

/* This is the beam pattern for the Team Barnato timing beacon. Use at own risk and no warranties are given.
in Micro Seconds
On - 468 uS
Off - 1200 uS
On - 468 uS
Off - 1200 uS
On - 468 uS
Off - 6000 uS */

int IRledPin = 9;    // LED connected to digital pin 3
int powerLed = 10;    //Power LED is connected to pin 13

void setup()   {               
 // initialize the IR digital pin as an output:
 pinMode(IRledPin, OUTPUT);
 pinMode(powerLed, OUTPUT);
 digitalWrite(powerLed, HIGH);

}

void loop()                   
{
 pulseIR(468);
 delayMicroseconds(1200);
 pulseIR(468);
 delayMicroseconds(1200);
 pulseIR(468);
 delayMicroseconds(6000);
}

// This procedure sends a 38KHz pulse to the IRledPin
// for a certain # of microseconds.
void pulseIR(long microsecs) {
 // we'll count down from the number of microseconds we are told to wait

 cli();  // this turns off any background interrupts

 while (microsecs > 0) {
   // 38 kHz is about 26 microseconds - to give 50% duty cycle 13 microseconds high and 13 microseconds low
  digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
  delayMicroseconds(10);         // hang out for 10 microseconds
  digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
  delayMicroseconds(10);         // hang out for 10 microseconds

  // so 26 microseconds altogether
  microsecs -= 26;
 }

 sei();  // this turns them back on
}

Ora devo creare uno sketch che vada a leggere quel codice e mi faccia chiudere il contatto (o comq un digitalwrite che poi porterò al modulo relè)

Userei un'altro arduino micro e come ricevitore userei il conosciuto tsop1838.

Qualcuno potrebbe aiutarmi nella compilazione del programma?

Graziem mille a tutti quelli che mi aiuteranno.

>Key84RR: ti rammento che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

Grazie,

Guglielmo

Grazie mille, ho corretto :slight_smile:

Come disse il mercante al turista:
-"Per vedere cammello, dare soldi"-.

Puso:
Come disse il mercante al turista:
-"Per vedere cammello, dare soldi"-.

Scusami, pensavo fosse un forum di appassionati di arduino...... Non di professionisti che vendono gli sketch.

Key84RR:
Scusami, pensavo fosse un forum di appassionati di arduino...... Non di professionisti che vendono gli sketch.

Non te la prendere Key84RR, ancora non conosci alcuni utenti ... "Puso", ogni tanto, se ne esce con battute che poco hanno a che vedere con il forum :wink:

Sicuramente, se qulcuno che conosce la materia passa, cercerà di aiutarti :slight_smile:

Guglielmo

Ho provato ad adattare un codice presente in un’altro progetto sempre di un cronometro infrarosso ed adattarlo ai miei scopi

Ho definito che il relè è un’uscita ed è al pin 7, e la parte finale di comando del relè.

#define RELE 7  //indica al compilatore che il PULSANTE è collegato al pin 7
#define IRpin_PIN      PIND // assign pin 2 raw mapping to IRpin 2
#define IRpin          2

#define MAXhighPULSE 2000 // Time counts to reset tokens to zero if no beam detected incase of false trigger, 2000 * RESOLUTION = 40ms
#define MAXlowPULSE 28 // the maximum pulse count we need. 560us / RESOLUTION = 28
#define MINlowPULSE 18 // the minimum pulse count we need. 360us / RESOLUTION = 18

#define RESOLUTION 20 // Multiplier - will be used to take reading of IRpin every 20ish microseconds
int lowpulse = 0; // start with 0 for the pulse length.
int highpulse = 0; // start with 0 for the pulse length.
int token = 0; // start with 0 count for tokens. We'll need 3 tokens to trigger the timer.

void setup() {
  pinMode(RELE, OUTPUT);      //imposta il pin LED come output
  
}


void loop() {
  highpulse = lowpulse = 0; // start out with no pulse length
  while (IRpin_PIN & (1 << IRpin)) { // while irpin is high - no beam is beam is being received.

    highpulse++;
    delayMicroseconds(RESOLUTION);// wait some time, the multiplier.

    if (highpulse >= MAXhighPULSE) { /* check to see if no signal has been received for over 40ms (we should
     recieve 3 tokens in 4ms, so if we only receive one or two tokens in 40ms it must be a false signal),
     then reset the token count if true as no/false signal is being received.
     */
      token = 0;
      highpulse = 0;// reset high pulse counter
    }
  }
  while (! (IRpin_PIN & _BV(IRpin))) {// while irpin is low, signal being received
    lowpulse++;
    delayMicroseconds(RESOLUTION);
  }
  if ((lowpulse >= MINlowPULSE)  && (lowpulse <= MAXlowPULSE)) {// was the pulse length what we expected?
    token ++; // if so then count 1 token, we need 3 tokens to trigger
  }
  if (token == 3)
  { // If we receive 3 correct pulses then trigger the lap timer.
    digitalWrite (RELE, HIGH); // eccita il relè per 
    delay(1000); // 1 secondo
    digitalWrite(RELE, LOW);  //diseccita il relè
    
  ;}
}

Nel week end dovrei riuscire a testarlo, ma da compilatore non di dà nessun codice di errore

... nei tag CODE NON devi (e non puoi) usare i colori ... edita il tuo post, elimina i colori e racchiudi TUTTO il codice nei tag CODE. Grazie :slight_smile:

Guglielmo

Ciao,
personalmente non ritengo sia un buon metodo per fare ciò che vuoi… hai idea della precisione che potrai ottenere? Quante volte passerai ed il codice trasmesso non verrà correttamente ricevuto? Hai considerato che probabilmente la luce del sole accecherà il ricevitore, riducendo di molto la sua sensibilità? In casa funziona tutto bene, ma all’esterno è un’altra storia.

Comunque per lo sketch, se ti carichi le librerie IRREMOTE di Ken Shirriff , trovi tutto già pronto al 90%, ovvero SendRaw , che puoi decidere e comporre a piacere, e IRrecvDemo; una volta decodificato il codice il resto è semplice.

Auguri per il tuo progetto.

Luciano

Buongiorno a tutti, ho provato a caricare i 2 sketch nei relativi arduini e ho constatato questo.

Trasmettitore funziona come previsto.
Ho controllato all’uscita del led con l’oscilloscopio, e mi ritrovo 3 pacchetti di dati (38Khz) lunghi 468 microsecondi intervallati tra loro da 1200 microsecondi, e poi una pausa di 6000 microsecondi

Il ricevitore invece non mi fà scattare il relè.
Come prima cosa sono andato a vedere se il Tsop riceveca correttamente i dati, e anche qui la risposta è positiva.
Collegando l’oscilloscopio tra massa e data del Tsop vedo che ho 3 impulsi negativi come mi aspettavo.

Quindi a questo punto il problema è del codice di arduino, qualcuno può controllare e vedere se secondo lui ci sono degli errori?
Il codice è il seguente

#define RELE 7  //indica al compilatore che il PULSANTE è collegato al pin 7
#define IRpin_PIN      PIND // assign pin 2 raw mapping to IRpin 2
#define IRpin          2

#define MAXhighPULSE 2000 // Time counts to reset tokens to zero if no beam detected incase of false trigger, 2000 * RESOLUTION = 40ms
#define MAXlowPULSE 28 // the maximum pulse count we need. 560us / RESOLUTION = 28
#define MINlowPULSE 18 // the minimum pulse count we need. 360us / RESOLUTION = 18

#define RESOLUTION 20 // Multiplier - will be used to take reading of IRpin every 20ish microseconds
int lowpulse = 0; // start with 0 for the pulse length.
int highpulse = 0; // start with 0 for the pulse length.
int token = 0; // start with 0 count for tokens. We'll need 3 tokens to trigger the timer.

void setup() {
 pinMode(RELE, OUTPUT);      //imposta il pin LED come output
 
}


void loop() {
 highpulse = lowpulse = 0; // start out with no pulse length
 while (IRpin_PIN & (1 << IRpin)) { // while irpin is high - no beam is beam is being received.

   highpulse++;
   delayMicroseconds(RESOLUTION);// wait some time, the multiplier.

   if (highpulse >= MAXhighPULSE) { /* check to see if no signal has been received for over 40ms (we should
    recieve 3 tokens in 4ms, so if we only receive one or two tokens in 40ms it must be a false signal),
    then reset the token count if true as no/false signal is being received.
    */
     token = 0;
     highpulse = 0;// reset high pulse counter
   }
 }
 while (! (IRpin_PIN & _BV(IRpin))) {// while irpin is low, signal being received
   lowpulse++;
   delayMicroseconds(RESOLUTION);
 }
 if ((lowpulse >= MINlowPULSE)  && (lowpulse <= MAXlowPULSE)) {// was the pulse length what we expected?
   token ++; // if so then count 1 token, we need 3 tokens to trigger
 }
 if (token == 3)
 { // If we receive 3 correct pulses then trigger the lap timer.
   digitalWrite (RELE, HIGH); // eccita il relè per 
   delay(1000); // 1 secondo
   digitalWrite(RELE, LOW);  //diseccita il relè
   
 ;}
}

In teoria ed in pratica funziona, il progetto l'ho preso da un'utente inglese che si è costruito il cronometro per il kart

Non sò se posso mettere il link qui, in caso contrario lo rimuoverò subito

Praticamente a mè tutto il codice riguardante la memorizzazione su sd e visualizzazione non mi serve, quindi l'ho rimosso e aggiuinto parte di codice per il relè