Partage
  • Partager sur Facebook
  • Partager sur Twitter

Optimisation d'une fonction.

Sujet résolu
2 juillet 2019 à 11:13:09

Bonjour à tous,

Je ne fais pas beaucoup de c. Donc, je m'adresse à ceux qui connaissent bien.

Je fais tourner un bout de code dans une arduino uno à une fréquence critique par rapport au processeur. Y a-t-il un moyen d'économiser des cycles d'horloge dans ce petit bout de code ?

ISR(TIMER2_COMPA_vect)
{
        if (++period_count_1 > tone_1)
        {
            PORTB = PORTB ^ 0b0000001 ; //inversion de la sortie digital 8
            period_count_1 = 0;  
        }

        if (++period_count_2 > tone_2)
        {
            PORTB = PORTB ^ 0b0000010 ; //inversion de la sortie digital 9
            period_count_2 = 0;
        }

        if (++period_count_3 > tone_3)
        {
            PORTB = PORTB ^ 0b0000100 ; //inversion de la sortie digital 10
            period_count_3 = 0;
        }

        if (++period_count_4 > tone_4)
        {
            PORTB = PORTB ^ 0b00001000 ; //inversion de la sortie digital 11
            period_count_4 = 0;
        }
}



  • Partager sur Facebook
  • Partager sur Twitter
2 juillet 2019 à 12:00:47

il naus faudrait un peut plus d'info et surtout savoir comment sont géré les differentes varible dans le code.

Une optimisation, si c'est pour quelques tours de cycles, tu peux rarremrnt faire mieux que le compilateur. Si tu veux vraiement optimiser quelque chose, il faut souvent regarder coté de l'algo (c'est pour ça que je te demande un peut plus d'info).

  • Partager sur Facebook
  • Partager sur Twitter

la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

Mon GitHub

2 juillet 2019 à 12:12:01

Merci beaucoup de ta réponse.

Le but est de faire jouer une partition à 4 voix par 4 buzzers différents. Le code est prévu pour pouvoir générer les 88 fréquences correspondant aux 88 touches d'un piano. Voici le code complet :

#define TOP_TIMER 119          // si je passe à 118, cela ne fonctionne plus

int clavier[90] = // demi-périodes (en micros secondes) des notes d'un piano
{
    32767, // valeur utilisée pour mettre le buzzer off.
    
    18182, // A-1       1
    17161, // A#-1      2
    16198, // B-1       3
    
    15289, // C0        4
    14431, // C#0       5
    13621, // D0        6
    12856, // D#0       7
    12135, // E0        8
    11454, // F0        9
    10811, // F#0       10
    10204, // G0        11
    9631,  // G#0       12
    9091,  // A0        13
    8581,  // A#0       14
    8099,  // B0        15

    7645,  // C1        16
    7215,  // C#1       17
    6810,  // D1        18
    6428,  // D#1       19
    6067,  // E1        20
    5727,  // F1        21
    5405,  // F#1       22
    5102,  // G1        23
    4816,  // G#1       24
    4545,  // A1        25
    4290,  // A#1       26
    4050,  // B1        27

    3822,  // C2        28
    3608,  // C#2       29
    3405,  // D2        30
    3214,  // D#2       31
    3034,  // E2        32
    2863,  // F2        33
    2703,  // F#2       34
    2551,  // G2        35
    2408,  // G#2       36
    2273,  // A2        37
    2145,  // A#2       38
    2025,  // B2        39

    1911,  // C3        40
    1804,  // C#3       41
    1703,  // D3        42
    1607,  // D#3       43
    1517,  // E3        44
    1432,  // F3        45
    1351,  // F#3       46
    1276,  // G3        47
    1204,  // G#3       48
    1136,  // A3        49   -> 440 hz
    1073,  // A#3       50
    1012,  // B3        51

    956,   // C4        52
    902,   // C#4       53
    851,   // D4        54
    804,   // D#4       55
    758,   // E4        56
    716,   // F4        57
    676,   // F#4       58
    638,   // G4        59
    602,   // G#4       60
    568,   // A4        61
    536,   // A#4       62
    506,   // B4        63

    478,   // C5        64
    451,   // C#5       65
    426,   // D5        66
    402,   // D#5       67
    379,   // E5        68
    358,   // F5        69
    338,   // F#5       70
    319,   // G5        71
    301,   // G#5       72
    284,   // A5        73
    268,   // A#5       74
    253,   // B5        75

    239,   // C6        76
    225,   // C#6       77
    213,   // D6        78
    201,   // D#6       79
    190,   // E6        80
    179,   // F6        81
    169,   // F#6       82
    159,   // G6        83
    150,   // G#6       84
    142,   // A6        85
    134,   // A#6       86
    127,   // B6        87

    119,    // C7        88
    32767   // valeur utilisée pour mettre le buzzer off.
};

int period_count_1  = 0;
int period_count_2  = 0;
int period_count_3  = 0;
int period_count_4  = 0;   

int tone_1 = 32767;
int tone_2 = 32767;
int tone_3 = 32767;
int tone_4 = 32767;

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

    float periode_timer = 0.0625f * TOP_TIMER ; // est-ce faux ?

    //Accorder clavier en fonction du timer :
    //Chaque valeur doit valoir la le nombre de débordement à attendre pour générer la bonne fréquence
    
    for (int i = 1; i < 89; ++i)
    {
        clavier[i] = clavier[i] / periode_timer;
    }
    
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);

    TCCR2A = 0b00000010 ;
    TCCR2B = 0b00000001 ;  // prescaler = 1
    TIMSK2 = 0b00000010 ;  // interruption locale autorisée
    OCR2A = TOP_TIMER ;    // TOP du compteur
}

 
// Routine d'interruption

ISR(TIMER2_COMPA_vect)
{
        if (++period_count_1 > tone_1)
        {
            PORTB = PORTB ^ 0b0000001 ; //inversion de la sortie digital 8
            period_count_1 = 0;  
        }

        if (++period_count_2 > tone_2)
        {
            PORTB = PORTB ^ 0b0000010 ; //inversion de la sortie digital 9
            period_count_2 = 0;
        }

        if (++period_count_3 > tone_3)
        {
            PORTB = PORTB ^ 0b0000100 ; //inversion de la sortie digital 10
            period_count_3 = 0;
        }

        if (++period_count_4 > tone_4)
        {
            PORTB = PORTB ^ 0b00001000 ; //inversion de la sortie digital 11
            period_count_4 = 0;
        }
}

La fonction tourne bien si je l'appelle tous les 119 ticks d'horloge, soit à 134 kHz (le processeur de l'arduino tourne à 16MHz). Si je descends à 118 ticks, cela ne fonctionne plus. Le problème est qu'actuellement, toutes les notes sont un peu fausses. Si je peux augmenter la fréquence d'appel à la fonction, je peux obtenir une meilleure définition.

-
Edité par Umbre37 2 juillet 2019 à 12:42:45

  • Partager sur Facebook
  • Partager sur Twitter
2 juillet 2019 à 16:45:22

alors c'est peut etre une question con mais pourquoi ne pas utiliser les PWM pour pilloter les tones et l'interruption pour changer la valeur du PWM ?

  • Partager sur Facebook
  • Partager sur Twitter

la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

Mon GitHub

2 juillet 2019 à 17:24:41

J'y ai pensé, mais il n'y a que 3 timers sur une Arduino Uno :) Chacun peut générer 2 PMW, mais à la même fréquence, seul l'angle peut être différent (pour faire une note il doit forcément être à 50% pour faire des ondes carrées je pense ? ). Je pourrais donc gérer 3 voix, mais pas 4. Si j'ai bien compris. Mon programme marche bien au final, j'arrive à jouer des mélodies, des accords. Mais quelques ticks d'économisés n'auraient pas été superflus pour gagner en justesse... Aucun moyen d'économiser dans l'interruption ?

Ce qui m'embête aussi c'est que toutes les notes sont un peu plus basse (peut-être un quart de ton plus ou moins), que prévu. Si c'était juste une histoire de précision, elles devraient être plus hautes ou plus basses aléatoirement. C'est comme si le timer tournait un peu plus lentement que ce que je prévois par calcul. A moins que ce soit une erreur de conception dans mon code ?

-
Edité par Umbre37 2 juillet 2019 à 17:32:14

  • Partager sur Facebook
  • Partager sur Twitter
3 juillet 2019 à 7:58:35

dans le code de l'interruption je ne vois pas d'optimisation en mesure de te faire rééelement gagner du temps.

Autre question (curiosité maladive :) ), pourquoi utiliser une fréquence de 134KHz pour le fonctionnement du truc et pas 44KHz (ou autre d'ailleur) ?

  • Partager sur Facebook
  • Partager sur Twitter

la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

Mon GitHub

3 juillet 2019 à 14:26:35

J'ai utilisé la fréquence la plus élevée possible sans que sa plante.

La note la plus aigüe d'un piano (le C7 dans mon tableau) a une fréquence de 4186 HZ. pour la générer je dois basculer la sortie 2 fois plus rapidement pour générer une onde carrée, soit à 8372 HZ. Si je ne contrôle le temps écoulé qu'à une fréquence de 44KHz seulement , ça ne me fait pas une grande précision. La note sera fausse. Evidement, plus la note à générer est grave, plus elle sera juste, la période à générer étant beaucoup plus longue...

Avec ton exemple de 44 KHz, pour faire le C7, je devrai compter jusqu'à 44000/8372 = 5 avant de basculer le pin. Pour la note juste en dessous, le B6 sur un piano, qui sonne à 3951 Hz, je devrais basculer le pin tous les 44000 / (3951*2) = 5 également. On ne pourra donc pas différencier ces 2 notes voisines, elles sonneront exactement pareil  !! (Dons mon code, je ne calcule pas en fréquence mais en période. Mais le principe est le même. )

Si je pouvais aller au delà de 134 kHz, je le ferais, pour gagner en justesse. Seulement le programme ne fonctionne plus si j'augmente la fréquence : l'interruption est trop longue...

-
Edité par Umbre37 3 juillet 2019 à 14:27:05

  • Partager sur Facebook
  • Partager sur Twitter
3 juillet 2019 à 14:46:44

Je ne sais pas trop pour optimiser ça, mais pense à compiler en -O2 ou -O3. ça va activer les optimisations du compilo - tu pourras voir si ça aide..

Mais on dirait que la correction de ton programme dépend du temps qu'il met à exécuter des instructions, ce qui rend la chose pas triviale

  • Partager sur Facebook
  • Partager sur Twitter
3 juillet 2019 à 15:32:25

Salut potterman ! Je compile avec l'IDE Arduino. Je ne sais pas du tout ce qu'il fait. Il y a des options de compilation dedans ? Je ne sais même pas si il respecte vraiment la norme du C. (j'imagine que oui)...

  • Partager sur Facebook
  • Partager sur Twitter
3 juillet 2019 à 16:32:19

A vrai dire, après une petite manipulation du fichier .ino, c'est un compilateur C++ qui opère.
  • Partager sur Facebook
  • Partager sur Twitter
3 juillet 2019 à 16:39:48

Merci zoup,

zoup a écrit:

A vrai dire, après une petite manipulation du fichier .ino, c'est un compilateur C++ qui opère.

du coup comme c'est pour de l'embarqué, je pense qu'ils ont tout fait pour optimiser le code...

Ca fonctionne comme ca. C'est juste un peu faux, mais c'est déjà bien. Merci bcp pour votre aide.

  • Partager sur Facebook
  • Partager sur Twitter
3 juillet 2019 à 17:09:36

Je ne sais pas si il y a des options de compilation. ça dépend du compilateur qu'ils utilisent. Si tu regardes dans la doc ou si tu fais des recherches sur internet tu trouveras peut-être..

Pour prendre l'exemple du compilateur GCC sur un processeur x86 (genre le processeur Intel de ta machine perso), tu peux lui spécifier -O0 qui signifie de ne faire aucune optimisation, -O1 qui signifie de faire les optims les plus simples, -O2 où il va faire du réordonnancement d'instruction en plus avec d'autres optims un peu plus fortes, et -O3 où il va se mettre à faire du déroulage de boucle et des trucs du genre..

Selon le code source, le processeur, et le compilateur, la différence entre -O0, -O1 et -O2 peut être énorme. De l'ordre d'un x2 sur la performance.

Peut-être que Arduino IDE utilise déjà ces options de compilations de base. Ou peut-être qu'il n'en utilise pas.

La phrase "c'est pour de l'embarqué, je pense qu'ils ont tout fait pour optimiser le code" est loin d'être vraie - parce que quand tu optimises, l'assembleur devient moins lisible. Sans optimisation, tu as une correspondance assez évidente entre ton code C et l'assembleur généré, tu peux dire avec précision "cette ligne de l'assembleur vient de telle ligne du C". Quand tu utilises des optimisations, en général ça casse cette propriété là, et donc certains fabricants de systèmes critiques (par exemple : fusée, avion..) vont compiler leur code sans aucune optimisation afin de pouvoir vérifier que le code assembleur correspond bien au code source, et que le compilateur n'a pas fait n'importe quoi entre temps (un compilo peut avoir des bugs).

ça peut donc valoir le coup de vérifier si les options d'optimisation sont activées - et si elles ne le sont pas, de les activer.

Par contre, si ton code repose sur des temps d'exécution - peut-être que faire exécuter des parties du code plus vite, ça va en fait fausser ton programme. Par exemple si telle fonction fait maintenant 20 cycles au lieu de 40 après optimisation, peut-être que ça va te fausser le reste de ton code, vu que tout sera décalé de 20 cycles.

  • Partager sur Facebook
  • Partager sur Twitter
4 juillet 2019 à 2:08:04

En fait, le bout de code que je voudrais optimiser est une interruption. C'est à dire une fonction appelée automatiquement tous les n ticks d'horloge. Je définis n moi même. C'est le rôle du#define TIMER_TOP au début du code. Si le processeur fait autre chose au moment où l'interruption est déclenchée il s'arrête, exécute l'interruption et reprend sa tâche après. Donc non, améliorer cette fonction ne va pas fausser mon code. Je pourrais juste l'appeler plus souvent et donc gagner en précision, en diminuant la valeur de TIMER_TOP. Le reste de mon programme s'adapte tout seul à l'augmentation de fréquence.

Pour l'optimisation par le compilateur, on parle d'Arduino, c'est prévu pour faire des petites choses à la maison, pas des fusées ou des avions je pense :)

  • Partager sur Facebook
  • Partager sur Twitter
4 juillet 2019 à 9:53:40

Il faut savoir que quand tu fais une interruption, le passage du code normal à l'interruption n'est pas instantané, et tu perds des cycles quoi qu'il arrive à faire ça. Si ça se trouve, le nombre de cycles que tu perds à switcher à l'interruption, est plus grand que le nombre de cycles que tu mets à faire ton code d'interruption.

Une recherche rapide me fait tomber sur ça : https://arduino.stackexchange.com/questions/8758/arduino-interruption-on-pin-change

Une simple interruption peut prendre jusqu'à 100 cycles ! Je pense que ça dépasse largement le nombre de cycles que met ta fonction à s'exécuter.

Le lien donne d'ailleurs des moyens de faire baisser ce chiffre là.. Mais je ne sais pas si c'est applicable à ton Arduino en particulier.. Et peut-être que chez toi une interruption ne prend pas aussi longtemps. Le seul moyen de savoir c'est de mesurer le temps en utilisant des fonctions de mesures de temps : tu enregistres le nombre de cycles, tu fais une interruption sur une fonction qui ne fait rien, tu enregistre le nombre de cycles, et tu regardes la différence entre les deux nombres (sachant qu'une fonction "qui ne fait rien" va quand meme mettre 1-4 cycles à s'exécuter mais ça donne une ordre d'idée du coût d'une interruption).

---

Pour les optims d'Arduino, oui peut être, mais ça ne coute rien de vérifier ! C'est pas évident qu'elles y soient par défaut.

D'ailleurs ce site là en parle : https://www.instructables.com/id/Arduino-IDE-16x-compiler-optimisations-faster-code/

  • Partager sur Facebook
  • Partager sur Twitter
4 juillet 2019 à 11:30:00

Merci pour ces infos très intéressantes. Les chiffres que tu donnes sont cohérents avec ce que j'ai observé. En effet, j'arrive à exécuter mon interruption tous les 119 cycles, dès que je passe à 118 ca donne n'importe quoi. Une centaine pour la lancer, et quelques-uns pour ma fonction. Les options de compilation de la fonction elle-même donneront donc un gain négligeable.

Je vais regarder ce que propose le lien. Merci bcp.

  • Partager sur Facebook
  • Partager sur Twitter
4 juillet 2019 à 12:46:04

Pour l'arduino, le compilateur est avr-g++, normalement.

Ca rigole pas avec l'optimisation, si on lui demande gentiment.

-
Edité par michelbillaud 4 juillet 2019 à 12:47:06

  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2019 à 10:29:15

Bon je laisse les choses en l'état. Ca fonctionne suffisamment bien. Merci à tous pour votre aide. Voici le code fini. Il permet tout simplement de faire jouer à l'Arduino un morceau à 4 voix, avec en demo un Choral de Bach :) si jamais ca amusait quelqu'un, voici le code complet :

#define TOP_TIMER 119 
#define CORRECTION_CLOCK 100      // de -200 à 200 correspond à une correction de -2% à 2% de l'horloge interne.

int clavier[90] = // clavier : demi-périodes (en micros secondes) des notes d'un piano
{
    32767, // valeur utilisée pour mettre le buzzer off.
    
    18182, // A-1       1
    17161, // A#-1      2
    16198, // B-1       3
    
    15289, // C0        4
    14431, // C#0       5
    13621, // D0        6
    12856, // D#0       7
    12135, // E0        8
    11454, // F0        9
    10811, // F#0       10
    10204, // G0        11
    9631,  // G#0       12
    9091,  // A0        13
    8581,  // A#0       14
    8099,  // B0        15

    7645,  // C1        16
    7215,  // C#1       17
    6810,  // D1        18
    6428,  // D#1       19
    6067,  // E1        20
    5727,  // F1        21
    5405,  // F#1       22
    5102,  // G1        23
    4816,  // G#1       24
    4545,  // A1        25
    4290,  // A#1       26
    4050,  // B1        27

    3822,  // C2        28
    3608,  // C#2       29
    3405,  // D2        30
    3214,  // D#2       31
    3034,  // E2        32
    2863,  // F2        33
    2703,  // F#2       34
    2551,  // G2        35
    2408,  // G#2       36
    2273,  // A2        37
    2145,  // A#2       38
    2025,  // B2        39

    1911,  // C3        40
    1804,  // C#3       41
    1703,  // D3        42
    1607,  // D#3       43
    1517,  // E3        44
    1432,  // F3        45
    1351,  // F#3       46
    1276,  // G3        47
    1204,  // G#3       48
    1136,  // A3        49   -> 440 hz
    1073,  // A#3       50
    1012,  // B3        51

    956,   // C4        52
    902,   // C#4       53
    851,   // D4        54
    804,   // D#4       55
    758,   // E4        56
    716,   // F4        57
    676,   // F#4       58
    638,   // G4        59
    602,   // G#4       60
    568,   // A4        61
    536,   // A#4       62
    506,   // B4        63

    478,   // C5        64
    451,   // C#5       65
    426,   // D5        66
    402,   // D#5       67
    379,   // E5        68
    358,   // F5        69
    338,   // F#5       70
    319,   // G5        71
    301,   // G#5       72
    284,   // A5        73
    268,   // A#5       74
    253,   // B5        75

    239,   // C6        76
    225,   // C#6       77
    213,   // D6        78
    201,   // D#6       79
    190,   // E6        80
    179,   // F6        81
    169,   // F#6       82
    159,   // G6        83
    150,   // G#6       84
    142,   // A6        85
    134,   // A#6       86
    127,   // B6        87

    119,    // C7        88
    32767   // valeur utilisée pour mettre le buzzer off.
};

int period_count_1  = 0;
int period_count_2  = 0;
int period_count_3  = 0;
int period_count_4  = 0;   

volatile int tone_1 = 32767;
volatile int tone_2 = 32767;  
volatile int tone_3 = 32767; 
volatile int tone_4 = 32767;  


void JS_Bach_BWV_244_3_Herzliebster_Jesu()
{
  char soprane[201] = { 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, 48, 48, 46, 46, 46, 46, 51, 51, 51, 51, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 56, 56, 56, 56, 54, 54, 54, 54, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 0, 53, 53, 53, 53, 54, 54, 54, 54, 56, 56, 56, 56, 58, 58, 56, 56, 54, 54, 54, 54, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 56, 56, 58, 58, 58, 58, 56, 56, 56, 56, 56, 56, 56, 56, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, 53, 53, 53, 53, 51, 51, 51, 51, 49, 49, 49, 49, 46, 46, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 51, 51, 51, 51, 49, 49, 49, 49, 47, 47, 47, 47, 47, 47, 47, 47, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 58, 58, 58, 58, 56, 56, 56, 56, 54, 54, 54, 54, 53, 53, 53, 53, 53, 53, 53, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0 };
  char alto[201]    = { 46, 46, 46, 46, 47, 47, 47, 47, 42, 42, 44, 44, 46, 46, 46, 46, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, 49, 49, 51, 51, 49, 49, 47, 47, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 53, 53, 51, 51, 51, 51, 49, 49, 47, 47, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 44, 44, 44, 44, 42, 42, 42, 42, 44, 44, 44, 44, 42, 42, 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 46, 46, 46, 46, 46, 46, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 42, 42, 42, 42, 47, 47, 47, 47, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 44, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0 };
  char tenor[201]   = { 42, 42, 42, 42, 44, 44, 44, 44, 39, 39, 39, 39, 41, 41, 39, 39, 38, 38, 38, 38, 39, 39, 39, 39, 38, 38, 38, 38, 39, 39, 41, 41, 42, 42, 42, 42, 41, 41, 41, 41, 39, 39, 39, 39, 38, 38, 38, 38, 38, 38, 38, 38, 0, 0, 0, 0, 38, 38, 38, 38, 39, 39, 39, 39, 41, 41, 41, 41, 42, 42, 41, 41, 39, 39, 41, 41, 42, 42, 42, 42, 44, 44, 44, 44, 44, 44, 44, 44, 42, 42, 42, 42, 42, 42, 42, 42, 41, 41, 41, 41, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 39, 39, 37, 37, 35, 35, 35, 35, 35, 35, 34, 34, 32, 32, 37, 37, 37, 37, 37, 37, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 40, 40, 40, 40, 39, 39, 39, 39, 39, 39, 38, 39, 41, 41, 41, 41, 41, 41, 41, 41, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 38, 38, 38, 38, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0 };
  char basse[201]   = { 39, 39, 39, 39, 32, 32, 34, 34, 35, 35, 35, 35, 34, 34, 34, 34, 34, 34, 32, 32, 30, 30, 30, 30, 34, 34, 34, 34, 27, 27, 27, 27, 39, 39, 39, 39, 38, 38, 38, 38, 39, 39, 39, 39, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 34, 34, 34, 34, 39, 39, 39, 39, 37, 37, 37, 37, 30, 30, 30, 30, 35, 35, 37, 37, 39, 39, 39, 39, 41, 41, 41, 41, 42, 42, 41, 41, 39, 39, 37, 37, 35, 35, 35, 35, 37, 37, 37, 37, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 27, 27, 27, 27, 32, 32, 34, 34, 35, 35, 35, 35, 29, 29, 29, 29, 30, 30, 30, 30, 42, 42, 40, 40, 39, 39, 37, 37, 35, 35, 34, 34, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 27, 27, 27, 27, 29, 29, 29, 29, 30, 30, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0 };
  
  delay(1500);
  for(int i = 0; i < 201; ++i)
  {
    tone_1 = clavier[soprane[i]];
    tone_2 = clavier[alto[i]];
    tone_3 = clavier[tenor[i]];
    tone_4 = clavier[basse[i]];
    delay(180);
  }
  
}

void setup ()
{
    float periode_timer = (0.0625f + (0.0625f * CORRECTION_CLOCK / 10000)) * ( TOP_TIMER + 1 ) ;
    
    //accorder piano en fonction du timer
    
    for (int i = 1; i < 89; ++i)
    {
        clavier[i] = clavier[i] / periode_timer;
    }
    
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);
    
    cli(); // Désactive l'interruption globale
    TCCR2A = 0b00000010 ;
    TCCR2B = 0b00000001 ;  // prescaler = 1
    TIMSK2 = 0b00000010 ;  // interruption locale autorisée
    OCR2A = TOP_TIMER ;    // TOP du compteur
    sei();                             // autorise les interruptions globale
    
    JS_Bach_BWV_244_3_Herzliebster_Jesu();
}

 
// Routine d'interruption

ISR(TIMER2_COMPA_vect)
{
        if (++period_count_1 > tone_1)
        {
            PORTB = PORTB ^ 0b0000001 ; //inversion de la sortie digital 8
            period_count_1 = 0;  
        }

        if (++period_count_2 > tone_2)
        {
            PORTB = PORTB ^ 0b0000010 ; //inversion de la sortie digital 9
            period_count_2 = 0;
        }

        if (++period_count_3 > tone_3)
        {
            PORTB = PORTB ^ 0b0000100 ; //inversion de la sortie digital 10
            period_count_3 = 0;
        }

        if (++period_count_4 > tone_4)
        {
            PORTB = PORTB ^ 0b00001000 ; //inversion de la sortie digital 11
            period_count_4 = 0;
        }
}

void loop () {}
  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2019 à 12:54:45

Ok super :) Mets le en résolu si le sujet est résolu ;)
  • Partager sur Facebook
  • Partager sur Twitter