comunicazione seriale bluetooth HC-05

Salve,
voglio inviare tre dati tra due arduino UNO, due costanti ed un analogico generato da un potenziometro, da un arduino Slave ad un Master, mediante due schede HC-05 bluetooth. Le ho configurate in tutto, anche nel blue rate, nella scheda master ho impostato il codice MAC address della slave (quella collegata all’analogico), sembra che comunichino, infatti all’inizio lampeggaino veloce, poi più lente ed insieme. Voglio leggere al monitor seriale il valore analogico ricevuto via bluetooth master, leggo qualcosa ma tutti zero, non riesco a capire cosa è sbagliato nel codice, potete aiutarmi, riporto sotto porzione del codice per Master e Slave.
Grazie

//CODICE ARDUINO UNO MASTER

#include <SoftwareSerial.h>
#include <SoftwareSerial.h>
#define RxPin 11
#define TxPin 10
SoftwareSerial softUART (RxPin,TxPin);

const int sensorPot = A0;
int analog;
const int dato_2;
const int dato_3;
byte pulsante;

void setup() {
Serial.begin(9600); //set baud rate
softUART.begin(38400);


}

void loop() {

analog = analogRead(sensorPot);
dato_2 == 2;
dato_3 ==3;

   //Invio dati to  Bluetooth
   if (softUART.available())
   {
   softUART.write(analog/4);  
   softUART.write(dato_2);
   softUART.write(dato_3);  
   delay(1000);  
   }        
           Serial.println(analog);    
               delay(1000);
}
>


<//CODICE ARDUINO UNO SLAVE
#include <SoftwareSerial.h>
#define RxPin 11
#define TxPin 10
SoftwareSerial softUART (RxPin,TxPin);
int analog;
int pulsante = 0;
int dato_2;
int dato_3;

void setup() {
Serial.begin(9600);
softUART.begin(38400);

}

void loop() {
   //Ricezione dati Bluetooth
   if (softUART.available ())
   {
   analog = softUART.read();
   dato_2 = softUART.read();
   dato_3 = softUART.read();
   }
analog = analog * 4;
Serial.println(analog);
Serial.println(dato_2);
Serial.println(dato_3);
delay(2000);//manda messaggio da arduino2 a monitor seriale
   
}

Devi studiarti meglio come funziona la classe "Serial" (indipendentemente se con vere seriali o SoftwareSerial) e vedere bene ciascun metodo che usi COSA trasmette e, dall'altro lato, COSA riceve (parlo di tipo dati).

La trasmissione di valori numerici e la loro ricezione è più complessa di quello che credi ... specie se tali valori occupano più di un solo byte, come nel caso degli "int" che ne occupano due.

Guglielmo

Nell'arduino che trasmette dici se ci sono dati sulla seriale, stampa write i valori.

  1. Trasmettere dei dati quando ci sono dati da leggere potrebbe creare problemi "mai visto fare".
  2. Arduino master non trasmette mai i dati perché if (softUART.available()) è sempre falsa, visto che
    nessuno trasmette sulla seriale, restituisce sempre zero, e la trasmissione non avviene mai.

Dovresti trasmettere in seguito a una condizione, un pulsante ad esempio, oppure leggi la seriale del PC, ricevo un comando dalla seriale PC e trasmetto di conseguenza allo slave.

if (softUART.available()) // Nel tuo caso sempre falsa, non ci sono mai dati trasmessi dallo slave
   {
   softUART.write(analog/4); 
   softUART.write(dato_2);
   softUART.write(dato_3); 
   delay(1000); 
   }

Grazie della risposta,
ho visto alcuni esempi e mi sembrava avessero fatto così. Perchè dici che non si sono dati trasmessi dallo slave? Lì ho un potenziometro che manda u intero in continuo, dividendolo per 4 lo faccio entrare in un byte. Semmai, entrando in 1 byte, sbaglio la definizione della ricezione, cioè analog ricevuto è byte e poi moltiplicandolo per 4 mi diventa analog_1 di tipo int? ho anche un testo sulle seriali per arduino e mi sembrava dicesse questo, puoi però dirmi dove trovare qualche documento o guida , esempio a riguardo, anche nel caso di voler inviare più dati in continuo?
grazie

