fbpixel
Utilisation d’un Shield WiFi avec Arduino

Utilisation d’un Shield WiFi avec Arduino

Le Shield WiFi permet à la carte Arduino de se connecter à internet en passant par un réseau local sans fil. Il intègre un lecteur de carte SD qui permet de stocker des données ou encore une page web pour piloter l’Arduino.
La base, pour créer des objets connectés, est de les connecter à un réseau comme le réseau WiFi.

Matériel

  • Ordinateur
  • Arduino UNO
  • Câble USB A Mâle/B Mâle
  • Arduino WiFi Shield

Principe de fonctionnement d’un Shield Wifi

Le réseau WiFi est un réseau Radio qui travaille sur les fréquences 2,45 GHz et 5 GHz. Le Shield Wifi possède une puce qui permet de gérer la communication wifi avec un réseau, comme sur un ordinateur. Le microcontrôleur peut communiquer avec cette puce pour se connecter à un réseau ou transmettre des information via ce réseau.

Schéma

Le shield Wifi se monte directement sur la carte Arduino et utilise le bus SPI pour communiquer avec le WiFI et la carte SD. La broche 10 est utilisé pour sélectionner le contrôleur WiFi, la broche 7 comme handshake entre l’Arduino et le WiFi; et la broche 4 pour sélectionner le module de carte SD.
En résumé, les broches utilisées sont:

  • 4 pour la sélection de la carte SD (SD_CS)
  • 7 pour le handshake avec le WiFi
  • 10 pour la sélection de la micropuce W5100 (W5100_CS)
  • le bus SPI : broches 11,12,13 sur une carte Arduino UNO/Duelmilanove. Les broches 50, 51 et 52 pour la Mega

Code de gestion d’un Shield Wifi

Pour communiquer sur le réseau, il nous faut utiliser un protocole particulier. Ce protocole est intégré dans toutes les librairies relatives à la communication WiFi.

  • Il faut connecter le module WiFi au réseau
  • définir un serveur server
  • définir un client client

Pour interagir avec le Shield Wifi, nous utilisons la librairie WiFi.h dont les fonctions à connaître sont les suivantes:

  • WiFi.begin() pour initialiser une connexion réseau
  • server.begin() pour initialiser un serveur
  • WiFiClient client = server.available() pour initialiser un client
  • client.read() pour lire des données provenant du client
  • client.print() pour envoyer des données au client
//Libraries
#include <WiFi.h>//https://www.arduino.cc/en/Reference/WiFi

//Parameters
String request ;
unsigned long refreshCounter  = 0;
int status  = WL_IDLE_STATUS;
char ssid[]  = "****************";
char password[]  = "****************";

//Objects
WiFiServer server(80);
WiFiClient client;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init WifiShield

  // Connect to Wifi network.
  while (status != WL_CONNECTED)
  {
    Serial.print("Connecting to Network named: "); Serial.println(ssid);
    status = WiFi.begin(ssid, password);
    delay(1000);
  }
  server.begin();
  Serial.println();
  Serial.println(F("WifiShield initialized"));
  Serial.print(F("IP Address: "));
  Serial.println(WiFi.localIP());
}

void loop() {
  client = server.available();
  clientRequest();
  handleRequest();
}

void clientRequest( ) { /* function clientRequest */
  ////Get client request
  if (!client) {
    return;
  }
  request = "";
  // Wait until the client sends some data
  while (!client.available()) {
    delay(1);
  }

  request = client.readStringUntil('\r'); // Read the first line of the request
  Serial.println(request);
  client.flush();
}

void handleRequest( ) { /* function handleRequest */
  ////Handle web client request
  if (request.indexOf("/dig2on") > 0) {
    digitalWrite(2, HIGH);
  }
  if (request.indexOf("/dig2off") > 0) {
    digitalWrite(2, LOW);
  }
  if (request.indexOf("GET") >= 0) {
    webpage(client);
    client.stop();
  }

}

void webpage(WiFiClient client) { /* function webpage */
  ////Send webpage to client

  //output HTML data header
  client.println(F("HTTP/1.1 200 OK\nContent-Type: text/html\nConnection: close\nRefresh: 5
\n"));
  //header
  client.println(F("<!DOCTYPE HTML><html><head><title>AranaCorp</title></head><body bgcolor='black' style='color:white;'>"));
  client.println(F("<h1 style='color:green;'>AranaCorp - Arduino Web Controller</h1>"));
  client.println("<p style='color:white;'>Page refresh number: " + String(refreshCounter) + "</p>");
  client.println(F("<h2 style='color:limegreen;'>Arduino Inputs</h2>"));
  //output analog input pin
  for (int i = 0; i < 6; i++) {
    client.println("<b>Input A" + String(i) + " : </b>" + String(analogRead(14 + i)) + "<br>");
  }
  //digital output
  client.println("<h2 style='color:limegreen;'>Arduino Outputs</h2>");
  client.println("<b>Digital output Pin 2 : </b><input value=" + String(digitalRead(2)) + " readonly></input>");
  client.println(F("<a href='/dig2on'><button>Turn On </button></a><a href='/dig2off'><button>Turn Off </button></a>"));

  //file end
  client.println("</body></html>");
  refreshCounter+=1;
  delay(1);
}

Résultat

Lorsque le code est téléchargé sur le microcontrôleur, ouvrez le moniteur série pour connaitre l’adresse IP.

Vous pouvez ensuite rentrer cette adresse IP dans votre navigateur internet afin que la page web s’affiche.

Applications

  • Utiliser une interface web pour piloter votre microcontrôleur

Sources

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

Utilisation d’un Shield LCD 16×2 avec Arduino

Utilisation d’un Shield LCD 16×2 avec Arduino

Un des éléments permettant d’afficher des informations les plus utilisés dans le monde Arduino est l’écran à cristaux liquide (Liquid Crystal Display) LCD 16×2. Lorsque l’on fabrique un système électronique, il peut être intéressant que celui-ci nous donne quelques informations sur son état sans avoir à le brancher à un ordinateur ou à le connecter à un autre système comme un smartphone. L’écran LCD 16×02 est fournit avec un grand nombre de kit Arduino et est très suffisant pour un grand nombre d’application.
L’écran LCD 16×2 peut être trouvé monté sur un Shield avec en bonus quelques boutons afin de créer des interfaces programmables simples permettant d’afficher des valeurs et de piloter votre projet Arduino. Tout cela en facilitant grandement le montage.

Matériel

  • Ordinateur
  • Arduino UNO
  • Câble USB A Mâle/B Mâle
  • LCD Shield

Principe de fonctionnement

Les afficheurs à cristaux liquides utilisent la propriété de modulation de lumière des cristaux liquides. Les écrans à cristaux liquides sont composés de deux couches de polariseurs, avec des directions de polarisation perpendiculaire, prenant en sandwich deux plaques de verres entre lesquelles sont placés les cristaux liquides. Sur les plaques de verre se trouve une matrice d’électrodes pour chaque pixel. Une tension appliquée entre les électrodes d’un pixel entraine un changement d’orientation des molécules et donc la transparence du pixel qui peut alors laisser, ou non, passer la lumière du rétroéclairage

Schéma

Le shield LCD est compatible avec les cartes Arduino UNO et Mega et se place directement sur la carte.
En résumé, les broches utilisées sont:

  • A0 pour la lecture des boutons
  • les broches 8, 9, 4, 5, 6, 7 pour la gestion de l’écran LCD

Le bouton RST est directement relié au bouton reset de la carte Arduino.  

Code

Une fois votre module correctement branché, vous pouvez modifier le code suivant pour obtenir la fonctionnalité désirée. Dans l’exemple suivant, nous définissons une fonction qui va venir lire la valeur des boutons et exécuter une action en fonction du bouton pressé.
Pour chaque bouton pressé, le nom et la valeur du bouton sont affichés. Il se peut que votre shield soit différent selon le fournisseur et la version. Si c’est le cas, ce code vous permettra de modifier facilement les valeurs de détections des boutons.

Pour gérer l’écran LCD 16×2 dans le programme, la librairie utilisée est LiquidCrystal.h dont les fonctions à connaître sont les suivantes:

  • LiquidCrystal lcd(rs, en, d4, d5, d6, d7) pour définir la communication 4bits
  • lcd.begin(16, 2); pour initialiser l’écran
  • lcd.print() pour afficher une chaine de caractères en ASCII
  • lcd.write() pour afficher des données, un octet à la fois.
  • lcd.setCursor(x, y) pour placer le curseur (colonne x: 0-16, ligne y:0-2)
  • lcd.clear() effacer ce qui est affiché à l’écran
//Libraries
#include <LiquidCrystal.h>//https://arduino.cc/en/Reference/LiquidCrystal

//Parameters
const int btnsPin  = A0;
int btnsVal  = 0;

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

//Enums
enum {
  BUTTON_NONE,
  BUTTON_UP,
  BUTTON_DOWN,
  BUTTON_LEFT,
  BUTTON_RIGHT,
  BUTTON_SELECT,
};

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init LCD16x2 Shield
  lcd.begin(16, 2);
  lcd.print(F("Hello World "));
  delay(2000);
  lcd.clear();
  lcd.print(F("Button pressed: "));
}

void loop() {
  btnListener(getBtnPressed());
}

void btnListener(byte btnStatus) { /* function btnListener */
  //// Get button value when pressed
  lcd.setCursor(0, 1);
  switch (btnStatus) {
    case BUTTON_UP:
      lcd.print(F("UP     "));
      lcd.print(btnsVal);
      break;

    case BUTTON_DOWN:
      lcd.print(F("DOWN   "));
      lcd.print(btnsVal);
      lcd.print("   ");
      break;

    case BUTTON_LEFT:
      lcd.print(F("LEFT   "));
      lcd.print(btnsVal);
      lcd.print("   ");
      break;

    case BUTTON_RIGHT:
      lcd.print(F("RIGHT  "));
      lcd.print(btnsVal);
      lcd.print("   ");
      break;

    case BUTTON_SELECT:
      lcd.print(F("SELECT "));
      lcd.print(btnsVal);
      lcd.print("   ");
      break;

    default://case BUTTON_NONE:
      //lcd.print(F("       "));
      break;
  }
  delay(100);
}

byte getBtnPressed() { /* function getBtnPressed */
  //// Get button value when pressed
  btnsVal = analogRead(btnsPin);
  if (btnsVal < 50)
    return BUTTON_RIGHT;
  else if (btnsVal < 250)
    return BUTTON_UP;
  else if (btnsVal < 350)
    return BUTTON_DOWN;
  else if (btnsVal < 450)
    return BUTTON_LEFT;
  else if (btnsVal < 650)
    return BUTTON_SELECT;
  else
    return BUTTON_NONE;
}

Applications

  • Créer une interface simple pour votre projet Arduino

Sources

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

Utilisation d’un Shield TFT LCD avec Arduino

Utilisation d’un Shield TFT LCD avec Arduino

Les Shields TFT sont des écrans LCD tactiles permettant d’afficher des images et de créer des interfaces utilisateurs, avec des graphismes plus ou moins complexes, pour piloter les microcontrôleurs Arduino. Dans ce tutoriel, nous utilisons le shield Kuman TFT 3.5″ (très proche du shield 2.8″) mais ce tutoriel peut être appliqué à d’autre Shield ou module LCD. Vérifiez bien les broches utilisées et la compatibilité de la librairie.

Matériel

  • Ordinateur
  • Arduino UNO ou Mega
  • Câble USB A Mâle/B Mâle
  • TFT LCD Shield
  • Carte SD

Principe de fonctionnement

Le shield TFT est muni d’un écran LCD tactile permettant d’afficher des images en couleurs et de créer des interfaces avec des courbes et des boutons, pour interagir et visualiser des données provenant de l’Arduino. Il est aussi muni d’un lecteur de carte micro SD qui peut servir à sauvegarder des images ou autres données.

N.B.: Même si le shield est compatible avec Arduino Mega et que l’écran fonctionne, le module SD ne fonctionne pas directement avec une carte Arduino Mega.

Schéma

Le shield TFT se place directement sur une carte Arduino UNO ou Mega. Le shield utilise quasiment toutes les broches de l’Arduino UNO. Assurez-vous de ne pas utiliser les mêmes pour d’autres modules.
A titre d’information les broches disponibles sont:

  • broche analogique A5
  • broche digitale 0
  • broche digitale 1


Si vous n’utilisez pas la fonctionnalité tactile de l’écran, vous pouvez aussi utiliser les broches: A1, A2, 6 et 7.
Si vous utilisez un autre Shield ou module LCD vérifiez bien les broches utilisées (pinout).

Calibration du TouchScreen

Tous les écrans sont différents pour pouvoir les utiliser correctement, il faut récupérer les bonnes valeurs de dimensions afin d’adapter l’affichage et la détection de pression. Pour cela, vous pouvez charger le code TouchScreen_Calibr_native.ino, présent dans les exemples de la librairie MCUFRIEND_kbv.h.

Une fois, le code chargé il va vous être demandé d’utiliser le stylet pour appuyer, maintenir et relacher à différents endroits de l’écran afin de le calibrer. Une fois cette opération effectuée, les paramètres de configuration s’affiche sur le moniteur série et sur l’écran.

Voici les résultats pour l’écran 3.5″ TFT LCD Shield

//3.5 Calibration
const int XP = 8, XM = A2, YP = A3, YM = 9; //320x480 ID=0x9486
const int TS_LEFT = 144, TS_RT = 887, TS_TOP = 936, TS_BOT = 87;

Voici les résultats pour l’écran 2.8″ TFT LCD Shield

//2.8 Calibration
const int XP=8,XM=A2,YP=A3,YM=9; //240x320 ID=0x9341
const int TS_LEFT=907,TS_RT=120,TS_TOP=74,TS_BOT=913;

Code

Pour utiliser l’objet TftScreen, nous utilisons les librairies SD.h, Adafruit_GFX.h, MCUFRIEND_kbv.h, et TouchScreen.h qui permettent de gérer la communication avec la carte SD, la création de graphique, la gestion de l’écran et l’écran tactile. Cet exemple propose une prise en main très simple de l’écran

N.B.: Pensez à utiliser les paramètres de l’écran tactile que vous utilisez.

//Libraries
#include <SD.h>//https://www.arduino.cc/en/reference/SD
#include <Adafruit_GFX.h>//https://github.com/adafruit/Adafruit-GFX-Library
#include <MCUFRIEND_kbv.h>//https://github.com/prenticedavid/MCUFRIEND_kbv
#include <TouchScreen.h> //https://github.com/adafruit/Adafruit_TouchScreen

//Constants
#define SD_CS 10
#define BLACK 0
#define GREY 21845
#define BLUE 31
#define RED 63488
#define GREEN 2016
#define DARKGREEN 1472
#define CYAN 2047
#define MAGENTA 63519
#define YELLOW 65504
#define GOLD 56768
#define WHITE 65535

//Touch screen configuration
#define MINPRESSURE 200
#define MAXPRESSURE 1000
// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
//3.5 Parameters
const int XP = 8, XM = A2, YP = A3, YM = 9; //320x480 ID=0x9486
const int TS_LEFT = 144, TS_RT = 887, TS_TOP = 936, TS_BOT = 87;
//2.8 Parameters
//const int XP = 8, XM = A2, YP = A3, YM = 9; //240x320 ID=0x9341
//const int TS_LEFT = 907, TS_RT = 120, TS_TOP = 74, TS_BOT = 913;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
TSPoint p;
bool down;
int pixel_x, pixel_y;     //Touch_getXY() updates global vars

//Variables
int currentPage  = 0, oldPage = -1;

//Objects
MCUFRIEND_kbv tft;

// Button calibration
Adafruit_GFX_Button page1_btn, page2_btn;
int margin = 5;
int btnWidth = 100;
int btnHeight = 40;
int btnY = 200;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init tft screen
  uint16_t ID = tft.readID();
  if (ID == 0xD3D3) ID = 0x9486;  //for 3.5" TFT LCD Shield , 0x9341 for 2.8" TFT LCD Shield  
  tft.begin(ID);
  tft.setRotation(1);//0-PORTRAIT 1-PAYSAGE 2-REVERSE PORTRAIT 3-REVERSE PAYSAGE
  //Uncomment if you are using SD
  /*if (!SD.begin(SD_CS)) {
    Serial.println(F("initialization failed!"));
    return;
  }*/
  currentPage = 0; // Indicates that we are at Home Screen
}

