La fin. La partie précédente .
Table des matières:
Capteur extérieur. Logiciels
Parlez du logiciel pour le capteur d'outre-mer. Après cela, vous obtiendrez un système complet avec lequel vous pourrez déjà expérimenter.
Permettez-moi de vous rappeler que le serveur est une unité centrale à domicile qui peut communiquer avec Internet via le WiFi, et le client est un capteur prêt à l'emploi qui transmet les données au serveur par voie hertzienne.
Le code source du serveur et du client est ici .
Les textes sources sont accompagnés de commentaires détaillés.
Presque rien n'a besoin d'être configuré sur le client.
L'émetteur radio nRF24L01 +, plus précisément la bibliothèque RadioHead, nécessite la spécification des adresses serveur et client. Les adresses sont fournies si vous avez plusieurs serveurs et clients. Une adresse est n'importe quel entier. Lorsqu'un client envoie un paquet de données à un serveur, il indique à quel serveur ce paquet est destiné. Le serveur, connaissant à son tour sa propre adresse, détermine si ce paquet lui est destiné.
Par conséquent, SERVER_ADDRESS
sur le serveur et sur le client doit ĂŞtre identique, mais CLIENT_ADDRESS
pour différents clients doit être différent. En d'autres termes, si vous connectez un autre nouveau capteur à notre système à l'avenir, alors CLIENT_ADDRESS
devra être modifié pour cela.
// #define SERVER_ADDRESS 10 #define CLIENT_ADDRESS 20 // !!!
Le RF_CHANNEL
canal radio RF_CHANNEL
doit être le même pour tout le monde. Par défaut, c'est 2. J'ai changé le numéro par défaut, vous pouvez en choisir un autre.
Les réglages du voltmètre pour mesurer la tension d'alimentation de la batterie doivent être modifiés:
// , const float r1 = 100400; // 100K const float r2 = 9960; // 10K // // http://localhost/arduino-secret-true-voltmeter/ const float typVbg = 1.082; // 1.0 -- 1.2
Pour économiser de l'énergie, la bibliothèque légère de faible puissance pour Arduino est utilisée .
Voici mes mesures de consommation réelles pour l'Arduino Pro Mini avec cette lib:
- généralement 25mA
- lorsque vous travaillez avec DHT le mĂŞme
- avec transmission radio 38 mA
- Ă LowPower.idle 15 mA
- Ă LowPower.powerdown 7,5 mA
Le client prend des mesures de température, d'humidité et de tension d'alimentation, regroupe tout cela dans une structure de données, envoie les données au serveur et «s'endort». Si des erreurs se sont produites pendant le transfert, le transfert est immédiatement répété.
Le serveur (central, unité d'origine), à ​​son tour, reçoit les données, confirme la réception et les traite.
Base de données, MySQL, PHP, serveur WWW
Après le travail effectué, nous avons une conception entièrement fonctionnelle de la station météo. Mais maintenant il y a un sou une douzaine de ces stations météorologiques, l'artisanat local n'est plus à la mode. Après tout, nous avons un Internet des objets.
Par conséquent, nous parlerons de la façon dont l'accès à ceux-ci est effectué sur votre Internet, nous y attacherons une base de données et une face Web à notre station météo.
L'énoncé du problème pour la "webcam":
- recevoir et stocker les données de la station météo: température, humidité, pression atmosphérique, tension d'alimentation
- afficher ces données
- construire des graphiques.
Dans ce cas, nous avons besoin d'un hébergement avec prise en charge d'Apache, PHP et MySQL avec le module mysqli. Et ces conditions sont satisfaites par presque tous les hébergements de la planète Terre. Ou au lieu d'héberger, votre ordinateur jouera le rôle d'un serveur connecté à un routeur de réseau domestique et disposant d'un accès à Internet.
Création de base de données
Commençons par le tout début, à savoir avec la conception et la création de la base de données.
Les bases de données sont votre monde et vous pouvez l’étudier pendant longtemps. Nous allons donc brièvement aborder uniquement les éléments dont nous avons directement besoin.
Tous les scripts SQL se trouvent dans le répertoire weather-station/server/php-sql/
Où commence la conception de la base de données? Avec une représentation logique et physique.
Vue logique ou schéma de base de données:
- Tableau de température et d'humidité DHT
- capteur de pression et de température tableau de données BMP
- les tables indiquées n'ont aucune relation entre elles, plus précisément, aucun lien n'est nécessaire.
Le schéma physique repose sur un SGBD et des types de données spécifiques. Il est plus facile de démonter avec un exemple spécifique. Le script SQL make_tables.sql
les schémas logiques et physiques.
Chaque table doit avoir un champ type
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT
Le nom du champ peut différer dans différentes bases de données, mais il n'y a qu'un sens: il s'agit d'un identifiant unique, une clé d'enregistrement. Pour l'avenir, si vous voyez une base de données dans des tables qui n'ont pas un tel compteur, vous devez savoir que cette base de données a été conçue par une personne très éloignée de la programmation, très probablement des sciences humaines.
Nous stockons les données des capteurs du même type dans une table; pour les capteurs d'un autre type, nous créons une autre table. Cela complique légèrement la base de données et la liaison PHP avec celle-ci, mais cela simplifie l'extension ou la modification de l'ensemble du système à l'avenir.
Il y a deux tableaux dans notre projet. La table arduino_dht
stocke les données des capteurs de type DHT (température, humidité), la table arduino_bmp
stocke les données des capteurs de type BMP (température, pression). Si à l'avenir vous souhaitez avoir, par exemple, un capteur de gaz ou un détecteur de mouvement, alors créez des tableaux supplémentaires, ne soyez pas paresseux. Si vous connectez un autre capteur de type DHT11 ou DHT22, vous n'avez pas besoin de créer une table supplémentaire, utilisez la table arduino_dht
. J'espère que le principe est clair: une entité physique distincte est une table distincte.
Si les données de plusieurs capteurs du même type sont stockées dans un tableau, comment les distinguer? Pour ce faire, entrez un champ dans chaque table
idSensor INTEGER
En fait, c'est CLIENT_ADDRESS
que nous avons enregistré dans le client/client.ino
pour chaque instance du client-client distant et dans server/server.ino
pour le capteur qui est connecté directement au serveur - l'unité centrale.
Dans les systèmes industriels, il devrait y avoir un autre tableau - la correspondance d' idSensor
et sa description verbale et lisible par l'homme. Par exemple, un capteur avec idSensor
= 2 est «Température, humidité dans l'appartement» , etc. Mais dans notre projet, nous ne compliquerons pas, rappelez-vous simplement que:
- un capteur avec
idSensor
, il s'agit de CLIENT_ADDRESS
, égal à 11 - c'est le capteur domestique sur le serveur - l'unité centrale, - un capteur avec
idSensor
, c'est aussi CLIENT_ADDRESS
, égal à 20 - c'est le premier (dans notre projet et le seul) client de capteur basé sur la fenêtre.
Ensuite. Les tableaux stockent les données suivantes:
- ipRemote - Adresse IP de la station météo (serveur) d'où proviennent les données, utile pour le débogage et la surveillance,
- dateCreate - date de la création de l'enregistrement,
- millis - utile pour le débogage, c'est le temps en millisecondes depuis le début de l'esquisse sur l'Arduino,
- température - température
- humidité - humidité
- tension - tension d'alimentation,
- pression - pression
- erreurs - le nombre d'erreurs (non utilisées). Il était destiné à stocker le nombre d'erreurs de transmission, etc., afin que vous puissiez évaluer à distance l'état de l'ensemble du système.
Comme vous pouvez le voir, les arduino_bmp
arduino_dht
et arduino_bmp
très similaires, la différence ne concerne que les champs de pression et d'humidité, et il y a un désir de tout vider dans un tas (table). Mais la première forme normale n'ordonne pas de le faire, de nombreux programmeurs débutants ont essayé de contourner cela, mais aucun d'entre eux n'a réussi, et nous ne le ferons pas. Voilà comment ne pas remarquer la loi de la gravitation universelle, pour le moment elle pourrait bien se révéler.
La table arduino_error_log
utile pour le débogage - c'est un journal des erreurs et autres messages système.
La création d'une base de données et de son utilisateur avec des droits est décrite dans make_db.sql
Ceci est fait une fois, le nom et le nom d'utilisateur de la base de données peuvent venir avec le vôtre. Et ce qui doit être fait exactement, c'est de définir votre mot de passe.
PHP et serveur web
Tous les paramètres de l'interface Web sont stockés dans config.php
. Modifiez-le en fonction des paramètres de votre base de données.
Définissez votre fuseau horaire au format PHP
date_default_timezone_set('Europe/Prague')
Tous les fuseaux horaires disponibles sont décrits ici .
Définissez votre clé secrète pour l'accès (sous forme de nombre) qui doit correspondre à la constante SOURCE_KEY
du sketch server.ino
$access_key = '***KEY***';
Dans notre serveur Web, il n'y a pas d'autorisation, de saisie de mot de passe, cela compliquerait la conception entière. Pour un prototype, ce n'est pas nécessaire. Par conséquent, toute la protection repose sur le fichier robots.txt
, l'absence d' index.php
et cette clé secrète d'accès.
Le script PHP principal weather.php
accepte une simple requête HTTP GET avec des données et les stocke dans les tables de base de données correspondantes. Si la clé $access_key
ne correspond pas, la demande sera rejetée.
Le weather-view.php
utilisé pour afficher les tableaux de données et contient des hyperliens vers d'autres scripts d'interface Web. Appelez-le comme ça
http:
Par exemple
http:
weather-view.php
affiche des étiquettes simples où vous devez vous rappeler que:
- le capteur avec l'identifiant 11 est le capteur domestique sur le serveur,
- Le capteur avec id 20 est un capteur de fenĂŞtre.
Le script function.php
contient des fonctions communes Ă tous les scripts PHP.
Le chart-dht.php
est responsable de la cartographie à l'aide de Google Charts . Voici, par exemple, un graphique de la tension d'alimentation du capteur étranger. La tension augmente lors d'une journée ensoleillée en raison de la batterie solaire, puis l'alimentation électrique des batteries se décharge progressivement.

export-dht.php
exporte les données des tables de base de données MySQL vers un fichier CSV. Pour une importation et une analyse supplémentaires dans des feuilles de calcul.
export-voltage.php
exporte les données sur la tension d'alimentation du capteur de fenêtre de la base de données MySQL vers un fichier CSV. Utile pour le débogage.
truncate.php
efface toutes les tables, c'est-à -dire supprime toutes nos données. Utile pour le débogage. Il n'y a pas de lien vers ce script depuis weather-view.php
, vous devez donc l'appeler via un lien direct dans la barre d'adresse de votre navigateur avec $access_key
.
Lors de la réception de données, la fonction mysqli_real_escape_string()
est couramment utilisée pour empêcher des valeurs incorrectes d'entrer dans la base de données.
N'oubliez pas de mettre robots.txt
à la racine de votre site pour l'empêcher de pénétrer dans les moteurs de recherche.
ESP8266, WiFi et transfert de données
Et maintenant, revenons Ă l'esquisse server.ino
, à la partie qui se connecte au point d'accès WiFi et envoie des données au serveur Web.
Comme je l'ai déjà écrit, je ne pouvais pas trouver une bibliothèque normale pour Arduino pour contrôler le module ESP8266 à l'aide des commandes AT, j'ai dû me "regrouper". Permettez-moi également de vous rappeler que vous devez flasher une version spécifique du firmware dans ESP8266-01. Et maintenant, quand tout est prêt, voyons comment cela fonctionne.
Pour accéder au serveur Web dans l'esquisse server.ino
, server.ino
devez modifier ces constantes
const String DEST_HOST = " "; // habr.com const String DEST_PORT = " "; // 80 const String DEST_URL = "/ /weather.php"; const String SOURCE_KEY= " "; // $access_key config.php
Dans server.ino
dans la fonction void setup()
, l'ESP8266 passe d'abord en mode Station, c'est-Ă -dire il commence Ă fonctionner en tant que client WiFi
espSendCmd(«AT+CWMODE_CUR=1», «OK», 3000)
puis suit la connexion au point d'accès
espState = espConnectToWiFi()
Si la connexion ne se produit pas, la tentative est répétée (une fois)
if ( espState != ESP_SUCCESS ) { delay(5000); Serial.println("WiFi not connected! Try again ..."); espConnectToWiFi(); }
Sélectionnez ensuite le mode de connexion unique TCP / IP
espSendCmd("AT+CIPMUX=0", "OK", 2000)
Lors de l'envoi de données de capteurs de type DHT au serveur Web, une fonction est utilisée qui indique le type=dht
données comme type=dht
espSendData( "type=dht&t=" + String(dhtData.temperature) + "&h=" + String(dhtData.humidity) + "&v=" + String(dhtData.voltage) + "&s=" + String(CLIENT_ADDRESS) )
Lors de l'envoi de données de capteurs BMP vers un serveur Web, la même fonction est utilisée avec le type de données indiqué par type=bmp
espSendData( "type=bmp&t=" + String(temperature_bmp) + "&p=" + String(pressure_bmp) + "&s=" + String(CLIENT_ADDRESS) )
La fonction espSendData()
accepte une chaîne de requête HTTP GET et l'envoie au serveur Web comme prévu.
À l'intérieur de lui-même, espSendData()
vérifie la disponibilité du module ESP en lui envoyant la commande «AT», puis il vérifie la connexion WiFi et se reconnecte si nécessaire. Ensuite, les données sont envoyées et la connexion TCP est fermée.
Application Android
De nos jours, quand tout le monde peut clignoter une LED, vous ne surprendrez personne avec une station météo. Mais si l'engin sait communiquer avec le serveur via le WiFi, a un visage web et une application mobile, alors c'est quelque chose! Par serveur, nous entendons ici bien sûr le serveur d'applications, c'est-à -dire dans notre cas, il s'agit d'une liaison PHP et d'un SGBD MySQL. Il n'y a pas assez de cerises sur le gâteau, à savoir l'application Android, que nous allons écrire maintenant.
L'architecture
L'architecture de l'ensemble de la plateforme logicielle de station météo est simple:
- la partie serveur (unité centrale) de la station météo collecte les données des clients capteurs à distance
- puis il transfère des données au serveur Web d'applications, qui enregistre ces données dans la base de données
- L'application Android (ou toute autre application distante: iOS, navigateur) demande des données à un serveur Web et les affiche à l'écran.
Sur l'écran de l'appareil Android, nous afficherons les lectures de capteur actuelles et les plus récentes.
HTTP GET et JSON
La question qui doit être résolue en premier lieu est de savoir comment les données seront transférées du serveur Web vers l'application Android.
Il n'est pas nécessaire d'inventer quoi que ce soit ici, tout a déjà été inventé pour nous - ce sont HTTP GET et JSON.
Dans notre cas, une simple demande GET au serveur Web peut être compilée et déboguée manuellement alors que l'application Android n'est pas encore prête.
En Java et Android, il existe des bibliothèques prêtes à l'emploi pour le traitement des données au format JSON. JSON est un format de texte lisible par l'homme, utile pour le débogage.
Afin de générer des données actuelles à partir des capteurs des stations météorologiques, créez un nouveau script PHP last-data-to-json.php sur le serveur Web.
Appel de script:
http://<>/last-data-to-json.php?k=<access_key>
oĂą <access_key>
, comme nous nous en souvenons, est la clé d'accès secrète à la base de données.
Exemple de réponse au format JSON:
{ "DHT 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:03", "temperature":"19", "humidity":"26", "voltage":"5.01" }, "DHT 20":{ "idSensor":"20", "dateCreate":"2016-04-18 07:36:26", "temperature":"10", "humidity":"26", "voltage":"3.7" }, "BMP 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:22", "temperature":"19", "pressure":"987.97" } }
Il faut rappeler que nous avons 3 capteurs. Leur ID et leur type (DHT ou BMP) sont codés en dur dans tout le code de la station météo. Cette méthode de codage hardcore est idéologiquement incorrecte, mais pour un prototype dessiné au genou (où une solution rapide et facile est nécessaire), c'est un compromis raisonnable.
$idSensor = 11; // DHT $idSensor = 11; // BMP $idSensor = 20; // DHT
Le last-data-to-json.php
prend les dernières données de ces capteurs hétérogènes de la base de données et les emballe au format JSON. La sélection des données de la base de données «de bout en bout» se déroule ainsi:
SELECT <> FROM <> ORDER BY id DESC LIMIT 1;
Android
Nous allons maintenant écrire une application Android simple qui demande, reçoit, décode les données JSON et affiche des informations à l'écran.
Notre application Android sera aussi simple que possible, seule l'essence de la technologie. Plus loin autour de ce "squelette" il sera déjà possible de remonter différentes "beautés".
Voici une capture d'écran de ce qui devrait se traduire par

