Envoyer des données d'un smartphone sur une carte arduino en bluetooth

Bonjour @ ts,

Je viens de réaliser un montage avec une carte Arduino qui pilote une bande led RGB avec plusieurs effets d'allumage grâce à des boutons et un potentiomètre (réglage luminosité). C'est pour l'éclairage du bureau de mon fils.
N'étant pas sur-doué dans le codage de l'arduino, j'avoue avoir fait pas mal de recherche pour récupérer les codes et arriver à le faire fonctionner.
Maintenant ce jeune homme voudrait pouvoir le piloter à partir de son smartphone.
Toujours en faisant des recherches, j'ai trouvé comment réaliser une aplli, faire communiquer le smartphone et la carte arduino, envoyer un octet et faire déclencher une séquence en fonction du code reçu.
Pour corser la chose, on voudrait ne pas utiliser le système de bouton mais envoyer les trois variables des couleurs RGB en fonction de la position d'un curseur sur le disque des couleurs. Pour l'appli j'ai trouvé comment récupérer ces 3 données,
Par contre je ne trouve pas comment je pourrai les envoyer à la carte, d'où la création de ce post.
Si quelqu'un a une idée, je suis preneur...
Dans un premier temps, je ne cherche pas forcément le code, mais plutôt le principe d'envoyer ces 3 valeurs (on va dire en même temps) et les utiliser à l'arrivée dans la carte.

Merci par avance pour vos réponses.

Cordialement,
Didier

Pour l'appli j'ai trouvé comment récupérer ces 3 données,
Par contre je ne trouve pas comment je pourrai les envoyer à la carte, d'où la création de ce post.

postez l’application.. dites nous si c’est iOS ou Android

Sur Android, l'appli Bluetooth Electronics est bien faite et permet de faire des jolies IHM. L'une d'elle existe pour choisir des niveaux RGB pour des leds. Cerise sur le gâteau, elle génère le code Arduino de réception.

Côté Arduino, il faut un module BT, comme le HC-05 ou le HM-10

Bonjour @ tous,