void loop() {
  down = Touch_getXY();
  switch (currentPage) {
    case 0:
      if (currentPage != oldPage) {
        Serial.println(F("Page 1"));
        drawPage1();
      }
      page2_btn.press(down && page2_btn.contains(pixel_x, pixel_y));
      //if (page2_btn.justReleased()) page2_btn.drawButton();

      if (page2_btn.justPressed()) {
        currentPage = 1;
      }
      break;

    case 1:
      if (currentPage != oldPage) {
        Serial.println(F("Page 2"));
        drawPage2();
      }
      page1_btn.press(down && page1_btn.contains(pixel_x, pixel_y));
      //if (page1_btn.justReleased()) page1_btn.drawButton();

      if (page1_btn.justPressed()) {
        currentPage = 0;
      }
      break;
  }
}

void drawPage1() { /* function drawHomePage */
  tft.setRotation(1);
  tft.fillScreen(BLACK);
  //Title
  tft.setCursor(0, 10);
  tft.setTextSize(3);
  tft.setTextColor(WHITE, BLACK);
  tft.print("This is page 1"); // Prints the string on the screen
  tft.drawLine(0, 32, 319, 32, DARKGREEN); // Draws the red line

  //text
  tft.setTextSize(3);
  tft.setTextColor(RED, BLACK);
  tft.setCursor(tft.width() / 2. -  14 * 3 * 3, 80);
  tft.print(" Go to page 2 ");

  //Button
  page2_btn.initButton(&tft, tft.width() / 2., 200, 2 * btnWidth, btnHeight, WHITE, GREEN, BLACK, "Page 2", 2);
  page2_btn.drawButton(false);
  oldPage = currentPage;
}

void drawPage2() { /* function drawHomePage */
  tft.setRotation(1);
  tft.fillScreen(GREY);
  //Title
  tft.setCursor(0, 10);
  tft.setTextSize(3);
  tft.setTextColor(WHITE, GREY);
  tft.print("This is page 2"); // Prints the string on the screen
  tft.drawLine(0, 32, 319, 32, DARKGREEN); // Draws the red line

  //text
  tft.setTextSize(3);
  tft.setTextColor(GREEN, BLACK);
  tft.setCursor(tft.width() / 2. - 14 * 3 * 3, 80);
  tft.print(" Go to page 1 ");

  //Button
  page1_btn.initButton(&tft, tft.width() / 2., 200, 2 * btnWidth, btnHeight, WHITE, RED, BLACK, "Page 1", 2);
  page1_btn.drawButton(false);
  oldPage = currentPage;
}
/************************************************************************************
    UTILITY FUNCTION
*************************************************************************************/
bool Touch_getXY(void)
{
  p = ts.getPoint();
  pinMode(YP, OUTPUT);      //restore shared pins
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    if (tft.width() <= tft.height()) { //Portrait
      pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
      pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    } else {
      pixel_x = map(p.y, TS_TOP, TS_BOT, 0, tft.width());
      pixel_y = map(p.x, TS_RT, TS_LEFT, 0, tft.height());
    }
  }
  return pressed;
}

