Kitchen Robotics Part 2 ou un autre avatar de Blynk


Entrée. Paroles, vous pouvez sauter


Bonjour encore! Dans cette histoire, je voudrais continuer sur le thème de la maison "construction de robots", c'est une sorte de suite du post précédent .

Je vous préviens immédiatement: je ne suis pas un expert dans ce secteur, j'apprends juste et depuis longtemps, je suis "gêné" d'exprimer mes pensées et de présenter des choses faites maison ici. Je lis des publications sur Habr depuis longtemps, parfois on se demande ce qui se passe dans le monde! Vous lisez un article, vous ne comprenez pas d'où vient l'auteur! Comment pouvez-vous même comprendre cela! À la lumière de tout cela, je pensais que ma présentation «maladroite» ne serait intéressante pour personne, mais plus de 9 000 personnes ont regardé l'histoire précédente, pour moi c'est certainement un succès, je pense que beaucoup de gens comme moi sont des «gens ordinaires» sans diplôme du Massachusetts Institute of Technology , ces informations leur sont donc plus accessibles. Alors allons-y ...

Altération de la structure


Comme base de mon projet, j'ai pris la "création" précédente, un chupocabra, qui était habillé et sous une performance son et lumière, a mené des vacances. Je l'ai fait pour une journée et grâce à des moyens improvisés, dont on peut retracer l'apparence, la performance était satirique. Cela ressemblait à ceci:


Tout d'abord, j'ai supprimé tout ce qui n'était pas nécessaire, acheté des profils en aluminium et des coins perforés pour un nouveau design.

J'ai beaucoup aimé les performances du robot de téléprésence de la société étrangère "Origibot"

image

image

Son aspect ascétique présente plusieurs avantages, jugez par vous-même, le poids n'est pas important, il s'agit principalement d'économie d'énergie, d'ergonomie, d'économie d'énergie de la batterie, d'un entraînement électrique moins puissant. Imaginez cette situation, hypothétiquement, nous sommes allés de l'avant et à ce moment-là des problèmes de communication, si le poids du robot est de plusieurs dizaines de kilogrammes, les conséquences peuvent être fatales. Le deuxième avantage de cette forme, je considère la possibilité de plier le manipulateur entre les roues, il est possible de soulever quelque chose du sol.

Eh bien, inspiré et c'est parti! Refaisant «le sien», il décide de diviser la production par étapes:

  1. La fabrication d'un empattement basé sur deux roues motrices et une support arrière.
  2. Rédaction d'un croquis pour la gestion.
  3. Montage d'un appareil photo ou d'un téléphone. La hauteur de placement a été choisie en fonction de la hauteur du poêle dans la cuisine afin que vous puissiez regarder dans la casserole et voir de quoi le bortsch a été cuit.
  4. Installer un servo sur la caméra pour pouvoir regarder sous les "pieds" et le plafond. Je n'ai pas pris la peine de mouvement horizontal, vous pouvez tourner la base.
  5. Installation sur le «produit» du manipulateur avec une poignée

Mise en service supplémentaire, en ce qui concerne le concept général du robot, dans le cas idéal qui n'a pas encore été mis en œuvre, le principal appareil de télécommunication devrait être un téléphone. Skype y est installé, qui est configuré pour recevoir automatiquement les appels vidéo, et le téléphone sera également un point d'accès pour une carte basée sur le module ESP, cela permettra de contrôler le robot et la visioconférence. Pourquoi skype Pourquoi proposer quelque chose si vous avez déjà des services qui fonctionnent parfaitement et changent automatiquement de qualité, en fonction de la bande passante du réseau.

Il n'y a eu aucun problème avec le premier article, la base était prête à partir de l'engin précédent, a supprimé tout ce qui était superflu, le routeur TPlink MR3020 avec une antenne à distance faite maison. Dans le discours précédent, il y avait des murs «épais», je devais la ferme collective, le résultat est + 9db. Les commandes de contrôle du trafic sont arrivées au routeur, le firmware cyberWRT.

Le deuxième point était plus intéressant, mon niveau dans la programmation arduino "LED Blinker", j'ai trouvé un croquis prêt sur Internet, malheureusement je ne me souviens pas de l'auteur, je ne l'ai pas fait beaucoup pour moi en utilisant la méthode du poke scientifique, il est utilisé par ceux qui comprennent mal la théorie. Étant donné que la programmation dans des langages encore plus bas est une forêt sombre pour moi, j'ai dû choisir une plate-forme sur laquelle je pouvais construire mon propre panneau de contrôle. Un aspect important pour moi était la possibilité de contrôler le robot via un service cloud, car le contrôle proviendra des "adresses grises". Le service Blynk est devenu une telle plateforme, je ne décrirai pas les avantages, il y a beaucoup d'informations sur le réseau. Dans la première version, j'ai utilisé le widget joystick pour contrôler le mouvement, le code est ci-dessous:

#define BLYNK_PRINT Serial #include <ESP8266_Lib.h> #include <BlynkSimpleShieldEsp8266.h> #include <AccelStepper.h> #include <Servo.h> #include <SimpleTimer.h> // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "****"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "****"; char pass[] = "****"; #define EspSerial Serial3 #define ESP8266_BAUD 115200 ESP8266 wifi(&EspSerial); BlynkTimer timer; Servo servo; Servo servo2; // These are used to set the direction of the bridge driver. #define ENB 5 //ENB      monstr motor shield  5  6     #define MOTORB_1 4 //IN3 #define MOTORB_2 9 //IN4 #define MOTORA_1 8 //IN1 #define MOTORA_2 7 //IN2 #define ENA 6 //ENA int motor_right_speed = 0; int motor_left_speed = 0; AccelStepper Stepper1(4, 10, 11, 12, 13); //4  ,      int steeps = 192; //  ,    ,    // SETUP void setup() { Serial.begin(9600); delay(10); EspSerial.begin(ESP8266_BAUD); delay(10); // Connect Blynk Blynk.begin(auth, wifi, ssid, pass); Blynk.connect(); // Configure pins pinMode(ENA, OUTPUT); pinMode(MOTORA_1, OUTPUT); pinMode(MOTORA_2, OUTPUT); pinMode(ENB, OUTPUT); pinMode(MOTORB_1, OUTPUT); pinMode(MOTORB_2, OUTPUT); digitalWrite(ENA,LOW); digitalWrite(ENB,LOW); Stepper1.setMaxSpeed(10000); //      (/) Stepper1.setAcceleration(10000); //  (/^2) servo.attach(1); servo2.attach(3); servo2.write(55); timer.setInterval(500L, StopServo); // Start serial communication } BLYNK_WRITE(V1) /     ,  , / { if (param.asInt() == 1) { servo.attach(1); servo.write(165); // High gear timer.setTimeout(500L, StopServo); } else { servo.attach(1); servo.write(115); // Low gear timer.setTimeout(500L, StopServo); } } BLYNK_WRITE(V2) { servo2.write(param.asInt()); } void StopServo() /  { servo.detach(); } // JOYSTICK BLYNK_WRITE(V0) { int nJoyY = param[0].asInt(); // read x-joystick int nJoyX = param[1].asInt(); // read y-joystick // OUTPUTS int nMotMixL; // Motor (left) mixed output int nMotMixR; // Motor (right) mixed output // CONFIG // - fPivYLimt : The threshold at which the pivot action starts // This threshold is measured in units on the Y-axis // away from the X-axis (Y=0). A greater value will assign // more of the joystick's range to pivot actions. // Allowable range: (0..+127) float fPivYLimit = 1023.0; // TEMP VARIABLES float nMotPremixL; // Motor (left) premixed output float nMotPremixR; // Motor (right) premixed output int nPivSpeed; // Pivot Speed float fPivScale; // Balance scale between drive and pivot // Calculate Drive Turn output due to Joystick X input if (nJoyY >= 0) { // Forward nMotPremixL = (nJoyX>=0)? 1023.0 : (1023.0 + nJoyX); nMotPremixR = (nJoyX>=0)? (1023.0 - nJoyX) : 1023.0; } else { // Reverse nMotPremixL = (nJoyX>=0)? (1023.0 - nJoyX) : 1023.0; nMotPremixR = (nJoyX>=0)? 1023.0 : (1023.0 + nJoyX); } // Scale Drive output due to Joystick Y input (throttle) nMotPremixL = nMotPremixL * nJoyY/900.0; //      nMotPremixR = nMotPremixR * nJoyY/1023.0; // Now calculate pivot amount // - Strength of pivot (nPivSpeed) based on Joystick X input // - Blending of pivot vs drive (fPivScale) based on Joystick Y input nPivSpeed = nJoyX; fPivScale = (abs(nJoyY)>fPivYLimit)? 0.0 : (1.0 - abs(nJoyY)/fPivYLimit); // Calculate final mix of Drive and Pivot nMotMixL = (1.0-fPivScale)*nMotPremixL + fPivScale*( nPivSpeed); nMotMixR = (1.0-fPivScale)*nMotPremixR + fPivScale*(-nPivSpeed)/ 1.1; motor_left_speed = nMotMixL; motor_right_speed = nMotMixR; if (motor_right_speed > 20) { digitalWrite(MOTORA_1,HIGH); digitalWrite(MOTORA_2,LOW); } else if (motor_right_speed < -20) { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2, HIGH); } else { digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, LOW); } if (motor_left_speed > 20) { digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH); } else if (motor_left_speed < -20) { digitalWrite(MOTORB_1,HIGH); digitalWrite(MOTORB_2,LOW); } else { digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, LOW); } analogWrite(ENB, abs(motor_left_speed)); analogWrite(ENA, abs(motor_right_speed)); } BLYNK_WRITE(V3) { // Motor Speed - Slider set with 0-100 and Send On Relese OFF int pinValue = param.asInt(); Stepper1.move(pinValue); } // MAIN CODE void loop() { Blynk.run(); timer.run(); Stepper1.run(); } 


