Skip to content

Repository files navigation

Atlas Controller

App Android/iOS (feito em Flutter) que controla um robô com ESP32 por Bluetooth Low Energy (BLE). Você escaneia e conecta no robô direto (sem pareamento prévio) e usa uma cruz direcional na tela para mandar ele andar.

Plataforma alvo Android e iOS
Flutter 3.47.0 (canal stable)
Comunicação BLE (GATT), serviço no padrão Nordic UART Service (NUS)

Até uma versão anterior deste app, a comunicação era por Bluetooth Classic (SPP) — o que só funcionava no Android. A migração para BLE foi feita justamente para permitir rodar no iOS; veja robot_connection.dart e o firmware em esp32_ble_bridge.ino no repositório orquestrador.


Índice


Como o app funciona, em 30 segundos

┌─────────────────┐   você toca no robô   ┌─────────────────┐
│  ConnectScreen  │ ────────────────────► │  ControlScreen  │
│                 │                        │                 │
│ escaneia e      │ ◄──────────────────── │ cruz direcional │
│ lista por perto │   botão desconectar    │ + status        │
└─────────────────┘                        └─────────────────┘
         │                                          │
         └──────────────┬───────────────────────────┘
                        ▼
              ┌───────────────────┐
              │  RobotConnection  │  ← o único que fala com o Bluetooth
              └───────────────────┘
                        │
                        ▼
                   🤖 ESP32

Cada toque num botão envia uma linha de texto pelo Bluetooth:

{"cmd":"F"}

As letras são F (frente), B (ré), L (esquerda), R (direita) e S (parar). O firmware do ESP32 precisa entender exatamente esse formato. Se você mudar o formato aqui, tem que mudar lá também.

O robô anda enquanto o dedo está pressionando o botão. Ao soltar, o app manda S automaticamente — inclusive se o dedo escorregar para fora do botão.

Para o mapa detalhado dos arquivos, veja ARQUITETURA.md.


Rodando o projeto

Primeira vez (depois de clonar)

Você precisa do Flutter 3.47+. Se ainda não tem, siga o guia oficial.

git clone <url-do-seu-repositorio>
cd app

flutter pub get     # baixa as dependências listadas no pubspec.yaml
flutter doctor      # confere o que falta no ambiente, por plataforma alvo

Você não precisa criar android/local.properties na mão. Ele guarda os caminhos do SDK da sua máquina, por isso não vai para o Git — o próprio flutter build gera ele no primeiro uso.

Testar no Linux (desktop, com Bluetooth real)

Se sua máquina Linux tem um adaptador Bluetooth (rfkill list bluetooth mostra hci0 e o serviço bluetooth está ativo), o flutter_blue_plus fala BLE de verdade por esse rádio via BlueZ — não é só uma prévia visual:

flutter run -d linux

Isso conecta de fato no ESP32 físico, sem precisar de celular nenhum. É o jeito mais rápido de testar a lógica de conexão durante o desenvolvimento. Único cuidado: permission_handler não tem implementação para desktop — connect_screen.dart já pula o pedido de permissão fora de Android/iOS de propósito, não "conserte" isso adicionando a chamada de volta.

Testar no Android (físico ou emulador)

Precisa do Android SDK (via Android Studio). Com um celular Android conectado (ou emulador rodando):

flutter run                      # hot reload direto no aparelho
flutter build apk --debug        # ou gera um APK para instalar manualmente

O APK sai em build/app/outputs/flutter-apk/app-debug.apk. Copie para o celular (cabo, Google Drive, etc.) e abra para instalar — o Android vai pedir para autorizar "instalar apps de fontes desconhecidas" na primeira vez.

Para a versão final, menor e mais rápida: flutter build apk --release.

Este APK sai assinado com a chave do projeto (android/robot-release.jks) e sem o Shorebird dentro — ou seja, ele não recebe atualização automática. Para gerar o APK que se atualiza sozinho, use shorebird release conforme a seção "Atualização automática" abaixo.

Testar no iPhone

Não é possível compilar para iOS sem macOS. O Xcode — obrigatório para compilar, assinar e instalar em um iPhone — só roda em macOS; não existe workaround via Linux/Windows para essa etapa específica. Com acesso a um Mac (próprio, emprestado, ou um serviço de CI como Codemagic/GitHub Actions com runner macos):

open ios/Runner.xcworkspace   # no Mac, dentro da pasta do projeto

No Xcode: selecione seu iPhone como destino, configure o signing com sua Apple ID (aba "Signing & Capabilities" do target Runner) e rode. A característica BLE já pede a permissão certa no iOS (NSBluetoothAlwaysUsageDescription em ios/Runner/Info.plist).

Verificar o código antes de commitar

flutter analyze   # procura erros e código suspeito
flutter test      # roda os testes automatizados (test/*.dart)

Os dois precisam passar limpos antes de você subir alterações.


Atualização automática (Shorebird)

O app se atualiza sozinho. Quem tem o APK instalado não precisa reinstalar nada a cada mudança: o Shorebird entrega o código Dart novo pela internet, o app baixa em segundo plano e aplica no próximo abrir.

O ciclo normal do dia a dia

Você mexe no código Dart, commita, dá git push na main. Só isso. O workflow .github/workflows/deploy.yml publica um patch e os celulares pegam a atualização sozinhos.

Quando um patch não dá conta

Patch só troca código Dart. Ele não consegue trocar:

  • código Kotlin ou o AndroidManifest.xml
  • dependência nova no pubspec.yaml que tenha parte nativa
  • versão do Flutter
  • ícone e outros recursos Android

Nesses casos, bumpe a version: do pubspec.yaml (1.0.0+11.0.1+2, lembrando que o número depois do + precisa subir) e dê push. O workflow detecta a versão nova, compila um APK novo assinado e publica numa GitHub Release. Esse APK precisa ser instalado à mão — é a única hora em que isso acontece.

Se você mexer em código nativo e esquecer de bumpar a versão, o passo de patch falha de propósito, com a mensagem do Shorebird dizendo que detectou diferença nativa. É o comportamento desejado: melhor o CI falhar do que os celulares receberem um patch que trava o app.

Publicar manualmente, da sua máquina

export PATH="$HOME/.shorebird/bin:$PATH"

shorebird patch --platforms=android --release-version=1.0.1+2   # atualização OTA
shorebird release --platforms=android --artifact=apk            # APK novo

E o iOS?

A esteira cobre só o Android. O Shorebird suporta iOS, mas compilar para iOS exige um runner macos no GitHub Actions (mais caro que o ubuntu) e uma conta paga no Apple Developer Program para assinar. Enquanto o iOS for instalado à mão pelo Xcode, ele não recebe as atualizações automáticas — cada mudança exige recompilar e reinstalar pelo Mac.

Segredos que o CI usa

Ficam em Settings → Secrets and variables → Actions do repositório:

Segredo O que é
SHOREBIRD_TOKEN API key criada em console.shorebird.dev
ANDROID_KEYSTORE_BASE64 o android/robot-release.jks em base64
ANDROID_KEYSTORE_PASSWORD a senha do keystore
ANDROID_KEY_ALIAS o alias da chave (robot)

O keystore não está no Git (é segredo). Guarde uma cópia dele fora do projeto: perdê-lo significa não conseguir mais atualizar o app instalado nos celulares — só reinstalando do zero.


Como fazer as alterações mais comuns

Quero mudar... Mexa em...
as cores do app lib/app/theme.dart
o texto de um botão ou aviso a tela correspondente em lib/screens/
adicionar um comando novo (buzina, luz) lib/models/robot_command.dart
o formato do que vai pelo Bluetooth lib/services/robot_connection.dart, método send
os UUIDs do serviço BLE RobotBleIds em robot_connection.dart e esp32_ble_bridge.ino (os dois lados)
o nome do app no celular android/app/src/main/AndroidManifest.xml, atributo android:label
o ícone do app android/app/src/main/res/mipmap-*/

Detalhes de configuração

Permissões

Android: Bluetooth e Localização — a Localização parece estranha, mas o Android exige ela para operações de Bluetooth em versões mais antigas; sem ela a lista de dispositivos volta vazia e sem erro nenhum, difícil de depurar. iOS: NSBluetoothAlwaysUsageDescription no Info.plist — sem ela o app crasha ao tentar usar Bluetooth.

Identificador do app (applicationId)

É com.setrem.robot_controller. Era com.example.robot_controller (o valor de exemplo que o Flutter gera, que a Play Store recusa) e foi trocado antes de o app começar a ser distribuído — de propósito, porque trocar depois é caro: para o Android, um applicationId diferente é outro app, então a atualização não instala por cima e todo mundo precisa desinstalar antes.

Se algum dia precisar mudar de novo, são dois lugares:

  • android/app/build.gradle.ktsapplicationId e namespace
  • a pasta android/app/src/main/kotlin/... e o package do MainActivity.kt

Assinatura de release

Todo APK precisa ser assinado. Sem nenhuma configuração, o projeto assina o release com a chave de debug — que é gerada por máquina. O APK instala e funciona, mas dois APKs assinados por chaves diferentes não se atualizam: o Android trata a troca de assinatura como app estranho e recusa a instalação por cima. Por isso o projeto tem uma chave própria (android/robot-release.jks), usada tanto aqui quanto pelo CI.

Para usar uma chave sua, o build.gradle.kts já está preparado: basta criar os dois arquivos abaixo e o build passa a usá-los sozinho.

  1. Gere o keystore (guarde bem a senha, ela não tem como ser recuperada):

    keytool -genkey -v -keystore ~/robot-controller.jks \
      -keyalg RSA -keysize 2048 -validity 10000 -alias robot
  2. Crie android/key.properties a partir do modelo versionado:

    cp android/key.properties.example android/key.properties
    # abra e preencha as senhas e o caminho do .jks
  3. flutter build apk --release — pronto, sai assinado com a sua chave.

🔒 Nunca suba key.properties nem o .jks para o GitHub. Os dois já estão no .gitignore. Se a chave vazar, outra pessoa consegue publicar atualizações falsas em nome do seu app — e trocar a chave depois de publicado é um processo doloroso.

Arquivos que não vão para o Git

  • android/local.properties — caminhos do SDK da sua máquina, gerado automaticamente.
  • build/ e .dart_tool/ — resultado da compilação, regeráveis.
  • *.jks e key.properties — chaves de assinatura, são segredo.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages