Problema comunicazione Android Arduino (App Inventor)

Mi scuso in anticipo per le dimensioni esagerate delle immagini ma sono riuscito a caricarle solo di questa grandezza.

Salve a tutti, ho un problema con un'applicazione che ho creato con app inventor. In pratica devo pilotare 8 relè tramite bluetooth con il telefono, per farlo sto usando un modulo bluetooth HC-05 collegato alla seriale di arduino (pin 0 e 1). Comunque dopo aver caricato uno sketch di prova su arduino e dopo aver creato l'applicazione con app inventor, ho provato a farlo funzionare. Quindi tramite il telefono riesco a connettermi tranquillamente al modulo HC-05, però quando sull'applicazione premo il tasto di accensione del relè, non succede niente, il relè non si eccita. Se qualcuno mi potesse aiutare glie ne sarei molto grato! Grazie a tutti in anticipo.

Questo è il programma:

char val; 
int rele1 = 13; 

void setup() {

  pinMode(rele1, OUTPUT);  
  Serial.begin(9600);      
}

void loop() {

  if( Serial.available() )       
  {
    val = Serial.read();         
  }
  if( val == 'H' )             
  {
    digitalWrite(rele1, HIGH); 
  } 
  else if( val == 'L' )
  { 
    digitalWrite(rele1, LOW);   
  }
  delay(100);                    

}

questo è lo screenshot dell'applicazione:

e questo è lo screenshot del programma a blocchi dell'app:

Nessuno può aiutarmi??

in arduino prova invece di char val; fare String val;

e invece di

if( val == 'H' ) fare if( val == "H" ) ecco..perdo tutti i punti =(

Il tuo problema è, molto probabilmente, che stai usando, per l'HC-05, la vera seriale di Arduino ... ... se fai un po' di ricerche qui sul forum vedrai che se ne è parlato una infinità di volte.

Prova a collegare il modulo bluetooth ad altri due pin (es. 10 e 11) ed crea una seriale virtuale con la SoftwareSerial ... vedrai che ... con ottima probabilità i problemi spariranno e inoltre avrai libera la vera seriale per fare debug ;)

Guglielmo

camperos: in arduino prova invece di char val; fare String val;

e invece di

if( val == 'H' ) fare if( val == "H" ) ecco..perdo tutti i punti =(

Ho provato a fare come mi hai detto ma al momento della verifica mi da errore.

Hai letto quanto ti ho scritto sopra ??? :roll_eyes: :roll_eyes: :roll_eyes:

Guglielmo

gpb01: Il tuo problema è, molto probabilmente, che stai usando, per l'HC-05, la vera seriale di Arduino ... ... se fai un po' di ricerche qui sul forum vedrai che se ne è parlato una infinità di volte.

Prova a collegare il modulo bluetooth ad altri due pin (es. 10 e 11) ed crea una seriale virtuale con la SoftwareSerial ... vedrai che ... con ottima probabilità i problemi spariranno e inoltre avrai libera la vera seriale per fare debug ;)

Guglielmo

Ciao Guglielmo, ti ringrazio ancora per i tuoi consigli. Ma siccome è da poco che ho cominciato a lavorare con arduino e sono ancora molto ignorante in materia, non è che saresti così gentile da farmi vedere come dovrebbe essere il mio sketch con la seriale virtuale che dovrei creare? Perchè io ho provato a vedere in giro per la rete ma ci ho capito ben poco di come fare per creare una seriale virtuale. Grazie in anticipo!

Devi semplicemente includere la libreria SoftwareSerial …

#include <SoftwareSerial.h>

… scegliere due pin … es 10 RX e 11 TX e collegarci il tuo modulo bluetooth … ovviamente TX Bluetooth → Pin RX di Arduino e RX Bluetooth ← pin TX di Arduino

… istanziare la classe SoftwareSerial

SoftwareSerial miaSeriale(10, 11);

… e quindi usare gli stessi comandi di ora sostituendo la classe Serial con l’istanza da te creata.
Esempio, invece di :

Serial.begin(9600);

… userai la tua :

miaSeriale.begin(9600);

La vera seriale, quella che usi con la Serial resterà in questo modo libera ed utilizzabile, ad esempio, per mandare messaggi di debug al monitor seriale :wink:

Guglielmo

Ti allego un piccolo programma che, dal monitor seriale ti permette di dialogare con qualche cosa connessa via bluetooth e viceversa :

// *****************************************************
//
//        Bluetooth module serial communication
//              Bluetooth <--> USB_Serial
//
// *****************************************************

#include <SoftwareSerial.h>

