This is an old revision of the document!
−Table of Contents
Introduction C Tinkering Kit on Ubuntu
You're probably itching to make some fun embedded computer projects with ODROID-C1. What you need is an add on prototyping T-breakout board, which can break out all those tasty power, GPIO, I2C, ADC pins from the 40 pin header onto a solderless breadboard. This set will make “cobbling together” prototypes with the ODROID-C1 super easy.
This kit comes with below many items.
- Assembled T-breakout PCB - 40Pin GPIO Breakout board
- Breadboard - 630 Tie-points with dual power lanes
- 40pin Ribbon cable - IDC Flat cable 100mm
- 40pin Male-to-Male Dupont jumper Wire 170mm
- 7 x Green LED 3mm
- 7 x Yellow LED 3mm
- 7 x Red LED 3mm
- 2 x Photo Cell (CdS Light sensor)
- 6 x Tact Switchs
- 50 x 330 Ohm 1/6W resister
- 50 x 10K Ohm 1/6W resister
DIY light level meter project
Linux
1. Configuration tinkering kit such as below schematic.
Light Level Meter schematic
2. Get the wiringPi library compatible ODROID-C1
# git clone https://github.com/hardkernel/wiringPi
3. Build the library
# cd wiringPi # ./build
4. Compile and run the example source code.
- example-led.c
//------------------------------------------------------------------------------------------------------------ // // ODROID-C GPIO(LED) / ADC Test Application. // // Defined port number is wiringPi port number. // // Compile : gcc -o <create excute file name> <source file name> -lwiringPi -lwiringPiDev -lpthread // Run : sudo ./<created excute file name> // //------------------------------------------------------------------------------------------------------------ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include <string.h> #include <time.h> #include <wiringPi.h> #include <wiringPiI2C.h> #include <wiringSerial.h> #include <lcd.h> //------------------------------------------------------------------------------------------------------------ // // Global handle Define // //------------------------------------------------------------------------------------------------------------ #define DATA_UPDATE_PERIOD 100 // 100ms //------------------------------------------------------------------------------------------------------------ // // ADC: // //------------------------------------------------------------------------------------------------------------ #define PORT_ADC1 0 // ADC.AIN0 static int adcValue = 0; //------------------------------------------------------------------------------------------------------------ // // LED: // //------------------------------------------------------------------------------------------------------------ static int ledPos = 0; const int ledPorts[] = { 24, // GPIOX.BIT0(#97) 23, // GPIOX.BIT11(#108) 22, // GPIOX.BIT3(#100) 21, // GPIOX.BIT4(#101) 14, // GPIOX.BIT8(#105) 13, // GPIOX.BIT9(#106) 12, // GPIOX.BIT10(#107) 3, // GPIOX.BIT18(#115) 2, // GPIOX.BIT19(#116) 0, // GPIOY.BIT8(#88) 7, // GPIOY.BIT3(#83) 1, // GPIOY.BIT7(#87) 4, // GPIOX.BIT7(#104) 5, // GPIOX.BIT5(#102) 6, // GPIOX.BIT6(#103) 10, // GPIOX.BIT20(#117) 26, // GPIOX.BIT2(#99) 11, // GPIOX.BIT21(#118) 27, // GPIOX.BIT1(#98) }; #define MAX_LED_CNT sizeof(ledPorts) / sizeof(ledPorts[0]) //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ // // system init // //------------------------------------------------------------------------------------------------------------ int system_init(void) { int i; // GPIO Init(LED Port ALL Output) for(i = 0; i < MAX_LED_CNT; i++) pinMode (ledPorts[i], OUTPUT); return 0; } //------------------------------------------------------------------------------------------------------------ // // board data update // //------------------------------------------------------------------------------------------------------------ void boardDataUpdate(void) { int i; // adc value read if((adcValue = analogRead (PORT_ADC1))) { ledPos = (adcValue * MAX_LED_CNT * 1000) / 1024; ledPos = (MAX_LED_CNT - (ledPos / 1000)); } else ledPos = 0; // LED Control for(i = 0; i < MAX_LED_CNT; i++) digitalWrite (ledPorts[i], 0); // LED All Clear for(i = 0; i < ledPos; i++) digitalWrite (ledPorts[i], 1); // LED On } //------------------------------------------------------------------------------------------------------------ // // Start Program // //------------------------------------------------------------------------------------------------------------ int main (int argc, char *argv[]) { static int timer = 0 ; wiringPiSetup (); if (system_init() < 0) { fprintf (stderr, "%s: System Init failed\n", __func__); return -1; } for(;;) { usleep(100000); if (millis () < timer) continue ; timer = millis () + DATA_UPDATE_PERIOD; // All Data update boardDataUpdate(); } return 0 ; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
Python example
Prerequisites: You must have python-dev and python-setuptools installed If you manually rebuild the bindings with swig-python wiringpi.i
0. Get/setup WiringPi library (If you already installed WiringPi library, skip this step.)
# git clone https://github.com/hardkernel/wiringPi.git # cd wiringPi # sudo ./build
1. Get/setup WiringPi 2 for Python repository
# git clone https://github.com/hardkernel/WiringPi2-Python.git # cd WiringPi2-Python
2. Build & install
# sudo python setup.py install
3. Run the example source code
- example-led.py
#!/usr/bin/python import wiringpi2 as wpi import time leds = [24, 23, 22, 21, 14, 13, 12, 3, 2, 0, 7, 1, 4, 5, 6, 10, 26, 11, 27] wpi.wiringPiSetup() # GPOI pin setup for x in leds: wpi.pinMode(x, 1) wpi.digitalWrite(x, 0) adc_unit = 4095 / len(leds) while True: time.sleep(0.05) # Read the adc value adcValue = wpi.analogRead(0) # Set the LEDs ledPos = (adcValue * len(leds) * 1000) / 1024 ledPos = len(leds) - (ledPos / 1000) for x in leds: wpi.digitalWrite(x, 0) for x in xrange(ledPos): wpi.digitalWrite(leds[x], 1)
Android
This process explains how to make an Android app which can access IO ports.
You need to install Google Android SDK/NDK on your host PC first to start below steps.
Insert this line into your ~/.bashrc file.
export NDK_PATH=/home/xxx/android-ndk-r10d
1. Download the wiringPi library and example App source code.
# git clone https://github.com/codewalkerster/example-led
2. Build a JNI library
$ cd example-led $ cd jni $ ndk-build Android NDK: WARNING: APP_PLATFORM android-16 is larger than android:minSdkVersion 7 in /media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/AndroidManifest.xml [armeabi] Compile thumb : wiringPi <= wiringPi.c /media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c:147:0: warning: "PAGE_SIZE" redefined [enabled by default] #define PAGE_SIZE (4*1024) ^ In file included from /home/codewalker/projects/android-ndk-r10d/platforms/android-21/arch-arm/usr/include/signal.h:34:0, from /home/codewalker/projects/android-ndk-r10d/platforms/android-21/arch-arm/usr/include/poll.h:34, from /media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c:59: /home/codewalker/projects/android-ndk-r10d/platforms/android-21/arch-arm/usr/include/limits.h:119:0: note: this is the location of the previous definition #define PAGE_SIZE 4096 ^ /media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c: In function 'interruptHandler': /media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c:1865:7: warning: return makes pointer from integer without a cast [enabled by default] return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; ^ [armeabi] Compile thumb : wiringPi <= wiringShift.c [armeabi] Compile thumb : wiringPi <= piHiPri.c [armeabi] Compile thumb : wiringPi <= piThread.c [armeabi] Compile thumb : wiringPi <= wiringPiSPI.c [armeabi] Compile thumb : wiringPi <= wiringPiI2C.c [armeabi] Compile thumb : wiringPi <= softPwm.c [armeabi] Compile thumb : wiringPi <= softTone.c [armeabi] Compile thumb : wiringPi <= mcp23008.c [armeabi] Compile thumb : wiringPi <= mcp23016.c [armeabi] Compile thumb : wiringPi <= mcp23017.c [armeabi] Compile thumb : wiringPi <= mcp23s08.c [armeabi] Compile thumb : wiringPi <= mcp23s17.c [armeabi] Compile thumb : wiringPi <= sr595.c [armeabi] Compile thumb : wiringPi <= pcf8574.c [armeabi] Compile thumb : wiringPi <= pcf8591.c [armeabi] Compile thumb : wiringPi <= mcp3002.c [armeabi] Compile thumb : wiringPi <= mcp3004.c [armeabi] Compile thumb : wiringPi <= mcp4802.c [armeabi] Compile thumb : wiringPi <= mcp3422.c [armeabi] Compile thumb : wiringPi <= max31855.c [armeabi] Compile thumb : wiringPi <= max5322.c [armeabi] Compile thumb : wiringPi <= sn3218.c [armeabi] SharedLibrary : libwiringPi.so [armeabi] Install : libwiringPi.so => libs/armeabi/libwiringPi.so [armeabi] Compile thumb : wiringPiDev <= ds1302.c [armeabi] Compile thumb : wiringPiDev <= maxdetect.c [armeabi] Compile thumb : wiringPiDev <= piNes.c [armeabi] Compile thumb : wiringPiDev <= gertboard.c [armeabi] Compile thumb : wiringPiDev <= piFace.c [armeabi] Compile thumb : wiringPiDev <= lcd128x64.c [armeabi] Compile thumb : wiringPiDev <= lcd.c [armeabi] Compile thumb : wiringPiDev <= piGlow.c [armeabi] SharedLibrary : libwiringPiDev.so [armeabi] Install : libwiringPiDev.so => libs/armeabi/libwiringPiDev.so [armeabi] Compile thumb : wpi_android <= wpi_android.c [armeabi] SharedLibrary : libwpi_android.so [armeabi] Install : libwpi_android.so => libs/armeabi/libwpi_android.so
3. Import existing project to the eclipse IDE.
4. Run example-led
https://www.youtube.com/watch?v=zyfULOkj0Vw
5. Source code browsing!
Add below items in jni/Android.mk to build libwingPi.so and libwingPiDev.so
include $(CLEAR_VARS) LOCAL_C_INCLUDES += \ $(NDK_PATH)/platforms/android-21/arch-arm/usr/include \ $(LOCAL_PATH)/wiringPi LOCAL_MODULE := wiringPi LOCAL_SRC_FILES := \ wiringPi/wiringPi.c \ wiringPi/wiringShift.c \ wiringPi/piHiPri.c \ wiringPi/piThread.c \ wiringPi/wiringPiSPI.c \ wiringPi/wiringPiI2C.c \ wiringPi/softPwm.c \ wiringPi/softTone.c \ wiringPi/mcp23008.c \ wiringPi/mcp23016.c \ wiringPi/mcp23017.c \ wiringPi/mcp23s08.c \ wiringPi/mcp23s17.c \ wiringPi/sr595.c \ wiringPi/pcf8574.c \ wiringPi/pcf8591.c \ wiringPi/mcp3002.c \ wiringPi/mcp3004.c \ wiringPi/mcp4802.c \ wiringPi/mcp3422.c \ wiringPi/max31855.c \ wiringPi/max5322.c \ wiringPi/sn3218.c LOCAL_CFLAGS += -UNDEBUG -DANDROID LOCAL_LDLIBS := -ldl -llog include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_C_INCLUDES += \ $(NDK_PATH)/platforms/android-21/arch-arm/usr/include \ $(LOCAL_PATH)/wiringPi LOCAL_MODULE := wiringPiDev LOCAL_SRC_FILES := \ devLib/ds1302.c \ devLib/maxdetect.c \ devLib/piNes.c \ devLib/gertboard.c \ devLib/piFace.c \ devLib/lcd128x64.c \ devLib/lcd.c \ devLib/piGlow.c LOCAL_SHARED_LIBRARIES := libwiringPi LOCAL_CFLAGS += -UNDEBUG include $(BUILD_SHARED_LIBRARY)
Make some JNI API functions to access the wirinPi library.
jint Java_com_hardkernel_wiringpi_MainActivity_analogRead(JNIEnv* env, jobject obj, jint port) { return analogRead(port); } void Java_com_hardkernel_wiringpi_MainActivity_digitalWrite(JNIEnv* env, jobject obj, jint port, jint onoff) { digitalWrite(port, onoff); } int Java_com_hardkernel_wiringpi_MainActivity_wiringPiSetupSys(JNIEnv* env, jobject obj) { wiringPiSetupSys(); return 0; }
Declare GPIO ports.
private final int ledPorts[] = { 97, // GPIOX.BIT0(#97) 108, // GPIOX.BIT11(#108) 100, // GPIOX.BIT3(#100) 101, // GPIOX.BIT4(#101) 105, // GPIOX.BIT8(#105) 106, // GPIOX.BIT9(#106) 107, // GPIOX.BIT10(#107) 115, // GPIOX.BIT18(#115) 116, // GPIOX.BIT19(#116) 88, // GPIOY.BIT8(#88) 83, // GPIOY.BIT3(#83) 87, // GPIOY.BIT7(#87) 104, // GPIOX.BIT7(#104) 102, // GPIOX.BIT5(#102) 103, // GPIOX.BIT6(#103) 117, // GPIOX.BIT20(#117) 99, // GPIOX.BIT2(#99) 118, // GPIOX.BIT21(#118) 98, // GPIOX.BIT1(#98) };
Define JNI functions
public native int wiringPiSetupSys(); public native int analogRead(int port); public native void digitalWrite(int port, int onoff); static { System.loadLibrary("wpi_android"); }
Generate GPIO access nodes
Make SYSFS GPIO access nodes with the /sys/class/gpio/export
Change the GPIO pins to output mode via direction node.
Don't forget to change the permissions for those nodes.
boolean exportGPIO() { try { DataOutputStream os = new DataOutputStream(mProcess.getOutputStream()); for (int port: ledPorts) { os.writeBytes("echo " + port + " > /sys/class/gpio/export\n"); os.writeBytes("chmod 666 /sys/class/gpio/gpio" + port + "/direction\n"); os.writeBytes("echo out > /sys/class/gpio/gpio" + port + "/direction\n"); os.writeBytes("chmod 666 /sys/class/gpio/gpio" + port + "/value\n"); } os.flush(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); return false; } return true; }
Korean: wiringPi의 “/dev/mem”을 open 하여 mmap을 사용하는 방식으로 만들려고 하였으니 “/dev/mem”은 root가 아니면 접근을 제한하도록 되어 있어서 불가능합니다. jni의 library에는 root 권한을 줄 방법이 없습니다.
English: It was impossible to access the /dev/mem in the Android platform because only root can access it. There is no way to add a root permission to the JNI library.
Let's display and access the GPIO
This function runs every 100msec.
It reads the ADC value and update the GUI as well as LED level meter.
The CdS optical sensor is connected to the ADC.
public void update() { int i = 0; int adcValue = 0; int ledPos = 0; if ((adcValue = analogRead (PORT_ADC1)) > 0) { ledPos = (adcValue * ledPorts.length * 1000) / 1024; ledPos = (ledPorts.length - (ledPos / 1000)); mADC.setProgress(adcValue); } else ledPos = 0; for (i = 0; i < ledPorts.length; i++) { digitalWrite (ledPorts[i], 0); mLeds.get(i).setChecked(false); } for (i = 0; i < ledPos; i++) { digitalWrite (ledPorts[i], 1); mLeds.get(i).setChecked(true); } if (!mStop) handler.postDelayed(runnable, 100); }
Note that wiringPiSetupSys() should be called once to initialize the wiringPi library.