Panneau de modération ]

[Effet] EMM Harmony Generator Version 2018

Une idée ? Creuser un schéma qui vous intéresse ? Besoin d'affiner votre projet avant de le concrétiser ? Parlons en ensemble !

[Effet] EMM Harmony Generator Version 2018

Messagepar Sebdeploudal le 23 Fév 2018 16:30

Bonjour,

Pour ceux qui ne connaissent pas : l'Harmony Generator c'est ca.
Le schéma
Image
et le schéma de principe
Image

Pour faire simple :
--> IC1 cale mon signale sur 0V;
--> IC2 est un redresseur, à sa sortie le signal part vers la partie logique et vers un switch;
--> le signal passant pas le switch passe par IC3 avant d'être mixer au signal entrant par RV2;

rôle de la partie logique :
on y entre une fréquence F qui est harmonizer puis octaver.
pour être plus clair, la fréquence est multiplié par 1,26 pour la tierce et 1,5 pour la quinte
Plus de précision ici
cette nouvelle fréquence peut à son tour être multiplié ou diviser par multiple de 2 pour passer à un ou plusieurs octave.

Enfin cette fréquence sort sous la forme d'un signal carré compris entre 0 et 5 V.
C'est ce signal qui contrôle le switch.

on peut donc simplifié comme ceci/
Image

avec ce genre de signaux
Image

Mon but est de remplacer la partie logique par un Arduino, comme cela le contrôle du switch est numérique, mais le traitement audio reste analogique.


pour le code, je compte partir de celui-ci qui fonctionne très bien même avec un basse

Code: Tout sélectionner
//generalized wave freq detection with 38.5kHz sampling rate and interrupts
//by Amanda Ghassaei
//https://www.instructables.com/id/Arduino-Frequency-Detection/
//Sept 2012

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
*/


//clipping indicator variables
boolean clipping = 0;

//data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;//keeps time and sends vales to store in timer[] occasionally
int timer[10];//sstorage for timing of events
int slope[10];//storage for slope of events
unsigned int totalTimer;//used to calculate period
unsigned int period;//storage for period of wave
byte index = 0;//current storage index
float frequency;//storage for frequency calculations
int maxSlope = 0;//used to calculate max slope as trigger point
int newSlope;//storage for incoming slope data

//variables for decided whether you have a match
byte noMatch = 0;//counts how many non-matches you've received to reset variables if it's been too long
byte slopeTol = 3;//slope tolerance- adjust this if you need
int timerTol = 10;//timer tolerance- adjust this if you need

//variables for amp detection
unsigned int ampTimer = 0;
byte maxAmp = 0;
byte checkMaxAmp;
byte ampThreshold = 30;//raise if you have a very noisy signal

void setup(){
 
  Serial.begin(9600);
 
  pinMode(13,OUTPUT);//led indicator pin
  pinMode(12,OUTPUT);//output pin
 
  cli();//diable interrupts
 
  //set up continuous sampling of analog pin 0 at 38.5kHz
 
  //clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;
 
  ADMUX |= (1 << REFS0); //set reference voltage
  ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
 
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA |= (1 << ADATE); //enabble auto trigger
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //enable ADC
  ADCSRA |= (1 << ADSC); //start ADC measurements
 
  sei();//enable interrupts
}

ISR(ADC_vect) {//when new ADC value ready
 
  PORTB &= B11101111;//set pin 12 low
  prevData = newData;//store previous value
  newData = ADCH;//get value from A0
  if (prevData < 127 && newData >=127){//if increasing and crossing midpoint
    newSlope = newData - prevData;//calculate slope
    if (abs(newSlope-maxSlope)<slopeTol){//if slopes are ==
      //record new data and reset time
      slope[index] = newSlope;
      timer[index] = time;
      time = 0;
      if (index == 0){//new max slope just reset
        PORTB |= B00010000;//set pin 12 high
        noMatch = 0;
        index++;//increment index
      }
      else if (abs(timer[0]-timer[index])<timerTol && abs(slope[0]-newSlope)<slopeTol){//if timer duration and slopes match
        //sum timer values
        totalTimer = 0;
        for (byte i=0;i<index;i++){
          totalTimer+=timer[i];
        }
        period = totalTimer;//set period
        //reset new zero index values to compare with
        timer[0] = timer[index];
        slope[0] = slope[index];
        index = 1;//set index to 1
        PORTB |= B00010000;//set pin 12 high
        noMatch = 0;
      }
      else{//crossing midpoint but not match
        index++;//increment index
        if (index > 9){
          reset();
        }
      }
    }
    else if (newSlope>maxSlope){//if new slope is much larger than max slope
      maxSlope = newSlope;
      time = 0;//reset clock
      noMatch = 0;
      index = 0;//reset index
    }
    else{//slope not steep enough
      noMatch++;//increment no match counter
      if (noMatch>9){
        reset();
      }
    }
  }
   
  if (newData == 0 || newData == 1023){//if clipping
    PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led
    clipping = 1;//currently clipping
  }
 
  time++;//increment timer at rate of 38.5kHz
 
  ampTimer++;//increment amplitude timer
  if (abs(127-ADCH)>maxAmp){
    maxAmp = abs(127-ADCH);
  }
  if (ampTimer==1000){
    ampTimer = 0;
    checkMaxAmp = maxAmp;
    maxAmp = 0;
  }
 
}

void reset(){//clea out some variables
  index = 0;//reset index
  noMatch = 0;//reset match couner
  maxSlope = 0;//reset slope
}


void checkClipping(){//manage clipping indicator LED
  if (clipping){//if currently clipping
    PORTB &= B11011111;//turn off clipping indicator led
    clipping = 0;
  }
}


