文档章节

Android NDK GPIO操作(pcduino 装Android系统)

simpower
 simpower
发布于 2014/11/01 13:07
字数 965
阅读 1045
收藏 0

开发工具: Eclipse
开发语言: Java和c++
     Pcduino跑Android系统让我兴奋了很长时间,也由此幻想了很多有趣的应用。例如 结合Yeelink做远程加电控制;结合微信开放接口与传感器向好友推送信息等等。 当然这些有趣的应用都离不开PCDUINO硬件的操作。那么在Android系统下怎么来操作硬件呢?我想大概有以下几种方式:


1、利用Arduino 库自己写c++程序然后编译成可执行文件,然后把可执行文件拷到PCDUINO中,添加权限,在模拟中端里运行可执行文件。
     优点:Arduino库函数完善,非常容易操作。
     缺点:貌似和Android开发的应用不能完美的结合。

2、利用Android 的Jni编程,直接驱动GPIO。
     优点:开发工具简单,利用Eclipse进行交叉编译,同时编译Java和c++代码。并且把硬件操作函数生成.so文件直接打包APK中。

     下面我们利用ANDROID NDK来开发一个简单实例: "光电开关控制UI上的灯泡亮灭"

      第一步:开发环境的搭建
                  1、安装Eclipse
                  2、安装ADT-v20插件(该版本已经直接支持Native编程)
                  3、安装CDT(编译c++代码)
                  3、安装android-ndk-r8e(该版本支持Windows,不用在Cygwin下编译了)
       按照这种模式搭建的开发环境用起来非常上手,java和c++程序直接交叉编译,然后打包生成APK.
      第二步:实例演练
                  1、新建Android 工程HelloJni,编写Java代码如下(定义本地函数)
                 public class MainActivity extends Activity 
            {        
                  @Override
                  protected void onCreate(Bundle savedInstanceState) 
        
              {
                super.onCreate(savedInstanceState);
                setTitle(getHelloJniData());
        
               }

                //c++中要实现的函数接口
                 public native String getHelloJniData();    //从本地函数获得字符串
                 public native void OpenLed();                //打开LED灯,本例子对应GPIO3
                 public native void CloseLed();                //关闭LED灯
                 public native int  ReadGpioState(int i);    //读取某个GPIO的状态,然后返回给Java层

                 //库载入代码
                 static
                 {
                     System.loadLibrary("Hellojni");          //Hellojni本地SO库
                  }
             }
                    2、实现本地c++代码
            (此处注意可以利用 javah 生成头文件,也可以自己按照Jni规则写)


             #define GPIO_MODE_DIR "/sys/devices/virtual/misc/gpio/mode/"
             #define GPIO_PIN_DIR "/sys/devices/virtual/misc/gpio/pin/"
             #define GPIO_IF_PREFIX "gpio"



            JNIEXPORT jstring JNICALL Java_com_hellojni_MainActivity_getHelloJniData (JNIEnv * env, jobject obj )
             
             {
                  return (*env)->NewStringUTF(env, "hello jni");
             }


              JNIEXPORT void JNICALL Java_com_hellojni_MainActivity_OpenLed (JNIEnv * env, jobject obj)   //打开LED
           {




                __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"OPEN- LED");


                memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_MODE_DIR, GPIO_IF_PREFIX, 3);    //此处对应地址/sys/devices/virtual/misc/gpio/mode/gpio3 设置为输出
                fd = open(path, O_RDWR);
                write(fd,"1",1);
                close(fd);


                 memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, 3);         //此处对应地址/sys/devices/virtual/misc/gpio/pin/gpio3 设置为高定平
                fd = open(path, O_RDWR);
                write(fd,"1",1);
                close(fd);
        }


       JNIEXPORT void JNICALL Java_com_hellojni_MainActivity_CloseLed(JNIEnv * env, jobject obj) //关闭LED
               
       {
              __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"CLOSE LED");
                memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_MODE_DIR, GPIO_IF_PREFIX, 3);
                fd = open(path, O_RDWR);
                write(fd,"1",1);
                close(fd);


                memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, 3);
                fd = open(path, O_RDWR);
                write(fd,"0",1);
                close(fd);
       }



       JNIEXPORT jint JNICALL Java_com_hellojni_MainActivity_ReadGpioState (JNIEnv *env, jobject obj,jint i) //读取某个IO口的状态
            {
                   char buf[4];
                    int ret = -1;
                    int fd = -1;
                    int state;


                    memset((void *)buf, 0, sizeof(buf));


                    memset(path, 0, sizeof(path));
                    sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, i);
                    fd = open(path, O_RDWR);
                    ret = read(fd, buf, sizeof(buf));


                    ret = buf[0] - '0';
                           switch( ret )
                           {
                               case 0:
                                       state=0;
                                    //   __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"LOW");    返回LOG调试信息
                                         break;
                               case 1:
                                       state=1;
                                    //   __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"HIGHT");
                                     break;
                               default:
                                       state=-1;
                                   ret = -1;
                                   break;
                           }
                      close(fd);
                             //  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"READ GPIO STATE");
            return state;
        }



                  3、到这里关键代码就都准备好了,可以直接在Java层调用这些接口函数操作IO了。下面最后再配置一下Eclipse交叉编译环境。
                         
                       右击HelloJni的工程属性,弹出 窗口,选Builders --->New---NDK_Builder。

 




 




 




 




 




到此开发环境搭建完毕!具体的细节哪里有问题,可以问度娘哦!!!


工程文件见附件!!!


感谢Lucifer㊣(1094294)大神的指导!!!




 hellojni.rar (985.58 KB, 下载次数: 22) 







  




本文转载自:http://www.pcduino.org/forum.php?mod=viewthread&tid=440

simpower
粉丝 28
博文 669
码字总数 50544
作品 0
海淀
程序员
私信 提问
Android LED(NDK)

开发工具: Eclipse 开发语言: Java、C 拿到pcDuino很久了,因为太忙一直没有用过。最近把原版的ubuntu换成了Android,以前自学过Android App,但没有操作底层资源的经验。通过借鉴 “shina...

simpower
2014/11/01
67
0
GPIO-Manager-Android

Android Version This is an Android version of the original Swing program located here: https://github.com/MohammadAdib/GPIO-Manager Originally created by: Mohammad Adib Thank yo......

微微的薄雾
2014/01/07
411
0
pcDuino上安装IOIO-OTG应用程序显示传感器波形

在Android+IOIO环境下安装一个简单的app应用可以显示模拟传感器输入信号,现在我想用pcDuino装Android系统运行IOIOSensorGraph.apk显示传感器波形,通过Rotary Potentiometer Module改变输入...

pc朵拉
2013/07/02
1K
3
在pcDuino的Android系统上控制IO

有了QT5,我们可以很方便的为Android写程序,尤其对于不熟悉Android SDK (或者Java)的开发人员。 对于只熟悉C语言或者Arduino编程的人来说,现在也可以轻松开发Android 程序了。 下面我们简要...

pc朵拉
2013/08/08
106
0
在pcDuino的Android系统上控制IO

有了QT5,我们可以很方便的为Android写程序,尤其对于不熟悉Android SDK (或者Java)的开发人员。 对于只熟悉C语言或者Arduino编程的人来说,现在也可以轻松开发Android 程序了。 下面我们简要...

pc朵拉
2013/07/30
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
15
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
16
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部