Perdona, non avevo fatto caso alla divisione per 4 e, dato che si tratta di una lettura da porta analogica con massimo 10 bit (0 … 1023), effettivamente quel numero non potrà mai essere superiore a 255 quindi … in un singolo byte ci sta :slight_smile:

Tieni piuttosto conto di quanto ti indica torn24

Guglielmo

Nell’arduino slave, usi la softwareserial per leggere dati dall’arduino master, poi usi Serial.println(analog);
che è la seriale standard di arduino, per cui il master non comunica su questa porta seriale, e per il master non ci sono mai dati sulla seriale.

Uso la softwareserial sui pin 10,11 per comunicare tra i due moduli bluetooth hc-05, la Serialprint in master l'ho messa per vedere a video dell'analogico prima dell'invio bluetooth, pensavo che si dessero fastidio.
Nello slave leggo la scheda HC-05 sempre con i pin 10-11 mediante softwareserial , scusate ma non capisco dove sbaglio. Potete indicarmi la sintassi per master e slave nel caso voglia inviare e ricevere tre dati come nell'esempio? e se devo trasferire un intero, per cui mi occorrono due byte, come faccio? se avete una guida , tutorial, dispense, sito, qualcosa per capire, ho preso un libro sulle seriali per arduino ma probabilmente non riportata tutti i passaggi. Grazie

Usi due seriali diverse la softUART e la Serial, nel Master controlli che nella softUART ci siano dati da leggere, softUART.available(), ma nello slave non trasmetti mai su questa seriale, per cui la condizione è sempre falsa.

Ci sono dati sulla softUART.available(), no non ci sono perché lo slave non trasmette dati su questa seriale, trasmette dati sulla Serial, altra seriale.

Rifletti su cosa vuoi fare e scrivi un programma.

  1. Il master deve inviare dati sulla seriale, ma quando?? Quando ci sono dati da leggere mi sembra
    poco furbo. Il master deve inviare dati quando?

  2. Lo slave se ci sono dati sulla seriale legge i dati.

  3. Lo slave trasmette, ma a chi?? Al serial monitor o al master ??

Per quanto riguarda trasmettere un intero o dato superiore al byte, convertire i dati in stringa e trasmettere e ricevere una stringa.

Si usa la funzione itoa() per trasformare un intero in un array di char, stringa in stile C,
Si trasmette la stringa con serial.write(stringa),

Da arduino ricevente si legge carattere per carattere fino a quando ci sono dati sulla seriale, e li si inserisce in un array di char.

Si ha la stringa finale e la si converte in intero con atoi().

Ho cambiato il software come sotto, nel monitor seriale attaccato all’arduino 2 (master) vedo un valore coerente di “analog”, ma ho due problemi:

  1. in arduino 2 ho messo un led che si deve accendere in funzione del valore di “analog” e non si accende, vedo solo il valore a monitor
  2. come mai se invio anhe duecostanti “dato_2”, “dato_3”, nel monito seriale attaccato ad arduino 2 vedo 0?
    Grazie

CODICE ARDUINO SLAVE

#include <SoftwareSerial.h>
#define RxPin 11
#define TxPin 10
SoftwareSerial softUART (RxPin,TxPin);

const int sensorPot = A0;
int analog;
const int dato_2;
const int dato_3;
byte pulsante;

void setup() {
Serial.begin(9600); //set baud rate
softUART.begin(38400);
 
 pinMode(2, OUTPUT);  //luce rossa
 pinMode(3, OUTPUT);  //luce gialla
 pinMode(4, OUTPUT);  //luce verde
 }