void loop(){
 
  checkClipping();
 
  if (checkMaxAmp>ampThreshold){
    frequency = 38462/float(period);//calculate frequency timer rate/period
 
    //print results
    Serial.print(frequency);
    Serial.println(" hz");
  }
 
  delay(100);//delete this if you want
 
  //do other stuff here
}




j'ajoute 2 rotary switch à l’Arduino pour sélectionner l'harmonie et l'octave,
[EDIT DU 12 01 2018]
Petit bout de code pour connaitre la valeur reçu eu Pin analogique par les rotary switch
Code: Tout sélectionner
int a=0;

void setup()
{
   pinMode(A2, INPUT_PULLUP);
   Serial.begin(9600);   
}

void loop()
{
   
   a = analogRead(2);
   Serial.print(a);
   Serial.print("\t");
   delay(10000);
}


et j'utilise la commande Tone() pour générer mon signal de commande sur une pin digital.
A suivre...
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL

Messagepar Bartgil le 25 Fév 2018 15:25

J'aime bien l'idée! Tu en avais déjà parlé, il me semble?
Donne sans rien attendre, tu ne seras jamais déçu.
Voir de belles choses, c'est bon pour la tête
Avatar de l’utilisateur
Bartgil
MODERATEUR PLEIN SUD
 
Messages: 2370
Enregistré le: 04 Mar 2009 21:19
Localisation: Ajaccio

Messagepar Sebdeploudal le 25 Fév 2018 22:25

Bartgil a écrit:J'aime bien l'idée! Tu en avais déjà parlé, il me semble?

De la version de 1981 oui, mais comme tout les sub octaver c'est toujours le verrouillage qui est compliqué.
Mais depuis que j'ai découvert Arduino, ça m'a ouvert des nouvelles portes.

Je fini une autre pédale à base de Arduino et CD4066 et ensuite je m'attaque au proto de celle-ci.
Si elle aboutie, je pourrais partir sur un truc dans le style whammy.
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL

Messagepar Sebdeploudal le 01 Juin 2018 10:52

Bon c'est parti, je reprends ce projet :
--> je part de mon Pedalshield UNO.
--> reconnaissance de fréquence des notes jouées. fonctionne.
--> je rajoute une fonction Tone/noTone avec frequence fixe sur le PIN 7 quand une note est jouée. fonctionne.
--> ajout de la partie "Générateur d'Octaves et Harmoniques". à venir.
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL

Messagepar Sebdeploudal le 19 Juin 2018 15:25

proto en cours ...

Image
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL

Messagepar Sebdeploudal le 21 Juin 2018 18:11

Premier problème:
je ne peux pas utiliser les entrées analogiques pour lire un rotary switch et sélectionner mes octaves et intervalles.
solution envisagé/
utiliser un second Arduino nano pour lire les sélecteur et communiquer entre les deux Arduino.
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL

Messagepar clément le 21 Juin 2018 20:31

Et si tu utilisais un shift-register pour le gros rotary switch d'octave?
C'est juste pour lire sa position dans ton Arduino ou ça a un effet physique sur le circuit en plus?
Avatar de l’utilisateur
clément
ELECTRON LIBRE
 
Messages: 343
Enregistré le: 03 Nov 2011 20:07
Localisation: Bruxelles

Messagepar Sebdeploudal le 22 Juin 2018 09:51

A voir, mais au prix d'un nano, je peut tester la communication entre 2 cartes. Comme ça une carte fait la lecture des port analogique(rotary switch utilisé comme un diviseur de tension à plusieurs niveau) et l'affichage LCD, et l'autre carte fait la détection de fréquence et la génération de signal pour piloter le 4066.
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL

Messagepar clément le 22 Juin 2018 10:17

Bien sûr! Je suggérais cela car j'avais l'impression en lisant ton post précédant que c'était une solution par défaut, et dans une volonté d'épurer / limiter le nombre de composants.
Avatar de l’utilisateur
clément
ELECTRON LIBRE
 
Messages: 343
Enregistré le: 03 Nov 2011 20:07
Localisation: Bruxelles

Messagepar Sebdeploudal le 22 Juin 2018 10:45

clément a écrit:Bien sûr! Je suggérais cela car j'avais l'impression en lisant ton post précédant que c'était une solution par défaut, et dans une volonté d'épurer / limiter le nombre de composants.

bah le shift-register permet d'ajouter des sortie numériques, moi je cherche des entrées analogique.
Quand cette machine fonctionnera (et elle fonctionnera), j'ajouterai un autre rotary pour transformé le montage et piloté plusieurs switch du 4066.
Pour avoir 2 harmoniques différentes genre Whammy.

Image
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL

Messagepar clément le 23 Juin 2018 11:25

Il y a plusieurs types de shift-register, un 74HC165 par exemple te permet de lire 8 entrées (je précise juste si jamais ça peut aider).
Avatar de l’utilisateur
clément
ELECTRON LIBRE
 
Messages: 343
Enregistré le: 03 Nov 2011 20:07
Localisation: Bruxelles

Messagepar Sebdeploudal le 25 Juin 2018 09:38

clément a écrit:Il y a plusieurs types de shift-register, un 74HC165 par exemple te permet de lire 8 entrées (je précise juste si jamais ça peut aider).

Effectivement au prix des puces (~0€40) les 74HC165 (ou CD4021) vont me simplifier la vie.
le savoir ne vaut que s'il est partagé.
Avatar de l’utilisateur
Sebdeploudal
ELECTRON LIBRE
 
Messages: 816
Enregistré le: 24 Aoû 2010 10:55
Localisation: Bretagne - KEMPER BREIZH IZEL


Retourner vers CONCEPTION

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité