sgjava

Members
  • Content Count

    127
  • Joined

  • Last visited


Reputation Activity

  1. Like
    sgjava got a reaction from Tido in Learning from DietPi!   
    As a dev I vote to keep the dev packages in. Sure is nice to have the build tools (even git client) installed even if things like libtool and pkg-config are missing from the base. If you are going for a minimal install I understand stripping all this stuff out, but I'm not sure how important it is to have a 700K vs 1.6 G image in today's terms. As @tkaiser points out most people have moved on beyond 4G SD cards. I've been using 32G for years and the price/performance is good for what I need it for.
     
    I've have some home made security cameras that write/read/delete 100s of movies and images a day 24/7 for years without failure. I realize there may be more intensive usages scenarios (more write intensive), but at the current pricing levels I'll toss the SD out every few years if I have to. As with all things the lowest common denominator or race to the bottom isn't always the best strategy. Stability and standardization are more important to me then a little extra RAM, a little more SD life, etc. Not that these are not important, but the bigger picture I think is more important to focus on.
  2. Like
    sgjava got a reaction from guidol in C2 mainline networking issues   
    @Igor I fixed this by using armbian-config, clearing interfaces and using /etc/network/interfaces. Now I can reboot with a static address. With NanoPi Duo I had to remove netplan and use ifupdown for eth0, but the xradio wifi stuff seems to be missing from the kernel (modules, etc.). But in essence they exhibited the same issue with eth0.
  3. Like
    sgjava got a reaction from WarHawk_AVG in Build libgpiod the "New GPIO Interface for User Space"   
    https://github.com/sgjava/userspaceio is my github and libgopid is at https://github.com/brgl/libgpiod
  4. Like
    sgjava got a reaction from berbec in Luma.OLED on NanoPi Duo with SPI?   
    I figured it out. I had it wired to MI instead of MO! I'll do a write up once I have everything working the way I want.
  5. Like
    sgjava got a reaction from guidol in CPU governor stays at ondemand   
    OK, I did the following:
    cat /etc/default/cpufrequtils # WARNING: this file will be replaced on board support package (linux-root-...) upgrade ENABLE=true MIN_SPEED=240000 MAX_SPEED=1008000 GOVERNOR=conservative sudo rm /lib/systemd/system/ondemand.service sudo systemctl daemon-reload sudo reboot cpufreq-info -o minimum CPU frequency - maximum CPU frequency - governor CPU 0 240000 kHz ( 20 %) - 1008000 kHz ( 84 %) - conservative CPU 1 240000 kHz ( 20 %) - 1008000 kHz ( 84 %) - conservative CPU 2 240000 kHz ( 20 %) - 1008000 kHz ( 84 %) - conservative CPU 3 240000 kHz ( 20 %) - 1008000 kHz ( 84 %) - conservative
  6. Like
    sgjava got a reaction from frottier in NanoPi Duo + I2C SSD1306 + Luma.OLED = Cool   
    The Luma library allows you to display text, graphics, animation, etc. on multiple display types. Here I will describe the easiest one to configure which is Luma.OLED and the I2C version of the SSD1306. You can find these displays on EBay and Amazon for less than $10 US each (you can get them for less than $3 US if you order from China, but it might not show up). I've configured Luma on many SBCs and it's my go to library if I need a small display for projects.
     

     
    Requirements
    NanoPi Duo (I used V1.0 board with 512 MB RAM) flashed with Armbian image. This will work with or without the mini shield. Small nylon nuts, bolts and standoffs if you want to mount display I2C OLED display (check http://luma-oled.readthedocs.io/en/latest/hardware.html) 4 female to female jumper wires If you want to configure wifi the easy way just edit the following file on the SD sudo nano /media/username/43296f0d-fc9e-4cec-b3bf-f335fc72f371/etc/network/interfaces and add:
    allow-hotplug wlan0 iface wlan0 inet static address 192.168.1.69 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 192.168.1.1 wpa-ssid your_ssid wpa-psk your_password Comment out the eth0 stuff. You can do it the hard way with the debug serial interface though if you want When I ordered my Duos I forgot to order the USB dongle, so I would have been out of luck otherwise. Boot up and configure the Duo the way you like, power off and wire up the display as follows:
    VCC to either 5Vin or 3V3 GND to GND SCL to SCL SDA to SDA Power up Duo and configure I2C:
    sudo nano /boot/armbianEnv.txt and add i2c0 to overlays= sudo apt-get install i2c-tools sudo usermod -a -G i2c username (non-root user you created) sudo i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- If you see the 3c on i2c0 then you are in business. Let's install Luma.OLED:
    sudo apt-get install python-dev python-pip libfreetype6-dev libjpeg-dev sudo -H pip install --upgrade pip sudo apt-get purge python-pip sudo -H pip install --upgrade pip setuptools sudo -H pip install --upgrade luma.oled sudo -H pip uninstall RPi.GPIO (this will not work on Duo and is not needed for I2C) OK, let's create a simple demo program to make sure things are working nano i2chello.py:
    import time from luma.core.interface.serial import i2c from luma.core.render import canvas from luma.oled.device import ssd1306 serial = i2c(port=0, address=0x3C) device = ssd1306(serial) with canvas(device) as draw: draw.rectangle(device.bounding_box, outline="white") draw.text((3, 3), "Hello", fill="white") time.sleep(10) And you should see (screen shot from the Luma emulator):
     

     
    Now we can install the Luma examples:
    sudo apt-get install git-core libsdl-dev libportmidi-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev libsdl-image1.2-dev
    git clone https://github.com/rm-hull/luma.examples.git
    cd luma.examples
    sudo -H pip install -e .
    Let's run an example: sudo python examples/invaders.py -d ssd1306 --i2c-port 0 --i2c-address 0x3c
  7. Like
    sgjava got a reaction from chwe in ArmbianIO API proposal   
    @chwe I don't remember why I removed this. I just added it back. Try again and it should register with Python now.
  8. Like
    sgjava got a reaction from Tido in Learning from DietPi!   
    As a dev I vote to keep the dev packages in. Sure is nice to have the build tools (even git client) installed even if things like libtool and pkg-config are missing from the base. If you are going for a minimal install I understand stripping all this stuff out, but I'm not sure how important it is to have a 700K vs 1.6 G image in today's terms. As @tkaiser points out most people have moved on beyond 4G SD cards. I've been using 32G for years and the price/performance is good for what I need it for.
     
    I've have some home made security cameras that write/read/delete 100s of movies and images a day 24/7 for years without failure. I realize there may be more intensive usages scenarios (more write intensive), but at the current pricing levels I'll toss the SD out every few years if I have to. As with all things the lowest common denominator or race to the bottom isn't always the best strategy. Stability and standardization are more important to me then a little extra RAM, a little more SD life, etc. Not that these are not important, but the bigger picture I think is more important to focus on.
  9. Like
    sgjava got a reaction from Tido in Learning from DietPi!   
    As a dev I vote to keep the dev packages in. Sure is nice to have the build tools (even git client) installed even if things like libtool and pkg-config are missing from the base. If you are going for a minimal install I understand stripping all this stuff out, but I'm not sure how important it is to have a 700K vs 1.6 G image in today's terms. As @tkaiser points out most people have moved on beyond 4G SD cards. I've been using 32G for years and the price/performance is good for what I need it for.
     
    I've have some home made security cameras that write/read/delete 100s of movies and images a day 24/7 for years without failure. I realize there may be more intensive usages scenarios (more write intensive), but at the current pricing levels I'll toss the SD out every few years if I have to. As with all things the lowest common denominator or race to the bottom isn't always the best strategy. Stability and standardization are more important to me then a little extra RAM, a little more SD life, etc. Not that these are not important, but the bigger picture I think is more important to focus on.
  10. Like
    sgjava got a reaction from Tido in User Space IO is Python 3 and Java 8 bindings for user space GPIO, SPI, I2C, PWM 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, PWM 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. Demo program using hardware PWM to flash LED:
     
  11. Like
    sgjava got a reaction from Tido in User Space IO is Python 3 and Java 8 bindings for user space GPIO, SPI, I2C, PWM 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, PWM 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. Demo program using hardware PWM to flash LED:
     
  12. Like
    sgjava got a reaction from MitchD 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)  
  13. Like
    sgjava got a reaction from MitchD 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)  
  14. Like
    sgjava got a reaction from Tido in Build libgpiod the "New GPIO Interface for User Space"   
    This has been replaced by: User Space IO get more details on this thread.
     

     
    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.
  15. Like
    sgjava got a reaction from MitchD 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.
  16. Like
    sgjava got a reaction from Tido 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)); } } }  
  17. Like
    sgjava got a reaction from Tido in Build libgpiod the "New GPIO Interface for User Space"   
    This has been replaced by: User Space IO get more details on this thread.
     

     
    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.
  18. Like
    sgjava got a reaction from Tido in Build libgpiod the "New GPIO Interface for User Space"   
    This has been replaced by: User Space IO get more details on this thread.
     

     
    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.
  19. Like
    sgjava got a reaction from MitchD 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!
     
  20. Like
    sgjava got a reaction from MitchD 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!
     
  21. Like
    sgjava got a reaction from manuti 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

  22. Like
    sgjava got a reaction from Igor_K 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.
     
     
  23. Like
    sgjava got a reaction from Igor_K 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.
     

  24. Like
    sgjava got a reaction from Tido 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.
  25. Like
    sgjava got a reaction from gnasch 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()