FLProg - Intégration indépendante dans le programme des contrôleurs personnalisés


Pendant longtemps, le projet FLProg n'a pas été couvert à Habré. Cela est dû au manque de temps pour écrire des articles et même à mes propres problèmes personnels. Mais le projet n'est pas mort, il vit et se développe. En moyenne une fois par mois, la prochaine version du programme est lancée. Depuis la dernière publication , le rendu du schéma a été entièrement refait (grâce à cela, les frises ont été éliminées lors du rendu), le système de référence croisée pour le projet, et un système d'analyse du projet pour les erreurs ont été introduits. Le code du programme lui-même a été porté vers une version plus récente du langage de programmation. Pour cette raison, d'un point de vue positif (de mon point de vue, bien sûr, les utilisateurs me soutiennent), l'interface du programme a changé. De nombreux blocs intéressants ont été ajoutés. Mise à l'échelle du schéma et recherche de blocs implémentées.

Mais encore, le principal problème du projet reste que le développeur du programme est une personne (c'est moi), et le nombre de différentes cartes contrôleur, capteurs, capteurs, cartes d'extension fabriqués à la fois par des chinois et récemment par nos fabricants est en constante augmentation. Et les utilisateurs veulent les essayer ou les utiliser dans leurs projets. Pour les périphériques, à un moment donné, ce problème a été plus ou moins résolu par moi à l'aide de la création d'un éditeur de blocs personnalisé. Cette étape, comme on dit, "shot", et maintenant, presque sur la plupart des cartes périphériques existantes, sur Internet ou sur le forum du programme , vous pouvez trouver le bloc utilisateur correspondant. Eh bien, ou sur le même forum (ou dans un groupe à Vkontakte ), demandez aux gourous locaux d'en écrire un. Habituellement, vous pouvez d'une manière ou d'une autre convenir.

Il est maintenant temps de résoudre le deuxième problème - ce sont les cartes contrôleur.

Récemment, une version bêta du programme avec le numéro 6.0 a été publiée. Dans cette version, l'éditeur de descriptions utilisateur des contrôleurs est implémenté. Comme pour les blocs personnalisés, les descriptions peuvent être regroupées dans des bibliothèques, enregistrées en tant que descriptions distinctes ainsi que des bibliothèques entières sous forme de fichier et partagées.

Avec cet article, je commence une série d'au moins deux articles dans lesquels nous verrons comment utiliser cet éditeur. Dans le premier article, avec la permission de shiotiny, je vais essayer de décrire sa carte ShIoTiny. Dans le deuxième article, nous allons essayer de trouver virtuellement un analogue d'un véritable contrôleur industriel et le décrire.

Commençons donc.

Ouvrez le programme FLProg. Dans le menu "Tools", sélectionnez "Controller Custom Descriptions Editor".



La fenêtre de l'éditeur de description s'ouvre.

Les descriptions personnalisées peuvent être combinées dans la bibliothèque avec n'importe quelle profondeur d'imbrication. Par conséquent, nous créons d'abord une bibliothèque de description.



Définissez le nom de la bibliothèque.



Après cela, nous allons créer une description du contrôleur dans la bibliothèque.



Et donnez-lui un nom:



Lors de la création d'une description de contrôleur, nous arrivons immédiatement à la branche des paramètres généraux.



Ici, nous pouvons changer le nom, définir le type de CPU, définir la taille de l'EEPROM, changer le numéro de version de la description.

Étant donné que la carte ShloTiny est basée sur le contrôleur ESP8266, nous la sélectionnons. Lors du choix d'un contrôleur, le volume EEPROM correspondant est automatiquement apposé. Si nécessaire, cette valeur peut être modifiée. Le numéro de version par défaut de la nouvelle description est défini sur 1.

À l'avenir, lors de la modification des descriptions existantes, il est recommandé de la modifier dans le sens de l'augmentation. Lorsque vous utilisez cette description dans un projet, le programme compare la version de la description dans le projet et dans la bibliothèque. Si le numéro de version de la description dans la bibliothèque est supérieur à celui du projet, l'élément de mise à jour de la description dans le programme apparaît dans le menu "Projet" du programme. Si vice versa, un élément apparaîtra pour mettre à jour la description dans la bibliothèque. Eh bien, si la description du contrôleur utilisé dans le projet ne se trouve pas du tout dans la bibliothèque, l'élément pour entrer la description du projet dans la bibliothèque apparaîtra dans le même menu.

Également dans ce fil, vous pouvez écrire une description textuelle du contrôleur qui aide à sa sélection.

Pour appliquer les modifications apportées avant de passer à une autre branche des paramètres du contrôleur, cliquez sur le bouton "Appliquer". Si cela n'est pas fait, les modifications ne seront pas enregistrées.

Considérez maintenant le schéma de circuit de la carte ShloTiny.



La carte a trois entrées numériques, trois sorties numériques, une entrée analogique et une entrée pour le capteur. Un total de huit conclusions du conseil d'administration.

Dans l'éditeur, allez dans la branche «Conclusions du contrôleur» et définissez le nombre de conclusions, n'oubliez pas de cliquer sur le bouton «Appliquer» après cela.



Le programme générera le nombre requis de conclusions. Nous passons au premier d'entre eux.



Sur cette branche, vous pouvez spécifier un autre nom de sortie, qui sera affiché dans le programme. S'il est absent, le programme affichera PinN où N est le numéro de broche dans la liste des broches. Je vous recommande de lui écrire une inscription au tableau dans le champ du nom alternatif. Cela facilitera la compréhension de la conclusion à tirer. Pour la carte décrite, nous y mettrons la valeur de Input1 conformément au schéma électrique. Ainsi, dans ce fil, vous pouvez écrire une description individuelle de la sortie, par exemple, pour indiquer les fonctionnalités de son application. Si nécessaire, vous pouvez également spécifier un alias pour la sortie, qui sera affiché dans le programme entre parenthèses après le nom de la sortie.

Après avoir effectué les modifications, n'oubliez pas de cliquer sur le bouton "Appliquer". Par le même principe, appelons les conclusions restantes.



Dans la même branche des principaux paramètres de sortie, les fonctions qu'il exécute lui sont ajoutées.



Les fonctions suivantes peuvent être attribuées à chaque broche.



  • I2C est une fonction de l'une des broches du bus I2C (SDA ou SCL).
  • SPI est une fonction de l'une des broches du bus SPI (MISO, MOSI, SCK, SS).
  • UART est une fonction de l'une des broches de l'interface UART (RX ou TX).
  • Fonction d'entrée analogique
  • Fonction de sortie analogique (pas encore utilisée dans FLProg, backlog pour le futur).
  • Fonction d'entrée / sortie numérique.

Attribuez la fonction d'entrée / sortie numérique de la broche 1. Lors de l'attribution d'une nouvelle fonction (pas encore configurée) à la sortie, la branche «Erreurs» apparaîtra dans l'arborescence du contrôleur et le chemin complet vers la branche de la fonction incorrecte deviendra rouge. Sur la branche "Erreurs", vous pouvez voir une liste des erreurs trouvées dans la description du contrôleur.



Dans ce cas, l'entrée 1 de la fonction «Entrée / sortie numérique» ne spécifie pas le numéro de cette entrée comme numérique. Nous passons à la branche de cette fonction (à l'avenir, je prévois de faire une transition directe vers la branche souhaitée lorsque je clique sur une erreur).



