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

Serrure de porte à clavier Arduino avec code utilisateur personnalisable

Composants et fournitures

Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Arduino UNO
× 1
Clavier matriciel 4x4
× 1
Bouton poussoir générique
× 1
LCD I²C
× 1
Serrure à solénoïde linéaire
× 1
MOSFET IRF510N
× 1
Relais 1 canal
× 1

Outils et machines nécessaires

Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Platine d'essai, 170 broches
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Kit 10 fils de câblage, 5 cm de long

À propos de ce projet

Salut, et bienvenue dans ce tutoriel (oui, il est vieux mais classique), aujourd'hui je réalise un projet de serrure de porte basé sur une carte Arduino, un clavier, un écran LCD I²C, et j'utiliserai pour la serrure un solénoïde et un relais. Vous pouvez consulter mon tutoriel sur la serrure à empreinte digitale où j'ai utilisé une serrure qui utilise un moteur DC, donc selon votre système de verrouillage, vous devrez choisir un câblage, des codes et les adapter.

N.B : Pour un vrai projet, je ne recommande pas d'utiliser un solénoïde du tout, mais plutôt de pirater une serrure qui peut être ouverte à la fois électroniquement et mécaniquement et d'adapter votre projet pour elle.

Pièces

Pour ce projet, nous aurons besoin de ces composants, ainsi que de quelques fils de câblage et d'une alimentation 12 V (désolé, je ne l'ai pas ajoutée ici) :

Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable

Le bouton poussoir est destiné à ouvrir la serrure depuis l'intérieur, vous pouvez l'enlever si vous voulez. La résistance est pour l'anti-rebond.

J'ai utilisé un clavier 4×4, vous pouvez utiliser un 3×4 mais vous devrez modifier certaines choses dans le code, comme pour la confirmation j'utilise 'A', vous pouvez le changer en '*' ou '#'.

Le solénoïde est alimenté par une alimentation externe 12 V, et piloté par le transistor MOSFET IRF510N.

Le transistor est utilisé comme un interrupteur et il est préférable d'utiliser un canal N. L'IRF510N est assez populaire quand il est utilisé avec un Arduino. Quand vous appliquez une tension de 5 V entre la Grille et la Source, le transistor devient comme un interrupteur fermé entre le Drain et la Source, et il n'a pas besoin de résistance comme les bipolaires.

Et s'il n'y a pas de tension appliquée, le transistor agit comme un interrupteur ouvert, et c'est ainsi que nous contrôlons le solénoïde.

Pour l'autre exemple, j'utilise un module relais 1 canal, il fonctionne avec 3,3 V, et nous contrôlons son entrée comme pour le transistor, la seule différence est qu'ils sont inversés (nous le verrons dans le code).

Diagramme de flux de l'algorithme

Pour rendre les choses faciles à comprendre, voici le diagramme de flux, il n'est pas complètement détaillé mais c'est une vue d'ensemble du code.

Serrure de porte à clavier Arduino avec code utilisateur personnalisable

N.B : Vous pouvez utiliser le relais pour contrôler n'importe quelle serrure électrique jusqu'à 250 VAC, vous pouvez aussi l'utiliser pour contrôler le solénoïde…

Les codes sont exactement les mêmes, la seule chose est que vous inversez entre (LOW et HIGH) pour ouvrir la serrure.

Rappelez-vous : la première fois, vous devez téléverser le code et changer le code d'accès, puis décommenter certaines lignes (lisez le code pour les trouver (elles sont dans setup)) et re-téléverser le code pour qu'il puisse lire le code d'accès depuis l'EEPROM. ÇA NE SE FAIT QU'UNE SEULE FOIS.

Vous pouvez aussi changer la longueur du code. Au début, je l'ai fait à 4 chiffres, vous pouvez le changer depuis le code par défaut, car j'ai utilisé dans le code « sizeof(code) » au lieu de « 4 ». Vous ne pouvez pas changer un code à 4 chiffres en un code à 6 chiffres, changez d'abord le code d'accès initial dans le code source.

Test

Vous trouverez le test dans les images ci-dessous, naviguez à travers elles

Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable
Serrure de porte à clavier Arduino avec code utilisateur personnalisable

Voilà pour le test du projet, c'est le même pour le solénoïde ou le relais, et le bouton poussoir ouvre de l'intérieur si vous voulez ou vous pouvez l'enlever.

J'espère que c'est utile et si vous avez un problème ou une question, laissez un commentaire.

Code

Keypad_doorlock_solenoid.inoArduino

N'oubliez pas de téléverser le code d'abord, puis décommenter les lignes 62 à 64 et re-téléverser, c'est fait une seule fois.

/* Ce code fonctionne avec clavier matriciel 4x4, LCD I2C, transistor IRF510N et un bouton poussoir
* C'est une serrure où le transistor pilote un solénoïde, vous pouvez l'ouvrir soit avec le bon code
* soit par le bouton poussoir de l'intérieur
* Le code peut être changé directement par le clavier et ne nécessite pas de re-téléverser le code
* Le code est stocké dans l'EEPROM
* Référez-vous à www.surtrtech.com pour plus de détails */
#include <Keypad.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#define Solenoid 11 // En fait la Grille du transistor qui contrôle le solénoïde
#define O_Button 10 // Bouton poussoir
#define I2C_ADDR 0x27 // Adresse I2C, vous devriez utiliser le code pour scanner l'adresse d'abord (0x27) ici
#define BACKLIGHT_PIN 3 // Déclaration des broches LCD
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
const byte numRows= 4; // nombre de lignes sur le clavier
const byte numCols= 4; // nombre de colonnes sur le clavier
char keymap[numRows][numCols]= {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
char keypressed; // Où les touches sont stockées, ça change très souvent
char code[]= {'6','6','0','1'}; // Le code par défaut, vous pouvez le changer ou en faire un à 'n' chiffres
char code_buff1[sizeof(code)]; // Où la nouvelle clé est stockée
char code_buff2[sizeof(code)]; // Où la nouvelle clé est stockée à nouveau pour la comparer à la précédente
short a=0,i=0,s=0,j=0; // Variables utilisées plus tard
byte rowPins[numRows] = {9,8,7,6}; // Lignes 0 à 3
// si vous modifiez vos broches, vous devriez modifier ceci aussi
byte colPins[numCols]= {5,4,3,2}; // Colonnes 0 à 3
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup() {
  lcd.begin (16,2);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH); // Allumage du rétroéclairage
  lcd.home ();
  lcd.print("Standby"); // Ce qui est écrit sur le LCD, vous pouvez changer
  pinMode(Solenoid,OUTPUT);
  pinMode(O_Button,INPUT);
  // for(i=0 ; i<sizeof(code);i++){
  // Quand vous téléversez le code la première fois, gardez-le commenté
  // EEPROM.get(i, code[i]); // Téléversez le code et changez-le pour le stocker dans l'EEPROM
  // }
  // Ensuite décommentez cette boucle for et re-téléversez le code (C'est fait une seule fois)
}

void loop() {
  keypressed = myKeypad.getKey(); // Attend constamment qu'une touche soit pressée
  if(keypressed == '*'){
    // * pour ouvrir la serrure
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Enter code"); // Message à afficher
    GetCode(); // Fonction d'obtention du code
    if(a==sizeof(code)) // La fonction GetCode assigne une valeur à a (c'est correct quand elle a la taille du tableau code)
      OpenDoor(); // Fonction d'ouverture si le code est correct
    else{
      lcd.clear();
      lcd.print("Wrong"); // Message à afficher quand le code est faux
    }
    delay(2000);
    lcd.clear();
    lcd.print("Standby"); // Retour au mode veille, c'est le message à afficher en attente
  }
  if(keypressed == '#'){
    // Pour changer le code, appelle la fonction changecode
    ChangeCode();
    lcd.clear();
    lcd.print("Standby"); // Quand c'est fini, retour au mode veille
  }
  if(digitalRead(O_Button)==HIGH){
    // Ouverture par le bouton poussoir
    digitalWrite(Solenoid,HIGH);
    delay(3000); // Ouvre pendant 3s, vous pouvez changer
    digitalWrite(Solenoid,LOW);
  }
}

void GetCode(){
  // Séquence d'obtention du code
  i=0; // Toutes les variables à 0
  a=0;
  j=0;
  while(keypressed != 'A'){
    // L'utilisateur appuie sur A pour confirmer le code sinon il peut continuer à taper
    keypressed = myKeypad.getKey();
    if(keypressed != NO_KEY && keypressed != 'A' ){
      // Si le caractère tapé n'est pas A et n'est pas "rien"
      lcd.setCursor(j,1); // Ceci pour écrire "*" sur le LCD quand une touche est pressée, sa position est contrôlée par j
      lcd.print("*");
      j++;
      if(keypressed == code[i] && i<sizeof(code)){
        // si le caractère tapé est correct, a et i s'incrémentent pour vérifier le caractère suivant
        a++; // Maintenant je pense que j'aurais dû utiliser seulement a ou i ... trop paresseux pour tester -_-'
        i++;
      } else a--; // si le caractère tapé est faux, a décrémente et ne peut pas égaler la taille de code []
    }
  }
  keypressed = NO_KEY;
}

void ChangeCode(){
  // Séquence de changement de code
  lcd.clear();
  lcd.print("Changing code");
  delay(1000);
  lcd.clear();
  lcd.print("Enter old code");
  GetCode(); // Vérifie l'ancien code d'abord pour pouvoir le changer
  if(a==sizeof(code)){
    // encore vérification de la valeur a
    lcd.clear();
    lcd.print("Changing code");
    GetNewCode1(); // Obtient le nouveau code
    GetNewCode2(); // Obtient le nouveau code à nouveau pour le confirmer
    s=0;
    for(i=0 ; i<sizeof(code) ; i++){
      // Compare les codes dans le tableau 1 et le tableau 2 des deux fonctions précédentes
      if(code_buff1[i]==code_buff2[i]) s++; // encore c'est comme ça qu'on vérifie, incrémente s quand les codes correspondent
    }
    if(s==sizeof(code)){
      // Correct est toujours la taille du tableau
      for(i=0 ; i<sizeof(code) ; i++){
        code[i]=code_buff2[i]; // le tableau code reçoit maintenant le nouveau code
        EEPROM.put(i, code[i]); // Et le stocke dans l'EEPROM
      }
      lcd.clear();
      lcd.print("Code Changed");
      delay(2000);
    } else{
      // Au cas où les nouveaux codes ne correspondent pas
      lcd.clear();
      lcd.print("Codes are not");
      lcd.setCursor(0,1);
      lcd.print("matching !!");
      delay(2000);
    }
  } else{
    // Au cas où l'ancien code est faux, vous ne pouvez pas le changer
    lcd.clear();
    lcd.print("Wrong");
    delay(2000);
  }
}

void GetNewCode1(){
  i=0;
  j=0;
  lcd.clear();
  lcd.print("Enter new code"); // dit à l'utilisateur d'entrer le nouveau code et d'appuyer sur A
  lcd.setCursor(0,1);
  lcd.print("and press A");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("and press A"); // Appuyer sur A continue d'afficher pendant que la ligne du haut affiche ***
  while(keypressed != 'A'){
    // A pour confirmer et quitter la boucle
    keypressed = myKeypad.getKey();
    if(keypressed != NO_KEY && keypressed != 'A' ){
      lcd.setCursor(j,0);
      lcd.print("*"); // Sur le nouveau code, vous pouvez afficher * comme je l'ai fait ou le changer en keypressed pour afficher les touches
      code_buff1[i]=keypressed; // Stocke les caractères dans le tableau
      i++;
      j++;
    }
  }
  keypressed = NO_KEY;
}

void GetNewCode2(){
  // C'est exactement comme la fonction GetNewCode1 mais cette fois le code est stocké dans un autre tableau
  i=0;
  j=0;
  lcd.clear();
  lcd.print("Confirm code");
  lcd.setCursor(0,1);
  lcd.print("and press A");
  delay(3000);
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("and press A");
  while(keypressed != 'A'){
    keypressed = myKeypad.getKey();
    if(keypressed != NO_KEY && keypressed != 'A' ){
      lcd.setCursor(j,0);
      lcd.print("*");
      code_buff2[i]=keypressed;
      i++;
      j++;
    }
  }
  keypressed = NO_KEY;
}

void OpenDoor(){
  // Fonction d'ouverture de la serrure, ouverte pendant 3s
  lcd.clear();
  lcd.print("Welcome"); // Avec un message affiché
  digitalWrite(Solenoid,HIGH);
  delay(3000);
  digitalWrite(Solenoid,LOW);
}
Keypad_doorlock_relay.inoArduino

N'oubliez pas de téléverser le code d'abord, puis décommenter les lignes 62 à 64 et re-téléverser, c'est fait une seule fois.

