IO Expander สำหรับ ESP32, ESP8266 และ Arduino: 24 ขั้นตอน
IO Expander สำหรับ ESP32, ESP8266 และ Arduino: 24 ขั้นตอน

สารบัญ:

Anonim
Image
Image
บทนำ
บทนำ

คุณต้องการขยาย IO ของ ESP32, ESP8266 หรือ Arduino ของคุณหรือไม่ และคุณได้คิดเกี่ยวกับความเป็นไปได้ของ GPIO ใหม่ 16 ตัวที่สามารถควบคุมได้โดยใช้บัส I2C หรือไม่? วันนี้ฉันจะมาแนะนำคุณเกี่ยวกับ GPIO expander MCP23016 นอกจากนี้ ฉันจะแสดงวิธีสื่อสารไมโครคอนโทรลเลอร์กับ MCP23016 ให้คุณดู ฉันจะพูดถึงการสร้างโปรแกรมที่เราจะใช้ไมโครคอนโทรลเลอร์เพียง 2 พินเพื่อสื่อสารกับเครื่องขยาย เราจะใช้สิ่งเหล่านี้เพื่อควบคุมไฟ LED และปุ่ม

ขั้นตอนที่ 1: บทนำ

อุปกรณ์ MCP23016 มี 16 บิตสำหรับการขยาย GPIO โดยใช้บัส I2C แต่ละบิตสามารถกำหนดค่าแยกกันได้ (อินพุตหรือเอาต์พุต)

MCP23016 ประกอบด้วยการตั้งค่า 8 บิตหลายแบบสำหรับการเลือกอินพุต เอาต์พุต และขั้ว

ตัวขยายเป็นวิธีแก้ปัญหาง่ายๆ เมื่อจำเป็นต้องใช้ IO สำหรับสวิตช์ เซ็นเซอร์ ปุ่ม และ LED รวมถึงตัวอย่างอื่นๆ

ขั้นตอนที่ 2: ลักษณะเฉพาะ

16 ขาเข้า / ขาออก (16 อินพุตมาตรฐาน)

ความถี่สัญญาณนาฬิกาบัส I2C ที่รวดเร็ว (0-400 kbits/s)

หมุดที่อยู่ฮาร์ดแวร์สามตัวอนุญาตให้ใช้อุปกรณ์ได้สูงสุดแปดเครื่อง

Interrupt Port Capture Recorder

ขั้วย้อนกลับลงทะเบียนสำหรับการตั้งค่าขั้วของข้อมูลพอร์ตอินพุต

เข้ากันได้กับไมโครคอนโทรลเลอร์ส่วนใหญ่

ขั้นตอนที่ 3: ESP01 สามารถมี 128 GPIO

ESP01 สามารถมี 128 GPIO!
ESP01 สามารถมี 128 GPIO!

ตัวอย่างที่แสดงขนาดของตัวขยายนี้คือการใช้งานกับ ESP01 ซึ่งสามารถเชื่อมต่อกับตัวขยายได้มากถึงแปดตัวด้วย IOS เพียง 2 ตัว ซึ่งสูงถึง 128 GPIO

ขั้นตอนที่ 4: MCP23016

MCP23016
MCP23016

ที่นี่ เรามีแผนผังของตัวขยายซึ่งมีสองกลุ่มแปดบิต ทำให้มีทั้งหมด 16 พอร์ต นอกจากพินอินเทอร์รัปต์แล้ว ยังมีพิน CLK ซึ่งเชื่อมต่อตัวเก็บประจุและตัวต้านทานซึ่งเชื่อมต่อภายในในพอร์ตลอจิก นี่คือการสร้างนาฬิกาโดยใช้แนวคิดของคริสตัลออสซิลเลเตอร์ซึ่งต้องการนาฬิกา 1MHz TP pin ใช้สำหรับวัดนาฬิกา พิน A0, A1 และ A2 เป็นที่อยู่ไบนารี

ขั้นตอนที่ 5: CLOCK

นาฬิกา
นาฬิกา
นาฬิกา
นาฬิกา

MCP23016 จึงใช้วงจร RC ภายนอกเพื่อกำหนดความเร็วของนาฬิกาภายใน จำเป็นต้องมีนาฬิกาภายใน 1 MHz (ปกติ) เพื่อให้อุปกรณ์ทำงานได้อย่างถูกต้อง นาฬิกาภายในสามารถวัดได้ที่ขา TP ค่าที่แนะนำสำหรับ REXT และ CEXT แสดงอยู่ด้านล่าง

ขั้นตอนที่ 6: ที่อยู่

ในการกำหนดที่อยู่ของ MCP23016 เราจะใช้หมุด A0, A1 และ A2 เพียงปล่อยไว้ที่ HIGH หรือ LOW เพื่อเปลี่ยนที่อยู่

ที่อยู่จะถูกสร้างขึ้นดังนี้:

MCP_Address = 20 + (A0 A1 A2)

โดยที่ A0 A1 A2 สามารถรับค่า HIGH / LOW ได้ ค่านี้จะสร้างเลขฐานสองตั้งแต่ 0 ถึง 7

ตัวอย่างเช่น:

A0> GND, A1> GND, A2> GND (หมายถึง 000 แล้ว 20 + 0 = 20)

หรืออย่างอื่น, A0> สูง, A1> GND, A2> สูง (ความหมาย 101 จากนั้น 20 + 5 = 25)

ขั้นตอนที่ 7: คำสั่ง

คำสั่ง
คำสั่ง

ด้านล่างเป็นตารางคำสั่งสำหรับการสื่อสาร ลองใช้ GP0 และ GP1 รวมทั้ง IODIR0 และ IODIR1

ขั้นตอนที่ 8: หมวดหมู่:

GP0 / GP1 - รีจิสเตอร์พอร์ตข้อมูล

มีรีจิสเตอร์สองตัวที่ให้การเข้าถึงพอร์ต GPIO สองพอร์ต

การอ่านค่ารีจิสเตอร์แสดงสถานะของพินบนพอร์ตนั้น

บิต = 1> สูง บิต = 0> ต่ำ

OLAT0 / OLAT1 - การลงทะเบียน LACTCH เอาต์พุต

มีรีจิสเตอร์สองตัวที่ให้การเข้าถึงพอร์ตเอาต์พุตของทั้งสองพอร์ต

IPOL0 / IPOL1 - รีจิสเตอร์ขั้วอินพุต

รีจิสเตอร์เหล่านี้อนุญาตให้ผู้ใช้กำหนดค่าขั้วของข้อมูลพอร์ตอินพุต (GP0 และ GP1)

IODIR0 / IODIR1

มีรีจิสเตอร์สองตัวที่ควบคุมโหมดพิน (อินพุตหรือเอาต์พุต)

บิต = 1> อินพุต บิต = 0> เอาต์พุต

INTCAP0 / INTCAP1 - Interrupt Capture Registers

เหล่านี้เป็นรีจิสเตอร์ที่มีค่าของพอร์ตที่สร้างการขัดจังหวะ

IOCON0 / IOCON1 - I / O Expander Control Register

สิ่งนี้ควบคุมการทำงานของ MCP23016

การตั้งค่าบิต 0 (IARES> ความละเอียดของกิจกรรมการขัดจังหวะ) จะควบคุมความถี่การสุ่มตัวอย่างของพินพอร์ต GP

Bit0 = 0> (ค่าเริ่มต้น) เวลาการตรวจจับกิจกรรมพอร์ตสูงสุดคือ 32ms (ใช้พลังงานต่ำ)

Bit0 = 1> เวลาการตรวจจับกิจกรรมสูงสุดบนพอร์ตคือ 200usec (การใช้พลังงานสูงกว่า)

ขั้นตอนที่ 9: โครงสร้างเพื่อการสื่อสาร

โครงสร้างเพื่อการสื่อสาร
โครงสร้างเพื่อการสื่อสาร

ฉันแสดงคลาส Wire ที่นี่ซึ่งเป็นการสื่อสาร I2C ใน Arduino หลักของเรา ซึ่งช่วยให้ตัวขยายสามารถทำงานกับ Arduino Uno และ Mega อย่างไรก็ตาม หลังมี IO หลายตัวอยู่แล้ว เราจัดการที่นี่กับที่อยู่ของชิป การควบคุมการเข้าถึง ซึ่งเป็นรหัสของรีจิสเตอร์ เช่นเดียวกับข้อมูล

