sgjava

Members
  • Content count

    72
  • Joined

  • Last visited


Reputation Activity

  1. Tido liked a post in a topic by sgjava in User Space IO is Python 3 and Java 8 bindings for user space GPIO, SPI, I2C and Serial interfaces   
    https://github.com/sgjava/userspaceio
     
    After a lot of work and testing I have produced the User Space IO project! It provides Python 3 and Java 8 bindings for Linux user space GPIO, SPI, I2C and Serial interfaces. This allows cross SBC and cross language development using a common API. I took two best of breed C APIs for Linux user space libgpiod and c-periphery and produced CFFI bindings for Python and JNA bindings for Java. Since all the bindings closely match the C API it's easy to move from language to language. The side effect of using the Java library is that it should work with many different JVM based languages. How about creating your programs in Kotlin or Scala for instance?
     
    GPIO access uses the new gpiod interface and not the deprecated sysfs interface using libgpiod v1.1 (head from git repo). GPIO, SPI, I2C and serial interfaces expose all the low level functionality. I have added some helper methods for handling repetitive functions like building I2C messages, reading words from two registers, etc. You can of course go as low level as you need to. Please use Github to post any issues, pull requests, etc. I have tested Nano Pi Duo for 32 bit and NanoPi Neo +2 for 64 bit compatibility. I'll test more SBCs as I have time. Also, I have deleted https://github.com/sgjava/libgpiod-extra since User Space IO supersedes it.
     
    Based of some of the questions I had in the past please note the following:
    gpiod_ctxless_event_loop_multiple can handle GPIO interrupts Miscellaneous GPIO request flags GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN, GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE, GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW Non-root access using rc.local.
  2. Tido liked a post in a topic by sgjava in User Space IO is Python 3 and Java 8 bindings for user space GPIO, SPI, I2C and Serial interfaces   
    https://github.com/sgjava/userspaceio
     
    After a lot of work and testing I have produced the User Space IO project! It provides Python 3 and Java 8 bindings for Linux user space GPIO, SPI, I2C and Serial interfaces. This allows cross SBC and cross language development using a common API. I took two best of breed C APIs for Linux user space libgpiod and c-periphery and produced CFFI bindings for Python and JNA bindings for Java. Since all the bindings closely match the C API it's easy to move from language to language. The side effect of using the Java library is that it should work with many different JVM based languages. How about creating your programs in Kotlin or Scala for instance?
     
    GPIO access uses the new gpiod interface and not the deprecated sysfs interface using libgpiod v1.1 (head from git repo). GPIO, SPI, I2C and serial interfaces expose all the low level functionality. I have added some helper methods for handling repetitive functions like building I2C messages, reading words from two registers, etc. You can of course go as low level as you need to. Please use Github to post any issues, pull requests, etc. I have tested Nano Pi Duo for 32 bit and NanoPi Neo +2 for 64 bit compatibility. I'll test more SBCs as I have time. Also, I have deleted https://github.com/sgjava/libgpiod-extra since User Space IO supersedes it.
     
    Based of some of the questions I had in the past please note the following:
    gpiod_ctxless_event_loop_multiple can handle GPIO interrupts Miscellaneous GPIO request flags GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN, GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE, GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW Non-root access using rc.local.
  3. MitchD liked a post in a topic by sgjava in Using Python, CFFI and libgpiod for cross SBC GPIO access   
    On my journey to finding the best solution for cross SBC/cross language GPIO support I went through the same issues as Python by the C side author did it seems and landed on CFFI. This is faster than ctypes and seem more natural to program with. ctypesgen (the code generator) doen't really support Python 3, so I've hit a dead end there. It seems like JNA is still the best choice for Java bindings, so I'm sticking with that for now. In any event I threw together a button press app that uses CFFI and libgrpiod. I'll be updating my bindings project to support this soon.
     
    libgpiod version 1.1.devel
    Name: gpiochip1, label: 1f02c00.pinctrl, lines: 32
    Press button within 5 seconds
    Falling edge timestamp 02/10/2018 19:49:05
    """ Test blocking event using built in button ------------- Should work on any board with a button built in. Just change chip and line value as needed. """ import sys, time from argparse import * from cffi import FFI parser = ArgumentParser() parser.add_argument("--chip", help="GPIO chip number (default 1 '/dev/gpiochip1')", type=int, default=1) parser.add_argument("--line", help="GPIO line number (default 3 button on NanoPi Duo)", type=int, default=3) args = parser.parse_args() ffi = FFI() # Specify each C function, struct and constant you want a Python binding for # Copy-n-paste with minor edits ffi.cdef(""" enum { GPIOD_LINE_EVENT_RISING_EDGE, GPIOD_LINE_EVENT_FALLING_EDGE, }; struct timespec { long tv_sec; long tv_nsec; }; struct gpiod_line { unsigned int offset; int direction; int active_state; bool used; bool open_source; bool open_drain; int state; bool up_to_date; struct gpiod_chip *chip; int fd; char name[32]; char consumer[32]; }; struct gpiod_chip { struct gpiod_line **lines; unsigned int num_lines; int fd; char name[32]; char label[32]; }; struct gpiod_line_event { struct timespec ts; int event_type; }; const char *gpiod_version_string(void); struct gpiod_chip *gpiod_chip_open_by_number(unsigned int num); struct gpiod_line *gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset); int gpiod_line_request_falling_edge_events(struct gpiod_line *line, const char *consumer); int gpiod_line_event_wait(struct gpiod_line *line, const struct timespec *timeout); int gpiod_line_event_read(struct gpiod_line *line, struct gpiod_line_event *event); void gpiod_line_release(struct gpiod_line *line); void gpiod_chip_close(struct gpiod_chip *chip); """) lib = ffi.dlopen("libgpiod.so") print "libgpiod version %s" % ffi.string(lib.gpiod_version_string()) gpiod_chip = lib.gpiod_chip_open_by_number(args.chip) # Make sure GPIO chip opened if gpiod_chip != ffi.NULL: print("Name: %s, label: %s, lines: %d" % (ffi.string(gpiod_chip.name), ffi.string(gpiod_chip.label), gpiod_chip.num_lines)) gpiod_line = lib.gpiod_chip_get_line(gpiod_chip, args.line) # Verify we have line if gpiod_line != ffi.NULL: consumer = sys.argv[0][:-3] if lib.gpiod_line_request_falling_edge_events(gpiod_line, consumer) == 0: timespec = ffi.new("struct timespec*") timespec.tv_sec = 5 print("Press button within 5 seconds") rc = lib.gpiod_line_event_wait(gpiod_line, timespec) if rc == 0: print("Timed out") elif rc == 1: event = ffi.new("struct gpiod_line_event*") # Read event off queue lib.gpiod_line_event_read(gpiod_line, event) if event.event_type == lib.GPIOD_LINE_EVENT_RISING_EDGE: print("Rising edge timestamp %s" % time.strftime('%m/%d/%Y %H:%M:%S', time.localtime(event.ts.tv_sec))) else: print("Falling edge timestamp %s" % time.strftime('%m/%d/%Y %H:%M:%S', time.localtime(event.ts.tv_sec))) else: print("Unable request falling edge for line %d" % args.line) lib.gpiod_line_release(gpiod_line) else: print("Unable to get line %d" % args.line) lib.gpiod_chip_close(gpiod_chip) else: print("Unable to open chip %d" % args.chip)  
  4. MitchD liked a post in a topic by sgjava in Using Python, CFFI and libgpiod for cross SBC GPIO access   
    On my journey to finding the best solution for cross SBC/cross language GPIO support I went through the same issues as Python by the C side author did it seems and landed on CFFI. This is faster than ctypes and seem more natural to program with. ctypesgen (the code generator) doen't really support Python 3, so I've hit a dead end there. It seems like JNA is still the best choice for Java bindings, so I'm sticking with that for now. In any event I threw together a button press app that uses CFFI and libgrpiod. I'll be updating my bindings project to support this soon.
     
    libgpiod version 1.1.devel
    Name: gpiochip1, label: 1f02c00.pinctrl, lines: 32
    Press button within 5 seconds
    Falling edge timestamp 02/10/2018 19:49:05
    """ Test blocking event using built in button ------------- Should work on any board with a button built in. Just change chip and line value as needed. """ import sys, time from argparse import * from cffi import FFI parser = ArgumentParser() parser.add_argument("--chip", help="GPIO chip number (default 1 '/dev/gpiochip1')", type=int, default=1) parser.add_argument("--line", help="GPIO line number (default 3 button on NanoPi Duo)", type=int, default=3) args = parser.parse_args() ffi = FFI() # Specify each C function, struct and constant you want a Python binding for # Copy-n-paste with minor edits ffi.cdef(""" enum { GPIOD_LINE_EVENT_RISING_EDGE, GPIOD_LINE_EVENT_FALLING_EDGE, }; struct timespec { long tv_sec; long tv_nsec; }; struct gpiod_line { unsigned int offset; int direction; int active_state; bool used; bool open_source; bool open_drain; int state; bool up_to_date; struct gpiod_chip *chip; int fd; char name[32]; char consumer[32]; }; struct gpiod_chip { struct gpiod_line **lines; unsigned int num_lines; int fd; char name[32]; char label[32]; }; struct gpiod_line_event { struct timespec ts; int event_type; }; const char *gpiod_version_string(void); struct gpiod_chip *gpiod_chip_open_by_number(unsigned int num); struct gpiod_line *gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset); int gpiod_line_request_falling_edge_events(struct gpiod_line *line, const char *consumer); int gpiod_line_event_wait(struct gpiod_line *line, const struct timespec *timeout); int gpiod_line_event_read(struct gpiod_line *line, struct gpiod_line_event *event); void gpiod_line_release(struct gpiod_line *line); void gpiod_chip_close(struct gpiod_chip *chip); """) lib = ffi.dlopen("libgpiod.so") print "libgpiod version %s" % ffi.string(lib.gpiod_version_string()) gpiod_chip = lib.gpiod_chip_open_by_number(args.chip) # Make sure GPIO chip opened if gpiod_chip != ffi.NULL: print("Name: %s, label: %s, lines: %d" % (ffi.string(gpiod_chip.name), ffi.string(gpiod_chip.label), gpiod_chip.num_lines)) gpiod_line = lib.gpiod_chip_get_line(gpiod_chip, args.line) # Verify we have line if gpiod_line != ffi.NULL: consumer = sys.argv[0][:-3] if lib.gpiod_line_request_falling_edge_events(gpiod_line, consumer) == 0: timespec = ffi.new("struct timespec*") timespec.tv_sec = 5 print("Press button within 5 seconds") rc = lib.gpiod_line_event_wait(gpiod_line, timespec) if rc == 0: print("Timed out") elif rc == 1: event = ffi.new("struct gpiod_line_event*") # Read event off queue lib.gpiod_line_event_read(gpiod_line, event) if event.event_type == lib.GPIOD_LINE_EVENT_RISING_EDGE: print("Rising edge timestamp %s" % time.strftime('%m/%d/%Y %H:%M:%S', time.localtime(event.ts.tv_sec))) else: print("Falling edge timestamp %s" % time.strftime('%m/%d/%Y %H:%M:%S', time.localtime(event.ts.tv_sec))) else: print("Unable request falling edge for line %d" % args.line) lib.gpiod_line_release(gpiod_line) else: print("Unable to get line %d" % args.line) lib.gpiod_chip_close(gpiod_chip) else: print("Unable to open chip %d" % args.chip)  
  5. Tido liked a post in a topic by sgjava in Build libgpiod the "New GPIO Interface for User Space"   
    Well, it's time to say goodbye to sysfs and hello to libgpiod! @zador.blood.stained pointed me in the right direction, but you need to do one little hack I'll explain below involving compiler_types.h. I tested this on a NanoPi Duo, but it should work on any mainline Armbian release (and other distros as well) as long as the kernel is >= 4.8. Try ls /dev/gpiochip* and see if anything is listed. If so, then proceed.
     
    I'm continuing work on my Github site https://github.com/sgjava/libgpiod-extra, so please report any issues there. There is an Armbian install script that automates the steps below I generated the Python wrapper, but there's a lot of functions to test, so I'm not sure of the quality. I'm working on some simple Python tests.
    sudo armbian-config, Software, Headers sudo apt-get install libtool pkg-config git clone https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git cd libgpiod mkdir -p include/linux cp /usr/src/linux-headers-$(uname -r)/include/linux/compiler_types.h include/linux/. ./autogen.sh --enable-tools=yes --prefix=/usr/local CFLAGS="-I/usr/src/linux-headers-$(uname -r)/include/uapi -Iinclude" make sudo make install sudo ldconfig Let's try some commands:
     
    sudo gpiodetect
     
    gpiochip0 [1c20800.pinctrl] (224 lines)
    gpiochip1 [1f02c00.pinctrl] (32 lines)
     
    sudo gpioinfo | grep "\[used\]"
     
        line  10:      unnamed "nanopi:blue:status" output active-high [used]
        line 166:      unnamed         "cd"   input  active-high [used]
        line 202:      unnamed  "interrupt"   input  active-high [used]
        line 205:      unnamed      "reset"  output   active-low [used]
        line   6:      unnamed          "?"  output  active-high [used]
        line   7:      unnamed   "vcc-wifi"  output  active-high [used]
        line  10:      unnamed "nanopi:green:pwr" output active-high [used]
     
    Notice how it found the Duo's built in LEDs
     
    Now let's test the Duo's built in button (press and release 3 times):
     
    sudo gpiomon --num-events=3 --rising-edge gpiochip1 3
     
    event:  RISING EDGE offset: 3 timestamp: [1516774143.944174870]
    event:  RISING EDGE offset: 3 timestamp: [1516774145.123474395]
    event:  RISING EDGE offset: 3 timestamp: [1516774145.987531088]
     
    Wire up LED (the normal way) and use Duo's IOG11 then to turn on and off:
     
    sudo gpioset gpiochip0 203=0
    sudo gpioset gpiochip0 203=1
     
    Python code
    import time from libgpiod.libgpiod import * chip = gpiod_chip_open("/dev/gpiochip0") line = gpiod_chip_get_line(chip, 203) # The will set line for output and set initial value (LED on) if gpiod_line_request_output(line, "test", 0) == 0: time.sleep(3) # LED off gpiod_line_set_value(line, 1) gpiod_line_release(line) gpiod_chip_close(chip) More reading at https://www.cnx-software.com/2017/11/03/learn-more-about-linuxs-new-gpio-user-space-subsystem-libgpiod and https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/README. Maybe @Larry Bank will work on ArmbianIO II It looks like in the old Github site there was a milestone to create Python and C++ wrappers https://github.com/brgl/libgpiod/milestone/3. Once I learn more about libgpiod I may just generate them like I did for ArmbianIO.
  6. MitchD liked a post in a topic by sgjava in Build libgpiod the "New GPIO Interface for User Space"   
    OK, I whipped up a simple Python program using a thread to wait for an edge event while the main program is doing something else. https://github.com/sgjava/libgpiod-extra/blob/master/python/buttonthread.py
     
    You can pass --chip with GPIO chip number and --line for the line (pin) where your built in button is located. Really no need for IRQs since the events are queued and the thread is waiting on the edge to happen. You can use the thread to do a callback using OOP and an Observer pattern. This is more elegant than having C callback to Python, Java, etc.
  7. Tido liked a post in a topic by sgjava in libgpiod-extra "New GPIO Interface for User Space"   
    I have deleted this project please see https://github.com/sgjava/userspaceio as it covers I2C, SPI and serial in addition to the new GPIOD.
     
    I posted instructions over in the H2/H3 forum, but my build project for libgpiod should work on any Armbian mainline distribution, so I'm posting a link here to my Github site. The install is scripted and comes with the ability to generate Python and Java bindings. libgpiod replaces the deprecated sysfs since kernel 4.8. libgpiod-extra project aims to make cross platform/cross language GPIO development a reality. No more one off hacked up Wiring Pi or RPi.GPIO for each SBC.
     
    I need help testing across multiple SBC platforms. Just follow the instructions on https://github.com/sgjava/libgpiod-extra.
     
    Verified on:
    NanoPi Duo (H2+) NanoPi Neo+ 2 (H5) Python:
    import time from argparse import * from libgpiod.libgpiod import * parser = ArgumentParser() parser.add_argument("--chip", help="GPIO chip number (default 0 '/dev/gpiochip0')", type=int, default=0) parser.add_argument("--line", help="GPIO line number (default 203 IOG11 on NanoPi Duo)", type=int, default=203) args = parser.parse_args() consumer = sys.argv[0][:-3] chip = gpiod_chip_open_by_number(args.chip) # Verify the chip was opened if chip: line = gpiod_chip_get_line(chip, args.line) # Verify we have line if line: # This will set line for output and set initial value (LED on) if gpiod_line_request_output(line, consumer, 0) == 0: print "\nLED on" time.sleep(3) # LED off gpiod_line_set_value(line, 1) print "LED off" gpiod_line_release(line) else: print "Unable to set line %d to output" % args.line else: print "Unable to get line %d" % args.line gpiod_chip_close(chip) else: print "Unable to open chip %d" % args.chip Java:
    import java.util.concurrent.TimeUnit; import libgpiod.LibgpiodLibrary; import libgpiod.LibgpiodLibrary.gpiod_chip; import libgpiod.LibgpiodLibrary.gpiod_line; public class LedTest { public static void main(String args[]) throws InterruptedException { // Default GPIO chip (NanoPi Duo chip 0) int chipNum = 0; // Default line int lineNum = 203; if (args.length > 0) { chipNum = Integer.parseInt(args[0]); lineNum = Integer.parseInt(args[1]); } // Use to debug if JNA cannot find shared library System.setProperty("jna.debug_load", "false"); System.setProperty("jna.debug_load.jna", "false"); // Use class name for consumer final String consumer = LedTest.class.getSimpleName(); // Load library LibgpiodLibrary lib = LibgpiodLibrary.INSTANCE; final gpiod_chip chip = lib.gpiod_chip_open_by_number(chipNum); // Verify the chip was opened if (chip != null) { final gpiod_line line = lib.gpiod_chip_get_line(chip, lineNum); // Verify we have line if (line != null) { // This will set line for output and set initial value (LED on) if (lib.gpiod_line_request_output(line, consumer, 0) == 0) { System.out.println("\nLED on"); TimeUnit.SECONDS.sleep(3); // LED off lib.gpiod_line_set_value(line, 1); System.out.println("LED off"); lib.gpiod_line_release(line); } else { System.out.println(String.format("Unable to set line %d to output", lineNum)); } } else { System.out.println(String.format("Unable to get line %d", lineNum)); } lib.gpiod_chip_close(chip); } else { System.out.println(String.format("Unable to open chip %d", chipNum)); } } }  
  8. Tido liked a post in a topic by sgjava in Build libgpiod the "New GPIO Interface for User Space"   
    Well, it's time to say goodbye to sysfs and hello to libgpiod! @zador.blood.stained pointed me in the right direction, but you need to do one little hack I'll explain below involving compiler_types.h. I tested this on a NanoPi Duo, but it should work on any mainline Armbian release (and other distros as well) as long as the kernel is >= 4.8. Try ls /dev/gpiochip* and see if anything is listed. If so, then proceed.
     
    I'm continuing work on my Github site https://github.com/sgjava/libgpiod-extra, so please report any issues there. There is an Armbian install script that automates the steps below I generated the Python wrapper, but there's a lot of functions to test, so I'm not sure of the quality. I'm working on some simple Python tests.
    sudo armbian-config, Software, Headers sudo apt-get install libtool pkg-config git clone https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git cd libgpiod mkdir -p include/linux cp /usr/src/linux-headers-$(uname -r)/include/linux/compiler_types.h include/linux/. ./autogen.sh --enable-tools=yes --prefix=/usr/local CFLAGS="-I/usr/src/linux-headers-$(uname -r)/include/uapi -Iinclude" make sudo make install sudo ldconfig Let's try some commands:
     
    sudo gpiodetect
     
    gpiochip0 [1c20800.pinctrl] (224 lines)
    gpiochip1 [1f02c00.pinctrl] (32 lines)
     
    sudo gpioinfo | grep "\[used\]"
     
        line  10:      unnamed "nanopi:blue:status" output active-high [used]
        line 166:      unnamed         "cd"   input  active-high [used]
        line 202:      unnamed  "interrupt"   input  active-high [used]
        line 205:      unnamed      "reset"  output   active-low [used]
        line   6:      unnamed          "?"  output  active-high [used]
        line   7:      unnamed   "vcc-wifi"  output  active-high [used]
        line  10:      unnamed "nanopi:green:pwr" output active-high [used]
     
    Notice how it found the Duo's built in LEDs
     
    Now let's test the Duo's built in button (press and release 3 times):
     
    sudo gpiomon --num-events=3 --rising-edge gpiochip1 3
     
    event:  RISING EDGE offset: 3 timestamp: [1516774143.944174870]
    event:  RISING EDGE offset: 3 timestamp: [1516774145.123474395]
    event:  RISING EDGE offset: 3 timestamp: [1516774145.987531088]
     
    Wire up LED (the normal way) and use Duo's IOG11 then to turn on and off:
     
    sudo gpioset gpiochip0 203=0
    sudo gpioset gpiochip0 203=1
     
    Python code
    import time from libgpiod.libgpiod import * chip = gpiod_chip_open("/dev/gpiochip0") line = gpiod_chip_get_line(chip, 203) # The will set line for output and set initial value (LED on) if gpiod_line_request_output(line, "test", 0) == 0: time.sleep(3) # LED off gpiod_line_set_value(line, 1) gpiod_line_release(line) gpiod_chip_close(chip) More reading at https://www.cnx-software.com/2017/11/03/learn-more-about-linuxs-new-gpio-user-space-subsystem-libgpiod and https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/README. Maybe @Larry Bank will work on ArmbianIO II It looks like in the old Github site there was a milestone to create Python and C++ wrappers https://github.com/brgl/libgpiod/milestone/3. Once I learn more about libgpiod I may just generate them like I did for ArmbianIO.
  9. Tido liked a post in a topic by sgjava in Build libgpiod the "New GPIO Interface for User Space"   
    Well, it's time to say goodbye to sysfs and hello to libgpiod! @zador.blood.stained pointed me in the right direction, but you need to do one little hack I'll explain below involving compiler_types.h. I tested this on a NanoPi Duo, but it should work on any mainline Armbian release (and other distros as well) as long as the kernel is >= 4.8. Try ls /dev/gpiochip* and see if anything is listed. If so, then proceed.
     
    I'm continuing work on my Github site https://github.com/sgjava/libgpiod-extra, so please report any issues there. There is an Armbian install script that automates the steps below I generated the Python wrapper, but there's a lot of functions to test, so I'm not sure of the quality. I'm working on some simple Python tests.
    sudo armbian-config, Software, Headers sudo apt-get install libtool pkg-config git clone https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git cd libgpiod mkdir -p include/linux cp /usr/src/linux-headers-$(uname -r)/include/linux/compiler_types.h include/linux/. ./autogen.sh --enable-tools=yes --prefix=/usr/local CFLAGS="-I/usr/src/linux-headers-$(uname -r)/include/uapi -Iinclude" make sudo make install sudo ldconfig Let's try some commands:
     
    sudo gpiodetect
     
    gpiochip0 [1c20800.pinctrl] (224 lines)
    gpiochip1 [1f02c00.pinctrl] (32 lines)
     
    sudo gpioinfo | grep "\[used\]"
     
        line  10:      unnamed "nanopi:blue:status" output active-high [used]
        line 166:      unnamed         "cd"   input  active-high [used]
        line 202:      unnamed  "interrupt"   input  active-high [used]
        line 205:      unnamed      "reset"  output   active-low [used]
        line   6:      unnamed          "?"  output  active-high [used]
        line   7:      unnamed   "vcc-wifi"  output  active-high [used]
        line  10:      unnamed "nanopi:green:pwr" output active-high [used]
     
    Notice how it found the Duo's built in LEDs
     
    Now let's test the Duo's built in button (press and release 3 times):
     
    sudo gpiomon --num-events=3 --rising-edge gpiochip1 3
     
    event:  RISING EDGE offset: 3 timestamp: [1516774143.944174870]
    event:  RISING EDGE offset: 3 timestamp: [1516774145.123474395]
    event:  RISING EDGE offset: 3 timestamp: [1516774145.987531088]
     
    Wire up LED (the normal way) and use Duo's IOG11 then to turn on and off:
     
    sudo gpioset gpiochip0 203=0
    sudo gpioset gpiochip0 203=1
     
    Python code
    import time from libgpiod.libgpiod import * chip = gpiod_chip_open("/dev/gpiochip0") line = gpiod_chip_get_line(chip, 203) # The will set line for output and set initial value (LED on) if gpiod_line_request_output(line, "test", 0) == 0: time.sleep(3) # LED off gpiod_line_set_value(line, 1) gpiod_line_release(line) gpiod_chip_close(chip) More reading at https://www.cnx-software.com/2017/11/03/learn-more-about-linuxs-new-gpio-user-space-subsystem-libgpiod and https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/README. Maybe @Larry Bank will work on ArmbianIO II It looks like in the old Github site there was a milestone to create Python and C++ wrappers https://github.com/brgl/libgpiod/milestone/3. Once I learn more about libgpiod I may just generate them like I did for ArmbianIO.
  10. MitchD liked a post in a topic by sgjava in How to compile libgpiod?   
    OK, I got it to build finally! I'm working on a how-to and will post that once I verify the steps and that it actually works, thanks!
     
  11. MitchD liked a post in a topic by sgjava in How to compile libgpiod?   
    OK, I got it to build finally! I'm working on a how-to and will post that once I verify the steps and that it actually works, thanks!
     
  12. manuti liked a post in a topic by sgjava in NanoPi Duo OTG works with FriendlyElec image, but not Armbian (SOLVED)   
    OK, solved this by using FriendlyElec's dtb! Armbian folks may want to use this DTB instead of what's in the current distro. lsusb show thumb drive:
     
    Bus 001 Device 002: ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive

  13. Igor_K liked a post in a topic by sgjava in What would be a good board with 2 Gb RAM for a bitcoin node?   
    @Igor_K See the post below for the parts list. The HC1 wasn't available when I bought them. I have a 480G SSD connected to one of the XU4s and use NFS for backups and security camera videos. I need to be able to swap things in and out based on needs, so the rack was a better choice for me. I can have 9 decent sized SBCs in that tower.
     
     
  14. Igor_K liked a post in a topic by sgjava in What would be a good board with 2 Gb RAM for a bitcoin node?   
    I concur with the others about the XU4. I have 3 of them in my home made SBC server rack which uses active cooling. The nice thing is the XU4 has a built in fan and they are rock solid (been running them over a year 24/7). The price is right too. If you plan on maxing out the CPU you will need more than the built in cooling.
     
    The ROCK 64 looks promising price wise and the ability to have up to 4G. This will be my next server.
     

  15. Tido liked a post in a topic by sgjava in ArmbianIO API proposal   
    Holy smokes, I didn't think the RPi.GPIO clone would be such a pain, but the bonus is I fixed some bugs in the C code and changed how callbacks work a bit. AIOAddGPIOCallback no longer sets pin direction, so you must call AIOAddGPIO and set the pin direction to GPIO_IN. I also added AIORemoveGPIOCallback which sets edge to "none" and causes the pthread to exit. This operated more like RPi.GPIO by leaving the pin set the way it was before the callback and only changes edge. I also fixed AIORemoveGPIO yesterday as it was using the literal pin number and not the mapped pin, so the pin was left in it's previous state (i.e. /sys/class/gpio/gpio123 was still there).
     
    I was able to implement most of the RPi.GPIO event methods:
    add_event_detect remove_event_detect add_event_callback I still need to work on:
    wait_for_edge event_detected Once this is done I should be able to test Luma.OLED on a few different model SBCs without code changes if I use the same pins. This will be the ultimate test. No more hacked up RPi.GPIO for each SBC! I had to have a custom RPi.GPIO for Odroid C1, Pine A64, the various Nano Pis, etc.
  16. gnasch liked a post in a topic by sgjava in ArmbianIO API proposal   
    OK, I started on the RPi.GPIO wrapper https://github.com/bitbank2/ArmbianIO/blob/master/python/RPi/GPIO.py which basically supports reading and writing to the pins. None of the event stuff is coded yet, but you can see where I'm going. No pin mappings yet. Just keeping it the way ArmbianIO does it for now. The Led test works
    import time import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) # Pin 12 set to output GPIO.setup(12,GPIO.OUT) # LED on GPIO.output(12,GPIO.LOW) time.sleep(3) # LED off GPIO.output(12,GPIO.HIGH) GPIO.cleanup()  
  17. chwe liked a post in a topic by sgjava in ArmbianIO API proposal   
    @chwe I've looked at the Node-Red demo and it looks interesting to make work flows, but if you look at https://github.com/monteslu/node-red-contrib-gpio you'll see it's pretty involved. The nice thing though is it would support many more SBCs by ArmbianIO's very nature. @Larry Bank and I were discussing adding PWM yesterday, board name detection (see @tkaiser's comments above), etc., so there's still some core functionality to add at the C level and then to the wrappers. Of course being an Open Source project any one can contribute
  18. sgjava liked a post in a topic by tkaiser in ArmbianIO API proposal   
     
    See 8 posts above or https://tech.scargill.net/banana-pi-m2/#comment-27947
     
    Edit: When asking @jernej back then whether he's fine with his code being used in other projects IIRC he had no objections.
  19. Larry Bank liked a post in a topic by sgjava in ArmbianIO API proposal   
    I've changed the way the Python wrapper is generated using ctypesgen instead of Swig. This makes the shared library much smaller because it doesn't have any Swig junk linked in. It's basically just a shared version of what @Larry Bank's make builds with the static library (maybe we should add an #IFDEF for that, so I don't have to compile it). There no need to load the library in your code since ctypesgen handles that in the armbianio.py it creates. Your Python code is more elegant and there's no mixing Swig shit code with ctypes or weirdo interface files just to deal with pointers. I'm going to generate the JNA code as well for Java just so I don't have to maintain the interface file if the underlying C API changes. Not sure about JavaScript yet, but if I can find a generator that deals with pointers well then maybe I'll try that next. Here's the obligatory Button program using a callback:
    import time from armbianio.armbianio import * # Simple callback displays pin and value def buttonCallback(iPin, iEdge): print "Button state: pin = %d, value = %d" % (iPin, iEdge) # Detect SBC rc = AIOInit() if rc == 1: # Function returns char array print "Running on a %s" % AIOGetBoardName(); if AIOHasButton(): button = 0 # Button callback AIOAddGPIOCallback(button, EDGE_BOTH, AIOCALLBACK(buttonCallback)); print "Press/release button a few times\n" time.sleep(10) # Remove callback AIORemoveGPIO(0) else: print "%s does not have a button" % AIOGetBoardName(); AIOShutdown() else: print "AIOInit error"  
  20. lanefu liked a post in a topic by sgjava in ArmbianIO API proposal   
    I've created Python bindings with Swig using a script that should install all dependencies and create an armbianio module and install locally with pip, so it's globally accessible in Python. I created a PR for Larry, but you can grab it at https://github.com/sgjava/ArmbianIO until the merge happens. I included a simple LED blink program that uses pin 12 (ArmbianIO mapping) for the NanoPi Duo. It would be nice to test other SBCs as well.