/* Ce code fonctionne avec clavier matriciel 4x4, LCD I2C, module relais et un bouton poussoir
* C'est une serrure où le relais peut contrôler une serrure, vous pouvez l'ouvrir soit avec le bon code
* soit par le bouton poussoir de l'intérieur
* Le code peut être changé directement par le clavier et ne nécessite pas de re-téléverser le code
* Le code est stocké dans l'EEPROM
* Référez-vous à www.surtrtech.com pour plus de détails */
#include <Keypad.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#define Relay 11 // Contrôle le Relais
#define O_Button 10 // Bouton poussoir
#define I2C_ADDR 0x27 // Adresse I2C, vous devriez utiliser le code pour scanner l'adresse d'abord (0x27) ici
#define BACKLIGHT_PIN 3 // Déclaration des broches LCD
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
const byte numRows= 4; // nombre de lignes sur le clavier
const byte numCols= 4; // nombre de colonnes sur le clavier
char keymap[numRows][numCols]= {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
char keypressed; // Où les touches sont stockées, ça change très souvent
char code[]= {'6','6','0','1'}; // Le code par défaut, vous pouvez le changer ou en faire un à 'n' chiffres
char code_buff1[sizeof(code)]; // Où la nouvelle clé est stockée
char code_buff2[sizeof(code)]; // Où la nouvelle clé est stockée à nouveau pour la comparer à la précédente
short a=0,i=0,s=0,j=0; // Variables utilisées plus tard
byte rowPins[numRows] = {9,8,7,6}; // Lignes 0 à 3
// si vous modifiez vos broches, vous devriez modifier ceci aussi
byte colPins[numCols]= {5,4,3,2}; // Colonnes 0 à 3
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup() {
  lcd.begin (16,2);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH); // Allumage du rétroéclairage
  lcd.home ();
  lcd.print("Standby"); // Ce qui est écrit sur le LCD, vous pouvez changer
  pinMode(Relay,OUTPUT);
  pinMode(O_Button,INPUT);
  // for(i=0 ; i<sizeof(code);i++){
  // Quand vous téléversez le code la première fois, gardez-le commenté
  // EEPROM.get(i, code[i]); // Téléversez le code et changez-le pour le stocker dans l'EEPROM
  // }
  // Ensuite décommentez cette boucle for et re-téléversez le code (C'est fait une seule fois)
}

void loop() {
  keypressed = myKeypad.getKey(); // Attend constamment qu'une touche soit pressée
  if(keypressed == '*'){
    // * pour ouvrir la serrure
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Enter code"); // Message à afficher
    GetCode(); // Fonction d'obtention du code
    if(a==sizeof(code)) // La fonction GetCode assigne une valeur à a (c'est correct quand elle a la taille du tableau code)
      OpenDoor(); // Fonction d'ouverture si le code est correct
    else{
      lcd.clear();
      lcd.print("Wrong"); // Message à afficher quand le code est faux
    }
    delay(2000);
    lcd.clear();
    lcd.print("Standby"); // Retour au mode veille, c'est le message à afficher en attente
  }
  if(keypressed == '#'){
    // Pour changer le code, appelle la fonction changecode
    ChangeCode();
    lcd.clear();
    lcd.print("Standby"); // Quand c'est fini, retour au mode veille
  }
  if(digitalRead(O_Button)==HIGH){
    // Ouverture par le bouton poussoir
    digitalWrite(Relay,LOW);
    delay(3000); // Ouvre pendant 3s, vous pouvez changer
    digitalWrite(Relay,HIGH);
  }
}

void GetCode(){
  // Séquence d'obtention du code
  i=0; // Toutes les variables à 0
  a=0;
  j=0;
  while(keypressed != 'A'){
    // L'utilisateur appuie sur A pour confirmer le code sinon il peut continuer à taper
    keypressed = myKeypad.getKey();
    if(keypressed != NO_KEY && keypressed != 'A' ){
      // Si le caractère tapé n'est pas A et n'est pas "rien"
      lcd.setCursor(j,1); // Ceci pour écrire "*" sur le LCD quand une touche est pressée, sa position est contrôlée par j
      lcd.print("*");
      j++;
      if(keypressed == code[i] && i<sizeof(code)){
        // si le caractère tapé est correct, a et i s'incrémentent pour vérifier le caractère suivant
        a++; // Maintenant je pense que j'aurais dû utiliser seulement a ou i ... trop paresseux pour tester -_-'
        i++;
      } else a--; // si le caractère tapé est faux, a décrémente et ne peut pas égaler la taille de code []
    }
  }
  keypressed = NO_KEY;
}