Ensuite, l'installation d'une caméra ou d'un téléphone, j'ai essayé les deux.

image

Sur la photo, le manipulateur se tient séparément.

Il est maintenant temps de tester! J'en ai profité pour partager l'écran du téléphone (disponible dans le dernier firmware android), la partie supérieure de la vidéo, le contrôle du bas. Pour tout démarrer en même temps, j'ai téléchargé l'application Screens depuis le Play Market et je suis allé ...


Au cours du premier «pokatushek», les lacunes suivantes ont été révélées: les moteurs qui, dans leur passé allemand, avaient l'habitude de faire tourner quelque chose sur une attraction, ont des sorties différentes en raison d'une ligne droite, le mouvement ne fonctionne pas. Tout le temps, il tire dans l'une des directions, a ajusté le calcul de la vitesse des moteurs dans le code, cela a aidé, mais a décidé de refaire le code en boutons, c'est plus pratique pour moi, et les mouvements dans l'appartement seront principalement linéaires.

Cela a été suivi de l'étape la plus longue, comme il s'est avéré, maintenant il est clair pourquoi de nombreux robots de téléprésence sur le marché n'ont pas de manipulateur. Il n'y a pas si longtemps, plongeant dans l'étude de la question, j'ai lu sur les méthodes de calcul des entraînements de rotation qui ne sont pas également répartis le long de l'axe de charge, je me suis souvenu de la façon dont je me suis assis à l'institut lors d'une conférence sur la mécanique théorique il y a quinze ans et j'ai choisi mon nez en pensant: «Pourquoi ai-je besoin d'un futur # Ingénieur - électricien # cette merde. " Bon, d'accord, comme on dit: "Pratiquer sans théorie est aveugle." Une dizaine de fois, j'ai refait le manipulateur, brûlé plusieurs servos, censés soulever la charge principale.

Si vous avez fait attention à la photo Origibot, il y a quelque chose de terrible en tant que lecteur, sur leur site Web, j'ai lu que le manipulateur est capable de soulever jusqu'à 1 kg, fantastique!
Si nous appliquons par exemple un servomoteur avec une force de 20 kg / cm, alors à une distance de 2 cm, une charge de 10 kg peut être soulevée, et si le poids de cette charge est inégalement réparti le long de l'axe et que l'axe est d'environ un mètre, alors encore moins.

