2014-04-25 2 views
0

Sur l'Arduino Esplora, basé sur la carte Leonardo, le support PWM de la broche 5 qui pilote le composant Rouge de la LED RGB ressemble à un timer avec la fonction tone. Cela a pour conséquence involontaire de rendre le composant Rouge inutilisable après avoir joué un son car son comportement devient imprévisible.Comment arrêter la fonction de tonalité d'Arduino Esplora interférant avec la LED RGB

Voici une routine simple setup montrant le problème:

void setup() 
{ 
    //analogWrite(5, 255); 
    //delay(1000); 
    analogWrite(5, 1); 
    delay(2000); 
    Esplora.tone(440); 
    delay(1000); 
    Esplora.noTone(); 
} 

Ce tourne sur le canal rouge de la LED à son réglage le plus bas et le maintient pendant deux secondes, puis joue un ton de 440 Hz pour 1/4 ensuite, dès que la tonalité commence, au lieu de rester à faible luminosité, la LED s'éteint complètement.

Si vous décommentez les deux premières lignes, cette fois-ci lorsque la tonalité commence, au lieu de (incorrectement) désactiver comme précédemment, elle revient maintenant (tout aussi incorrectement) en pleine luminosité.

Je n'arrive pas à comprendre comment restaurer la fonctionnalité du composant Red (ou plus précisément PWM sur la broche 5) après avoir appelé tone.

Je suppose que générer le bon HZ pour le son, tone change les réglages du minuteur, ce qui affecte alors la fonction PWM. Si je peux trouver comment réinitialiser manuellement la minuterie pour soutenir correctement PWM pour la LED à nouveau, cela peut être la solution. Cependant, je suis nouveau pour Arduino, les timers et autres, donc c'est de la pure spéculation et je peux me tromper complètement avec cette approche ou ma compréhension, mais d'après ce que j'ai lu, cela semble aller dans la bonne direction .

Alors quelqu'un sait comment restaurer la fonctionnalité PWM correcte sur cette broche?

Mark

+0

