Gebruikersnaam: Wachtwoord:

Auteur Topic: Arduino PT2399 tap tempo  (gelezen 45749 keer)

0 leden en 1 gast bekijken dit topic.

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Arduino PT2399 tap tempo
« Gepost op: 18 mei 2013, 18:01:01 »
Nieuw topic :)
Goed onderweg met de Arduino, had ik opeens het plan om mijn timewarp delay een update te geven.
De timewarp is mn huidige tap tempo delay, met een lichte envelope follower ipv modulatie.
Ik gebruik de TapTation chip van 'the Tonegod' icm 2 pt2399's in serie.
Dit heeft een paar beperkingen.
Deze chip is niet gemaakt voor 2 delay ic's en het analoge sync circuit wat ik gebruik (current mirrors) lijkt een beetje te wiebelen met temperatuur ed.
Ik gebruik maar iets van 20k van een 100k digipot, wat de 'resolutie' in timings niet ten goede komt.
En eigenlijk adverteert the Tonegod met een precisie die hij behalve op geselecteerde PT's niet waar kan maken.
Heb een extra schmit trigger en 4013 nodig om meerdere functies onder 1 knop te krijgen.

Nu denk ik een boel problemen in 1 klap op te kunnen vangen door zelf de timing/schakel software op een Arduino (of eigenlijk een losse Atmega 328) te schrijven.

Het nieuwe concept:
-cleane delay van max 1sec
-stereo/ping-pong uit
-tap tempo(als het even kan te syncen op MIDI-tempo)
-variabele LPF en HPF voor delays. (12dB/oct)
-lfo modulatie van delay tijd en filters
-te 'saven' mix, feedback, LPF, HPF en timing.

Het belangrijkste is voor mij de nerdy uitdaging van acuraatheid.

Ben weer eens niet de eerste die 'moeilijk' doet  :P:
http://www.diystompboxes.com/smfforum/index.php?topic=99717.0
En de table op pagina 9 van deze datasheet is onbruikbaar...
http://noise-room.com/sitebuildercontent/sitebuilderfiles/2399datasheet.pdf
Het idee van de sync is makkelijk, het process gaat even duren.

Je zet een puls op de pt2399 ingang voor iedere waarde (0~255) van een 8-bit digitale (10k~50k) potmeter aan pin 6.
Je kijkt vervolgens met de software hoe lang het duurt voordat deze puls op de uitgang staat.
Een opampje/comparator, maakt van de puls weer een digitaal signaal, 1/0)
Hier maak je een lijst van. (potmeterstand : tijd) Deze lijst schrijf je naar de EEPROM.
Bij een 50k pot is de delaytijd al behoorlijk lang, ik denk ook dat ik de autocalibratie moet laten stoppen als de delaytijd van 2 PT2399's in serie de 1 seconde overschreidt, of als de potmeter/rheostat zn max waarde heeft gehaald.

Manuele delaytijd is gewoon een mapping van een analoge input, die je bij verandering naar de digitale pot stuurt.

Als je nu een tempo tapt, zoekt de software de dichtsbijzijnde waarde uit de lijst en koppelt deze weer aan de setting van de digipot.

Dit is het eerste wat ik wil uitwerken, omdat dit het een multitool maakt voor iedere willekeurige delay-IC, in ieder willekeurig pedaal, met iedere willekeurige SPI pot.

Ik zie dit deelconcept zo voor me:
Je wilt een bestaande delay tap tempo maken?
kwestie van timing-pot los solderen van de delay.
3 draadjes van het TT-pcb op die plek solderen
3 draadjes van de oude delaypot op het TT-pcb solderen,
1 draadje op de ingang, 1 op de uitgang, 1 op de voeding, 1 op GND.
één keer (in de zoveel tijd?) de calibratie doen en als het goed is klopt het dan. Als bonus nog een leuk knipperledje?

Haha, voor mij zou het ideaal zijn als ik er hier een paar van had liggen iig ;)

Ik ben nog steeds beginnend met Arduino, maar dit krijg ik waarschijnlijk wel opgelost.
HPF/LPF/mix/delay/feedback gaat ook wel lukken, heb ik geschetst en deels getest, maar is voorlopig bijzaak.

Een ander dingetje, waar Remork me aan herinnert, mocht ik het vergeten, is dat je aan 2 taps om een tempo te bepalen niets hebt. Je wilt echt het gemiddelde van een reeks van 4 of meer.
Dit wordt zeker stoeien met de sketch, maar zie ik wel voor me.

