Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Détecteur de métaux Arduino IB DIY sensible avec discrimination

Composants et fournitures

Arduino Nano R3
× 1
Adafruit Standard LCD - 16x2 Blanc sur Bleu
× 1
CI d'amplificateur opérationnel TL081
× 1
Haut-parleur :0,25 W, 8 ohms
× 1
Transistor à usage général NPN
× 1
Recherche de bobines
× 2
Résistances, condensateurs
× 1

Applications et services en ligne

Arduino IDE

À propos de ce projet

Cette fois, je vais vous montrer comment fabriquer un détecteur de métaux sensible également capable de faire la distinction entre les matériaux ferreux et non ferreux. La sensibilité est satisfaisante, étant donné qu'il s'agit d'un appareil relativement simple.

Ce projet est parrainé par PCBgogo :

https://www.pcbgogo.com/promo/from_MirkoPavleskiMK

Il s'agit d'une continuation du projet de David Crocker présenté au forum Arduino CC en 2013. J'ai décidé de tester son code car je n'ai trouvé aucune preuve (photo ou vidéo) que ce détecteur de métaux a été fabriqué par qui que ce soit et fonctionne bien.

J'ai d'abord fait une version basique avec le code présenté sur GitHub, pour m'assurer de la fonctionnalité de l'appareil puis j'ai mis à jour le code pour qu'il ait un signal sonore, et sur un écran LCD 16 sur 2 des informations visuelles sur le type de objet détecté (matériau ferreux ou non ferreux) et graphique à barres LCD pour la proximité des objets détectés.

L'appareil est très simple à construire et ne comprend que quelques composants :

- Microcontrôleur Arduino Nano

- Amplificateur opérationnel (dans mon cas LT1677, mais vous pouvez utiliser TL081 ou 741)

- Peu de résistances et condensateurs

- Petit transistor et haut-parleur

- Écran LCD

- 3 interrupteurs

- Potentiomètre

- Batterie

- Et des bobines de recherche

Il s'agit d'une technologie de détecteur à Induction Balance VLF (très basse fréquence) et contient deux bobines identiques :la bobine émettrice et la bobine réceptrice. Comme pour tous les détecteurs d'équilibre à induction, l'équilibre de la bobine est très critique. Le potentiomètre est utilisé pour mettre à zéro la petite composante déphasée de 90 degrés du signal. (le composant en phase est annulé en ajustant le placement relatif des bobines dans un style de détecteur IB typique). Chacune des bobines est enroulée sur un corps de 11 cm à l'aide de 64 spires de fil de cuivre émaillé de 0,5 mm^2 en forme de D, enroulées de ruban adhésif autour d'elles, tamisées à l'aide d'une feuille d'aluminium liée avec du fil de cuivre étamé (en prenant soin de laisser un petit espace pour que l'écran ne se comporte pas comme un virage court), et les a noués sur une plaque en plastique.

Nous devons d'abord déterminer la fréquence de résonance parallèle du circuit bobine-condensateur primaire à l'aide de l'un des nombreux calculateurs en ligne. Je l'ai mesuré avec un oscilloscope, mais si vous respectez les dimensions données ci-dessus, ce sera exactement 7,64 kHz, vous pouvez donc entrer directement la valeur donnée dans le code. Dans le cas d'une autre valeur de la fréquence de résonance, nous devons faire un changement approprié dans le code dans la file d'attente :

#define TIMER1_TOP (249) // affine la fréquence

Comme vous pouvez le voir dans la vidéo, les résultats sont étonnamment bons. Sans la présence d'un métal, l'appareil est parfaitement stable. La portée est relativement large et par exemple, un couvercle métallique d'un diamètre de 15 cm est détecté à une distance de plus de 30 cm. Les objets métalliques plus gros sont détectés à des distances supérieures à 40-50 cm. On peut détecter une petite pièce à une distance de 15cm dans les airs. J'utilise deux batteries au lithium pour l'alimentation qui sont connectées en série (7,4 volts) et cette tension est connectée à l'entrée Vin de l'Arduino. La consommation ne dépasse pas 20mA donc les batteries durent très longtemps. La vidéo décrit en détail la construction de l'ensemble de l'appareil.

