Parte 2 da robótica da cozinha ou um outro avatar de Blynk


Entrada. Letras, você pode pular


Olá novamente! Nesta história, eu gostaria de continuar o tópico de "construção de robôs" em casa, este é um tipo de continuação do post anterior .

Avisarei você imediatamente: não sou especialista neste setor, estou apenas aprendendo e, durante muito tempo, fiquei "envergonhado" de expressar meus pensamentos e apresentar coisas caseiras aqui. Eu tenho lido publicações sobre Habr há muito tempo, às vezes você se pergunta o que está acontecendo no mundo! Você lê uma postagem, não entende de onde o autor conhece! Como você pode descobrir isso! À luz de tudo isso, pensei que minha apresentação "desajeitada" não seria interessante para ninguém, mas mais de 9k pessoas assistiram à história anterior, para mim é certamente um sucesso, acho que muitas pessoas como eu são "pessoas comuns" sem diplomas do Instituto de Tecnologia de Massachusetts , para que essas informações sejam mais acessíveis a eles. Então vamos lá ...

Alteração da estrutura


Como base do meu projeto, tirei a "criação" anterior, um chupocabra, que estava vestido e com uma performance leve, conduzia um feriado. Fiz isso por um dia e, por meios improvisados, que podem ser rastreados em sua aparência, a performance foi satírica. Parecia algo assim:


Antes de tudo, removi tudo o que era desnecessário, comprei perfis de alumínio e cantos perfurados para um novo design.

Gostei muito do desempenho do robô de telepresença da empresa estrangeira "Origibot"

imagem

imagem

Sua aparência ascética tem várias vantagens, julgue por si mesmo, o peso não é grande, isso é principalmente economia de energia, ergonomia, economia de energia da bateria, um acionamento elétrico menos potente. Imagine esta situação, hipoteticamente, seguimos em frente e, naquele momento, problemas de comunicação, se o peso do robô for de várias dezenas de quilogramas, as consequências podem ser fatais. A segunda vantagem desta forma, considero a capacidade de dobrar o manipulador entre as rodas, é possível levantar algo do chão.

Oh bem, inspirado e pronto! Remanescente "dele", ele decidiu dividir a produção em etapas:

  1. A fabricação de uma distância entre eixos baseada em duas rodas motrizes e uma traseira de apoio.
  2. Escrevendo um esboço para gerenciamento.
  3. Montando uma câmera ou telefone. A altura da colocação foi escolhida com base na altura do fogão na cozinha, para que você pudesse olhar para a panela e ver de que a sopa de beterraba foi cozida.
  4. Instalar um servo na câmera para que você possa olhar sob as "pernas" e o teto. Eu não me incomodei com o movimento horizontal, você pode virar a base.
  5. Instalação no "produto" do manipulador com um punho.

Comissionamento adicional, no que diz respeito ao conceito geral de robô, no caso ideal que ainda não foi implementado, o principal dispositivo de telecomunicações deve ser um telefone. O Skype está instalado nele, configurado para receber chamadas de vídeo automaticamente, e o telefone também será um ponto de acesso para uma placa baseada no módulo ESP, possibilitando o controle do robô e da videoconferência. Por que o skype Por que criar algo se você já possui serviços que funcionam perfeitamente e alteram a qualidade automaticamente, dependendo da largura de banda da rede.

Não houve problemas com o primeiro item, a base estava pronta do ofício anterior, removeu tudo supérfluo, o roteador TPlink MR3020 com uma antena remota caseira. No discurso anterior havia paredes “grossas”, tive que cultivar coletivamente, o resultado é + 9db. Os comandos de controle de tráfego chegaram ao roteador, firmware cyberWRT.

O segundo ponto foi mais interessante: meu nível na programação do arduino "LED Blinker", encontrei um esboço pronto na Internet, infelizmente não me lembro do autor, não fiz muito por mim usando o método de puxão científico, é usado por aqueles que entendem mal a teoria. Como a programação em linguagens de nível inferior ainda é uma floresta sombria para mim, tive que escolher uma plataforma na qual pudesse construir meu próprio painel de controle. Um aspecto importante para mim foi a capacidade de controlar o robô por meio de um serviço em nuvem, pois o controle será dos "endereços cinza". O serviço Blynk se tornou uma plataforma, não vou descrever as vantagens, há muita informação na rede. Na primeira versão, usei o widget do joystick para controlar o movimento, o código é mostrado abaixo:

#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(); } 


Em seguida, a instalação de uma câmera ou telefone, tentei os dois.

imagem

Na foto, o manipulador fica separado.

Agora é hora de testar! Aproveitei a oportunidade para dividir a tela no telefone (disponível no firmware Android mais recente), na parte superior do vídeo, no controle inferior. Para começar tudo ao mesmo tempo, baixei o aplicativo Telas do Play Market e fui ...


Durante o primeiro “pokatushek”, as seguintes deficiências foram reveladas: os motores que, no passado alemão, costumavam girar algo em alguma atração, têm saídas diferentes como resultado de uma linha reta, o movimento não funciona. Todo o tempo que ele puxa em uma das direções, fez um ajuste no cálculo da velocidade dos motores no código, ajudou, mas decidiu refazer o código em botões, é mais conveniente para mim, e os movimentos no apartamento serão principalmente lineares.

Isso foi seguido pelo estágio mais demorado, como ficou claro, agora fica claro por que muitos robôs de telepresença no mercado não têm um manipulador. Há pouco tempo, pesquisando sobre o estudo da questão, li sobre métodos para calcular unidades de rotação que não são divididas igualmente ao longo do eixo de carga, lembrei-me de como estava sentado no instituto em uma palestra sobre mecânica teórica há quinze anos e peguei meu nariz pensando: “Por que preciso de um futuro #Engineer - um eletricista # essa porcaria ". Bem, tudo bem, como se costuma dizer: "A prática sem teoria é cega". Cerca de dez vezes refiz o manipulador, queimei vários servos, que deveriam levantar a carga principal.

Se você prestou atenção na foto do Origibot, há algo terrível como uma unidade, no site deles eu li que o manipulador é capaz de levantar até 1 kg, fantástico!
Se aplicarmos, por exemplo, um servoconversor com uma força de 20 kg / cm, a uma distância de 2 cm, uma carga de 10 kg poderá ser aumentada e, se o peso dessa carga for desigualmente distribuído ao longo do eixo e o eixo for de cerca de um metro, menos ainda.

É bom que a velha câmera giratória de CCTV esteja à mão, tirei dois motores de passo dela, ótimo! Um motor eleva o eixo e o segundo eu uso em uma cortina automática. Há muito que eu queria fazer uma casa, mas ao mesmo tempo descobrir como trabalhar com os stepworms! Por assim dizer, dois coelhos com uma cajadada ao mesmo tempo. Sim! O principal "problema" estava esperando, esqueci de dizer que usei o controlador Wemos D1 R1 para o meu produto caseiro, é semelhante ao Arduino Uno, apenas há wifi a bordo. Enquanto não havia manipulador, havia pinos suficientes na placa, um motor de passo adicionado, para controlar os enrolamentos de que você precisa de quatro pinos, onde posso obtê-lo? Verificou-se que os pinos da placa são os pinos do próprio CES, que fornece comunicação; os pinos do 0 ao 8 são repetidos ainda mais. Bem, como se costuma dizer: "Uma cabeça ruim não dá paz às suas mãos!"
O preço do erro - ao transferir os resultados do trabalho para o painel Wemos 2560 esp8266, este painel é um Mega e Esp regular. Levei-o para automação da estufa, é claro que não foi imediatamente, o esboço não foi compilado, os erros voaram. Encontrei uma solução no site:
community.alexgyver.ru/threads/robotdyn-mega-wifi-r3-connect-blynk.1270/#post-16746
Abaixo está um esboço para um Mega operado por botão:

 #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(); 