Selon le schéma électrique de la carte, la sortie «Input1» est connectée à la broche GPIO2 du contrôleur. Nous entrons cette valeur dans le champ «Numéro d'entrée numérique». Lors de la compilation d'un projet, cette valeur sera insérée dans le code. Étant donné que l'utilisation de cette entrée en tant que sortie n'est pas fournie, nous supprimons la case à cocher «Peut être utilisé en tant que sortie». Comme toujours, cliquez sur le bouton "Appliquer". De la même manière, configurez les deux autres entrées numériques. Accédez ensuite à la sortie de l'entrée analogique "ADC1" et ajoutez-y la fonction "Entrée analogique".



Dans les paramètres de cette fonction, vous devez spécifier le numéro de cette sortie comme entrée analogique. Selon le schéma, c'est 0 (dans ESP8266, c'est un).



Passez ensuite au paramètre de sortie "1WIRE". Ici, nous y ajoutons la fonction d'entrée / sortie numérique, mais nous interdisons son utilisation à la fois d'entrée et de sortie. Par conséquent, il sera disponible pour la sélection uniquement dans les blocs de capteurs et n'est pas disponible lors de la création d'entrées et de sorties.



Les réglages des sorties «K1» - «K3» sont similaires aux réglages des entrées «Input1» - «Input3» uniquement en cas de sorties, nous interdisons leur utilisation comme entrée.





Accédez à la branche "Images". Dans celui-ci, nous pouvons ajouter des images chargées dans la description du contrôleur, par exemple, avec l'apparence du contrôleur, le brochage, etc.

Veuillez noter que les images sont chargées directement dans la description du contrôleur et qu'elles sont stockées dans un projet créé à l'aide de celle-ci. Par conséquent, ne téléchargez pas de grandes images. Cela entraînera une augmentation de la taille du projet et affectera la vitesse de son ouverture.

L'image est ajoutée à l'aide du bouton "Ajouter une image".



Après avoir sélectionné et chargé une image (seul le format PNG est pris en charge), une branche distincte est créée pour chaque image de l'arborescence. Dans cette branche, vous pouvez spécifier un nom pour l'image téléchargée, qui sera affiché dans les informations du contrôleur.



Si nécessaire, vous pouvez télécharger plusieurs images et les définir dans l'ordre souhaité.





Nous passons à la branche "Blocs standard".



Cette branche affiche les blocs qui peuvent être représentés dans la bibliothèque de blocs standard du programme en fonction des paramètres actuels du programme. Qu'est-ce que ça veut dire. Certains éléments constitutifs du programme sont destinés uniquement à certains types de CPU. Et leur disponibilité dépend du processeur sélectionné. De plus, les blocs conçus pour fonctionner avec SPI, I2C, UART n'apparaîtront dans cette liste que si les fonctions correspondantes sont ajoutées aux broches du contrôleur. Les blocs conçus pour fonctionner avec l'EEPROM n'apparaissent que si la taille de l'EEPROM spécifiée sur la branche des paramètres généraux du contrôleur est supérieure à zéro, ou si la fonction I2C est ajoutée aux broches du contrôleur. Par défaut, tous les blocs de la bibliothèque sont interdits d'utilisation (marqués en orange). Vous pouvez autoriser l'utilisation d'un bloc distinct ou de l'ensemble du dossier de blocs en mettant en surbrillance la branche nécessaire et en cliquant sur le bouton "Autoriser" ou dans le menu contextuel.



Lorsque vous autorisez l'affichage d'un bloc ou d'un dossier de blocs dans le programme, ils sont peints en noir.

Le blocage d'un bloc ou d'un dossier séparé est interdit de la même manière.



Dans un dossier dans lequel tous les blocs ne peuvent pas être affichés, ils sont marqués de trois astérisques avant et après le nom.

