Revision History
A running log of all changes that are made to this API with each iteration.
Version 2.0
Many things... Documentation coming.
Version 1.2
V1.2 makes versioning the python much simpler. It allows for much easier modification to the PiSoC firmware, without needing to version those changes in the python code. It also simplifies the API expansion process greatly for new developers, and provides frameworks for easy integration of new interfaces.
New to v1.2.7
- Changed all references of RPiSoC to PiSoC in the Python API and the documentation to be consistent with the official branding.
New to v1.2.5
In PiSoC code:
In analog.CapSense
- Added analog.CapSense.readRaw() for reading raw data form the CapSense buffer, to be used for manual calibration
- Added analog.CapSense.isTouched() to replace analog.CapSense.Read() for when SmartSense is disabled (it is by default)
- Added calibration code to analog.CapSense.Start() so that analog.CapSense.isTouched() gives desired behavior without SmartSense
In module pisoc.py
In pisoc.SERIAL
- Changed the initialization so that a serial port does not need to be provided. It will be determined at run time, and should be platform independent.
- Added pisoc.SERIAL.reconnect() for situations where the PiSoC might lose connection, and the user can check for this and reconnect if needed
- Added pisoc.SERIAL.disconnect() for a clean closing of the serial port
- Added pisoc.SERIAL.isConnected() to check the status of the serial connection with the PiSoC
New to v1.2.4
In the PiSoC code
- Added support for a standard Ultrasonic Range Finder, which should be useable by any SR-series range finer, excluding the 08 (which uses a different protocol), and the 3-pin Parallax ranger.
- Generally, it will support any range finder that uses a GPIO protocol based on pulse length measurements.
- This includes both 3-pin, 4-pin, and 5-pin devices
- Trigger length, and timeout duration is set on the application layer, so it can be as transportable as possible
- It was originally implemented using a hardware timer capturing clock events between the rising and falling edge of an input pin, but it required the use of customized digital logic and cascaded hardware multiplexers to handle the routing of any GPIO to the Timers input.
- At full scale, this used more digital resources than was acceptable, and so it was abandoned for a software approach
The timer component is still used for accuracy purposes, but it is used in its fixed function state, so that no UDB resources are wasted, and the routing was handled in software
In module digital.py
- Added digital.rangeFinder with the following supported methods:
- digital.rangeFinder.readRaw(): gets a raw value from the PiSoC, which is representative of how many microseconds the rangers echo pin was held high. It will trigger the range by sending a short pulse, the length defined upon construction of the object. The result will be measured on the desired signal pin, and stop measuring when a timeout is reached
- digital.rangeFinder.readMeters(): Uses readRaw to get a raw time value in microseconds, and then calculates the distance between the ranger and the pinged object in meters
- digital.rangeFinder.readCentimeters(): Uses readRaw to get a raw time value in microseconds, and then calculates the distance between the ranger and the pinged object in centimeters
- digital.rangeFinder.readInches(): Uses readRaw to get a raw time value, and then calculates the distance between the ranger and the pinged object in Inches
- digital.rangeFinder.setDelay(): Sets the length of the trigger pulse, in microseconds, which will be used to tell the device to send out a ping. This is handled in __init__, so it should only be called under unique circumstances.
- digital.rangeFinder.setTimeout(): Sets the timeout length in microseconds. If the PiSoC is still waiting for a completed response after this amount of time, it will stop counting and immediately return the result. This is handled in __init__, so it should only be called under unique circumstances.
New to v1.2.3
In the PiSoC code
- Included custom component for NeoPixel (or general WS2812 strip light) control. Output is on Port 6, pin 0 (required by the shield).
- This means that the first PWM output, which was on P6[0], had to be moved to Port 0 Pin 2
In module digital.py
- Added digital.NeoPixelShield which supports use of the NeoPixels Arduino shield through Python. Included methods are:
- digital.NeoPixelShield.Start(): Powers up and enables the needed hardware for the NeoPixels component
- digital.NeoPixelShield.Stop() : Powers down and disables the hardware used by the NeoPixels component
- digital.NeoPixelShield.Stripe(): Draws a line of length len of the stated color, starting from the first pixel, and extending as far as the 40th (last) pixel. It will wrap around rows
- digital.NeoPixelShield.SetPixel(): Sets a pixel of the stated color at position (x,y) = (row, column)
- digital.NeoPixelShield.DrawRow(): Fully draws the chosen row the desired color
- digital.NeoPixelShield.DrawColumn(): Fully draws the chosen column the desired color
- digital.NeoPixelShield.Dim(): Preserves the color to be drawn to the shield, but dims the brightness.
- Added 140 predefined colors as class attributes. They are the standardized colors of the HTML and CSS interfaces, and they are called by their official names, so for an object constructed as ‘shield’, you could access the color black with shield.Black
New to v1.2.2
In the PiSoC code
- USBUART (Serial) support has been added, allowing for use of the board through PC interfaces
In module pisoc.py
- Added class SERIAL() which will open a Windows COM Port, or Linux or OS X Serial Port for communication with the PiSoC over any baud rate
- It is chosen from the application layer by:
New to v1.2.1
This was a largely structural change to the PiSoC firmware. It redesigned the data structures in place for handling of device requests.
A bit-field struct is now used as the global data vessel, which will contain all needed data for any request made
- An additional layer of abstraction was added to the firmware, which should simplify the process of expansion for new developers
- Functions that make calls to hardware registers no longer handle any data packing- they all require meaningful, unpacked data as arguments
- The new abstraction layer handles bit unpacking, and then repacking into the bit-field for any supported device
- This bit-field, which should contain all relevant data, is then passed to the hardware layer where all arguments will be derived directly from an attribute of the struct
Parallel work done by Mark Bradley has been merged with my work for LabVIEW support through a LINX bridge
New to v1.2.0
In the PiSoC code:
- Added a way for the PiSoC to scan its generated source to determine
- What GPIO were being used
- How many PWMs, analog pins, and capsense buttons are being used
- If there existed one or more VDACs, IDACs, Delsig ADCs, SAR ADCs, or Wave DACs
- The full scale ranges on any DACs that are found
- The resolution of every PWM being used, as well as how many unique clocks are driving them
- Details about exactly which PWMs are sharing specific clocks, and the source frequency and default divider placed on those clocks
That data was then packed appropriately so that it could easily and efficiently be sent to the Raspberry Pi on request
Changed the GPIO structure to support all possible GPIO, and removed the control/status registers which were previously writing to, and polling these GPIO. With this approach, modification is simplified and digital resources are reserved.
Added full support for up to 24 PWM channels (previously there was only support for 8)
Added support for 6 CapSense buttons, located on Port 4, pins 0-5, with P4[6] needing a ~2.2nF Cmod
Made a skeleton for UART support, but haven’t yet completed the implementation
In pisoc.PiSoC:
- Added the ability to determine what is in the PiSoC firmare during the construction of the object.
- Added a DEBUG feature, which when set to True will print warnings and other diagnostic information to the terminal during run time
In module analog.py
In digital.Servo
- Fixed a bug which caused errors with 8-bit PWMs, due to a poorly derived (non-generalized) formula for calculation of a comparison value
In all classes
- Removed hard coded constraints, dependent on the version of the API, and replaced them with references to the data collected at construction of the PiSoC object.
- For instance, instead of raising an exception when you ask to initialize an analog pin not in range(10), as it was previously, I will raise an exception when trying to initialize an analog pin not in range(PiSoC.ANALOG_IN_NUM), where PiSoC.ANALOG_IN_NUM is the number of analog inputs which were discovered when the PiSoC class was constructed. This makes the API more portable and easier to version.
In pisoc.SPI and pisoc.I2C
- Provided an optional second argument to the receiveData() method, which will accept a delay, in seconds, to be called between the write operation and read operation. This is to be used by advanced users expanding the API. If a feature they implement requires a highly complex operation to be executed on the PiSoC, the Python may have to wait a small amount of time between the request and the response. Otherwise, a garbage response will be returned by the method.
Version 1.1
This version provides the Pi with a lot more functionality, and use of the API is intended to be more flexible than in the previous version.
New to v1.1.2
In the PiSoC code
- Removed the second SAR ADC and replaced it with a sequenced ADC, with 10 analog inputs. This allows for simplified use of analog pins, and gives 10 more.
- Removed Port 6 as a GPIO register so that more analog pins could be added
- PWM (and consequently servo) pins were moved from Port 3 to Port 6, so that Port 3 could be used for the new analog pins (Ports 0 and 3 have slightly better analog performance than the other ports)
- Changed the structure of the GPIO functionality enumeration. I concatenated all of the seperate GPIO registers into one register, and changed the packing and unpacking process of each transfer to contain the port, pin, command, and value to be written if applicable.
- Added the ability to change drive modes to each GPIO at run time.
In module pisoc.py
- Fixed the import structure so that both smbus and spidev aren’t needed. This means you don’t have to configure the Pi for I2C if you only intend to use SPI, or vice versa.
In module digital.py
- Removed classes digital.DigitalInput and digital.DigitalOutput
- Added class digital.digitalPin which allows one to instantiate any of the GPIO as input or output, or in any of several different drive modes if needed.
In module analog.py
- Added analog.analogPin which simplifies the process of getting an analog reading from an ADC, and it adds an aditional 10 analog inputs.
In digital.Servo
- Simplified instantiation. It is now only required to provide a servo location relative to Port 6.
- Pulse width and angle ranges can still be input, but they will simply default to standard values if only the servo location is given
- Minimum pulse width defaults to 1.0; maximum pulse width defaults to 2.0; minimum angle defaults to 0; maximum angle defaults to 180
New to V1.1.1
Code structure
- communication.py was removed and merged with module pisoc.py to simplify the overall structure.
In pisoc.SPI
- Further minimized latency inherent to each SPI transfer.
- pisoc.SPI.cleanup() will now reset any global data tracked within the PiSoC class, in case pisoc.SPI.cleanup() is not called at termination
In pisoc.I2C
- pisoc.I2C.cleanup() method will now reset any global data tracked within the PiSoC class, in case pisoc.I2C.cleanup() is not called at termination
In analog.VDAC
- Added analog.VDAC.SetVoltage() method, so that the user can directly input a voltage within the specified DAC’s full scale range
In analog.IDAC
- Added a analog.IDAC.SetCurrent() method, so that the user can directly input a current in milliamperes within the specified DAC’s full scale range
New to V1.1.0
In the PiSoC code
- Added I2C support
- Added the ability to software reset the PiSoC through the Raspberry Pi
- Removed unneeded delays, speeding up the init process
- changed which bootloader is used
- clocked the PWM’s seperately, such that they aren’t all sharing the same clock; they are only sharing their clock with one other PWM instead of 7, as was the case in V1.0.0
- Fixed a bug discovered in the WaveDAC class, which was generating waves that appeared to be very noisy.
In digital.PWM
- Added ability to modify the frequency of the clocks which drive the PWM signals with digital.PWM.SetClocks()
- Added ability to read back the actual PWM clocking frequency with digital.PWM.GetClocks()
- Added a warning when the clock range of the PWM clocks might be inaccurate (since the frequencies are generated using clock dividers, and they can be inaccurate at high frequencies)
- Changed digital.PWM.SetDutyCycle() to be a float value instead of an int, for more precision
- Added digital.PWM.GetDutyCycle() which will give back the percentage of time between 0 and 100 how long your PWM is high.
- Added digital.PWM.SetClockDivider() which lets you give the PWM clock a specific divider value, so you don’t have to be worried about an inaccurate result using digital.PWM.SetClocks()
- Added digital.PWM.GetClockDivder() method to see what the most recently confirmed clock divider value is
- Added digital.PWM.SetFrequency() which provides the ability to modify the actual wave frequency of the PWM, between 0.006 Hz and 2.4MHz, without affecting the duty cycle too profoundly.
- Added digital.PWM.GetFrequency() method which will return the actual frequency of the PWM wave
In pisoc.PiSoC
- Added class attributes to the PiSoC indicate whether a register address is already in use. So if the user attempts to initialize an object that is already in use, a warning will be issued.
In analog.ADC
- Changed return value of analog.ADC.CountsTo_Volts() from a millivolt value to a microvolt value, so that precision is increased. The return value of the Python method when called is still in Volts.
In classes digital.DigitalInput and digital.DigitalOutput
- Moved the bit masking process of the digital inputs and outputs to the C code, where it can be executed more quickly, and with fewer data transfers
In analog.WaveDAC
- Added a warning when the frequency might be out of range
In module digital.py
Version 1.0
The public release of the API. It exposes, most fundamentally, the following functionality to the Raspberry Pi through the PiSoC
- 8 PWM channels
- 20 digital outputs
- 19 digital inputs
- 2 8-bit VDAC’s
- 1 8-bit IDAC
- 1 8-bit WaveDAC
- 1 16-bit Delta Sigma ADC
- 2 12-bit SAR ADC’s
Communication to the PiSoC requires use of SPI. No other communication protocol is yet supported, and the VDAC’s and IDAC’s are currently untested.