如何在Android 5.1的DragonBoard 410C上用Kotlin访问GPIO低功耗连接器
Hey Richard,我刚好折腾过DragonBoard 410C的Android GPIO开发,给你分享下实操经验,不管是用mraa库还是替代方案都能快速实现LED闪烁!
用mraa库实现Kotlin版LED闪烁
一、先搞定mraa库的集成
mraa有专门适配Android的预编译包,你不用自己编译,直接集成就行:
- 第一步:下载适配DragonBoard 410C的ARM架构mraa Android库,里面包含
libmraa.so动态库和对应的Java绑定类(或者打包好的mraa.jar)。 - 第二步:把
libmraa.so放到项目的app/src/main/jniLibs/armeabi-v7a目录(没有就新建这个路径)。 - 第三步:把
mraa.jar复制到app/libs目录,然后在Module级的build.gradle里添加依赖:implementation files('libs/mraa.jar')
二、Kotlin核心代码(LED闪烁)
首先要确认引脚映射:DragonBoard 410C的40针连接器引脚对应mraa的逻辑编号,比如GPIO_12对应的mraa编号是6(一定要查官方的mraa引脚映射表,别瞎猜)。
1. 配置权限
在AndroidManifest.xml里添加必要的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.usb.host" />
2. 闪烁逻辑代码
import io.mraa.Mraa import io.mraa.Gpio import kotlinx.coroutines.* import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private lateinit var gpio: Gpio private var isBlinking = false private val coroutineScope = CoroutineScope(Dispatchers.Default) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 关键:设置mraa适配DragonBoard平台 Mraa.setPlatform(Mraa.Platform.QUALCOMM_DRAGONBOARD) val targetPin = 6 // 替换成你实际要控制的mraa引脚编号 try { // 初始化GPIO为输出模式 gpio = Mraa.gpioInit(targetPin) gpio.dir(Gpio.DIR_OUT) } catch (e: Exception) { Log.e("MRAA_ERROR", "GPIO初始化失败: ${e.localizedMessage}") Toast.makeText(this, "GPIO初始化失败", Toast.LENGTH_SHORT).show() return } // 绑定按钮控制闪烁启停 btn_blink_toggle.setOnClickListener { isBlinking = !isBlinking if (isBlinking) startBlink() else stopBlink() } } private fun startBlink() { coroutineScope.launch { while (isBlinking) { gpio.write(1) // 点亮LED delay(500) gpio.write(0) // 熄灭LED delay(500) } } } private fun stopBlink() { gpio.write(0) // 确保LED熄灭 } override fun onDestroy() { super.onDestroy() isBlinking = false coroutineScope.cancel() gpio.close() // 必须释放GPIO资源,避免内存泄漏 } }
替代方案:直接操作sysfs(无需mraa)
如果mraa库集成遇到问题,你可以直接通过Android的sysfs文件系统控制GPIO,这是更底层的方式,但需要注意权限:
- 先查DragonBoard 410C的引脚对应内核GPIO编号(比如GPIO_12对应内核编号202)。
- 核心代码示例:
import java.io.FileWriter import kotlinx.coroutines.* class SysfsGpioController { private val kernelGpioNum = 202 // 替换成你的内核GPIO编号 private val exportPath = "/sys/class/gpio/export" private val unexportPath = "/sys/class/gpio/unexport" private val directionPath = "/sys/class/gpio/gpio$kernelGpioNum/direction" private val valuePath = "/sys/class/gpio/gpio$kernelGpioNum/value" private var isBlinking = false private val scope = CoroutineScope(Dispatchers.IO) fun initGpio() { try { // 导出GPIO FileWriter(exportPath).use { it.write(kernelGpioNum.toString()) } // 设置为输出方向 FileWriter(directionPath).use { it.write("out") } } catch (e: Exception) { e.printStackTrace() } } fun startBlink() { isBlinking = true scope.launch { while (isBlinking) { FileWriter(valuePath).use { it.write("1") } delay(500) FileWriter(valuePath).use { it.write("0") } delay(500) } } } fun cleanup() { isBlinking = false scope.cancel() try { FileWriter(valuePath).use { it.write("0") } FileWriter(unexportPath).use { it.write(kernelGpioNum.toString()) } } catch (e: Exception) { e.printStackTrace() } } }
⚠️ 注意:这种方式需要你的App拥有root权限,或者系统已经给sysfs的GPIO路径配置了可读写权限,否则会抛出权限异常。
踩坑提醒
- mraa的平台设置必须是
Mraa.Platform.QUALCOMM_DRAGONBOARD,设置错了会导致引脚完全对应不上。 - 不管用哪种方式,退出App时一定要释放GPIO资源(mraa调用
close(),sysfs执行unexport),否则下次启动可能无法正常访问引脚。 - 接线时注意LED的限流电阻,别直接接GPIO引脚,避免烧坏硬件。
内容的提问来源于stack exchange,提问作者Richard Chambers
相关产品推荐
相关产品推荐

