2012-11-01 20 views
9

Bir master Arduino'nun iki köleyi kontrol ettiği bir I²C kurulumunu deniyorum.Arduino I²C başlatıldıktan sonra donuyor

Enter image description here

Ben I²C için iki 2000 ohm pullup dirençleri kullanıyorum ve tüm panoları Arduino Duemilanoves bulunmaktadır. I²C kurulumu ve kontrol ayarlarının her ikisi de birbiriyle bağlantısı kesildiğinde düzgün çalışır, ancak bağlandığında Arduinolar ilk wire.write işlevi çağrılır yapılmaz yanıt vermezler. Seri mesajları almaya son veriyorum, köle Arduinolar master'dan mesaj almayı durdurdu ve düğmeyi kullanarak sistemi açma ve kapatma yeteneğini kaybediyorum.

Her bir wire.write işlevinden sonra kısa gecikmeler eklemeyi denedim ve sorunu düzeltmek amacıyla çeşitli darbeli dirençler kullanmıştım, ancak hiçbir şey işe yaramıyor gibi görünüyor. Bunu nasıl düzeltebilirim?

Usta Kodu:

#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(); 
    } 

// bu noktaya döngü kadar tüm kod düğmesine basarak açıp sistem döner. // Aşağıdaki kod, potansiyometre okumalarına dayanarak I²C'ye karşılık gelir.

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(); 
} 

Köle 1 Kod:

#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"); 
    } 
    } 
} 

Slave 2:

Tamam bu nedenle bu gidiyor:

#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

Sinyal bütünlüğünü belirlemek ve donanım sorunlarını belirlemek için bir osiloskopa erişiminiz var mı? – cowboydan

+0

Kurulumumu bir osiloskopla kontrol etmedim, ancak i2c kurulumunu ek bileşenler (potansiyometre, LED, düğmeler, vb.) Ve i2c'siz ek bileşenler olmadan test ettim ve her iki sistemin de ayrı ayrı çalışmasını sağladım. – pongAssist

+0

I2C köle adreslerinin nerede ayarlandığını söyleyebilir misiniz? Donanımda mı yer alıyorlar? Arduino kölelerinden birini çıkarmayı denemek ve cevap vermek için sadece bir tane almaya çalıştım. – cowboydan

cevap

2

Bu biraz size yardımcı olabilir bir metin duvarı ol ve ben zaten c bir kez daha kulağa zarar vermeden önce klavyeyi yaladıktan sonra kulağa kızgın gelebilirim çünkü Arduino'nun bu "özelliği" çok kötü ve 3.3v'luk bir cihaza takarsanız size 250 $ 'a mal olacak. SDA ve SCL pinlerinde gerçekten kötü 20k dahili pullups sağlayan Tel Kitaplığı'nı kullanıyorsunuz. HER ARDUİNO ÜZERİNDE

. Toplam pullup direncinin artık korktuğu (vidalandığı) bir durum var. Dahili pulpaların nasıl devre dışı bırakılacağı konusunda araştırma yapmanız gerekir. Kütüphaneyi değiştirmenizi tavsiye ederim. Bütünsel nedenlerle, bu tür bir kontrol asla yazılımda yapılmamalıdır. Matematiğini gerekli harici pulpada kontrol edin. Arduino üzerindeki her SCL/SDA pininin kapasitansı 10pF olmalıdır.İşte

formül ATMEGA veri sayfası, I2C bölüm

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

4

"olayı almak" dir için bölüm 21 mi göreceğiz ATMEGA veri sayfasında İşte

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

doğrudan bir olay işlevi, işlev işlevi

döndürmeden çıkmaz Bu arada, bu arada, AVR donanımı, bu olay çıkana kadar I2C veriyolunu donmuş halde tutar, ayrıca

saatin gerilmesi olarak da bilinir, ne anlama geldiğini tahmin et, Tel, FIFO değişkenlerini uçucu olarak ilan etmedi.) (mevcut asla değişmeyecek çünkü hepsi bir kesme oluyor ve rxBufferIndex ve rxBufferLength

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

bu uçucu olarak ilan edilmez çünkü (Wire.available()), yani sonsuz döngü haline gelir iken sahiptir olası bir sebep

Arduino an için kızgın rant eklemek d bu korkunç kütüphaneleri burada

çözümü? Başka bir kütüphane kullanın, "Wire.h" ödünçlerinin kullandığı TWI yardımcı programları, nasıl ve ne zaman kullanılacağını bilirseniz doğrudan kullanılabilir.

0

Birden çok köle ile çalışmak yerine, Tek ana ve tek köle yapılandırmasıyla İlk Başlatma. Programı mümkün olduğunca basit tutmaya çalışın. almak ve Master/Slave göndererek

0

Sen receiveEvent

içine yazamazsınız gibi Sen fonksiyonunu oluşturmak

receiveEvent komutunu tanımlayan sonra usta requestFrom arayıp değeri ve köle tutamaklar (requestEvent) sormak ve orada yazma kullanmalıdır .

yani 1- Ana wire.Write (Komut adı)

2- köle: kolları (receiveEvent) ve komut numarası

3- Usta elde requestFrom

4- köle kolları gönderir (requestEvent) ve komut kimliğine dayanarak yanıtı master'a gönderir.

İlgili konular