C'est bien que la vieille caméra rotative CCTV soit à portée de main, j'en ai retiré deux moteurs pas à pas, super! Un moteur soulèvera l'axe, et le second que j'utilise sur un rideau automatique. Je voulais depuis longtemps créer une maison, mais en même temps, savoir comment travailler avec les vers de terre! Pour ainsi dire, deux oiseaux avec une pierre à la fois. Ouais! Le principal "problème" attendait à l'avance, j'ai oublié de dire que j'ai utilisé le contrôleur Wemos D1 R1 pour mon produit fait maison, il ressemble à Arduino Uno, seulement il y a du wifi à bord. Bien qu'il n'y ait pas de manipulateur, il y avait suffisamment de broches sur la carte, un moteur pas à pas ajouté, pour contrôler les enroulements dont vous avez besoin de quatre broches, où puis-je l'obtenir? Il s'est avéré que les broches de la carte sont les broches du CES lui-même, qui assure la communication, les broches du 0 au 8 sont répétées. Eh bien, comme on dit: "Une mauvaise tête ne donne aucune paix à vos mains!"
Le prix de l'erreur - en transférant les résultats du travail sur la carte Wemos 2560 esp8266, cette carte est une Mega et Esp régulière. Je l'ai pris pour l'automatisation de la serre, bien sûr ça ne s'est pas passé tout de suite, le croquis n'a pas été compilé, des erreurs ont volé. Trouvé une solution sur le site:
community.alexgyver.ru/threads/robotdyn-mega-wifi-r3-connect-blynk.1270/#post-16746
Voici un croquis pour un Mega à bouton:

 #define BLYNK_PRINT Serial #include <ESP8266_Lib.h> #include <BlynkSimpleShieldEsp8266.h> #include <AccelStepper.h> #include <Servo.h> #include <SimpleTimer.h> #define EspSerial Serial3 #define ESP8266_BAUD 115200 ESP8266 wifi(&EspSerial); #define ENB 5 //ENB      monstr motor shield  5  6     #define MOTORB_1 4 //IN3 #define MOTORB_2 9 //IN4 #define MOTORA_1 8 //IN1 #define MOTORA_2 7 //IN2 #define ENA 6 //ENA BlynkTimer timer; Servo servo; Servo servo2; AccelStepper Stepper1(4, 10, 11, 12, 13); //4  ,      char auth[] = "****"; char ssid[] = "****"; char pass[] = "****"; // SETUP void setup() { Serial.begin(9600); delay(10); EspSerial.begin(ESP8266_BAUD); delay(10); // Connect Blynk Blynk.begin(auth, wifi, ssid, pass); Blynk.connect(); // Configure pins pinMode(ENA, OUTPUT); pinMode(MOTORA_1, OUTPUT); pinMode(MOTORA_2, OUTPUT); pinMode(ENB, OUTPUT); pinMode(MOTORB_1, OUTPUT); pinMode(MOTORB_2, OUTPUT); Stepper1.setMaxSpeed(100); //      (/) Stepper1.setAcceleration(96); //  (/^2) servo.attach(2); //   servo.write(115); //    servo2.attach(3); //  servo2.write(55); //    //timer.setInterval(500L, StopServo); // Start serial communication } BLYNK_WRITE(V6) { servo.write(param.asInt()); //timer.setTimeout(2500L, StopServo); } BLYNK_WRITE(V7) { servo2.write(param.asInt()); } //void StopServo() { // servo.detach(); //} BLYNK_WRITE(V8) { int pinValue = param.asInt(); Stepper1.move(pinValue); } BLYNK_WRITE(V4) { int speedL = param.asInt(); //      . 1,13       analogWrite(ENA, speedL); analogWrite(ENB, speedL* 1.13); } / FORWARD BLYNK_WRITE(V0) { int button = param.asInt(); // read button if (button == 1) { digitalWrite(MOTORA_1,HIGH); digitalWrite(MOTORA_2,LOW); digitalWrite(MOTORB_1,HIGH); digitalWrite(MOTORB_2,LOW); } else { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,LOW); digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,LOW); } } // RIGHT BLYNK_WRITE(V1) { int button = param.asInt(); // read button if (button == 1) { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,HIGH); digitalWrite(MOTORB_1,HIGH); digitalWrite(MOTORB_2,LOW); } else { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,LOW); digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,LOW); } } // LEFT BLYNK_WRITE(V2) { int button = param.asInt(); // read button if (button == 1) { digitalWrite(MOTORA_1,HIGH); digitalWrite(MOTORA_2,LOW); digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,HIGH); } else { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,LOW); digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,LOW); } } // BACKWARD BLYNK_WRITE(V3) { int button = param.asInt(); // read button if (button == 1) { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,HIGH); digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,HIGH); } else { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,LOW); digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,LOW); } } // MAIN CODE void loop() { Blynk.run(); timer.run(); Stepper1.run(); 


