GithubHelp home page GithubHelp logo

abelectronicsuk / abelectronics_python_libraries Goto Github PK

View Code? Open in Web Editor NEW
77.0 13.0 62.0 538 KB

Python Libraries to work with Raspberry Pi expansion boards from AB Electronics

License: GNU General Public License v2.0

Python 100.00%

abelectronics_python_libraries's Introduction

AB Electronics Python Libraries

Python Libraries to work with Raspberry Pi expansion boards from https://www.abelectronics.co.uk

Downloading and Installing the library

Python 3

To install the library you will need the Python3 build and install packages. To install them run the following command.

sudo apt update
sudo apt install python3-build python3-installer git

Download the ABElectronics_Python_Libraries to your Raspberry Pi:

git clone https://github.com/abelectronicsuk/ABElectronics_Python_Libraries.git

To install the python library navigate into the ABElectronics_Python_Libraries folder and run:

python3 -m build
sudo python3 -m installer dist/*.whl

Python 2

If you want to install the library on older versions of Linux using Python 2 you can run the following command.

sudo python setup.py install

If you have PIP installed you can install the library directly from GitHub with the following command replacing python2.7 with the version of Python on your computer:

sudo python2.7 -m pip install git+https://github.com/abelectronicsuk/ABElectronics_Python_Libraries.git

Using classes without installing the library.

To use a specific part of our Python library in your project without installing the entire library, you can simply copy the needed class file into your project's directory. For example, to use the IO Pi Plus, copy the IOPi.py file from the IOPi directory to where your project files are located. After doing this, you can use the class in your program by adding an import statement at the beginning of your Python code. This allows you to directly utilize the class's functionality in your project.

from IOPi import IOPi

ADCDACPi

This directory contains ADC DAC Pi Python Library with ADC read and DAC write demos to use with the ADC DAC Pi

ADCPi

This directory contains ADC Pi Python Library and demos to use with the ADC Pi

ADCDifferentialPi

This directory contains ADC Differential Pi Python Library and demos to use with the ADC Differential Pi
This library is also compatible with the Delta-Sigma Pi

ExpanderPi

This directory contains IO Pi Python Library and demos to use with the Expander Pi

I2C Switch

This directory contains the I2C Switch Python library and demo to use with the 4-channel I2C switch

IOPi

This directory contains IO Pi Python Library and demos to use with the IO Pi Plus

IOZero32

This directory contains IO Zero 32 Python Library and demos to use with the IO Zero 32

RTCPi

This directory contains RTC Pi Python Library and demos to use with the RTC Pi

ServoPi

This directory contains ServoPi Python Library and demos to use with the Servo Pi

07-07-2017 Changes for Version 2.0

Version 2.0.0 of the Python library has introduced several changes to the structure of the classes and demo files. The major changes are listed below. Please read CHANGELOG.md for a complete list of changes.

  • Files renamed: removed ABE_ from all names.
    ABE_ADCDACPi > ADCDACPi
    ABE_ADCDifferentialPi > ADCDifferentialPi
    ABE_ADCPi > ADCPi
    ABE_ExpanderPi > ExpanderPi
    ABE_IOPi > IOPi
    ABE_RTCPi > RTCPi
    ABE_ServoPi > ServoPi

  • All classes and demo files are now compatible with Python 2 and 3. The ABElectronics_Python3_Libraries will no longer be updated so please use this version instead for your Python 3 projects.

  • Moved all demo files into demo sub-folders for each class

  • The ABE_Helper class has been integrated into the board classes and does not need to be imported separately.

  • Added a setup.py into the root for installing the library into the main Python library directory.

Previous versions of the Python libraries can be found at https://github.com/abelectronicsuk/Archive

abelectronics_python_libraries's People

Contributors

abelectronicsuk avatar alecrobingould avatar moeskerv avatar nealthegitguy avatar qpeten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

abelectronics_python_libraries's Issues

Duplicate readings of channels

It appears that when I read channels 1 and 2, I get the same reading. Same goes with all pairs (3,4: 5,6: 7,8). Have you been able to test this with some known voltage? Say a pot or something? I'm just wondering if I'm crazy or not.

Publish this project on PyPI

As I said in #16 it would be nice to use the pip-version of smbus.

Another benefit of this would be that you could publish the project on PyPI and make it installable via pip. That would make it easier for others to use it in their projects, because they can specify the needed version in their setup.py.

Best Luke

Add exceptions for errors

When initialising the instance, apart from the ADCPI timeout, there are no other useful exceptions. I'm having problems initialising and trying to narrow down the where the issue might be.

Also, the internal function that gets the I2C addresses might be useful if it could be called from the instance, again to see if the problem is Pi or ADC related.

Thanks!

IOPi.py more "generic" constructor

I'm playing with IO Pi Zero module connected to NanoPi Duo2 (Armbian Focal) , I can have it working as expected but it need little tweaking.

The Constructor of class IOPi in line 134
device = platform.uname()[1]
is getting the "name" of board but in my case the hostname is returned. And that is obviously useless :-(

My workaround was just to change line 132 to:
i2c__bus = 0
as my NanoPi Duo2 bus is 0.

What do you thing about idea of providing the "bus number" as additional parameter to the constructor. This will easily expand the coverage of your library to many boards without touching other part of library. Because now every board should be somehow "hardcoded" inside the __get_smbus() method.

for example:

def __init__(self, address, initialise=True, bus=-1)

then if bus != -1 don't check the "board type" - just use passed value as i2c_bus.

Setting channel 0 or negative in read_raw in ADCPi does not raise a ValueError

Describe the bug
It is possible to call read_raw(0) and read_raw(-1), this does not raise an exception.

To Reproduce
from ADCPi import ADCPi
adc = ADCPi(0x68, 0x6B, 18)
adc.read_raw(0)
adc.read_raw(-1)
print("If you see this printout, the two above lines failed to give an exception")

Expected behavior
read_raw(X) with X anything other than the numbers 1 to 8 should raise a ValueError: read_raw: channel out of range

Error running demo_pwm.py

Hi there
getting this error running the demo
with python 2.7 and 3

Traceback (most recent call last):
File "demo_pwm.py", line 49, in
main()
File "demo_pwm.py", line 39, in main
pwm.set_pwm_freq(1000)
File "/usr/local/lib/python2.7/dist-packages/ServoPi/ServoPi.py", line 112, in set_pwm_freq
newmode = (oldmode & 0x7F) | 0x10
TypeError: unsupported operand type(s) for &: 'exceptions.IOError' and 'int'

Any idea how to resolve this issue?
Thanks in advance

MPC23017 works with Thinkpad Laptop i2c bus but it seems like it times out when writing to it too fast

First of all, thanks for all the information and code you provide for the IOPi plus board, it makes it working with it so much easier and enjoyable.
I know the IOPI Plus board is not intended to be used this way, but I am using my Thinkpad laptop VGA i2c bus to interface with it. The python library works quite well, but I had to place a very short time.sleep(0.01) after __bus.write_byte_data() and other bus interactions because if I don't it seems like the board can't catch up and SMBus() throws me an IOError: [Errno 6] No such device or address.

Is there a more elegant way to deal with this?

Jardi.

P.S.
My reason for trying this is that I am planning on moving my Home Assistant instance from the Pi to an Intel NUC but I have a whole bunch of doors and windows sensors interfacing with it through an IOPi Plus board which I would also like to adapt to the NUC. My plan is to convert your IOPi.py library into a more generic MPC23017 library that can be use in any other linux system with an I2C bus, and since I don't have a NUC yet I am doing some testing using my Thinkpad's VGA port.

SPI Bus too fast

Measured Voltages about 8% too low
I was measuring 2.46V at ADC input and it was reporting 1.31V. And I wanted the exact value! I slowed down the bus and around 200kHz, the values are correct.

Recommendation
Please slow down SPI by default as precision is very important. For speed, you may explain in a comment that it can be augmented but sub-estimate begins to be over 5% somewhere around 1MHz.

** Line of source code **
self.__spiADC.max_speed_hz = (200000)

Use smbus2 from PyPI

Hey guys,

is there a good reason, why you use the smbus package which needs to be installed via apt?

I tried to run your modules with smbus2 which is installable via pip and it works without problems.
The big benefit of using this would be, that you can add it as a dependancy in the setup.py.

If you would like, I could make a pull request for that.

If you prefer keeping the apt-version, I would like to make a fork of your project and publish it on PyPI with the changes if this is ok for you.

Best Luke

Whitespace issues in ABE_helpers.py

There is a problem with mixed spaces and tabs in ABE_helpers.py in the ADCPi folder.

The lines around the if/elif statement have a single tab mixed in with the spaces, which is causing Python to throw an exception. Can you please fix this?

[ServoPi.py] Invalid servo range in the Servo.move method

In ServoPi.py @ line 255, there's the following condition check:
if channel >= 0 and channel <= 15:

Which accept the value 0, and fail for value 16.

But the set_pwm() function except a value between 1-16

It should be:
if channel >= 1 and channel <= 16:

Bug fixes and suggestion for ABElectronics_IOPi.py

In ABElectronics_IOPi.py:
bugs:

  1. In invertPort, your input parameters are (self, port, polarity), but you later use 'value' four times in the method instead of 'polarity'. Need to change 'value' to 'polarity' four times in the function, or else change 'polarity' to 'value' once.
  2. In invertPort, writePort, and setPortDirection methods, you've shadowed the instance variables (port[x]_polarity, port[x]_val, and port[x]_dir, respectively, where [x] is A or B) with local variables of the same name, and thus the behavior is not what was intended, as the instance variable values do not get set. The same thing was done in readPin and readPort methods, but one could argue that it doesn't matter there.

suggestion:
I think it is an unnecessary and perhaps invalid assumption in the init method that the initial state of the pins should be low. On many devices, the default (off) state is a high pin, so this just turns everything on as soon as you instantiate the class. I suggest leaving each pin in the state it was when you acquire the handle, by replacing the following lines in the init method:
bus.write_byte_data(self.address,self.GPIOA,0x00)
bus.write_byte_data(self.address,self.GPIOB,0x00)
with the following:
self.portA_val = bus.read_byte_data(self.address,self.GPIOA)
self.portB_val = bus.read_byte_data(self.address,self.GPIOB)
thus reading the initial state and setting the instance variables to match the device, rather than the other way around.

Thanks for publishing this. It really gave me a big head-start on where I would be if I had to start from scratch.

Errno16

From: Elliott
Board: Raspberry Pi Zero V1.1
OS: Raspbian Bullseye
Python Verison: 3.12.2 https://www.python.org/downloads/
RTC Board: https://www.abelectronics.co.uk/p/70/rtc-pi
RTCLib: As per https://github.com/abelectronicsuk/ABElectronics_Python_Libraries/
Installed: As per Tutorial https://www.abelectronics.co.uk/kb/article/30/rtc-pi-setup-on-raspberry-pi-os
and https://www.abelectronics.co.uk/kb/article/1/i2c-part-2-enabling-i2c-on-the-raspberry-pi
No other boards added & no other GPIO pins used
IDE: Thonny

Tutortial has worked the RTC is keeping correct date and time. Have confirmed by turning off WiFi and rebooting several times with WiFi off.

Error when running demo_rtcgetdate.py from RTCPi see attached file Errno16
ErrNo16
The UU at 0x68 indicates that there is another device or driver at the same address.

Debugging Output see attachment
E16_Debug

Steps Tried
Pins soldered and secure
Redid tutorial

Internet search has shown
https://www.linuxquestions.org/questions/linux-embedded-and-single-board-computer-78/what-is-error-ioerror-%5Berrno-16%5D-device-or-resource-busy-4175599788/
Implies
2 Solutions

  1. Remove driver however I do not know how to deteremine this and how to remove
  2. The last post yes it is i2c slave address and to view te i2cdump output

i2cdump output
dump

From the dump the issues seems to be with i2c-1

Resolution sort

  1. How to remove what is on i2c-1
  2. Other causes/ solutions to fix

Thank you for your time and attention

TimeoutError not defined in Python 2.7

global name 'TimeoutError' is not defined
When the TimeoutError is raised in Python 2.7 it results in a NameError. From what I can tell TimeoutError wasn't introduced until Python 3.3

Recommendation
Please define a custom "TimeoutError" class in the beginning of the library for systems using Python 2. It would be very helpful to be able to handle this error in my code where I import the library when this happens. Right now I have to handle it as a "NameError" instead.

ADCPi.read_voltage() freezes without raising an exception

I have a use case with a couple of different scripts logging and watching ADCPi channels. If one script calls ADCPi.read_voltage() before the first was finished, both scripts become totally unresponsive.

This situation with several simultaneous calls for ADCPi.read_voltage() can easily be triggered by starting a few instances of the demo script:
python demo-readvoltage.py &
When I start the 4th or 5th test script they all freeze without raising any exception.

It would be nice if the ADCPi.read_voltage() could handle this situation by raising an exception when it fails. Perhaps there could be a timeout if for the underlying i2c reading?

Resistance on ADC Pi

Hello.

First I would like to thank you for your wonderful products.

In the past I have found on the ADC Pi's page about the information of the resistors installed on it (in order to be able to measure voltages >2v). But I forgot to save.

Today when I used ADC Pi to measure the output signal of a pressure sensor (PSE563, with 1-5v output, https://docs.rs-online.com/3ae2/0900766b80df5651.pdf) I didn't get the right result. I discovered this sensor uses a 1000-ohm resistor as the output impedance so it falsified the measurement results.

image

image

I couldn't find the contact section on your website so I wrote this post. I hope you can tell me about the resistor information on your ADC Pi.

Thank you.

ADCPi Plus -- can't get example to work

I am running Linux raspberrypi 4.9.39-v7+ #1 SMP Wed Jul 26 05:31:05 CEST 2017 armv7l GNU/Linux and i2cdetect gives the following output:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- 6d -- --
70: -- -- -- -- -- -- -- --

Unfortunately, the example (copied to another file) fails with:

Traceback (most recent call last):
  File "test_ADC_I2C_MCP3428.py", line 60, in <module>
    main()
  File "test_ADC_I2C_MCP3428.py", line 39, in main
    adc = ADCPi(0x68, 0x6d, 12)
  File "/usr/local/lib/python3.4/dist-packages/ADCPi/ADCPi.py", line 109, in __init__
    self.set_bit_rate(rate)
  File "/usr/local/lib/python3.4/dist-packages/ADCPi/ADCPi.py", line 261, in set_bit_rate
    self.__bus.write_byte(self.__adc1[0], self.__adc1[1])
  File "/usr/local/lib/python3.4/dist-packages/smbus/util.py", line 59, in validator
    return fn(*args, **kwdefaults)
  File "/usr/local/lib/python3.4/dist-packages/smbus/smbus.py", line 121, in write_byte
    raise IOError(ffi.errno)
OSError: 5

As you see, I adapted the address of the second ADC to 0x6d, as for some (to me currently unknown) reason i2cdetect would not detect it reliably on it's default address.

Timeouterror causing values to freeze

Hello,

I am using the ADC Differential Pi to do some telemetry on batteries. I have a thermistor/current sensor and voltage sensor (all calculated by reading voltage drop). However, when I get a timeouterror I see that the values freeze on the last one before the timeout. Is there something I can do to avoid this?

    def __read_adc(self):
        self.__adc = ADCDifferentialPi(0x6a, 0x69, 18)
        self.__adc.set_pga(1)
        self.__fail_count = 0
        while not self.stop:
            try:
                timestamp = datetime.now()
                self.dataset[0] = ((self.__adc.read_voltage(1) + self.config.vcor) * self.config.Gv)
                self.dataset[1] = (self.__adc.read_voltage(4) - self.config.icor) / self.config.vgain
                if -15 <= self.dataset[1] <= 15:
                    self.dataset[1] = 0
                tcor = self.calc_temperature(self.calc_resistance(self.__adc.read_voltage(3)))
                self.dataset[2] = (self.__adc.read_voltage(8)/self.config.celcius) + tcor
            except KeyboardInterrupt:
                LOGGER.info("Stopping")
                break
            except:
                LOGGER.exception("Unexpected: ")
                sys.exit()
                self.__fail_count += 1
            time.sleep(0.2)
Unexpected: 
Traceback (most recent call last):
  File "/home/pi/scmeter/strom_diagnostic.py", line 82, in __read_adc
    tcor = self.calc_temperature(self.calc_resistance(self.__adc.read_voltage(3)))
  File "/usr/local/lib/python3.5/dist-packages/ADCDifferentialPi/ADCDifferentialPi.py", line 136, in read_voltage
    raw = self.read_raw(channel)
  File "/usr/local/lib/python3.5/dist-packages/ADCDifferentialPi/ADCDifferentialPi.py", line 199, in read_raw
    raise TimeoutError(msg)
TimeoutError: read_raw: channel 3 conversion timed out
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 50, 769936)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 50, 769936)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 51, 776438)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 52, 782307)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 53, 788786)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 54, 794547)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 55, 800444)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 56, 806269)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 57, 813006)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 58, 815608)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 34, 59, 817479)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 35, 0, 821270)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],
    'table': 'testing',
    'timestamp': datetime.datetime(2019, 3, 11, 17, 35, 1, 825087)}
{   'data': [   {   'Current': -217.7699303136222,
                    'Temperature': 14.410154208169065,
                    'Voltage': 47.31267686170213}],

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.