inviare e ricevere stringhe o interi tra arduino uno ed arduino Mega 2560

Ciao a tutti,
non riesco a far comunicare questi due device tramite il bus seriale i2c.
Il mio progetto è quello di mandare al Master un valore che raccoglie lo Slave tramite un sensore di umidità, e poi una volta che il Master ha ricevuto il valore occorre che invii allo Slave un segnale per accendere un LED.
Ho provato con tanti metodi ma nessun codice sembra funzionare...non riesco nemmeno a printare una semplice stringa.
MI sapreste dare una mano con gli sketch? GRAZIE MILLE DI TUTTO :slight_smile: :slight_smile: :slight_smile: :slight_smile:

http://forum.arduino.cc/index.php?topic=407307.msg2802085#msg2802085
http://forum.arduino.cc/index.php?topic=407303.msg2802068#msg2802068

Sei riuscito a fare il maggior numero di violazioni con solo 2 post:
Il cross-posting è vietato.
In sezione internazionale non si scrive in italiano, ma in inglese.
In sezione italiana metti sotto megatopic dove c'e' scritto chiaramente che li vanno solo certi tipi di thread.
E non ti sei presentato.

Quindi:
ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e SOPRATTUTTO a leggere il regolamento se non lo hai già fatto: Regolamento
Qui una serie di link utili, non inerenti al tuo problema:

Posta il codice che stai usando.
Mi raccomando, il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare ( pulsante </> ).
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.

Se usi librerie metti un link. Se spieghi come e cosa hai collegato, meglio.
Più info e più è chiaro quel che vuoi fare.

si vede che sono nuovo eh....xD
Mi ero sbagliato prima a mettere la mia domanda nella sezione internazionale, non sapendo come eliminarla l ho lasciata li xD

Dario94:
si vede che sono nuovo eh....xD

NON è una giustificazione, ci sono chiari avvertimenti ... quindi presta più attenzione e, onde evitare futuri problemi, leggi con attenzione il REGOLAMENTO !

Guglielmo

Come ti ha chiesto Nid, metti il codice che stai usando (... mi raccomando, in conformità al regolamento, punto 7, racchiuso tra i tag CODE che, in fase di edit, ti inserisce il bottone </> ... primo a sinistra) e descrivici COSA vuoi far parlare ... due Arduino UNO (uno Master ed uno Slave) ? O cosa ?

Guglielmo

GRAZIE ANCORA PER TUTTO PER LA PAZIENZA :stuck_out_tongue_closed_eyes:

Il Master deve essere l Arduino UNO mentre lo Slave è l ARDUINO MEGA 2560.
Il primo codice "funzionante " che sono riuscito a buttar giù è uno molto semplice dove accendo un led:

//I2C SLAVE
#include <Wire.h>
int ledPin =  13;
void setup()
{
pinMode(ledPin, OUTPUT);     
Wire.begin(4);                        // indirizo #4 
Wire.onReceive(receiveEvent);    
}

void loop ()
{
delay(100);
}
// funzione eseguita quando si ricevono dati dal master
// questa funzione è registrata come evento
void receiveEvent(int howMany)
{
digitalWrite(ledPin, Wire.read());
}
//I2C MASTER
#include <Wire.h>
int ledPin =  13;               
void setup(){
pinMode(ledPin, OUTPUT);     
Wire.begin();                 /
}
void loop()
{
digitalWrite(ledPin, HIGH);  
Wire.beginTransmission(4);    device #4
Wire.write(HIGH);                
Wire.endTransmission();       // fine trasmissione
delay(1000);                 
digitalWrite(ledPin,LOW);    
Wire.beginTransmission(4);    
Wire.write(LOW);                
Wire.endTransmission();       // fine trasmissione
delay(1000);                 
}

Ora mi piacerebbe fare in modo che il master legga il valore di un sensore collocato nello slave, in base a questo valore il master deve restituire "1" per accendere il led, o "0" per tenerlo spento (led situato sullo slave)

Dato che è sempre il "Master" a prendere l'iniziativa, devi fare in modo che il "Master" invii un comando allo "Slave" per digli di inviare , come risposta, il valore del sensore.

Quindi ...

  1. dovrai implementare una logica per ricevere un carattere di comando, che so io, se invii 'L' accendi il LED, se invii 'l' spegni il LED e se invii 'S' vuoi il valore del sensore.

  2. lo "Slave" in funzione del carattere dovrà fare due cose diverse ... con 'L' accendere il LED, con 'l' spegnere il LED, con 'S' inviare il valore del sensore.

Guglielmo

Grazie, ho capito la logica..
Come faccio però a far si che il Master Invii dati e li riceva contemporaneamente?
Ho buttato giù uno sketch
LATO MASTER:

#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 3;
String cod;

void loop() {
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte

  char c = Wire.read();
  cod += c;
  int codint = cod.toInt();
  if ( codint < 30) {
    x = 1;
  } else {
    x = 0;
  }
  Wire.endTransmission();    // stop transmitting

  Wire.beginTransmission(8); // transmit to device #8
  Wire.write("finally x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission(); 

  x = 3;
  cod = " ";
  

  delay(500);
}

LATO SLAVE

#include <Wire.h>
int on = 13;
int valore = 10;
void setup() {
  pinMode(on, OUTPUT);
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop() {
  delay(100);
  valore = analogRead(A1);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer

    if (x == 1) {
      digitalWrite(on, HIGH);
      
    } else if (x == 0) {

      digitalWrite(on, LOW);
    }  else if (x == 3); {
      Wire.write(valore);
        
    }
  
}

Nonostante allo slave sia collegato il sensore in A1, la X torna sempre valore 1 , ma dovrebbe inviare 0..
Potreste aiutarmi?

Grazie in anticipo

E sempre il master che interroga e riceve i dati ... devi studiarti come funziona il bus I2C ... prova a leggere QUI e poi guardati gli esempi nell'IDE della libreria Wire ... c'è tutto !

Guglielmo

Nel mio progetto il master deve inviare un segnale allo slave per accendere i Led in base al valore del sensore. Ma come fa il Master a sapere il valore del sensore? quindi
1- il Master prima manda la richiesta per conoscere il valore del sensore
2-riceve "x"
3-in base a x invia allo slave "accendi " o "spegni"

Sto utilizzando gli esempi forniti da Arduino, ma ci sono del tipo ("Master Reader - Slave Sender") oppure ( " Master Writer - Slave Receiver")
A me pare di capire che il master nel mio caso debba fare entrambi i compiti (?)
In più il mio codice non sembra leggere correttamente il valore del sensore.

Avresti qualche consiglio un po' più approfondito da darmi (se non è disturbo?)

Quanto hai scritto è giusto ...

  1. master invia comando 'S'
  2. slave risponde con valore sensore
  3. master esamina valore e ... o manda 'L' o manda 'l'

Ti basta vedere come funziona l'invio di una richiesta ad uno "slave" ("Master Writer - Slave Receiver") e come si riceve una risposta ("Master Reader - Slave Sender") e mettere assieme le varie cose.

Pubblica poi qui il codice (inizia con cose semplici, per gli abbellimenti c'è sempre tempo) così lo possiamo discutere ...

Guglielmo

Ok.. Quindi come pensavo, devo mettere assieme entrambi gli esempi!
Cercherò di fare tutto il più correttamente possibile e domani posterò una versione del codice (Funzionante, spero :D)

Grazie mille dell'aiuto e della pazienza!

Buongiorno, oggi è stata mattinata produttiva. Credo che il codice si possa ancora migliorare consigli e miglioramenti sono sempre apprezzati :smiley: :grinning: .

Vi invio il codice del :

MASTER

#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600);
}

byte x = 3;
String i;
String completa;

void loop() {
  //invio richiesta valore sensore
  Wire.beginTransmission(8);    
  Wire.write("sto mandando una x di: "); //invio allo slave valore x = 3
  Wire.write(x);  
  Wire.endTransmission();    // stop transmitting

  delay(500);

  Wire.requestFrom(8, 3); // dalla porta 8 richiedo i 3 byte del sensore
  
    while (Wire.available()) { // se lo slave rispone male 
    char c = Wire.read();  // receivo valore sensore e lo metto in char c
    //Serial.print(c);       
    i = c;    //converto in stringa ogni singolo char che acquisisco
    completa += i; //ogni carattere implementato finisce in stringa "completa"
    if (completa.length() == 3) {
    Serial.println("il valore della prima pianta e' " + completa);
    }

    if (completa.toInt() < 300) {
      x = 1;
    } else {
      x = 0;

    }

    Wire.beginTransmission(8);
    Wire.write("accertato il valore del sensore /n sto mandando una x di: ");    
    Wire.write(x); //spedisco allo slave segnale per il led
    Wire.endTransmission();

  }

  delay(500);
  completa = ""; //reimpostiamo la variabile vuota per il prossimo ciclo.
}

E DELLO SLAVE:

#include <Wire.h>

int valore;
String stringaValore;
char val[5];

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

void loop() {
  delay(100);
  valore = analogRead(A1);
}

void receiveEvent(int howMany) {
  //Aquisisce la x
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read();  // riceve dal Master (x=3) e lo mettte in char c
    Serial.print(c);         // stampo c=3
  }
  int x = Wire.read();    // se integer
  Serial.println(x);         // print the integer

  if (x == 3){
    
  Wire.onRequest(requestEvent); //richiamo metodo
  }
}

void requestEvent() 
{
  stringaValore = String(valore); //converto valore del sensore in stringa
  stringaValore.toCharArray(val, 5); //converto la stringa in char perchè posso stampare solo i char
   Wire.write(val); //invio valore acquisito dal sensore al Master
  
   Wire.onReceive(receiveEvent2); //faccio partire il secondo metodo di lettura
}

void receiveEvent2(int howMany) {
  //Aquisisce la x
  while (1 < Wire.available()) 
    char c = Wire.read(); //ricevo dal master x e lo metto in c 
    Serial.print(c);         
  }
  int x = Wire.read();  
  Serial.println(x);       

  if (x == 1){
    digitalWrite (13, HIGH); //se x = 1 accendiamo, altrimenti l incontrario
    } else if (x == 0) {
      digitalWrite(13, LOW);
    }
}

@ELKri: ... come mai un nuovo account? :o :o :o Cosa è successo all'account Dario94?

Ti rammento che, in conformità al REGOLAMENTO, punto 13. <<NON è permesso registrarsi con più "account">> !!!

Attendo tue spiegazioni per capire quale dei due account devo chiudere !

Guglielmo

Sisi Dario94 non c'è più quell account è stato eliminato.
Io ed il mio collega abbiamo deciso di creare un nuovo account insieme visto che il progetto richiede due teste.

Ok, allora usa solamente questo nuovo. L'altro è stato bloccato.

Guglielmo