This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 2 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
wiringPi for Android
#31
(10-22-2018, 12:15 PM)lobo Wrote: I tried now to integrate the serial part into an app and it works so far. I think you missed to chmod the serial port:
Code:
chmod 666 /dev/ttyS1
If you need this at start, I see the only working solution so far to extract the boot.img and to modify the ueventd.rk30board.rc.

Hi lobo!

I use same method from http s://tinkerboarding.co.uk/forum/thread-671.html
And add next line
Code:
/dev/ttyS1                0660   system  system
# also i try 0666 value, but without success result.
to ueventd.rk30board.rc.

But without command
Code:
chmod 666 /dev/ttyS1
in adb wiringPi not works.

Android M V13.13.0.74.

Note:
I copy file from my TB to desktop
Code:
adb pull ueventd.rk30board.rc /Users/user/Desktop/test
and it contains my line with correct permission for /dev/ttyS1
Reply
#32
Then show please what shows 'ls -la /dev/ttyS1' directly after reboot. Maybe another method is setting the permission back?

[EDIT]
A quick search:
Code:
grep -r "/dev/ttyS1" .
./init.connectivity.rc:    chmod 0660 /dev/ttyS1
./init.connectivity.rc:    chown bluetooth net_bt_stack /dev/ttyS1
Maybe this is making this. Try to remove this lines from 'init.connectivity.rc' and lets see if it works.
[-] The following 1 user Likes lobo's post:
  • fited
Reply
#33
(02-12-2019, 05:07 PM)lobo Wrote: Then show please what shows 'ls -la /dev/ttyS1' directly after reboot. Maybe another method is setting the permission back?

[EDIT]
A quick search:
Code:
grep -r "/dev/ttyS1" .
./init.connectivity.rc:    chmod 0660 /dev/ttyS1
./init.connectivity.rc:    chown bluetooth net_bt_stack /dev/ttyS1
Maybe this is making this. Try to remove this lines from 'init.connectivity.rc' and lets see if it works.

Wow, i didn't even think about it! Most likely the issue in this overrides.
I will try in 10 hours and post results! I forget device at home.
Thank you very much for answer!
[-] The following 1 user Likes fited's post:
  • fited
Reply
#34
(02-12-2019, 05:07 PM)lobo Wrote: Maybe this is making this. Try to remove this lines from 'init.connectivity.rc' and lets see if it works.
Yes, after i remove this lines, all works perfectly! You rock! Thank you very much again!!!
Reply
#35
(10-20-2017, 03:53 AM)Ecce Wrote: Great job, thanks for your work !

I push the library into jniLibs folder and build an android app to access gpio, it is working for me.

This is my execution result.


* I modify the Application.mk for tinkerboard
Code:
APP_ABI := armeabi armeabi-v7a

How did you communicate from the wirinpi to your app? I made an Android app in unity and successfully deployed it on the Tinker Board but i don't know how to read/write the GPIO
Reply
#36
Hello ugobyte,
sorry for late response. Maybe you have found the solution already?
Anyway here is a small receipt:

First read (if you not have yet), how to add jni code to your AndroidStudio project: https://developer.android.com/studio/pro...ative-code

You will have or add a cpp folder in src/main. There you create a Cmake makefile CMakeLists.txt, the wiring.h from TB wiringPi source code and a cpp library as e.g. wpi_android.cpp. The cpp library acts as bridge between the wiringPi C code and the Java code.

A CMakeLists.txt (to compile the wpi_android.cpp):
Code:
cmake_minimum_required(VERSION 3.4.1)

set(CMAKE_VERBOSE_MAKEFILE on)

find_library( log-lib log )

add_library( wiringPi SHARED IMPORTED )

set_target_properties( wiringPi PROPERTIES IMPORTED_LOCATION
       /path/to/wiringPi/libs/${ANDROID_ABI}/libwiringPi.so )

add_library( # Sets the name of the library.
            wpi_android

            # Sets the library as a shared library.
            SHARED

            # Provides a relative path to your source file(s).
            # Associated headers in the same location as their source
            # file are automatically included.
            wpi_android.cpp )

target_include_directories(wpi_android PUBLIC
       /path/to/wiringPi/jni/wiringPi
       )

target_link_libraries( # Specifies the target library.
                      wpi_android
                      # Links the target library to the log library
                      # included in the NDK.
                      ${log-lib}
                      wiringPi
                      )
You would need to correct the paths to your needs.

A wpi_android.cpp:
Code:
#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <string.h>

#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOG_TAG "wpi_android"

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/system_properties.h>

#include <softPwm.h>
#include <dlfcn.h>

#include "wiringPi.h"

#ifdef __cplusplus
extern "C" {
#endif

jint Java_com_jw_wiringpi_wpiAndroid_wiringPiSetupSys(JNIEnv* env, jobject obj) {
   LOGI("Entering wiringPiSetupSys");
   return wiringPiSetupSys();
}


jint Java_com_jw_wiringpi_wpiAndroid_wiringPiSetup(JNIEnv* env, jobject obj) {
   LOGI("Entering wiringPiSetup");
   return wiringPiSetup();
}

//void pullUpDnControl (int pin, int pud)
void Java_com_jw_wiringpi_wpiAndroid_pullUpDnControl(JNIEnv* env, jobject obj, jint port, jint pud) {
   return pullUpDnControl(port, pud);
}

//void pinMode (int pin, int mode)
void Java_com_jw_wiringpi_wpiAndroid_pinMode(JNIEnv* env, jobject obj, jint port, jint mode) {
   return pinMode(port, mode);
}

//void pinModeAlt (int pin, int mode)
void Java_com_jw_wiringpi_wpiAndroid_pinModeAlt(JNIEnv* env, jobject obj, jint port, jint mode) {
   pinModeAlt(port, mode);
}

jint Java_com_jw_wiringpi_wpiAndroid_digitalRead(JNIEnv* env, jobject obj, jint port) {
   return digitalRead(port);
}

//int getAlt (int pin)
jint Java_com_jw_wiringpi_wpiAndroid_getAlt(JNIEnv* env, jobject obj, jint port) {
   return getAlt(port);
}

void Java_com_jw_wiringpi_wpiAndroid_digitalWrite(JNIEnv* env, jobject obj, jint port, jint onoff) {
   digitalWrite(port, onoff);
}

jint Java_com_jw_wiringpi_wpiAndroid_analogRead(JNIEnv* env, jobject obj, jint port) {
   return analogRead(port);
}

jint Java_com_jw_wiringpi_wpiAndroid_softPwmCreate(JNIEnv* env, jobject obj, jint port, jint value, jint range) {
   return softPwmCreate(port, value, range);
}

void Java_com_jw_wiringpi_wpiAndroid_softPwmWrite(JNIEnv* env, jobject obj, jint port, jint value) {
   softPwmWrite(port, value);
}

void Java_com_jw_wiringpi_wpiAndroid_softPwmStop(JNIEnv* env, jobject obj, jint port) {
   softPwmStop(port);
}

void Interrupt(void) {
   LOGI("Interrupt");
}

jint Java_com_jw_wiringpi_wpiAndroid_wiringPiISR(JNIEnv* env, jobject obj, jint port, jint edge) {
   return wiringPiISR (port, edge, &Interrupt);
}


#ifdef __cplusplus
}
#endif
Note the syntax of the functions: Java_com_jw_wiringpi_wpiAndroid_wiringPiSetup. This points to a Java class com.jw.wiringpi.wpiAndroid. But you are free to rename this to your own needs. I for myself stay with this and add a package to my AndroidStudio project com.jw.wiringpi and a class wpiAndroid.

In app/build.gradle there must be added externalNativeBuild.cmake.path = "src/main/cpp/CMakeLists.txt" to make AndroidStudio find the CmakeLists.txt.
With this, the wpi_android.cpp should be compiled during build process.

