Jump to content

sgjava

Members
  • Posts

    411
  • Joined

  • Last visited

Everything posted by sgjava

  1. OK, finally watched the video and it all makes sense now (I emailed the author to confirm the use of the consumer arg). The Python wrapper I generate is solid now. I needed to add a couple ctypes Structures to an include file and it works on 32 bit and 64 bit platforms. I've given up on sysfs for good! ledtest.py https://github.com/sgjava/libgpiod-extra/blob/master/python/ledtest.py now accepts command line arguments, so it's easy to run on any SBC. I shows you how to safely open the GPIO chip and get the line without suffering a Segmentation Fault! Once I'm done't with the basic demos I'll work on using threads in Python to handle non-blocking callbacks. I kind of like the idea of handling threads in the bindings instead of using C pthreads. Then you have more control.
  2. 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)); } } }
  3. I noticed when updating that linux-headers-next-sunxi package was being updated and this seem like a better way (using apt-get). Could I use something like linux-headers-$BRANCH-$LINUXFAMILY?
  4. Is there a way to script downloading the Linux headers like armbian-config Headers?
  5. 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.
  6. 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!
  7. OK, I used armbian-config to get the headers since you cannot get the headers with apt-get install linux-headers-$(uname -r) or apt-get install linux-headers-generic. The later tries to pull the 4.4 headers and libgpiod requires >= 4.8. So it looks like I'm doing it right, but any combination of includes using /usr/src/linux-headers-4.14.14-sunxi has not worked.
  8. I've tried to compile libgpiod (my assumption is this is a user space lib) and it depends on gpio.h which is used by the kernel. According to https://github.com/brgl/libgpiod/issues/22 gpio.h should be installed with linux-libc-dev which is already installed and gpio.h is missing. I installed the kernel headers and tried (it ends up with typedef conflicts): ./autogen.sh --enable-tools=yes --prefix=/usr/local CFLAGS="-I/usr/src/linux-headers-4.14.14-sunxi/arch/arm/include -I/usr/src/linux-headers-4.14.14-sunxi/include" configure: error: linux/gpio.h header not found (needed to build the library) I've attached the config.log. Maybe I'm totally missing the boat, but there's not a lot of info out there build this for ARM and there are no deb packages for ARM I can find. config.log
  9. 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
  10. I just got 4 NanoPi Duos v1.1 and the OTG port functions (unlike v1.0)! This is with the FriendlyElec image. I was wondering should I compare the FriendlyElec's sun8i-h2-plus-nanopi-duo.dtb to the one on Armbian? I already tried messing with Armbian's sun8i-h2-plus-nanopi-duo.dtb by changing usb@01c19000 status = "okay" and adding dr_mode = "host". I'm not sure I can just drop in the dtb? Any way, I'll see what I can figure out. I'm excited the OTG port works now for more than just power since that saves you from buying the Mini Shield if you have a simple project that just needs a USB drive or camera.
  11. @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.
  12. @Crypta I have ordered several times from http://www.friendlyarm.com/index.php?route=product/product&product_id=197. I've dealt with the sales person directly to get a custom order (some items like the the mini shield have to be ordered with the Duo on their site and cannot be ordered separately). The sales guy always gives me different prices (higher) for shipping, etc. so I stick with the web site if possible. They have a US distributor, but they only allow 2 Duos at a time. You can find them on ebay for $20 with free shipping. I have received every order so far from FriendlyElec, but I use Amex with my paypal, so if I do get ripped off they will strip it off the vendors account and get my money back. I've ordered M1s, M1+, and batches of Duos.
  13. I really like the NanoPi Duo. I just ordered 4 more, but these are version 1.1 boards (512MB), so the OTG is supposed to be fully functional, so you can power off the rail and use the OTG port for cameras, etc. They came in at $15.74 each (AliExpress is $36 each!) which includes the DHL shipping (no slow China Post, epacket, etc.) from FriendlyElec. It only takes about a week to reach the US. One of the great things is you can buy the $10 mini shield if you need a lot of USB ports, Ethernet port, etc. I use them both ways. Also they drop right into a breadboard, so prototyping is easy without ribbon cables, etc. I just checked and the Orange Pi Zero 512MB comes in around $12.08 if you buy 4 (or $13.34 for 1) with crappy epacket shipping. The big difference I see is the GPIO/I2C/SPI, etc. ports require you to solder on a header and the form factor. I'll pay a little extra if I don't have to mess around a lot to prototype and deploy projects. If you really want to go low price/low power consumption and can code in C the look at https://www.pine64.org/?page_id=917. I just ordered 10 of these for creating low power projects (think sensor arrays). This is definitely more involved though
  14. 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. 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. 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 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. OK, I tried https://github.com/nativelibs4java/JNAerator to generate the JNA wrapper, but it generates a bunch of BirdJ and other dependencies that are really not required for a simple and clean Java API. The Java interface file I created was easy enough to hand edit (in fact I just copied the C header and changed a few types and dealt with the function pointer). The Swig requirement has been totally removed from the project! I just need to port the rest of the demo programs over to Java.
  19. @StuxNet I've committed the pin mappings for NanoPi Duo https://github.com/rm-hull/OPi.GPIO/tree/master/nanopi to OPi.GPIO only because the Luma libraries depend on RPi.GPIO API and there wasn't a good alternative (unless you want to use the one off hacked up FriendlyElec junk). Larry's library already spans many more SBCs and has I2C and SPI access as part of the API. OPi.GPIO is only for GPIO and only supports Python (by design). I believe Luma uses Python's spidev for SPI and I'm not sure about I2C. ArmbianIO supports C, Python and Java using pretty much the same method/function signatures. I plan on creating a RP.iGPIO wrapper that maps Pi pins to specific SBCs, so I can use Luma without having to hack in a new GPIO replacement for each SBC. I might be able to leverage @Larry Bank's pin mappings in C and just create the BOARD/BCM dicts. The only reason for this is so many projects rely on crappy RPi.GPIO instead of some type of abstraction
  20. 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"
  21. It shouldn't be a big deal to write a RPi.GPIO API using ctypes against ArmbianIO (you can see the demo apps I already built using Python and ArmbianIO). Then libraries like Luma.OLED will work without modification across all platforms supported by ArmbianIO. I suspect WiringPi https://github.com/WiringPi/WiringPi-Python would be better suited using ctypes as well after looking at the interface file. I fell for the Swig trap by the allure of simple code generation, but it generates unusable shit turds when it hits pointers in C (C++ seems to be handled better). I ended up using JNA for Java which is like ctypes in that respect.
  22. I have the Java wrapper working pretty good. Same issues with Swig as generating the Python wrappers. Pointer (function, char array, etc.) parameters generate worthless code without a lot of manual man handling. Like using ctypes with Python I used JNA for Java, thus no generated code is needed. See https://github.com/bitbank2/ArmbianIO/blob/master/java/Button.java for an example. I need to extract the full interface into it's own file, so there no need to embed it in each program. I'll wrap that up when I port all the Python demos over to Java. I have I2C and SPI examples for Python, so pretty much all the features of ArmbianIO have been tested. The nice thing is the API is the same for all languages, so unlike RPi.GPIO you can pick your language. Once I've built everything out I'll use Valgrind to verify there are no memory leaks high level code to C. You can see where I fixed most of the OpenCV Java memory leaks https://github.com/sgjava/opencvmem
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines