[Conseil] Sur la faisabilité de mon prjet et sur l'Arduino à choisir

Bonjour,

J'ai pour projet de créer pour un enfant une veilleuse/lampe de chevet avec un compartiment secret. Le tout serait contrôlé avec une télécommande infrarouge (pour le côté magique) et 2 potentiomètres (pour le design).

Petite précision: je suis un néophyte (notions d'électronique et "grosses notions" en programmation) autodidacte et j'apprends au fur et à mesure que je rencontre des problèmes. Surtout qu'on trouve de bons tuto accessibles à tous.
Mais des conseils d'experts sont toujours bons à prendre ne serait-ce que pour s'assurer d'être sur la bonne voie.

Même si je suis conscient que mon projet semble ambitieux pour un début, je reste convaincu qu'il est réalisable mais peut-être pas en intégralité.
En fouinant durant des jours, j'ai déjà résolu quelques difficultés qui s'annonçaient infaisables selon les forums. Mais désormais j'affronte vaillamment de nouveaux obstacles que je ne saurais surmonter seul.

Ma veilleuse sera idéalement composée de :
1 Arduino Uno
1 bargraph de 10 LED via un bitshifter 74HC595 (uniquement décoratif)
5 LED RGB via un multiplexeur PWM TLC5940
1 potard pour choisir la couleur des RGB
1 potard pour la luminosité
1 servomoteur qui contrôle l'ouverture de 2 clapets en fonction de la luminosité
1 récepteur infrarouge avec une télécommande d'une vieille TV
1 moteur DC récupéré sur un lecteur CD avec le mécanisme du tiroir pour faire le compartiment secret

Voici où j'en suis :
Bargraph Ok :slight_smile:
5 Led RGB Ok :wink:
5 Led RGB + 2 potards OK ;D
Bargraph + 5 Led Rgb + 2 potards OK :stuck_out_tongue:
Récepteur infrarouge OK :slight_smile:
Récepteur infrarouge + 5 Led RGB KO >:(

Servomoteur + 1 potard pour choisir l'angle OK :slight_smile:
Servomoteur + 5 Led RGB KO :cry:

J'ai su qu'un conflit de TIMER était responsable de mes KO car les librairies du TLC5940, IR, et Servo utilisent toutes les 3 les mêmes TIMERS simultanément.

J'ai donc appris ceci sur ma Uno :
Je dispose de 3 TIMERS :
TIMER0: 8 bit
contrôlé par les pins 5 et 6
utilisé de base par delay(), milis(), micros(), et autres
TIMER1: 16 bit
contrôlé par les pins 9 et 10
TIMER2: 8 bit
contrôlé par les pins 11 et 3
utilisé de base par tone(), noTone()

Si j'ai bien compris, je peux jouer avec les TIMER 1 et 2 mais pas le 0 car c'est le principal.

De plus mes librairies utilisent: (informations à vérifier car c'est ce que j'ai "décrypté" des librairies mais je suis loin d'être un as)
TLC5940: TIMER 1 et 2
IR: je peux choisir le TIMER dans la librairie mais un TIMER 8bit suffit
Servo: un TIMER 16 bit. Je pense pouvoir bidouiller la librairie pour choisir mon TIMER mais je suis moyen sûr d'y arriver.

En avançant dans mon projet, je viens de m'apercevoir qu'il va me manquer 2 pins PWM.

D'où mes questions :

1/ Mon projet vous semble-t-il réalisable ? Ou je ferais mieux d'oublier quelques fonctions ?

2/ Quelle carte Arduino serait suffisante ?
Sachant que j'ai besoin de :

  • 4 TIMERS sans compter le TIMER0 (si je ne me trompe pas)
  • 8 pins PWM et 5 pins digitaux
  • L'intensité et tout le reste me dépasse un peu :blush:

3/ Est-ce que les Pins dont je parle correspondent aux pins de ma Uno ?
Donc il y a une importance dans mes branchements ?
Exemple: Mon TIMER1 est utilisé par TLC5940 et le Servo donc TLC5940 sur le pin 9 et le Servo sur le pin 10.

Et une petite dernière pour la route...
4/ Que se passe-t-il si je branche mon Servo sur le pin 11 (TIMER2 8 bit) et que la librairie utilise un TIMER 16 bit ?

En attendant vos réponses, et pour vous prouver à quel point je suis désireux de connaissances, je m'en vais poursuivre mon apprentissage d'autoCAD pour la carcasse de ma veilleuse. Donc j'espère que vous serez nombreux à me conseiller :grinning:

Je m'excuse de ne pas mettre mes sources car j'écris de mon téléphone mais je pourrai facilement vous les fournir si besoin.

Je vous remercie par avance de prendre le temps de m'aider même si mon roman peut en rebuter plus d'un.

Bisous bisous

Pourquoi faut il autant de timers ?
Il faudrait mettre sur le papier les différentes séquences temporelles pour optimiser ça.

Deux rectifications :
Ce ne sont pas les sorties qui controlent le timer mais l'inverse : c'est le timer qui controle les sorties qui lui sont ratachées. Le timer se controle en écrivant dans ses registres.

Il n'est pas interdit d'utiliser le timer 0, c'est juste qu'il est utilisé par les fonctions arduino qui gérent le temps (millis et delay). La PWM dépendant du timer 0 sera aussi modifiée. Ce sera aussi le cas des autres PWM dépendant des timers 1 et 2 s'ils sont modifiés, ce n'est pas bloquant mais il faut le savoir.

La modification du timer 0 est déconseillé aux débutants, toutefois à partir du moment ou tu sais ce que tu fais tout est permis.

Sinon
l'AtMega 328p possède 3 timers, cartes : UNO, nano, mini-pro
L'AtMega 32U4 possède 4 timer, cartes : Leonardo, micro
L'AtMega 2560 possède 7 timers, cartes : Atmega 2560

Bonjour,

Merci pour ces précisions 68tjs et également à Christian_R qui m'a donné un bon axe de réflexion.

Avant tout je ne sais vraiment pas comment poser sur papier mes séquences temporelles mais j'ai cogité sur

Pourquoi faut il autant de timers ?

Je me suis rendu compte que ma loop() appelait sans cesse une fonction qui est bourrée de timers.
Du coup je n'ai jamais de timer de disponible.

J'ai rajouté un delay() par-ci ou par-là histoire de voir... peine perdue... tout bug les Led ne s'allument pas toutes et avec des couleurs aléatoires.

Le code code sera plus parlant alors voici sans plus attendre...... MES SOURCES :fearful:
Car oui j'ai tout pompé, je vous avez prévenu que je débutais même si j'utilise de jolis mots pour endormir la foule.
Je tiens à précisé que j'ai passé beaucoup de temps à essayer de comprendre chaque lignes et je trouve avoir bien bosser pour en arriver à ce résultat.

J'ai mixé ces 2 tutos :

Pour arriver à ceci : Code fonctionnel

//http://lucidtronix.com/tutorials/4
/* LucidTronix HSB RGB necklace
 * uses TLC5940 chip. for details see:
 * http://www.lucidtronix.com/tutorials/6
 * Control rgb color by specifying
 * Hue saturation and brightness.
 * This code shows a rainbow.
 * It is okay to daiy-chain the chips
 * just change the NUM_TLCS constant
 * in the Tlc5940.h file.
 * This code uses an arduino color library
 * available here:
 * http://www.lucidtronix.com/tutorials/19
 *
 * http://www.instructables.com/id/How-to-Use-an-RGB-LED/
 */
#include <Tlc5940.h>
#include <tlc_fades.h>
#include <Color.h>
// how many millis to strobe over all the LEDs

TLC_CHANNEL_TYPE channel;

Color cur_color(1,1,1);
int scope_period = (200 * NUM_TLCS);
int led_period = scope_period / (NUM_TLCS * 16);
float hue = 0;

const boolean invert = true; // set true if common anode, false if common cathode
unsigned char couleur = 0; // a value from 0 to 255 representing the hue
unsigned char luminosite;
unsigned char brightness = 255; // 255 is maximum brightness
int R, G, B;  // the Red Green and Blue color components
boolean eteint = 0;

const int Pot1_pin = A0;
const int Pot2_pin = A1;

void setup()
{
  Tlc.init();
  Serial.begin(9600);
}

void loop()
{
  
luminosite = map(analogRead(Pot2_pin),0, 1023, 0, 16);

if (luminosite == 0)
{
  eteint = 0;
} else { eteint=1; }

   if (eteint == 0)
    {
      eteindreLed();
    } else {
      luminosite = map(analogRead(Pot2_pin),0, 1023, 0, 16);
      couleur = map(analogRead(Pot1_pin), 0, 1023, 0, 255);
      changeCouleur();
    }

}

void changeCouleur(){
  hueToRGB(couleur, brightness);// call function to convert hue to RGB
  uint32_t lastMillis = millis();
  int cur_val = channel % 3;
  int color_component = 0;
  if ( cur_val == 0) color_component = R*luminosite;
  else if  ( cur_val == 1) color_component = G*luminosite;
  else if ( cur_val == 2) color_component = B*luminosite;
  tlc_addFade(channel,                      // led channel
              color_component,   // start fade value (0-4095)
              color_component,                            // end fade value (0-4095)
              lastMillis + 2,               // start millis
              lastMillis + (uint16_t)scope_period / 4  // end millis
             );
  if (channel++ == NUM_TLCS * 16) {
    channel = 0;
  }
  uint32_t currentMillis;
  do {
    currentMillis = millis();
    tlc_updateFades(currentMillis);
  } while (currentMillis - lastMillis <= led_period);
}

void eteindreLed() {
  Tlc.setAll(0);
  Tlc.update();
}

void hueToRGB( int hue2, int brightness)
{
    unsigned int scaledHue = (hue2 * 6);
    unsigned int segment = scaledHue / 256; // segment 0 to 5 around the
                                            // color wheel
    unsigned int segmentOffset =
      scaledHue - (segment * 256); // position within the segment

    unsigned int complement = 0;
    unsigned int prev = (brightness * ( 255 -  segmentOffset)) / 256;
    unsigned int next = (brightness *  segmentOffset) / 256;
    
 /*   int Pot1_val = map(analogRead(Pot1_pin), 0, 1023, 0, 5);
    
    Serial.println(scaledHue);
Serial.println(segment);
    Serial.println(Pot1_val);
*/
    if(invert)
    {
      brightness = 255-brightness;
      complement = 255;
      prev = 255-prev;
      next = 255-next;
    }
//segment = Pot1_val;

    switch(segment ) {
    case 0:      // red
        R = brightness;
        G = next;
        B = complement;
    break;
    case 1:     // yellow
        R = prev;
        G = brightness;
        B = complement;
    break;
    case 2:     // green
        R = complement;
        G = brightness;
        B = next;
    break;
    case 3:    // cyan
        R = complement;
        G = prev;
        B = brightness;
    break;
    case 4:    // blue
        R = next;
        G = complement;
        B = brightness;
    break;
   case 5:      // magenta
    default:
        R = brightness;
        G = complement;
        B = prev;
    break;
    }
}

Pour éviter d'appeler continuellement ma fonction changeCouleur() j'ai modifié ma loop() comme ceci :

void loop()
{
//bargraph();
luminosite = map(analogRead(Pot2_pin),0, 1023, 0, 16);

if (luminosite == 0)
{
  eteint = 0;
} else { eteint=1; }

if (eteint != eteint_old) {
   eteint_old = eteint;
   if (eteint == 0)
    {
      eteindreLed();
    } else {
      luminosite = map(analogRead(Pot2_pin),0, 1023, 0, 16);
      couleur = map(analogRead(Pot1_pin), 0, 1023, 0, 255);
      changeCouleur();
    }
  }  
}

Mais ça ne fonctionne pas. Chaque fois que "eteint" passe de 0 à 1 la led n°1 s'allume, à la 3 troisième fois ça passe sur la seconde led pour 3 fois et ainsi de suite.

J'ai également essayé d'oublié ce Fade qui est joli mais me pourri la vie... Encore raté

Bref je continu de chercher car je suis convaincu que c'est possible à faire mais une petit coup de pouce bien avisé fait toujours plaisir... :sweat_smile: ... à moins que je me le retrouve dans le :fearful:

Encore merci et à bientôt... j'espère.... j'espère vraiment :kissing: