Comme beaucoup d'autres produits faits maison, j'utilise régulièrement des microcontrôleurs AVR pour toutes sortes de bricolages amateurs. Et grâce au concept Arduino, ces objets artisanaux prennent désormais également un aspect élégant. En effet, pour quelque 300-400 roubles, nous obtenons une carte multicouche miniature avec un masque, une sérigraphie et avec les périphériques pour le microcontrôleur complètement élevés dessus (d'ailleurs, dans la version SMD!). Je ne parle pas de toutes sortes de plug-ins de la même série "Arduino": capteurs, contrôleurs, écrans et ensembles entiers, les périphériques supplémentaires dont nous avons tant besoin. Et encore une fois, tout est également bon marché et d'excellentes performances. Pratiquement plus besoin d'élever quelque chose et de souder sur le "genou".
Mais tous ces différents métiers amateurs, nécessitent naturellement une
programmation préalable. Et plus tard, avec diverses améliorations, je dois constamment reflasher ces métiers. Il est clair qu'il est plus pratique de le faire à distance que de les faire constamment glisser vers un programmeur normal. En général, grâce à la même plate-forme Arduino, il existe de nombreuses options ici: Bluetooth, ZigBee, un canal radio avec votre protocole personnel, IR et même Wi-Fi. Tous vous permettent d'établir un contact sans fil avec votre microcontrôleur. Mais nous nous arrêterons sur la dernière option. Il y a quatre raisons principales:
1: moderne, l'Internet des objets!
2: il y a un routeur sans fil dans chaque appartement, enregistrez vos appareils sur le réseau domestique et le tour est joué!
3: vos métiers font un saut révolutionnaire dans leur développement; non seulement ils peuvent être programmés à distance, mais ils peuvent désormais également communiquer avec le monde qui les entoure: l'horloge électronique prend indépendamment l'heure exacte des horloges du serveur NTP, les appareils exécutifs sont contrôlés à l'autre bout de la ville ou du pays, les appareils d'enregistrement stockent les données accumulées dans nuage etc. etc.
4: il existe une merveilleuse série de puces ESP8266 sur lesquelles
il n'est pas très facile de mettre en œuvre tout cela.
De plus, dans cet article, en utilisant l'exemple d'un bras mécanique sur des servos, la programmation à distance et l'échange de données avec un PC (ou autre) avec des appareils basés sur des microcontrôleurs AVR seront démontés et démontrés. Je tiens à noter tout de suite que tous les programmes énumérés ci-dessous sont purement démonstratifs et n'ont aucune valeur commerciale. Par conséquent, les affirmations, telles que pourquoi le programmeur est si castré et mal fonctionnel ou pourquoi il n'y a pas de services supplémentaires partout, ne sont pas acceptées. Étant donné que les codes sont ouverts, tout le monde peut les terminer à leur discrétion, mais j'ai encore assez de travail.
Il est supposé que le lecteur connaît déjà à la fois les modules Arduino (blindages) et la connexion et le firmware de l'ESP8266. En fait, une énorme quantité de matériel a été publiée sur le Web expliquant les bases du travail avec ces appareils et je ne voudrais pas répéter ici. Pour les débutants, à la fin de l'article, il y a une liste de liens utiles sur ces questions, où vous pouvez trouver beaucoup d'informations
, pourquoi tout cela ne fonctionne pas pour vous . D'après mon expérience en tant qu'ancien ingénieur en électronique, je peux déclarer de manière responsable que 99% des problèmes sont les suivants:
1. Mauvais contacts. Étant donné que les boucliers «Arduino» impliquent une commutation entre eux via des fils de type «père-mère», et non par soudage, très souvent quelque chose, quelque part, disparaît. Vérifiez-le. Et en effet, comme on dit, l'électronique est la science des contacts.
2. Problèmes d'alimentation. Ne fournissez pas 5 volts de puissance là où 3,3 est requis. Parfois, la fumée provient de l'ESP8266. Bien que, d'un autre côté, il digère sans problème les signaux logiques des appareils à cinq volts.
3. Problèmes avec une puissance suffisante. L'ESP8266 a un caractère vil et peut parfois consommer près de trois cents milliampères, bien qu'avant il puisse se contenter de trente. En conséquence, la fragile carte stabilisateur 3,3 volts "Arduino", à laquelle vous ne pouvez rien ajouter, elle est connectée, elle descend immédiatement à des valeurs microscopiques. Et vous ne pouvez pas comprendre pourquoi cela fonctionne, alors non.
4. Confusion avec les conclusions. Vérifiez toujours quels signaux vont où. Le récepteur RXD doit se connecter à l'émetteur TXD, ainsi que le TXD à RXD, mais MOSI doit se connecter à MOSI, et MISO à MISO, etc.
5. Ne vous fiez pas aux résistances de rappel en circuit dans l'ESP8266, tirez toujours les fils à zéro ou à la puissance, à travers des résistances externes de 5 à 10 kilo-ohms, et pas seulement un cavalier. Sinon, vous pouvez, au mieux, obtenir une consommation actuelle sans précédent, puis sentir l'odeur désagréable du plastique brûlé.
6. Bancs de logiciels. Étant donné que les logiciels pour les utilisateurs individuels sont écrits par les mêmes passionnés, des problèmes du micrologiciel lui-même et des bogues apparaissent périodiquement lors de la mise à jour des versions du même micrologiciel. Il est traité en rampant dans les forums concernés, parfois même en anglais. Certains camarades ont même affirmé que la puce ESP elle-même était humide comme le temps à Saint-Pétersbourg, mais d'autre part, il y avait aussi l'opinion que depuis 2014 (l'année de sa première sortie), la situation avec cela s'était considérablement améliorée (contrairement à la météo).
7. Problèmes mystérieux. Il s'agit d'un phénomène rare, mais consommateur de nerfs. Par exemple, je n'avais pas d'appareil «Arduino» distant. C'est plutôt arrivé, mais avec des erreurs. Mais cela s'est passé sans erreur si un câble du programmeur était accroché (mais sans le programmeur lui-même). "AHA," me dis-je, et soudai un condensateur de 15 pF entre la broche de transfert de données et la broche de synchronisation. Tout fonctionnait. Mais le jour a tué.
Commençons donc par le plus simple. Nous avons un membre mécanique MechArm (mais pas ce que Howard Volovits a assemblé) fabriqué en Chine et un ordinateur personnel avec Windows. La tâche consiste à flasher à distance le programme et à le gérer depuis l'ordinateur.

Pour le contrôleur de contrôle, nous prenons une jolie écharpe miniature Arduino Nano avec une pierre ATmega328P. Cette planche est parfaitement enfoncée dans le bras mécanique.

Maintenant, nous décidons comment nous allons le programmer. Il existe trois méthodes principales qui conviennent le mieux au micrologiciel distant: via l'interface SPI, via le chargeur de démarrage intégré, via le port JTAG.
L'option la plus simple est bien sûr le chargeur de démarrage intégré (chargeur de démarrage). Il s'agit d'une mémoire préenregistrée dans FLASH, un programme qui reçoit un code selon un certain protocole (par exemple, en utilisant l'UART le plus simple) et l'écrit à l'emplacement du programme chargé avec des commandes spéciales. Cela fonctionne, par exemple, le bootloader ARDUINO IDE. Après une réinitialisation ou un démarrage, le chargeur de démarrage attend un certain temps pour recevoir des données et s'il n'attend pas, il démarre l'exécution du programme à partir de l'adresse zéro. Si les données arrivent, il les écrit dans la section programme. Après la prochaine réinitialisation, le programme téléchargé démarre. En détail, j'ai peut-être décrit de manière inexacte, mais l'essentiel est juste cela. Par conséquent, nous n'avons besoin que de trois sorties pour la programmation: récepteur RTD, réinitialisation RESET et masse GND. En général, l'émetteur TRD est également utilisé pour vérifier le programme enregistré, mais pour les applications de démonstration simples (pas pour une centrale nucléaire), la vérification peut être omise.
Le chargeur lui-même est écrit en langage assembleur, il y a des exemples de chargeurs simples dans les fiches techniques sur AVR. Vous pouvez creuser un chargeur de démarrage existant s'il est dans le domaine public et simplement l'utiliser sous une forme prête à l'emploi si le protocole par lequel il fonctionne est connu. La seule mise en garde est que vous devez configurer l'AVR dans un mode spécial en faisant clignoter des bits de fusible spéciaux, ce qui est fait par un programmeur normal, puis vous pouvez également coudre le chargeur de démarrage dans la mémoire du microcontrôleur (c'est-à-dire que vous ne pouvez pas vous passer d'une programmation).
La deuxième option consiste à programmer via l'interface série SPI. Il n'y a pas de chargeur de démarrage interne ici, mais nous programmons en envoyant des commandes spéciales puis des données via l'interface susmentionnée. Ici, nous avons un chargeur de démarrage externe, mais vous devez toujours l'écrire. En plus de RESET et GND, quatre sorties MOSI supplémentaires sont utilisées pour la transmission, les données MISO, la synchronisation SLK, la sélection de la puce CS. Mais en général, vous pouvez également supprimer MISO et CS. Les données ne seront acceptées (il n'y aura alors aucune vérification du programme), et nous n'avons qu'un seul cristal.
Chaque approche a ses avantages et ses inconvénients (et je n'ai pas du tout considéré JTAG, car la vie humaine est courte). Mais à la fin, je me suis penché vers SPI parce que j'étais trop paresseux pour écrire dans l'assembleur, mais je n'ai pas trouvé de chargeurs de démarrage prêts à l'emploi ouverts (je ne l'ai pas bien cherché).
Pour construire un canal sans fil, j'ai, comme déjà mentionné, choisi la puce ESP8266 actuellement très connue - un microcontrôleur, ou plutôt, un SoC (System-on-Chip) entier du fabricant chinois Espressif avec une interface Wi-Fi. En plus du Wi-Fi, il se distingue par la possibilité d'exécuter des programmes à partir de la mémoire flash externe. Et spécifiquement pour mon projet, j'ai pris l'ESP8266-07 avec 512 Ko de mémoire à bord.

En général, n'importe quel ESP8266 convient où il y a des jambes supplémentaires pour implémenter SPI. Par conséquent, le ESP8266-01 le plus simple ne nous convient pas, car il a très peu de jambes pour les ports d'entrée / sortie. Mais d'un autre côté, la différence de prix est inférieure à cent roubles et ils sont disponibles à parts égales. Eh bien, les grandes cartes de débogage avec ESP, où un tas de périphériques sont pratiques, ne nous conviennent pas non plus, car elles ne vont pas là où nous voulons les pousser dans notre bras mécanique.
L'essence globale de l'idée en général était la suivante. Le corps du programme chargé dans le microcontrôleur est transféré de l'ordinateur à l'ESP sans fil via WI-FI (au sein de votre réseau domestique). Et ESP déjà câblé à l'aide de l'interface SPI écrit ce programme directement dans la mémoire FLASH du microcontrôleur. Ensuite, il le réinitialise naturellement et permet au programme chargé de s'exécuter. De plus, l'ESP doit avoir une unité indépendante, qui gère également l'échange de données avec le microcontrôleur, car nous voulons non seulement programmer, mais aussi échanger des données avec lui. En particulier, pour un projet avec MechArm, après avoir enregistré le programme, nous transmettons toujours des signaux d'asservissement afin de mettre cette main en mouvement. Par conséquent, sur l'ESP lui-même, il est conseillé pour nous d'élever un serveur TCP pour le transfert de programme et un serveur UDP pour contrôler MechArm. En conséquence, ces serveurs rejoignent le réseau domestique et écoutent attentivement s'il y a quelqu'un qui veut télécharger un nouveau code sur MechaArm ou le faire signe à quelqu'un.
J'ai donc trouvé sur le Web que le firmware vous permet déjà de programmer l'AVR par voie aérienne, mais là le principal problème est que pour quoi d'autre ce firmware ne peut plus être utilisé. Après la programmation, nous aimerions également communiquer avec AVR à distance.
Quels logiciels utiliserons-nous:
Pour PC, j'ai tout écrit en JAVA,
IntelliJ IDEA . Mais en gros, vous pouvez tout faire, l'essentiel pour nous est d'écrire un client qui enverra le programme pour flasher AVR à ESP8266.
J'écris moi-même des programmes pour AVR dans
ATMEL STUDIO , en langage C, rarement en assembleur. Je n'utilise pas de croquis Arduino en principe, presque toutes les bibliothèques nécessaires sont écrites en une heure ou deux, avec une compréhension complète de son travail. J'ai essayé les croquis, mais tant que vous n'avez pas de système d'exploitation sur l'AVR, les croquis enlèveront les périphériques à un ami et échoueront régulièrement. Oui, l'IDE Arduino lui-même, par rapport à ATMEL STUDIO, est bien sûr une chose très primitive. Mais ici, la question est, bien sûr, controversée, pour les sciences humaines et les écoliers, ce sera plus amusant et plus facile, probablement, avec des croquis.
Pour programmer l'ESP8266, j'ai utilisé le firmware NodeMCU et j'ai écrit des programmes en Lua. Non, j'aimerais écrire en Java et en C, mais il n'y en a pas en ESP. Le langage Lu tel qu'il est appliqué à notre tâche n'est pas difficile, pour maîtriser quelques trivialités. Et en fait, pour télécharger des programmes et les déboguer sur ESP, j'ai pris l'
IDE ESPlorer . Un produit domestique gratuit (mais vous pouvez le donner à l'auteur), qui ne peut bien sûr pas être comparé aux environnements mentionnés ci-dessus, mais comme le dit le cheval du cadeau ... Mais pour utiliser ESPlorer et écrire sur LUA, nous devons d'abord changer le firmware de base (fourni par le fabricant) dans la puce ESP8266 pour nouveau. Le programme NODE MCU PyFlasher nous aidera dans cette entreprise. Je veux dire, cela aidera à le reflasher. Et nous allons créer le firmware nous-mêmes et le remettre entre les mains du site Web des créateurs:
NodeMCU . Et vous pouvez en savoir plus sur ce processus
ici:Tout est très accessible et compréhensible. Nous ajoutons la prise en charge SPI et les opérations binaires aux bibliothèques de base (dans LUA, dans notre cas, les opérations binaires sont surchargées et inutiles). De nombreuses bibliothèques ne doivent pas être insérées dans le firmware des bibliothèques, car en raison de la présence de divers logiciels sur l'ESP8266, il reste très peu de mémoire, une sorte de 20 kB pathétique.
Bien sûr, vous pouvez simplement prendre le firmware fini, dont beaucoup traînent déjà sur Internet, mais je ne le recommande pas. Du moins parce que certains d'entre eux ne prennent pas en charge les opérations sur les bits (et nous en avons besoin) et qu'il n'y a pas de régulation du taux de transfert de données via SPI.
En conséquence, ils sont transmis par défaut à une vitesse de 40 MHz divisée par un petit coefficient et donc l'AVR n'a pas le temps de les digérer.
Qui est trop paresseux pour créer un firmware, vous pouvez télécharger le mien depuis le
cloud .
Nous avons maintenant le firmware et nous devons le charger dans l'ESP8266 au lieu de celui de base. Pour ce faire, nous avons besoin d'un simple adaptateur USB - UART.
Nous connectons les jambes TXD à RXD et RXD à TXD, nous faisons la masse commune, mais n'utilisons pas, il semble, une sortie d'alimentation 3,3 V pratique sur l'adaptateur. Dans la plupart des cas, l'ESP8266 le vidange complètement. Par conséquent, nous le nourrissons séparément. Ensuite, nous avons mis l'ESP en mode de programmation (GP0 au sol, si quelqu'un a oublié) et
exécutons le
NODE MCU PyFlasher .

Surtout, n'oubliez pas d'effacer la mémoire flash (oui, efface toutes les données), sinon, selon la version du micrologiciel, après la programmation, des déchets inutiles peuvent rester dans la mémoire, qui à leur tour déversera des déchets dans la console lors de travaux ultérieurs. Avant cela, j'utilisais un logiciel, où il n'y avait pas d'option pour effacer la mémoire au préalable, j'étais terriblement tourmenté, car rien ne fonctionnait. Et le cercueil vient d'ouvrir, seule la vérité sur le forum anglais des créateurs de NODE MCU.
Après avoir acquis le firmware nécessaire, nous pouvons maintenant écrire et déboguer des programmes LUA (il y a aussi MicroPython, mais je ne l'ai pas utilisé) en utilisant des API très pratiques de NODE MCU. Nous lançons l'ESPlorer déjà mentionné.

Nous le configurons également pour fonctionner avec ESP8266, définissons les paramètres de la connexion série. Tout est assez simple et répété à plusieurs reprises sur Internet.
Maintenant, nous écrivons le programme sur LUA, que nous téléchargeons ensuite sur ESP8266:
Lua bootloader pour AVR écrit sur ESP8266<b>function InstrProgrammingEnable ()
Lorsque les fonctions concernées effectuent les actions suivantes:
function InstrProgrammingEnable () - met le microcontrôleur en mode de programmation avec une commande spéciale envoyée via SPI.
Fonction ProgrammingEnable () - il suffit de réinitialiser l'AVR pendant 25 ms avant de commencer la programmation
function ProgrammingDisable () - après la fin de la programmation, nous traduisons les sorties SPI dans ESP8266 dans un état inactif afin qu'elles n'interfèrent pas avec nous lors de l'exécution de code sur le microcontrôleur (du coup elles y sont utilisées)
function InstrFlashErase () - nous effaçons la mémoire flash du microcontrôleur avant de programmer. Pourquoi cela doit être expliqué n'est pas nécessaire.
fonction InstrStorePAGE (H, adresse, données) - cette commande écrit l'octet du programme dans le tampon interne du microcontrôleur. Mais ce n'est pas l'enregistrement flash lui-même, car le flash est écrit ici page par page à 128 octets.
fonction InstrWriteFLASH (page_address_low, page_address_high) - mais il s'agit d'un enregistrement flash et cela prend du temps, faites attention au retard de 5000 μs.
Programmation de fonction (charge utile) - la fonction la plus grande et la plus importante utilisant les fonctions ci-dessus. Il prend le programme transmis en morceaux de 1024 octets, les divise en octets et forme les adresses pour eux, puis l'envoie au microcontrôleur dans le tampon interne et initialise l'enregistrement flash tous les 128 octets. Puis il prend le kilo-octet suivant de code et répète l'opération, naturellement avec un décalage dans les adresses, afin d'écrire plus loin et de ne pas écraser l'enregistrement. Au début, j'ai essayé de transférer le programme entier, mais lorsque je dépasse 6 kilo-octets dans ESP8266, la mémoire disponible se termine et elle se bloque. Un kilo-octet s'est avéré être l'unité la plus pratique, car il est soigneusement divisé en parties et facilement transmis via TCP (nous devons toujours l'obtenir de l'ordinateur). Une taille plus grande n'est également pas nécessaire, TCP, vous savez, dans la version actuelle limite le paquet transmis à 1500 ou octets (mais pour une raison quelconque, 1440 m'a été transmis, en quelque sorte).
Comme si rien de compliqué, mais quelques écueils devaient être surmontés.
Vient ensuite le BLOC PRINCIPAL. Dans ce document, nous:
Nous sommes enregistrés dans un réseau sans fil.
Nous créons d'abord un serveur TCP qui écoute trois commandes:
1. «programme» (nous programmerons)
2. «données» (nous allons modifier les données),
3. «stop» (on arrête tout).
Si nous programmons, nous initialisons d'abord le SPI et créons un autre serveur TCP qui saisit les données (code du micrologiciel) par kilo-octet et appelle les fonctions de programmation du microcontrôleur pour eux. Je comprends qu'il semble stupide de créer un deuxième serveur, mais c'est une nécessité, car l'API locale prend en charge la création d'un seul socket, et nous devons séparer les commandes "programme" et "données" avec les données transmises, car à l'œil, elles ne diffèrent pas, il y a des octets et voici des octets.
Si nous voulons ne pas programmer, mais échanger des données, en les envoyant dans notre cas au microcontrôleur, alors nous envoyons d'abord la chaîne «data» via TCP. En réponse à cela, un serveur UDP sera déjà créé (je vous rappelle que nous ne gérons pas dynamiquement avec une main mécanique et que nous n'avons pas besoin de retards avec la formation de paquets TCP, et envoyons en effet un octet dans son ensemble une trame TCP en harmonie). Et les datagrammes UDP seront petits et se formeront rapidement.
Une fois l'UART initialisé, chaque octet reçu sans fil est déjà envoyé via le câble TXD au microcontrôleur, qui est obligé de l'accepter si le programme correspondant y est mis à jour. L'échange de données dans une autre direction n'est pas non plus difficile à organiser, mais je ne l'ai pas encore mis en œuvre.
Eh bien, avec la commande "stop", les serveurs mentionnés ci-dessus (sauf le tout premier) ferment les connexions et le serveur principal passe à nouveau dans l'état d'attente des commandes "programme" et "données".
Étant donné que l'interface SPI est émulée par programme dans ESP8266, les ports d'E / S pour les signaux CS, CLK, MISO, MOSI, RESET (pour AVR), vous pouvez utiliser tous ceux disponibles, et non ceux indiqués dans mon chargeur de démarrage. En outre, il s'est avéré que CS et MISO, en principe, peuvent également être interrompus dans ce cas, cela fonctionnera sans eux. Eh bien, une broche est utilisée sur la LED intégrée à la carte ESP8266 de sorte qu'elle clignote parfois et indique que le programme est toujours vivant.
Les vérifications des erreurs d'enregistrement ne sont pas effectuées (à l'exception de la première demande à AVR, mais ces informations sont simplement affichées sur la console), l'EEPROM n'est pas programmé, plus de 32 Ko n'est pas cousu - bref, il y a encore du travail à faire. La vitesse d'échange SPI est d'environ 115 Kbit, en quelques secondes tout clignote, environ, comme avec un programmeur série ordinaire comme ISP500).
Prenez le code, entrez vos réseaux et mots de passe, compilez sur ESplorer, appelez-le «init» (pour qu'il démarre au redémarrage) et envoyez-le à ESP8266. Ça devrait marcher. Dans le sens de travailler en tant que programmeur sans fil, au moins.
Nous allons maintenant traiter avec la partie gestionnaire - un ordinateur personnel.
En fait, nous devons prendre le fichier HEX dans lequel vos programmes écrits dans l'environnement ATMEL STUDIO se tournent et l'envoyer via WI-FI au port socket que nous connaissons (dans ce cas 4000). Le petit hic, c'est que nous avons besoin d'un fichier BIN binaire pour le transfert, et ATMEL STUDIO ne nous plaît qu'avec un HEX. Il existe deux voies de sortie; ou convertissez-le au format BIN avec un convertisseur de programme spécial, tel que WinHex, ou faites-le vous-même dans votre programme. Je ne l'ai pas encore fait, mais cela ne semble pas difficile, il faut couper le titre et faire autre chose.
En conséquence, j'ai écrit le programme de chargeur de démarrage dans JAVA (principalement parce que je ne sais rien faire d'autre), travaillant dans l'environnement IntelliJ IDEA tout simplement magnifique et gratuit. Il crée un client TCP qui recherche un serveur s'exécutant sur ESP8266. S'il le trouve, il le contacte et lui envoie un fichier situé à une telle adresse. Le code est ci-dessous.
Téléchargeur de fichiers JAVA sur PC import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.List; public class Net { <b> public static void main(String args[]) { new Http_client(4000); }</b> } class Http_client extends Thread { int port; String s; String Greetings_from_S; Http_client(int port){ this.port = port; start(); } public void run() {
Ici, bien sûr, trop de blessures ont été enroulées, toutes sortes de prêts, en principe, ne sont pas nécessaires. Si la connexion TCP est établie, elle l'est. Le seul problème était que le fichier ne voulait en aucun cas être envoyé en morceaux de 1024 octets, comme j'avais vraiment besoin, bien que j'indique explicitement la taille. Apparemment, il existe une sorte de tampon final inaccessible à partir de JAVA, et il envoie des paquets de la taille qu'il souhaite, ce qui est complètement inacceptable pour le côté récepteur. Au début, j'ai essayé de retarder afin que le tampon se lasse d'attendre les prochaines pièces et de l'envoyer tel quel. Mais le retard a commencé à fonctionner lorsqu'il a atteint 10 secondes, ce qui semblait en quelque sorte un peu trop pour un kilo-octet transféré.
Mais ensuite, j'ai remarqué que pour une raison quelconque, la première pièce se déroule toujours sans heurts, laquelle a été commandée, et dès la seconde commence une bacchanale imprévisible. Par conséquent, j'ai demandé au client d'ouvrir la connexion, d'envoyer une partie du code en 1024 octets et de fermer la connexion. Et ainsi de suite jusqu'à l'envoi de l'intégralité du fichier. Tout fonctionnait bien.
La seule chose à faire est d'installer le runtime JAVA sur l'ordinateur. Mais je commence généralement tout de suite à partir d'IntelliJ IDEA car là, vous pouvez toujours voir ce qui se passe dans la console (mais ici, vous avez besoin d'un environnement JAVA). Bien sûr, d'une manière intelligente, vous devez créer une interface graphique. Autrement dit, la fenêtre où le chemin d'accès au fichier tombe, la possibilité de modifier les numéros de port dans la fenêtre et, bien, d'autres choses nécessaires. Et collectez tout cela sous la forme d'un fichier exécutable.
Et tapericha, comme Koroviev disait, revenons aux citoyens, en fait, au membre mécanique MechArm, qui a été mentionné au tout début. Nous avons maintenant la possibilité de le programmer à distance, puis de le gérer. Passons au programme de contrôle sur le côté du microcontrôleur.
Dans ce cas, nous devons contrôler quatre servos. Voici ceux-là.
Un tel entraînement est contrôlé par des impulsions rectangulaires d'une période de 20 ms (50 Hz) avec un facteur de marche de 2 à 4%. Autrement dit, 2% est un virage complet dans un sens, 4% dans l'autre. La tâche est juste pour le PWM intégré dans l'AVR.

Un servomoteur est utilisé pour se déplacer à gauche et à droite; le second sur soi - de soi; troisième de haut en bas; le quatrième est la griffe elle-même, qui doit être comprimée et développée. Tout est écrit en C et compilé dans un fichier HEX dans ATMEL STUDIO. Un type de programme un peu étrange est dû au fait qu'au départ, la main était contrôlée depuis le clavier attaché avec des fils au microcontrôleur. Mais les fils d'hier, nous devons encore évoluer.
Vous pouvez bien sûr utiliser des croquis pour les servos de "ARDUINO", mais je ne les aimais pas. C'est plus intéressant de t'écrire. De plus, les quatre servos devraient fonctionner simultanément, et non en mode multiplexé, lorsque le PWM passe successivement à chaque servo. Car personne n'a annulé la gravité, et un membre surélevé descendra immédiatement si les impulsions de contrôle cessent d'arriver au servomoteur correspondant. Je ne suis pas sûr que l'esquisse «ARDUINO» permette un fonctionnement simultané pour quatre servos. Mais nous-mêmes pouvons bien écrire un programme qui répond aux exigences nécessaires. En général, en l'absence d'un système d'exploitation qui sépare les agneaux des chèvres, l'utilisation de croquis en concurrence pour les périphériques du microcontrôleur (et nous ne savons même pas lesquels à l'avance) est trop bogué.
Voici le code lui-même que nous écrivons sur l'Arduino Nano en utilisant l'ESP8266-07.
Programme de contrôle de MechArm pour microcontrôleur AVRmega328P #define F_CPU 16000000 #include <avr/io.h> #include <stdint.h>// #include <avr/interrupt.h> #include <math.h> // #include <stdio.h> // - #include <avr/eeprom.h> #include <setjmp.h> #include <stdlib.h> // #define UART_BAUD_RATE 115200 // 1 20 #define COUNTER1_OFF TCCR1B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER1_ON TCCR1B=0b00000011 // 0 0 1 #define COUNTER0_OFF TCCR0B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER0_ON TCCR0B=0b00000100 // 2 B2(PD6) 3(PD7) #define COUNTER2_OFF TCCR2B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER2_ON TCCR2B=0b00000110 volatile uint16_t period_20ms; volatile uint8_t State_of_keyboard; volatile uint8_t start_position [6]; volatile int8_t number_servo; ISR(USART_RX_vect)// UART { State_of_keyboard=UDR0; return; } ISR(TIMER0_COMPA_vect)// 0 { PORTB &=~(1<<0); TIMSK0&=~(1<<OCIE0A); TIFR0 |=(1<<OCF0A); return; } ISR(TIMER0_COMPB_vect) // 1 { PORTB &=~(1<<1); TIFR0 |=(1<<OCF0B); TIMSK0 &=~(1<<OCIE0B); return; } ISR(TIMER2_COMPA_vect)// 2(PD6) { PORTD &=~(1<<6); TIFR2 |=(1<<OCF2A); TIMSK2 &=~(1<<OCIE2A); return; } ISR(TIMER2_COMPB_vect)// 3(PD7) { PORTD &=~(1<<7); TIFR2 |=(1<<OCF2B); TIMSK2 &=~(1<<OCIE2B); return; } ISR(TIMER1_OVF_vect){// 20 COUNTER1_OFF; COUNTER0_OFF; COUNTER2_OFF; TIFR0 |=(1<<OCF0A); TIFR0 |=(1<<OCF0B); TIFR2 |=(1<<OCF2A); TIFR2 |=(1<<OCF2B); TIFR1 |=(1<<TOV1); PORTB |=(1<<0)|(1<<1); PORTD |=(1<<6)|(1<<7); TCNT1 = period_20ms; // 20 TCNT0 = 0; TCNT2 = 0; TIMSK0|=(1<<OCIE0A)|(1<<OCIE0B); TIMSK2|=(1<<OCIE2A)|(1<<OCIE2B); OCR0A=start_position[1];// 0 0 OCR0B=start_position[2];// 0 1 OCR2A=start_position[3];// 0 2 OCR2B=start_position[4];// 0 3 COUNTER1_ON; COUNTER2_ON; COUNTER0_ON; return; } void time_delay(long i) { cli();sei(); long k; i*=2000; for(k=0;k<i;k++){;;}; } void timer_counter0_1_2_INIT()// 0,1,2 { // 1 TCCR1A &=~(1<<COM1A0)|~(1<<COM1A1)|~(1<<COM1B0)|~(1<<COM1B1);// TCCR1A &=~(1<<WGM10)|~(1<<WGM11); TCCR1B &=~(1<<WGM12)|~(1<<WGM13);// period_20ms=60575; TCNT1 = period_20ms; TIMSK1|=(1<<TOIE1);//| //TIFR0 TOV0 // 0 TCCR0A &=~(1<<COM0A0)|~(1<<COM0A1)|~(1<<COM0B0)|~(1<<COM0B1);// TCCR0A &=~(1<<WGM00)|~(1<<WGM01); TCCR0B &=~(1<<WGM02);// // 2 TCCR2A &=~(1<<COM2A0)|~(1<<COM2A1)|~(1<<COM2B0)|~(1<<COM2B1);// TCCR2A &=~(1<<WGM20)|~(1<<WGM21); TCCR2B &=~(1<<WGM22);// COUNTER1_ON; } void servo_reset() { start_position[1]=97;// 0 0 start_position[2]=70;// 0 1 start_position[3]=92;// 0 2 start_position[4]=124; // 0 3 COUNTER1_ON; time_delay(100); } void servo_go( int8_t moven, uint8_t servo_position_max, uint8_t servo_position_min)// { switch (moven){ case 1: start_position[number_servo]++; if(start_position[number_servo]==servo_position_max){start_position[number_servo]--;};// +90 break; case 2: start_position[number_servo]--; if(start_position[number_servo]==servo_position_min){start_position[number_servo]++;};//6 -90 break; }; time_delay(20); return; } //PORTB-0,1, PORTD - 6,7 - , 8- COUNTER 0 int main(void) { uint8_t servo_positionmin=0, servo_positionmax=0; int8_t const servo_position1max = 122, servo_position1min=58; // int8_t const servo_position2max = 120, servo_position2min=36;// int8_t const servo_position3max = 125, servo_position3min=68;// int8_t const servo_position4max = 129, servo_position4min=108;// 128 108 sei(); DDRD = 0B11000010; // D2-D5 , D0 RX, D1 TX, D6 D7 3 4 PORTD = 0B00111110; // DDRB |=(1<<0)|(1<<1);// PORTB &=(~1<<0)|(~1<<1); UCSR0A=0;// UART UCSR0B=0b10010000; UCSR0C=0b00000110; UBRR0L=103;// 115200 UBRR0H=0; timer_counter0_1_2_INIT(); servo_reset(); PORTB |=(1<<5); while (1) { switch (State_of_keyboard) { case 1:// 1 PD0(PB0) number_servo=1; servo_positionmin=servo_position1min; servo_positionmax=servo_position1max; break; case 2: // 1 PD0(PB0) number_servo=1; servo_positionmin=servo_position1min; servo_positionmax=servo_position1max; break; case 5: number_servo=2; // 2 PD1(PB1) servo_positionmin=servo_position2min; servo_positionmax=servo_position2max; break; case 6: number_servo=2; // 2 PD1(PB1) servo_positionmin=servo_position2min; servo_positionmax=servo_position2max; break; case 7: number_servo=3;// 3 PD6 servo_positionmin=servo_position3min; servo_positionmax=servo_position3max; break; case 8: number_servo=3;// 3 PD6 servo_positionmin=servo_position3min; servo_positionmax=servo_position3max; break; case 3: number_servo=4; // 4 PD7 servo_positionmin=servo_position4min; servo_positionmax=servo_position4max; break;// case 4: number_servo=4; // 4 PD7 servo_positionmin=servo_position4min; servo_positionmax=servo_position4max; break;// // c - , 4- // , } if(State_of_keyboard==1||State_of_keyboard==3||State_of_keyboard==5||State_of_keyboard==7) { servo_go(1,servo_positionmax,servo_positionmin);// } if(State_of_keyboard==2||State_of_keyboard==4||State_of_keyboard==6||State_of_keyboard==8) // { servo_go(2,servo_positionmax,servo_positionmin);// } time_delay(20); } }
L'essence du programme ressort clairement du texte et des commentaires. Nous utilisons un compteur T1 pour une période exemplaire de 20 ms et des compteurs T0, T2 pour émettre des signaux PWM vers quatre lignes du port d'E / S, puisque chacun de ces deux compteurs peut fonctionner sur deux appareils.
Le programme définit les positions initiales des servos en chargeant les registres de comptage OCR0A, OCR0B, OCR2A, OCR2B. Des constantes de contrainte sont également introduites, car nous n'avons pas toujours besoin d'une plage de 180 degrés. Eh bien et plus loin, par interruption de l'UART, le programme capture le numéro envoyé par ESP8266 (de 1 à 8) et le traduit en une commande pour le servo correspondant. Il y a quatre disques, chacun fonctionnant dans deux directions, donc des entiers de un à huit suffisent. Une fois le nombre sélectionné, le contenu des registres de compteur ci-dessus est soit incrémenté soit décrémenté, modifiant respectivement le rapport cyclique de l'impulsion de commande et l'angle de rotation du servo-variateur sélectionné. Les entraînements que nous n'avons pas sélectionnés conservent l'ancienne valeur de l'angle de rotation (puisque le contenu des registres correspondants, bien qu'ils aient été mis à jour, n'ont pas changé) et continuent de maintenir le bras mécanique dans la même position.
Il ne nous reste plus qu'à écrire un programme de contrôle, désolé pour la tautalogie, pour contrôler une main mécanique directement depuis l'ordinateur via WI-FI.
Le code est également écrit en JAVA, mais un peu anobli. Une interface graphique et la possibilité de modifier les numéros de port et l'adresse réseau de l'ESP8266 sont apparues.