void loop() {
digitalWrite(2, LOW); //Led rossa
digitalWrite(3, LOW); //Led verde
digitalWrite(4, LOW); //Led gialla
analog = analogRead(sensorPot);
dato_2 == 2;
dato_3 ==3;
analog == analog/4; 


    //Invio dati to  Bluetooth
    softUART.write(analog);   
    softUART.write(dato_2);
    softUART.write(dato_3);
    
   
        //Accendi luce rossa se analog < 500
        if (analog < 470) {
        digitalWrite(2, HIGH); 
        }
          //Accendi luce rossa se 470 > analog > 530
          if ((analog >= 470 && analog <= 530)){
          digitalWrite(3, HIGH);
          }
          //Accendi luce rossa se analog > 530
            if (analog > 530) {  
            digitalWrite(4, HIGH);
            }
            Serial.println(analog);    
                delay(1000);

CODICE ARDUINO 2 (MASTER)

#include <SoftwareSerial.h>
#define RxPin 11
#define TxPin 10
SoftwareSerial softUART (RxPin,TxPin);
byte analog1_byte;
int pulsante = 0;
int dato_2; 
int dato_3;
int analog;

void setup() {
Serial.begin(9600);
softUART.begin(38400);
pinMode(5, OUTPUT); 
pinMode(3, INPUT);
}

void loop() {
 digitalWrite(2, LOW); //pulsante
 digitalWrite(5, LOW); //lampadina
 pulsante =   digitalRead(3);
   
    //Ricezione dati Bluetooth
    if (softUART.available > (2) )
   {
    analog = softUART.read();
    dato_2 = softUART.read();
    dato_3 = softUART.read();
    }

 analog = int(analog*4);
 Serial.println(analog);
 Serial.println(dato_2);
  Serial.println(dato_3);
 
 delay(2000);//manda messaggio da arduino2 a monitor seriale
  
      if ((analog > 470)){
      digitalWrite(5, HIGH);
       }
 }

Nell'arduino slave ci sono queste righe

analog = analogRead(sensorPot);
dato_2 == 2;
dato_3 ==3;
analog == analog/4

Leggi il valore analogRead() e lo assegni alla variabile con =,per cui quando trasmetti la variabile analog ha un valore, poi usi ==, queste sono confronti logici, restituiscono true e false ma non assegnano alla variabile nessun valore, per cui le variabile dato_2 e dato_3 non hanno nessun valore assegnato.
Devi usare = al posto di ==.

Poi se io nel loop() uso digitalWrite() fuori da qualunque controllo, esempio un if(), per accendere o spegnere dei led, questi resteranno sempre accesi o spenti. Ossia se dico spegni il led, il loop() viene ripetuto velocissimamente e ogni millesimo di secondo spegne il led, per cui saranno sempre spenti.

Grazie,
ho capito gli errori, riprovo. Sapete se c'è u simulatore, cioè un emulatore per arduino e/o per la breadboard?
Grazie

Ho provato e funziona tutto, grazie
Mi manca un’ultima cosa: voglio usare lo smartphone come joystik per una robot car, 2 motori il problema è che non riesco a vedere la scheda HC-05 montata sulla robot car.
Allego di seguito il codice:
Ho provato con varie appl, Arduino BLue, BLEJoystik, ho impostato la HC-05 come slave, ma non la vedo. Ho impostato come ingressi TX,RX quelli di default 0, 1. Non so se sbaglio qualcosa nel codice,.
Sapete dirmi una applicazione per IOS o Androis ed un tutorial su come settare i comandi, perchè non capisco come in che ordine le varie appl inviano i comandi.
Grazie

//*****************************************************************************************
//Definisco le costanti con Define; sono i contatti nel modulo L298 (enA, in1, in2 per il motore Left, gli altri per l'eventuale motore Right)
#include <SoftwareSerial.h>
int enA = 11;
int in1 = 5;
int in2 = 6;
int enB = 10;
int in3 = 7;
int in4 = 8;


int xAxis;
int yAxis;
int  x = 0;
int  y = 0;

// Variabili e libreria per il sensore ad ultrasuoni
#include <NewPing.h>
#define TRIGGER_PIN  12  // Pin di arduino collegato al pin "TRIGGER" del sensore a ultrasuoni
#define ECHO_PIN     11  // Pin di arduino collegato al pin "ECHO" del sensore a ultrasuoni
#define MAX_DISTANCE 200 // Massima distanza del ping (in centimetri) 
                         // La massima distanza supportata è circa 400-500 cm

//*****************************************************************************************
void setup() {
Serial.begin(9600);
// Read the incoming data from the Joystick, or the master Bluetooth device, legge x scalato 0-255 (1 Byte)
  
  
 //Set le uscite del modulo L298N; sono tutti visti come output da Arduino
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

   digitalWrite(enA, LOW);
   digitalWrite(enB, LOW);
   digitalWrite(in1, LOW);
   digitalWrite(in2, LOW);
   digitalWrite(in3, LOW);
   digitalWrite(in4, LOW);
  Serial.begin(9600); // Default communication rate of the Bluetooth module
}

//*****************************************************************************************
void loop() {
  
if (Serial.available() >= 2) {
x = Serial.read();
delay(10);
y = Serial.read();
xAxis = map(x, 0, 255, 0, 1023);  // Legge il valore x dalla seriale e lo scala in 0-1023. Questo sarà il valore di comando sinistra/destra
yAxis = map(y, 0, 255, 0, 1023);  // Come sopra, ma sarà ilvalore di comando sinistra/destra
}   
 //*****************************************************************************************
 // y-axis used for forward and backward control
 if (yAxis < 470) {
    // Set Motor Left backward
    digitalWrite(enA, HIGH);
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor Right backward
    digitalWrite(enB, HIGH);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW); 
}
 else if (yAxis > 550) {
    // Set Motor A forward
    digitalWrite(enA, HIGH);
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    
    // Set Motor Right backward
    digitalWrite(enB, HIGH);
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH); 
  }
