2012-11-01 100 views
9

我在嘗試一個I²C設置,其中一個主Arduino控制兩個從機。啓動後ArduinoI²C死機

Enter image description here

我使用的I²C2個2000歐姆的上拉電阻和所有的板是Arduino Duemilanoves。 I²C設置和控制設置在互相斷開連接時都能正常工作,但在連接時,只要調用第一個wire.write函數,Arduin就會變得無響應。我停止接收串行消息,從設備Arduinos停止接收來自主設備的消息,並且我失去了使用按鈕打開和關閉系統的能力。

我試過在每個wire.write函數之後添加短暫的延遲,並嘗試使用各種上拉電阻來解決問題,但似乎沒有任何效果。我怎樣才能解決這個問題?

主碼:

#include <Wire.h> 

int potPin1 = 0; // Select the input pin for the potentiometer 
int potPin2 = 1; 
int potVal1;  // Variable to store the value coming from the sensor 
int potVal2; 
int times=0; // All the below variables are used to control an on-off button 
int state=0; 
int lastState=0; 
boolean pot=false; 

void setup() 
{ 
    pinMode(13, OUTPUT); //LED that turns on when system is activated 
    pinMode(3, INPUT); //Button that turns on system 
    Serial.begin(9600); 
    Wire.begin(); 
} 

void loop(){ 
    state=digitalRead(3); 
    if(state != lastState){ 
     if(state==HIGH){ 
      times++; 
      Serial.println(times); 
     } 
     else{ 
      Serial.println("off"); 
     } 
    } 

    lastState=state; 

    if(times%2 ==1) 
    { 
     turnPotOn(); 
    } 
    else 
    { 
     turnPotOff(); 
    } 

//在循環到這一點的所有代碼打開系統和關閉按下按鈕。 //下面的代碼對應於基於電位計讀數的I²C。

if(pot==true) 
    { 
     potVal1 = analogRead(potPin1); // Read the value from the sensor 
     potVal2 = analogRead(potPin2); 

     if((potVal1>700) && (300<potVal2) && (potVal2<700)) 
     { 
      arduino1_motor1(); 
     } 
     else if ((potVal1<330) && (336<potVal2) && (potVal2<683)) 
     { 
      arduino1_motor2(); 
     } 
     else if ((potVal2>683) && (330<potVal1) && (potVal1<640)) 
     { 
      arduino2_motor3(); 
     } 
     else if ((potVal2<336) && (330<potVal1) && (potVal1<640)) 
     { 
      arduino2_motor4(); 
     } 
     else if ((potVal2<336) && (potVal1<330)) 
     { 
      arduino12_motor24(); 
     } 
     else if ((potVal2>683) && (potVal1>640)) 
     { 
      arduino12_motor23(); 
     } 
     else if ((potVal2>683) && (potVal1<640)) 
     { 
      arduino11_motor23(); 
     } 
     else if ((potVal2<336) && (potVal1>330)) 
     { 
      arduino11_motor24(); 
     } 
     else 
     { 
      arduino12_still(); 
     } 
    } 
    else 
    { 
     // arduino1_still(); 
     // arduino2_still(); 
     Serial.println("OFF"); 
    } 
} 

void turnPotOff() 
{ 
    digitalWrite(13, LOW); 
    pot=false; 
} 

void turnPotOn() 
{ 
    digitalWrite(13, HIGH); 
    pot=true; 
} 

void arduino1_motor1() 
{ 
    Wire.beginTransmission(5); 
    Wire.write('A'); 
    Wire.endTransmission(); 
    arduino2_still(); 
    Serial.println("A1 in M1 d"); 
} 

void arduino1_motor2() 
{ 
    Wire.beginTransmission(5); 
    Wire.write('B'); 
    Wire.endTransmission(); 
    arduino2_still(); 
    Serial.println("A1 in m2 d"); 
} 

void arduino12_still() 
{ 
    arduino1_still(); 
    arduino2_still(); 
    Serial.println("A1 & A2 stl"); 
} 

void arduino2_motor3() 
{ 
    arduino1_still(); 
    Wire.beginTransmission(10); 
    Wire.write('M3'); 
    Wire.endTransmission(); 
    Serial.println("A2 in M3 d"); 
} 

void arduino2_motor4() 
{ 
    arduino1_still(); 
    Wire.beginTransmission(10); 
    Wire.write('D'); 
    Wire.endTransmission(); 
    Serial.println("A2 in M4 d"); 
} 

void arduino12_motor24() 
{ 
    Wire.beginTransmission(5); 
    Wire.write('B'); 
    Wire.endTransmission(); 
    Wire.beginTransmission(10); 
    Wire.write('D'); 
    Wire.endTransmission(); 
    Serial.println("A1 & A2 in M2 and M4 d"); 
} 

void arduino12_motor23() 
{ 
    Wire.beginTransmission(5); 
    Wire.write('B'); 
    Wire.endTransmission(); 
    Wire.beginTransmission(10); 
    Wire.write('C'); 
    Wire.endTransmission(); 
    Serial.println("A1 & A2 in M2 and M3 d"); 
} 

void arduino11_motor24() 
{ 
    Wire.beginTransmission(5); 
    Wire.write('A'); 
    Wire.endTransmission(); 
    Wire.beginTransmission(10); 
    Wire.write('D'); 
    Wire.endTransmission(); 
    Serial.println("A1 & A2 in M1 and M4 d"); 
} 