En conséquence, la puissance du nom chinois était encore moins - 5kg / cm, j'ai décidé d'essayer à travers la ceinture:

image

La courroie a glissé malgré le tendeur attaché au rouleau (non illustré). Une psychose et une nervosité exceptionnelles causées par une série de revers techniques ont été interrompues par une nouvelle idée. Il est nécessaire de réduire le poids de la structure - d'abandonner les deux servos à la fin de l'axe, pour des degrés de liberté supplémentaires et de réduire la longueur de l'axe du manipulateur. (J'espère que le fusible restera et que cette décision est temporaire).

image

Sur la photo également, j'ai installé un haut-parleur externe, qui a été soudé à l'appareil photo ds-2cd2432f-iw par le fabricant Hikvizhn. L'orateur à plein temps semblait faible.

Maintenant, l'apparence est la suivante.

image

Résumé


Nous avons un appareil photo sur roues, pourquoi jusqu'à présent j'ai refusé le téléphone. Skype ne fonctionne pas correctement en mode multi-fenêtres sur mon téléphone, lorsque le contrôle de l'image vidéo est réduit à la taille d'une petite fenêtre, ce qui n'est pas très pratique lorsque le robot se déplace. Par conséquent, je me suis arrêté sur l'appareil photo, j'utilise toujours la version payante du programme "Tiny cam pro" pour accéder à la vidéo, accéder de n'importe où dans le monde, l'appareil photo est connecté sans fil à un routeur sur lequel ses ports sont transférés et le service de nom de domaine No-Ip est utilisé. Il est bon que le fournisseur fournisse jusqu'à présent une adresse "blanche". Pourquoi je n'utilise pas Blynk pour la transmission vidéo, demandez-vous, car il existe un widget standard pour transmettre le protocole rtsp. Je réponds, je veux utiliser toutes les fonctionnalités de la caméra, à savoir la communication bidirectionnelle. Même si c'est sous une forme telle qu'elle est fournie par une application dans laquelle des codecs audio sont utilisés, ce qui réduit considérablement la qualité du son. Le protocole rtsp le plus important de l'application Blynk fonctionne avec un léger retard, ce qui est essentiel pour voyager sur un mécanisme qui pèse 10 kg.

La nutrition, un sujet intéressant distinct. Le problème d'une borne de recharge autonome n'a pas encore été résolu, n'a pas eu le temps. Sur le modèle précédent, j'ai utilisé des batteries Li-ion soudées par paires en parallèle, pour augmenter la tension à 12V et augmenter la capacité, en travaillant via le contrôleur de charge. Dans ce projet, il a refusé le lithium, les piles ont explosé terriblement d'une mauvaise expérience! Une batterie au plomb-acide de 7 A / h est installée à l'arrière de l'unité, pour une répartition uniforme de la charge lorsque le manipulateur soulève la charge. Un convertisseur CC qui réduit la tension de 5 V est connecté à la batterie pour alimenter le contrôleur et la logique des deux pilotes de moteur MonstrmotorShield, un pour chaque roue, car seul le plancher du conducteur fonctionnait dans les deux planches, très probablement un mariage en usine, ne pouvait pas se faire une idée, eh bien, ne l'a-t-il pas jeté? ...

Parmi les problèmes non encore résolus, la charge autonome, je veux le répéter comme ça



Je n'ai pas non plus bien compris la bibliothèque AccelStepper, si vous alimentez les enroulements du moteur, une fois le manipulateur terminé, l'alimentation reste, ce qui augmente le courant de décharge de la batterie d'environ 400 mA, ce qui n'est pas économique, vous devez trouver la logique lorsque le manipulateur est en position basse, l'alimentation des enroulements est coupée. Je voudrais également des commentaires afin que la position des servos et des vers-pas arrive à Blynk lorsque le robot est allumé. Et bien sûr, la batterie doit déconnecter la charge lorsque la tension chute à 10,5 V, ce qui empêchera sa dégradation prématurée. Il n'y a aucun moyen de contrôler depuis un ordinateur. Et bien sûr, le code doit être optimisé.

Ceux qui n'ont pas peur de beaucoup de livres et lisent jusqu'au bout, merci, bonne chance à tous, tout va bien!
Enfin, nous allons faire un peu!

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


All Articles