Разработка мобильного приложения для электросамоката/электровелосипеда

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Разработка мобильного приложения для электросамоката/электровелосипеда
Сложная
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    760
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    646
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1056
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    878
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    450

Разработка мобильного приложения для электросамоката/электровелосипеда

Электросамокаты и велосипеды с контроллером — это не просто устройства с BLE-чипом. Типичный стек: контроллер BLDC-мотора (Sabvoton, Kelly, Votol) общается с дисплеем или BMS по протоколу UART/RS485 (часто проприетарный), BLE-модуль (Nordic nRF52840, ESP32) слушает шину и транслирует данные в мобильное приложение. Разработка приложения без понимания этой цепочки заканчивается тем, что приложение «подключилось», но не знает, что делать с потоком байт.

Реверс-инжиниринг протокола контроллера

Большинство производителей контроллеров (особенно китайских) не публикуют протоколы. Процесс: снять родной дисплей, подключить USB-UART анализатор (FTDI232, CP2102) параллельно шине и записать трафик в логи. Инструмент — PulseView + декодер UART, либо просто запись в файл через minicom/CoolTerm.

Типичный фрейм протокола Xiaomi M365 (как пример открытого):

[0x55][0xAA][len][addr][cmd][data...][crc_lo][crc_hi]

Фрейм начинается с 0x55 0xAA, затем длина полезной нагрузки, адрес получателя (0x20 — контроллер, 0x21 — BMS, 0x3E — дисплей), команда, данные, CRC16. Для менее популярных брендов CRC считается по-разному — XOR, Modbus CRC, иногда просто сумма байт с маской.

class ScooterFrameParser {
    private val buffer = ByteArrayOutputStream()

    fun feed(byte: Byte): ScooterFrame? {
        buffer.write(byte.toInt())
        val bytes = buffer.toByteArray()

        // Ищем начало фрейма
        val start = findStart(bytes) ?: return null
        if (bytes.size - start < 4) return null

        val len = bytes[start + 2].toInt() and 0xFF
        val totalLen = len + 6 // header(2) + len(1) + addr(1) + cmd(1) + crc(2) - 1

        if (bytes.size - start < totalLen) return null

        val frame = bytes.copyOfRange(start, start + totalLen)
        buffer.reset()
        if (start + totalLen < bytes.size) {
            buffer.write(bytes, start + totalLen, bytes.size - start - totalLen)
        }

        return if (verifyCRC(frame)) parseFrame(frame) else null
    }
}

BLE-коммуникация и стабильность соединения

На Android BLE работает через BluetoothGatt. Главная боль — onConnectionStateChange с status = 133 (GATT_ERROR) при подключении, особенно на Android 12+ с включённым Bluetooth Permission. Лечение: retry с задержкой 500-1000 мс, максимум 3 попытки, после — показываем пользователю инструкцию переподключить Bluetooth.

class ScooterBLEManager(private val context: Context) {
    private var gatt: BluetoothGatt? = null
    private var retryCount = 0

    fun connect(device: BluetoothDevice) {
        gatt = device.connectGatt(context, false, object : BluetoothGattCallback() {
            override fun onConnectionStateChange(g: BluetoothGatt, status: Int, newState: Int) {
                when {
                    newState == BluetoothProfile.STATE_CONNECTED -> {
                        retryCount = 0
                        g.discoverServices()
                    }
                    status == 133 && retryCount < 3 -> {
                        retryCount++
                        g.close()
                        Handler(Looper.getMainLooper()).postDelayed({ connect(device) }, 800)
                    }
                    else -> notifyConnectionFailed()
                }
            }

            override fun onCharacteristicChanged(g: BluetoothGatt,
                characteristic: BluetoothGattCharacteristic, value: ByteArray) {
                frameParser.feed(value)
            }
        }, BluetoothDevice.TRANSPORT_LE)
    }
}

На iOS CBPeripheral стабильнее, но сессия CoreBluetooth не выживает после перезапуска приложения — сохраняем peripheral.identifier (UUID) в UserDefaults и восстанавливаем через retrievePeripherals(withIdentifiers:).

Дашборд: что показываем

Стандартный набор данных с контроллера самоката/велосипеда:

  • Скорость (км/ч) — реальная, с датчика колеса или расчётная из RPM + длина окружности
  • Заряд батареи (%) — из BMS, реже — расчётный по напряжению
  • Напряжение/ток батареи — важно для мониторинга рекуперации
  • Температура контроллера и мотора — критично для тяжёлых подъёмов
  • Пробег — одометр, суммарный и за поездку
  • Режим езды — Eco/Normal/Sport или D1-D5
  • Состояние тормозов (если датчики подключены к контроллеру)

Скоростной график за поездку — обязательный элемент. Renderим через MPAndroidChart (Android) или Swift Charts (iOS 16+). Данные пишем в Room/Core Data каждые 500 мс — поездка на 30 км при таком интервале = ~3600 точек, это не проблема.

Управление режимами и настройки контроллера

Ряд контроллеров позволяет перепрограммировать параметры: максимальный ток, ограничение скорости, мощность рекуперации. Отправляем write-команду в Notify Characteristic. Важно: изменения параметров контроллера требуют предупреждения пользователя и подтверждения — неправильный ток может вывести мотор из строя или разрядить батарею за поездку.

Для шеринговых сервисов (флот самокатов) добавляется серверная часть: MQTT или WebSocket, история поездок на бэкенде, геофенсинг, удалённая блокировка. Это отдельный уровень сложности.

Разработка приложения с BLE-подключением к самокату, дашбордом и записью поездок: 6-8 недель на одну платформу. Кросс-платформа на Flutter с поддержкой нескольких протоколов контроллеров: 3-4 месяца. Стоимость рассчитывается индивидуально после анализа конкретной модели устройства и наличия документации на протокол.