Ik vrees dat ik me ook aan de smd moet gaan wagen voor deze, en zal daar ook mee moeten oefenen. Dit idee gaat echter 'trough-hole' makkelijk in een DD-passen, en zelfs 19" is een optie.

Afijn, als dit voor het eind van dit jaar gerealiseerd is ben ik blij, hiermee niet zo'n haast als de looper en de steile leercurve aan het begin van het Arduino avontuur...
« Laatst bewerkt op: 18 mei 2013, 18:38:16 door Mattnezz »

Offline Flo

  • Moderator
  • Hero Member
  • *****
  • Berichten: 8578
  • teveel info...
Re: Arduino PT2399 tap tempo
« Reactie #1 Gepost op: 18 mei 2013, 18:55:01 »
Tof! Ik zal je progressie volgen en later mogelijk ook wat pogingen doen voor een tap tempo PT.

Mijn eerste poging zou ook waarschijnlijk een auto-calibratie zijn die een lookup table genereert voor een specifieke PT2399 chip.
« Laatst bewerkt op: 18 mei 2013, 22:34:09 door Flo »

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #2 Gepost op: 19 mei 2013, 12:20:12 »
Ik ben niet ver maar heb een begin... En daarmee stapelen de vraagstukken zich al lekker op.  :P
Aan de basis van een tap-tempo apparaat staat natuurlijk tempo herkenning.
Ik heb nu nog slechts een sketch geschreven die dus twee of meer taps als input heeft en een tijd als output. Bij meer dan 2 taps wordt een gemiddelde berekend.
Misschien leuk basisblok voor de Arduinoprutsers om even te checken, want er hoeft alleen even een mom schakelaar tussen pin 2 en GND.
Uploaden en serial monitor/ on board ledje bekijken...
Citaat
int tapButton = 2;          //mom Sw tussen pin 2 & GND
boolean ledState = LOW;
int indLed = 13;            //indicatieled op pin 13

boolean currentState = LOW;
boolean lastState = LOW;

long t1 = 0;   //tap-tempo variabelen
long t2 =0;
int sum = 0;
int divider = 0;
int tapCount = 0;
int lastInterval = 1000;
int interval = 1000;
int average =1000;
int timeOut = 2000;
int delayTime = 1000;

void setup(){
  pinMode(tapButton, INPUT_PULLUP);
 
  pinMode(indLed, OUTPUT);
  Serial.begin(9600);
}

//DEBOUNCING:
int debounceDelay = 5;
boolean debounce(boolean last)                           
  {
  boolean current = digitalRead(tapButton);                 
  if(last != current)                         
  {
  delay(debounceDelay);
  current = digitalRead(tapButton);                 
  }
  return current;                               
  }
 
 
void loop(){
 unsigned long time = millis();
 
 currentState=debounce(lastState);              //debounce functie oproepen
 
 if(lastState == HIGH && currentState == LOW) { //als de TT-knop wordt ingedrukt
   tapCount++;                                  //wordt het aantal keer drukken geteld
   switch(tapCount){
   case 1: t1 = time; break;                  //bij de eerste tap wordt de 'stopwatch' op 0 gezet
   case 2: t2 = (time - t1);                  //bij de tweede wordt de tussentijd berekend
           interval = t2;                     //deze tussentijd wordt opgeslagen
           t1 = time;                          //stopwatch wordt opnieuw op 0 gezet
           tapCount= 1;                        //tapcount gaat 1 stap terug, zodat bovenstaande regel opnieuw wordt
                                               //uitgevoerd bij een volgende tap.
 Serial.print (" time: "); Serial.println(interval);
           break;
   }
  }
lastState = currentState;                      //stand van de momentschakelaar wordt opgeslagen.

if(lastInterval != interval){                  //als er een verandering is in het interval tussen 2 taps
  sum = (sum + interval);                          //worden de getapte tijden opgeteld
  divider ++;                                  //en gedeeld door het aantal taps
  average = (sum/divider);                     //voor een gemiddelde
  lastInterval=interval;                       //hier krijgt lastInterval de waarde van interval, om een verandering te herkennen
  Serial.print ("average = ");Serial.print (sum);Serial.print("/"); Serial.print (divider);  Serial.print (" = ");Serial.println(average);
}

if( time-t1 == timeOut){                     //na een tijd van timeOut (2sec) na de laatste tap,
 delayTime = average;                          //wordt de delaytijd de waarde van de geiddelde tijd tussen de taps
 tapCount = 0;                                 //de tap teller wordt gereset
 sum = 0;                                      //zo ook de tijd optelling
 divider =0;                                   //en de deler
 Serial.print ("delay time: "); Serial.print(delayTime);  Serial.println(" ms.");
 Serial.println(" ------------------------"); Serial.println("  ");
 delay(2);
}
  ledState = (time/delayTime)%2;               //(korte vorm van 'blink without delay')
 digitalWrite (indLed,ledState);               //led knippert op het ingetapte tempo.
 
}