Bonus : Exemple d’interface graphique

Dans cet exemple, nous allons créer une interface graphique pour montrer différentes fonctionnalités que l’on peut développer avec le shield TFT.

Pensez à utiliser les paramètres de l’écran que vous utilisez.

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <TouchScreen.h>

#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>
#include <FreeDefaultFonts.h>

#define MINPRESSURE 200
#define MAXPRESSURE 1000

// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
//3.5 Calibration
const int XP = 8, XM = A2, YP = A3, YM = 9; //320x480 ID=0x9486
const int TS_LEFT = 144, TS_RT = 887, TS_TOP = 936, TS_BOT = 87;
/*PORTRAIT CALIBRATION     320 x 480
  x = map(p.x, LEFT=144, RT=887, 0, 320)
  y = map(p.y, TOP=936, BOT=87, 0, 480)
  Touch Pin Wiring XP=8 XM=A2 YP=A3 YM=9
  LANDSCAPE CALIBRATION    480 x 320
  x = map(p.y, LEFT=936, RT=87, 0, 480)
  y = map(p.x, TOP=887, BOT=144, 0, 320)*/
//2.8 Calbiration
//const int XP=8,XM=A2,YP=A3,YM=9; //240x320 ID=0x9341
//const int TS_LEFT=907,TS_RT=120,TS_TOP=74,TS_BOT=913;
/*PORTRAIT CALIBRATION     240 x 320
  x = map(p.x, LEFT=907, RT=120, 0, 240)
  y = map(p.y, TOP=74, BOT=913, 0, 320)
  Touch Pin Wiring XP=8 XM=A2 YP=A3 YM=9
  LANDSCAPE CALIBRATION    320 x 240
  x = map(p.y, LEFT=74, RT=913, 0, 320)
  y = map(p.x, TOP=120, BOT=907, 0, 240)*/


TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
TSPoint p;

Adafruit_GFX_Button on_btn, off_btn, page1_btn, page2_btn, page3_btn;
Adafruit_GFX_Button ok_btn, cncl_btn, plus_btn, minus_btn;
Adafruit_GFX_Button menu_btn, info_btn, back_btn;

int pixel_x, pixel_y;     //Touch_getXY() updates global vars

// Button calibration
int margin = 5;
int btnWidth = 100;
int btnHeight = 40;
int btnY = 200;

// Software variable
bool enable_nuit = false;
int parameter = 50, old_parameter = 50;

long temp0 = 60;
long temp1 = 25.5;
long temp2 = 40;
long temp3 = 35.6;


#define BLACK   0x0000
#define GREY    0x5555
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define DARKGREEN   0x05C0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define GOLD    0xDDC0
#define WHITE   0xFFFF

enum pageId {
  MENU,
  SENSOR,
  CMD,
  PARAM,
  INFO
};
unsigned int currentPage = MENU, oldPage = -1;

void setup(void)
{
  Serial.begin(9600);
  //init TFTTouch
  uint16_t ID = tft.readID();
  Serial.print("TFT ID = 0x");
  Serial.println(ID, HEX);
  Serial.println(F("Calibrate for your Touch Panel"));
  if (ID == 0xD3D3) ID = 0x9486;  //for 3.5" TFT LCD Shield , 0x9341 for 2.8" TFT LCD Shield
  tft.begin(ID);
  tft.setRotation(1); //0-PORTRAIT 1-PAYSAGE 2-REVERSE PORTRAIT 3-REVERSE PAYSAGE
  //tft.setFont(&FreeSmallFont);
  /*if (!SD.begin(SD_CS)) {
    Serial.println(F("initialization failed!"));
    return;
    }*/
  currentPage = MENU; // Indicates that we are at Home Screen
  Serial.println("Home Page");
}

