Michael Klein
Published © CC BY-NC-SA

Calliope Mini I2C IO-Expander

Die weltweit erste I2C Grove-Erweiterung mit 16 digitalen Ein-/Ausgängen für den Calliope Mini.

BeginnerFull instructions provided30 minutes465
Calliope Mini I2C IO-Expander

Things used in this project

Hardware components

Calliope mini
Calliope mini
×1
PCBWay Custom PCB
PCBWay Custom PCB
×1

Software apps and online services

Upverter
Upverter

Story

Read more

Custom parts and enclosures

Ausgänge beschaltet

.hex-Datei zum runterladen mit dem passenden Menü.

Schalter (Eingänge beschaltet)

.hex-Datei zum runterladen

GerberfileV1

Gerberdatei zur PCB-Produktion

Schematics

Schaltplan

Code

Schalter (Eingänge beschaltet)

JavaScript
LEDs von Register A werden mit Schaltern von Register B geschaltet.
let Kommentar = ""
Kommentar = " Register A=Ausgabe B=Eingabe stellen"
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.EinOderAusgabe_A, MCP23017.bitwert(BITS.keiner))
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.EinOderAusgabe_B, MCP23017.bitwert(BITS.Alle))
Kommentar = "Pullup-Widerstände für saubere Signalübertragung ein!"
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.PullUp_Widerstaende_A, MCP23017.bitwert(BITS.Alle))
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.PullUp_Widerstaende_B, MCP23017.bitwert(BITS.Alle))
basic.forever(() => {
    if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit1))) {
        MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit1))
    } else {
        if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit2))) {
            MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit2))
        } else {
            if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit3))) {
                MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit3))
            } else {
                if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit4))) {
                    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit4))
                } else {
                    if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit5))) {
                        MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit5))
                    } else {
                        if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit6))) {
                            MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit6))
                        } else {
                            if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit7))) {
                                MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit7))
                            } else {
                                if (MCP23017.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit8))) {
                                    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit8))
                                } else {

                                }
                            }
                        }
                    }
                }
            }
        }
    }
})

Ausgänge beschaltet (LEDs)

JavaScript
Es werden der Reihe nach alle Ausgänge kurz eingeschaltet und hinterher die Dezimalwerte von 0 is 255 in jedes Register geschrieben.
let Kommentar = ""
Kommentar = "Alle Register auf Ausgabe stellen"
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.EinOderAusgabe_A, MCP23017.bitwert(BITS.keiner))
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.EinOderAusgabe_B, MCP23017.bitwert(BITS.keiner))
Kommentar = "Pullup-Widerständ für saubere Signalübertragung ein!"
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.PullUp_Widerstaende_A, MCP23017.bitwert(BITS.Alle))
MCP23017.writeRegister(ADDRESS.A20, REG_MCP.PullUp_Widerstaende_B, MCP23017.bitwert(BITS.Alle))
basic.forever(() => {
    Kommentar = "Ein Bit mit einer 1 beschreiben bedeutet eine LED leuchten lassen"
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit1))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit2))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit3))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit4))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit5))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit6))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit7))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.Bit8))
    basic.pause(250)
    Kommentar = "Alle LEDs von Register A aus!"
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.keiner))
    Kommentar = "Weiter mit den LEDs von Register B"
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit1))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit2))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit3))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit4))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit5))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit6))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit7))
    basic.pause(250)
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.Bit8))
    basic.pause(250)
    Kommentar = "Jetzt wird bei beiden Registern von 0 bis 11111111"
    Kommentar = "= Dezimal 255 gezählt."
    Kommentar = "Dabei entspricht die LED-Anzeige einem Dualzähler!"
    for (let Index = 0; Index <= 255; Index++) {
        MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, Index)
        MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, Index)
        basic.pause(250)
    }
    Kommentar = "Beide Register auf 0 setzen = LEDs aus"
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_A, MCP23017.bitwert(BITS.keiner))
    MCP23017.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, MCP23017.bitwert(BITS.keiner))
})

custom.ts

Typescript
aktualisiertes custom.ts file für des MCP23017-Menü in Makecode
/**
 *  MCP23017-Interfacefunktionen
 */