Ce qui se passe là-bas est clair depuis la fenêtre. Je ne
fournis pas
le texte du programme ici (il est disponible sur
Github ), pour la raison suivante: environ 95% de son volume est la création de fenêtres et le traitement du signal à partir du clavier. Mais l'essentiel est le même que le programme précédent sur JAVA. Un client est créé, seul UDP, qui, selon la touche enfoncée, envoie un numéro de 1 à 8, à l'adresse indiquée sur le port spécifié.
Ou vous pouvez immédiatement obtenir l'exécutable
d'ici . Pour les machines 64 bits avec Windows. Même un environnement JAVA installé n'est pas nécessaire. Tout a déjà été poussé dans 178 Mo.
Ainsi, le stylo mécanique a été assemblé, débogué et présenté à son frère pour son anniversaire. Peut ramasser des piles de plastique avec de la vodka, sur Skype dans une autre ville. Bien que pour le bras mécanique d'Howard Volovitsa de la série "The Big Bang Theory", elle est encore loin.
Mais ensuite, dans les articles suivants (si quelqu'un est intéressé), nous pourrons le gérer à partir d'un téléphone mobile, faire de même avec un chariot robotique à quatre roues et mettre à jour l'heure des montres électroniques des serveurs de montre sur Internet. Ensuite, nous avons mis l'ancien smartphone sur le chariot et en avons transféré la vidéo vers le réseau neuronal avec reconnaissance des formes, puis les signaux de contrôle vers les moteurs,
oh, quelque chose me porte déjà ...Et tout cela avec le magnifique ESP8266.
Je serais heureux si quelqu'un trouvait l'article intéressant.
[1]
Brochage et spécifications de l'ESP8266[2]
Connexion de l'ESP8266. Démarrage rapide.[3]
Mise à jour du firmware de NodeMCU via le cloud[4]
NODE MCU PyFlasher[5]
ESPlorer - IDE pour ESP8266[6]
Programmation C pour AVR[7] Revue d'articles - «Programmation de microcontrôleurs en langage C»[8] Description de l'API NodeMCU[9] Référence Lua[10] Scripts et modules Lua[11] IntelliJ IDEA[12] Téléchargez Java sur votre ordinateur maintenant![13] Atmel Studio