//*****************************************************************************************
  // X-axis used for left and right control
 // X-axis used for forward and backward control
 if (xAxis < 470) {
    // Set Motor Left Stop to rotate the machine on the left
    digitalWrite(enA, LOW);
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    // Set Motor Right forward to rotate the machine on the left
    digitalWrite(enB, HIGH);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, HIGH); 
}
 else if (xAxis > 550) {
    // Set Motor Left forward to rotate the machine on the right
    digitalWrite(enA, HIGH);
    digitalWrite(in1, HIGH);
    digitalWrite(in2, HIGH);
    
    // Set Motor Right Stop to rotate the machine on the right
    digitalWrite(enB, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW); 
 }
 //*****************************************************************************************
 // Logica del sensore HS-SR4 a ultrasuoni
 delay(50);                      // effettuo 20 ping al secondo. 29ms è il ritardo minimo ammesso tra 2 ping.
  unsigned int uS = sonar.ping_cm(); // Invia il ping e determina in cm di distanza (uS).
  if (uS < 15) {
digitalWrite (enA,LOW);   // se l'ostacolo è a meno di 15 cm spengi i motori
digitalWrite (enB,LOW);   // se l'ostacolo è a meno di 15 cm spengi i motori
 }
 else {
digitalWrite (enA,HIGH);
digitalWrite (enB,HIGH);
  }

Che lo smartphone veda o non veda il bluetooth, non può dipendere dal codice, se la scheda è alimentata dovrebbe essere percepita.

gava10:
Sapete dirmi una applicazione per IOS o Androis ed un tutorial su come settare i comandi ...

Dimentica iOS, NON permette la connessione con il Bluetooth classico (v2.x) come quello del HC-05, ma solo con BLE (Bluetooth Low Energy v4.x e successive).

Se il modulo HC-05 è configurato come "slave", qualsiasi programma di "emulazione terminale Bluetooth" di Android dovrebbe vederlo.

Guglielmo