bool down ;
void loop(void) {
  switch (currentPage) {
    case MENU: //Menu page
      if (currentPage != oldPage)   drawMenuScreen();
      page1_btn.press(down && page1_btn.contains(pixel_x, pixel_y));
      page2_btn.press(down && page2_btn.contains(pixel_x, pixel_y));
      page3_btn.press(down && page3_btn.contains(pixel_x, pixel_y));

      if (page1_btn.justReleased())
        page1_btn.drawButton();
      if (page2_btn.justReleased())
        page2_btn.drawButton();
      if (page3_btn.justReleased())
        page3_btn.drawButton();

      if (page1_btn.justPressed()) {
        page1_btn.drawButton(true);
        currentPage = SENSOR;
      }
      if (page2_btn.justPressed()) {
        page2_btn.drawButton(true);
        currentPage = CMD;
      }
      if (page3_btn.justPressed()) {
        page3_btn.drawButton(true);
        currentPage = PARAM;
      }
      break;

    case SENSOR:
      if (currentPage != oldPage)   drawSensorScreen();
      readSensor();
      updateTemp();
      menu_btn.press(down && menu_btn.contains(pixel_x, pixel_y));
      info_btn.press(down && info_btn.contains(pixel_x, pixel_y));

      if (menu_btn.justReleased())
        menu_btn.drawButton();
      if (info_btn.justReleased())
        info_btn.drawButton();

      if (menu_btn.justPressed()) {
        menu_btn.drawButton(true);
        currentPage = MENU;
      }
      if (info_btn.justPressed()) {
        info_btn.drawButton(true);
        currentPage = INFO;
      }
      break;

    case CMD:
      if (currentPage != oldPage)   drawCmdScreen();
      on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
      off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
      back_btn.press(down && back_btn.contains(pixel_x, pixel_y));

      if (back_btn.justReleased())
        back_btn.drawButton();
      if (on_btn.justReleased())
        on_btn.drawButton();
      if (off_btn.justReleased())
        off_btn.drawButton();

      if (back_btn.justPressed()) {
        back_btn.drawButton(true);
        currentPage = MENU;
      }
      if (on_btn.justPressed()) {
        on_btn.drawButton(true);
        tft.fillRect(tft.width() / 2. - (btnWidth + 40) / 2, btnY - 4 * margin - (btnHeight) / 2 - (btnHeight + 40), btnWidth + 40, btnHeight + 40, GREEN);
        Serial.println(F("Set ON"));
      }
      if (off_btn.justPressed()) {
        off_btn.drawButton(true);
        tft.fillRect(tft.width() / 2. - (btnWidth + 40) / 2, btnY - 4 * margin - (btnHeight) / 2 - (btnHeight + 40), btnWidth + 40, btnHeight + 40, RED);
        Serial.println(F("Set OFF"));
      }
      break;

    case PARAM: //consigne
      if (currentPage != oldPage)   drawParamScreen();
      plus_btn.press(down && plus_btn.contains(pixel_x, pixel_y));
      minus_btn.press(down && minus_btn.contains(pixel_x, pixel_y));
      ok_btn.press(down && ok_btn.contains(pixel_x, pixel_y));
      cncl_btn.press(down && cncl_btn.contains(pixel_x, pixel_y));

      if (plus_btn.justReleased())
        plus_btn.drawButton();
      if (minus_btn.justReleased())
        minus_btn.drawButton();

      if (ok_btn.justReleased())
        ok_btn.drawButton();
      if (cncl_btn.justReleased())
        cncl_btn.drawButton();
      if (plus_btn.justPressed()) {
        plus_btn.drawButton(true);
        parameter += 1;
        Serial.print(F("Consigne : "));
        Serial.println(parameter);

        drawTextInRect(tft.width() / 2., 60 + 3 * 4 + 6 * 8, parameter, 4, RED, BLACK);
      }
      if (minus_btn.justPressed()) {
        minus_btn.drawButton(true);
        parameter -= 1;
        Serial.print(F("Consigne : "));
        Serial.println(parameter);

        drawTextInRect(tft.width() / 2., 60 + 3 * 4 + 6 * 8, parameter, 4, RED, BLACK);
      }

      if (ok_btn.justPressed()) {
        ok_btn.drawButton(true);
        Serial.println(F("Valider"));
        validateScreen();
        delay(1000);
        currentPage = MENU;

      }
      if (cncl_btn.justPressed()) {
        cncl_btn.drawButton(true);
        parameter = old_parameter;
        Serial.println(F("Annule "));
        cancelScreen();
        delay(1000);
        currentPage = MENU;
      }
      break;

    case INFO:
      if (currentPage != oldPage) drawInfoScreen();
      if (Touch_getXY()) {
        currentPage = MENU;
      }
      break;
  }
  if (oldPage == currentPage){
    down = Touch_getXY();
  }else{
    down=false;
  }
}

/************************************************************************************
    SCREENS DEFINTION
 ************************************************************************************/
void drawMenuScreen() {
  tft.fillScreen(BLACK);
  tft.setTextSize(2);

  // Title
  tft.setTextColor(WHITE, BLACK);
  tft.setCursor(0, 10);
  tft.print("Exemple de menu"); // Prints the string on the screen
  tft.drawLine(0, 32, tft.width() * 0.6, 32, DARKGREEN); // Draws the red line
  tft.setTextColor(WHITE, BLACK);//((255, 255, 255), (0,0,0));
  tft.setCursor(0, 80);
  tft.setTextColor(GREEN, BLACK);//((255, 255, 255), (0,0,0));

  // Button
  page1_btn.initButton(&tft,  tft.width() / 2. , tft.height() / 2. - (1.*btnHeight + margin), 2 * btnWidth, btnHeight, WHITE, GREEN, BLACK, "SENSOR", 2);
  page2_btn.initButton(&tft, tft.width() / 2., tft.height() / 2., 2 * btnWidth, btnHeight, WHITE, GREEN, BLACK, "COMMAND", 2);
  page3_btn.initButton(&tft, tft.width() / 2., tft.height() / 2. + (1.*btnHeight + margin), 2 * btnWidth, btnHeight, WHITE, GREEN, BLACK, "PARAMETER", 2);
  page1_btn.drawButton(false);
  page2_btn.drawButton(false);
  page3_btn.drawButton(false);

  //Button frame
  tft.drawRoundRect(tft.width() / 2. - 1.5 * btnWidth, tft.height() / 2. - (1.5 * btnHeight + 2 * margin), 2 * btnWidth + btnWidth, 3 * btnHeight + 4 * margin, 10, GREEN);
  oldPage = currentPage;
}

void readSensor() {
  temp0 = temp0 + random(-25, 25) / 10;
  temp1 = temp1 + random(-25, 25) / 10;
  temp2 = temp2 + random(-25, 25) / 10;
  temp3 = temp3 + random(-25, 25) / 10;
}

void drawSensorScreen() {
  tft.fillScreen(BLACK);

  tft.drawLine(tft.width() / 2., 0, tft.width() / 2., tft.height(), WHITE);
  tft.drawLine(0, tft.height() / 2., tft.width(), tft.height() / 2., WHITE);

  updateTemp();

  tft.setTextSize(1);
  // bouton centré X,Y
  menu_btn.initButton(&tft,  tft.width() / 2. - btnWidth - margin , tft.height() - btnHeight / 2., btnWidth, btnHeight, WHITE, GREY, BLACK, "MENU", 2);
  info_btn.initButton(&tft, tft.width() / 2. + btnWidth + margin, tft.height() - btnHeight / 2., btnWidth, btnHeight, WHITE, GREY, BLACK, "INFO", 2);
  menu_btn.drawButton(false);
  info_btn.drawButton(false);

  oldPage = currentPage;
}

void updateTemp() {
  //temp1
  if (parameter < temp0) { //(abs(parameter-temp0)<1){
    drawTextInRect(tft.width() / 4., tft.height() / 4., temp0, 5, GREEN, 255);
  } else {
    drawTextInRect(tft.width() / 4., tft.height() / 4., temp0, 5, RED, 255);
  }
  drawTextInRect(3 * tft.width() / 4., tft.height() / 4., temp1, 5, RED, 255);
  drawTextInRect(tft.width() / 4., 3 * tft.height() / 4., temp2, 5, RED, 255);
  drawTextInRect(3 * tft.width() / 4., 3 * tft.height() / 4., temp3, 5, RED, 255);
}