void ChangeCode(){
  // Séquence de changement de code
  lcd.clear();
  lcd.print("Changing code");
  delay(1000);
  lcd.clear();
  lcd.print("Enter old code");
  GetCode(); // Vérifie l'ancien code d'abord pour pouvoir le changer
  if(a==sizeof(code)){
    // encore vérification de la valeur a
    lcd.clear();
    lcd.print("Changing code");
    GetNewCode1(); // Obtient le nouveau code
    GetNewCode2(); // Obtient le nouveau code à nouveau pour le confirmer
    s=0;
    for(i=0 ; i<sizeof(code) ; i++){
      // Compare les codes dans le tableau 1 et le tableau 2 des deux fonctions précédentes
      if(code_buff1[i]==code_buff2[i]) s++; // encore c'est comme ça qu'on vérifie, incrémente s quand les codes correspondent
    }
    if(s==sizeof(code)){
      // Correct est toujours la taille du tableau
      for(i=0 ; i<sizeof(code) ; i++){
        code[i]=code_buff2[i]; // le tableau code reçoit maintenant le nouveau code
        EEPROM.put(i, code[i]); // Et le stocke dans l'EEPROM
      }
      lcd.clear();
      lcd.print("Code Changed");
      delay(2000);
    } else{
      // Au cas où les nouveaux codes ne correspondent pas
      lcd.clear();
      lcd.print("Codes are not");
      lcd.setCursor(0,1);
      lcd.print("matching !!");
      delay(2000);
    }
  } else{
    // Au cas où l'ancien code est faux, vous ne pouvez pas le changer
    lcd.clear();
    lcd.print("Wrong");
    delay(2000);
  }
}

void GetNewCode1(){
  i=0;
  j=0;
  lcd.clear();
  lcd.print("Enter new code"); // dit à l'utilisateur d'entrer le nouveau code et d'appuyer sur A
  lcd.setCursor(0,1);
  lcd.print("and press A");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("and press A"); // Appuyer sur A continue d'afficher pendant que la ligne du haut affiche ***
  while(keypressed != 'A'){
    // A pour confirmer et quitter la boucle
    keypressed = myKeypad.getKey();
    if(keypressed != NO_KEY && keypressed != 'A' ){
      lcd.setCursor(j,0);
      lcd.print("*"); // Sur le nouveau code, vous pouvez afficher * comme je l'ai fait ou le changer en keypressed pour afficher les touches
      code_buff1[i]=keypressed; // Stocke les caractères dans le tableau
      i++;
      j++;
    }
  }
  keypressed = NO_KEY;
}

void GetNewCode2(){
  // C'est exactement comme la fonction GetNewCode1 mais cette fois le code est stocké dans un autre tableau
  i=0;
  j=0;
  lcd.clear();
  lcd.print("Confirm code");
  lcd.setCursor(0,1);
  lcd.print("and press A");
  delay(3000);
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("and press A");
  while(keypressed != 'A'){
    keypressed = myKeypad.getKey();
    if(keypressed != NO_KEY && keypressed != 'A' ){
      lcd.setCursor(j,0);
      lcd.print("*");
      code_buff2[i]=keypressed;
      i++;
      j++;
    }
  }
  keypressed = NO_KEY;
}

void OpenDoor(){
  // Fonction d'ouverture de la serrure, ouverte pendant 3s
  lcd.clear();
  lcd.print("Welcome"); // Avec un message affiché
  digitalWrite(Relay,LOW);
  delay(3000);
  digitalWrite(Relay,HIGH);
}

Schémas

Serrure de porte à clavier Arduino avec code utilisateur personnalisable Serrure de porte à clavier Arduino avec code utilisateur personnalisable

Processus de fabrication

  1. À l'intérieur des coffres-forts bancaires : histoire, conception et avenir de la sécurité
  2. Construire une porte à verrouillage automatique intelligente via la proximité Bluetooth de votre smartphone
  3. Système de Capteur de Température Multi-Position pour Intégration Domotique
  4. MotionSense : Détection d'intrusion intelligente avec Arduino et ESP8266
  5. Prévention incendie imprimante 3D : Système de sécurité à capteur intelligent
  6. Serrure de porte sécurisée par mot de passe avec Arduino, clavier et actionneur linéaire
  7. Créer une jauge IoT connectée au Web avec Arduino, Yaler et IFTTT
  8. Lévitation magnétique répulsive avec Arduino : circuit simple et guide DIY
  9. CoroFence : Détecteur Thermique Avancé PIR + Capteur Grid-EYE & IoT