void arduino11_motor23() 
{ 
    Wire.beginTransmission(5); 
    Wire.write('A'); 
    Wire.endTransmission(); 
    Wire.beginTransmission(5); 
    Wire.write('C'); 
    Wire.endTransmission(); 
    Serial.println("A1 & A2 in M1 and M3 d"); 
} 

void arduino1_still() 
{ 
    Wire.beginTransmission(5); 
    Wire.write('S'); 
    Wire.endTransmission(); 
} 

void arduino2_still() 
{ 
    Wire.beginTransmission(10); 
    Wire.write('S'); 
    Wire.endTransmission(); 
} 

從1個編號:

#include <Servo.h> 
#include <Wire.h> 

Servo myservo1; 
Servo myservo2; 

void setup() 
{ 
    Serial.begin(9600);   // setup serial 
    myservo1.attach(2); 
    myservo2.attach(3); 
    Wire.begin(5); 
    Wire.onReceive(receiveEvent); 


} 

void loop() 
{ 
} 

void receiveEvent(int howMany) 
{ 
    while(Wire.available()) 
    { 
    char v = Wire.read(); 

    if(v == 'A') 
    { 
     myservo1.write(0); 
     myservo2.write(180); 
     Serial.println("Arduino 1 in motor 1 direction"); 
    } 
    else if(v == 'B') 
    { 
     myservo1.write(180); 
     myservo2.write(0); 
     Serial.println("Arduino 1 in motor 2 direction"); 
    } 
    else 
    { 
     myservo1.write(90); 
     myservo2.write(85); 
     Serial.println("Arduino 1 still"); 
    } 
    } 
} 

從2:

#include <Servo.h> 
#include <Wire.h> 

Servo myservo3; 
Servo myservo4; 

void setup() 
{ 
    Serial.begin(9600);   // Setup serial 
    myservo3.attach(2); 
    myservo4.attach(3); 
    Wire.begin(10); 
    Wire.onReceive(receiveEvent); 
} 

void loop() 
{ 
} 

void receiveEvent(int howMany) 
{ 
    while(Wire.available()) 
    { 
     char v = Wire.read(); 

     if(v == 'C') 
     { 
      myservo3.write(0); 
      myservo4.write(180); 
      Serial.println("Arduino 2 in motor 3 direction"); 
     } 
     else if(v == 'D') 
     { 
      myservo3.write(180); 
      myservo4.write(0); 
      Serial.println("Arduino 2 in motor 4 direction"); 
     } 
     else 
     { 
      myservo3.write(90); 
      myservo4.write(90); 
      Serial.println("Arduino 2 still"); 
     } 
    } 
} 
+0

您是否有權訪問示波器來確定電子信號的完整性並排除硬件問題? – cowboydan

+0

我沒有使用示波器檢查過我的設置,但是我已經測試了沒有附加組件(電位計,LED,按鈕等)的i2c設置以及沒有i2c的附加組件,並且發現兩個系統都可以單獨工作。 – pongAssist

+0

你可以說I2C的從地址設置在哪裏嗎?他們是否設置在硬件?我嘗試刪除一個arduino奴隸,並試圖讓一個人迴應。 – cowboydan

回答

2

這可以幫助你了一點:

好了,這是怎麼回事成爲文字牆,我已經c因爲這個Arduino的「特性」非常糟糕,如果你插入一個3.3v設備,它會花費你$ $$。 您正在使用Wire Library,它能夠在SDA和SCL引腳上實現非常糟糕的20k內部上拉。

ON ARACHIN ARDUINO。你現在有一種情況,總上拉電阻現在被鎖住(擰緊)。 您需要研究如何禁用內部上拉。我建議修改庫。出於整體原因,這種控制不應該用軟件來完成。 仔細檢查所需的外部上拉電阻。 Arduino上的每個SCL/SDA引腳的電容應爲10pF。

這裏是式從ATMEGA數據表

http://i.imgur.com/ZAByF.png

這裏直接的就是ATMEGA數據表,參見第21爲I2C部

http://www.atmel.com/Images/doc8161.pdf

4

的 「接收事件」 是在ISR內部,直到事件函數返回纔會退出

哦,AVR硬件將I2C總線保持在凍結狀態,直到此事件退出,也稱爲時鐘延伸

哦,猜猜看,Wire沒有將FIFO變量聲明爲volatile,所以即使他有一段時間(Wire.available()),這將成爲無限循環,因爲可用的()將永遠不會改變,因爲這一切都發生在中斷和rxBufferIndex和rxBufferLength不聲明爲揮發性

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_volatile

這是一個可能的原因

插入憤怒的咆哮關於Arduino和d其可怕的圖書館在這裏

解決方案?使用另一個庫,如果你知道如何,那麼可以直接使用「Wire.h」借用的TWI實用程序,這很好,我一直都在使用它。

0

而不是嘗試多個從站,首先啓動與單主站和單從站配置。儘量讓程序儘可能簡單。創建功能等接收和發送到主/從

0

無法裏面receiveEvent

receiveEvent定義命令 則主應該調用requestFrom並要求值和從手柄(requestEvent),並使用寫有。

即 1-萬事達wire.Write(命令名)

2-從屬:手柄(receiveEvent),並獲得該命令ID

3-主機發送requestFrom

4-從屬手柄(requestEvent)並根據命令ID將回復發送給主站。

相關問題