Quelles sont les valeurs de TCCR3A, TCCR3B, TCCR4A, TCCR4B, TCCR4C, TCCR4D et TCCR4E avant et après la faute (en hexadécimal s'il vous plaît)? –

+0

Nouveau sur Arduino. Comment puis-je les vérifier? Tout code d'esquisse serait apprécié. (Et étiez-vous celui qui m'a voté vers le bas? Si oui, soin d'élaborer sur pourquoi ??) – MarqueIV

+0

Juste les sortir via la connexion série. –

Répondre

1

j'ai étudié les documents 32U4 un peu et a saisi la logique spécifique Esplora des bibliothèques Arduino qu'ils utilisent pour initialiser les ressources PWM au démarrage. La routine timerFix() ci-dessous peut être utilisée pour restaurer les paramètres appropriés.

void loop() 
{ 
    Esplora.writeRGB(127,0,0); 
    delay(1000); 
    Esplora.tone(311); 
    delay(1000); 
    timerFix(); 
    Esplora.writeRGB(32,0,0); 
    delay(1000); 
} 
void timerFix() 
{ 
    #define sbi(sfr,b) (_SFR_BYTE(sfr) |= _BV(b)) 

    //Tone will have hijacked the timer used for the 
    //RGB led RED channel so once we're done we need 
    //to restore it. First shutdown the tone internals 
    //if not done already... 
    Esplora.noTone(); 

    //Now clear the Timer Count Control Registers to 
    //have them in a known state. 
    TCCR3A = 0; 
    TCCR3B = 0; 

    //Setup the clock source - clk/64 
    sbi(TCCR3B, CS31); 
    sbi(TCCR3B, CS30); 

    //Set the wave form generator for 10-bit PWM 
    sbi(TCCR3A, WGM30); 

    //re-link the PWM timer to output channel 
    //by passing something other than 0 and 255 
    //so that the analogWrite function is forced to 
    //recompute the correct value for either the 
    //OCR3A or OCR3B register (output control register) 
    //as appropriate 
    analogWrite(5, 1); 

    //turn the LED channel off 
    analogWrite(5, 0); 
} 
1

vos soupçons concernant tone() reconfigurant la minuterie est correcte. Sur le '32U4, le temporisateur 3 est utilisé pour tone(), mais sur l'Esplora, OC3A est utilisé pour le composant rouge (OC1B et OC1A sont utilisés pour les composants vert et bleu respectivement). Cela signifie qu'à chaque fois que tone() est appelé sur l'Esplora, le temporisateur 3 est reconfiguré pour CTC (WGM3 [3: 0] = 0b0100), alors que le composant rouge nécessite PWM pour être utilisé correctement (et analogWrite() utilise spécifiquement la phase 8 bits -correct PWM [WGM [3: 0] = 0b0001]). Et puisque la minuterie est nécessaire jusqu'à ce que la tonalité s'arrête, il n'y a aucun moyen sensé de passer d'un mode à l'autre.

Normalement, le moyen le plus simple de résoudre ce problème est de dire à tone() d'utiliser une minuterie différente. Malheureusement sur l'Esplora il n'y a pas de minuteur qu'il peut utiliser: timer 0 est utilisé par delay() et autres, timer 1 est utilisé par les composants verts et bleus, timer 4 fonctionne complètement différemment que les bibliothèques Arduino sont programmées, et Le timer 2 n'existe même pas sur le '32U4.

Cependant, la broche pour OC3A sur le '32U4 est la même broche pour nOC4A. Cela signifie que nous pouvons utiliser le timer 4 pour contrôler le composant rouge à la place. Les valeurs de TCCR4 * n'étaient pas 0 lorsque vous les avez examinées, mais cela peut être dû au fait que le bootloader les manipule; J'ai été incapable de trouver quelque chose dans le noyau Arduino ou la bibliothèque Esplora qui les modifie.

Il y a 2 problèmes avec l'aide de la minuterie 4:

  1. Pin 13 est connecté à OC4A. Cela signifie que la broche 13 doit toujours être configurée comme une entrée car la sortie de celle-ci sera un signal PWM qui est la phase opposée à la composante rouge. Les bibliothèques Arduino ne sont pas programmées pour gérer le timer 4. Cela signifie que nous aurons besoin d'accéder au timer 4 à un niveau bas pour le configurer et l'utiliser.

Et:

pinMode(13, INPUT); 
// disable timer 4 interrupts 
TIMSK4 = 0; 
// reset TCCR4C 
TCCR4C = 0; 
// set OCR4C to maximum 
OCR4C=0xff; 
// clear dead time register 
DT4 = 0; 
// enable PWM based on OCR4A and connect nOC4A (and OC4A) 
TCCR4A = _BV(PWM4A) | _BV(COM4A0); 
// match analogWrite() prescaling 
TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 
// enable fast PWM 
TCCR4D = 0; 
// set minimum brightness 
OCR4A = 0xff; 

delay(1000); 
OCR4A = 0xbf; // low brightness 
delay(1000); 
OCR4A = 0x3f; // high brightness 
delay(1000); 
OCR4A = 0x7f; // mid brightness 
delay(1000); 
OCR4A = 0x00; // max brightness 
+0

Hi Ignacio! C'est une très bonne description de ce qu'est le problème. Vous êtes allé au-dessus et au-delà, et j'ai dépassé ce dont j'ai besoin, qui est simplement de reconfigurer Timer3 pour PWM après avoir joué un son. La raison en est que pendant que je fais du prototypage sur un Esplora, je veux me protéger contre n'importe quel forum où cela peut être un problème. Mais c'est une trop bonne réponse pour changer/mettre à jour alors pourrais-je vous demander d'en créer un second avec un simple extrait sur la façon de reconfigurer le minuteur pour revenir à la prise en charge de PWM? Je vais juste basculer entre le son et le RVB si je dois, ne pas utiliser la led lors de la lecture des sons. – MarqueIV

+0

Aussi, même si cela ne répond pas à mes besoins immédiats, je suis toujours intéressé à comprendre ce que vous avez fait ici. Pouvez-vous développer les commentaires sur les choses comme OCR4A et autres? Je googling autour, mais je ne peux pas sembler trouver un bon tutoriel sur les minuteurs et comment toutes ces valeurs se rapportent. – MarqueIV

+0

Une autre chose ... dans votre 'mise en garde' ci-dessus concernant la broche 13, c'est normalement la broche LED par défaut. Y a-t-il un mal à le laisser juste comme sortie pour voir l'inverse du rouge? Est-ce que ça gâcherait quelque chose, ou étiez-vous en train de le faire pour que vous ne le voyiez pas? – MarqueIV

Questions connexes