weer behoorlijk straight forward gedaan.
Wat beter kan: waarschijnlijk haal ik beter de 5ms delay (debounceDelay) uit de debounce en vervang ik deze door de methode die millis() gebruikt. Ik dacht eerst voor 't' een hele rits nodig te hebben, maar 2 waren wel genoeg, een array is een beetje zinloos...

Ik zou het zeer op prijs stellen als iemand misschien tips heeft voor verbeteringen. Er zullen er tig zijn. Dit blokje is weer eens on the flow geschreven, werkt, maar ik blijf beginner ;)

Afijn, deze sketch levert me 1 variabele op, namelijk "delayTime".
Deze moet gekoppeld gaan worden aan een te maken 'lookup table'.

Hiervoor moet ik gaan uitzoeken hoe je het voor elkaar krijgt om een dichtsbijzijnde waarde te zoeken ???

Stel bij digipot stand 100, hoort een delaytijd van 260ms, bij digipot stand 99, 256ms.
Hoe zorg ik nou dat ik bij een delayTime van 257, dus de digipot stand 99 oproep?
Nog een probleem, delayTime 258 zit precies tussen stand 99 en 100 in.
Ik denk aan valsspelen bij Lingo, en de ballen uit de grabbelton... Als een nummer niet op de kaart staat, moet de delayTime met 1 verhoogd worden en kijken of hij er nu wel bij staat, zo niet met 1 verlagen en opnieuw kijken, nog steeds niet, met  2 verhogen etc.

Maar hoe 'kijkt' de software?
if(delayTime staatOpDeKaart) of if(delayTime staatNietOpDeKaart) gaat niet werken (helaas) :-\ .
Iets als ctrl-F zou leuk zijn ;) tips, iemand?

Het sketchje om te syncen zal ik iig binnenkort schrijven. Heb de bestelde digitale potmetertjes nog niet binnen, en de spi-communicatie zal ook wel even vies tegenvallen, maar ik heb wel een delay-pedaaltje waarvan de tijd geregeld zou kunnen worden middels pwm.
Ipv van naar een potmeter, hoef ik dan dus alleen een waarde tussen 0 en 255 op een pwm pin te gooien , filteren, en te meten hoeveel delay tijd dat geeft.

EDIT: even sketch met commentaar neergezet. copy-pasten in de arduino-software op full screen is het wat overzichtelijker btw...

EDIT EDIT: vorige code had fout, bij het toevoegen commentaar heb ik iets weggehaald waardoor hij niet meer werkte, is nu aangepast.
op de serial monitor moet zoiets staan:
delay time: 1000 ms.
 ------------------------
 
 time: 435
average = 435/1 = 435
delay time: 435 ms.
 ------------------------
 
 time: 401
average = 401/1 = 401
 time: 459
average = 860/2 = 430
 time: 442
average = 1302/3 = 434
 time: 461
average = 1763/4 = 440
 time: 452
average = 2215/5 = 443
 time: 431
average = 2646/6 = 441
delay time: 441 ms.
 ------------------------
 
bovenste resultaat van 1 tap

2e resultaat van 2 taps

onderste resultaat van 7 taps...
« Laatst bewerkt op: 19 mei 2013, 19:56:29 door Mattnezz »

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #3 Gepost op: 20 mei 2013, 00:34:38 »
Met bovenstaande sketch een beetje gespeeld.
Ik kwam er zo achter dat millis() nog behoorlijk groffe eenheid is, als je er me gaat rekenen.
Met PWM en ledje even snel een simpele 'ramp up' LFO gemaakt, maar het viel niet mee om die sync te krijgen. Heb van de delayTime een clock gemaakt door hem door 256 te delen, en bij iedere puls die dat oplevert een PWM uitgang met 1 te verhogen. Zelfs met een 'float' krijg je afwijkingen. Dit moet hoe dan ook anders en ik zal eens een Arduino LFO gaan bekijken.
Dit 'probleem'tijdelijk opgelost met time=micros(); ipv time=millis();

Ik wacht de digipots nog even af, intussen zal ik een pcb/shield tekenen, omdat dit nou eenmaal overzichtelijker werkt dan al die draadjes.
Ik denk na een test met enkel een gitaar, dat een analoge ingang gevoelig genoeg is om een terugkomende puls te registreren en zal ter bescherming een koppelC/sperdiode plaatsen. Dit bespaart me een comparator.
Ik zit eigenlijk te overwegen om de uitgangs jack van een delaypedaal te gebruiken voor de sync functie, en simpel een meting te doen tussen de 2 pulsen die daar verschijnen, namelijk eerst dry, dan wet. Dit is makkelijker dan in een onbekend delaycircuit de wet-trace te vinden, alhoewel pin 3 van een feedbackpot een goed punt kan zijn.

Op het 'shield' komen gelijk wat potmeters  (de ACP-trimpots), de tempo schakelaar/sync start schakelaar, een bs170 voor modulatie en nog wat knipperdingen.
Er komen dan maar 5 draadjes uit. GND, 1 om de puls te sturen en 1 om de puls te vangen, en 2 om aan pin 6 van beide pt2399's te hangen. Of beter 2 jackbussen en 2 voor de pinnen 6.

De schakeling voor de modulatie moet los van het tempo. (Bij de TapTation was dit een ramp)
Ik gebruik wel de methode met de BS170 en PWM aan de voet van de rheostat. De modulatie wordt nog een verhaal apart, want de depth moet afhankelijk van de delaytijd worden, en ook nog regelbaar. Ik denk dat dit in een simpele vergelijking te benaderen is.
Anders heb je namelijk geheid het probleem dat de 'depth' groter wordt bij langere delaytijd.
LFO wordt in eerste instantie ook een simpele driehoek.

Doordat de modulatie de gemiddelde delaytijd beïnvloed, denk ik dat het verstandig is deze vanuit het midden te laten opereren, dus geen modulatie betekent een 50/50 (127) pwm, en niet 0. Daarom lijkt het me ook belangrijk om de 'look-up' table te schrijven met de pwm op deze stand.


Offline Flo

  • Moderator
  • Hero Member
  • *****
  • Berichten: 8578
  • teveel info...
Re: Arduino PT2399 tap tempo
« Reactie #4 Gepost op: 20 mei 2013, 13:19:05 »

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #5 Gepost op: 20 mei 2013, 14:01:32 »
Ja, die had ik al gevonden, maar die code voor de PIC is mij iets te hoog gegrepen  :-[
Wat me wel opviel is dat hij voor de sinus een array-achtig iets gebruikt, waar alle PWM waarden in staan.

Ik heb van de bovenstaande sketch zo een tap tempo sinus gemaakt:

De delayTime in ms gelaten.
onderaan zie je hoe ik een led laat knipperen:
ledState = (time/delayTime)%2;
digitalWrite(indLed,ledState);


ik heb nog een variable gemaakt:
int factor = (delayTime * 1000);
zo krijg je een tijd in micro sec.
ik maak een klok voor de LFO:
Citaat
  ledState = (time/delayTime)%2;               //(korte vorm van 'blink without delay')
  digitalWrite (indLed,ledState);               //led knippert op het ingetapte tempo.
  LFOfactor= (factor/358);
  LFOclock = (micros()/LFOfactor)%2;

Ik deel door 358 (ipv 360) om met de sin(x); functie 2 helften te maken. sin(181) en hoger geeft een negatieve waarde, en ik kreeg geen mooie sinus voor mekaar door er bijvoorbeeld 1,00 bij op te tellen. dus 1 helft is van 1 tot 180, de andere van 180 tot 1. Dit zijn 358 stappen die in de tijd van 1 'delayTime' gemaakt moeten worden. Als ik door 179 zou delen krijg ik dus een sinun die 2x zo lang is als het tempo, en door 716 geeft een 2x zo snelle sinus...
zo dus...een if-statement telt op tot de piek, en daarna af:
in de 2e statement had ik eerst if(n==0) maar dan knippert de led bovenaan de sinus, bij if(n==1) heb ik een op het eerste gezicht mooi verloop.
Citaat
if(runLFO == true && LFOclock != lastLFOclock){ //1 actie per klokpuls
  if (peak == false)                             //1e helft van de sinus
  {n++;
  if (n==180) {peak = true;}}                    //2e helft van de sinus
  if (peak == true)
  {n--;
  if (n==1) {peak = false;}}
  sin (n);
  int x = (n * 255);                            //een heel (integer) getal maken
  constrain(x,0,255); // niet nodig volgens mij...
  analogWrite(LFOpin,x);
  lastLFOclock = LFOclock;
  }


Dit werkt redelijk goed, maar boven een bepaalde snelheid ga je de afwijkingen zien.
Ik denk dat dit toch komt door de afronding bij de deling, en de vertaging door de loop.

Grappige is dat ik dus helemaal niet bezig ben met een LFO ;) De functie die de sinus maakt krijgt zn snelheid mee van een potmeter, en gaat nooit tap tempo worden. Voor modulatie is het wel al tof om een regelbare sinus lfo te hebben die dus geen vertraging in de rest van de software geeft, door het omzeilen van de 'delay(x);'-functie.

Ben reeds onderweg met de pulseSendPin en pulseRecievePin en zit te kijken of ik daar überhaubt mooie readings uit kan krijgen...

EDIT:
video van LFO op half tempo, dus delen door 178 om hem ongeveer hetzelfde te laten doen als het tempo ledje... De uit sync lijkt toch nog mee te vallen zo...
https://dl.dropboxusercontent.com/u/23071527/video-2013-05-20-14-18-15.mp4

« Laatst bewerkt op: 20 mei 2013, 14:25:42 door Mattnezz »

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #6 Gepost op: 21 mei 2013, 01:43:01 »
eerste tijdmeting een feit!
Zet met een knopje een 1ms puls via condensator en jackbusje op de ingang.
De puls is tot 2.2V beperkt door een 330R en een ledje.
Jackbusje op de uitgang naar een analoge pin op de arduino. (A5)
op de analoge pin een threshold van 2, daarboven wordt hij geregistreerd als hoog.

bij de eerst ontvangen puls: ->  t1 = millis();
bij de tweede ontvangen puls -> t2 = millis()-t1;
en er rolt een delaytijd uit.

Nu nog manueel, maar dat gaat dus automatisch worden.
onder de 1 seconde delaytijd, geeft 10x drukken hetzelfde resultaat, daarboven is de afwijking max 2ms. Zeer bruikbaar lijkt me.


Proefkonijn was mn Time Warp, en er vielen leuke dingen op.
Test met feedback dicht en mix/blend open (50% dry / 50% wet)
in de 'normale' kwarten-stand is de max delaytijd 1207ms. Dat is nog redelijk cleane delay, maar ik ga het zeker beperken tot max 500ms per pt2399.
De minimale delaytijd is 70ms. Wat wel ongeveer lijkt te kloppen met de datasheet.
Ik heb hierop twee mix knoppen, 1 voor de repeat van de eerste pt2399 en 1 voor de repeats van de 2e.
Nooit zo nauwkeurig bekeken, maar de ene geeft bijna exact de halve tijd van de ander...
trouwens de langste delaytijd die ik uit de Timewarp kreeg was 4772ms, muzikaal is dat vage ellende  ;)



Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #7 Gepost op: 21 mei 2013, 17:19:23 »
Ow als iemand een Arduino Shield wil maken, en eagleCAD gebruikt...
http://ladyada.net/make/pshield/download.html
Vandaag even de maten over zetten in mn eigen tekenprogramma...
Ipv de Eagle files overtekenen naar een ander programma is deze ook handig:
http://blog.arduino.cc/2011/01/05/nice-drawings-of-the-arduino-uno-and-mega-2560/
« Laatst bewerkt op: 21 mei 2013, 20:05:31 door Mattnezz »

Offline Flo

  • Moderator
  • Hero Member
  • *****
  • Berichten: 8578
  • teveel info...
Re: Arduino PT2399 tap tempo
« Reactie #8 Gepost op: 21 mei 2013, 18:23:51 »
Cool!

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #9 Gepost op: 21 mei 2013, 21:47:45 »
Nieuwe problemen...

Het eerste probleem was het dichttimmeren van de tijdlezingen, zodat de software duidelijk het verschil ziet tussen de dry-puls en de wet-puls, maar dat is gelukt.

