Teil 5 des Rasberry Pi I2C Projektes

Communication mit dem PCF8574

Die Idee den I2C Bus mit der LIBRARY von BCM8235 anzusprechen ist gut, ging aber bisher nicht. Komischerweise habe ich immer einen Fehler der in einem Segmentation Fault landet. Nachdem ich einige Zeit damit verbracht hatte nach einer Lösung zu suchen und zu finden hab ich das erst einmal beiseite gelegt um mit dem Projekt überhaupt weiter zu kommen. Da die Platine aus China mitlerweile auf dem Weg ist und ALLPCB.COM mir mitgeteilt hat, Liefertermin 5.1.2021 und FedEx sich auch schon gemeldet, sollte es nicht an diesem Stück Software liegen das es nicht weiter geht. Die Routinen sind austauschbar und es gibt immer mehere Wege zu einer Lösung.

Alternativen

WiredPi oder der Weg über das OS-Filesystem sind aktuelle die Alternativen um mit dem Baustein zu kommunizieren. Der Weg über das Filesystem ist der Weg, welchen auch scheinbar I2CSET und I2CGET, I2CDETECT, … auf der OS Seite verwenden. Der Zugriff erfolgt dann quasi mit OS Boardmitteln in dem über das Filesystem auf den Baustein zugegriffen wird. Damit habe ich auch die ersten Tests gemacht und kontrolliert ob der Baustein am Bus reagiert. Das geht also.

Bei github habe ich folgendes gefunden und auf der Basis habe ich es mit meinem System probiert, it works.

// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// PCF8574
// This code is designed to work with the PCF8574_LBAR_I2CL I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/products

#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <math.h>

void main()
{
    // Create I2C bus
    int file;
    char *bus = "/dev/i2c-1";
    if((file = open(bus, O_RDWR)) < 0)
    {
        printf("Failed to open the bus. \n");
        exit(1);
    }
    // Get I2C device, PCF8574 I2C address is 0x20(32)
    ioctl(file, I2C_SLAVE, 0x20);
    
    // Set all pins as INPUT(0xFF)
    char config[1] = {0};
    config[0] = 0xFF;
    write(file, config, 1);
    printf("All Pins State are HIGH \n");
    sleep(1);
    
    // Read 1 byte of data
    char data[1] = {0};
    if(read(file, data, 1) != 1)
    {
        printf("Error : Input/output Error \n");
    }
    else
    {
        // Output to screen
        int data1 = (data[0] & 0xFF);
        
        for(int i=0; i<8; i++)
        {
            if((data1 & ((int)Math.pow(2, i))) == 0)
            {
                printf("I/O Pin %d State is LOW \n", i);
            }
            else
            {
                printf("I/O Pin %d State is HIGH \n", i);
                sleep(0.5);
            }
        }
    }
}

WiredPi bin ich sicher wird auch gehen, wollte ich aber eigentlich nicht verwenden, weil es eventuell nicht weiter entwicklet wird. Mal sehen, vielleicht kommt es doch noch in die engere Wahl und zwar aus folgendem Grund.

Eine wichtige Rolle spielt auch die Geschwindigkeit mit der auf die Bausteine zugegriffen werden kann. Der Zugriff über das Filesystem ist der langsamste. Am besten ist es eine Bibliothek zu verwenden die direkt auf die Bausteine zugreift. Die Geschwindigkeit ist schnell mal um den Faktor 5 schneller. Nun liegt es wohl an der Software wie man die Routinen erstellt. ggf. lässt sich dann mit beiden Alternativen mal Tests machen und dann zeigt sich wer das Rennen gewinnt.