Page 1 sur 1

module arduino :)

Publié : 29 avr. 2015, 18:13
par did concombre
Bonjour,
Je viens de me fabriquer un module à base d'arduino. Tout marche bien, j'ai utilisé un MCP4922 pour avoir un DAC sans avoir à filtrer les pwm de l'arduino.
J'ai 2x gate out, 2x CV out (0-5v) et 2x CV ou gate in (0-5v).
Je me demandais donc si certains d'entre vous avaient déjà fabriqué des choses de ce type et si ils n'avaient pas par hasard des codes à partager.
Je suis assez nul en programmation (mais j'y travaille) mais j'ai déjà pu faire des test avec un petit code pour un lfo que voici :

Code : Tout sélectionner

void lfo(){
 float poti = (analogRead(potB)/100.0)+0.1;
 float something = millis()/(1000.0/poti);
 int value = 2000.0 + 1900 * sin( something * 2.0 * PI  );
 analogWrite(BV,value/16); //c'est la led
 dac.outputB(value); //pour sortir sur le DAC
}
Je sais qu'il ne s'agit pas d'un module analogique mais comme je fabrique mes modules petit à petit c'est un bon moyen d'avoir des valeurs et des durées "quantifiables" pour tester si tout marche bien comme prévu sans voir à sortir un oscillo etc etc et (pour le moment j'ai peu de modules) à terme diminuer la place que pourraient prendre certains modules (comme un séquenceur par exemple) ou être interchangeable facilement avec un ordinateur pas loin (et je me rends compte que j'ai toujours un ordinateur pas loin quand je fais de la musique).
Enfin voilà. Si ça vous intéresse :)

Re: module arduino :)

Publié : 29 avr. 2015, 18:20
par did concombre
j'ai oublié de dire qu'il y a aussi de potards et un encoder rotatif

Re: module arduino :)

Publié : 29 avr. 2015, 18:21
par Caribo
Hello,
As tu regardé du coté des fabricants de modules sur base d'arduino ?
Je penses particulèrement au Ardcore chez Snazzy Fx et Euro-Duino chez Circuit Abbey :
- http://snazzyfx.com/products/ardcore/
- http://www.circuitabbey.com/EuroDuinoKit.html

Sur ces pages des produits, tu as des liens pour voir des codes déjà prévu à cet effet, peut être peux tu les adapter en fonction de ton montage !

Re: module arduino :)

Publié : 29 avr. 2015, 18:24
par did concombre
oui, c'est en voyant ces modules que je me suis dit que j'allais en faire un et non, j'ai pas encore regardé... :roll:

Re: module arduino :)

Publié : 30 avr. 2015, 10:06
par ri0h
Je n'ai pas fabriqué de modules à proprement parler mais j'ai fait quelques tests en essayant de faire cracher de l'audio à l'Arduino (via sa PWM), le conseil que je peux te donner, c'est de faire un maximum de compromis pour limiter ton temps de calcul, recalculer un sinus à chaque fois que tu changes la valeur de ton LFO c'est un coup à beaucoup ralentir la machine, idem pour les calcul avec des nombres flottants (là tu lui fais faire un arrêt cardiaque à l'Arduino), si tu veux faire a * 3.14, ça ira plus vite de faire (a*3215)>>10 par exemple, toujours privilégier les calculs avec des entiers.

Le truc c'est d'avoir ton tableau de sinus calculé à l'avance, ça te permet une fois que tu marches en interruption de timer de récupérer juste la valeur qui t'intéresse dans ton tableau sans recalculer, par contre après tu satures vite la RAM ou le flash si ton tableau fait rien que 512 ou 1024 cases, donc ça reste quand même un peu de la bidouille, l'Arduino étant quand même très light pour beaucoup de ces applications.

Re: module arduino :)

Publié : 30 avr. 2015, 10:40
par ACX
Je viens juste de terminer mon LFO basé sur un PIC, alors je peux expliquer brièvement le principe.

On part d'un registre appelé l'accumulateur de phase. Ce registre est chargé à une valeur MAX, puis il est décrémenté régulièrement (par une interruption générée par un Timer par exemple). Lorsqu'il arrive à 0 cet accumulateur est rechargé à la valeur MAX et ainsi de suite. On obtient donc un système périodique dont la fréquence dépend de la valeur de MAX, de la valeur du décrément et de la fréquence des interruptions.
Le plus simple est de jouer sur un seul de ces paramètres comme la valeur du décrément. Plus sa valeur est grande et plus la fréquence sera élevée.
A partir de là, si on envoie directement la valeur de l'accumulateur de phase dans le DAC, on obtient une magnifique dent de scie descendante. Pour la dent de scie ascendante on effectue une simple soustraction, en panachant les deux on a un triangle, et on obtient enfin une onde carrée en envoyant simplement les valeurs MAX et zéro.

Pour le sinus c'est un peu plus compliqué. Comme le dit ri0h, le microcontrôleur n'est pas capable d'effectuer ces calculs aussi vite. On passe donc par une table d'onde.

Il faut d'abord calculer les sinus pour mettons 1024 valeurs. Très facile avec Excel, impossible sinon. Cette table est ensuite chargée dans le µC et on se sert cette fois ci des valeurs de l'accumulateur de phase comme index pointant vers cette table. Petite astuce, pour ne pas prendre trop de place en mémoire on peut se servir du fait que la sinusoïde est doublement symétrique et donc une table de 256 suffit pour avoir la précision d'une table de 1024 valeurs.

On peut de la même manière fabriquer toutes les formes d'onde que l'on veut.

Re: module arduino :)

Publié : 30 avr. 2015, 11:43
par baloran
ACX a écrit :Petite astuce, pour ne pas prendre trop de place en mémoire on peut se servir du fait que la sinusoïde est doublement symétrique et donc une table de 256 suffit pour avoir la précision d'une table de 1024 valeurs.
Oui et autre astuce , l'interpolation ;)

Imaginons un compteur de 0..255 pour les indices du tableau dans lequel sont rangées les valeurs pré calculées d'une forma d'onde. A très basse vitesse de lecture, un LFO bien lent par exemple, les 256 valeurs vont générer des paliers éventuellement audibles. On peut donc imaginer un compteur non sur 8 bits (0..255) mais plutôt sur 16 bits (0..65535) . Dans ce cas, les 8 bits de poids fort donnent l'indice dans le tableau, les 8 bits de poids faible le ratio de chacune des deux valeurs adjacentes du tableau. Ainsi on obtient un beau signal avec une définition de quasi 65536 pas avec seulement 256 valeurs.

Exemple : Onde[0] = xxx Onde[1] = xxx Onde[2] = xxx Onde[255] = xxx et inc l'incrément de 0..65535

si inc= 0 alors signal Onde[0] * 256 / 256 + Onde[1] * 0 / 256
inc = 10 alors signal Onde[0] * 246 / 256 + Onde[1] * 10 / 256
inc = 100 alors signal Onde[0] * 146 / 256 + Onde[1] * 100 / 256
inc = 255 alors signal Onde[0] * 1 / 256 + Onde[1] * 255 / 256
inc = 256 alors signal Onde[1] * 256 / 256 + Onde[2] * 0 / 256
etc....
en gros cela donnerait un truc du genre

signal = Onde[ ( inc >> 8 ) ] * ( 256 - ( inc & 0x00FF ) ) / 256 + Onde[ ( inc >> 8 ) + 1 ] * ( inc & 0x00FF ) / 256

Bon, il y a encore des optimisations possibles pour soulager le CPU et des casts importants à placer mais ça, ce sont les joies de l'apprentissage :wink:

Avec des simples incréments , masques logiques et des rotations de bits, cela reste des calculs "simples" pour les "petits PIC".

Pour finir, afin d'économiser de la "RAM" , tu peux ranger les valeurs des tableaux dans le code source avec les directives PROGMEM etc...

J'avais fait il y a quelques temps un projet de séquenceur / arpégiateur etc sur la même base que la tienne : arduino et 4922.
http://bricosique.blogspot.fr/p/interfa ... ateur.html
Le code source complet est dispo (pas d'interpolation, mais des PROGMEM pour les modulations )

Re: module arduino :)

Publié : 30 avr. 2015, 14:50
par Salmacis
Pour ma part j'utilise un timer dont je regle la frequence de l'IT (interuption)
A chaque IT j'incremente un compteur et quand il attend la valeur max (360 dans mon cas) je le reinitialise à zero.

En sortie du LFO en fonction du compteur j'ai donc avec Cpt = compteur

SINUS = Tabsinus[Cpt] // Table de sinus
SAW = cpt *0xFFF/360
INVSAW = 0xFFF - cpt*0xFFF/360
SQUARE = si cpt < 180 0 si cpt >=180 0xFFF
S&H = si cpt = 180 valeur aleatoire Rand()
Noise = TabNoise[cpt] // Table remplie avec des valeurs aleatoires
LAG = rampe entre deux valeurs aleatoires

Tu peut aussi eventuellement mettre une valeur de pourcentage de ton LFO vers ta sortie CV OUT afin de regler le taux du LFO.

Je n'ai pas implante cela sur un Arduino avec leur IDE mais sur un Atmel XMEGA, un Arduino DUE et une Nucleo STM32L152RE.

Re: module arduino :)

Publié : 30 avr. 2015, 22:41
par did concombre
je viens de rentrer chez moi, merci pour vos réponses, je lis ça au plus vite (mais pas maintenant)

Re: module arduino :)

Publié : 30 avr. 2015, 23:55
par Portamento
Hi,
tu peux également faire une pseudo table d'onde :
Dans le setup, tu utilises tes fonctions mathématique pour calculer la valeur de CV souhaitée que tu stokes dans l'eeprom. Dans le loop, il te resteras à aller lire l'eeprom en fonction d'un compteur de boucle. Cela t'évite d'avoir à faire des calcul mais l'eeprom est assez lente. Pour un LFO ou ADSR, etc c'est assez rapide.

Tu as une explication de la programmation des tables d'ondes ici : http://www.cfp-radio.com/arduino/wavefa/wavefa.html" onclick="window.open(this.href);return false;

J'ai fait quelques modules à base arduino. Regarde le site de ma signature. :smile:

Re: module arduino :)

Publié : 02 mai 2015, 17:23
par did concombre
merci pour les conseils, je comprends pas encore tous les codes ou bouts de codes fournis mais déjà je sais que je dois creuser vers les tableaux pour stocker les valeurs des formes d'ondes. Le truc des symétries qui réduisent la quantité de mémoire c'est une bonne chose à savoir. Je posterai ce que je trouve ici si jamais :)