Arduino : transmission de mesures

Arduino : transmission de mesures

Arduino : transmission de mesures

Faire des mesures de PH et conductivité et les transmettre vers un serveur apache pour en garder un historique.

Il faut

97% Complete

Câblage matériel

A faire

Connexion Wifi

Sur un Arduino Uno WiFi il faut brancher une source supplémentaire d'alimentation : le 5v de l'USB ne suffi pas. FIXME

Transmission des données vers le serveur apache

A faire

Mesures de PH

Mesures de PH

90% Complete
Cette sonde de PH est composée d'un connecteur et d'un plongeur.

Il faut

Présentation de la sonde

Connecteur PH mètre

Le connecteur possède 6 broches.

  1. To : Température
  2. Do : sortie logique (sortie de comparateur) : valeur du pH supérieure ou inférieure à un seuil réglé par potentiometre. (en vue d'une action de correction de pH) Etat signalé par une LED
  3. Po : Sortie analogique du PH
  4. G : Ground
  5. G : Ground
  6. V+ :

Caractéristiques techniques

  • Alimentation : 5v
  • Plage PH : 0-14 PH
  • Plage de température: 0-60 ℃
  • zéro-point: 7 ± 0.5PH
  • alcalin Erreur: 0.2PH
  • Pourcentage théorique Pente: ≧98. 5%
  • Résistance interne: ≦250MΩ
  • Temps de réponse: ≦1min
  • Température de fonctionnement: 0-60 ℃
  • Borniers: BNC

Documentation

Cablage

TODO

Code

const byte pHpin = A0;    // Connect the sensor's Po output to analogue pin 0.

void loop(){

  Serial.print("Lecture du PH :");
  float mesurePH;
  if( getPh( &mesurePH ) == READ_OK){
    Serial.println(mesurePH);
  }

}

// ----------------------------------------------------------------------------------------
// Fonction de mesure du PH qui est branché sur le port analogique
// @return : float
float getPh(float *ph){
 
  // Read and reverse the analogue input value from the pH sensor then scale 0-14.
  // La valeur 0.1 est un ajustement custom...
  *ph = ((1023 - analogRead(pHpin)) / 73.07) + 0.1;
  // Pas d'erreur
  return READ_OK;
}

Mesures de température

Mesures de température

100% Complete
Sonde DS18B20 de température (en version étanche).

Il faut

Principe de fonctionnement

Le capteur DS18B20 est un capteur 1-Wire, cela signifie qu'il communique avec une carte maître au moyen d'un bus 1-Wire. Plusieurs capteurs peuvent être reliés sur un même bus 1-Wire. Chaque capteur dispose d'une adresse unique gravée lors de la fabrication, ils sont donc tous unique.

Un bus 1-Wire est composé classiquement des trois fils : un fil de masse, un fil d'alimentation (5 volts) et un fil de données. Un seul composant externe est nécessaire pour faire fonctionner un bus 1-Wire : une simple résistance de 4.7K ohms en résistance de tirage à l'alimentation sur la broche de données.

Cablâge

Schéma de Cablage DS18B20

La sonde de température à 3 fils :

  1. Rouge : 5V
  2. Noir : Ground
  3. Jaune : Data

Le fils jaune est donc à brancher sur une entrée numérique de l'arduino.

Attention il y a une résistance de 4.7k à brancher entre le fil rouge et le jaune.

Programme

Source : carnetdumaker

Avant toute chose, il faut installer la librairie "one wire" pour Arduino (si ce n'est pas déjà fait). L'installation se fait soit à partir du dépot GIT, soit par le manager le library dans le logiciel Arduino (Sketch > Include Library > Manage Library) en cherchant "onewire".

Le code (initialisation de la sonde) :

// sonde température DS18B20 *******************************************************************
#include <OneWire.h>          // librairie pour sonde temérature
#define TemperaturePIN 4     // PIN (broche) sur laquelle est branchée la sonde
byte data[12];                // Tableau de 12 octets pour lecture des 9 registres de RAM et des 3 registres d'EEPROM du capteur One Wire
byte adresse[8];              // Tableau de 8 octets pour stockage du code d'adresse 64 bits du composant One Wire
OneWire  capteur(TemperaturePIN);  // crée un objet One Wire sur la broche voulue
enum DS18B20_RCODES {         /* Code de retour de la fonction getTemperature() */
  READ_OK,          // Lecture ok
  NO_SENSOR_FOUND,  // Pas de capteur
  INVALID_ADDRESS,  // Adresse reçue invalide
  INVALID_SENSOR    // Capteur invalide (pas un DS18B20)
};

Dans le bloc setup() :

void setup() {

  // --- initialisation du capteur DS18B20 ------
  capteurInit();
}

Dans le bloc loop() :

void loop() {

  // Lecture du capteur de temperature
  afficheTemperature();

}

Plus loin dans le code :

// ----------------------------------------------------------------------------------------
// Initialisation d'un capteur sur la broche.
//
void capteurInit(void) {
  Serial.println("**** Detection du capteur température **** ");
  // Si aucune sonde n'est détecté
  if ( !capteur.search(adresse)) {
    Serial.print("Aucun capteur 1-wire present sur la broche ");
    Serial.println(TemperaturePIN);
    
    delay (1000); // pause 1 seconde
    capteur.reset_search();
    return; // On sort de la fonction
  }
  // la fonction search renvoie la valeur VRAI si un élément 1-wire est trouvé.
  // Stocke son code d'adresse 16 bits dans le tableau adresse[8]
  // adresse envoyé à la fonction correspond à l'adresse de début du tableau adresse[8] déclaré ...   
  Serial.print ("Capteur 1-wire present avec code adresse 64 bits : ");
  //--- affichage des 64 bits d'adresse au format hexadécimal
   for(int i = 0; i < 8; i++) { // l'adresse renvoyée par la fonction search est stockée sur 8 octets
    if (adresse[i]<16) Serial.print('0'); // pour affichage des O poids fort au format hexadécimal
    Serial.print(adresse[i], HEX); // affiche 1 à 1 les 8 octets du tableau adresse au format hexadécimal
    Serial.print(" ");
  }
  Serial.println();
  //---- test du type de capteur ----
  // le type du capteur est donné par le 1er octet du code adresse 64 bits
  // Valeur 0x28 pour capteur type DS18B20, 0x10 pour type DS18S20, 0x22 pour type DS1820
  if ( adresse[0] == 0x10) {
    Serial.println("Type du capteur present : Capteur temperature DS18S20.");
  } else if (adresse[0]==0x28)   {
    Serial.println ("Type du capteur present : Capteur temperature DS18B20.");
  } else {
    Serial.println ("Le capteur present n'est pas un capteur de temperature DS18B20.");
  }
  //----- contrôle du code CRC ----
  // le dernier octet de l'adresse 64bits est un code de contrôle CRC
  // à l'aide de la fonction crc8 on peut vérifier si ce code est valide
  if (capteur.crc8( adresse, 7) == adresse[7]) // vérification validité code CRC de l'adresse 64 bits
  // le code CRC de l'adresse 64 bits est le 8ème octet de l'adresse (index 7 du tableau)
  {
    Serial.println ("Verification du code CRC de l'adresse 64 bits de ce capteur : VALIDE !");
  } else {
    Serial.println ("Verification du code CRC de l'adresse 64 bits de ce capteur : NON VALIDE !");     
  }
  //------- message final détection ----
  Serial.println("----- fin de la recherche du capteur ----");
  Serial.println("");   
}
// ----------------------------------------------------------------------------------------
// Fonction d'affichage de la température.
//
void afficheTemperature(){
  // La temperature renvoyée est en Farenheit
  float temperatureF;
  if (getTemperature(&temperatureF, true) != READ_OK) {
    Serial.println(F("Erreur de lecture du capteur"));
    return;
  }
  // Affichage de la température du capteur
  Serial.print ("Temperature = ");
  Serial.print (temperatureF,2);
  Serial.println ("°C. ");
}
// ----------------------------------------------------------------------------------------
// Fonction de mesure de la température renvoyée par la sonde.
// avant chaque nouvelle instruction, il faut :
//    * initialiser le bus 1-wire
//    * sélectionner le capteur détecté
//    * envoyer l'instruction
// @return : float
byte getTemperature(float *temperature, byte reset_search) {
  byte data[9], addr[8];
  // data[] : Données lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire détecté
 
  /* Reset le bus 1-Wire ci nécessaire (requis pour la lecture du premier capteur) */
  if (reset_search) {
    capteur.reset_search();
  }
 
  /* Recherche le prochain capteur 1-Wire disponible */
  if (!capteur.search(addr)) {
    // Pas de capteur
    return NO_SENSOR_FOUND;
  }
 
  /* Vérifie que l'adresse a été correctement reçue */
  if (OneWire::crc8(addr, 7) != addr[7]) {
    // Adresse invalide
    return INVALID_ADDRESS;
  }
 
  /* Vérifie qu'il s'agit bien d'un DS18B20 */
  if (addr[0] != 0x28) {
    // Mauvais type de capteur
    return INVALID_SENSOR;
  }
 
  /* Reset le bus 1-Wire et sélectionne le capteur */
  capteur.reset();
  capteur.select(addr);
 
  /* Lance une prise de mesure de température et attend la fin de la mesure */
  capteur.write(0x44, 1);
  delay(800);
 
  /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
  capteur.reset();
  capteur.select(addr);
  capteur.write(0xBE);
 
 /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) {
    data[i] = capteur.read();
  }
   
  /* Calcul de la température en degré Celsius */
  *temperature = ((data[1] << 8) | data[0]) * 0.0625;
 
  // Pas d'erreur
  return READ_OK;
}

Fonctions utiles de la sonde

Fonctions d'initialisation

Fonctions de communication

Fonction de contrôle des données

Fonction de contrôle de de l'alimentation

Transmission Wifi

100% Complete
Transmission de données via une requète GET à un serveur HTTP.

Il faut

Câblage

Code

// Transmission Wifi ***************************************************************************
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include "utility/debug.h"
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   2  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); // you can change this clock speed
#define WLAN_SSID       "YourWifiSSID"           // cannot be longer than 32 characters!
#define WLAN_PASS       "WifiPassWord"
#define WLAN_SECURITY   WLAN_SEC_WPA2 // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define IDLE_TIMEOUT_MS  3000      // Amount of time to wait (in milliseconds) with no data
                                   // received before closing the connection.  If you know the server
                                   // you're accessing is quick to respond, you can reduce this value.
#define WEBSITE      "www.yourwebsite.fr"
#define WEBPAGE      "yourpage.php"
String g_STR_Request;
uint32_t ip;

void setup() {

WifiInit();

}

void loop() {

  // Envoie les donnees au serveur HTTP
  WifiSend();
  delay( TIMER * 3600000 );
}

// ----------------------------------------------------------------------------------------
// Initilisation de la connection wifi.
// Une fois la procedure executee, la variable client est initialisee.
//
void WifiInit(){
  /* Initialise the module */
  Serial.println(F("\nInitialisation de la connection WIFI..."));
  if (!cc3000.begin()) {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }
 
  Serial.print(F("\nTentative de connection a :")); Serial.println(WLAN_SSID);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }
   
  Serial.println(F("Connected!"));
 
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP()) {
    delay(100); // ToDo: Insert a DHCP timeout!
  }  
 
  // Try looking up the website's IP address
  ip = 0;
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
}

// ----------------------------------------------------------------------------------------
// Envoie un enregistrement dans la base des capteurs.
// @see : https://www.adafruit.com/products/1469
void WifiSend(){
  g_STR_Request = WEBPAGE;
    
  // ID du capteur --------------------------
  g_STR_Request += "&capteurID=";
  g_STR_Request.concat(CAPTEURS_ID);
    
  // Temperature --------------------------
  Serial.println("Lecture de la temperature");
  float temperatureF;
  if (getTemperature(&temperatureF, true) == READ_OK) {
    g_STR_Request += "&temperature=";
    g_STR_Request.concat(temperatureF);
  }
  // PH ------------------------------------
  Serial.println("Lecture du PH");
  float mesurePH;
  if( getPh( &mesurePH ) == READ_OK){
    g_STR_Request += "&ph=";
    g_STR_Request.concat(mesurePH);
  }
 
  /* Try connecting to the website.
     Note: HTTP/1.1 protocol is used to keep the server from closing the connection before all data is read.
  */
  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  Serial.print("Send request :");
  Serial.println( g_STR_Request );
  if (www.connected()) {
    // On va devoir convertir le Strring en char pour l'envoyer dans la fonction www.fastrprint
    int str_len = g_STR_Request.length() + 1;
    char l_CHR_Request[str_len];
    g_STR_Request.toCharArray(l_CHR_Request, str_len);  // Convertion en char
    
    www.fastrprint(F("GET "));
    www.fastrprint( l_CHR_Request );   
    www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\r\n"));
    www.fastrprint(F("\r\n"));
    www.println();
    
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }
  Serial.println(F("-------------------------------------"));
 
  /* Read data until either the connection is closed, or the idle timeout is reached. */
  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      Serial.print(c);
      lastRead = millis();
    }
  }
  www.close();
  Serial.println(F("-------------------------------------"));
 
  /* You need to make sure to clean up after yourself or the CC3000 can freak out */
  /* the next time your try to connect ... */
  Serial.println(F("\n\nDisconnecting"));
  cc3000.disconnect();
}

Copyright © 2015 Alex-design.fr All rights reserved.