Comme vous pouvez le voir, l'interface utilisateur est juste Spartan, basée sur LinearLayout, rien de plus.
En haut de TextView, l'ID des capteurs et leurs données météorologiques sont affichés. Le bouton Actualiser lance une deuxième demande au serveur Web. Ensuite dans EditText est le seul paramètre de programme - c'est l'URL de demande dans le formulaire
http://< >/last-data-to-json.php?k=<access_key>
Que faut-il noter?
Dans le manifeste, ajoutez des lignes autorisant Internet et vérifiant l'état de la connexion réseau:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
Travailler avec le réseau et recevoir des données du site Web est le suivant.
Nous utilisons AsyncTask pour créer une tâche d'arrière-plan distincte du thread d'interface utilisateur principal. Cette tâche en arrière-plan prend l'URL de la demande et l'utilise pour créer la HttpURLConnection
.
Une fois la connexion établie, AsyncTask charge le contenu de la page Web (JSON) en tant que InputStream. Ensuite, InputStream est converti en chaîne, qui est décodée à l'aide de JSONObject et affichée dans l'interface utilisateur à l'aide de la méthode onPostExecute()
.
Dans MainActivity.java, modifiez l'URL de votre:
private static final String defUrl = "http://host/dir/last-data-to-json.php?k=< >";
il sera utilisé par défaut la première fois que vous exécuterez une application Android.
Épilogue
Eh bien, quelque chose a déjà fonctionné. Ensuite, vous pouvez optimiser quelque chose, remplacer quelque chose, vous pouvez tout jeter, mais aussi emprunter quelque chose.
Un autre point sensible distinct est la consommation d'énergie . Je recommande de lire les commentaires sur les articles où il existe de nombreux conseils pratiques.
Ă€ l'infini ... et au-delĂ .