#define  BT_RX 10            // PIN to receive from bluetooth
#define  BT_TX 11            // PIN TO transmit to bluetooth

SoftwareSerial btSerial(BT_RX, BT_TX);

void setup()
{
  delay (1000);
  //
  Serial.begin(9600);        // Initialize USB Serial port
  //
  btSerial.begin(9600);      // Initialize Bluetooth SoftwareSerial port for selected data speed
  //
  Serial.println("--- Ports ready ---");
  Serial.println("");
  //
}

void loop()
{
  if (btSerial.available() > 0) Serial.write(btSerial.read());
  if (Serial.available() > 0) btSerial.write(Serial.read());
}

Ora, prendendo spunto da questo … adatta il tuo :wink:

Guglielmo

Grazie mille Guglielmo! Ora funziona tutto perfettamente! Sei un grande! :wink:

Ho semplicemente aggiunto la seriale virtuale allo sketch mantenendolo identico a prima:

#include <SoftwareSerial.h>

#define   RX 10            
#define   TX 11            

SoftwareSerial miaSeriale(10, 11);

char val;
int rele1 = 13;

void setup() {

  pinMode(rele1, OUTPUT);  
  miaSeriale.begin(9600);       
}

void loop() {

  if( miaSeriale.available() )       
  {
    val = miaSeriale.read();         
  }
  if( val == 'H' )               
  {
    digitalWrite(rele1, HIGH);  
  } 
  else if( val == 'L' )
  { 
    digitalWrite(rele1, LOW);   
  }
  delay(100);

... te lo avevo detto ... purtroppo è un problema che capita spessissimo !!!

Beh ... ripeto, ha il suo lato positivo ... se devi fare debug e mandare messaggi al serial monitor, ora la porta verso il PC e libera :grin:

Guglielmo

P.S. : Però il codice racchiudilo tra i tag CODE che, in fase di edit, ti inserisce il bottone # ... terzultimo della seconda fila e non tra quelli QUOTE ;)

gpb01: ... te lo avevo detto ... purtroppo è un problema che capita spessissimo !!!

Beh ... ripeto, ha il suo lato positivo ... se devi fare debug e mandare messaggi al serial monitor, ora la porta verso il PC e libera :grin:

Guglielmo

P.S. : Però il codice racchiudilo tra i tag CODE che, in fase di edit, ti inserisce il bottone # ... terzultimo della seconda fila e non tra quelli QUOTE ;)

Ciao Guglielmo, volevo chiederti un'ultima cosa. Praticamente io per ogni relè ho usato un tasto per l'accensione e un tasto per lo spegnimento quindi invio 2 valori. Ora io per l'ultimo relè, vorrei che dopo aver inviato il valore con un solo tasto, il relè si spegnesse dopo un tot di tempo ad esempio dopo un delay di 500ms, e rimanesse spento fin quando non ripremo il tasto per accenderlo di nuovo. Come potrei fare? Io ho provato in diversi modi che in teoria mi sembrava potessero funzionare ma a quanto pare non è stato così. Grazie in anticipo!

Molto semplice ...

... prima però devi studiarti come si usa la millis(), prima QUI, poi QUI ed infine leggi anche QUI ...

Vedi se riesci a capire da solo come applicare quello che avrai studiato o se ti serve un'indicazione ... ;)

Guglielmo

Si ben o male il concetto l'ho capito, solo che come al solito non ho capito come integrarlo con il mio sketch.. :sweat_smile: :blush: Anzi ho provato a modificarlo seguendo l'esempio che mi hai dato QUI ma il relè mi "lampeggia" e non rimane spento..

Allora …
definisci una variabile in cui salverai il tempo nel momento in cui accendi il relè :

unsigned long tempoReleUno;

dove accendi il relè aggiungi …

tempoReleUno = millis();

poi nel loop() avrai un if così fatto :

if ( (millis() - tempoReleUno)  > 500 ) {
  // spegni il rele
}

… tutto qui :grin:

Guglielmo

Niente non va, rimane perennemente acceso adesso.

Questo è lo sketch che sto usando:

#include <SoftwareSerial.h>

#define   RX 12            // PIN to receive from bluetooth
#define   TX 13            // PIN TO transmit to bluetooth

SoftwareSerial MySerial(12, 13);

char val;
int rele1 = 11;
int rele2 = 10;
int rele3 = 9;
int rele4 = 8;
int rele5 = 7;
int rele6 = 6;
int rele7 = 5;
int rele8 = 4;

unsigned long tempoRele8;


void setup() {

  pinMode(rele1, OUTPUT);  // Onboard relays as OUTPUT
  pinMode(rele2, OUTPUT);
  pinMode(rele3, OUTPUT);
  pinMode(rele4, OUTPUT);
  pinMode(rele5, OUTPUT);
  pinMode(rele6, OUTPUT);
  pinMode(rele7, OUTPUT);
  pinMode(rele8, OUTPUT);
  MySerial.begin(9600);       // start serial communication at 9600bps
}

void loop() {

  if( MySerial.available() )       // if data is available to read
  {
    val = MySerial.read();         // read it and store it in 'val'
  }
  if( val == 'A' )               // if 'A' was received
  {
    digitalWrite(rele1, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'B' )          // if 'B' was received
  { 
    digitalWrite(rele1, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'C' )               // if 'C' was received
  {
    digitalWrite(rele2, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'D' )          // if 'D' was received
  { 
    digitalWrite(rele2, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'E' )               // if 'E' was received
  {
    digitalWrite(rele3, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'F' )          // if 'F' was received
  { 
    digitalWrite(rele3, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'G' )               // if 'G' was received
  {
    digitalWrite(rele4, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'H' )         // if 'H' was received
  { 
    digitalWrite(rele4, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'I' )               // if 'I' was received
  {
    digitalWrite(rele5, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'L' )          // if 'L' was received
  { 
    digitalWrite(rele5, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'M' )               // if 'M' was received
  {
    digitalWrite(rele6, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'N' )          // if 'N' was received
  { 
    digitalWrite(rele6, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------  
  if( val == 'O' )               // if 'O' was received
  {
    digitalWrite(rele7, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'P' )          // if 'P' was received
  { 
    digitalWrite(rele7, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'Q' )               // if 'Q' was received
  {
    digitalWrite(rele8, HIGH);  // turn ON the RELAY
    
    tempoRele8 = millis();
    
    if ( (millis() - tempoRele8)  > 500 ) {
    digitalWrite(rele8, LOW);   // turn OFF the RELAY
    } 
  }
}

E ti credo !!! XD

Cosa ho scritto io ??? Dove lo devi mettere quel IF ??? E tu invece ... perché lo metti dentro un'altro IF ???

Deve stare da solo a inizio loop() poiché non deve essere condizionato da nulla !

Guglielmo

Fatto, ma mi rimane comunque sempre acceso

#include <SoftwareSerial.h>

#define   RX 12            // PIN to receive from bluetooth
#define   TX 13            // PIN TO transmit to bluetooth

SoftwareSerial MySerial(12, 13);

char val;
int rele1 = 11;
int rele2 = 10;
int rele3 = 9;
int rele4 = 8;
int rele5 = 7;
int rele6 = 6;
int rele7 = 5;
int rele8 = 4;

unsigned long tempoRele8;


void setup() {

  pinMode(rele1, OUTPUT);  // Onboard relays as OUTPUT
  pinMode(rele2, OUTPUT);
  pinMode(rele3, OUTPUT);
  pinMode(rele4, OUTPUT);
  pinMode(rele5, OUTPUT);
  pinMode(rele6, OUTPUT);
  pinMode(rele7, OUTPUT);
  pinMode(rele8, OUTPUT);
  MySerial.begin(9600);       // start serial communication at 9600bps
}

void loop() {
  
  if ( (millis() - tempoRele8)  > 500 ) {
    digitalWrite(rele8, LOW);   // turn OFF the RELAY
    } 

  if( MySerial.available() )       // if data is available to read
  {
    val = MySerial.read();         // read it and store it in 'val'
  }
  if( val == 'A' )               // if 'A' was received
  {
    digitalWrite(rele1, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'B' )          // if 'B' was received
  { 
    digitalWrite(rele1, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'C' )               // if 'C' was received
  {
    digitalWrite(rele2, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'D' )          // if 'D' was received
  { 
    digitalWrite(rele2, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'E' )               // if 'E' was received
  {
    digitalWrite(rele3, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'F' )          // if 'F' was received
  { 
    digitalWrite(rele3, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'G' )               // if 'G' was received
  {
    digitalWrite(rele4, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'H' )         // if 'H' was received
  { 
    digitalWrite(rele4, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'I' )               // if 'I' was received
  {
    digitalWrite(rele5, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'L' )          // if 'L' was received
  { 
    digitalWrite(rele5, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'M' )               // if 'M' was received
  {
    digitalWrite(rele6, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'N' )          // if 'N' was received
  { 
    digitalWrite(rele6, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------  
  if( val == 'O' )               // if 'O' was received
  {
    digitalWrite(rele7, HIGH);  // turn ON the RELAY
  } 
  else if( val == 'P' )          // if 'P' was received
  { 
    digitalWrite(rele7, LOW);   // turn OFF the RELAY
  }
//------------------------------------------------------------------
  if( val == 'Q' )               // if 'Q' was received
  {
    digitalWrite(rele8, HIGH);  // turn ON the RELAY
    
    tempoRele8 = millis();
        
  }
}

... ancora mi sembra ancora ovvio ]:D ]:D ]:D

Devi stare più attento alla logica del programma ... tu fai :

if( MySerial.available() )       // if data is available to read
  {
    val = MySerial.read();         // read it and store it in 'val'
  }

ma se non premi null'altro ... chi cambia il valore di val ? Nessuno e quindi, se l'ultima volta hai premuto 'Q' ... sempre 'Q' resta e tiene sempre acceso il led !!!

TUTTI quegli IF vanno messi sotto la condizione del MySerial.available() ... così li esegui SOLO se c'è un nuovo carattere !!!

Guglielmo

Ora ho fatto così ma sempre la stessa storia, rimane acceso…

#include <SoftwareSerial.h>

#define   RX 12            // PIN to receive from bluetooth
#define   TX 13            // PIN TO transmit to bluetooth

SoftwareSerial MySerial(12, 13);

char val;
int rele1 = 11;
int rele2 = 10;
int rele3 = 9;
int rele4 = 8;
int rele5 = 7;
int rele6 = 6;
int rele7 = 5;
int rele8 = 4;

unsigned long tempoRele8;

void setup() {

  pinMode(rele1, OUTPUT);  // Onboard LED as OUTPUT
  pinMode(rele2, OUTPUT);
  pinMode(rele3, OUTPUT);
  pinMode(rele4, OUTPUT);
  pinMode(rele5, OUTPUT);
  pinMode(rele6, OUTPUT);
  pinMode(rele7, OUTPUT);
  pinMode(rele8, OUTPUT);
  MySerial.begin(9600);       // start serial communication at 9600bps
}

void loop() {
  
  if ( (millis() - tempoRele8)  > 500 ) {
    digitalWrite(rele8, LOW);   // turn OFF the RELAY
    }

  if( MySerial.available() )       
  {
    val = MySerial.read();         
  }
  if( val == 'A' )              
  {
    digitalWrite(rele1, HIGH);  
  } 
  else if( val == 'B' )
  { 
    digitalWrite(rele1, LOW);   
  }
//------------------------------------------------------------------
  if( MySerial.available() )       
  {
    val = MySerial.read();        
  }
  if( val == 'C' )               
  {
    digitalWrite(rele2, HIGH); 
  } 
  else if( val == 'D' )
  { 
    digitalWrite(rele2, LOW);   
  }
//------------------------------------------------------------------
  if( MySerial.available() )       
  {
    val = MySerial.read();         
  }
  if( val == 'E' )            
  {
    digitalWrite(rele3, HIGH); 
  } 
  else if( val == 'F' )
  { 
    digitalWrite(rele3, LOW);   
  }
//------------------------------------------------------------------
  if( MySerial.available() )       
  {
    val = MySerial.read();         
  }
  if( val == 'G' )               
  {
    digitalWrite(rele4, HIGH);  
  } 
  else if( val == 'H' )
  { 
    digitalWrite(rele4, LOW);   
  }
//------------------------------------------------------------------
  if( MySerial.available() )       
  {
    val = MySerial.read();         
  }
  if( val == 'I' )               
  {
    digitalWrite(rele5, HIGH);  
  } 
  else if( val == 'L' )
  { 
    digitalWrite(rele5, LOW);  
  }
//------------------------------------------------------------------
  if( MySerial.available() )       
  {
    val = MySerial.read();         
  }
  if( val == 'M' )               
  {
    digitalWrite(rele6, HIGH);  
  } 
  else if( val == 'N' )
  { 
    digitalWrite(rele6, LOW);   
  }
//------------------------------------------------------------------  
  if( MySerial.available() )       
  {
    val = MySerial.read();         
  }
  if( val == 'O' )               
  {
    digitalWrite(rele7, HIGH); 
  } 
  else if( val == 'P' )
  { 
    digitalWrite(rele7, LOW);   
  }
//------------------------------------------------------------------
  if( MySerial.available() )       
  {
    val = MySerial.read();        
  }
  if( val == 'Q' )              
  {
    digitalWrite(rele8, HIGH);  
    
    tempoRele8 = millis();
   }

}