Skocz do zawartości

Dwa Arduino i I2C


Haragorn

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" ? 

Link do komentarza
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.

Link do komentarza
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).

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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
    
  }
}

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

 

Link do komentarza
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 🙂

Link do komentarza
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
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.