Como resultado, o poder do substantivo chinês era ainda menor - 5kg / cm, decidi tentar através do cinto:

imagem

A correia escorregou apesar do tensor preso ao rolo (não na foto). Psicose e nervosismo excepcionais causados ​​por uma série de contratempos técnicos foram interrompidos por uma nova idéia. É necessário reduzir o peso da estrutura - abandonar os dois servos no final do eixo, para graus adicionais de liberdade e reduzir o comprimento do eixo do manipulador. (Espero que o fusível permaneça e essa decisão seja temporária).

imagem

Também na foto, instalei um alto-falante externo, que foi soldado à câmera ds-2cd2432f-iw pelo fabricante Hikvizhn. O orador em tempo integral parecia fraco.

Agora a aparência é a seguinte.

imagem

Sumário


Temos uma câmera sobre rodas, por que até agora eu recusei o telefone. O Skype não funciona corretamente no modo de várias janelas do meu telefone, quando o controle da imagem de vídeo é minimizado para o tamanho de uma pequena janela, o que não é muito conveniente quando o robô se move. Portanto, parei enquanto estava na câmera, ainda uso a versão paga do programa “Tiny cam pro” para acessar o vídeo, acessar de qualquer lugar do mundo, a câmera está conectada sem fio a um roteador no qual suas portas são encaminhadas e o serviço de nome de domínio No-Ip é usado. É bom que o provedor até agora forneça um endereço "branco". Por que eu não uso o Blynk para transmissão de vídeo, você pergunta, porque existe um widget padrão para a transmissão do protocolo rtsp. Eu respondo, quero usar toda a funcionalidade da câmera, ou seja, comunicação bidirecional. Mesmo que seja da forma como é fornecida por um aplicativo no qual codecs de áudio são usados, reduzem significativamente a qualidade do som. O protocolo rtsp mais importante no aplicativo Blynk funciona com um pequeno atraso, o que é essencial para viajar em um mecanismo que pesa 10 kg.

Nutrição, um tópico interessante separado. A questão de uma estação de carregamento autônoma ainda não foi resolvida; No modelo anterior, usei baterias de íon de lítio soldadas em pares em paralelo, para aumentar a tensão para 12V e aumentar a capacidade, trabalhando através do controlador de carregamento. Neste projeto, ele recusou lítio, as baterias explodiram terrivelmente de uma experiência ruim! Uma bateria de chumbo-ácido 7A / h é instalada na parte traseira da unidade, para distribuição uniforme da carga quando o manipulador eleva a carga, um conversor dc é conectado à bateria, o que reduz a tensão de 5V, para alimentar o controlador e a lógica dos dois drivers do motor MonstrmotorShield, um para cada roda, porque apenas o piso do motorista trabalhava em ambas as placas, provavelmente um defeito de fábrica, não conseguia pensar bem, não posso jogá-lo fora? O driver do motor ln298 é necessário para que dois motores de passo funcionem.

Dos problemas ainda não resolvidos, cobrança autônoma, quero repetir assim



Também não entendi bem a biblioteca AccelStepper, se você fornecer energia aos enrolamentos do motor, depois que o manipulador terminar, a energia permanecerá, o que aumenta a corrente de descarga da bateria em cerca de 400mA, o que não é econômico, você precisa criar a lógica quando o manipulador está na posição mais baixa, a energia dos enrolamentos é desligada. Eu também gostaria de receber feedback para que a posição dos servos e dos stepworms chegue a Blynk quando o robô é ligado. E, claro, a bateria deve desconectar a carga quando a tensão cair para 10,5V, o que impedirá sua degradação prematura. Não há como controlar a partir de um computador. E, claro, o código precisa de otimização.

Quem não tem medo de muitos livros e lê até o fim, obrigado, boa sorte a todos, tudo de bom!
Finalmente, vamos fazer um pouco!

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


All Articles