Skocz do zawartości
Haragorn

Dwa Arduino i I2C

Pomocna odpowiedź

Dzień dobry 

Mam połączone Arduino Mega z Uno przy pomocy I2C do komunikacji. Mega jest "master", który po wciśnięciu przycisku wysyła wartość zmiennej "stan". Uno jako "slave" ma tą wartość odczytać i wykonać odpowiednie polecenie. I tu jest problem, ponieważ o ile Mega wysyła wartość (gdy sprawdzam status transmisji komendą: 

unsigned char statuss = Wire.endTransmission();
Serial.println (statuss);

 to wartość "statuss" = 0, czyli sukces) to gdy sprawdzam monitor Uno, to nic tam nie ma do wyświetlenia. Czy mógłby mi ktoś powiedzieć gdzie występuje błąd w mojej pracy ? 

Kod dla Mega:

// Enable debug prints to serial monitor
#define MY_DEBUG 

// Enable serial gateway
#define MY_GATEWAY_SERIAL

// Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif

// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE

// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP

// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60 
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN  3 
#define MY_REPEATER_FEATURE



//----------------biblioteki-----------------------------
#include <SPI.h>        
#include <MFRC522.h>    //RFID RC522
#include <Wire.h>       //Dla I2C
#include <Bounce2.h>    //Obsługa przycisków
#include <MySensors.h>
//-------------------------------------------------------

//----------------definiowanie elementów-----------------

#define BUTTON_PIN 31
#define RELAY_1  24  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
#define NUMBER_OF_RELAYS 1 // Total number of attached relays
#define RELAY_ON 1  // GPIO value to write to turn on attached relay
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay

//-------------------------------------------------------

//----------------zmienne--------------------------------

Bounce debouncer = Bounce();
volatile boolean stan = true;

//-------------------------------------------------------

//-------------------------------------------------------
void before() { 
  for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
    // Then set relay pins in output mode
    pinMode(pin, OUTPUT);   
    // Set relay to last known state (using eeprom storage) 
    digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
  }
}
//-------------------------------------------------------

//-------------------------------------------------------
void setup() 
{
  // Setup locally attached sensors
  delay(5000);
   // Setup the button.
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  // After setting up the button, setup debouncer.
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);
  digitalWrite(RELAY_1, LOW);
  
  //Inne
  Serial.begin(9600);
  SPI.begin(); 
}
//-------------------------------------------------------

//-------------------------------------------------------
// Główna funkcja sterująca
void loop() 
{

  // Send locally attached sensor data here 
  if (debouncer.update()) 
  {
    // Get the update value.
    int value = debouncer.read();
    // Send in the new value.
    if(value == LOW)
    {
         stan = !stan;
         Serial.println(stan);
         Wire.beginTransmission(1);
         Wire.write(stan);              // sends one byte
         Wire.endTransmission();
         unsigned char statuss = Wire.endTransmission();
         Serial.println (statuss);
    }
  }

  }
//-------------------------------------------------------

Kod dla Uno:

//----------------biblioteki-----------------------------

#include <Servo.h>      //Servo
#include <Wire.h>       //Dla I2C

//-------------------------------------------------------

//----------------zmienne--------------------------------

volatile byte stan = 1;

//-------------------------------------------------------

//-------------------------------------------------------

void setup() 
{
  Serial.begin(9600);
  Wire.begin(1);
}

//-------------------------------------------------------

//-------------------------------------------------------
// Główna funkcja sterująca

void loop() 
{
  
  Wire.onReceive(czytaj);
 
}

//-------------------------------------------------------

//-------------------------------------------------------

void czytaj(int howMany) 
{
  if (Wire.available()) 
  { 
    stan = Wire.read(); // receive byte as a character
    Serial.println(stan);
  }
}

//-------------------------------------------------------

Jeśli chodzi o połączenia to na pewno są dobrze, ponieważ gdy wczytam przykłady z biblioteki "Wire" to komunikacja działa poprawnie. Może źle korzystam z biblioteki "MySensors" ? 

Udostępnij ten post


Link to post
Share on other sites

Adres 1 jest w i2c zarezerwowany, ztcp adresy z których możesz korzystać zaczynają się od 8.

Robienie Serial.print w funkcji obsługi przerwania to zły pomysł. Ustaw w niej tylko jakąś zmienną globalną, a print daj w pętli w loop. Wire.onReceive powinno iść do setup, bo musisz to ustawić tylko raz.

Udostępnij ten post


Link to post
Share on other sites

Wdrożyłem wszystkie sugestie. Wybrałem adres powyżej 8. Ustawiłem na master i slave adres 10 i teraz komunikacja nie działa w ogóle, ponieważ slave nie potwierdziło odbioru adresu (błąd 2. Standardowo sprawdzam status transmisji w Mega na monitorze portu).

Udostępnij ten post


Link to post
Share on other sites

To pokaż jak je wdrożyłeś, wklej nowy kod.

Udostępnij ten post


Link to post
Share on other sites

Kod dla Mega:

// Enable debug prints to serial monitor
#define MY_DEBUG 

// Enable serial gateway
#define MY_GATEWAY_SERIAL

// Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif

// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE

// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP

// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60 
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN  3 
#define MY_REPEATER_FEATURE



//----------------biblioteki-----------------------------
#include <SPI.h>        
#include <MFRC522.h>    //RFID RC522
#include <Wire.h>       //Dla I2C
#include <Bounce2.h>    //Obsługa przycisków
#include <MySensors.h>
//-------------------------------------------------------

//----------------definiowanie elementów-----------------

#define BUTTON_PIN 31
#define RELAY_1  24  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
#define NUMBER_OF_RELAYS 1 // Total number of attached relays
#define RELAY_ON 1  // GPIO value to write to turn on attached relay
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay

//-------------------------------------------------------

//----------------zmienne--------------------------------

Bounce debouncer = Bounce();
volatile boolean stan = true;

//-------------------------------------------------------

//-------------------------------------------------------
void before() { 
  for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
    // Then set relay pins in output mode
    pinMode(pin, OUTPUT);   
    // Set relay to last known state (using eeprom storage) 
    digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
  }
}
//-------------------------------------------------------

//-------------------------------------------------------
void setup() 
{
  // Setup locally attached sensors
  delay(5000);
   // Setup the button.
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  // After setting up the button, setup debouncer.
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);
  digitalWrite(RELAY_1, LOW);
  
  //Inne
  Serial.begin(9600);
  SPI.begin(); 
}
//-------------------------------------------------------

//-------------------------------------------------------
// Główna funkcja sterująca
void loop() 
{

  // Send locally attached sensor data here 
  if (debouncer.update()) 
  {
    // Get the update value.
    int value = debouncer.read();
    // Send in the new value.
    if(value == LOW)
    {
         stan = !stan;
         Serial.println(stan);
         Wire.beginTransmission(10);
         Wire.write(stan);              // sends one byte
         Wire.endTransmission();
         unsigned char statuss = Wire.endTransmission();
         Serial.println (statuss);
    }
  }

  }
//-------------------------------------------------------

Kod dla Uno: 

//----------------biblioteki-----------------------------

#include <Servo.h>      //Servo
#include <Wire.h>       //Dla I2C

//-------------------------------------------------------

//----------------zmienne--------------------------------

volatile byte stan = 0;

//-------------------------------------------------------

//-------------------------------------------------------

void setup() 
{
  
  Wire.begin(10);
  Wire.onReceive(czytaj);
  Serial.begin(9600);
 

}

//-------------------------------------------------------

//-------------------------------------------------------
// Główna funkcja sterująca

void loop() 
{
 if (stan > 0)
 {
   Serial.println(stan);
 }
}

//-------------------------------------------------------

//-------------------------------------------------------

void czytaj(int howMany) 
{
  if (Wire.available()) 
  { 
    stan = Wire.read(); // receive byte as a character
    
  }
}

//-------------------------------------------------------

 

Udostępnij ten post


Link to post
Share on other sites

endTransmission masz dwa razy.

Pokaż może jednak jak to masz wszystko podłączone?

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Nie wiem, czy będzie dokładnie wszystko widać. Wydaje mi się, że jest dobrze ponieważ, gdy wgram przykłady z biblioteki Wire to wszystko ładnie działa. 

20190111_122959.jpg

Udostępnij ten post


Link to post
Share on other sites

Wygląda dobrze. Jaką wartość mają te oporniki (jestem za leniwy żeby szukać kodów)?

Jeszcze jedna rzecz mi przychodzi do głowy — spróbuj zamiast if dać w czytaj while.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

Rezystory są po 4.7 k Om 

To też zmieniałem...

Udało się 😍 . Już nawet sam nie wiem co zrobiłem. Wgrałem przykłady z biblioteki Wire i zmieniłem je pod siebie. Jakimś cudem wszystko działa. 

Dziękuję Ci za pomoc 🙂

Udostępnij ten post


Link to post
Share on other sites

A mógłbyś tu jeszcze wkleić działający kod, dla potomnych? Pomogłoby to wszystkim innym osobom borykającym się z podobnym problemem.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Dla potomnych.

Program jest testowy, więc nie oczekujcie zaawansowanej technologii. Zadaniem jest sprawdzenie poprawności działania I2C. 

Kod dla Master: 

//-------------------------------------------------------
// Enable debug prints to serial monitor
#define MY_DEBUG 

// Enable serial gateway
#define MY_GATEWAY_SERIAL

// Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif

// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE

// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60 
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN  3 
#define MY_REPEATER_FEATURE
//-------------------------------------------------------

//-------------------------------------------------------
#include <Wire.h>
#include <MySensors.h>
#include <SPI.h>  
#include <MFRC522.h> 
#include <Bounce2.h> 
//-------------------------------------------------------

//-------------------------------------------------------
#define BUTTON_PIN A9
Bounce debouncer = Bounce();
bool y = true;
//-------------------------------------------------------

//-------------------------------------------------------
void setup() 
{
  Wire.begin(); // join i2c bus (address optional for master)
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  // After setting up the button, setup debouncer.
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(15);
  Serial.begin(9600);
}
//-------------------------------------------------------

//-------------------------------------------------------
void loop() 
{
  if (debouncer.update()) 
  {
    // Get the update value.
    int value = debouncer.read();
    // Send in the new value.
    if(value == LOW)
    {
      
      Wire.beginTransmission(10); // transmit to device #8
      Wire.write(y);              // sends one byte
      Wire.endTransmission();    // stop transmitting
      unsigned char statuss = Wire.endTransmission();
      Serial.println (statuss);
    }
    }
}
//-------------------------------------------------------

Kod dla Slave :

//-------------------------------------------------------
#include <Wire.h>
//-------------------------------------------------------

//-------------------------------------------------------
volatile bool b; 
//-------------------------------------------------------

//-------------------------------------------------------
void setup() 
{
  Wire.begin(10);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}
//-------------------------------------------------------

//-------------------------------------------------------
void loop() 
{
  if (b == true)
  {
    Serial.print(b);
    b = !b;
  }
  
  delay(100);
}
//-------------------------------------------------------

//-------------------------------------------------------
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) 
{
  while (0 < Wire.available()) 
  { 
    bool c = Wire.read(); // receive byte as a character
    b=c;
  }
}
//-------------------------------------------------------

 

 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@Haragorn, dzięki - na pewno przyda się komuś w przyszłości 🙂

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Napisz odpowiedź...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...