0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何僅在兩個Aduino之間進(jìn)行2路I2C通信

454398 ? 來源:網(wǎng)絡(luò)整理 ? 作者:網(wǎng)絡(luò)整理 ? 2019-11-25 15:16 ? 次閱讀

步驟1:您需要什么:

我們假設(shè)您具有以下部分:

兩個Arduino UNO

一些公對母電線

一些公對公電線

一個旋轉(zhuǎn)電位計

一個面包板

步驟2:I2C的工作方式

I2C是一種通信協(xié)議,使您可以在微控制器和某些傳感器等電路之間進(jìn)行通信。它僅使用兩根線(如此高效?。5谝痪€是時鐘線,通常在文檔中寫為SCL。第二根線是數(shù)據(jù)線,通常寫為SDA。

I2C總線上的設(shè)備可以是“主機(jī)”或“從機(jī)”。僅主機(jī)控制時鐘線上的電壓,而主機(jī)和從機(jī)都可以操縱數(shù)據(jù)線上的電壓。通過仔細(xì)輪流,網(wǎng)絡(luò)上的所有設(shè)備都可以共享信息

為了將信息發(fā)送到正確的位置,每個從站都有一個唯一的地址號碼,就像每個電話都有一個唯一的號碼一樣。

當(dāng)我看到I2C器件時,他們有文檔說:“該電路希望接收N字節(jié)表示ABC的數(shù)據(jù),并發(fā)送回M字節(jié)表示DEF的數(shù)據(jù)?!比绻徺I的設(shè)備不包含此信息,則不要購買。

有關(guān)I2C通信內(nèi)部工作的更多詳細(xì)信息,請查看以下鏈接:

http://www.robot-electronics.co.uk/i2c-tutorial

http://www.i2c-bus.org/結(jié)果

https://en.wikipedia.org/wiki/I%C2%B2C

步驟3:設(shè)置

上圖中的設(shè)備使用引腳A4和A5進(jìn)行I2C通信。每種類型的arduino和Wire庫的I2C引腳說明如下:

https://www.arduino.cc/zh/Reference/Wire

主設(shè)置看起來像這樣:

#include

void setup() {

// note that begin() has no parameter.

Wire.begin();

}

從站設(shè)置看起來像這樣:

#include

void setup() {

// note that begin() has a parameter.

// Any number from 0.。..127 will work.

Wire.begin(1);

}

如果您要在該網(wǎng)絡(luò)上使用第二個從站,則需要除#1外的地址,因為該地址已被使用。這意味著只能通過仔細(xì)計劃來添加和刪除網(wǎng)絡(luò)上的設(shè)備。許多使用I2C的設(shè)備都將帶有一個帶撥碼開關(guān)(小光開關(guān))的PCB,可以將其撥動以更改地址。便宜的型號將有裸露的接觸。要翻轉(zhuǎn)這些開關(guān),必須觸摸裸觸點(diǎn)。

第4步:發(fā)送數(shù)據(jù)

與之交談的人,然后發(fā)送信息,然后說“我完成了?!?/p>

void loop() {

Wire.beginTransmission(1);

Wire.write(“hello, ”);

Wire.endTransmission();

}

從站僅需發(fā)送信息。每個人都假定從服務(wù)器正在與主機(jī)通信。

void loop() {

Wire.write(“world!”);

}

Wire.write()具有三個版本:一個用于單個數(shù)字,一個用于字符串,以及一個用于數(shù)據(jù)塊。您必須告訴Wire數(shù)據(jù)塊有多長時間。

步驟5:接收數(shù)據(jù)

主機(jī)可以使用

Wire.read()

從網(wǎng)絡(luò)獲取單個字節(jié)的數(shù)據(jù),而不管是誰發(fā)送的。

Wire.read()是阻塞操作-您的Arduino在讀取一個字節(jié)之前不會做其他任何事情。如果沒有要讀取的字節(jié),則可能要等待很長時間!為避免此問題,還有

Wire.available()

將返回等待讀取的字節(jié)數(shù)。

將兩者放在一起,

while(Wire.available()) {

char c = Wire.read();

// do something with c

// maybe count how much we received,

// do something when we get the whole message.

}

// do other stuff while we wait for the whole message.

第6步:請求/接收

您已經(jīng)擁有運(yùn)行I2C網(wǎng)絡(luò)所需的一切,但是我想讓您了解另外一項功能,這有點(diǎn)棘手,所以請忍受我。實際上,我會說這完全是不需要,但是我將其包括在內(nèi)是為了徹底。也許表明有很多方法可以完成相同的工作,有些方法比其他方法更好。

您已經(jīng)知道,在C代碼中,有諸如setup()和loop()之類的方法。您也可以創(chuàng)建自己的方法并按名稱調(diào)用它們。您是否知道可以將方法名稱作為參數(shù)發(fā)送給另一個方法?通常用于稱為回調(diào)的東西。在這種情況下,我們將告訴線庫(I2C)當(dāng)從站從網(wǎng)絡(luò)接收數(shù)據(jù)時調(diào)用哪種方法。

// a master is calling and requesting something.

void requestEvent() {

// definitely send something back.

Wire.write(2); // one byte as an example.

}

// a master has sent something.

// Might not be requesting anything.

// Might not be all the data that was sent (yet)

void receiveEvent(int bytes) {

int i;

for(i=0;i char c = Wire.read();

// do something with c.

}

// maybe send something back

}

void setup() {

Wire.begin(1); // slave address = 1

Wire.onRequest(requestEvent);

Wire.onReceive(receiveEvent);

}

void loop() {

// do nothing!

}

此處的一些注意事項:

requestEvent()不會收到數(shù)字,說明主機(jī)期望多少字節(jié)。

據(jù)我所知,這些事件是中斷-無論loop()中發(fā)生了什么,它們都會盡快發(fā)生。如果時間和代碼正確,那么無論循環(huán)做什么,都可能會嚴(yán)重混亂。由于很難重新創(chuàng)建導(dǎo)致問題的條件,因此很難診斷出它為什么混亂。

因此,正如我所說的,盡管您可以使用這些工具,但我不建議您這樣做

第7步:雙向通信

現(xiàn)在讓我們將它們放在一起。

主代碼:

#include

#define TO_MASTER_SIZE 3

#define TO_SLAVE_SIZE 4

#define START_NODE 1 // The starting I2C address of slave nodes

#define END_NODE 2 // last node to probe +1

#define NODE_READ_DELAY 100 // Some delay between I2C node reads

byte messageToMaster[TO_MASTER_SIZE];

byte messageToSlave[TO_SLAVE_SIZE];

void setup() {

Serial.begin(9600);

Serial.println(“MASTER”);

Wire.begin(); // Activate I2C link

}

void loop() {

for (int address = START_NODE; address 《 END_NODE; address++) {

sendToSlave(address);

readFromSlave();

}

delay(NODE_READ_DELAY);

}

void sendToSlave(int address) {

// message is 0123

for(int i = 0; i 《 SEND_SIZE; i++) {

messageToSlave[i] = (byte)i;

}

Wire.beginTransmission(address);

Wire.write(messageToSlave, TO_SLAVE_SIZE);

Wire.endTransmission();

}

void readFromSlave() {

// if data size is available from nodes

if(Wire.available() == TO_MASTER_SIZE) {

for (int i = 0; i 《 TO_MASTER_SIZE; i++) {

messageToMaster[i] = Wire.read(); // get data

}

int fromAddress = messageToMaster[0];

int value = ((int)messageToMaster[1] 《《 8 ) | (int)messageToMaster[2];

Serial.print(“Slave ”);

Serial.print(fromAddress);

Serial.print(“ says ”);

Serial.print(value);

}

}

從站代碼:

#include

// Change this unique address for each I2C slave node

#define NODE_ADDRESS 1

// matches values on master side.

#define TO_MASER_SIZE 3

#define TO_SLAVE_SIZE 4

#define NODE_READ_DELAY 100

byte messageToMaster[TO_MASTER_SIZE];

byte nodeReceive[TO_SLAVE_SIZE];

void setup() {

Serial.begin(9600);

Serial.print(“SLAVE #”);

Serial.println(NODE_ADDRESS);

Wire.begin(NODE_ADDRESS); // Activate I2C network

}

void loop() {

delay(NODE_READ_DELAY);

if(Wire.avaialable() == TO_SLAVE_SIZE) {

readFromMaster();

sendToMaster();

}

}

void readFromMaster() {

for(int i = 0; i 《 TO_SLAVE_SIZE; i ++){

nodeReceive[i] = Wire.read();

}

Serial.print(“Master says ”);

for(int i = 0; i 《 TO_SLAVE_SIZE; i ++){

Serial.print(nodeReceive[i]);

}

Serial.println();

}

void sendToMaster() {

int x = analogRead(A0);

messageToMaster[0] = NODE_ADDRESS;

messageToMaster[1] = (x0》》8) & 0xff; // the top byte of x

messageToMaster[2] = (x0 ) & 0xff; // the bottom byte of x

Wire.write(messageToMaster,TO_MASTER_SIZE);

Serial.print(“Sensor value: ”);

Serial.println(x);

}

有趣的一點(diǎn)是,總線(網(wǎng)絡(luò))上的任何人都可以收聽雙向通信。從理論上講,可以添加一個靜默設(shè)備,其唯一的工作就是監(jiān)視網(wǎng)絡(luò)。

第8步:最終想法

單個I2C網(wǎng)絡(luò)可能有多個主機(jī),但這是多余的棘手的問題–主機(jī)之間必須進(jìn)行協(xié)商以避免彼此之間的交談,這會導(dǎo)致混亂。

責(zé)任編輯:wv

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • aduino
    +關(guān)注

    關(guān)注

    0

    文章

    3

    瀏覽量

    3445
收藏 人收藏

    評論

    相關(guān)推薦

    TPA6130A2如果不需要I2C功能,是否可以將I2C兩個引腳懸空?

    如果不需要I2C功能,是否可以將I2C兩個引腳懸空。 2.如果將I2C兩個引腳懸空,該IC是否
    發(fā)表于 11-01 08:16

    ad如何設(shè)置兩個元器件的距離

    之間應(yīng)保持的最小距離,以確保電路板的電氣性能和制造過程的可靠性。以下是如何在AD中設(shè)置兩個元器件之間距離的步驟: 一、進(jìn)入規(guī)則設(shè)置界面 打開AD軟件 :首先,確保你已經(jīng)打開了Altium Designer軟件,并加載了需要
    的頭像 發(fā)表于 09-02 15:31 ?4190次閱讀

    簡單認(rèn)識I2C通信協(xié)議

    I2C(Inter-Integrated Circuit)通信協(xié)議是由飛利浦公司(現(xiàn)為恩智浦半導(dǎo)體)開發(fā)的一種簡單、雙向二線制同步串行總線協(xié)議。自1982年發(fā)布以來,I2C協(xié)議因其高效、靈活和易于實現(xiàn)的特點(diǎn),在電子設(shè)備間的數(shù)據(jù)交
    的頭像 發(fā)表于 07-25 18:06 ?1248次閱讀

    兩個ESP8266模塊之間如何進(jìn)行TCP通信?

    嗨,我有兩個ESP8266模塊,我希望它們之間進(jìn)行TCP通信。 我已經(jīng)編寫了固件,將一 ESP 配置為 AccessPoint,另一
    發(fā)表于 07-12 06:26

    使用UDP廣播在兩個ESP8266之間進(jìn)行通信,發(fā)送會存在延遲是怎么回事?

    我正在使用 UDP 廣播在兩個ESP8266 (wemos) 之間進(jìn)行通信。 作為測試,我只是從第一設(shè)備發(fā)送 10 個字節(jié),第二
    發(fā)表于 07-11 06:27

    兩個PLC之間如何交互信號

    在工業(yè)自動化系統(tǒng)中,PLC(Programmable Logic Controller,可編程邏輯控制器)是核心的控制設(shè)備。在許多復(fù)雜的應(yīng)用場景中,需要兩個或多個PLC之間進(jìn)行信號交互,以實現(xiàn)更高
    的頭像 發(fā)表于 06-14 16:57 ?3475次閱讀

    兩個銅片可以形成原電池嗎

    兩個銅片本身不能形成原電池,因為原電池的工作原理依賴于兩個不同電位的電極材料之間的氧化還原反應(yīng)。
    的頭像 發(fā)表于 05-21 16:23 ?778次閱讀

    I3C接口通信基礎(chǔ)

    I 2 CI3C之間顯著的變化是時鐘速度。I 2
    發(fā)表于 05-03 10:22 ?3365次閱讀
    <b class='flag-5'>I3C</b>接口<b class='flag-5'>通信</b>基礎(chǔ)

    什么是I3C接口 I3C和SPI接口有什么區(qū)別

    I3C接口使用通信線,一根是數(shù)據(jù)線(SDL),另一根是時鐘線(SCL)。與I2C總線一樣,I3C接口也支持多主設(shè)備(Main Maste
    的頭像 發(fā)表于 03-05 16:50 ?2607次閱讀
    什么是<b class='flag-5'>I3C</b>接口 <b class='flag-5'>I3C</b>和SPI接口有什么區(qū)別

    arcgis中如何關(guān)聯(lián)兩個屬性表

    在ArcGIS中,關(guān)聯(lián)兩個屬性表是一重要的操作,可以通過此操作將兩個表中的數(shù)據(jù)關(guān)聯(lián)起來,以便進(jìn)行分析和查詢。下面是詳細(xì)介紹如何在ArcGIS中實現(xiàn)屬性表的關(guān)聯(lián)。 首先,我們需要明確
    的頭像 發(fā)表于 02-25 11:01 ?3922次閱讀

    使用片ADU360進(jìn)行I2C通信,當(dāng)與從機(jī)進(jìn)行通信時,從機(jī)無法進(jìn)入I2C中斷是為什么?

    問題說明:使用片ADU360進(jìn)行I2C通信,主機(jī)使用IO口模擬方式,從機(jī)使用內(nèi)部外設(shè) 主機(jī)IO口模擬方式,確認(rèn)是可行,當(dāng)與從機(jī)進(jìn)行
    發(fā)表于 01-15 06:47

    i2c接口和spi接口區(qū)別

    重要的區(qū)別。 I2C接口和SPI接口都屬于串行通信接口標(biāo)準(zhǔn),廣泛應(yīng)用在嵌入式系統(tǒng)和電子設(shè)備中。它們之間的主要區(qū)別在于通信協(xié)議、電氣特性、速度和適用場景等方面。
    的頭像 發(fā)表于 12-25 15:02 ?3678次閱讀

    如何給C語言中的函數(shù)定義兩個不同的名字?

    最近有位哥問我,如何給C語言中的函數(shù)定義兩個不同的名字?就是這兩個名字都是指向同一函數(shù),同一地址,而且
    的頭像 發(fā)表于 12-19 16:21 ?716次閱讀

    i2c工作原理及使用方法

    的標(biāo)準(zhǔn)。 I2C協(xié)議具有以下特點(diǎn): 簡單:I2C使用根線(數(shù)據(jù)線SDA和時鐘線SCL)進(jìn)行通信,極大地簡化了連接的線路。 多主機(jī):支持多個
    的頭像 發(fā)表于 12-19 16:17 ?1171次閱讀

    兩個硬盤2系統(tǒng)開機(jī)切換

    切換兩個硬盤上的系統(tǒng)是一種常見的行為,可以讓用戶在不同的操作系統(tǒng)之間進(jìn)行切換,以滿足不同的需求。在本文中,我們將詳細(xì)介紹如何配置和使用兩個硬盤上的系統(tǒng)
    的頭像 發(fā)表于 11-28 15:08 ?7193次閱讀