Michael Klein
Published © CC BY-SA

16 Digitale Ein-/Ausgänge am Calliope Mini + Custom Blocks

Ansteuern des MCP23017 mit seinen 16 digitalen Ein- und Ausgängen über I2C und Custom Blocks oder als Makecode-Paket

IntermediateProtip1 hour728
16 Digitale Ein-/Ausgänge am Calliope Mini + Custom Blocks

Things used in this project

Hardware components

MCP23017
×1
Calliope mini
Calliope mini
×1
LED (generic)
LED (generic)
×3
Breadboard (generic)
Breadboard (generic)
×1
Resistor 4.75k ohm
Resistor 4.75k ohm
×2
Resistor 221 ohm
Resistor 221 ohm
×3
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×3

Software apps and online services

MakeCode
Microsoft MakeCode

Story

Read more

Schematics

MCP23017LED.hex

Das passende .hex file mit allem drin und dran

Code

custom.ts

Typescript
Diesen Text in custom.ts kopieren
/**
 *  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=""
namespace custom {
    /**
     * 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 (!(custom.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)
    }
}

MCP23017 LED

JavaScript
Das passende Programm mit Blöcken. Bitte erst custom.ts importieren!
// Alle Ports die 0 sind werden zu Ausgängen
//
// Standardwert ist 1 für alle = Eingänge
custom.writeRegister(ADDRESS.A20, REG_MCP.EinOderAusgabe_B, custom.bitwert(BITS.keiner))
custom.writeRegister(ADDRESS.A20, REG_MCP.PullUp_Widerstaende_A, custom.bitwert(BITS.Alle))
custom.writeRegister(ADDRESS.A20, REG_MCP.PullUp_Widerstaende_B, custom.bitwert(BITS.Alle))
basic.forever(() => {
    if (custom.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_A, custom.bitwert(BITS.Bit1) + custom.bitwert(BITS.Bit2))) {
        custom.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, custom.bitwert(BITS.Bit1) + custom.bitwert(BITS.Bit2))
    } else {
        if (custom.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_A, custom.bitwert(BITS.Bit2))) {
            custom.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, custom.bitwert(BITS.Bit2))
        } else {
            if (custom.ReadNotAnd(ADDRESS.A20, REG_MCP.Bitmuster_A, custom.bitwert(BITS.Bit3))) {
                custom.writeRegister(ADDRESS.A20, REG_MCP.Bitmuster_B, custom.bitwert(BITS.Bit3))
            } else {
                
            }
        }
    }
})
 

MPC23017OhneCustom

JavaScript
Der ganze Spaß in Javascript ohne Customblocks
const ADDR = 0x20;
const REG_IODIRA = 0x00;
const REG_IODIRB = 0x01;
const REG_GPPUA = 0x0C; // Pullup Widerstände einschalten Register A
const REG_GPPUB = 0x0D; // Pullup Widerstände einschalten Register B
const REG_GPIOA = 0x12;
const REG_GPIOB = 0x13;

writeRegister(ADDR, REG_IODIRA, 0xff);
// Register A alle Pins auf Eingang schalten
writeRegister(ADDR, REG_IODIRB, 0xf8);
// 3 Pins als Ausgang (Nullen) schalten 1111 1000
// 1111 1111 0xff   0000 0001 0x01
// 1111 1110 0xfe   0000 0010 0x02
// 1111 1100 0xfc   0000 0100 0x04
// 1111 1000 0xf8   0000 1000 0x08
// 1111 0000 0xf0   0001 0000 0x10
// 1110 0000 0xe0   0010 0000 0x20
// 1100 0000 0xc0   0100 0000 0x40
// 1000 0000 0x80   1000 0000 0x80
// 0000 0000 0x00
writeRegister(ADDR, REG_GPPUB, 0xff);

basic.forever(() => {
    if (!(readRegister(ADDR, REG_GPIOA) & 0x01)) {
        writeRegister(ADDR, REG_GPIOB, 0x01);
    }
     if (!(readRegister(ADDR, REG_GPIOA) & 0x02)) {
         writeRegister(ADDR, REG_GPIOB, 0x02);
     }
     if (!(readRegister(ADDR, REG_GPIOA) & 0x04)) {
        writeRegister(ADDR, REG_GPIOB, 0x04);
    }
})
function writeRegister(addr: number, reg: number, value: number) {
    pins.i2cWriteNumber(addr, reg * 256 + value, NumberFormat.UInt16BE)
}
function readRegister(addr: number, reg: number): number {
    pins.i2cWriteNumber(addr, reg, NumberFormat.Int8LE);
    return pins.i2cReadNumber(addr, NumberFormat.Int8LE)
}

Credits

Michael Klein

Michael Klein

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

Comments