PiFace Digital Not Supported Yet

Here it is! I’ll make a project post in the next couple days with all the how to stuff. You will have to create the widgets on your MQTT dashboard for this to work. Digital outputs can be created using add new>device/widget>custom widgets>button and the digital inputs can be created using add new>device/widget>custom widgets>2 state. Digital outputs are channel 0-7 and digital inputs are channel 8-14

import paho.mqtt.client as mqtt
import time
import sys
import pifacedigitalio

#time.sleep(30) #Sleep to allow wireless to connect before starting MQTT

#set up user info
username = "username from mqtt dashboard"
password = "password from mqtt dashboard"
clientid = "clientid from mqtt dashboard"

#handle incoming messages from Cayenne
def on_message(client, userdata, message):
    #print("Received message '" + str(message.payload) + "' on topic '" + message.topic + "' with QoS " + str(message.qos)) #uncomment to print recieved message
    updatevaluetopic = str(message.topic.rsplit('/',2)[0]) + "/data/" + str(message.topic.rsplit('/',2)[2]) #topic to send updated value to dashboard
    commandresponsetopic = str(message.topic.rsplit('/',2)[0]) + "/response" #topic to send response to dashboard
    try: #if there is an error let Cayenne know about it
        pfd.output_pins[int(message.topic.rsplit('/',2)[2])].value = int(message.payload.split(',')[1]) #set output to the value recieved
        updatevalue = message.payload.split(',')[1] #set value to send back to dashboard
        mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send back the value that was recieved to update the dashboard widget
        commandresponse = "ok," + str(message.payload.split(',')[0]) #set the response to send back to the dasboard
        mqttc.publish(commandresponsetopic, payload=commandresponse, retain=True) #send response to the dashboard
    except:
        commandresponse = "error," + str(message.payload.split(',')[0])
        mqttc.publish(topic, payload=commandresponse, retain=True)

#handle falling events
def updatedashboardfalling(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=1" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#handle rising events
def updatedashboardrising(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=0" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#Set up PiFace Digital
pifacedigitalio.init()
pfd = pifacedigitalio.PiFaceDigital()

#set up MQTT
mqttc = mqtt.Client(client_id=clientid)
mqttc.username_pw_set(username, password=password)
mqttc.connect("mqtt.mydevices.com", port=1883, keepalive=60)
mqttc.loop_start()
mqttc.subscribe("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#")
mqttc.message_callback_add("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#", on_message)

#set up interrupts
listener = pifacedigitalio.InputEventListener(chip=pfd)
for i in range(4):
    listener.register(i, pifacedigitalio.IODIR_FALLING_EDGE, updatedashboardfalling)
    listener.register(i, pifacedigitalio.IODIR_RISING_EDGE, updatedashboardrising)
listener.activate()

while True:
    try:
        for i in range(8): #since interrupts can be unreliable send the actual value to the dashboard every 1 second as well
            updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(i + 8) #topic to send updated value to dashboard
            updatevalue = "digital,d=" + str(pfd.input_pins[i].value) #set value to send back to dashboard
            mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard
        time.sleep(1)
    except (EOFError, SystemExit, KeyboardInterrupt): #handle ctrl+c and reboots cleanly
        mqttc.disconnect()
        listener.deactivate()
        sys.exit()

Looks great.
I tried AddNew / Bring your own thing but without luck.
Seems like the tutorial videos are no longer up to date. Should I use Cayenne MQTT Python?

Also in Add new Device / Custom Widgets, I cannot select a Device

Yep, leave your dashboard at the bring your own thing screen then copy/paste the username, password, client id there in to the python script I posted. Run the script and when the script makes a connection the screen with your user, pass, and client id will disappear and show you your dashboard. Once you are at this stage then you can add the custom widgets.

btw I didn’t use the Cayenne python MQTT library, I just used the standard paho library.

Sorry - can’t get it to work.
Started python3
Pasted the code (with the pated, Uid,Pwd and clientID) but get the errors:
Traceback (most recent call last):
File “”, line 6, in
NameError: name ‘mqttc’ is not defined

Should I crate a file, make it executable or smoothing and maybe in a special directory.
Sorry for being such a rookie.

Oh, you’ll have to install the MQTT library too. Use this command:

sudo pip install paho-mqtt
sudo pip3 install paho-mqtt (for python 3 if you need it)

Also, I’m not sure if you meant that you were using the command python3 and then pasting in that code or not but you will need to create a new file, say piface.py, paste in the code from above, and then run it using the command python piface.py

Hi adam
I tried to follow your instructions and finally got able to control the two relays.
However. When pressing one of the four input ports 8-11 the state is not visible.
Furthermore when leaving the device on for some hours, it suddenly stops responding. (unable to control relais)
Is there a plan for when this solution will be added as a “normal” plug and play device? (I mean since it is present in the available devices - or am I misunderstanding this as well?)
Sorry for all the crazy questions.

You can try to add it via the extension, I didn’t know it was there. It looks like the one that is available to add as an extension is a PiFace 1. From a quick read it looks like they are identical other than the 2 fits the b+ and newer models. Worth a shot to see if it works.

This was my very first attempt when trying out Cayenne and I never got it to work.
Actually I thought Raspberry-PI+PiFaxe+Cayenne would be the perfect match for my project, controlling two relays and reading digital inputs. :disappointed_relieved:
According to @eptak on Dec. 2015 the Piface 1 and 2 should be supported.

@wek I came back to this thread from another post and just now realized where the mistake is. Try the code below:

import paho.mqtt.client as mqtt
import time
import sys
import pifacedigitalio

#time.sleep(30) #Sleep to allow wireless to connect before starting MQTT

#set up user info
username = "username from mqtt dashboard"
password = "password from mqtt dashboard"
clientid = "clientid from mqtt dashboard"

#handle incoming messages from Cayenne
def on_message(client, userdata, message):
    #print("Received message '" + str(message.payload) + "' on topic '" + message.topic + "' with QoS " + str(message.qos)) #uncomment to print recieved message
    updatevaluetopic = str(message.topic.rsplit('/',2)[0]) + "/data/" + str(message.topic.rsplit('/',2)[2]) #topic to send updated value to dashboard
    commandresponsetopic = str(message.topic.rsplit('/',2)[0]) + "/response" #topic to send response to dashboard
    try: #if there is an error let Cayenne know about it
        pfd.output_pins[int(message.topic.rsplit('/',2)[2])].value = int(message.payload.split(',')[1]) #set output to the value recieved
        updatevalue = message.payload.split(',')[1] #set value to send back to dashboard
        mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send back the value that was recieved to update the dashboard widget
        commandresponse = "ok," + str(message.payload.split(',')[0]) #set the response to send back to the dasboard
        mqttc.publish(commandresponsetopic, payload=commandresponse, retain=True) #send response to the dashboard
    except:
        commandresponse = "error," + str(message.payload.split(',')[0])
        mqttc.publish(topic, payload=commandresponse, retain=True)

#handle falling events
def updatedashboardfalling(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=1" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#handle rising events
def updatedashboardrising(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=0" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#Set up PiFace Digital
pifacedigitalio.init()
pfd = pifacedigitalio.PiFaceDigital()

#set up MQTT
mqttc = mqtt.Client(client_id=clientid)
mqttc.username_pw_set(username, password=password)
mqttc.connect("mqtt.mydevices.com", port=1883, keepalive=60)
mqttc.loop_start()
mqttc.subscribe("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#")
mqttc.message_callback_add("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#", on_message)

#set up interrupts
listener = pifacedigitalio.InputEventListener(chip=pfd)
for i in range(4):
    listener.register(i, pifacedigitalio.IODIR_FALLING_EDGE, updatedashboardfalling)
    listener.register(i, pifacedigitalio.IODIR_RISING_EDGE, updatedashboardrising)
listener.activate()

while True:
    try:
        for i in range(8): #since interrupts can be unreliable send the actual value to the dashboard every 1 second as well
            updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(i + 8) #topic to send updated value to dashboard
            updatevalue = "digital,d=" + str(pfd.input_pins[i].value) #set value to send back to dashboard
            mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard
        time.sleep(1)
    except (EOFError, SystemExit, KeyboardInterrupt): #handle ctrl+c and reboots cleanly
        mqttc.disconnect()
        listener.deactivate()
        sys.exit()

Thanks for the info. I have a PiFace Digital 2. I can access it with the emulator while it’s connected to the Pi. I just haven’t found a way to control it using Cayenne. What you posted is for the original PiFace Digital. I don’t have one of those. Do you think what you posted will work for the PiFace Digital 2? Thanks again. Have a good weekend.

Yep, that code is for a 2. If you scroll up a bit I have instructions for setting up the dashboard. For reference, this is the PiFace I have https://www.amazon.com/gp/product/B00PL4LO50/ref=oh_aui_search_detailpage?ie=UTF8&psc=1

Great! Thank you.

Piface DIgital 2 does not work on Raspian Stretch. If you haven’t purchased one yet, don’t bother. The board will never be recognized. There is almost zero documentation and what little there is, is outdated. It does work on earlier Raspbian versions but they are not available from Raspberry Pi (org) anymore.

The Piface Digital 2 has left a lot of people with Pi on their faces.

Looks like if you manually install via pip is should work https://www.element14.com/community/thread/61209/l/piface-digital-2-board-can-not-locate-packages-to-install?displayFullThread=true Let me know if it doesn’t and I can get this script out again and test it. Also found this post which has instructions for compiling from source.

Hello Adam,

I correctly installed pifacedigitalio and pifacecommon. The Piface Digital 2 board is not recognized. It works with Raspbian Jessie. I didn’t save the error messages, sorry. I will get some detailed information for you by tomorrow.

Best wishes

1 Like

Hello Adam,

The Piface Digital 2 is installed on a RPi2B. It works the Jessie.

  1. I setup the RPi using the Cayenne IOS app.

  2. I had to do this in order to make step 1 work otherwise installation/setup failed at (Cayenne step 3) “Installing Software”:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt-get install python3.4
sudo apt --fix-broken install
sudo apt install python3-dev

wget https://cayenne.mydevices.com/dl/rpi_ecsjr4jzls.sh https://cayenne.mydevices.com/dl/rpi_ecsjr4jzls.sh
sudo bash rpi_ecsjr4jzls.sh -v

  1. I could not install pifacedigitalio using this command:

    sudo apt-get install python{,3}-pifacedigitalio

    This resulted in:

Reading package lists… Done
Building dependency tree
Reading state information… Done
E: Unable to locate package python-pifacedigitalio
E: Unable to locate package python3-pifacedigitalio

So I did this instead:

wget https://pypi.python.org/packages/06/33/38ff94cd74442da0f2d18241b88ebd3c8a89489ddb1d880d72a67306569c/pifacedigitalio-3.0.5.tar.gz
tar xvzf pifacedigitalio-3.0.5.tar.gz
cd pifacedigitalio-3.0.5/
sudo python3 setup.py install

I was also able to install pifacedigitalio and pifacecommon using:

pip3 install pifacedigitalio
pip3 install pifacecommon

I also did this:

	sudo pip install paho-mqtt
  1. I used the Python code you provided (the last version)

    When I run: python pyface.py
    I get this:

Traceback (most recent call last):
File “pyface.py”, line 41, in
pifacedigitalio.init()
File “/home/pi/pifacedigitalio-3.0.5/pifacedigitalio/core.py”, line 166, in init
raise failed_boards[0]
pifacedigitalio.core.NoPiFaceDigitalDetectedError: No PiFace Digital board detected (hardware_addr=0, bus=0, chip_select=0).

When I run: python3 pyface.py
I get this:

Traceback (most recent call last):
File “pyface.py”, line 41, in
pifacedigitalio.init()
File “/home/pi/pifacedigitalio-3.0.5/pifacedigitalio/core.py”, line 166, in init
raise failed_boards[0]
File “/home/pi/pifacedigitalio-3.0.5/pifacedigitalio/core.py”, line 162, in init
init_board)
File “/home/pi/pifacedigitalio-3.0.5/pifacedigitalio/core.py”, line 82, in init
self.init_board()
File “/home/pi/pifacedigitalio-3.0.5/pifacedigitalio/core.py”, line 107, in init_board
h=self.hardware_addr, b=self.bus, c=self.chip_select))
pifacedigitalio.core.NoPiFaceDigitalDetectedError: No PiFace Digital board detected (hardware_addr=0, bus=0, chip_select=0).

I basically stopped trying at this point, I had spent too much time. My application only requires two relay outputs so I purchased a simple relay output board for $20 and control it using Cayenne GPIO DO.

I hope this helps and does not confuse. I will not be using the Piface Digital 2 for this project but I am glad to help you in any way if you need me to test something. Please let me know if I should provide more (or more clear) information.

Best wishes,

Neil Hastings

Quick question…did you enable SPI via settings in raspi-config? Looks like it’s just not detecting the board. Also found a post suggesting you swap the SPI jumpers for the PiFace Digital from “default” to “swapped” CE lines, but if it’s working on your Pi2 then I’d say you should be good there.

I did enable SPI using raspi-config. The Cayenne web interface also confirms SPI is enabled.

This weekend, I’ll try swapping the SPI jumper(s) to “swapped” and will let you know what happens.

By the way, I enjoyed reading all of your posts regarding this subject. You are very clear and incisive in your troubleshooting skills.

Thanks,

Neil

1 Like