The Java class wpiAndroid:
Code:
package com.jw.wiringpi;

/**
* Created by joerg on 16.09.17.
*/

public final class wpiAndroid {
   static {
       System.loadLibrary("wpi_android");
   }
   static public native int wiringPiSetup();
   static public native int wiringPiSetupSys();
   static public native void digitalWrite(int port, int onoff);
   static public native int digitalRead(int port);
   static public native void pullUpDnControl(int port, int pud);
   static public native void pinMode(int port, int mode);
   static public native int softPwmCreate(int port, int value, int range);
   static public native void softPwmWrite  (int port, int value) ;
   static public native void softPwmStop   (int port) ;
}

In you app code to initialize wiringPi, e.g. in onCreate():
Code:
if (wiringPiSetup() != 0) {
Log.e(TAG, "Error setting up wiringPi!");
}
If AndroidStudio doesn't find the function by itself, you can add a import statement:
Code:
import static com.jw.wiringpi.wpiAndroid.wiringPiSetup;

Somewhere in your code to read a gpio:
Code:
int in = digitalRead(24)

Or to write a gpio:
Code:
digitalWrite(21, 1)

If there is no gpiomem driver with permission 666 to /dev/gpiomem, the access to /dev/mem is restricted and you would need root access with your app!

Hope it helps an happy coding.
Reply
#37
(04-14-2019, 06:59 AM)lobo Wrote: Hello ugobyte,
sorry for late response. Maybe you have found the solution already?
Anyway here is a small receipt:

Thanks for such a detailed response. I will begin trying it now.
Reply
#38
I am having a weird issue with I2C:

Let me show you the first code: 
Code:
#include <wiringPi.h>
#include <stdio.h>
#include <wiringPiI2C.h>

void main(void)
{
   char rd = '';
   wiringPiSetup () ;
   int dev = wiringPiI2CSetup(8);
   int i=0;
   printf ("dev id = %d",dev);
   
   while(1)
   {
      read(dev, rd, 1);
      printf ("digitalread I2C 0x08 rd:%c\n", rd);
      delay(1000);
   }

}

I built this code as an executable, executed it from adb shell, and it worked perfectly fine. Now my actual application is an app and it should read data from the i2c slave and display it. So, I created a shared library:

Code:
#include <wiringPi.h>
#include <stdio.h>
#include <wiringPiI2C.h>

char command()
{
   char rd = '';
   wiringPiSetup () ;
   int dev = wiringPiI2CSetup(8);
   int i=0;

   read(dev, rd, 1);

   return rd;

}

When I start the app, it crashes. I traced the problem back to the following lines in wiringPiI2C.c:
Code:
if ((fd = open (device, O_RDWR)) < 0)
   return wiringPiFailure (WPI_ALMOST, "Unable to open I2C device: %s\n", strerror (errno)) ;

For some reason, the open function returns a value less than zero and then the wiringPiFailure function causes the app to crash.

ls -la /dev/i2c* gives me the following
Code:
crw------- root     root      89,   0 2013-01-21 08:50 i2c-0
crw-rw-rw- system   system    89,   1 2013-01-21 08:50 i2c-1
crw-rw---- system   system    89,   2 2013-01-21 08:50 i2c-2
crw-rw---- system   system    89,   3 2013-01-21 08:50 i2c-3
crw-rw---- system   system    89,   4 2013-01-21 08:50 i2c-4
crw------- root     root      10,  51 2013-01-21 08:50 i2c_detect

What am I doing wrong?
Reply
#39
I think you need to chmod 666 /dev/i2c-1. If your app is running after that, you would need to edit ueventd.rk30board.rc. This is done by repacking the boot.img and flashing to TB or directly to sdcard.
If it is not running, your app needs root. If you are on Android Nougat, you would need to install Magisk for that and put some code in your app for getting root permission.
Reply
#40
Good job has done so far. Carry on!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)