Nous interdisons l'utilisation de moteurs, d'horloges en temps réel, d'écrans, d'unités de commande infrarouge, de capteurs (à l'exception des capteurs DS18B20 et DHT22 - comme le développeur de la carte n'a jusqu'à présent annoncé leur prise en charge), des puces d'extension et d'un haut-parleur piézo.



Nous ferons de même pour le langage LAD



N'oubliez pas de les appliquer après avoir apporté des modifications.

Les branches restantes de la description du contrôleur seront discutées dans le prochain article, tandis que les paramètres actuels sont suffisants pour utiliser cette carte particulière dans le programme FLProg.

Pour l'instant, je dirai brièvement que la branche "Blocs spéciaux" est utilisée pour charger des blocs personnalisés dans la description, qui sera affichée dans la bibliothèque de blocs standard du programme utilisant ce contrôleur. La branche «Code spécial» est utilisée pour enregistrer le code qui sera toujours inséré dans le code compilé, et la branche «Bibliothèques spéciales» est utilisée pour charger les bibliothèques dans la description du contrôleur, qui sera téléchargée dans le dossier \ bibliothèques ArduinoIDE avec lequel le programme fonctionne.

Après toutes les modifications, enregistrez la bibliothèque de description du contrôleur.



Essayons maintenant d'utiliser la description du contrôleur que nous avons créée.
Dans le programme FLProg, nous créons un nouveau projet pour le contrôleur.



Ouvrez la fenêtre de sélection du contrôleur.



Et sélectionnez la description que nous avons créée.



Lors du choix d'un contrôleur, vous pouvez voir ses images et, si nécessaire, enregistrer le nécessaire dans un fichier.





Vous pouvez également voir d'autres paramètres



Après avoir sélectionné le contrôleur, confirmez sa sélection:



En conséquence, la fenêtre principale de travail du projet s'ouvre, configurée en fonction du contrôleur sélectionné.



Le but de ce poste ne comprend pas la tâche de formation pour travailler avec le programme FLProg. Ceci est assez bien décrit dans mes articles précédents , sur le site Web du projet et sur le forum du projet . De plus, il existe déjà beaucoup de chaînes sur YouTube où des didacticiels vidéo sur l'utilisation du programme sont publiés. Par exemple, une très bonne chaîne «Key to Arduino» , vient de mener une série de leçons, avec une très bonne présentation du matériel.

Par conséquent, par exemple, nous créons simplement un projet simple et essayons de le compiler.
Tout d'abord, ajoutez l'entrée du contrôleur.



Seules les conclusions que nous avons été autorisés à travailler à ce titre sont disponibles pour sélection en tant qu'intrants.



Créez ensuite une sortie numérique. Seules les conclusions autorisées sont également disponibles ici.



Nous assemblons le circuit de sorte que lorsque le bouton de l'entrée 1 (entrée 1) est enfoncé, le relais K1 (relais 1) s'allume.
Nous retirons également l'unité pour lire les informations du capteur DS18B20 sur une carte de circuit imprimé dans une carte séparée.



Accédez aux paramètres de blocage. Lors de la création du nouveau bus OneWire, nous constatons que toutes les entrées / sorties numériques sont disponibles pour la sélection. Il s'agit d'une faille dans la version 6.0. Mais comme cette version a toujours le statut bêta, elle est excusable. Dans la version 6.1, il sera possible d'interdire l'utilisation d'une broche comme capteur, capteur ou pour les puces d'extension. De plus, dans le prochain billet, je vous dirai une autre façon de résoudre ce problème. Pour l'instant, sélectionnez 1 broche FIL.



Nous configurons le capteur pour définir l'adresse via le tableau.



Nous insérons une nouvelle carte devant la première et y retirons le bloc «OneWire Bus Scan».



Nous le configurons sur le même bus OneWire et sur la même baie sur laquelle est configurée l'unité de lecture du capteur DS18B20.



Nous assemblons un schéma pour un seul démarrage d'un balayage de bus lorsque le contrôleur démarre, en utilisant le bloc R du déclencheur (sélection du bord d'attaque).



Sur une carte avec une unité de lecture de données du capteur DS18B20, nous assemblons un circuit marche / arrêt relais avec hystérésis. Pour cela, nous utilisons deux comparateurs et un déclencheur SR. Grâce à ce schéma, le relais 2 s'active lorsque la température descend en dessous de 10 degrés et s'éteint lorsque la température dépasse 20 degrés.



Nous commençons le schéma de compilation.



En conséquence, le code résultant s'ouvrira dans l'IDE Arduino. En tant que carte, nous sélectionnons NodeMCU, sur lequel la même puce est installée que sur ShloTiny. La vérification du code montre qu'il est correct et peut être téléchargé.



Code compilé
#include <OneWire.h> extern "C" { #include "user_interface.h"; } OneWire _ow13(13); byte _FLPArray133289689[9]; unsigned long _d18x2x1Tti = 0UL; float _d18x2x1O = 0.00; bool _trgr1 = 0; bool _bounseInputD2S = 0; bool _bounseInputD2O = 0; unsigned long _bounseInputD2P = 0UL; bool _trgrt1 = 0; bool _trgrt1I = 0; bool _sowb1_needScan = 0; bool _sowb1_ost = 0; bool _sowb1_Out_1 = 0; void setup() { pinMode(2, INPUT); pinMode(12, OUTPUT); pinMode(14, OUTPUT); _bounseInputD2O = digitalRead(2); } void loop() { bool _bounceInputTmpD2 = (digitalRead (2)); if (_bounseInputD2S) { if (millis() >= (_bounseInputD2P + 40)) { _bounseInputD2O = _bounceInputTmpD2; _bounseInputD2S = 0; } } else { if (_bounceInputTmpD2 != _bounseInputD2O ) { _bounseInputD2S = 1; _bounseInputD2P = millis(); } } //:1 if (1) { if (_trgrt1I) { _trgrt1 = 0; } else { _trgrt1 = 1; _trgrt1I = 1; } } else { _trgrt1 = 0; _trgrt1I = 0; }; if (_sowb1_needScan) { if ( _oneWireSeach (_FLPArray133289689, _ow13)) { _sowb1_Out_1 = 1; } _ow13.reset_search(); _sowb1_needScan = 0; } if (_trgrt1) { if (! _sowb1_ost) { _sowb1_ost = 1; _sowb1_needScan = 1; _sowb1_Out_1 = 0; } } else { _sowb1_ost = 0; } //:2 digitalWrite(12, !(_bounseInputD2O)); //:3 if (_isTimer(_d18x2x1Tti, 1000)) { _d18x2x1Tti = millis(); _d18x2x1O = _readDS18_ow13(_FLPArray133289689, _FLPArray133289689[8]); } if (((_d18x2x1O)) > (20)) _trgr1 = 0; if (((_d18x2x1O)) < (10)) _trgr1 = 1; digitalWrite(14, _trgr1); } bool _isTimer(unsigned long startTime, unsigned long period ) { unsigned long currentTime; currentTime = millis(); if (currentTime >= startTime) { return (currentTime >= (startTime + period)); } else { return (currentTime >= (4294967295 - startTime + period)); } } float _convertDS18x2xData(byte type_s, byte data[12]) { int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; if (data[7] == 0x10) { raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw & ~7; else if (cfg == 0x20) raw = raw & ~3; else if (cfg == 0x40) raw = raw & ~1; } return (float)raw / 16.0; } float _readDS18_ow13(byte addr[8], byte type_s) { byte data[12]; byte i; _ow13.reset(); _ow13.select(addr); _ow13.write(0xBE); for ( i = 0; i < 9; i++) { data[i] = _ow13.read(); } _ow13.reset(); _ow13.select(addr); _ow13.write(0x44, 1); return _convertDS18x2xData(type_s, data); } bool _oneWireSeach (byte array[], OneWire ow ) { byte temp[8]; byte i; if ( !ow.search(temp)) { return false; } if (OneWire::crc8(temp, 7) != temp[7]) { return false; } switch (temp[0]) { case 0x10: array[8] = 1; break; case 0x28: array[8] = 0; break; case 0x22: array[8] = 0; break; default: return false; } for ( i = 0; i < 8; i++) { array[i] = temp[i]; } return true; } 


Description du contrôleur ShloTiny pour le programme FLProg

Nous terminerons cette leçon, dans le prochain article, nous essaierons de décrire quelque chose de plus sérieux et plus proche des «vrais» contrôleurs industriels.

Source: https://habr.com/ru/post/fr467007/


All Articles