void drawCmdScreen() {
  tft.setRotation(1);            //PORTRAIT
  tft.setTextSize(1);
  tft.fillScreen(BLACK);

  back_btn.initButton(&tft,  60 , 20, btnWidth, btnHeight, BLACK, BLACK, WHITE, "<- Back", 2);

  // bouton centré X,Y
  on_btn.initButton(&tft,  tft.width() / 2. - btnWidth / 2. , btnY, btnWidth, btnHeight, WHITE, GREEN, BLACK, "ON", 2);
  off_btn.initButton(&tft, tft.width() / 2. + btnWidth / 2. + margin, btnY, btnWidth, btnHeight, WHITE, RED, BLACK, "OFF", 2);
  back_btn.drawButton(false);
  on_btn.drawButton(false);
  off_btn.drawButton(false);
  tft.fillRect(tft.width() / 2. - (btnWidth + 40) / 2, btnY - 4 * margin - (btnHeight) / 2 - (btnHeight + 40), btnWidth + 40, btnHeight + 40, RED);
  oldPage = currentPage;
}

void validateScreen() {
  tft.setRotation(1);
  tft.fillScreen(BLACK);
  tft.setTextSize(5);
  tft.setTextColor(BLACK, GREEN);
  tft.setCursor(tft.width() / 2. - 6 * 6 * 4, tft.height() / 2. - 1 * 6);
  tft.print(" VALIDE ");
}

void cancelScreen() {
  tft.setRotation(1);
  tft.fillScreen(BLACK);
  tft.setTextSize(5);
  tft.setTextColor(BLACK, RED);
  tft.setCursor(tft.width() / 2. - 6 * 6 * 4, tft.height() / 2. - 1 * 6);
  tft.print(" ANNULE ");
}

void drawParamScreen() {
  tft.setRotation(1);
  tft.fillScreen(BLACK);
  //Title
  tft.setTextSize(3);
  tft.setTextColor(WHITE, BLACK);
  tft.setCursor(tft.width() / 2. - 9 * 3 * 3, 50);
  tft.print("Parameter");

  ok_btn.initButton(&tft,  2 + btnWidth / 2., btnHeight / 2. + margin, btnWidth, btnHeight, WHITE, DARKGREEN, BLACK, "Valider", 2);
  cncl_btn.initButton(&tft, tft.width() - btnWidth / 2 - 2, btnHeight / 2. + margin, btnWidth, btnHeight, WHITE, RED, BLACK, "Annuler", 2);
  ok_btn.drawButton(false);
  cncl_btn.drawButton(false);

  drawTextInRect(tft.width() / 2., 60 + 3 * 4 + 6 * 8, parameter, 4, RED, BLACK);
  plus_btn.initButton(&tft,  tft.width() / 2. - btnWidth / 2. , 60 + 3 * 4 + 6 * 8 + (btnWidth - 30), btnWidth - 20, btnWidth - 30, WHITE, GREEN, BLACK, "+", 5);
  minus_btn.initButton(&tft, tft.width() / 2. + btnWidth / 2. + margin, 60 + 3 * 4 + 6 * 8 + (btnWidth - 30), btnWidth - 20, btnWidth - 30, WHITE, GREEN, BLACK, "-", 5);
  plus_btn.drawButton(false);
  minus_btn.drawButton(false);
  oldPage = currentPage;
}

void drawInfoScreen() {
  tft.setRotation(1); 
  tft.fillScreen(BLACK);//(100, 155, 203)
  tft.drawRoundRect(10, 50, tft.width() - 20, tft.height() - 60, 5, GREEN); //tft.fillRect (10, 10, 60, 36);
  tft.setTextSize(2);
  tft.setTextColor(WHITE, BLACK);
  tft.setCursor(70, 18);
  tft.print("Information sur l'exemple");
  tft.setTextSize(2);
  tft.setTextColor(WHITE, BLACK);
  tft.setCursor(25, 80);
  tft.print("En cas de probleme avec ce tutoriel,\n  n'hesitez pas a nous contacter");
  tft.setCursor(20, 245);
  tft.print("www.aranacorp.com" );
  oldPage = currentPage;
}


/************************************************************************************
    UTILITY FUNCTION
*************************************************************************************/

void drawTextInRect(int x, int y, long temp, int tsize, unsigned int fColor, unsigned int bColor) {
  int marg = 10;
  char buf[12];
  int nbChar = strlen(itoa(temp, buf, 10)) + 2;
  if (bColor != 255) tft.fillRect(x - nbChar * 3 * tsize - marg, y - nbChar * 1 * tsize - marg, nbChar * 6 * tsize + 2 * marg, nbChar * 2 * tsize + 2 * marg, bColor);
  tft.setTextSize(tsize);
  tft.setTextColor(fColor, BLACK);
  //tft.setCursor(x-strlen(*text)*3*tsize+marg, y+rheight/2.+marg);
  tft.setCursor(x - nbChar * 3 * tsize, y - nbChar * 1 * tsize);
  tft.print(temp);
  //while(*text) tft.print(*text++);
  tft.write(0xF7);
  tft.print("C");
}

bool Touch_getXY(void)
{
  p = ts.getPoint();
  pinMode(YP, OUTPUT);      //restore shared pins
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    if (tft.width() <= tft.height()) { //Portrait
      pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
      pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    } else {
      pixel_x = map(p.y, TS_TOP, TS_BOT, 0, tft.width());
      pixel_y = map(p.x, TS_RT, TS_LEFT, 0, tft.height());
    }
  }
  return pressed;
}

Applications

  • Créer une interface graphique pour piloter votre projet Arduino

Sources

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

Utilisation du Motor Shield Arduino

Utilisation du Motor Shield Arduino

Le Motor Shield officiel d’Arduino est une carte d’extension pour les microcontrôleurs Arduino UNO et Mega pour le pilotage de moteur CC et de moteur pas-à-pas. Nous avons vu comment piloter un moteur CC en utilisant un pont en H ce qui peut nécessiter beaucoup de branchement lorsqu’on utilise le circuit intégré simplement. Pour une application embarquée, comme un robot Willy, vous serez amené à piloter plusieurs moteurs en parallèle. Ils existent pour cela des Shields qui simplifieront le montage.

Matériel

  • Ordinateur
  • Arduino UNO
  • Câble USB A Mâle/B Mâle
  • Arduino Motor Shield
  • Moteur CC x1 ou Moteur pas-à-pas x1

Principe de fonctionnement

Le Motor Shield Arduino utilise le double pont en H L298. Il permet de piloter des moteurs en direction et en vitesse avec une tension nominale entre 5 et 12V et un courant de 2A, jusqu’à 4A avec une source de tension extérieure.
Ce shield permet de piloter:

  • jusqu’à deux moteurs à courant continu ou un moteur pas à pas bipolaire
  • deux capteurs analogiques
  • deux sorties PWM comme des servomoteurs.
  • un bus I2C est disponible ce qui permet de brancher des modules compatibles

Schéma

Compatible avec les carte UNO et Mega, le shield se place directement sur la carte Arduino. L’alimentation se branche au bornier Power. Les moteurs sont branchés sur les borniers A+,A-,B+,B-. Les broches de l’Arduino sont directement reliées aux broches du circuit intégré:

  • Digital pin 12: direction DC Motor #A / Stepper #A
  • Digital pin 13: direction DC Motor #B / Stepper #B
  • Digital pin 3: vitesse DC Motor #A / Stepper #A
  • Digital pin 11: vitesse DC Motor #B / Stepper #B
  • Digital pin 9: activation brake DC Motor #A
  • Digital pin 8: activation brake DC Motor #B
  • Entrées disponibles In2 In3 reliées aux entrées analogiques A2 et A3
  • Sorties disponibles Out5, Out6 reliées aux sorties PWM 5 et 6

Dans le cas d’un shield, les branchements sont prédéfinis. Vérifiez bien dans la documentation technique du composant comment l’utiliser.
Les branchements des moteurs sont détaillés dans les schémas suivants.

Code

Pour interagir avec le Motor Shield, nous n’utilisons pas de librairie particulière car il est relié au broches de l’Arduino directement. Il vous est toujours possible de créer votre librairie pour simplifier votre code.

//Parameters
const int input_voltage  = 9;//V
const int nominal_voltage  = 5;////V
const int MAX_SPEED  = int(nominal_voltage * 255 / input_voltage);
const int directionA  = 12;
const int directionB  = 13;
const int brakeA  = 9;
const int brakeB  = 8;
const int speedA  = 3;
const int speedB  = 11;
const int in2  = A2;
const int in3  = A3;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init Motor Shield
  pinMode(directionA, OUTPUT); //Initiates Motor Channel A pin
  pinMode(brakeA, OUTPUT); //Initiates Brake Channel A pin
  pinMode(directionB, OUTPUT); //Initiates Motor Channel B pin
  pinMode(brakeB, OUTPUT); //Initiates Brake Channel B pin
}

void loop() {
  readSensorMS();
  testMotorMS();
  //testStepperMS();
}

void testStepperMS() { /* function testStepperMS */
  //// Test stepper
  Serial.println("Move stepper 1 step clockwise");
  stpCW(1);
  Serial.println("Move stepper 1 step counter clockwise");
  stpCCW(1);
}

void testMotorMS() { /* function testMotorMS */
  //// Test DC motor
  Serial.println(F("-------------------------------------"));
  Serial.println(F("Avant "));
  dcForward();
  delay(500);
  Serial.println(F("Arrière "));
  dcBackward();
  delay(500);
  Serial.println(F("Arrêt "));
  dcStop();
  delay(1000);
}

void readSensorMS() { /* function readSensorMS */
  //// Read sensors
  Serial.print(F("In2 : ")); Serial.println(analogRead(in2));
  Serial.print(F("In3 : ")); Serial.println(analogRead(in3));
}

void dcForward() { /* function dcForward */
  //// set forward motion for A and B
  digitalWrite(directionA, HIGH); //Establishes forward direction of Channel A
  digitalWrite(brakeA, LOW);   //Disengage the Brake for Channel A
  analogWrite(speedA, MAX_SPEED);
  digitalWrite(directionB, HIGH); //Establishes forward direction of Channel B
  digitalWrite(brakeB, LOW);   //Disengage the Brake for Channel B
  analogWrite(speedB, MAX_SPEED);
}

void dcBackward() { /* function dcBackward */
  //// set backward motion for A and B
  digitalWrite(directionA, LOW); //Establishes forward direction of Channel A
  digitalWrite(brakeA, LOW);   //Disengage the Brake for Channel A
  analogWrite(speedA, MAX_SPEED);
  digitalWrite(directionB, LOW); //Establishes forward direction of Channel B
  digitalWrite(brakeB, LOW);   //Disengage the Brake for Channel B
  analogWrite(speedB, MAX_SPEED);
}

void dcStop() { /* function dcStop */
  //// stop motors A and B
  digitalWrite(brakeA, HIGH);   //Engage the Brake for Channel A
  analogWrite(speedA, 0);
  digitalWrite(brakeB, HIGH);   //Engage the Brake for Channel B
  analogWrite(speedB, 0);
}

void stpCW(int nbstep) { /* function stpCW */
  //// Move stepper clockwise
  for (int i = 0; i < nbstep; i++) {
    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, HIGH);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, LOW);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);

    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, LOW);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, HIGH);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);
  }
}

void stpCCW(int nbstep) { /* function stpCCW */
  //// Move stepper counter-clockwise
  for (int i = 0; i < nbstep; i++) {
    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, HIGH);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, HIGH);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);

    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, LOW);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, LOW);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);
  }
}

void dcStop() { /* function dcStop */
  //// stop motors A and B
  digitalWrite(brakeA, HIGH);   //Engage the Brake for Channel A
  analogWrite(speedA, 0);
  digitalWrite(brakeB, HIGH);   //Engage the Brake for Channel B
  analogWrite(speedB, 0);
}

Applications

  • Piloter un robot à deux roues comme Willy

Sources

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

Connectez votre Arduino à internet avec un Shield Ethernet W5100

Connectez votre Arduino à internet avec un Shield Ethernet W5100

La connexion d’un microcontrôleur à internet est rendu possible par l’utilisation d’un Shield Ethernet W5100. La base de la création d’objets connectés, est de les faire communiquer avec leur environnement en passant par un réseau comme le réseau Wifi.
La communication via le réseau Ethernet est très pratique lorsqu’on veut connecter, en filaire, un appareil au réseau Wifi.

Pour une connexion au Wifi sans fil, optez pour un Shield Wifi ou un autre type de carte.

