Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Controle o Arduino Rover usando Firmata e o controlador do Xbox One

Componentes e suprimentos

Microsoft Xbox Controller e Adaptador sem fio para Windows
Este controlador pode ser adicionado a um PC Windows usando o adaptador
× 1
SparkFun Bluetooth Modem - BlueSMiRF prata
Ou um módulo Bluetooth idêntico (HC-05, HC-06)
× 1
Arduino UNO
× 1

Aplicativos e serviços online

Microsoft Windows 10 IoT Core
Este aplicativo é o intermediário entre o esboço Firmata padrão e o controlador do Xbox One

Sobre este projeto


Há alguns meses comprei um pequeno rover (controlado por um Arduino Uno) por um preço muito bom. O kit era muito completo:Chassis de carro, 2 rodas de carro, 2 motores DC Gear, um UNO R3, um controlador de motor H-Bridge duplo L298N e vários outros componentes.

Este rover deve ser programado para operação autônoma. Portanto, um sensor ultrassônico e um servo também são adicionados ao kit. Além disso, um bom protetor de sensor Arduino 5 está no kit. Sim, foi uma verdadeira pechincha;-)

Mas minha ideia era usar um controlador do Xbox One e o protocolo Firmata para dirigir este sozinho ou com um dos meus filhos. E funciona muito bem!

Aqui está um vídeo da solução final:

As principais peças utilizadas neste projeto são:
  • Um kit rover (usamos para esta demonstração apenas um subconjunto das peças:a placa de base, as rodas, os motores, o Arduino Uno, o suporte de bateria de 9 volts e o controlador de motor L298N Dual H-Bridge)
  • Um suporte de bateria extra para 6 baterias AA
  • Um módulo Bluetooth (HC-06)
  • Um controlador Xbox One com adaptador sem fio para Windows (para conectá-lo a um laptop)
  • Um laptop (com Windows 10 + VS2015 + dongle Bluetooth)
  • Uma luz intermitente apenas para efeito dramático

Construindo o kit

Construir o kit não é tão difícil. Embora o manual de construção esteja em chinês, tudo parece bastante lógico. Há apenas uma placa de base, então tive que colocar alguns componentes em cima dela e alguns na parte inferior (agora o controlador do motor):

Nesta imagem, dois suportes de bateria diferentes são adicionados. Durante a programação, descobri que precisava usar uma fonte de alimentação separada apenas para colocar os motores em funcionamento.

Conectando os motores - layout dos pinos do controlador

O ponto forte do hardware, desta vez, não é o Arduino Uno, mas o controlador do motor.

“O L298 é um driver de ponte H duplo para motores DC com escova e motores de passo. Ele suporta uma ampla faixa de tensão de operação e pode fornecer 2 A por canal em um pacote de orifício que é acessível para projetos do tipo faça você mesmo. ”

Este controlador controlará a velocidade e direção de cada um dos dois motores, usando sinais vindos do Arduino.

O layout dos pinos do Controlador de Motor Dual H-Bridge L298N é:
  • Plus + do motor DC 1
  • Menos - do motor DC 1
  • Power IN. Eu forneço 9 volts de um suporte de bateria separado
  • Terreno comum. Conectado ao meu suporte de bateria separado e ao Arduino
  • Desligar . Pode produzir 5 volts ( não usado . Meu Arduino recebe energia de outro suporte de bateria)
  • ENA conectado ao Arduino D10. Esta porta é compatível com PWM (branco)
  • IN1 conectado ao Arduino D9. (cinza)
  • IN2 conectado ao Arduino D8. (roxo)
  • IN3 conectado ao Arduino D7. (azul)
  • IN4 conectado ao Arduino D6. (verde)
  • ENB conectado ao Arduino D5. Esta porta é compatível com PWM (amarelo)
  • Plus + do motor DC 2
  • Menos - do motor DC 2
  • O jumper próximo a 2 e 3 é NÃO removido porque eu não exceda a potência de entrada acima de 12 volts (até 35 volts) (jumper não marcado na imagem)

Nota:o controlador tem sua própria fonte de alimentação. O Arduino também tem um. Para manter as coisas funcionando (sem explodir, estabeleça um terreno comum . Veja o marcador 4 acima)

Conectando os motores - layout de pinos do Arduino