Eentje met de EEPROM, want ik heb tot nu toe alleen getallen onder de 255 opgeslagen, maar een delaytijd van 635ms past niet in 1 byte, en ik vind het zonde om hem dan minder significant op te slaan.
Ik bedoel, ik zou door 10 kunnen delen en opslaan, en bij het lezen met 10 vermenigvuldigen, maar dat is m niet...
Deze begrijp ik alleen niet helemaal.
Citaat
http://playground.arduino.cc/Code/EEPROMWriteAnything
Het lijkt me makkelijker dan een 2-byte waarde op te slaan, maar hoe het werkt met ophalen van data... :-[

Mijn idee is dus om een 256 variabelen lange array te maken, bijv potValue[].
en een index...
Zou handig zijn als deze bij het aanzetten van de delay van de EEPROM geladen kunnen worden.
Maar dan nog moet ik de juiste waarde te pakken zien te krijgen.
Deze array wordt gevuld met lezingen. bijv: potValue[0]=31 ms, potValue[156]=500ms... etc.
Zou het dan lukken om bij een gevonden tap-tempo tijd met een 'for loop' door de 'array' te 'scrollen' om het ingetapte tempo te vinden in een paar if-statements? ???
bijv:
if(findTime==true;)
for(int x=0;x<256;x++){
if (delayTime==potValue
  • ) // zou dat een hit opleveren?

else if (delayTime==(potValue
  • +1) //of deze?

else if (delayTime==(potValue
  • +2) // deze misschien?

krijg ik dan geen problemen met:
else if (delayTime==(potValue
  • -1)? bij een oplopende for-loop (x++)


Ik ga dit iig even proberen, maar vrees dat dit ook weer efficienter kan, of zelfs helemaal niet werkt zo ;)

Soms voel ik me net alsof ik voor het eerst een flower-booster aan het solderen ben, haha...

En dan, zo ja de waarde via SPI naar de potmeter sturen...


Offline Flo

  • Moderator
  • Hero Member
  • *****
  • Berichten: 8578
  • teveel info...
Re: Arduino PT2399 tap tempo
« Reactie #10 Gepost op: 22 mei 2013, 00:36:00 »
Het eerste probleem was het dichttimmeren van de tijdlezingen, zodat de software duidelijk het verschil ziet tussen de dry-puls en de wet-puls, maar dat is gelukt.
Ik dacht je een puur "wet" signaal uit de delay liet komen tijdens calibratie? Zo ja, waarom heb je dan met een "dry-puls" te maken?

Eentje met de EEPROM, want ik heb tot nu toe alleen getallen onder de 255 opgeslagen, maar een delaytijd van 635ms past niet in 1 byte, en ik vind het zonde om hem dan minder significant op te slaan.
... Het lijkt me makkelijker dan een 2-byte waarde op te slaan, maar hoe het werkt met ophalen van data... :-[
Ja, je kunt een 16 bits "int" opslaan als 2 bytes. Je zou de bitshift operators << en >> kunnen gebruiken, zoals hier:
http://forum.arduino.cc/index.php/topic,37470.0.html

Mijn idee is dus om een 256 variabelen lange array te maken, bijv potValue[].
Volgens mij heb je meer aan een lookup table die andersom werkt. Je hebt een delay-tijd en je zoekt daar een potmeter stand bij.
De tabel kan dus beter een lijst van bytes zijn zoals dit:
DelayTijdTabel[ delayTijdInMilliSec ] = PotmeterStand
Deze lijst zou zelfs 1000 bytes groot kunnen zijn, voor elke millisec een potmeterstand, maar ik denk dat je met 100 bytes (intervallen van 10ms) er ook wel uitkomt. Helemaal als je het (gewogen) gemiddelde neemt van de twee dichtsbijzijnde waarden.

En dan, zo ja de waarde via SPI naar de potmeter sturen...
Wat betekent SPI?
Ah: http://gammon.com.au/spi :)
« Laatst bewerkt op: 22 mei 2013, 01:19:29 door Flo »

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #11 Gepost op: 22 mei 2013, 01:54:14 »
Citaat
Ik dacht je een puur "wet" signaal uit de delay liet komen tijdens calibratie? Zo ja, waarom heb je dan met een "dry-puls" te maken?
Er zijn niet veel delays met een puur "wet" uitgang, meestal is de maximale mix 50/50. Vandaar dat ik :
eerst een puls op de ingang zet.
dan kijk of er een puls binnen 10ms op de uigang komt, dit moet wel de "dry" zijn gezien de minimale delay-tijd van 25mS van de pt2399.
De puls die nog minstens 10ms later komt, moet dan wel de "wet" zijn.
Dus ik meet het interval tussen 2 pulsen op de uitgang...
Dat gaat wel eens mis.
Iedere keer dat de potmeter 1/256 omhoog gaat, kijk ik ook of dat interval groter is geworden.
Zo niet, wordt er op dezelfde potmeterstand nog een puls gegeven.
Als hij na 5 keer nog geen langer interval geeft, ga ik pas naar de volgende stand.
Wacht even en stuur de volgende puls, en meet een nieuw interval.

Morgen zullen de potmeters arriveren en hoop ik de echte tests te doen, maar moet voor een kunstproject voor iemand ook even snel een '2 gitaren naar 1 versterker' dingetje bouwen...

Ik heb nu een array gemaakt door handmatig de delaytijd te vergroten door aan de 'time' pot te draaien. ik druk op een knop om de puls de geven en draai de pot dan een stukje.
Deze array bevat maar 30 punten, maar dat stuk software lijkt nu goed te werken.

EEPROM
Citaat
Ja, je kunt een 16 bits "int" opslaan als 2 bytes. Je zou de bitshift operators << en >> kunnen gebruiken, zoals hier:
http://forum.arduino.cc/index.php/topic,37470.0.html
dank dank, ik ga dat eens goed bekijken! ;D

Citaat
Volgens mij heb je meer aan een lookup table die andersom werkt. Je hebt een delay-tijd en je zoekt daar een potmeter stand bij.
De tabel kan dus beter een lijst van bytes zijn zoals dit:
DelayTijdTabel[ delayTijdInMilliSec ] = PotmeterStand

Ik ben er al uit ;D ;D ;D
Dacht dat het lastig werd, maar viel mee, en gaat reuze snel!
heb toch een potmeter waarde x gebruikt, en een afwijking y.
toch met een leuke for-loop:

Citaat
if(FIND==true){
 for(int x=0;x<256;x++){
   if(delayTime == potValue[ x ] ) {
     Serial.print(potValue[ x ] ) ;
     Serial.println("spot on!") ;
     FIND=false;
     break;
     }
   else if(delayTime == ( potValue[ x ] + y ) ) {
     Serial.print("potVal: "); Serial.print( x );
     Serial.print(", time: ");Serial.print(potValue[ x ]); Serial.print(" ms,");
     Serial.println(" deviation: -");Serial.print(y);Serial.println(" ms");
     FIND=false
     break;
   }
   else if(delayTime == (potValue[ x ] - y) ) {
     Serial.print("potVal: ") ; Serial.print( x ) ;
     Serial.print(", time: ") ;
     Serial.print(potValue[ x ] ) ;
     Serial.print(" ms,");Serial.print(" deviation: +" ) ;Serial.print(y);Serial.println(" ms"); delay(1);FIND=false;break;}
 if( x ==255 ) { y++; }
 if( y==20 ){
    FIND=false;
    Serial.println ("NOT FOUND!");
    break;}
 }


Hij is een beetje vervuild met de serialmonitor uitingen, maar das voor mij nou eenmaal duidelijk.
Ik zoek dus een potwaarde bij delayTime...
op het moment dat de 'delayTime' getapt is, wordt "FIND" true.
dan kijk ik in de eerste 255 stappen 'for loop' of hij erbij staat,
dan verhoog ik y met 1.
Kijk vervolgens of er een potmeterstand voor 1ms langer is
En dan voor een potmeterstand die een 1 ms kortere tijd geeft.

Ik geef nu nog bij 20ms afwijking een 'error', maar praktijk moet zeggen binnen welke perken ik moet zoeken.

Hier zocht ik naar een delayTime van 309 ms.

serial mon:
    searching...
    potVal: 23, time: 319 ms, deviation: +10 ms

Zo eerlijk als wiskunde.

moet ik met spi alleen de pot op 23 zetten ;)
Citaat
Wat betekent SPI?
met n duur woord ;) Serial Peripheral Interface , haha... communicatievorm, maar in geval van nood krijg ik de data ook wel naar de pots met shiftOut. De potmeters vonden dit nou eenmaal tof volgens de MCP42xxx datasheet. SPI schijnt sneller te zijn...
http://arduino.cc/en/Reference/SPI

« Laatst bewerkt op: 22 mei 2013, 02:21:26 door Mattnezz »

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #12 Gepost op: 22 mei 2013, 17:10:27 »
Citaat
Morgen zullen de potmeters arriveren en hoop ik de echte tests te doen, maar moet voor een kunstproject voor iemand ook even snel een '2 gitaren naar 1 versterker' dingetje bouwen...
timing was perfect :0, net dat bouwsel af, belt de postbode aan.
Heb de MCP 4251-503 en de MCP42050 om aan de praat te krijgen.
Deze zijn beide 256-standen dual pots van 50k.
de 4250 kost iets van 1,50 en de 42050 2,35. Hun preciesie is evenredig met de prijs, maar ik denk dat dat door de sync-check dus geen fluit uit maakt.
Ik duik eens rustig (voor mijn doen dan) in de datasheets en de links van Flo.

Heb bij Newtone ook nog wat momentschakelaars en ACP trimmers gehaald voor op mn arduino shield.

Ik bedacht me dat de uitgang van de delay straks aan de hoogohmige A5-input van de arduino zit, ik ga eens kijken hoe makkelijk ik daar een envelope detector in ga krijgen.

Verder heet zo'n atmega328 een microprocessor... Waarom is ie dan zo groot? ;)
Wil toch eens kijken of ik een smd-versie op een pcb geplakt krijg, van bootloader kan voorzien en geprogrameerd krijg.... Kreeg mn tubetje cr44 vandaag ook en ga eens oefenen op de smd 74hc595 om hem zo klein te krijen als een 7-segment display wat hij aanstuurt.

Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #13 Gepost op: 23 mei 2013, 00:26:26 »
Nou, ik had er vet zin in om eens wat te gaan testen... viel ff vies tegen.
Ik heb een ander delaypedaaltje genomen. deze heb ik voor meer tests gebruikt.
Het was het eerste delay-pedaaltje wat ik heb gemaakt met 2 pt2399's in serie.
Hier zitten 2 delaychips in met de pinnen 6 omhoog gebogen en daar 2 draadjes aan gesoldeerd.

Alvorens te testen, die 2 draadjes met 10k aan de breadboard-GND geknoopt.
puls gestuurd... kreeg niets terug :-[
Kreeg de eerste puls wel terug, maar de tweede niet.
Vervolgens kreeg ik de tweede wel terug en de eerste niet... tobben, code aanpassen, comparator ertussen, versterker ertussen... niets... Zelfs de audioprobe, en ja ik hoorde allebei de pulsen toch echt duidelijk... grrr.

Ik zoeken in schema's en wat blijkt...
'Dry' is in tegenfase met 'wet'.
dat viel vies tegen dus, maar oplossing is dus om A5 op een halve voeding te zetten. Of ongeveer, gebruik nu interne pullup en externe 10k naar gnd, en dat werkt met een koppel C ervoor dus wel.
De software kijkt nu of er een afwijking van minstens 2 plaatsvindt op de analogRead, en ziet dat als een ontvangen puls, als ie aan de eerder genoemde voorwaarden voldoet....

afijn met die 10k per 'pin 6' van de pt2399 meet de arduino nu 279ms en dat klopt wel ongeveer met de datasheet. http://noise-room.com/sitebuildercontent/sitebuilderfiles/2399datasheet.pdf
welke voor 9k2> 136.6ms geeft en voor 10k5> 151ms.
Ik hoopte al iets tussen 273.2 en 302ms. te vinden.

Intussen wel een beetje begrepen hoe je met pin 10,11,12 en 13 van de arduino SPI kan doen.
Praktijkles verschoven naar morgenavond ;)






Offline Mattnezz

  • Hero Member
  • *****
  • Berichten: 3509
  • Just a method to the Mattnezz
Re: Arduino PT2399 tap tempo
« Reactie #14 Gepost op: 23 mei 2013, 20:44:30 »
Het is inmiddels morgenavond en alles staat op breadboard.
Alleen heb ik weer een spiegologisch probleempje...
Als ik de MCP42xxxx datasheet bekijk weet ik niet hoe ik de command-byte moet maken.
http://ww1.microchip.com/downloads/en/DeviceDoc/11195c.pdf
Het komt door dit plaatje...

De waarden weet ik wel, maar welke volgorden moet dit hebben....
De commandbyte is altijd hetzelfde, namelijk schrijven naar beide pots te gelijk.
ik vermoed dat hij er zo uit moet zien.
byte commandByte = B00(C0)(C1)00(P0)(P1);
als ik C0,C1 => 1,0 maak zou hij data moeten schrijven.
als ik P0,P1 beide 1 maak zou hij naar beide potmeters moeten sturen...
Maar, moet de commandbyte nu dit zij:
B00100011;
Of juist omgedraaid?
B11000100;

Afijn ik heb de potmeter nu zo ver dat hij naar reset even laag getrokken te hebben op de halve waarde zit, en dit geeft ook nog een verwachtte delaytijd...
Ga nu stukje spi-code schrijven.