L'interface la plus ancienne des ordinateurs et des microcontrôleurs est l'interface série, souvent marquée Rx/Tx (=Receive/Transmit) ou UART (=Universal Asynchronous Receiver Transmitter). Pour la réalisation technique, des normes ont été publiées sous les noms de RS-232 ou EIA-485. Avec un débit initial de 75 bauds, les premiers ordinateurs se connectent via un modem dans le monde des téléimprimeurs. Les progrès techniques ont ensuite fait passer les vitesses de transmission de 300, 1200, 2400, 9600, 19200 bauds à 56kBaud. C'est alors que l'ère de la DSL a commencé.
Il reste de cette époque ces interfaces qui servent de connexion entre les ordinateurs et les microcontrôleurs. En raison de l'absence de l'ancienne interface COM sur le PC, aujourd'hui un adaptateur USB avec une interface Virtual Comm. Port (VCP) est nécessaire. Le composant essentiel, par exemple ATMega 16U2, CH340/341 ou FT232, peut être installé sur le MCU ou - pour les très petits microcontrôleurs - peut être requis comme un adaptateur USB-série séparé, par exemple l'adaptateur UART-TTLUSB 3.3V 5V Interface CH340G ou FT232-AZ USB to TTL Serial Adapter pour 3.3V et 5V. Le cas échéant, le pilote requis doit être installé sous Windows.
Sur notre micro-contrôleur avec ATMEGA 328P, les broches 2 et 3 (en haut à gauche sur l'image) sont connectées à la puce pour l'interface USB ATMEGA 16U2 ainsi qu'aux broches sortantes 0=RX et 1 =TX. Pendant la programmation et l'utilisation du moniteur série en fonctionnement, les GPIO 0 et 1 ne doivent donc pas être utilisés d'une autre manière. Il est préférable de ne pas les utiliser du tout.
Dans ce blog, cependant, nous voulons connecter des microcontrôleurs les uns aux autres et envoyer des données (par exemple des données de capteurs) d'un MCU à un second microcontrôleur. Le croquis du microcontrôleur émetteur semble assez simple. Le code est identique à celui de l'envoi de données au moniteur série. Ouvrez le port série et envoyez des données avec Serial.print() ou Serial.println().
Voici le sketch pour l'affichage de l'humidité relative et de la température dans le moniteur série, en même temps que le micro contrôleur "envoyant" (télécharger) :
// broche GPIO pour les données
// DHT22 (AM2302)
Dht dht(Dhtpin, Dhtttype);
annuler d'installation(annuler) {
En série.Commencer(9600);
En série.Imprimeur(F("Test DHT22!"));
dht.Commencer();
}
annuler boucle(annuler) {
flotter H = dht.Ahumeur();
flotter t = dht.Lire la température();
En série.imprimer(F("T ="));
En série.imprimer(t);
En série.imprimer(F("° C H ="));
En série.imprimer(H);
En série.Imprimeur(F(" % "));
retard(1000);
}
Pour le deuxième micro contrôleur, nous démarrons à nouveau l'IDE Arduino.
Attention : Pour ouvrir deux ports com virtuels différents, l'IDE Arduino doit être démarré (instancié) une deuxième fois, une nouvelle fenêtre n'est pas suffisante.
Tout d'abord, le sketch pour la réception des données est téléchargé, puis TX et RX sont chacun connectés en croix.
Attention : Tant que les sketches sont téléchargés sur l'un ou l'autre des micro-contrôleurs, les MCU ne doivent pas être connectés entre eux. Nous y remédions en utilisant SoftwareSerial. Grâce à cela, nous pouvons également recevoir des données et afficher (éventuellement d'autres données) dans le moniteur série en même temps. Nous en reparlerons plus tard.
Voici d'abord le schéma du circuit :
En raison des tensions différentes au niveau du micro contrôleur avec ATMega 328P (5V) et du D1 mini (3.3V), j'ai installé un diviseur de tension avec 1 kOhm et 2.2 kOhm entre TX au micro contrôleur émetteur et RX au D1 mini. Vous pouvez également utiliser un convertisseur de niveau logique.
Voici les explications pour la bibliothèque SoftwareSerial
Comme mentionné au début, le matériel Arduino a un support intégré pour la communication série sur les broches 0=RX et 1=TX (qui va également à l'ordinateur via la connexion USB). Par conséquent, les broches numériques 0 et 1 ne doivent pas être utilisées dans le programme si possible.
Le support série natif est fourni par un matériel (intégré dans la puce) appelé UART. Ce matériel permet à la puce ATMega de recevoir une communication série même en travaillant sur d'autres tâches, tant qu'il reste de la place dans le tampon série de 64 octets.
La bibliothèque HardwareSerial est intégrée dans l'IDE Arduino et n'a pas besoin d'être incluse (exception : ESP32 Serial1 et Serial2).
La bibliothèque SoftwareSerial est conçue pour fournir une communication série supplémentaire sur d'autres broches numériques de l'Arduino, en utilisant un logiciel pour reproduire la fonctionnalité (d'où le nom "SoftwareSerial"). Il est possible d'initialiser plusieurs ports série logiciels à des vitesses allant jusqu'à 115200 bps, mais n'en utiliser qu'un à la fois. Un paramètre optionnel permet d'utiliser des signaux inversés pour les appareils qui requièrent ce protocole.
Pour utiliser cette bibliothèque, il faut d'abord l'inclure avec :
Ensuite, un objet avec un nom librement choisi, souvent mySerial ou SoftSerial, est instancié avec les broches utilisées (7 et 8 dans l'exemple) :
SoftwareSerial myserial(7,8,); // RX, TX
Il faut noter que la broche RX est capable d'interruption.
Enfin, l'objet mySerial est lancé dans la fonction void setup() avec la vitesse (baud rate) souhaitée (les baud rates de 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 31250, 38400, 57600, et 115200 sont autorisées) :
myserial.Commencer(9600);
Vous trouverez de plus amples explications et, surtout, des restrictions sous https://www.arduino.cc/en/Reference/SoftwareSerial
Voici un aperçu des méthodes/fonctions (avec un lien vers la documentation Arduino) :
SoftwareSerial(), Disponible(), Commencer(), Écoute(), débordement(), coup d'oeil(), en train de lire(), imprimer(), Imprimeur(), liste(), l'écriture()
Et voici le croquis pour la réception des données (Télécharger):
SoftwareSerial SoftSerial;
// Variables globales pour stocker les données entrantes
int dateness = 0;
Chaîne de caractères base de données="";
Chaîne de caractères base de données="";
annuler d'installation() {
// Début Comms série avec 9600 bauds
En série.Commencer(9600);
SoftSerial.Commencer(9600, Swserial_8n1, 4, 5, faux); // rx = 4, tx = 5
}
annuler boucle() {
// Lorsque les données sont disponibles ...
SI (SoftSerial.Disponible() > 0) {
// Lecture de données entrants
dateness = SoftSerial.en train de lire();
// Format des données est ascii (0..255),
// donc la conversion en char ()
SI (Carboniser(dateness) != '\ N') {
base de données += Carboniser(dateness);
}
Autre {
En série.Imprimeur("Base de données");
En série.Imprimeur(base de données);
En série.Imprimeur();
base de données = base de données;
base de données="";
}
}
}
Notes sur ce croquis:
Les données sont reçues au format ASCII sous forme de caractères individuels. Pour la suite du traitement, nous avons d'abord besoin de la concaténation des caractères en une chaîne de caractères. Tant que la fin de la ligne (\n) n'est pas atteinte, les différents caractères (données) sont assemblés dans le jeu de données de la chaîne de caractères après conversion avec char().
Si le caractère reçu est égal au saut de ligne (\n), le saut vers autre chose se produit avec la sortie de la chaîne de données dans le moniteur série, le stockage de la chaîne dans une seconde variable dataSet (avec la majuscule S) pour un traitement ultérieur, et la réinitialisation de dataset à la chaîne vide pour recevoir à nouveau des données.
Bien entendu, la chaîne complète peut être placée dans le WLAN domestique comme serveur web avec un microcontrôleur ESP et s'afficher entièrement dans le navigateur du PC ou du smartphone. Toutefois, si vous souhaitez poursuivre le traitement des valeurs de température et d'humidité relative, la chaîne de caractères doit être décomposée et les caractères convertis en valeurs numériques respectives avec décimales (float).
Pour cela, nous avons besoin des fonctions substring() et toFloat(). Les lignes correspondantes dans le code sont :
Chaîne de caractères Ttring = base de données.sous-chaîne(de, à);
Chaîne de caractères Hstring = base de données.sous-chaîne(de, à);
T = Ttring.flotter();
H = Hstring.flotter();
La dernière question qui se pose est de savoir quelles valeurs nous devons utiliser pour from et to afin d'obtenir les deux sous-chaînes de telle sorte que nous puissions ensuite les convertir en nombres à virgule flottante (=floating point !).
Au premier essai, j'ai compté les caractères. Le comptage de l'indice commence à 0, from est l'indice inclusif, à partir duquel la sous-chaîne commence, to est l'indice de fin exclusif, c'est-à-dire le premier caractère après. Cela fonctionne tant que les valeurs de température et d'humidité ont deux chiffres avant la virgule. Les températures à un chiffre ou les signes négatifs perturbent le comptage. Nous avons donc besoin de points de référence pour les indices. J'ai décidé de déterminer l'indice de T et de H respectivement, car les fonctions pour les caractères (isAlpha(), isAlphaNumeric(), isAscii(), isControl(), isDigit(), isGraph(), isHexadecimalDigit(), isLowerCase(), isPrintable(), isPunct(), isSpace(), isUpperCase(), isWhitespace() ) étaient malheureusement inadaptées à ce but.
Donc, sans plus attendre, j'ai programmé une boucle for dans laquelle de l'index=0 à la dernière position (fonction length() ) on vérifie si charAt(i) est égal à 'T' ou 'H'. (Remarque : char nécessite des guillemets simples). J'avais maintenant une référence pour chacune de mes sous-chaînes. Les valeurs exactes dépendent, bien sûr, de la chaîne de caractères envoyée.
pour (int je=0; je<=base de données.longueur(); je++)
{
SI (base de données.Charret(je) == "T ') indice = je;
SI (base de données.Charret(je) == "H") index = je;
}
Voici le croquis complet (à télécharger) :
pour (int je=0;je<=base de données.longueur();je++)
Softwaresérial Softsherial;
// variables globales pour stocker les données entrantes
int calotte = 0;
Chaîne de caractères base de données="";
Chaîne de caractères base de données="";
int indice;
int index;
flotter T;
flotter H;
annuler d'installation() {
// commencez les comms série avec 9600 bauds
En série.Commencer(9600);
Softsherial.Commencer(9600, SWSERIAL_8N1, 4, 5, faux);
}
annuler boucle() {
// lorsque les données sont disponibles ...
SI (Softsherial.Disponible() > 0) {
// lire les données entrantes
calotte = Softsherial.en train de lire();
// Format de données est ASCII (0..255),
// Conversion donc en caractères ()
SI (Carboniser(calotte) != "\ n ') {
base de données += Carboniser(calotte);
}
Autre {
En série.Imprimeur("Base de données");
En série.Imprimeur(base de données);
En série.Imprimeur();
base de données = base de données;
base de données="";
Conversion de données();
}
}
}
annuler Conversion de données() {
pour (int je=0; je<=base de données.longueur(); je++)
{
SI (base de données.Charret(je) == "T ') indice = je;
SI (base de données.Charret(je) == "H") index = je;
}
Chaîne de caractères Ttring = base de données.sous-chaîne(indice+4, index-5);
Chaîne de caractères Hstring = base de données.sous-chaîne(index+4, index+9);
T = Ttring.flotter();
H = Hstring.flotter();
En série.imprimer("T =");
En série.Imprimeur(T);
En série.imprimer("H =");
En série.Imprimeur(H);
En série.Imprimeur();
}
J'espère que ces petits trucs et astuces sur la transmission des données et la manipulation des chaînes de caractères vous seront utiles. J'ai moi-même dû bricoler pendant un certain temps. Vous pourrez bientôt lire le résultat global de nos expériences, y compris la sortie des données dans le WLAN, dans l'E-Book de notre kit de démarrage Smart Home.
2 commentaires
Bernd Albrecht
Hallo, Herr Schulz,
vielen Dank für Ihr Interesse an unseren Produkten und Blog-Beiträgen. Gerne nehmen wir auch Anregungen auf oder schreiben über „Ihr Projekt“. Bitte haben Sie Verständnis, dass wir keine maßgeschneiderten Auftragsarbeiten annehmen können.
Zu Ihrer Anfrage teile ich Ihnen folgendes mit:
zu 1. Kennen Sie eigentlich die Suchfunktion auf der Seite von AZ-Delivery.de? Ich habe das Wort Ethernet eingegeben und erhalte eine Registerkarte „Products“ (12) und auf Mausklick gelange ich zur zweiten Registerkarte „Pages“ (18). Hier finden Sie die Beiträge zu den Ethernet-Shields und – Modulen.
zu 2. Für das Senden von Befehlen (z.B. Datenabfrage) an den Micro Controller empfehle ich auch die Arduino IDE. In der obersten Zeile können Sie dann z.B. T für Temperatur und P für Luftdruck (pressure) eingeben und auf Senden drücken. Mit der Befehlszeile Serial.read() im Sketch lesen Sie den gesendeten Buchstaben und können dann mit einer if-Abfrage den gewünschten Wert senden. Für die Aufzeichnung größerer Datenmengen benötigen Sie ein Speichermedium. Produkte und passende Blog-Beiträge habe ich über das Wort „Daten“ im Suchfenster erhalten.
zu 3. Zum Thema Anzeige von Messdaten im heimischen WLAN haben wir ebenfalls in der Vergangenheit bereits im Blog berichtet. Ein weiterer Beitrag befindet sich im Vorlauf und sollte zeitnah erscheinen.
zu 4. Um einfache Emails zu versenden, benötigen Sie ein Modul für eine SIM-Karte. Ich selbst habe ein GPS-Modul verwendet, um Positionsdaten zu senden. Aber es gibt auch ein einfaches GSM-Modul im Sortiment.
Thomas Schultz
Ich finde die Idee des Blogs wirklich toll, abr leider ist bis jetzt nicht ein Projekt aufgetaucht,
das mich interessieren würde. Diese Beitrag mc zu mc ist zwar etwas in dieser Richtung, aber immer noch nicht, was ich bräuchte. Was ich mir wünschen würde wären folgende drei Beispiele:
1. Der Einsatz eines LAN-Shields
2. Die Steuerung eines Arduino via USB vom PC aus. Daten- und Befehlsaustausch.
Der arduino soll Daten sammeln und auf Anforderung an den PC schicken oder auf der Platte ablegen.
Und, es sollten vom PC aus Befehle (z.B. via DOS-Zeile) an den Arduino geschickt werden.
3. Die Steuerung z.B. eines Relais via Webseite ist ja bereits behandelt worden. Was mich aber interessieren würde ist, wie ich permanent auf der Webseite einen Meßwert anzeigen lassen kann.
Aktuelles Anwendungsprojekt: Ich möchte gerne den ELV-Gewitterwarner mit einer Logik versehen und aus der Ferne ablesbar machen.
Und zum Schluss noch eine Frage: Kennt ihr eine Möglichkeit um einen Schaltzustand per Emails oder noch besser als Pushnachricht an mehrere Freunde schicken kann.