Merci pour vos réponses
@ J-M-L c'est pour l'utiliser sur un Android.
@ lesept, merci pour le lien. Il a pu m'aider un peu dans mes recherches bien qu'il utilise des Leds RGB alors que je vais utiliser des bandes leds.
Après pas mal de recherche et de regroupement de codes j'ai pu avancer sur mon appli et sur le code que je voudrais utiliser.
Sur l'ensemble il fonctionne à peut-prêt. J'arrive à allumer ma bande de led avec la couleur que je choisis et son intensité.
Le problème que je rencontre, c'est que par moment j'ai l'impression que ma carte bluetooth se bloque et je ne reçois plus rien.
Pour être plus précis, au repos la led de la carte bluetooth clignote. Lorsque elle est connectée à mon tél elle clignote 2 fois toutes les 4 à 5s. Lorsque j'ai le soucis elle ne clignote plus.
Je me suis aperçu que dans le code, que je mettrai plus bas, lorsque je dévalide les 2 actions que je veux faire (pour mes essais, il n'y a plus de blocage de la carte bluetooth, c'est à dire qu'en regardant le moniteur série je reçois mes infos et la led de la carte bluetooth est toujours active.

char caracter;
String DonneesRecu;

String red;
String green;
String blue;
String brightness;
int ind1;
int ind2;
int ind3;
int ind4;
int roLed;
int veLed;
int blLed;
int lumLed;

// Necessaire pour bluetooth
#include <SoftwareSerial.h>
#include <Wire.h>//Include libraries: SoftwareSerial & Wire
SoftwareSerial Bluetooth(11,12); //Define PIN11 & PIN12 as RX and TX pins

//  Necessaire pour bandeau led
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
//#include <FastLED.h>

#define BRIGHTNESS 200

#define LED_PIN    6

#define LED_COUNT 41

// Declare our NeoPixel strip object:


Adafruit_NeoPixel strip = Adafruit_NeoPixel(41, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() { 
  Serial.begin(9600);
  Bluetooth.begin(9600);

   strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(200); // Set BRIGHTNESS to about 1/5 (max = 255)
}

void loop() { 

   
  
  if(Bluetooth.available()) {
   
  caracter = Bluetooth.read();
  DonneesRecu = DonneesRecu + caracter;

   if(caracter == '*') {    
    DonneesRecu = DonneesRecu.substring(0, DonneesRecu.length() - 1); // Delete last char *
        Serial.print("données reçues = ");
        Serial.println(DonneesRecu);
        ind1 = DonneesRecu.indexOf(',');
        red = DonneesRecu.substring(0, ind1);
        roLed = red.toInt();
        ind2 = DonneesRecu.indexOf(',', ind1+1 );
        green = DonneesRecu.substring(ind1+1, ind2);
        veLed = green.toInt();
        ind3 = DonneesRecu.indexOf(',', ind2+1 );
        blue = DonneesRecu.substring(ind2+1, ind3);
        blLed = blue.toInt();
        ind4 = DonneesRecu.indexOf(',', ind3+1 );
        brightness = DonneesRecu.substring(ind3+1);
        lumLed = brightness.toInt();
       
        

        //Serial.print("red = ");
        //Serial.println(red);
        //Serial.print("green = ");
        //Serial.println(green);
        //Serial.print("blue = ");
        //Serial.println(blue);
        //Serial.print("brightness = ");
        //Serial.println(brightness);
        Serial.print("valeur rouge = ");
        Serial.println(roLed);
        Serial.print("valeur verte = ");
        Serial.println(veLed);
        Serial.print("valeur bleu = ");
        Serial.println(blLed);
        Serial.print("valeur luminosite = ");
        Serial.println(lumLed);
        Serial.println();

        DonneesRecu = "";
        delay(10);

         //couleurDemandee();
        
         colorWipe(strip.Color(roLed, veLed, blLed), 10); 
       
   }
   
  } 
} 


void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void couleurDemandee()  {

     strip.setBrightness(lumLed);
      for(uint16_t i=0; i<strip.numPixels(); i++) {
          strip.setPixelColor(i, strip.Color(roLed, veLed, blLed) );
        }
        delay(50);
        strip.show();
  
}

Je joint également une image du moniteur série et de l'appli sur le tél.

Je me demandais si mon problème provient de mon code (ce qui ne m'étonnerai pas) ou de ma carte bluetooth.
Si l'un d'entre vous pouvez m'aider ce serait super sympa de votre part.
J'avoue une nouvelle fois que je ne suis pas un pro de la programmation Arduino, mais que j'aime bien m'y plonger dedans pour essayer d'avancer.

Merci par avance pour vos réponses

moniteur série.JPG

Application bluetooth du téléphone_2.jpg

moniteur série.JPG

Application bluetooth du téléphone_2.jpg

Bonjour,

Le délai 50 est vraiment nécessaire dans la procédure couleurDemandee?, si ce n'est pas le cas, le supprimer.

Bjr @ ts,

@ nico78:
Comme je ne suis pas un grand spécialiste de l’Arduino (j'essaie de m'améliorer en me jetant des défis), les codes que je met dans mes programmations proviennent, du coup, de code que je trouve sur le Net. Effectivement en y réfléchissant un peu, il n'y en a sans doute pas besoin. Je vais le supprimer et dirai si ça ne change rien dans la prog.

Pour mon problème de plantage, après avoir passé une nuit blanche (on dit que la nuit porte conseil et je confirme le dicton) je me suis demandé si je n'avais pas un problème d'alimentation. Et là en mettant une alim plus forte -> plus de blocage. Même si je n'ai pas beaucoup de led pour faire mes essais, je pense que suivant la couleur que je voulais allumer cela devait demander trop d'intensité et faire chuter la tension aux bornes de la carte bluetooth.

J'espère que cela pourra en aider certains s'ils se trouvent dans mon cas.

Maintenant reste à affiner l'appli du tél et le code car j'ai d'autres trucs à ajouter. En autre allumer une 2ème bande led de couleurs différentes pour éclairer le clavier du PC portable, ajouter des effets d'éclairage pour celle du fond du bureau (rainbow, serpent, flemme, etc...).
Encore quelques heures à passer sur ce projet... ;D ;D

Je vous tiendrai au courant de son avancement et peut-être revenir vers vous pour d'autres questions... :wink:

Amitiés @ tous

Bjr @ ts,

Je reviens vers vous pour faire part de mes avancées (en fait juste une qui fonctionne, je bute sur d’autres points).
J’ai réussi à faire allumer une 2ème bande de led en blanc avec réglage de la luminosité et l’éteindre ( souhaits du fiston).
Par contre je bute grave sur un problème où je tourne en rond. J’espère que je serai assez clair sur mes explications pour que vous puissiez m’aider. Je me base, pour essayer de faire fonction le programme, sur des codes qui existent et qui fonctionnent (donc je me dit que ça doit être réalisable).

En fait je voudrais rajouter plus haut des effets spéciaux, tel rainbow, un effet serpent, ou d’autres effets qui en fait, si j’ai bien compris sont répétitifs par rapport au simple fait de choisir une couleur à allumer.

J’ai essayé de faire en utilisant 2 codes différents (je les mettrai à la fin du post) mais j’ai toujours un problème dans les 2 cas:
Dans le 1er “reception_donnees_2_9” le soucis et que le void rainbow ne tourne pas en permanence (il s’arrête de tourner une fois qu’il a fini son cycle) et je voudrais que le cycle se répète, par contre je peux re-sélectionner une autre couleur et ça fonctionne.
Dans le 2ème code “reception_donnees_2_11” j’ai fait différemment et là, quelque soit le “choice” sélectionné, ça tourne en permanence, super pour rainbow, mais maintenant je ne peux plus en sortir et choisir un autre effet.
J’ai essayé de rajouter le void “lectureBluetooth” en me disant que si le code trouve quelque chose en réception du bluetooth (la valeur de “FctBouton” qui permet de choisir en 1 → allumage fixe de la 1ère bande led, en 2 allumage de la 2 ème bande, en 3 l’effet “rainbow”, en 4 et 5 des effets que je n’ai pas encore définis, mais qui se répèteront) il pourrait sortir de ce “choice” et reprendre un autre effet.
Je pense que je n’ai pas bien saisi cette fonction car pour tous les “choice” le void demandé se fait une fois et s’arrête. je me retrouve au point de départ.

Merci de m’avoir lu et aussi merci par avance si vous pouvez m’aider…

Amitiés @ ts…

Il faut que tu postes ton code, sinon on ne peut pas t'aider

Bjr @ ts,

Je ne pouvais les mettre dans le post précédent et j’en avais crée un autre mais il na pas du être enregistré.
En fait je vais devoir le faire en deux car les 2 codes dépassent le nombre de caractères dont j’ai droit

Du coup, les voici:
Je sais que j’y ai mis pas mal de “Serial.print”, mais ils sont provisoires, c’est pour moi pour essayer de comprendre ce qui se passe.

Le 1er code: reception_donnees_2_9

char caracter;
String DonneesRecu;

String red;
String green;
String blue;
String brightness;
String ValBouton;
int ind1;
int ind2;
int ind3;
int ind4;
int ind5;
int roLed;
int veLed;
int blLed;
int lumLed;
int FctBouton;

// Necessaire pour bluetooth
#include <SoftwareSerial.h>
#include <Wire.h>//Include libraries: SoftwareSerial & Wire
SoftwareSerial Bluetooth(10,11); //Define PIN10 & PIN11 as RX and TX pins

//  Necessaire pour bandeau led
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#include <FastLED.h>


#define BRIGHTNESS 200
#define FRAMES_PER_SECOND  120

#define LED_PIN    6
#define LED_PIN2    5


#define LED_COUNT 41
#define LED_COUNT2 41

struct CRGB leds[LED_COUNT];
struct CRGB leds2[LED_COUNT2];
CRGBPalette16 gPal;

  // FOR SYLON ETC
     uint8_t thisbeat =  23;
     uint8_t thatbeat =  28;
     uint8_t thisfade =   2;                                     // How quickly does it fade? Lower = slower fade rate.
     uint8_t thissat = 255;                                     // The saturation, where 255 = brilliant colours.
     uint8_t thisbri = 255; 
     int     myhue =   0;

// Declare our NeoPixel strip object:


Adafruit_NeoPixel strip = Adafruit_NeoPixel(41, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(41, LED_PIN2, NEO_GRBW + NEO_KHZ800);

void setup() {
   delay(3000);
   
  Serial.begin(9600);
  Bluetooth.begin(9600);

   strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(200); // Set BRIGHTNESS to about 1/5 (max = 255)

  strip2.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip2.show();            // Turn OFF all pixels ASAP
  strip2.setBrightness(200);
}

uint8_t gHue = 0;

void loop() { 

   
  
  if(Bluetooth.available()) {
   
  caracter = Bluetooth.read();
  DonneesRecu = DonneesRecu + caracter;

   if(caracter == '*') {    
    DonneesRecu = DonneesRecu.substring(0, DonneesRecu.length() - 1); // Delete last char *
        Serial.print("données reçues = ");
        Serial.println(DonneesRecu);
        ind1 = DonneesRecu.indexOf(',');
        red = DonneesRecu.substring(0, ind1);
        roLed = red.toInt();
        ind2 = DonneesRecu.indexOf(',', ind1+1 );
        green = DonneesRecu.substring(ind1+1, ind2);
        veLed = green.toInt();
        ind3 = DonneesRecu.indexOf(',', ind2+1 );
        blue = DonneesRecu.substring(ind2+1, ind3);
        blLed = blue.toInt();
        ind4 = DonneesRecu.indexOf(',', ind3+1 );
        brightness = DonneesRecu.substring(ind3+1, ind4);
        lumLed = brightness.toInt();
        ind5 = DonneesRecu.indexOf(',', ind4+1 );
        ValBouton = DonneesRecu.substring(ind4+1);
        FctBouton = ValBouton.toInt();
       
        

        //Serial.print("red = ");
        //Serial.println(red);
        //Serial.print("green = ");
        //Serial.println(green);
        //Serial.print("blue = ");
        //Serial.println(blue);
        //Serial.print("brightness = ");
        //Serial.println(brightness);
        Serial.print("valeur rouge = ");
        Serial.println(roLed);
        Serial.print("valeur verte = ");
        Serial.println(veLed);
        Serial.print("valeur bleu = ");
        Serial.println(blLed);
        Serial.print("valeur luminosite = ");
        Serial.println(lumLed);
        Serial.print("valeur Fct Bouton = ");
        Serial.println(FctBouton);
        Serial.println();

        DonneesRecu = "";
        delay(10);

        if (FctBouton == 1) {
         strip.setBrightness(lumLed);
         couleurDemandee();
        }

        
        else if (FctBouton == 2) {
          strip2.setBrightness(lumLed);
          couleurDemandee2();
        }
       
          
       
        else if (FctBouton == 3) {
          strip.setBrightness(lumLed);
          rainbow3(20);
        }

       
       else if (FctBouton == 4) {
        strip.setBrightness(lumLed);
       colorWipe((roLed, veLed, blLed), 50);
        
    
        }
   }
   
  } 
} 


void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void colorWipe2(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip2.numPixels(); i++) {
    strip2.setPixelColor(i, c);
    strip2.show();
    delay(wait);
  }
}

    void couleurDemandee()  {

     strip.setBrightness(lumLed);
      for(uint16_t i=0; i<strip.numPixels(); i++) {
          strip.setPixelColor(i, strip.Color(roLed, veLed, blLed) );
        }
        delay(50);
        strip.show();
  
}

void couleurDemandee2()  {

     strip2.setBrightness(lumLed);
      for(uint16_t i=0; i<strip2.numPixels(); i++) {
          strip2.setPixelColor(i, strip2.Color(roLed, veLed, blLed) );
        }
        delay(50);
        strip2.show();
  
}

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, LED_COUNT, gHue, 7);
}

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, LED_COUNT, 20);
  int pos = beatsin16( 13, 0, LED_COUNT-1 );
  leds[pos] += CHSV( gHue, 255, 192);
        // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND);

  EVERY_N_MILLISECONDS( 20 ) { gHue++; }
}

void confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, LED_COUNT, 10);
  int pos = random16(LED_COUNT);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, LED_COUNT, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, LED_COUNT-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

void rainbow2(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i*1+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } 
  else if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } 
  else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow3(int wait) {
  // Hue of first pixel runs 3 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 3*65536. Adding 256 to firstPixelHue each time
  // means we'll make 3*65536/256 = 768 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

Encore merci par avance si vous pouvez m’aider

@mitiés @ ts

Ne t'inquiète pas pour les print, c'est normal en phase de débug...
J'avais fait un code similaire pour une horloge infinie : il faut organiser le code autour de la communication avec ton IHM et non pas autour des animations. L'idéal est de faire une machine d'états. Lis le tuto de J-M-L, ça te donnera une idée de comment faire.

Mon idée est la suivante :

  • pour chaque animation, tu crées une fonction spécifique
  • la loop écoute la liaison bluetooth, pour recevoir les commandes
  • ensuite elle exécute la machine d'états pour faire évoluer les animations

Là où ça se complique c'est si tu veux pouvoir changer d'animation en cours d'exécution d'une autre animation. Pour ça, il faut que tes fonctions d'animation soient conçues de manière à n'exécuter qu'un seul pas de l'animation à chaque appel.

Par exemple, un rainbow : chaque appel va vérifier que le temps depuis le dernier changement de couleur est passé. Si non, return. Si oui, tu changes les couleurs et tu affiches les couleurs. Puis return. Avec ça, le temps pendant lequel la fonction est exécuté est minimal et tu es sûr de ne pas rater l'arrivée de commandes BT.

Du coup, le contrôle de chaque animation (c'est à dire par exemple le numéro de la couleur à afficher sur la led 0) est soit géré dans la machine d'état (donc la loop) soit en static dans la fonction.

C'est un peu compliqué, mais une fois que tu as saisi comment faire pour une animation, les autres sont faciles à faire...

Bjr "lesept",

Merci pour ta réponse et comme tu dits "C'est un peu compliqué," même beaucoup quand tu es néophyte en programmation Arduino.
Je vais suivre tes conseils et bien regarder, à tête reposer, ce que tu as fait et le tuto de J-M-L.
J'ai juste regardé la vidéo de ton horloge et -> chapeau bas, c'est super.

Pour ton idée que tu as décrite ça rejoint un peu ce que je pensais faire, car j'ai 2 animations simples: allumage d'une couleur fixe en fonction des valeurs RGB reçues pour les 2 bandes leds. Ca j'ai réussi à le faire fonctionner car il n'y a pas de cycle répétitif.

Par contre est-ce que tu pourrais me dire à quoi correspond les termes "IHM" et "machines d'états" dans ta réponse?

Amitiès,
Didier

IHM : interface homme machine. C'est le code que tu as sur ton smartphone pour envoyer des ordres en BT (bluetooth) à l'Arduino.
Machine d'états : un système qui exécute des instructions en fonction de règles (voir le tuto, ou Wikipedia)

Bjr "Lesept",

Merci pour tes infos.
Dans mon boulot on parle de DHM (dialogue homme machine)... :wink: LOL

Je vais regarder tout ça.

@+
Didier

CHI, IHM, UI, GUI, UX ça oui c'est courant mais DHM, jamais entendu cela ces 40 dernières années...

Comme quoi, il n'est jamais trop tard pour s'instruire !

disons que l'expression est plus réservée sans doute au traitement du langage naturel comme moyen d'entrée d'information, mais oui il n'y a pas qu'une seule expression