Ce ne sont que des résultats préliminaires. Il est possible d'améliorer considérablement la sensibilité en insérant un transistor MOSFET de puissance pour piloter la bobine Tx, mais je vais le tester et le présenter dans l'une des vidéos suivantes.

Code

  • Code Arduino
  • Lib.LcdBarGraph.
Code ArduinoArduino
// Détecteur de métaux à balance à induction// Nous faisons tourner le CPU à 16MHz et l'horloge ADC à 1MHz. La résolution ADC est réduite à 8 bits à cette vitesse. // La minuterie 1 est utilisée pour diviser l'horloge système par environ 256 pour produire une onde carrée de 62,5 kHz. // Ceci est utilisé pour piloter la minuterie 0 et également pour déclencher les conversions ADC.// La minuterie 0 est utilisée pour diviser la sortie de la minuterie 1 par 8, donnant un signal de 7,8125 kHz pour piloter la bobine de transmission.// Cela nous donne 16 ADC cycles d'horloge pour chaque conversion ADC (cela prend en fait 13,5 cycles), et nous prenons 8 échantillons par cycle de la tension d'entraînement de la bobine. // L'ADC met en œuvre quatre détecteurs sensibles à la phase à des intervalles de 45 degrés. L'utilisation de 4 au lieu de 2 nous permet d'annuler la troisième harmonique de la// fréquence de la bobine.// La minuterie 2 sera utilisée pour générer une tonalité pour l'écouteur ou le casque. // D'autres rapports de division pour la minuterie 1 sont possibles, à partir d'environ 235 vers le haut.// Câblage:// Connectez la broche numérique 4 (alias T0) à la broche numérique 9// Connectez la broche numérique 5 via la résistance à la bobine primaire et au condensateur de réglage // Connectez la sortie de l'amplificateur de réception à la broche analogique 0. Sortie de la réception l'amplificateur doit être polarisé à environ la moitié de la référence analogique.// Lors de l'utilisation de l'alimentation USB, changez la référence analogique sur la broche 3,3 V, car il y a trop de bruit sur le rail +5 V pour obtenir une bonne sensibilité.#include  #include #define max_ampAverage 200LiquidCrystal lcd (6, 7, 10, 11, 12, 13);LcdBarGraph lbg(&lcd, 16, 0, 1); #define TIMER1_TOP (259) // peut ajuster ceci pour affiner la fréquence pour obtenir la bobine réglée (voir ci-dessus) #define USE_3V3_AREF (1) // défini sur 1 de l'exécution sur un Arduino avec alimentation USB, 0 pour un embarqué atmega28p sans alimentation 3,3 V disponible // Définitions des broches numériques // Broche numérique 0 non utilisée, cependant, si nous utilisons le port série pour le débogage, il s'agit de l'entrée série const int debugTxPin =1 ; // transmission de la broche réservée au débogageconst int encoderButtonPin =2; // bouton encodeur, également IN0 pour sortir du mode veilleconst int earpiecePin =3; // écouteur, alias OCR2B pour la génération de tonalitéconst int T0InputPin =4;const int coilDrivePin =5;const int LcdRsPin =6;const int LcdEnPin =7;const int LcdPowerPin =8; // Activation de l'alimentation LCD et du rétroéclairageconst int T0OutputPin =9;const int lcdD4Pin =10;const int lcdD5Pin =11; // broches 11-13 également utilisées pour ICSPconst int LcdD6Pin =12;const int LcdD7Pin =13;// Définitions des broches analogiquesconst int receiverInputPin =0;const int encoderAPin =A1;const int encoderBpin =A2;// Broches analogiques 3-5 non utilisé// Variables utilisées uniquement par les bacs ISRint16_t[4] ; // bacs utilisés pour accumuler les lectures ADC, un pour chacun des 4 phasesuint16_t numSamples =0;const uint16_t numSamplesToAverage =1024;// Variables utilisées par l'ISR et en dehors des moyennes itvolatile int16_t[4] ; // lorsque nous avons accumulé suffisamment de lectures dans les bacs, l'ISR les copie ici et recommence.volatile uint32_t ticks =0; // compteur de ticks système pour l'heure volatile bool sampleReady =false; // indique que le tableau des moyennes a été mis à jour // Variables utilisées uniquement en dehors de l'ISRint16_t calib[4] ; // valeurs (définies lors de l'étalonnage) que nous soustrayons des moyennesvolatile uint8_t lastctr;volatile uint16_t misses =0; // cela compte le nombre de fois que l'ISR a été exécuté trop tard. Doit rester à zéro si tout fonctionne correctement.const double halfRoot2 =sqrt(0.5);const double quarterPi =3.1415927/4.0;const double radiansToDegrees =180.0/3.1415927;// L'échantillonnage et le maintien ADC se produisent 2 horloges ADC (=32 système horloges) une fois que l'indicateur de débordement de la minuterie 1 est défini.// Cela introduit une légère erreur de phase, que nous ajustons dans les calculs.const float phaseAdjust =(45.0 * 32.0)/(float)(TIMER1_TOP + 1);float seuil =5,0 ; // plus faible =plus grande sensibilité. 10 est à peu près utilisable avec une bobine bien équilibrée. // L'utilisateur pourra régler cela via un potentiomètre ou un encodeur rotatif.void setup(){ lcd.begin(16, 2);// LCD 16X2 pinMode(encoderButtonPin, INPUT_PULLUP); digitalWrite (T0OutputPin, LOW); pinMode (T0OutputPin, SORTIE); // broche d'impulsion de la minuterie 1 utilisée pour alimenter la minuterie 0 digitalWrite(coilDrivePin, LOW); pinMode (coilDrivePin, SORTIE); // sortie timer 0, onde carrée pour piloter la bobine de transmission cli(); // Arrêtez la minuterie 0 qui a été configurée par le noyau Arduino TCCR0B =0; // arrête le temporisateur TIMSK0 =0; // désactiver l'interruption TIFR0 =0x07; // effacer toute interruption en attente // Configurer l'ADC pour déclencher et lire le canal 0 sur le débordement du temporisateur 1#if USE_3V3_AREF ADMUX =(1 <> 8); OCR1AL =(TIMER1_TOP/2 &0xFF); ICR1H =(TIMER1_TOP>> 8); ICR1L =(TIMER1_TOP &0xFF); TCNT1H =0 ; TCNT1L =0 ; TIFR1 =0x07 ; // efface toute interruption en attente TIMSK1 =(1 <
 15000) *p =15000; } else { *p -=val; si (*p <-15000) *p =-15000; } if (ctr ==7) { ++numSamples; if (numSamples ==numSamplesToAverage) { numSamples =0; if (!sampleReady) // si l'échantillon précédent a été consommé { memcpy((void*)averages, bins, sizeof(averages)); sampleReady =vrai; } memset(bins, 0, sizeof(bins)); } }}boucle vide (){ while (!sampleReady) {} uint32_t oldTicks =ticks ; if (digitalRead(encoderButtonPin) ==LOW) { // Bouton d'étalonnage enfoncé. Nous sauvegardons les sorties actuelles du détecteur de phase et les soustrayons des résultats futurs. // Cela nous permet d'utiliser le détecteur si la bobine est légèrement déséquilibrée. // Il serait préférable de regrouper plusieurs échantillons au lieu d'en prendre un seul. for (int i =0; i <4; ++i) { calib[i] =moyennes[i]; } sampleReady =false; Serial.print("Calibré :"); lcd.setCursor(0,0); lcd.print("Calibrage... "); for (int i =0; i <4; ++i) { Serial.write(' '); Serial.print(calib[i]); lcd.setCursor(0,1) ; lcd.print(' '); lcd.print(calib[4]); lcd.print(" "); } Serial.println(); } else { for (int i =0; i <4; ++i) { moyennes[i] -=calib[i]; } const double f =200,0 ; // Massez les résultats pour éliminer la sensibilité à la 3e harmonique, et divisez par 200 double bin0 =(averages[0] + halfRoot2 * (averages[1] - averages[3]))/f; double bin1 =(moyennes[1] + halfRoot2 * (moyennes[0] + moyennes[2]))/f ; double bin2 =(moyennes[2] + halfRoot2 * (moyennes[1] + moyennes[3]))/f ; double bin3 =(moyennes[3] + halfRoot2 * (moyennes[2] - moyennes[0]))/f ; sampleReady =false; // nous avons fini de lire les moyennes, donc l'ISR est libre de les écraser à nouveau double amp1 =sqrt((bin0 * bin0) + (bin2 * bin2)); double amp2 =sqrt((bin1 * bin1) + (bin3 * bin3)); double ampAverage =(amp1 + amp2)/2.0 ; // L'échantillonnage/maintien ADC a lieu 2 horloges après le dépassement de la minuterie double phase1 =atan2(bin0, bin2) * radiansToDegrees + 45,0 ; double phase2 =atan2(bin1, bin3) * radiansToDegrees ; if (phase1> phase2) { double temp =phase1; phase1 =phase2 ; phase2 =temp; } double phaseAverage =((phase1 + phase2)/2.0) - phaseAdjust; if (phase2 - phase1> 180.0) { if (phaseAverage <0.0) { phaseAverage +=180.0; } else { phaseMoyenne -=180,0; } } // À des fins de diagnostic, imprime le nombre de casiers individuels et les 2 gains et phases calculés indépendamment Serial.print(misses); Serial.write(' '); if (bin0>=0.0) Serial.write(' '); Serial.print(bin0, 2); Serial.write(' '); if (bin1>=0.0) Serial.write(' '); Serial.print(bin1, 2); Serial.write(' '); if (bin2>=0.0) Serial.write(' '); Serial.print(bin2, 2); Serial.write(' '); if (bin3>=0.0) Serial.write(' '); Serial.print(bin3, 2); Serial.print(" "); Serial.print(amp1, 2); Serial.write(' '); Serial.print(amp2, 2); Serial.write(' '); if (phase1>=0.0) Serial.write(' '); Serial.print(phase1, 2); Serial.write(' '); if (phase2>=0.0) Serial.write(' '); Serial.print(phase2, 2); Serial.print(" "); // Affiche l'amplitude et la phase finales, que nous utilisons pour décider ce que nous avons trouvé (le cas échéant) if (ampAverage>=0.0) Serial.write(' '); Serial.print(ampMoyenne, 1); Serial.write(' '); lcd.setCursor(0,0); lcd.print(" "); lcd.print(ampMoyenne); lcd.setCursor(0,1) ; lbg.drawValue(ampAverage, max_ampAverage); if (phaseAverage>=0.0) Serial.write(' '); Serial.print((int)phaseAverage); // Décidez de ce que nous avons trouvé et dites à l'utilisateur si (ampAverage>=seuil) { // Lorsqu'il est maintenu aligné avec le centre de la bobine :// - les métaux non ferreux donnent un déphasage négatif, par ex. -90deg pour le cuivre ou l'aluminium épais, une olive en cuivre, -30deg pour l'aluminium fin. // Les métaux ferreux donnent un déphasage nul ou un petit déphasage positif. // Nous dirons donc que tout ce qui a un déphasage inférieur à -20 degrés est non ferreux. if (phaseAverage <-20.0) { Serial.print (" Non ferreux "); lcd.setCursor(0,0); lcd.print("Non ferreux "); } else { Serial.print(" Ferreux"); lcd.setCursor(0,0); lcd.print("Ferreux "); } float temp =ampAverage; int thisPitch =map (temp, 10, 200, 100, 1500); ton (3, thisPitch, 120); while (temp>
 seuil) { Serial.write('!'); temp -=(seuil/2); } } Serial.println(); } while (ticks - oldTicks <8000) { } }
LcdBarGraph lib.C/C++
Aucun aperçu (téléchargement uniquement).

Schémas


Processus de fabrication

  1. Détecteur de pleurs de bébé bricolage facile avec Raspberry Pi
  2. horloge IV9 Numitron DIY la plus simple avec Arduino
  3. Jeu de gyroscope Arduino avec MPU-6050
  4. Détecteur de tremblement de terre ADXL335 bricolage sensible
  5. Voltmètre DIY avec Arduino et un écran Nokia 5110
  6. MobBob :Robot Arduino DIY contrôlé par smartphone Android
  7. Roue de mesure simple bricolage avec encodeur rotatif
  8. Jauge IoT avec Arduino, Yaler et IFTTT
  9. Moniteur de qualité de l'air DIY avec capteur Sharp GP2Y1010AU0F