// Basierend auf der tollen Grundlagenseite 
// http://robert-fromm.info/?post=elec_i2c_calliope
// (cc) Creative Commons Robert Fromm 2017
// Als Makecode / pxt-Paket 17.03.2018 M.Klein v3.02

enum REG_MCP {
    //% Bitmuster um Register A zu beschreiben
    Bitmuster_A = 0x12,
    //% Bitmuster um Register B zu beschreiben
    Bitmuster_B = 0x13,
    //% Aus- / Eingaberichtung des Registers A
    EinOderAusgabe_A = 0x00, //Register stehen standardmäßig auf Eingabe (1111 1111)
    //% Aus- / Eingaberichtung des Registers B
    EinOderAusgabe_B = 0x01,
    //% Pullup Widerstände Register A
    PullUp_Widerstaende_A = 0x0C,
    //% Pullup Widerstände Register B
    PullUp_Widerstaende_B = 0x0D
}

enum ADDRESS {                // Adresse des MCP23017
    //% block=0x20
    A20 = 0x20,               // Standardwert
    //% block=0x21
    A21 = 0x21,               // 
    //% block=0x22
    A22 = 0x22,               // 
    //% block=0x23
    A23 = 0x23,               // 
    //% block=0x24
    A24 = 0x24,               // 
    //% block=0x25
    A25 = 0x25,               // 
    //% block=0x26
    A26 = 0x26,               // 
    //% block=0x27
    A27 = 0x27                // 
}
enum BITS {                    //
    //% block=11111111
    Alle = 0xff,               // 
    //% block=00000000
    keiner = 0x00,             // 
    //% block=00000001
    Bit1 = 0x01,               // 
    //% block=00000010
    Bit2 = 0x02,               // 
    //% block=00000100
    Bit3 = 0x04,               // 
    //% block=00001000
    Bit4 = 0x08,               // 
    //% block=00010000
    Bit5 = 0x10,               // 
    //% block=00100000
    Bit6 = 0x20,                // 
    //% block=01000000
    Bit7 = 0x40,                // 
    //% block=10000000
    Bit8 = 0x80                 // 

}
/**
 * Benutzerdefinierte Blöcke
 */
//% weight=100 color=#0fbc11 icon="\uf2db"

namespace MCP23017 {
    /**
     * Schreibt in ein Register einen bestimmten Bitwert
     * addr: Adresse des MCP23017 (Standard 0x20)
     * reg: Register
     * value: Bitmuster als Dezimalzahl
     */
    //% blockId=Schreiberegister block="Beschreibe an Adresse %addr|das Register %reg|mit dem Wert %value"
    export function writeRegister(addr: ADDRESS, reg: REG_MCP, value: number) {
        pins.i2cWriteNumber(addr, reg * 256 + value, NumberFormat.UInt16BE)
    }

    /**
     * Liest aus Register einen bestimmten Bitwert,
     * verknüpft ihn mit einem Bitmuster und gibt 
     * "Wahr" zurück wenn die Bits gesetzt sind.
     * addr: Adresse des MCP23017 (Standard 0x20)
     * reg: Register
     * value: Bitmuster als Dezimalzahl
     * return: wahr oder falsch
     */

    //% blockId=LiesRegisterNAND block="Lies von Adresse %addr|das Register %reg|und verknüpfe es mit Bitwert %value"
    export function ReadNotAnd(addr: ADDRESS, reg: REG_MCP, value: number): boolean {
        return (!(MCP23017.readRegister(addr, reg) & value))
    }

    /**
     * Bitwert für  alle Ein- bzw. Ausgänge zum auswählen
     */
    //% blockId=alle block="%alle"
    export function bitwert(alle: BITS): number {
        return alle
    }

    //% blockId=LiesRegister block="Lies von Adresse %addr|das Register %reg| aus"
    export function readRegister(addr: ADDRESS, reg: REG_MCP): number {
        pins.i2cWriteNumber(addr, reg, NumberFormat.Int8LE);
        return pins.i2cReadNumber(addr, NumberFormat.Int8LE)
    }
}

Credits

Michael Klein

Michael Klein

41 projects • 52 followers
Na klar Bio! Oder direkt aus dem Garten ;-)
Thanks to Robert Fromm.

Comments