Conectar o Arduino é bastante simples. Conectamos o aterramento e os 5 volts da fonte de alimentação ao Arduino. E conectamos as seis linhas (ENA, IN1-4 e ENB) aos pinos D10 até D5.

Deve ficar claro que as portas 7 e 8 (e 9 e 10 para o outro motor) são apenas portas GPIO normais. Eles serão usados ​​para a direção do motor. Se ambas as portas (por exemplo, 7 e 8) estiverem BAIXAS, o motor não fará nada (ele para). Se um estiver ALTO e o outro BAIXO, o motor funcionará em uma direção. Se conectado ao contrário (o primeiro é definido como BAIXO e o outro como ALTO), o motor conectado funcionará na outra direção.

Mas .. apenas definir esses pinos não resultará em nada. Ainda não há peças móveis!

A mágica virá dos pinos 5 e 10. Esses são pinos "especiais" que podem gerar um sinal PWM. Definir um valor entre 0 e 255 resultará no funcionamento do motor MUITO lento (parado) ou em alta velocidade.

Nota:Cada porta no Arduino Uno capaz de PWM é marcada com um til (o ~).

Conectando o Bluetooth

O módulo Bluetooth que uso só precisa ser conectado às portas RX e TX (cruze as linhas) e precisa de 5 volts de energia e aterramento do Arduino.

Esboço Firmata no Arduino

O esboço Firmata “StandardFirmata” é tudo o que precisamos no Arduino! Basta obtê-lo dos exemplos do IDE do Arduino e carregá-lo (talvez seja necessário liberar o TX / RX primeiro para concluir o upload).

Observação:devido à falta de qualidade do meu módulo Bluetooth, sempre diminuo a taxa de transmissão que está codificada dentro do esboço e a defino para 9600.

Senhores, liguem os motores

Ou teste a conexão ...

Então, por que estou usando o Firmata? porque é fácil. Quão fácil? Muito fácil. E pode até ser feito sem programação. Basta iniciar o aplicativo Windows Remote Arduino Experience (disponível na loja e também funciona em um dispositivo Windows 10 Mobile).

Primeiro, você terá que se conectar ao módulo HC-6 Bluetooth já emparelhado.

Quando emparelhado, vá para a página PWM. Habilite o pino digital 5 e atribua a ele um valor de, digamos, 128.

Cuidado:a próxima etapa fará seu motor funcionar. Coloca o capacete e tira a farinha das rodas. Você saberá o porquê quando o vir.

Em seguida, vá para a página Digital. E acione a chave do pino digital 6.

Agora, se tudo estiver conectado e funcionando, um dos motores vai girar!

Nesse caso, você pode verificar outras velocidades (usando um valor de PWM mais alto ou mais baixo) ou alterar a direção (defina o pino digital de 6 para 0 volt e o pino digital de 7 para 5 volt).

E aí está. Você pode controlar essa roda!

Mas há mais, o mesmo vale para o pino 10 (PWM) e o pino digital 9 e o pino digital 8.

Ambas as rodas funcionando. Agora comece a codificar ...

O aplicativo UWP como o combinador

Deve ficar claro que precisamos de um novo aplicativo UWP entre o controlador do Xbox One e o rover.

Eu já escrevi sobre como usar o controlador do Xbox One aqui. Desta vez, combinaremos esse conhecimento com nosso rover.

Vejamos a interface de nosso aplicativo UWP:

É muito chato, dois botões e um bloco de texto. Não terei mais nada a fazer do que conectar primeiro ao Arduino usando Firmata. E uma vez que a conexão é feita, o botão do controlador terá que iniciar um loop gigante para ler a entrada do controlador e transformá-la em comandos úteis.

E o que queremos criar são os controles de tanque clássicos com duas alças. Tudo o que precisamos é verificar os dois botões no controle do Xbox One. Movê-los para frente e para trás também iniciará o motor correspondente para frente e para trás:

Nota:Se você iniciar um novo aplicativo UWP, não se esqueça de adicionar o recurso Bluetooth. E você terá que instalar o pacote nuget para Firmata.

Primeiro, adicionamos o snippet XAML (consulte a seção de código para obter o código-fonte Xaml) na grade do mainform para que tenhamos alguns botões.

Em seguida, adicionamos o código por trás (consulte a seção de código para o código-fonte C #) do formulário principal. I basicamente é dividido em duas partes. Primeiro fazemos uma conexão por Bluetooth com o protocolo Firmata. Em seguida, começamos a ouvir a entrada no controlador do Xbox One.

Dentro do loop para verificar os controles, decidimos se um botão está apontando para frente ou para trás ou se está na faixa de ‘parar’. Depois disso, decidimos qual será o valor do pino PWM.

É interessante ver que escrever um valor PWM é representado no Firmata como escrever um valor analógico em uma porta digital. Não há nenhum método PWM especial na classe Arduino.

Eu adicionei dois métodos “ArduinoDigitalWrite” e “ArduinoAnalogWrite” para evitar a gravação do mesmo valor repetidamente no Arduino. Isso vai atrapalhar a comunicação e degradar o desempenho do Arduino. (Em um design muito mais rico, adicionei uma campainha. Sem ignorar comandos duplicados, o desempenho da campainha era extremamente pobre e terrível de ouvir).

Quando os motores recebem os pulsos PMW baixos, o motor não está começando a funcionar diretamente, ele gemerá com um som muito distinto. Este é um comportamento normal. E foi assim que descobri que precisava adicionar duas fontes de energia. Na primeira vez que conectei tudo, pensei que o controlador estava quebrado. Nada aconteceu. Até que desliguei um dos motores e o outro começou a gemer.

Então é assim que funciona:

Nota de rodapé:a luz piscando não serve apenas para um efeito dramático. Sempre que suas criações começarem a se mover, preste atenção à segurança. A engenhoca é burra, você não! Portanto, eu coloquei essa luz em cima dela em primeiro lugar.

Código

  • controles Xaml para iniciar a comunicação
  • Código por trás do formulário principal do aplicativo UWP
Controles Xaml para iniciar os snippets de comunicação
Cole-o no formulário principal de seu novo aplicativo UWP
  
Código por trás do mainform do aplicativo UWP C #
Este código se conecta ao rover usando Firmata e passa os comandos do Controlador do Xbox One
 public selected parcial class MainPage:Page {private BluetoothSerial _bluetooth; private RemoteDevice _arduino; privado UwpFirmata _firmata =null; Gamepad privado _Gamepad =null; // Nunca fornecemos um PWM de mais de 255 * 0,75 private double _SpeedLimit =0,75; // valores abaixo deste valor absoluto param o rover private double _ActionPoint =0.15; byte privado _LeftForward =6; byte privado _LeftBackward =7; byte privado _LeftValue =5; byte privado _RightForward =9; byte privado _RightBackward =8; byte privado _RightValue =10; Dicionário privado  _CurrentPinStates =novo Dicionário  (); Dicionário privado  _CurrentSpeedValues ​​=novo Dicionário  (); public MainPage () {this.InitializeComponent (); } private void btnStart_Click (objeto remetente, RoutedEventArgs e) {btnStart.IsEnabled =false; Gamepad.GamepadAdded + =Gamepad_GamepadAdded; Gamepad.GamepadRemoved + =Gamepad_GamepadRemoved; _bluetooth =novo BluetoothSerial ("HC-06"); _bluetooth.ConnectionLost + =BluetoothConnectionLost; _bluetooth.ConnectionFailed + =BluetoothConnectionFailed; _bluetooth.ConnectionEstablished + =OnConnectionEstablished; _firmata =novo UwpFirmata (); _arduino =novo RemoteDevice (_firmata); _firmata.begin (_bluetooth); _bluetooth.begin (9600, SerialConfig.SERIAL_8N1); _arduino.DeviceReady + =ArduinoDeviceReady; } private async void BluetoothConnectionLost (string message) {await Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="ConnectionLost" + mensagem; btnStart.IsEnabled =true;}); } private async void BluetoothConnectionFailed (string message) {await Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="ConnectionFailed" + mensagem; btnStart.IsEnabled =true;}); } private async void ArduinoDeviceReady () {await Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="Dispositivo pronto";}); } private void OnConnectionEstablished () {var action =Dispatcher.RunAsync (CoreDispatcherPriority.Normal, new DispatchedHandler (() => {DisableEnableButtons (true); ArduinoDigitalWrite (_LeftForward, PinState.LOW); ArduinoDigitalWrite (_RightBackward, PinState.LOW); ArduinoDigitalWrite (_RightForward, PinState.LOW);})); } private void DisableEnableButtons (bool enabled) {// Desativar todos os botões. Caso contrário, // o 'A' pressionará aquele focalizado. btnController.IsEnabled =enabled; btnStart.IsEnabled =habilitado; } private async void Gamepad_GamepadRemoved (objeto remetente, Gamepad e) {_Gamepad =null; esperar Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="Controlador removido";}); } private async void Gamepad_GamepadAdded (objeto remetente, Gamepad e) {_Gamepad =e; esperar Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="Controlador adicionado";}); } private async void btnController_Click (objeto remetente, RoutedEventArgs e) {DisableEnableButtons (false); while (true) {await Task.Delay (TimeSpan.FromMilliseconds (3)); if (_Gamepad ==null) {continue; } // Obtenha o estado atual var reading =_Gamepad.GetCurrentReading (); if (Math.Abs ​​(reading.LeftThumbstickY) <_ActionPoint) {ArduinoDigitalWrite (_LeftForward, PinState.LOW); ArduinoDigitalWrite (_LeftBackward, PinState.LOW); sldrLeftSpeed.Value =0; } else if (reading.LeftThumbstickY> =_ActionPoint) {ArduinoDigitalWrite (_LeftForward, PinState.HIGH); ArduinoDigitalWrite (_LeftBackward, PinState.LOW); sldrLeftSpeed.Value =255 * Math.Abs ​​(reading.LeftThumbstickY) * _SpeedLimit; } else if (reading.LeftThumbstickY <=-_ActionPoint) {ArduinoDigitalWrite (_LeftForward, PinState.LOW); ArduinoDigitalWrite (_LeftBackward, PinState.HIGH); sldrLeftSpeed.Value =255 * Math.Abs ​​(reading.LeftThumbstickY) * _SpeedLimit; } if (Math.Abs ​​(reading.RightThumbstickY) <_ActionPoint) {ArduinoDigitalWrite (_RightForward, PinState.LOW); ArduinoDigitalWrite (_RightBackward, PinState.LOW); sldrRightSpeed.Value =0; } else if (reading.RightThumbstickY> =_ActionPoint) {ArduinoDigitalWrite (_RightForward, PinState.HIGH); ArduinoDigitalWrite (_RightBackward, PinState.LOW); sldrRightSpeed.Value =255 * Math.Abs ​​(reading.RightThumbstickY) * _SpeedLimit; } else if (reading.RightThumbstickY <=-_ActionPoint) {ArduinoDigitalWrite (_RightForward, PinState.LOW); ArduinoDigitalWrite (_RightBackward, PinState.HIGH); sldrRightSpeed.Value =255 * Math.Abs ​​(reading.RightThumbstickY) * _SpeedLimit; }}} private void ArduinoDigitalWrite (byte port, PinState state) {// ignorar comandos duplicados var exists =_CurrentPinStates.ContainsKey (port); if (! existe || _CurrentPinStates [porta]! =estado) {_CurrentPinStates [porta] =estado; _arduino.digitalWrite (porta, estado); }} private void ArduinoAnalogWrite (byte port, ushort value) {// ignorar comandos duplicados var exists =_CurrentSpeedValues.ContainsKey (port); if (! existe || _CurrentSpeedValues ​​[porta]! =valor) {_CurrentSpeedValues ​​[porta] =valor; _arduino.analogWrite (porta, valor); }}} 

Processo de manufatura

  1. Sistema de atendimento usando Arduino e RFID com Python
  2. Controle remoto universal usando Arduino, 1Sheeld e Android
  3. Faça você mesmo voltímetro usando Arduino e Smartphone
  4. Usando IoT para controlar remotamente um braço robótico
  5. Medição de frequência e ciclo de trabalho usando Arduino
  6. Sonar usando arduino e exibição no IDE de processamento
  7. Controle de brilho do LED usando Bolt e Arduino
  8. Braço robótico simples e inteligente usando Arduino
  9. Controle total de sua TV usando Alexa e Arduino IoT Cloud
  10. Rádio FM usando Arduino e RDA8057M