Matériel

  • Ordinateur
  • Arduino UNO
  • Câble USB A Mâle/B Mâle
  • Câble Ethernet RJ45
  • Ethernet Shield W5100

Principe de fonctionnement du Shield Ethernet W5100

La communication utilise le réseau éthernet qu’il est possible de connecter au réseau Wifi. Pour pouvoir accéder à la carte Arduino sans avoir à la connecter au routeur internet, il est nécessaire de créer un pont entre la connexion wifi et la connexion Ethernet sur votre ordinateur. Pour cela, il faut:

  • Allez dans le Centre Réseau et Partage
  • Allez dans “Modifier les paramètres de la carte”
  • Sélectionnez Ethernet et Wifi /(internet source) et clique droit
  • Cliquez sur “Créer pont”

Sous Windows, dans le terminal de commande, tapez “arp -a” pour voir les adresses IP utilisées sur le réseau.

Le Shield Ethernet W5100 utilise la Microchip W5100 comme contrôleur Ethernet.

Schéma

Le Shield Ethernet W5100 est compatible avec les microcontrôleurs Arduino UNO et Mega. La puce W5100 et la carte SD utilisent le SPI bus pour communiquer avec la carte Arduino. La broche 10 est utilisé pour sélectionner le contrôleur Ethernet W5100, la broche 9 comme RESET pour le W5100 et la broche 4 pour sélectionner le module de carte SD.

En résumé, les broches utilisées sont:

  • 4 pour la sélection de la carte SD (SD_CS)
  • 9 pour le reset de la micropuce W5100 (W5100_RST)
  • 10 pour la sélection de la micropuce W5100 (W5100_CS)
  • le bus SPI : broches 11,12,13 sur une carte Arduino UNO/Duelmilanove. Les broches 50, 51 et 52 pour la Mega.

Code de gestion d’un Shield Ethernet W5100

Pour communiquer sur le réseau, il nous faut utiliser un protocole particulier. Ce protocole est intégré dans toutes les librairies relatives à la communication WiFi:

  • Il faut connecter le module WiFi ou Ethernet au réseau
  • définir un serveur server
  • définir un client client
//Libraries
#include <Ethernet.h>//https://github.com/CisecoPlc/Arduino-W5100-W5200/tree/master/Ethernet

//Parameters
String request ;
unsigned long refreshCounter  = 0;
IPAddress ip(192, 168, 1, 179) ;
byte mac [6] = {0x54, 0x34, 0x41, 0x30, 0x30, 0x31};

//Objects
EthernetServer server(80);
EthernetClient client;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init W5100
  Ethernet.begin(mac, ip);
  while (!Ethernet.begin(mac)) {
    Serial.println(F("failed. Retrying in 1 seconds."));
    delay(1000);
    Serial.print(F("Starting W5100..."));
  }
  pinMode(2, OUTPUT);
  server.begin();
  Serial.println(F("W5100 initialized"));
  Serial.print(F("IP Address: "));
  Serial.println(Ethernet.localIP());
}

void loop() {
  client = server.available();
  clientRequest();
  handleRequest();
}

void clientRequest( ) { /* function clientRequest */
  ////Get client request
  if (!client) {
    return;
  }
  // Wait until the client sends some data
  while (!client.available()) {
    delay(1);
  }

  request = client.readStringUntil('\r'); // Read the first line of the request
  Serial.println(request);
  client.flush();
}

void handleRequest( ) { /* function handleRequest */
  ////Handle web client request
  if (request.indexOf("/dig2on") > 0) {
    digitalWrite(2, HIGH);
  }
  if (request.indexOf("/dig2off") > 0) {
    digitalWrite(2, LOW);
  }
  if (request.indexOf("GET") >= 0) {
    webpage(client);
    client.stop();
  }

}

void webpage(EthernetClient client) { /* function webpage */
  ////Send webpage to client

  //output HTML data header
  client.println(F("HTTP/1.1 200 OK"));
  client.println(F("Content-Type: text/html"));
  client.println();
  //header
  client.print(F("<!DOCTYPE HTML><html><head><title>AranaCorp</title>"));
  client.print(F("<meta http-equiv='content-type' content='text/html; charset=UTF-8'>"));
  //meta-refresh page every x seconds
  client.print(F("<meta http-equiv='refresh' content='2'>"));
  client.print(F("</head><body bgcolor='black'><br>"));
  client.print(F("<hr/><hr>"));
  client.print(F("<h1 style='color : #3AAA35;'><center> AranaCorp - Arduino Web Controller </center></h1>"));
  client.print(F("<hr/><hr>"));
  client.println("<center><p style='color:white;'>");
  client.print(F("Page refresh number: "));
  client.print(refreshCounter); //current refresh count
  client.println("</p></center><br>");
  client.print(F("<h2 style='color:green;'>Arduino Inputs</h2>"));
  client.println("<p style='color:white;'>");

  client.print(F("<br><br>"));
  client.print("<br><br>");

  //output analog input pin
  for (int i = 0; i < 6; i++) {
    client.print("<b>Input A");
    client.print(i);
    client.print(" : </b>");
    client.print(analogRead(14 + i)); //A0=14, A1=15 ,etc.
    client.print(F("<br>"));
  }
  client.print(F("</p><br>"));

  client.print(F("<h2 style='color:green;'>Arduino Outputs</h2>"));
  client.print(F("<p style='color:white;'>"));

  //digital output
  client.print(F("<br><br>"));

  client.print(F("<b>Digital output Pin 2 : </b>"));
  client.print("<input value=" + String(digitalRead(2)) + " readonly></input>");
  client.print(F("<a href='/dig2on'><button>Turn On </button></a>"));
  client.print(F("<a href='/dig2off'><button>Turn Off </button></a><br />"));

  client.print(F("</p><br>"));

  //file end
  client.print(F("<br></body></html>"));
  refreshCounter += 1;
  delay(1);
}

Résultat

Nous pouvons voir que le Shield Ethernet W5100 s’initialise correctement. Lorsque vous entrer l’adresse IP dans la barre d’adresse de votre navigateur, la page web décrite dans la fonction webpage s’affiche.
Une fois la page chargée, les valeurs des entrées analogiques varient à chaque rafraichissement et l’état de la broche 2 peut être modifier en appuyant sur les boutons correspondants.

Applications

  • Utiliser une interface web pour piloter votre Arduino

Sources

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie