[ Arduino 503] Des capteurs plus évolués

Comme nous avons pu le voir plus tôt, certains capteurs transmettent l’information sous forme d’une donnée électrique qui varie : la résistance ou la tension.
Cependant, certains capteurs envoient l’information de manière « codée », afin qu’elle soit plus résistante au bruit (perturbations) et garantir le signal transmis. Parmi ces méthodes de transmission, on retrouve l’utilisation d’une PWM, de la fréquence ou d’un protocole de communication.

Capteur à sortie en modulation de largeur d’impulsion (PWM)

Principe

Vous vous souvenez de la PWM ? Nous l’avons utilisée dans le chapitre sur les sorties analogiques. Dans ce type de signal, l’information est présente dans la durée de l’état haut par rapport à l’état bas. Ici, notre capteur va donc de la même façon coder l’information via une durée d’état (mais elle ne sera pas forcément relative à son état antagoniste). Il est donc nécessaire de connaitre les caractéristiques du capteur pour pouvoir interpréter le signal correctement.
En effet, si on prend le signal sans rien savoir du capteur, comment déterminer ce que 20ms d’état haut signifie par exemple ?
Pour cela, ce type de composant doit toujours être utilisé avec sa documentation technique, afin de déterminer des paramètres comme ses bornes inférieure et supérieure de mesure. Mais c’est aussi vrai pour les autres (si vous tombez sur une résistance variable sans rien en connaître, vous devrez vous farcir une belle séance d’étalonnage pour l’identifier !).

Utilisation

Prenons un cas simple. Imaginons que nous avons un capteur de température qui nous renvoie l’information suivante : « La température en °C Celsius est proportionnelle à la durée d’état haut. La plage de mesure va de 0°C à 75°C pour une durée d’état haut de 0ms à 20ms ».
Nous avons donc une relation proportionnelle entre une température et une durée. Nous pouvons alors déduire une règle mathématique pour faire la conversion degrésdurée.
En effet, on a les équivalences suivantes :

  • \(0^{\circ}C \Leftrightarrow 0ms \Leftrightarrow 0\%\)
  • \(75^{\circ}C \Leftrightarrow 20ms \Leftrightarrow 100\%\)

Une simple règle de trois nous donne : \(x = \frac{75}{20} = 3.75^{\circ}C/ms\) ce qui signifie que pour chaque milliseconde, on a 3.75°C .
Voyons maintenant comment l’utiliser…

Dans la pratique avec Arduino

Bon, c’est pas mal on a le côté théorique de la chose, mais ça ne nous dit toujours pas comment on va l’exploiter avec notre Arduino. En effet, générer une PWM on sait faire, mais mesurer une durée d’état haut ça on ne sait pas !
Et bien rassurez-vous, comme d’habitude c’est assez simple. En effet, il existe une fonction dans le framework Arduino qui sert exactement à cela, mesurer une durée d’état haut ou bas.
Cette fonction s’appelle pulseIn(). Elle prend simplement en paramètres la broche sur laquelle vous voulez faire la mesure et l’état que vous voulez mesurer (HIGH ou LOW). En option, un troisième paramètre permettra de spécifier un « timeout », un temps maximal à attendre avant de décider que la mesure n’est pas possible. Si le timeout est de 2 secondes et que l’état à mesurer n’a pas commencé 2 secondes après l’appel de la fonction, alors cette dernière retournera 0. Dernier détail, l’intervalle de mesure de la fonction est de 10µs à 3 minutes et renvoie un unsigned long représentant la durée de l’état en microsecondes.
Voilà, vous savez tout pour utiliser cette fonction ! Il ne faut pas oublier cependant que la broche sur laquelle nous allons faire la mesure doit être placée en INPUT lors du setup() 😉 .
Reprenons maintenant l’exemple commencé ci-dessus.
Pour mesurer la température, nous allons mesurer l’état haut en sachant que celui-ci sera proportionnel à la température. Un code simple serait donc :

Simulation de l’exemple

Si comme moi vous n’avez pas de capteur retournant une PWM, voici un petit montage tout simple permettant de tester ce concept.
Pour cela, nous allons utiliser une PWM de l’Arduino ! En effet, on sait depuis le chapitre « Sorties analogiques » faire varier un rapport cyclique dans une PWM, on va donc l’appliquer ici pour tester pulseIn().
Pour cela, reliez une broche PWM à la broche qui vous sert de capteur puis essayez de réaliser ce que l’on vient de voir.

La fréquence de la PWM via Arduino est d’environ 490Hz, ce qui signifie que la durée d’état haut pourra varier entre 0ms et 2,04ms

Étude de cas : le capteur de distance SRF05

Prenons un exemple, le télémètre ultrason SRF05 dont la doc. technique a été retranscrite ici.
Ce composant est l’exemple classique du capteur renvoyant un créneau codant l’information. En effet, ce dernier mesure ce que l’on appelle un temps de vol. Explications !
Le SRF05 est un télémètre ultra-son. Pour mesurer une distance, il compte le temps que met une onde pour faire un aller-retour. Un chronomètre est déclenché lors du départ de l’onde et est arrêté lorsque l’on détecte le retour de l’onde (une fois que celle-ci a « rebondi » sur un obstacle). Puisque l’on connait la vitesse de propagation (V) de l’onde dans l’air, on peut déterminer la distance (d) nous séparant de l’objet. On a donc la formule : \(v = \frac{d}{t}\) soit \(d = t \times v\).

Le temps mesuré correspond à l’aller ET au retour de l’onde, on a donc deux fois la distance. Il ne faudra pas oublier de diviser le résultat par deux pour obtenir la distance réelle qui nous sépare de l’objet.

Comme expliqué dans la documentation, pour utiliser le sonar il suffit de générer un état haut pendant 10 µs puis ensuite mesurer l’état haut généré par le sonar.
Ce dernier représente le temps que met l’onde à faire son aller-retour. Si l’onde met plus de 30ms à faire son voyage, elle est alors considérée comme perdue et la ligne repasse à LOW.
Et voilà, vous avez maintenant toutes les informations pour faire un petit programme d’essai pour utiliser ce sonar.
Ah, une dernière information… La vitesse d’une onde sonore dans l’air à 15°C est de 340 mètres par seconde. Ça pourrait être utile !

Capteur à signal de sortie de fréquence variable

Voyons maintenant un autre type de sortie très similaire à celui vu ci-dessus, la fréquence. Les capteurs de ce type vont donc vous délivrer une fréquence variable en fonction de la valeur mesurée. Je ne vais pas vous mentir, je n’ai pas d’exemple en tête !
Cependant, il est facile d’imaginer comment les utiliser en prenant en compte ce que l’on vient de voir pour le capteur renvoyant une PWM.
En effet, considérons un capteur nous envoyant un signal de type « créneau » à une fréquence f. Un créneau possède en théorie une durée d’état haut égale à la durée de l’état bas. Si on fait donc une mesure de cette durée d’état haut via pulseIn() vue précédemment, on peut aisément déduire la période (T) du signal (qui sera égale à deux fois la valeur lue) et ainsi la fréquence puisque \(f = 1/T\).
De manière programmatoire, on obtiendra donc le code suivant :

Exemple / Exercice

Afin de mettre tout cela en pratique, je vous propose un petit exercice pour mettre en œuvre ce dernier point. Peu de matériel est à prévoir.

Principe

Pour cet exercice, je vous propose d’émuler le comportement d’un capteur générant une fréquence variable.
Nous allons utiliser un potentiomètre qui va nous servir de « variateur ». Ensuite nous allons utiliser une fonction propre à Arduino pour générer une fréquence particulière qui sera l’image multipliée par 10 de la valeur mesurée du potentiomètre. Enfin, nous allons « reboucler » la sortie « fréquence » sur une entrée quelconque sur laquelle nous mesurerons cette fréquence.
C’est clair ? J’espère !

La fonction tone()

Pour faire cette exercice vous connaissez déjà tout à une chose près : Comment générer une fréquence. Pour cela, je vous propose de partir à la découverte de la fonction tone(). Cette dernière génère une fréquence sur une broche, n’importe laquelle. Elle prend en paramètre la broche sur laquelle le signal doit être émis ainsi que la fréquence à émettre. Par exemple, pour faire une fréquence de 100Hz sur la broche 3 on fera simplement : tone(3, 100);.
Un troisième argument peut-être utilisé. Ce dernier sert à indiquer la durée pendant laquelle le signal doit être émis. Si on omet cet argument, la fréquence sera toujours générée jusqu’à l’appel de la fonction antagoniste noTone() à laquelle on passe en paramètre la broche sur laquelle le signal doit être arrêté.

L’utilisation de la fonction tone interfère avec le module PWM des broches 3 et 11. Gardez-le en mémoire 😉 . Cette fonction ne peut pas non plus descendre en dessous de 31Hz.

Vous avez toutes les informations, maintenant à vous de jouer !

Correction

Voici ma correction commentée. Comme il n’y a rien de réellement compliqué, je ne vais pas faire des lignes d’explications et vous laisser simplement avec le code et ses commentaires 👿 !

Capteur utilisant un protocole de communication

Certains capteurs ne renvoient pas l’information sous forme « physique » dans le sens ou ils ne renvoient pas quelque chose de mesurable directement, comme un temps ou une tension. Non, ces derniers préfèrent envoyer l’information encapsulée bien au chaud dans une trame d’un protocole de communication.
Le gros intérêt de cette méthode est très probablement la résistance au « bruit ». Je ne parle bien sûr pas des cris des enfants du voisin ou les klaxons dans la rue mais bien de bruit électronique. Ce dernier est partout et peut avoir des conséquences ennuyeuses sur vos mesures. Transmettre l’information par un protocole de communication est donc un moyen fiable de garantir que la donnée arrivera de manière intègre jusqu’au destinataire. De plus, on peut facilement coupler cette transmission avec un protocole de vérification simple ou compliqué (comme la vérification de parité ou un calcul de CRC).

Cette partie ne vas pas vous enseigner comment utiliser chacun des moyens de communication que nous allons voir. En effet, il s’agit plutôt d’une introduction/ouverture sur l’existence de ces derniers. Ils seront traités de manière indépendante dans des chapitres dédiés comme le fût la voie série.

Quelques protocoles de communication

Voie série / UART

Ce protocole vous devez déjà le connaître par cœur puisque nous l’utilisons presque dans tous les chapitres ! Il s’agit en effet de la voie série via Serial. Rien de réellement compliqué donc tellement vous êtes habitués à le voir !
Ceci est une liaison point-à-point, donc seuls deux composants (l’Arduino et le capteur) peuvent être reliés entre eux directement. Elle est généralement bi-directionnelle, ce qui signifie que les deux composants reliés peuvent émettre en même temps.

I2C

Le protocole I²C (Inter-Integrated Circuit) ou TWI (Two Wire Interface) permet d’établir une liaison de type « maître/esclave ». L’Arduino sera maître et le capteur l’esclave (l’Arduino peut aussi être un esclave dans certains cas). Ainsi, l’Arduino émettra les ordres pour faire les demandes de données et le capteur, lorsqu’il recevra cet ordre, la renverra.
Ce protocole utilise 3 fils. Un pour la masse et ainsi avoir un référentiel commun, un servant à émettre un signal d’horloge (SCL) et un dernier portant les données synchronisées avec l’horloge (SDA).
Chez Arduino, il existe une librairie pour utiliser l’I2C, elle s’appelle Wire.
On peut placer plusieurs esclaves à la suite. Un code d’adresse est alors utilisé pour décider à quel composant le maître fait une requête.

SPI

Le SPI (Serial Peripheral Interface) est une sorte de combo entre la voie série et l’I2C. Elle prend le meilleur des deux mondes.
Comme en voie série, la liaison est bi-directionnelle et point-à-point*. Cela signifie que Arduino et le capteur sont reliés directement entre eux et ne peuvent que parler entre eux. Cela signifie aussi que les deux peuvent s’envoyer des données simultanément.
Comme en I2C, la liaison est de type maître/esclave. L’un fait une demande à l’autre, le maître transmet l’horloge à l’esclave pour transmettre les données.
Cette transmission utilise 4 fils. Une masse pour le référentiel commun, un fil d’horloge (SCLK), un fil nommé MOSI (Master Output, Slave Input; données partant de l’Arduino et allant vers le capteur) et MISO (Master Input, Slave Output, données partant du capteur et allant vers l’Arduino).
*Afin d’améliorer cette voie série, il existe une autre broche nommée SS (Slave Select) permettant de choisir à quel composant le maître parle. Ainsi la liaison n’est plus limitée à un esclave seulement.
Chez Arduino, il existe une librairie pour utiliser le SPI, elle s’appelle … SPI.

Protocole propriétaire

Ici pas de solution miracle, il faudra manger de la documentation technique (très formateur !). En effet, si le constructeur décide d’implémenter un protocole à sa sauce alors ce sera à vous de vous plier et de coder pour réussir à l’implémenter et l’utiliser.

Vous savez maintenant tout sur les capteurs, votre Arduino peut maintenant « sentir » le monde qui l’entoure comme promis en introduction de cette partie. Mais ce n’est pas fini, il existe un grand nombre de capteurs, beaucoup trop important pour en faire une liste exhaustive dans un tutoriel comme celui-ci.
Maintenant que vous pouvez percevoir le monde, passons à la suite en essayant d’interagir avec ce dernier grâce à l’utilisation de moteurs

Une expérience (bonne ou mauvaise) à partager ? Des questions à poser ? Des conseils à donner ? Ne soyez pas timide !

30 commentaires

  1. Bonjour, jai une question sur les capteur ultrason :
    Je veut en acheter un mais les prix varie beaucoup, sur internet je peut en avoir un a 5€ et en magasin a 30 voir 50€ .
    Comment je fait pour choisir ?

  2. je n’arrive pas à faire marcher mon capteur HC-SR04 que j’ai acheté sur ebay: Voici mon code:

    #define VITESSE 340

    const int declencheur = 2;
    const int capteur = 3;

    void setup()
    {
    pinMode(declencheur, OUTPUT);
    pinMode(capteur, INPUT);

    digitalWrite(declencheur, LOW);
    Serial.begin(9600);
    }

    void loop()
    {
    digitalWrite(declencheur, HIGH);
    delayMicroseconds(10);
    digitalWrite(declencheur, LOW);

    //puis on récupère la mesure
    unsigned long duree = pulseIn(capteur, HIGH);

    if(duree > 30000)
    {

    Serial.println(« Onde perdue, mesure echouee ! »);
    }
    else
    {
    duree = duree/2;
    float temps = duree/1000000.0;
    float distance = temps*VITESSE;

    Serial.print(« Duree = « );
    Serial.println(temps);
    Serial.print(« Distance = « );
    Serial.println(distance);

    delay(250);
    }

    pouvez vous le tester pour voir si cela marche avec votre HC-SR04 je voudrai savoir si le problème vient de moi ou du composant.
    J’ai l’impression que sur celui-ci il manque le composant y1, on peut le voir sur la photo.
    Merci bien de votre réponse.

    Philou Chagnot

    • Salut !

      Malheureusement je n’ai pas acces a mes composants pour quelques jours, je ne peux donc rien tester pour le moment.

      Petite précision que j’aurais du apporter dans le tuto, le code du SR04 est un des seuls que je n’ai pas testé (je n’avais pas le composant à ce moment là). Je pense qu’il est bon mais il est possible que j’ai oublié quelque chose !!

  3. Bonsoir !

    Un petit message pour deux raisons :
    – Le code du tuto fonctionne parfaitement avec le HC-SR04, le problème est certainement résolu mais comme cela les prochains n’auront pas de doutes en lisant les commentaires, je viens de tester tout cela avec mon matériel 🙂

    – Sinon je tenais à remercier Eskimon et compagnie pour ce super tuto, que je suis dès que j’ai un peu de temps libre, que ce soit en pdf ou sur le site direct. Bravo en tous les cas car c’est un travail monstrueux mais qui porte ses fruits !

    Encore bravo et merci,

    Eagle.

      • Bonjour à tous !

        Si j’ai bien compris tu voudrais faire une sorte de rendu visuel de tes mesures ?
        Pour cela il faudra obligatoirement que tu en fasses plusieurs, et que déplaces le capteur pour obtenir le « tracé » de ce que tu veux visualiser. Mais cette technique est un peu restreinte car tu ne pourras avoir un résultat qu’en 2D.
        Imaginons que tu veuilles faire le plan d’une pièce : une solution pourrait-être de placer ton capteur ultrason sur une plateforme rotative, actionnée par un Servo ou un PaP. Tu commences à un point, tu fais ta mesure, tu fais tourner un peu, un petit degré par exemple, tu fais ta mesure, et ce plusieurs fois jusqu’à faire un tour complet … Ensuite avec un autre programme tu rassemble tes données, et tu auras le « plan » de ta pièce.
        Une version que j’avais croisé de ce type de sonar utilisait une boussole intégrée, afin de bien retracer le pla selon les points cardinaux 🙂

        Tu peux faire pareil (en plus simple même ^^) en te déplaçant en ligne droite par exemple, comme les bateaux et leur sonar font. Tu fais une mesure, tu avances, tu mesures, tu avances, … Et pareil tu compiles tout ça dans comme tu peux 😉
        L’important c’est de bien faire des mesures régulières, e bien entendu, plus ce sera régulier, plus ce sera précis ! 😉

        Voila, dit moi si tu as des questions ou si ce n’est pas ce que tu veux ^^

        A plus,

        Eagle.

        • Un problème sera tout de même que les US sont « en cône », on a pas une belle mesure bien directrice comme un rayon infrarouge ou laser (LIDAR <3 ). Du coup pour la précision sur une droite ca risque de pas être ca...

          • Ah oui évidemment, mais bon ça peut-être un bon début pour modéliser un environnement, et c’est simple à mettre en œuvre ! Tout dépends de la distance, mais si ça reste raisonnable les mesures peuvent être cohérente à mon avis. Je vais essayer ça en ligne droite cette aprem tiens, ça pourrait être amusant 🙂

  4. Bonjour Eskimon,

    Je me joins à tous ceux qui te remercie pour ces supers tutos que tu (vous) proposes et pour le temps que tu prends pour repondre aux questions. Mon problème est le suivant, je fais une acquisition à partir d’un laser qui a une frequence de 2khz. Dans mon code je fais l’acquisition toutes les 512 us cependant le signal acquis est vraiment pourris. Même lorsque le signal est sensé etre constant, j’ai des grandes variations dans ma mesure ? Ma question est quand on fait de l’acquisition de donnée si le signal change pendant que le can fait son acquisition les sorties sont perturbées non ? du coup pour régler mon problème faire des moyennes de mesure fonctionnerait ? changer pour un can plus rapide comme le mcp3202 ?

    Merci beaucoup,

    • Dans un premier temps le moyennage offre des résultats intéressant, gratuit et facile a mettre en oeuvre. Tu peux par exemple:
      – Faire une moyenne avec les 10 derniers résultats (pour que l’impact d’une mesure soit pondérée par les précédentes)
      – Faire un paquet de mesure a l’instant t et en déduire la moyenne (tu auras une mesure moyenne pour l’instant t)

      Si tu veux en parler plus en détail, je t’invite a aller ouvrir un sujet sur zestedesavoir dans la rubrique Systèmes et Matériel. Ce sera plus simple pour poser des questions et échanger avec d’autres compare a cette zone de commentaire 🙂

  5. Bonjour,
    je sais comment afficher du texte sur mon écran (Nokia 5110), mais je n’arrive pas à afficher les données de mon capteur de température et d’humidité (DHT11) sur mon écran.
    Voici mon programme :

    Secret SelectionnerAfficher
    • Salut,
      Pour ce genre de problème, je te propose de passer par un vrai espace d’échange comme les forums de Zeste de Savoir. Ils permettront d’échanger plus facilement que cette zone de commentaire 😉 (que je réserve plutôt aux commentaires lies au tutoriel lui-même). A bientôt !

  6. Salut, tes Tutos mon beaucoup aidés dans la réalisation de mon projet mais il n’est pas terminé car je n’arrive pas à faire le programme pour commander mon capteur de vibrations (DV18015), pourrai-tu m’aider ?

    • Hello !

      Sans code ni montage ni doc technique difficile de dire ce qui bloque 😉 . Je te propose que l’on se retrouve sur les forums de Zeste de Savoir (rubrique « Systèmes et Matériels ») pour en parler plus en détails afin de garder cette section pour les commentaires sur le tutoriel lui-même.

  7. Salut ! 🙂

    J’ai essayé de faire la simulation du capteur avec variation de fréquence mais j’ai remarqué un petit problème… Lorsque j’utilise des fréquences basses (40Hz), j’ai une erreur relativement faible, je lis 40.33 Hz. Cependant, lorsque j’impose une fréquence assez grande (10 000 Hz), l’erreur me parait énorme, j’obtiens en lecture 12 000 Hz soit une différence de 2 000 Hz, comment cela se fait-il ? (J’ai fait le code moi même mais j’obtiens la même chose que toi. Le potar est sur A0, le pin qui met la fréquence est le 2 et celui qui la lit est le 4 (d’ailleurs on dit un ou une pin ? :p)) Oui je mets des parenthèses dans les parenthèses 😀

    Merci, à bientôt 😉

    Amicalement, Chicken’

  8. Bon,.. voilà .. je suis en première et je dois faire un TPE (un gros travail pratique) j’ai suivi pas mal de tuto (d’eskimon biensur 🙂 )… dans mon projet j’aurais besoin d’utilisier un capteur thermique (pour par la suite controler des ventilo , voyez l’idée ? 😉 ) cependant je ne sais vers quelle type de capteur me tourner ..la température ne dépassera pas 110° .. Donc si quelqu’un pourait m’aider je lui en serait très reconnaisant 😉
    Amicalement Mathieu!

  9. Bonjour Eskimon,

    Je travail actuellement sur un capteur d’image (un capteur assez particulier),
    J’ai pu obtenir un code auquel je ne comprend rien si quelqu’un pouvait m’aider à décortiquer la gestion de l’horloge.

    Voici le datasheet du capteur CCD.
    http://www.hamamatsu.com/resources/pdf/ssd/c12666ma_kacc1216e.pdf

    Merci d’avance, voici le code
    ———————————————————–

    // This code is a modified from the original sketch from Peter Jansen
    // https://github.com/tricorderproject/arducordermini
    // This code removes the external ADC and uses the internal ADC instead.
    // also this code just prints the output to csv output to the terminal.

    #define SPEC_GAIN A0
    //#define SPEC_EOS NA
    #define SPEC_ST A1
    #define SPEC_CLK A2
    #define SPEC_VIDEO A3
    #define WHITE_LED A4
    #define LASER_404 A5

    #define SPEC_CHANNELS 256
    uint16_t data[SPEC_CHANNELS];

    void setup() {

    //pinMode(SPEC_EOS, INPUT);
    pinMode(SPEC_GAIN, OUTPUT);
    pinMode(SPEC_ST, OUTPUT);
    pinMode(SPEC_CLK, OUTPUT);

    pinMode(WHITE_LED, OUTPUT);
    pinMode(LASER_404, OUTPUT);

    digitalWrite(WHITE_LED, LOW);
    digitalWrite(LASER_404, LOW);

    //digitalWrite(WHITE_LED, HIGH);
    //digitalWrite(LASER_404, HIGH);

    digitalWrite(SPEC_GAIN, HIGH);
    digitalWrite(SPEC_ST, HIGH);
    digitalWrite(SPEC_CLK, HIGH);
    digitalWrite(SPEC_GAIN, HIGH); //LOW Gain
    //digitalWrite(SPEC_GAIN, LOW); //High Gain

    //Serial.begin(9600);
    Serial.begin(115200);
    }

    void readSpectrometer()
    {
    //int delay_time = 35; // delay per half clock (in microseconds). This ultimately conrols the integration time.
    int delay_time = 1; // delay per half clock (in microseconds). This ultimately conrols the integration time.
    int idx = 0;
    int read_time = 35; // Amount of time that the analogRead() procedure takes (in microseconds) (different micros will have different times)
    int intTime = 100;
    int accumulateMode = false;
    int i;

    // Step 1: start leading clock pulses
    for (int i = 0; i < SPEC_CHANNELS; i++)
    {
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);
    }

    // Step 2: Send start pulse to signal start of integration/light collection
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    digitalWrite(SPEC_ST, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    digitalWrite(SPEC_ST, HIGH);
    delayMicroseconds(delay_time);

    // Step 3: Integration time — sample for a period of time determined by the intTime parameter
    int blockTime = delay_time * 8;
    long int numIntegrationBlocks = ((long)intTime * (long)1000) / (long)blockTime;
    for (int i = 0; i < numIntegrationBlocks; i++) {
    // Four clocks per pixel
    // First block of 2 clocks — measurement
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);

    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);
    }

    // Step 4: Send start pulse to signal end of integration/light collection
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    digitalWrite(SPEC_ST, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    digitalWrite(SPEC_ST, HIGH);
    delayMicroseconds(delay_time);

    // Step 5: Read Data 2 (this is the actual read, since the spectrometer has now sampled data)
    idx = 0;
    for (int i = 0; i read_time) delayMicroseconds(delay_time – read_time); // Read takes about 135uSec

    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);

    // Second block of 2 clocks — idle
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);
    }

    // Step 6: trailing clock pulses
    for (int i = 0; i < SPEC_CHANNELS; i++) {
    digitalWrite(SPEC_CLK, LOW);
    delayMicroseconds(delay_time);
    digitalWrite(SPEC_CLK, HIGH);
    delayMicroseconds(delay_time);
    }
    }

    void print_data()
    {
    for (int i = 0; i < SPEC_CHANNELS; i++)
    {
    Serial.print(data[i]);
    Serial.print(',');
    }
    Serial.print("\n");
    }

    void loop()
    {
    // digitalWrite(LASER_404, HIGH);
    // readSpectrometer();
    // digitalWrite(LASER_404, LOW);
    // print_data();
    // delay(10);

    // digitalWrite(WHITE_LED, HIGH);
    // readSpectrometer();
    // digitalWrite(WHITE_LED, LOW);
    // print_data();
    // delay(10);

    readSpectrometer();
    print_data();
    delay(10);
    }

  10. Salut, j’ai une question sur un capteur à effet doppler que j’aimerai fabriquer :
    Je voudrais calculer la vitesse d’un objet en utilisant l’effet doppler, sauf que la plupart des systèmes émetteur/récepteur que j’ai trouvé ne le permettent pas car la sortie du signal n’est pas « brut » et on ne peut pas modifier le signal comme on veut.
    Je sais qu’il y a les capteurs tout-fait mais je préfererais vraiment partir d’un truc plus basique et gérer le traitement moi-même avec l’arduino.
    En plus de ça, la vitesse de l’objet sera faible, donc les variations de l’onde réfléchie aussi donc il faut un capteur précis.
    Bref, c’est la galère, j’aimerai bien un peu d’aide.
    Merci d’avance, et encore bravo
    Thomas

  11. Bonjour! Merci pour se super tuto!!
    Je travail sur un projet pour mon école. J’ai un capteur de débit relié à un compteur d’eau; Ce capteur me délivre un signal à créneau. Pour une impulsion j’ai un litre qui passe. La fréquence Max est de 14 Hz c’est à dire 14 litres par seconde. Donc ma problématique est d’avoir le débit instantanée pour pouvoir après faire un tracé de ce dernier. J’en déduit aussi que la fréquence est proportionnel au débit. Donc ma question est, comment je doit m’y prendre pour calculer plusieurs période par seconde et ensuite déduire la fréquence.

    J’espère que vous avez compris ma problématique. Merci d’avance !!

Laisser un commentaire