ขั้นตอนที่ 10: โปรแกรม

โปรแกรม
โปรแกรม

โปรแกรมของเราประกอบด้วยการสื่อสาร ESP32 กับ MCP23016 เพื่อให้มี GPIO มากขึ้น จากนั้นเราจะมีปุ่มและไฟ LED บางดวงเชื่อมต่อกับ MCP23016 เราจะควบคุมพวกมันทั้งหมดโดยใช้บัส I2C เท่านั้น ดังนั้นจะใช้เพียงสองพิน ESP32 เท่านั้น คุณสามารถดูวงจรภาพด้านล่างในวิดีโอ

ขั้นตอนที่ 11: ESP01

ESP01
ESP01

ที่นี่ ฉันแสดง Pinout ของ ESP01

ขั้นตอนที่ 12: การติดตั้ง ESP01

การติดตั้ง ESP01
การติดตั้ง ESP01

ในตัวอย่างนี้ เรามี GPIO0 ที่เชื่อมต่ออยู่ใน SDA และ GPIO2 เชื่อมต่ออยู่ใน SCL เรายังมีบอร์ดรีเลย์ ออด และไฟ LED อีกพอร์ตหนึ่งใน GP1.0 เรามี LED อีกหนึ่งตัวที่มีตัวต้านทาน

ขั้นตอนที่ 13: NodeMCU ESP-12E

NodeMCU ESP-12E
NodeMCU ESP-12E

ที่นี่ เรามี Pinout ของ NodeMCU ESP-12E

ขั้นตอนที่ 14: การติดตั้ง NodeMCU ESP-12E

การติดตั้ง NodeMCU ESP-12E
การติดตั้ง NodeMCU ESP-12E

ในกรณีนี้ ข้อแตกต่างเพียงอย่างเดียวจากตัวอย่างแรกคือคุณได้เชื่อมต่อ D1 และ D2 ใน SDA และ SCL ตามลำดับ

ขั้นตอนที่ 15: WiFi NodeMCU-32S ESP-WROOM-32

WiFi NodeMCU-32S ESP-WROOM-32
WiFi NodeMCU-32S ESP-WROOM-32

นี่คือ Pinout ของ WiFi NodeMCU-32S ESP-WROOM-32

ขั้นตอนที่ 16: การติดตั้ง WiFi NodeMCU-32S ESP-WROOM-32

การติดตั้ง WiFi NodeMCU-32S ESP-WROOM-32
การติดตั้ง WiFi NodeMCU-32S ESP-WROOM-32

คราวนี้ ความแตกต่างหลักจากอีกสองตัวอย่างคือปุ่มและไฟ LED กะพริบสามดวง ที่นี่ SDA เชื่อมต่อกับ GPIO19 ในขณะที่ SCL เชื่อมต่อกับ GPIO23

ขั้นตอนที่ 17: ไลบรารีและตัวแปร

อันดับแรก เราจะรวม Wire.h ซึ่งรับผิดชอบการสื่อสาร i2c และการตั้งค่าที่อยู่ i2c ของ MCP23016 ฉันแสดงคำสั่งหลายคำสั่ง แม้แต่บางคำสั่งที่เราไม่ได้ใช้ในโครงการนี้

#include // ระบุการใช้งานไลบรารี Wire.h //endereço I2C do MCP23016 #define MCPAddress 0x20 // COMMAND BYTE TO REGISTER RELATIONSHIP: ตาราง: 1-3 ของ Microchip MCP23016 - DS20090A //ENDEREÇOS DE REGISTRADORES #define GP0 0x00 // การลงทะเบียนพอร์ตข้อมูล 0 #x01 DATA // 0 #define GP PORT REGISTER 1 #define OLAT0 0x02 // OUTPUT LATCH REGISTER 0 #define OLAT1 0x03 // OUTPUT LATCH REGISTER 1 #define IPOL0 0x04 // INPUT POLARITY PORT REGISTER 0 #define IPOL1 0x05 // INPUT POLARITY PORT REGISTER0 #กำหนด / I/O DIRECTION REGISTER 0 #define IODIR1 0x07 // I/O DIRECTION REGISTER 1 #define INTCAP0 0x08 // INTERRUPT CAPTURE REGISTER 0 #define INTCAP1 0x09 // INTERRUPT CAPTURE REGISTER 1 #define IOCON0 0x0A // I/O EXPANDER CONTROL ลงทะเบียน 0 #define IOCON1 0x0B // I/O EXPANDER CONTROL REGISTER 1

ขั้นตอนที่ 18: ตั้งค่า

ที่นี่ เรามีฟังก์ชันเพื่อเริ่มต้นไมโครคอนโทรลเลอร์สี่ประเภทที่แตกต่างกัน เรายังตรวจสอบความถี่ ตั้งค่า GPIO และตั้งค่าพิน ในลูป เราจะตรวจสอบสถานะของปุ่ม

การตั้งค่าเป็นโมฆะ () { Serial.begin (9600); ล่าช้า (1000); Wire.begin(19, 23); //ESP32 // Wire.begin(D2, D1); //nodemcu ESP8266 // Wire.begin(); //arduino // Wire.begin(0, 2); // ESP-01 Wire.setClock(200000); // frequencia //configura o GPIO0 como OUTPUT (todos os pinos) กำหนดค่าพอร์ต (IODIR0, OUTPUT); //configura o GPIO1 como INPUT o GP1.0 e como OUTPUT ระบบปฏิบัติการ GP1 กำหนดค่าพอร์ต (IODIR1, 0x01); // seta todos os pinos ทำ GPIO0 como LOW writeBlockData(GP0, B00000000); // seta todos os pinos ทำ GPIO1 como LOW writeBlockData(GP1, B00000000); } วงเป็นโมฆะ () { //verifica e o botão GP foi pressionado checkButton (GP1); } // จบลูป

ขั้นตอนที่ 19: กำหนดค่าพอร์ต

ในขั้นตอนนี้ เรากำหนดค่าโหมดของพิน GPIO และระบุโหมดของพอร์ต

//configura o GPIO (GP0 ou GP1)//como parametro passamos: //port: GP0 ou GP1 //custom: INPUT para todos เป็น portas do GP trabalharem como entrada // OUTPUT para todos เป็น portas do GP trabalharem como saida / / กำหนดเอง um valor de 0-255 indicando o modo das portas (1=INPUT, 0=OUTPUT) // เช่น: 0x01 ou B00000001 ou 1: indica que apenas o GPX.0 trabalhará como entrada o restando como saida void configurationPort(พอร์ต uint8_t, uint8_t กำหนดเอง) { ถ้า (กำหนดเอง == INPUT) {writeBlockData (พอร์ต, 0xFF); } else if (กำหนดเอง == OUTPUT) {writeBlockData (พอร์ต, 0x00); } อื่น ๆ { writeBlockData (พอร์ต กำหนดเอง); } }

ขั้นตอนที่ 20: WriteBlockData & CheckButton

ที่นี่เราส่งข้อมูลไปยัง MCP23016 ผ่านบัส i2c ตรวจสอบสถานะของปุ่มและระบุขั้นตอนต่อไปโดยคำนึงถึงสภาพการกดหรือไม่

//envia dados para o MCP23016 através do barramento i2c//cmd: COMANDO (registrador) //data: dados (0-255) เป็นโมฆะ writeBlockData (uint8_t cmd, uint8_t data) { Wire.beginTransmission (MCPAddress); Wire.write(cmd); Wire.write (ข้อมูล); Wire.endTransmission(); ล่าช้า(10); }

// ยืนยัน se o botão foi pressionado // parametro GP: GP0 ou GP1 void checkButton (uint8_t GP) { // faz a leitura do pino 0 no GP fornecido uint8_t btn = readPin (0, GP); //se botão pressionado, seta para HIGH เป็น portas GP0 if(btn) {writeBlockData(GP0, B11111111); } //caso contrario deixa todas em estado LOW อื่น {writeBlockData(GP0, B00000000); } }

ขั้นตอนที่ 21: ReadPin & ValueFromPin

เราจัดการกับการอ่านพินเฉพาะและการคืนค่าบิตไปยังตำแหน่งที่ต้องการ

// faz a leitura de um pino específico//pin: pino desejado (0-7) //gp: GP0 ou GP1 // retorno: 0 ou 1 uint8_t readPin (uint8_t pin, uint8_t gp) { uint8_t statusGP = 0; Wire.beginTransmission(MCPAที่อยู่); Wire.write(gp); Wire.endTransmission(); Wire.requestFrom(MCPAที่อยู่, 1); // ler do chip 1 ไบต์ statusGP = Wire.read(); คืนค่าจากพิน (พิน, statusGP); } // retorna o valor do bit na posição desejada //pin: posição do bit (0-7) //statusGP: valor lido do GP (0-255) uint8_t valueFromPin (uint8_t pin, uint8_t statusGP) { return (statusGP & (0x0001 << พิน)) == 0 ? 0: 1; }

ขั้นตอนที่ 22: โปรแกรม ESP8266

จากที่นี่เราจะมาดูกันว่าโปรแกรมที่เราใช้ใน ESP-01 และใน nodeMCU ESP-12E ถูกสร้างขึ้นอย่างไร ซึ่งช่วยให้เราเข้าใจว่าความแตกต่างระหว่างทั้งสองมีน้อยเพียงใด

เราจะแก้ไขเฉพาะบรรทัดของตัวสร้างการสื่อสาร i2c ซึ่งเป็นวิธีการเริ่มต้นของวัตถุ Wire

เพียงแค่ uncomment บรรทัดตามจานที่เราจะรวบรวม

// Wire.begin(D2, D1); //nodemcu ESP8266// Wire.begin(0, 2); //ESP-01

ติดตั้ง

สังเกตว่าผู้สร้างยังคงแสดงความคิดเห็น ดังนั้น ให้ยกเลิกความคิดเห็นตามบอร์ดของคุณ (ESP-01 หรือ nodeMCU ESP12-E)

การตั้งค่าเป็นโมฆะ () { Serial.begin (9600); ล่าช้า (1000); // Wire.begin(D2, D1); //nodemcu ESP8266 // Wire.begin(0, 2); //ESP-01 Wire.setClock (200000); // frequencia //configura o GPIO0 como OUTPUT (todos os pinos) กำหนดค่าพอร์ต (IODIR0, OUTPUT); //configura o GPIO1 como OUTPUT (todos os pinos) กำหนดค่าพอร์ต (IODIR1, OUTPUT); // seta todos os pinos ทำ GPIO0 como LOW writeBlockData(GP0, B00000000); // seta todos os pinos ทำ GPIO1 como LOW writeBlockData(GP1, B00000001); }

ห่วง

ในลูป เราสลับพินทุกๆ 1 วินาที ดังนั้น เมื่อเปิด pin0 ของ GP0 หมุดของ GP1 จะปิด เมื่อ pin0 ของ GP1 เปิดอยู่ หมุด GP0 จะถูกปิด

วงเป็นโมฆะ () {// seta o pino 7 do GP0 como HIGH e os demais como LOW writeBlockData (GP0, B10000000); // seta todos os pinos ทำ GPIO1 como LOW writeBlockData(GP1, B00000000); ล่าช้า (1000); // seta todos os pinos ทำ GPIO0 como LOW writeBlockData(GP0, B00000000); //seta o pino 0 do GP1 como HIGH e os demais como LOW writeBlockData(GP1, B00000001); ล่าช้า (1000); } // จบลูป

ขั้นตอนที่ 23: สำคัญ

ตัวแปรและไลบรารีที่ใช้เหมือนกับของโปรแกรมที่เราทำสำหรับ ESP32 เช่นเดียวกับวิธี configurationPort และ writeBlockData

ขั้นตอนที่ 24: ไฟล์

ดาวน์โหลดไฟล์:

ไฟล์ PDF

INO (ESP8266)

INO (ESP32)

แนะนำ: