Spécifications du module
- 2 CV (0-5V) (réglage précis de la conversion dans le logiciel) + 2 Gates
- Midi vers CV suivant la norme 1V/Octave sur cinq octaves (accord fin, transposition)
- Mode Dual et Split
- Gestion de l'expression, vélocité, modulation et bend
- LFO combinable avec modulations, plusieurs formes d'onde
- Gestion du MIDI Clock, Start, Stop etc...
- Arpégiateur (différents motifs, range)
- Mini séquenceur 32 pas.
- Midi Thru, Midi Out
- Interface ergonomique
Plutôt que de longues explications, une petite vidéo ;)
Le schéma
Le DAC et l'optocoupleur sont montés sur une plaque proto pour Arduino comme celle-ci
Mon DAC est un cms, la plaque proto intègre un emplacement pour ce type de composant.
Pour le compilateur, j'utilise et recommande la dernière version dispo à cette adresse : http://arduino.cc/en/Main/Software
Le code source
Le dossier MIDI doit être placé dans libraries. Exemple : C:\arduino-1.0.1\libraries\MIDI
Le fichier LL412.ino peut être placé dans un dossier LL412 de vos documents. C'est lui qu'il faudra ouvrir avec l'environnement de développement Arduino.
La façade est en plexi (PMMA) avec un feuille de SCOTCHMARK pour la sérigraphie...C'est facile à percer et la transparence parfaite évite les découpes pour l'afficheur, car question travail soigneux... ;)
J'ai trouvé l'afficheur pour pas cher sur la baie, celui-ci n'est pas rétro-éclairé . Aussi, tout afficheur type HD44780 2 lignes de 32 ou 40 caractères fera l'affaire. Cela s'adapte en 2 secondes dans le code source.
Une version en 5U avec un 4x20 devrait pouvoir être envisagé en organisant la façade autrement, le code source s'adaptera facilement.
Pour l'alimentation, un bloc secteur pour pédale de guitare (+9 v) fait l'affaire mais il faut inverser la polarité, sur l'Arduino c'est un connecteur 2.1mm avec + au centre.
Quelques photos du b..désordre intérieur et de la façade
et la version 5U de MikZed53
Quelques remarques
L'accord se règle par logiciel. La variable REF_1V donne la correspondance. Chez moi , c'est 896 pour 1v/octave. Pour régler l'accord, vous pressez A1 et tournez A1 jusqu'à "1 VOLT" et là avec les poussoirs A2 et A3 vous changez la référence pour que la même note soit juste sur au moins 4 octaves. L'utilisation d'un simple accordeur électronique est très pratique pour cela.Pour l'affichage 2x32, j'ai défini six zones décrites dans le prog, ligne 400:
byte ZL[]= {9, 9, 9, 9, 9, 9};
byte ZPOS[]= {1, 10, 19, 1, 10, 19};
byte ZLIN[]= {0, 0, 0, 1, 1, 1};
ZL est la largeur des zones
ZPOS la colonne de départ
ZLIN la ligne
La zone 1 a une longueur de 9, commence colonne 1 sur la ligne 0
...
La zone 6 a une longueur de 9, commence colonne 19 sur la ligne 1
Pour 16 caractères x 2 lignes on peut faire trois zones
xxxxxx xxxx xxxx
xxxxxx xxxx xxxx
ce qui donne
byte ZL[]= {6, 4, 4, 6, 4, 4};
byte ZPOS[]= {0, 7, 12, 0, 7, 12};
byte ZLIN[]= {0, 0, 0, 1, 1, 1};
Ne pas oublier dans setup()
ligne 1251 : lcd.begin(32, 2);
devient lcd.begin(16, 2);
Il faudra aussi modifier quelques libellés dans le code qui sont trop longs ;)
Ci-dessous des programmes simplifiées pour tester chaque organe.
Pour le montage, il est plus simple de tester chaque élément avant d'envoyer tout le code. C'est le rôle de ces petits bouts de codes.
L'afficheur
L'afficheur doit afficher Bonjour de LL412LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#define NB_COLONNE 32
#define NB_LIGNE 2
int cpt=0;
void setup()
{
lcd.begin(NB_COLONNE, NB_LIGNE);
lcd.clear();
}
void loop()
{
lcd.setCursor(0,0);
lcd.print("Bonjour de LL412");
lcd.setCursor(0,1);
lcd.print(cpt);
cpt++;
delay(1000);
}
Les gates
Les deux gates doivent battre la seconde...
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#define NB_COLONNE 16
#define NB_LIGNE 2
#define GATE_0 8
#define GATE_1 9
int cpt=0;
void setup()
{
pinMode(GATE_0,OUTPUT);
pinMode(GATE_1,OUTPUT);
digitalWrite(GATE_0,LOW);
digitalWrite(GATE_1,LOW);
lcd.begin(NB_COLONNE, NB_LIGNE);
lcd.clear();
}
void loop()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Gates On");
digitalWrite(GATE_0,HIGH);
digitalWrite(GATE_1,HIGH);
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Gates Off");
digitalWrite(GATE_0,LOW);
digitalWrite(GATE_1,LOW);
delay(1000);
}
Le midi In
Une note jouée au clavier doit être affichée (appui et relâchement).
#include <LiquidCrystal.h>
#include <MIDI.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#define NB_COLONNE 16
#define NB_LIGNE 2
void HandleNoteOn(byte channel, byte pitch, byte velocity)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Note On");
lcd.setCursor(0,1);
lcd.print(pitch);
}
void HandleNoteOff(byte channel, byte pitch, byte velocity)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Note Off");
lcd.setCursor(0,1);
lcd.print(pitch);
}
void setup()
{
lcd.begin(NB_COLONNE, NB_LIGNE);
lcd.clear();
MIDI.begin(0);
MIDI.setHandleNoteOn(HandleNoteOn);
MIDI.setHandleNoteOff(HandleNoteOff );
}
void loop()
{
MIDI.read();
}
Un convertisseur Midi CVsimplifié.
Chaque note jouée au clavier sera convertie en tension et gate sur CV 0 et GATE 0#include <LiquidCrystal.h>
#include <MIDI.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO Pa sutilisé pour le moment
#define SPICLOCK 13//sck
#define DAC_0 10//ss
#define DAC_1 9//ss un seul DAC pour le moment
#define GATE_0 8
#define GATE_1 9
#define NB_COLONNE 16
#define NB_LIGNE 2
int REF_1V = 895; // coorespondance DAC 1v/Oct
void p_CV(byte port, int pitch)
{
dac_Out(port, (long)REF_1V * pitch / 12 );
}
void HandleNoteOn(byte channel, byte pitch, byte velocity)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Note On");
lcd.setCursor(0,1);
lcd.print(pitch);
p_CV(0, pitch);
digitalWrite(GATE_0, HIGH);
}
void HandleNoteOff(byte channel, byte pitch, byte velocity)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Note Off");
lcd.setCursor(0,1);
lcd.print(pitch);
p_CV(0, pitch);
digitalWrite(GATE_0, LOW);
}
// ------------------
// Ecriture tension sur DAC
// ------------------
void dac_Out(int port, uint16_t sample)
{
uint8_t dacSPI0 = 0;
uint8_t dacSPI1 = 0;
byte selector;
switch (port)
{
case 0:
selector = DAC_0;
sample = sample | 0b0111000000000000;
break;
case 1:
selector = DAC_0;
sample = sample | 0b1111000000000000;
break;
}
dacSPI0 = (sample >> 8) & 0x00FF;
dacSPI1 = sample & 0x00FF;
digitalWrite(selector,LOW);
SPDR = dacSPI0; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
SPDR = dacSPI1;
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
digitalWrite(selector,HIGH);
}
// ------------------
// Setup Arduino
// ------------------
void setup()
{
byte clr;
lcd.begin(32, 2);
lcd.clear();
// Initialisation DAC(s) et SPI
pinMode(GATE_0,OUTPUT);
pinMode(GATE_1,OUTPUT);
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(DAC_0,OUTPUT);
digitalWrite(DAC_0,LOW);
SPCR = (1<<SPE)|(1<<MSTR);
clr=SPSR;
clr=SPDR;
delay(10);
// Initialisation Midi
MIDI.begin(0);
MIDI.setHandleNoteOn(HandleNoteOn);
MIDI.setHandleNoteOff(HandleNoteOff );
pinMode(GATE_0,OUTPUT);
pinMode(GATE_1,OUTPUT);
digitalWrite(GATE_0,LOW);
digitalWrite(GATE_1,LOW);
}
void loop()
{
MIDI.read();
}
@+
Ce module est une pure merveille , je le recommande à tous , un grand bravo et merci à toi Laurent de nous faire partager ta passion ;) Mik
RépondreSupprimerSuper content que tu ais pu mener à bien ce montage, ton expérience et ta patience serviront à d'autres, je l'espère. Le module de Mik est en 5U , intégré dans un Yusynth, avec un afficheur 2x16, ca marche !
RépondreSupprimerMerci ;)
Hi, This is beast module, I want it so bad :)
RépondreSupprimerIt's hard to find DAC chip MCP4922 in my country,
- Is MCP4822 can work on it (I have it laying around) ?
- The feature is cool, but if I just need only Arpeggiator, Sequencer and Step record, How to change the code? I'm newbie in programmer.
Sorry for my English
Mercy
-Toby
Hi Tobby,
RépondreSupprimerYes, the MCP4822 Works Fine.
For change the code, i can help you a little but if you don't use function, it's more easy :D :D
Regards ;)
Laurent
Thanks for your response.
SupprimerI like Roland SH101 and SC Pro One an arpeggiator feature for mono synth. I dont own them, my plan is to build mono synth with an arpeggiator.
So, Can you help me how to change or deleted the code line?
If you dont mind, this is my mail : saw6667061@gmail.com
Or you can publish here. :)
Merci,
Toby
Hello Toby,
SupprimerSorry for the tardive response ;)
Yes, i can HELP you for cleaning the code.
Regards
Any clue? :)
RépondreSupprimerBonjour,
RépondreSupprimerje dispose d'une modeste config midi autour de Cubase (clavier DX7, expandeur Yam TG55, BàR Boss DR550) et je cherchais depuis un moment un moyen simple d'y inclure mon vieux Moog Rogue que je viens de re-régler et nettoyer après plusieurs années de séjour au sous-sol (ah les joies de la mousse de polyether qui fond sur les potentiomètres au bout de quelques années)
Votre petit module me paraît sympathique et me permettra de retrouver les "joies" de la programmation (je suis développeur retraité)et de découvrir l'arduino qui m'intéresse à d'autres titres que pour la musique.
Je ne manquerai pas de vous faire part de l'avancement de la chose lorsque je me lancerai.
En attendant, bravo pour vos réalisations !
Bonjour Jean Benoit
SupprimerPardon pour la réponse tardive, je me suis éloigné du micro quelques temps ;) J'aimerai avoir des sous sols qui recèlent de si jolies vieilleries :D
A votre disposition pour toute info. L'arduino et les pics sont des petites machines vraiment motivantes.
Bien cordialement,
Bonjour,
Supprimerpremière étape : un kit arduino est en commande !
Après réception, je testerai un peu les fonctions de base pour me familiariser avec les interactions vis-à-vis de l'extérieur.
En effet, quand je bossais, ma "sortie" classique se faisait via une imprimante ou un traceur. J'ai donc tout à apprendre des E/S via un transistor, un dac ou un optocoupleur. :-)
Bonjour Jean Benoît,
SupprimerJ'ai connu aussi les interfaces parallèles, les UARTs ( j'ai développé des protocoles de comm, on dialoguait avec le contrôleur en directe :D)
Pour qui a connu cela, l'Arduino, c'est de la récréation, de la programmation plaisir et un super terrain de jeu ;)
Amicalement,
Bonjour,
Supprimerj'ai profité de 3 semaines d'un bon rhume pour enfin m'atteler à ce projet. J'ai avancé petit à petit en testant avec ces petits bouts de code diablement utiles.
Au passage, et si ça peut aider de futurs constructeurs, j'ai longtemps cherché pourquoi je n'avais pas de signaux "NoteOff". C'est qu'en fait, mon DX7, né avant la norme midi, utilise un signal NoteOn" avec une velocité nulle.
Autre souci rencontré, je suis obligé de déconnecter Rx/Tx quand j'upload un programme. Ce problème ne semble pas se produire avec toutes les versions de cartes d'après mes recherches sur internet.
J'en suis maintenant à la compilation du programme définitif. Et là, je crois que je dois repartir sur des bases plus saines : ma carte arduino, achetée à bas prix à HongKong ne semble pas supporter la gestion de la bibliothèque avr/pgmspace.h (la ligne correspondante est grisée dans la liste des bibliothèques)
Donc, suite au prochain achat !
Amicalement,
Jean
Re,
Supprimerje me réponds à moi-même, ayant terminé ce montage sympa. Il n'y avait pas de souci de compatibilité restreinte avec mon clone d'origine incertaine (DX.com) mais vu ma lenteur à me décider, depuis la naissance de LL412, un certain nombre de mises à jour avaient eu lieu dans l'IDE et les bibliothèques, en particulier, avr/pgmspace, qui a été mise plus en conformité avec les évolutions du C (tout ceci me dépasse un peu, mais j'ai réussi à ne pas me noyer) Il a donc fallu corriger un petit nombre d'instructions, et finalement presque tout est rentré dans l'ordre. Presque, en effet, car il restait bien sûr un oubli de câblage du +5V vers le MCP4922, et une inversion CV1 / CV0 par rapport aux GATE.
J'ai donc réalisé une mise en boîte au format rack 1U pour être en accord avec les quelques bricoles déjà installées. Et tout roule !
Merci, Laurent
Amicalement,
Jean
Bravo ! et désolé pour le silence (oupppss) , j'ai le nez dans le guidon et zappe des réponses. Si tu veux mettre en ligne ton code source à jour, n'hésite pas, un mail et je le publie ici.
SupprimerBonjour,
SupprimerJe me lance aussi dans l'aventure. Mon clavier maitre ne transmet pas non plus de vrai message NoteOff,mais NoteOn avec vélocité nulle. Du coup, la fonction handlenoteoff n'est jamais appelée et la gate ne retombe jamais.
Une idée ?
Merci d'avance pour vos réponses!
JB
Bonjour,
SupprimerIl suffit d'ajouter après le
void HandleNoteOn(byte channel, byte pitch, byte velocity)
{
if (velocity==0 ) {
HandleNoteOff(channel, pitch, velocity);
return;
}
....
Bon courage ;)
Merci pour cette réponse ultra rapide! Et en plus ça fonctionne!
SupprimerComment se fait-il que certains claviers MIDI ne transmettent pas de message NoteOff ? Aucun des 2 que j'ai testé n'en transmet, et à en croire la toile, c'est assez courant...
JB
Bonjour, super projet, pour l'utilisation d'un mcp4822, quelles seraient les modifications à apporter au code? Je ne sais pas si je vois juste mais le 4922 peut aller jusqu'à sa tension d'alimentation (5V) mais le 4822 semble aller jusqu'à la moitié (selon la fiche technique) il serait toujours possible d'amplifier la tension pour obtenir une échelle de 0 à 5v avec un ampli-op (on pourrait même aller de 0 à 10 pour plus d'octaves)
RépondreSupprimerJ'aimerais aussi savoir à quelle note équivaut la valeur 0V dans ton programme merci
Bonjour Julien, ouppps, je viens juste de découvrir ta question. Pour le MCP4822, je dois vérifier mais c'est simple. Le 4822 et le 4922 ont le même range. les deux permettent par programmation d'activer le x2.
SupprimerDans LL113, j'utilise des MCP4822 amplifiés pour atteindre 0-10V ;)
Bonjour,
RépondreSupprimerJ'admire la simplicité et l’originalité de ce montage. J'ai, cependant, une petite question qui concerne tous les Midi to CV, et celui-ci en particulier.
Le pitch de la note, convertie en CC se fait par simple division dans la fonction
dac_Out(port, (long)REF_1V * pitch / 12 );
ce qui est logique pour l'accordage chromatique. En midi, on est lié aux tuning du synthé ou sampleur. J'ai passé pas mal de temps a jouer avec des tableaux de microtunuung, ce qui est très galère en midi propre. Certains AUs comme Albino acceptent des tableaux Scala ce qui facilite la tache.
Ma question, que le me permettrai a poser aux anciens utilisateurs et concepteurs de synthés analogiques est: y a-t-il des expériences et des convertisseurs midi/cv qui supportent cela, et particulièrement au créateur de cette merveille : dans quelle mesure cela peut être utile à mettre en place.
Cordialement,
Vic
Bonjour Vic,
SupprimerMerci pour ces mots ;)
Dans mon projet de polyphonique, chaque VCO et VCF est piloté par la somme de deux tensions : une théorique équivalente à la formule de ll412 et une fine qui a été calculée par la procédure d'Autotune. Tout est faisable, comme remplacer la fonction par une table personnalisée. Mais la difficulté est d'imaginer une procédure ergonomique pour mettre à jour cette table.
Musicalement,
Laurent
Bonjour,
RépondreSupprimerJ'ai réalisé le projet, avec quelques mods mineures: Ajout des diodes de protection et les DEL d'affichage sur chaque sortie gate, ajout d'un tampon AOP a chaque CV, des terminaux pour la prog facile du AVR. Le morceau de code est terriblement complexe et je m'aventure a petit pas. Cela dit, ce projet est une pure merveille ! J'apprécie particulièrement le mode Arp Transpose et le Sequenceur. Les LFOs ont une forme d'onde bien curieuse, ça fait un effet sur les FM et PWM en très basse fréquence :D
J'ai deux zones d'ombre tout de même: Comment la modulation est gérée et en quel mode précisément. Pour le Pitch et l'EXP c'est assez clair. Et en deuxième place: Ou est le Do de référence: C1 ou C5? Car une fois les 5 octaves atteintes ça recommence par le plus bas.
Voila, c'est pas grand chose. Je vais poster la photo du pojet une fois la sérigraphie réalisée, pour le moment c'est de l'alu brut.
Cordialement,
Vic
Merci pour ces mots et très bonnes idées ces modifs.
SupprimerJe ne comprends pas trop la question sur la modulation ? d'un point de vue programmation ? ou du point de vue ergonomie ?
Il n'y a pas de Do de référence, juste la possibilité de définir dans les paramètres 0v = note 24 ou 32 ou...
Oui, je parle de mémoire, après 4 octaves et des brouettes, on dépasse la résolution du DAC et il retourne à zéro (modulo 4096 en gros...) Un peu de code permettrait de corriger ce point. Pour le moment, je n'ai plus de ll412, donc je suis très théorique :D :D
Bien cordialement,
Laurent
Bonjour,
RépondreSupprimerPour la modulation je l'avais imaginé de la façon suivante: En mode Normal, en CV1 on reçoit la note 1/V et en CV2 la modulation de 0 a 5V, en continu. Dans le menu, bouton 3, les choix basculent être différentes types d'expressions et LFOs. Pas de Modulation. Ou c'est active dans un autre mode? En bref, de quel façon et dans quel mode la modulation est prise en compte?
Cordialement,
Vic
PS: Je suis en train de moder le code pour étudier les possibilites ...
hello laurent ca fait longtemps . aloRS à quand une petite mise à jour stp :)
RépondreSupprimerHello Mike
RépondreSupprimerIl n'y aura pas de mise à jour de ce projet ... venant de moi ;)
Bien à toi
Salut, petit bond en 2020 (dsl pour le deterrage). Petite question concernant la librairie pgmspace. les prog_uchar semblent poser probleme. As-tu reessayé de compiler avec les versions recentes d'arduino ? merci d'avance pour ta reponse et felicitations pour ce projet que je decouvre que maintenant
RépondreSupprimerHello, je découvre aussi en 2020 ce super projet et je tombe sur le même pb. j'essaie de comprendre et de corriger mais mes connaissances en programmation sont assez limitées. Le 1er qui trouve indique la solution aux autres ?
RépondreSupprimerMerci.
Et Laurent, vu comment c'est programmé, ça sent le pro et donc n'auriez vous pas quelques instants à nous aider car ça ne doit pas être compliqué pour vous, même si je comprends que vous ne ferez pas la maintenance pendant des décénnies... Merci, et merci surtout pour le partage de ce qui semble être un vrai bijou ;-)
Cordialement
ALors pour Mattheewww, j'ai fait les modifs suivantes et ça compile mais je ne peux pas tester, je n'ai pas reçu tout le matériel :
RépondreSupprimerj'ai remplacé les
PROGMEM prog_uchar Sinus[] = {... par
PROGMEM const char Sinus[] = {
ensuite j'ai remplacé le
PROGMEM prog_int16_t Onde_Hz[] = { par
PROGMEM const int16_t Onde_Hz[] = {
ensuite ligne 109 et+, j'ai remplacé les
prog_char m_Reglage_0[] PROGMEM = "ACCORD"; par
PROGMEM const char m_Reglage_0[] = "ACCORD";
plus loin j'ai remplacé les
const char *menu_Reglage[] PROGMEM = { par
const char menu_Reglage[] = {
idem pour toutes les séries de la même façon.
dis mois ce que ça donne, perso j'ai la version 1.8.12.
A+
Alors j'ai essayé un truc tout bete, jai jai pris la version 1.0 d'arduino (de 2012l. Ca Compile sans probleme er ca telecharge 😄
RépondreSupprimerJe l'ai fait au format 3u. Il me reste des pcb si besoin
RépondreSupprimerhttps://zupimages.net/viewer.php?id=20/24/u6sp.jpg
https://scontent-mrs2-1.xx.fbcdn.net/v/t1.0-9/104385450_2967758479944124_8517072070096468865_o.jpg?_nc_cat=108&_nc_sid=8024bb&_nc_ohc=eisB-PpZA8gAX_-XvbT&_nc_ht=scontent-mrs2-1.xx&oh=d4c5f0d40129a204a515294603705999&oe=5F0EEC2B
RépondreSupprimersuper, tu es déjà bien avancé ! moi j'attends encore les pièces et j'ai commandé un afficheur 4002. par contre le pcb peut m'intéresser. tu as des photos ? je ne sais pas comment passer par mp pour ne pas pourrir ce fil ?
RépondreSupprimerAllo Mattheewww ?
RépondreSupprimermerci Matthewww...
RépondreSupprimersalut, dsl du retard j'ai été pas mal occupé. Contacte moi en MP pour le pcb ;) (par mail a mattdusud@gmail.com)
Supprimer