{"id":20354652,"url":"https://github.com/alexlopezdevelop/lsmaker","last_synced_at":"2025-06-14T12:04:16.384Z","repository":{"id":113667165,"uuid":"296550489","full_name":"AlexLopezDevelop/LSMaker","owner":"AlexLopezDevelop","description":null,"archived":false,"fork":false,"pushed_at":"2021-08-01T08:47:12.000Z","size":9904,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-14T12:02:11.415Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlexLopezDevelop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-18T07:44:19.000Z","updated_at":"2021-08-01T08:47:16.000Z","dependencies_parsed_at":"2023-07-09T14:45:36.681Z","dependency_job_id":null,"html_url":"https://github.com/AlexLopezDevelop/LSMaker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AlexLopezDevelop/LSMaker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLopezDevelop%2FLSMaker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLopezDevelop%2FLSMaker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLopezDevelop%2FLSMaker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLopezDevelop%2FLSMaker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexLopezDevelop","download_url":"https://codeload.github.com/AlexLopezDevelop/LSMaker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLopezDevelop%2FLSMaker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259812991,"owners_count":22915196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T23:09:17.310Z","updated_at":"2025-06-14T12:04:11.376Z","avatar_url":"https://github.com/AlexLopezDevelop.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LSMaker APP Docs\n\n# Introducción\n\nEsta documentación se ha realizado con el fin de poder tener una base desde la que poder partir para saber el funcionamiento de la conexión entre la app iOS/Android y el LSMaker via Bluetooth\n\n# Configuración\n\n## Establecer conexión\n\nPara poder conectarse al LSMaker via bluetooth se necesita usar una librería que gestione dicha comunicación, en el caso de iOS se usa CoreBluetooth que es la librería nativa de Apple y en el caso de Android se usa BluetoothGatt que también es la librería nativa de Google.\n\n[Apple Developer Documentation](https://developer.apple.com/documentation/corebluetooth)\n\n[Android Developer Documentation](https://developer.android.com/reference/android/bluetooth/BluetoothGatt)\n\nUna vez se disponga de una libraría bluetooth, para poder mantener la conexión entre la App y el LSMaker es necesario es saber los UUID para el envío de información. \n\n[UUID](https://www.notion.so/670b59fb4d7c4282bf37198fcac5acc5)\n\n## Enviar información\n\nPara un mejor entendimiento usaremos de ejemplo el código de iOS.\n\nUsando la librería CoreBluetooth una vez se selecciona el dispositivo al que se quiere conectar, se ejecuta la función *didDiscoverServices* que es la encargada de buscar la característica/servicio a la que se quiere conectar.\n\n```swift\nfunc peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {\n        for service in peripheral.services! {\n            print(\"Service found with UUID: \" + service.uuid.uuidString)\n\n            //device information service\n            if (service.uuid.uuidString == rxServiceUUID?.uuidString) {\n                peripheral.discoverCharacteristics(nil, for: service)\n            }\n        }\n    }\n```\n\nAccedemos a todos los servicios que tiene el dispositivo *peripheral.services* y buscamos el que necesitemos en este caso sería el *rxServiceUUID*.\n\nUna vez se encuentra el servicio llamamos a la función *discoverCharacteristics* que es la que se encarga de enviarle la información al LSMaker.\n\n```swift\nfunc peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {\n        if (service.uuid.uuidString == rxServiceUUID?.uuidString) {\n            if let characteristic = service.characteristics?.first(where: { (c) -\u003e Bool in\n                c.uuid.uuidString == rxCharUUID?.uuidString\n            }) {\n\n                lsmakerBluetooth.initialize(peripheral: peripheral, characteristic: characteristic)\n\n                let lsMakerAcceleration: UInt8 = 0x15\n\n                let queue = DispatchQueue(label: \"lsmaker.control.thread\")\n\n                queue.async { [self] in\n                    while connection {\n                        lsmakerBluetooth.move(\n                                speed: drivingDataManager.speed,\n                                acceleration: lsMakerAcceleration,\n                                turn: drivingDataManager.turn)\n                        usleep(2000)\n                    }\n                }\n            }\n        }\n    }\n```\n\nComo ya se ha dicho esta función sera la encargada de mantener la conexión y estar enviando la información al LSMaker. Para un mejor entendimiento iremos paso a paso que hace este código.\n\nPrimeramente volvemos a revisar qué es el servicio correcto. Posteriormente obtenemos el servicio para posteriormente usarlo.\n\n```swift\nif (service.uuid.uuidString == rxServiceUUID?.uuidString) {\n            if let characteristic = service.characteristics?.first(where: { (c) -\u003e Bool in\n                c.uuid.uuidString == rxCharUUID?.uuidString\n            })\n```\n\nInicializamos el objeto quien se encargara de proporcionar los datos que se actualizan en cualquier otra vista de la app. \n\n```swift\nlsmakerBluetooth.initialize(peripheral: peripheral, characteristic: characteristic)\n```\n\n```swift\nclass BluetoothService {\n    var peripheral: CBPeripheral?\n    var characteristic: CBCharacteristic?\n\n    func initialize(peripheral: CBPeripheral, characteristic: CBCharacteristic) {\n        self.peripheral = peripheral\n        self.characteristic = characteristic\n    }\n\n    func move(speed: UInt8, acceleration: UInt8, turn: UInt8) {\n        let value: [UInt8] = [\n            0x00, // header\n            0x00, // opcode\n            speed, // speed\n            acceleration, // acceleration\n            turn // turn\n        ]\n\n        if let lsmakerCharacteristic = characteristic {\n            peripheral?.writeValue(Data(value), for: lsmakerCharacteristic, type: .withoutResponse)\n        }\n    }\n}\n```\n\nCómo podemos ver en el ejemplo podríamos directamente enviarle los datos dentro de la función  pero paparte de ser una mala práctica. No podríamos actualizar el valor desde otra parte de la App, ya que siempre se enviaría el mismo valor. Aun así ayuda para poder probar de que se a realizado la conexión correctamente.\n\n```swift\nlet lsMakerAcceleration: UInt8 = 0x15 //bad\n```\n\nAqui simplemente creamos un hilo independiente al principal, que se encargue de mantener la conexión y estar enviando los datos, ya que en el caso de estar en el mismo hilo principal la app se quedaría parada hasta que acabe la conexión.\n\n```swift\nlet queue = DispatchQueue(label: \"lsmaker.control.thread\")\n\tqueue.async { [self] in\n```\n\nEste bucle es el encargado de constantemente enviarle datos al LSMaker, por lo que mientras haya conexión se estará ejecutando y enviara los valores de velocidad, aceleración y giro que tenga la clase lsmakerBluetooth en ese momento.\n\nImportante poner un delay ya que si se envía tanta información el procesador del LSMaker se colapsa\n\n```swift\nwhile connection {\n\tlsmakerBluetooth.move(\n\t   speed: drivingDataManager.speed,\n     acceleration: lsMakerAcceleration,\n     turn: drivingDataManager.turn\n\t)\n  usleep(2000)\n}\n```\n\n## Parámetros a enviar\n\nEn este caso se han de enviar 3 parámetros para el movimiento:\n\n[Movimiento](https://www.notion.so/92eb18f3c93b49c880d2ba437c72a976)\n\nPara crear el byte, seria añadirle 0x al valor. \n\nEjemplo: Si quiero una velocidad de 50 el valor a enviar seria: 0x50\n\nTodos estos parámetros han de ir en un array a la hora de enviarlo con un header y opcode que por defecto son siempre 0x00:\n\n```jsx\nlet valueToSend: [UInt8] = [\n            0x00, // header\n            0x00, // opcode\n            speed, // Velocidad\n            acceleration, // Aceleración \n            turn // Giro\n        ]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexlopezdevelop%2Flsmaker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexlopezdevelop%2Flsmaker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexlopezdevelop%2Flsmaker/lists"}