uraimo / swiftygpio Goto Github PK
View Code? Open in Web Editor NEWA Swift library for hardware projects on Linux/ARM boards with support for GPIOs/SPI/I2C/PWM/UART/1Wire.
License: MIT License
A Swift library for hardware projects on Linux/ARM boards with support for GPIOs/SPI/I2C/PWM/UART/1Wire.
License: MIT License
Since some tests have been done on RPi 2, i'm moving that among the tested boards.
This issue is related to the ARM6 Raspberry boards, AFAIK there are no ready to install packages for those yet (also, those boards don't run ubuntu and Raspbian doesn't have clang-3.6, required to build Swift, so that needs to be built too). I'm trying to build everything on an old Rev1, i know others are already working on it with more chances to see the end of it.
A simple GPIO read/write test on one of these board could be enough to understand if there are major issues, other than that it could be nice, but not essential, to verify if all the defaults GPIOs are correct.
To sum up the GPIO presets for those boards:
The BananaPi boards use an Allwinner A20 and the way gpio registers are arranged in memory is different from what we have on the RaspberryPi.
An example of how to interact with gpios on BananaPis can be found here.
It would be nice to be able to reuse the same code for the CHIP, based on a similar SoC.
I believe this is the actual link:
http://swift-arm.ddns.net/job/Swift-3.0-Pi3-ARM-Incremental/lastSuccessfulBuild/artifact/
There should be some way to obtain a set of GPIO objects already configured for one of the supported boards.
Once the basic functionalities are stable, it could make sense to make this transition, for performance reasons.
I would like to request Swift 3.0 support. If there is no progress made, then I will try porting it myself, but I would much rather it be a collaborative effort. Would you be interested?
Maybe this:
public class GPIO {
var name : String = ""
var id : Int = 0
...
}
should be:
public class GPIO {
public private(set) var name : String = ""
public private(set) var id : Int = 0
...
}
I think they might be useful for building stuff on top.
I'm planning to refactor a few things before releasing version 1.0.0, for example some public method prototype will change to conform to the Swift's API Design Guidelines.
RaspberryPi3 B
Ubuntu Mate 16.04
Pre-built 4.1.3
Communicating with the ADC1115 analog to digital convertor.
I'm basing my implementation on the approach described here for Arduino.
Communication with the device is fine. i2cdetect -y 1
reports the board as present at address 0x48.
Here is my code:
let myData: [UInt8] = [1, 132, 131]
// PROBLEM IS HERE...
i2c.writeData(72, command: 0, values: myData)
usleep(3000)
while true == true {
i2c.writeByte(72, value: 0)
let byte1 = i2c.readByte(72)
let byte2 = i2c.readByte(72)
//let resData = i2c.readWord(72, command: 0)
print(byte1, byte2)
//print(resData)
usleep(5000)
}
Please list any error message you've receveived during execution.
When I attempt to do a writeData
write, I get this error message:
true
I2C write failed: Input/output error
Aborted
(True refers to the result of isReachable(72)
.)
Does it work on a Raspberry Pi 2?
This task mainly involves general testing and verification of the GPIO ids.
I attempted to build the BBB example, but there was an error with SPM. This is using build 59 from Joe Bell's Jenkins ARM build.
debian@beaglebone:~/Development/delete/SwiftyGPIO/Examples/Basic-bbb$ swift build
Compile Swift Module 'BasicGPIO' (1 sources)
/home/debian/Development/delete/SwiftyGPIO/Examples/Basic-bbb/Sources/main.swift:3:13: error: use of unresolved identifier 'SwiftyGPIO'
let gpios = SwiftyGPIO.getGPIOsForBoard(.RaspberryPiB2Zero)
^~~~~~~~~~
/home/debian/Development/delete/SwiftyGPIO/Examples/Basic-bbb/Sources/main.swift:4:10: error: use of unresolved identifier 'GPIO'
var gp = GPIO(name: "GPIO_45",id: 45)
^~~~
<unknown>:0: error: build had 1 command failures
error: exit(1): /home/debian/swift/releases/external/20160609-59/usr/bin/swift-build-tool -f /home/debian/Development/delete/SwiftyGPIO/Examples/Basic-bbb/.build/debug.yaml
Extension of the PWM feature to output digital signals with custom bit patterns representing 1s and 0s. Required for WS281x led strips driver.
In progress.
When trying to compile via Xcode 8.3.1 I am greeted with 15 errors. 13 of them are issues with assigning UInt32 types to UInt types, which I can resolve with just casting to UInt and two are unresolved identifier issues. I tried to fix myself but wasn't able to figure out the unresolved identifier issues: O_SYNC line 159 and CRTSCTS line 186 in file UART.swift. This is the same file that is having issues with doing something like this:
var x: UInt
let y: UInt32 = 3
x = y //Cannot assign value of type 'UInt32' to type 'UInt'
Other than these, it compiles just fine (I commented out the unresolved identifier issues and it compiles)
Having multiple errors when trying to build on macOS, all are within UART.swift file.
When I remove it from target, it builds without any issues.
From here:
The names of these device files can vary wildly. I would suggest searching a list of possible serial device names.
Examples include:
ttyS
ttyAMA
ttymxc
Way better than the current static configuration.
This could be implemented for every board (the search order could not be necessarily the same for every board) or just for unknown boards.
PWM outputs have a few uses (for hobby projects mainly driving motors and playing sounds) and a convenient sysfs interface. Implementation should be really straightforward.
This issue collects interesting libraries that could be built from SwiftyGPIO and that could be useful for other people building embedded projects with Swift using specific sensors/devices, feel free to chime in if you want to build one of these or if you have other (better) ideas/requests:
~~ 2018-> ~~
Any
Any
Any
Currently, the SwiftGPIO interfaces are tight up to concrete classes which heavily depend on Raspberry Pi's environment, OS and libraries. The downside is the code which has integrated SwiftyGPIO gets crash when run on MAC.
In order to take advanges of XCode, and enable debugging capable on MAC/XCode, I'd like to add mocks feature into SwiftyGPIO.
The overall feature will conduct these things:
Check out this branch for more detail: https://github.com/haikieu/SwiftyGPIO/tree/Add-Mocks
Raspberry Pi Zero / 3B
Raspian Stretch
Swift 3.1.1
I've been using pigpio in Python to use the hardware PWM outputs to drive LEDs while also dimming them. That worked fine, and I got a nice smooth ramp from 0% to 100% duty cycle that looked good.
Because of perf issues with Python on the Zero with the rapid changes to the duty cycle needed, I gave SwiftyGPIO a shot, and it also works very well, but the behavior of killing and reconfiguring the clock every time the PWM frequency or dutycycle is changed causes unwanted flashing and flickering.
There also appears to be an issue where turning on one PWM channel turns the other off, possibly because of this clock change?
I've forked the repo so I can put together a revised implementation, which would be loosely based on how pigpio handles the clock, which makes this smooth updating of the duty cycle possible. The key difference is that pigpio configures the clock once with a fixed divisor of 2 for the PLLD clock. By using M/S mode, it can create any frequency up to (PLLD / 2) Hz without having to reinitialize the clock. My plan is to implement a similar behavior in the RaspberryPWM class where it can initialize the clock once for both PWM channels.
Unfortunately, if I wanted to avoid too many changes, it would probably require a lazy Singleton so that the different RaspberryPWM instances can store and share the clock state data independent of a specific pin/channel.
The PWM pattern code would be left alone if possible.
It would be nice if SwiftyGPIO.RaspberryGPIO
would have a description
(aka conform to the CustomStringConvertible
protocol) containing all its properties. When you currently do a
button.onChange { gpio in
print("Value changed:", gpio)
}
You just get a:
Value changed: SwiftyGPIO.RaspberryGPIO
Hi, I have this error when I run the executable file on my R Pi 2.
Can't open /dev/mem
Aborted (core dumped)
The program it is very simple:
import Glibc
let gpios = SwiftyGPIO.GPIOs(for:.RaspberryPi2)
var gp = gpios[.P18]
gp?.direction = .OUT
gp?.value = 1
On the BCM 18 there is the wire that I want to use to pilot a led.
What I am missing?
Thanks
It needs to be tested and it would be nice to have a list of the GPIO ids.
Raspberry Pi 3B
Debian Buster 64-bit Preview
Swift 4.1.1
At least some issues with PWM assuming UInt == UInt32 while memory mapping GPIOs. This causes bad memory mapping behavior as the stride is different. In general, any of the base pointers using "UnsafeMutablePointer<UInt>" are probably wrong for Raspberry Pi.
I've got the PWM module through a "best-effort" conversion to 64-bit, and I'm able to use basic PWM. Since the RPi GPIOs are the only ones doing direct memory access like this, I should be able to fix up the GPIOs as well.
Minor one line change from ErrorProtocol to Error when compiling from latest Swift snapshot in POSIXError.swift
Specify which kind of ARM board you are using, e.g. RaspberryPi3, RaspberryPi1, BBB, etc...
Raspberry Pi 3 B+
Which OS are you using? e.g. Ubuntu Mate 16.04, Raspbian, Armbian, etc...
Hypriot 1.9.0
Which Swift version are you using? Did you compile it yourself or did you use prebuilt binaries?
4.1.2 using pre-built binaries
Describe your hardware setup (e.g. board connected to i2c sensor) and describe briefly the issue, specifying the steps needed to reproduce it, if necessary.
I have an LED on the breadboard with a resistor. The ground is connected to P6, the positive is connected to P4 on a Raspberry Pi 3 B+
I've got a project created that compiles. The code in main.swift is as follows:
import Glibc
import SwiftyGPIO
var gp4 = GPIO(name: "P4", id: 4)
gp4.direction = .OUT
repeat {
gp4.value = (gp4.value == 0) ? 1 : 0
usleep(150 * 1000)
} while(true)
I also tried declaring gp4
like this:
let gpios = SwiftyGPIO.GPIOs(for: .RaspberryPi3)
var gp4 = gpios[.P4]!
Please list any error message you've receveived during execution.
When gp4
is declared like this:
var gp4 = GPIO(name: "P4", id: 4)
gp4.direction = .OUT
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /home/swift/GPIOTest/.build/checkouts/SwiftyGPIO.git-1189449763/Sources/SwiftyGPIO.swift, line 104
Current stack trace:
Illegal instruction (core dumped)
When gp4
is declared like this:
let gpios = SwiftyGPIO.GPIOs(for: .RaspberryPi3)
var gp4 = gpios[.P4]!
Fatal error: Can't open /dev/mem , use sudo!: file /home/swift/GPIOTest/.build/checkouts/SwiftyGPIO.git-1189449763/Sources/SwiftyGPIO.swift, line 353
Current stack trace:
Illegal instruction (core dumped)
Another thing that's missing to reach feature parity with Android Things.
It could be tested with a NEO-6 series low cost GPS board or just a serial/usb adapter and minicom from a pc.
It would be nice to be able to do something like this:
var gpio = GPIO(name: "P0",id: 0)
gpio.onRising{
print("Value changed! It's now HIGH!")
}
gpio.onFalling{
print("Value changed! It's now LOW!")
}
gpio.onChanged{
print("Value changed!")
}
Currently you quickly run into a
Fatal error: Can't open /dev/mem , use sudo!: file ../.build/checkouts/SwiftyGPIO.git-1203819502/Sources/SwiftyGPIO.swift, line 353
when a tool is started w/o sudo.
Since that is so common, I would rather provide a proper API for that (probably something throwing an Error). The (user)-dev should handle that case, and provide a clean exit.
Does it work on a BeagleBone Black?
This task involves general testing and verification of the GPIO ids.
I get an error while using the i2c.writeByte(HTU21DF_ADDRESS, value: HTU21DF_READHUM) command.
I using the current master version of the Library. Is this a known issue?
Swift version 3.0.2 (swift-3.0.2-RELEASE)
Target: armv6--linux-gnueabihf
raspberry pi 2 an raspbian jessi
RaspberryPi3
Ubuntu Mate 16.04
4.1.3, pre-built
Attempting to drive a motor controller (https://www.pololu.com/product/3754) using PWM. I have one channel each for the right and left sides of my robot vehicle. When I startPWM
to one channel, the other channel stops. This occurs even if the period and duty are the same with each startPWM
call. Any way to overcome this behavior?
Does it work on a 40 pin Raspberry Pi board like the A+,B+, Pi 2 or Pi zero?
This task involves general testing and verification of the GPIO ids.
Is there something special that needs to happen in order to use SwiftyGPIO with the new Raspberry Pi Zero W? I have swift 3.0.2 installed and working (I was able to build and run some existing apps that do not use SwiftyGPIO). And, I am going by the RPi Zero GPIO Header chart and have an LED hooked up to GPIO #3. Also tested that it works with the command line gpio program, and was able to get the LED to power on/off by setting GPIO pin 3 to high/low.
I'm using the Examples/Basic/raspi1PlusAndZero/Sources/main.swift file (had to change the .RaspberryPiRevPlusZero to .RaspberryPiPlusZero)
But when I build and run the program (it does run since I put some debug print statements in to confirm) I don't see a flashing LED and I think I should.
A software implementation of a SPI using two GPIOs could be useful.
The GPIO ids are different now, from the documentation:
Pins XIO-P0 to P7 linearly map to gpio408 to gpio415 on kernel 4.3 and gpio1016 to gpio1023 on kernel 4.4.11. For kernel 4.4.13-ntc-mlc the range is gpio1013 to gpio1019.
The library should be always in sync with the latest OS release.
Missing for now, it should be straightforward to implement.
RaspberryPi3
Linux version 4.9.24-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #993 SMP Wed Apr 26 18:01:23 BST 2017
Swift version 3.0.2-dev (LLVM 976c51bb80, Clang 18b736028f, Swift c907b76555)
Target: armv7--linux-gnueabihf
Myself compile from https://github.com/swift-arm/build-swift
Have connected USB-UART cp1202 to USB. TX connected to RX (loop back)
project source SwiftyGPIO/Examples/UART/raspi2/
MESSAGE:
Send: fatal error: Index out of range: file /home/pi/buildSwiftOnARM/build-swift/scripts/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 364
At the moment, SPIs can only be used as output. While it does not make much sense to build a software counterpart of the big banging SPI, extending the sysfs SPI to be able to read and not only write it shouldn't be too complex.
Can be tested with some low cost devices like the MCP3002 or a LIS3DH module.
From strace:
open("/sys/class/gpio//export", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
futex(0x76f62828, FUTEX_WAKE_PRIVATE, 2147483647) = 0
fstat64(3, {st_mode=S_IFREG|0770, st_size=4096, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x74d8a000
write(3, "2", 1) = -1 EBUSY (Device or resource busy)
close(3) = 0
munmap(0x74d8a000, 4096) = 0
It needs to be tested and it would be nice to have a list of the GPIO ids.
Some sensors need to keep a hold of the bus between related read/write operations and require that a "repeated start" is performed to lock it. The RaspberryPi does not perform this operation by default but a workaround exist to enable this behaviour. See below.
https://www.i2c-bus.org/repeated-start-condition/
http://raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm
https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=15840&start=25
The current documentation is mostly contained in the readme. Converting it in something more accessible, for example a structured gitbook document, could improve readability.
Furthermore, after reading AndroidThings's documentation, I've realized that providing a basic introduction to electronics fundamentals and explaining clearly what is supported on each board could be a good idea.
will work on that
Since last year the official Debian distro seems to have been improved a lot, with SPI, I2C and PWM (and 1wire?) via sysfs now enabled by default.
I've also discovered that the 8 gpios are managed by an external IC connected to the cpu via i2c, so we'll never have memory mapped gpios for this board.
The C.H.I.P. also seems to have an ADC (12 bits) pin that's normally connected to the battery charging circuitry but that's still accessible via the VCC1v8 pin. That's useful for a lot of things, and even if the RaspberryPi doesn't have analog ports other board do (e.g. BBB), so it could make sense to add this to the set of available interfaces.
RPi 3 Model B
Ubuntu Mate 16.04
Swift 4.1.3, canned.
Attempting to address four SPI slaves using a LS7366R break-out board. I'm unclear from the SwiftyGPIO SPI documentation how to do slave select. Do I separately set the CS or GPIO pins low/high in order to select a slave, i.e. slave select is separate from the SPI library implementation itself?
Thanks in advance!
RPi 3B
Ubuntu Mate 16.04
Pre-built 4.1.3
Trying to communicate with an LSM303 but getting mostly zeros. I don't think this is a problem with the library but I could use guidance on when to use readData
versus readByte
if you could!
I'm porting from Python:
https://github.com/adafruit/Adafruit_Python_LSM303/blob/master/Adafruit_LSM303/LSM303.py#L85
I'm enabling the magnetometer based on this Python command:
self._mag.write8(LSM303_REGISTER_MAG_MR_REG_M, 0x00)
I'm issuing the following SwiftyGPIO command for that, to enable the mag:
i2c!.writeByte(magAddress, command: UInt8(LSM303_REGISTER_MAG_MR_REG_M), value: 0x00)
I'm port the following Python command to read data:
mag_raw = self._mag.readList(LSM303_REGISTER_MAG_OUT_X_H_M, 6)
I'm issuing the following SwiftyGPIO command for that, to read data:
let gyroData = i2c!.readData(magAddress, command: UInt8(LSM303_REGISTER_MAG_OUT_X_H_M)
Should I be fetching six bytes using readByte
instead? I think not.
I'm getting the following data in response:
[104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
The first six bytes should be meaningful, with hi/lo bytes representing the magnetometer raw data.
I've tried a lot of permutations but I'm confident I've nailed it with this approach.
Thanks!
This is available at least on RaspberryPi boards (pin-4 by default, 1-wire can be enabled on multiple pins recompiling the kernel) and it's used for example to communicate with the DS18B20 sensor.
There are converters from i2c available, but since this is supported via sysfs if it's easy to implement (and to enable via config.txt) it may be nice to have support for this protocol too. It's a low priority task, btw.
Line 335 in c59c2ce
Perhaps it's because I'm tired and it's very late but I couldn't get past this line when reading the code. What is the purpose of the right-shift? Doesn't it always result in zero?
You have fixed the .self to CChar for reference to metatype warnings,
but dont added a tag to the repo after this changes.
So it would be nice if you could bump the version.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.