analoge potmeter als soort schakelaar
13 berichten
• Pagina 1 van 2 • 1, 2
analoge potmeter als soort schakelaar
(nieuw op dit forum, dus hoop dat ik in juiste rubriek post)
Ik ben bezig met een deel van een sketch die een LFO moet moet maken, en stuitte voor de 2e keer op een probleempje met potmeters op analoge ingangen.
Ik krijg het niet simpel opgelost, en hoop dat iemnd me kan helpen.
Een LFO (low frequency oscillator) is een langzaam bewegende golf, in mijn geval een sinus-vormige pwm uitsturing met regelbare snelheid en amplitude.
De golfvorm zet ik op de gate van een bs170 fet en gebruik dit om de delaytijd van een PT2399 te moduleren voor een muzikaal vibrato effect.
De amplitude en snelheid regel ik met 2 potmeters die zijn aangesloten op analoog 0 en 1.
Nu geven de grenswaarden problemen, welke ik met 'smoothing' en 'map' niet weggewerkt krijg.
bijv:
Dit werkt natuurlijk gewoon, maar als ik bij 'speed' de potmeter net tussen bijvoorbeeld 1 en 2 heb staan, dus op het overgangs punt, dan krijg je natuurlijk haperingen.
Ik denk dat dit simpel weg te werken is, maar ik kom er even niet uit.
Ik heb eerst 'smoothing' geprobeerd, maarja, dit vertraagt de hapering alleen een beetje.
Vervolgens iets met currentReading/lastReading, om de potmeterstand alleen bij verandering te lezen. Geen succes.
Toen ik aan de for-loop/switch...case begon om dit probleem aan te pakken, ben ik maar een forum gaan opzoeken, want ik denk dat dit dus heel simpel op te lossen moet zijn.
Wie kan mij in de goede richting duwen?
Ik ben bezig met een deel van een sketch die een LFO moet moet maken, en stuitte voor de 2e keer op een probleempje met potmeters op analoge ingangen.
Ik krijg het niet simpel opgelost, en hoop dat iemnd me kan helpen.
Een LFO (low frequency oscillator) is een langzaam bewegende golf, in mijn geval een sinus-vormige pwm uitsturing met regelbare snelheid en amplitude.
De golfvorm zet ik op de gate van een bs170 fet en gebruik dit om de delaytijd van een PT2399 te moduleren voor een muzikaal vibrato effect.
De amplitude en snelheid regel ik met 2 potmeters die zijn aangesloten op analoog 0 en 1.
Nu geven de grenswaarden problemen, welke ik met 'smoothing' en 'map' niet weggewerkt krijg.
bijv:
- Code: Alles selecteren
int depthReading = analogRead(A0);
int depth = map(depthReading, 0, 1023, 0, 127);
int speedReading =analogRead(A1);
int speed = map (speedReading, 0, 1023, 20, 1);
Dit werkt natuurlijk gewoon, maar als ik bij 'speed' de potmeter net tussen bijvoorbeeld 1 en 2 heb staan, dus op het overgangs punt, dan krijg je natuurlijk haperingen.
Ik denk dat dit simpel weg te werken is, maar ik kom er even niet uit.
Ik heb eerst 'smoothing' geprobeerd, maarja, dit vertraagt de hapering alleen een beetje.
Vervolgens iets met currentReading/lastReading, om de potmeterstand alleen bij verandering te lezen. Geen succes.
Toen ik aan de for-loop/switch...case begon om dit probleem aan te pakken, ben ik maar een forum gaan opzoeken, want ik denk dat dit dus heel simpel op te lossen moet zijn.
Wie kan mij in de goede richting duwen?
Advertisement
Re: analoge potmeter als soort schakelaar
Wat nu dus het best lijkt te werken is iets als dit, een soort debounce...
en in de loop zoiets:
Maar nog steeds behoorlijk beetje springerige waarden. Hoe zou ik dit kunnen veranderen zodat een fysieke verandering van de potmeterstand als zodanig wordt geregistreerd?
- Code: Alles selecteren
int smoothSpeed(int last)
{
potReadingS = analogRead(speedPot);
int current = map(potReadingS, 0, 1023, 31, 1);
if(last <= (current - 3) || last >= (current + 3))
{
delay(10);
potReadingS = analogRead(speedPot);
current = map(potReadingS, 0, 1023, 31, 1);
}
return current;
}
en in de loop zoiets:
- Code: Alles selecteren
speedReading = smoothSpeed(lastSpeedReading);
if(speedReading != lastSpeedReading )
{
SPEED = (speedReading*200) ;
Serial.print(" speed: "); Serial.println(speedReading);
}
lastSpeedReading = speedReading;
Maar nog steeds behoorlijk beetje springerige waarden. Hoe zou ik dit kunnen veranderen zodat een fysieke verandering van de potmeterstand als zodanig wordt geregistreerd?
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: analoge potmeter als soort schakelaar
Voortschrijdend gemiddelde nemen:Maak een array van 10 elementen bijvoorbeeld :
- Code: Alles selecteren
init() {
unsigned int reeks[10]; // reeks met waarden
unsigned int reeksIndex = 0; // index naar de reeks
unsigned int Som = 0; // totaal van de reeks waarden
boolean eersteSerie = true; // bij eerste 10 waarden is de reeks nog niet gevuld
}
loop(){
PotReadingS = analogRead(speedPot);
if (eersteSerie) {
reeks[reeksindex] = PotReadingS; // zet de waarde in de eerste vrije reeks regel
reeksIndex++; // verwijs naar de volgende index
som += PotReadingS; // verhoog de som
gemiddelde = som / reeksindex; // deel som door aantal velden
if (reeksIndex == 10) { // hele tabel gevuld?
reeksindex = 0; // index op 0 zetten
eersteSerie = false; // en dit doe je nooit meer
}
} else {
som = som + PotReadingS - reeks[reeksIndex]; // verhoog de som met de nieuwe waarde en verlaag met die waarde uit de tabel
reeks[reeksIndex] = PotReadingS; // zet de nieuwe waarde in de tabel
gemiddelde = som / 10; // deel de som door 10 (immers de hele tabel is gevuld
reeksIndex++; // verhoog de index voor de volgende waarde
if (reeksIndex == 10) { // hele tabel gehad?
reeksIndex = 0; // gewoon opnieuw beginnen
}
}
}
Re: analoge potmeter als soort schakelaar
Dank nicoverduin.
Ik begrijp dat mijn voorbeeld-code wat lelijk is, hij is inmiddels ook al 10 veranderd, en vandaar dat de term 'smoothSpeed' wellicht misleidend is...
Het voorbeeld wat jij geeft had ik reeds binnen de code zitten, maar het hielp niet dus heb ik het weggehaald.
Wat jouw code doet is volgens mij vergelijkbaar met een analoog laag-doorlaat filter.
Ik zoek eigenlijk alleen detectie van het verdraaien van de potmeter, zodat op dat moment een nieuwe frequentie/amplitude gegeven kan worden aan een LFO.
Wat het best werkte was dus iets met een threshold, maar ik vrees dat ik iets verkeerd doe, want ik krijg nog steeds verspringingen binnen die threshold.
.
Als een analogRead van een potmeter over een threshold gaat, moet er iets gebeuren, anders niets... Misschien zit ik alweer te lang te staren.
Ik begrijp dat mijn voorbeeld-code wat lelijk is, hij is inmiddels ook al 10 veranderd, en vandaar dat de term 'smoothSpeed' wellicht misleidend is...
Het voorbeeld wat jij geeft had ik reeds binnen de code zitten, maar het hielp niet dus heb ik het weggehaald.
Wat jouw code doet is volgens mij vergelijkbaar met een analoog laag-doorlaat filter.
Ik zoek eigenlijk alleen detectie van het verdraaien van de potmeter, zodat op dat moment een nieuwe frequentie/amplitude gegeven kan worden aan een LFO.
Wat het best werkte was dus iets met een threshold, maar ik vrees dat ik iets verkeerd doe, want ik krijg nog steeds verspringingen binnen die threshold.
.
Als een analogRead van een potmeter over een threshold gaat, moet er iets gebeuren, anders niets... Misschien zit ik alweer te lang te staren.
Re: analoge potmeter als soort schakelaar
Ach het is gelukt! Ook al behoorlijk chaotisch uitgewerkt
De threshold moest toch echt in de loop:
Toch condensatortje van de potmeter gehaald en nicoverduin's code gebruikt, alhoewel een beetje anders en lelijker Maar die had ik nog uit eerdere probeersels.
setup()
de smoothing zelf:
Ow nu het werkt is het nog zaak dat ik de LFO een beetje vorm geef...
Voor nu ben ik blij dat de sketch doet wat ie moet doen, een LFO maken waarvan de amplitude afhankelijk is van frequentie, delaytijd (van de echo) en een potmeterstand.
Dit was maar een extratje op een groter project... En alhoewel alles nieuw voor me is, liep het juist op dit relatief simpele stukje vast...
Dank voor het meedenken iig, en als dingen netter of efficienter kunnen hoor ik de suggesties heel graag.
De threshold moest toch echt in de loop:
- Code: Alles selecteren
speedReading = smoothSpeed(lastSpeedReading);
depthReading = smoothDepth(lastDepthReading);
if( speedReading <= (lastSpeedReading - 2) || speedReading >= (lastSpeedReading + 2) ||
depthReading <= (lastDepthReading - 2) || depthReading >= (lastDepthReading + 2) )
{
int fact = map(delayTime,0,timeOut,127,0);
DEPTH=depthReading/(127.0 + fact + speedReading);
SPEED = (speedReading*200) ;
Serial.print("LFO> depth: "); Serial.print(DEPTH*100); Serial.print(" % ");Serial.print(" speed: ");Serial.println(speedReading);
lastSpeedReading = speedReading;
lastDepthReading = depthReading;
}
Toch condensatortje van de potmeter gehaald en nicoverduin's code gebruikt, alhoewel een beetje anders en lelijker Maar die had ik nog uit eerdere probeersels.
setup()
- Code: Alles selecteren
for (int r = 0; r < 5; r ++){
potReadingsS[r] = 0;
potReadingsD[r] = 0;
}
de smoothing zelf:
- Code: Alles selecteren
//AVERAGING FILTER LFO DEPTH:
int smoothDepth(int last)
{
sumReadingsD= sumReadingsD - potReadingsD[readingCountD];
potReadingsD[readingCountD] = analogRead(depthPot);
sumReadingsD= sumReadingsD + potReadingsD[readingCountD];
readingCountD ++;
if (readingCountD >= 5)
readingCountD=0;
averageReadingsD = sumReadingsD/5;
int current = map (averageReadingsD, 0, 1023, 0, 127);
return current;
}
//AVERAGING FILTER LFO SPEED
int smoothSpeed(int last)
{
sumReadingsS = sumReadingsS - potReadingsS[readingCountS];
potReadingsS[readingCountS] = analogRead(speedPot);
sumReadingsS= sumReadingsS + potReadingsS[readingCountS];
readingCountS ++;
if (readingCountS >= 5)
readingCountS=0;
averageReadingsS = sumReadingsS/5;
int current = map(averageReadingsS, 0, 1023, 62, 2);
return current;
}
Ow nu het werkt is het nog zaak dat ik de LFO een beetje vorm geef...
Voor nu ben ik blij dat de sketch doet wat ie moet doen, een LFO maken waarvan de amplitude afhankelijk is van frequentie, delaytijd (van de echo) en een potmeterstand.
Dit was maar een extratje op een groter project... En alhoewel alles nieuw voor me is, liep het juist op dit relatief simpele stukje vast...
Dank voor het meedenken iig, en als dingen netter of efficienter kunnen hoor ik de suggesties heel graag.
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: analoge potmeter als soort schakelaar
Ik zei al in mijn intro dat ik een "zeikerd" ben met programmeren . Commentaar kost niets meer in de executietijd .
- astrofrostbyte
- Berichten: 229
- Geregistreerd: 20 Jan 2013, 12:01
Analoge potmeter waarde middelen
Ik zou ook gaan voor een middeling van de analoge potmeter waarden, het is vrij simpel toe te voegen.
Hou er echter wel rekening mee dat je sample-rate ook zeer belangrijk is, als je 100 samples/sec zou nemen dan is een middelings diepte van 5 elementen onvoldoende. een potmeter verdraaing is erg traag.
qua middeling zie je veel varianten,
Zelf ga ik vaak voor de ( 7 x oudeWaarde + nieuweWaarde ) / 8 type, omdat hij zich gedraagt als een 1e orde (RC) filter.
deze methode is ook zeer efficient te coderen (snel,weinig geheugen)
Hou er echter wel rekening mee dat je sample-rate ook zeer belangrijk is, als je 100 samples/sec zou nemen dan is een middelings diepte van 5 elementen onvoldoende. een potmeter verdraaing is erg traag.
qua middeling zie je veel varianten,
Zelf ga ik vaak voor de ( 7 x oudeWaarde + nieuweWaarde ) / 8 type, omdat hij zich gedraagt als een 1e orde (RC) filter.
deze methode is ook zeer efficient te coderen (snel,weinig geheugen)
Gear: Arduino- Uno,Due,Ethernet,Mega2560 , OLS LogicAnalyser, TDS1002, Rigol DG1022, J-Link EDU, BusPirate
Re: analoge potmeter als soort schakelaar
Zelf ga ik vaak voor de ( 7 x oudeWaarde + nieuweWaarde ) / 8 type, omdat hij zich gedraagt als een 1e orde (RC) filter.
Ah dat ga ik onthouden!
De middeling die ik heb gebruikt komt van hier: http://arduino.cc/en/Tutorial/Smoothing
Ik ben dus slecht in het schrijven van functies, want ik probeerde die opsomming in de if-statement te veranderen naar een een functie die de drempel maakt...
De LFO amplitude moet afhankelijk zijn van 3 dingen, de instelleing van de 'speed' potentiometer, instelling van de 'depth' potmeter, en de delaytijd.
Het hele verhaal is nu dus zo:
- Code: Alles selecteren
speedReading = smoothSpeed(lastSpeedReading);
depthReading = smoothDepth(lastDepthReading);
if( speedReading < (lastSpeedReading - 1) || speedReading > (lastSpeedReading + 1) ||
depthReading < (lastDepthReading - 1) || depthReading > (lastDepthReading + 1) ||
delayTime != lastDelayTime)
{
// ... dan LFO updaten
lastSpeedReading = speedReading;
lastDepthReading = depthReading;
lastDelayTime = delayTime;
}
Ik was er reeds achter dat >=2 eigenlijk hetzelfde is als >1...
Kan ik de threshold niet vangen in de smoothSpeed() of smoothDepth() functies? Of is dat niet gebruikelijk?
Deze functies middelen nu alleen de lezingen van de 2 potmeters...
Wat ik eigenlijk zou willen is dat ik met die extra functie de if-statement kan beperken tot:
- Code: Alles selecteren
if (speedReading != lastSpeedReading || depthReading != lastDepthReading || delayTime != lastDelayTime)
{
//...dan LFO updaten
}
De huidige code werkt goed hoor, alleen viel iemand mij lastig met de term 'code smell' en ik denk dat de laatste vorm duidelijker is.
zou zoiets mogelijk zijn, of valt dat juist buiten de programmeer etiquetten?
- Code: Alles selecteren
int smoothDepth(int last)
{
//eerst een gemiddelde lezing
if(deze lezing meer dan +1/-1 afwijkt van de vorige lezing)
{
//middel een nieuwe lezing
//geef de nieuwe lezing
//oude lezing = nieuwe lezing
}
}
Dat laatste idee krijg ik dus niet aan de gang...
Maarja, ik ontving mijn Arduino Uno precies 1 maand en 1 week geleden, en had daarvoor nog nooit ook maar één code/sketch of digitaal kunstwerk gezien.
Ik ben dus allang blij dat ik de dingen die ik voor ogen heb kan doen.
Nu de sketchjes wat groter worden, zijn tips om overzicht te houden dus zeer welkom...
- astrofrostbyte
- Berichten: 229
- Geregistreerd: 20 Jan 2013, 12:01
Re: analoge potmeter als soort schakelaar
ja tis een hele kunst om duidelijke code te maken,
zet anders even de volledig code/sketch hier neer ..
zet anders even de volledig code/sketch hier neer ..
Gear: Arduino- Uno,Due,Ethernet,Mega2560 , OLS LogicAnalyser, TDS1002, Rigol DG1022, J-Link EDU, BusPirate
Re: analoge potmeter als soort schakelaar
zet anders even de volledig code/sketch hier neer ..
Ahum... Ik wil dat wel doen Het is echter de 2e sketch die ik heb geschreven...
Dus misschien is het beter als ik alleen het stukje voor de LFO eruit haal... Maarja, zal heel de waanzin wel posten, maar denk vrees dat er voor jullie teveel
haken en ogen aan zitten om doorheen te komen.
Even kort wat de sketch nu doet, wat iets meer is dan een golfje maken.
(Hij moet ook nog een state-variable filter aansturen, maar dit is de basis die ik eigenlijk 'net' zou willen krijgen.
Ik gebruik een digitale dual potmeter (MCP4251 of MCP42050) om de delaytijd van een echo-pedaaltje te regelen.
Ik gebruik geen datasheet tabellen voor de delaytijd, maar laat de arduino eerst de delaytijden bij de 255 potmeterstanden meten.
Meten gaat door een kleine puls het circuit in te sturen en te kijken hoeveel tijd er tussen de eerste (dry) en de tweede puls (wet) zit.
De puls gaat vanaf Arduino pin 4 via een condensator en weerstand naar GND het delay-circuit (5V puls ook gedempt met weerstand en dioode/led) in en komt via een koppelcondensator ook weer terug op A5;
A5 is expres van PULLUP voorzien en heeft ook een 10k naar GND, dit zodat ook een negatieve uitslag gemeten kan worden.
Deze waardes worden opgeslagen in een array int potValue[255];
deze array wordt bij een succesvolle test naar de EEPROM geschreven.
Bij het opstarten wordt de EEPROM gelezen.
Vervolgens een stuk wat de tijd meet tussen drukken op een moment-schakelaar. Het is belangrijk dat de gemeten tijd een gemiddelde is van 2 of meer drukken.
Als iets langer dan de langst gemeten delaytijd is verstreken moet een potmeterstand gevonden worden die dus de bijbehorende gemeten delaytijd geeft.
LFO is modulatie die aan die tijd wordt toegevoegd/weggehaald.
Ik maak een varierend PWM-signaal (32kHz, iig hoger dan audio) wat van Arduino's pin 3 op de gate van 2 bs170 fetjes staat. drain verbonden met de potmeter en source aan GND. parallel aan de fet een 3k6 weerstand.
Door de sinus om een pwm van 127 te laten draaien, probeer ik de gemiddelde delaytijd hetzelfde te houden.
Modulatie/vibrato/chorus is leuk, maar teveel is onmuzikaal, vandaar dat de LFO amplitude afhankelijk is van de eerder genoemde 3 zaken...(depth, speed, delay time.)
hier foto van UNO/Breadboard/testpedaaltje: https://dl.dropboxusercontent.com/u/23071527/2013-06-01%2019.57.55.jpg
Afijn hier wat ik nu heb, excuses voor gebrekkig commentaar in nederlands en engels door elkaar....
- Code: Alles selecteren
//SPI LIBREARY: ****************************************************************************************
#include <SPI.h> //spi library
const int SSDelayPotPin = 10; // deze verbinden met Slave Select vd MCP4251
//byte commandByte = B00010011; //Alleen voor MCP42050;
//WRITE TO EEPROM: **************************************************************************************
#include <EEPROM.h> //EEPROM library
void EEPROMWriteInt(int p_address, int p_value)
{
byte lowByte = ((p_value >> 0) & 0xFF);
byte highByte = ((p_value >> 8) & 0xFF);
EEPROM.write(p_address, lowByte);
EEPROM.write(p_address + 1, highByte);
}
//READ FROM EEPROM: **************************************************************************************
unsigned int EEPROMReadInt(int p_address)
{
byte lowByte = EEPROM.read(p_address);
byte highByte = EEPROM.read(p_address + 1);
return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}
//LFO GLOBAL VARIABLES: ***********************************************************************************
const int speedPot = A1;
const int depthPot = A0;
const int LFOPin = 3;
int speedReading = 0; int lastSpeedReading = 0;
int depthReading = 0; int lastDepthReading = 0;
//averaging potreadings
int potReadingsS [5];
int readingCountS= 0;
int sumReadingsS = 0;
int averageReadingsS = 0;
int potReadingsD [5];
int readingCountD= 0;
int sumReadingsD = 0;
int averageReadingsD = 0;
//lfo clock
boolean LFOClock = false;
boolean lastLFOClock = false;
int SPEED = 1;
float DEPTH = 0.00;
//sine wave array:
int n =0;
int sineWave[]={
0, 4, 8, 13, 17, 22, 26, 30, 35, 39, 43, 47, 51, 55, 59,
63, 67, 71, 74, 78, 81, 84, 88, 91, 94, 97, 100, 102, 105, 107,
109, 112, 114, 116, 117, 119, 120, 122, 123, 124, 125, 125, 126, 126, 126,
127, 126, 126, 126, 125, 125, 124, 123, 122, 120, 119, 117, 116, 114, 112,
109, 107, 105, 102, 100, 97, 94, 91, 88, 84, 81, 78, 74, 71, 67,
63, 59, 55, 51, 47, 43, 39, 35, 30, 26, 22, 17, 13, 8, 4,
0, -4, -8, -13, -17, -22, -26, -30, -35, -39, -43, -47, -51, -55, -59,
-63, -67, -71, -74, -78, -81, -84, -88, -91, -94, -97,-100,-102,-105,-107,
-109,-112,-114,-116,-117,-119,-120,-122,-123,-124,-125,-125,-126,-126,-126,
-127,-126,-126,-126,-125,-125,-124,-123,-122,-120,-119,-117,-116,-114,-112,
-109,-107,-105,-102,-100, -97, -94, -91, -88, -84, -81, -78, -74, -71, -67,
-63, -59, -55, -51, -47, -43, -39, -35, -30, -26, -22, -17, -13, -8, -4 };
//DELAY_TIME CHECK GLOBAL VARIABLES****************************************************
boolean runCheck = false; //
int sendPulsePin = 2; //Arduino-pin to send pulse to delay circuit / AC coupled 4u7 cap limited to 2Vpeak
int recievePulsePin = A5; //ardiuno-pin to recieve pulse from delay-circuit. AC coupled, referenced at Vdd/2
int testPin = 8; //connect switch between pulled up pin and gnd
boolean currentState = LOW;
boolean lastState = LOW;
int pulseRead = 0;
int lastPulseRead = 0;
int pulseCount = 0;
int threshold = 2; //set threshold low enough to read delayed pulse from delay/echo circuit
int potValue[255]; //array filled with delay time readings for digipot value between 0 & 255
int index = 0;
//time measurement
long t1 = 0;
long t2 = 0;
long tCheck = 0;
int delayRead = 1000;
unsigned int resistance = 0; //Arduino calculates resistance connected to PT2399's pin 6 in ohms
int test = 0; //keeps track fo no of tests, when unexpected value occurs, test same potsetting max 10 times
int fail = 0; //after 10 tests, report FAIL,keep track of failed measurements, reset if > 10
boolean FIND = true;
int deviation=1;
//TAP TEMPO GLOBAL VARIABLES : *************************************************
const int tapButton = 7; //mom Sw between pin 7 & GND for tap-tempo
boolean currentTapState = LOW; //variables for debounce
boolean lastTapState = LOW; //tap-tempo button/ button change detection
unsigned long tap1 = 0; //time first tap
unsigned long tap2 = 0; //time second tap
// variables for average interval calculation for >2 taps
int sum = 0;
int divider = 0;
int tapCount = 0;
unsigned long lastInterval = 0;
unsigned long interval = 0;
unsigned long average =300;
unsigned long timeOut = EEPROMReadInt(514); // read longest available delay time from EEPROM
unsigned long delayTime = 300; //root delay time
unsigned int lastDelayTime = 300; // to detct change in delay time
//tempo indicatie led:
const int indLed = 4; //led with 330R connected to pin 4
int blinkLed = 150; // gives rate for tempo indication Led
boolean ledState = LOW;
// SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP * SETUP *
void setup(){
Serial.begin(9600);
SPI.begin();
for (int a = 0 ; a <= 510 ; a += 2){ //collect timing data from EEPROM
int v = a / 2;
potValue[v] = EEPROMReadInt( a );
Serial.print("adress: ");Serial.print(a);
Serial.print(" pot : "); Serial.print(v);
Serial.print (" value: "); Serial.print(potValue[v]);Serial.println(" ms.");
delay(1);
}
Serial.print("TimeOut: ");Serial.println(timeOut);
for (int r = 0; r < 5; r ++){ //reset pot reading smoothing array
potReadingsS[r] = 0;
potReadingsD[r] = 0;
}
pinMode (SSDelayPotPin, OUTPUT);
pinMode (sendPulsePin, OUTPUT);
pinMode (testPin,INPUT);
digitalWrite(testPin,HIGH);
pinMode (recievePulsePin,INPUT_PULLUP);
pinMode(tapButton,INPUT_PULLUP);
pinMode(indLed,OUTPUT);
pinMode(LFOPin,OUTPUT);
int prescalerVal = 0x07; //FAST PWM op pin 3 en 11 32kHz.
TCCR2B &= ~prescalerVal;
TCCR2B |= 1;
}
// END SETUP * END SETUP * END SETUP * END SETUP * END SETUP * END SETUP * END SETUP * END SETUP * END SETUP * END SETUP *
//DEBOUNCING & AVERAGING ************************************************************************************************
//DEBOUNCE START SYNC PROG SWITCH
int debounceDelay = 5;
boolean debounce(boolean last)
{
boolean current = digitalRead(testPin);
if(last != current)
{
delay(debounceDelay);
current = digitalRead(testPin);
}
return current;
}
//DEBOUNCE TAP_TEMPO SWITCH:
boolean debounceTap(boolean last)
{
boolean current = digitalRead(tapButton);
if(last != current)
{
delay(debounceDelay);
current = digitalRead(tapButton);
}
return current;
}
//AVERAGING FILTER LFO DEPTH:
int smoothDepth(int last)
{
sumReadingsD= sumReadingsD - potReadingsD[readingCountD];
potReadingsD[readingCountD] = analogRead(depthPot);
sumReadingsD= sumReadingsD + potReadingsD[readingCountD];
readingCountD ++;
if (readingCountD >= 5)
readingCountD=0;
averageReadingsD = sumReadingsD/5;
int current = map (averageReadingsD, 0, 1023, 0, 127);
return current;
}
//AVERAGING FILTER LFO SPEED
int smoothSpeed(int last)
{
sumReadingsS = sumReadingsS - potReadingsS[readingCountS];
potReadingsS[readingCountS] = analogRead(speedPot);
sumReadingsS= sumReadingsS + potReadingsS[readingCountS];
readingCountS ++;
if (readingCountS >= 5)
readingCountS=0;
averageReadingsS = sumReadingsS/5;
int current = map(averageReadingsS, 0, 1023, 62, 2);
return current;
}
// LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP * LOOP *
void loop(){
unsigned long time = millis();
pulseRead = analogRead (recievePulsePin);
currentState=debounce(lastState);
currentTapState=debounceTap(lastTapState); //debounce functie oproepen
//resistance= (index*195.3125)+1125; //MCP42050
resistance= (index*195.3125)+1075; //MCP4251
// START DELAY TIME MEASUREMENT***************************************************************************
if(lastState == HIGH && currentState == LOW && FIND == false ){ //send 1st pulse
analogWrite (LFOPin,127);
index=0;
digiPotWrite(index);
tCheck = time;
runCheck= true;
digitalWrite(sendPulsePin,HIGH);
delayMicroseconds(80);
digitalWrite(sendPulsePin,LOW);
}
if ( pulseCount == 0 && runCheck==true){ //auto send 80us pulse if pulseCount is reset
tCheck = time;
digitalWrite(sendPulsePin,HIGH);
delayMicroseconds(80);
digitalWrite(sendPulsePin,LOW);
}
// DELAY TIME MEASUREMENT LOOP ***************************************************************************
if(runCheck==true)
{
if(pulseRead >(lastPulseRead+threshold)|| pulseRead < (lastPulseRead-threshold)) //if a change is detected at A5
{
pulseCount ++;
if (pulseCount == 1){ //at first pulse
t1=time; //flag millis()/time
if((t1-tCheck)<10) //if first pulse is recieved within 10ms from the send pulse, it must be the dry signal
lastPulseRead=pulseRead; //record the change
else {
delay((potValue[index-1]+500)) ;
pulseCount = 0;
}
delay(30); //wait for 30ms. before next pulse detection
}
if (pulseCount == 2){ //this must be the delayed/wet signal
t2=(time-t1); //so measure the inteval between 2 pulses
if(t2 < 2000 && t2 > 35){ //if the reading is between 35 and 2000ms, the reading is acceptable.
delayRead = t2;
pulseCount=0;
lastPulseRead = pulseRead;
delay(50);
potValue[index] = delayRead;
}
Serial.print(" digi pot: ");
Serial.print(index);
Serial.print(" = delay time : ");
Serial.print(delayRead);
Serial.print(" ms. ");
Serial.print(" Resistance = ");
Serial.print(resistance);
Serial.println(" ohm.");
//more checks
//check if new measurement is longer than last mesurement
if(potValue[index] > potValue[(index -1)] && (potValue[index]-potValue[index-1])<30){
index ++; //if yes, move to next digipot setting
digiPotWrite(index);
delay(potValue[index]); //wait at least last delaytime so the detector(A5) won't detect the potshifts noise as avalid pulse.
test=0; //reset test count
pulseCount = 0; //and pulse count.
Serial.print("--OK-->");
}
//if an increase in digipot value gives a shorter or the same delay time, something must be wrong, so test again.
if(potValue[index] <= potValue[(index-1)]){
if(test>1)delay((potValue[index-1]+1000));
test++; //keep track of the number of tests
Serial.print(" test: ");
Serial.print(test);
pulseCount=0;
if(test == 10){
Serial.print(" FAIL "); Serial.println(fail);
fail ++;
potValue[index] = (potValue[index - 1] + 4);
index++;
test=0;
if (fail>9){index=0;fail=0;}
}
}
else {
delay((potValue[index-1]+500));
pulseCount=0;
}}
if(index == 255){
timeOut=delayRead;
//WRITE POTVALUES/DELAYTIMES TO EEPROM:
for (int a = 0 ; a <= 510 ; a += 2){
int v = a / 2;
EEPROMWriteInt( a , potValue[v]);
}
delay(300); //relax ??
EEPROMWriteInt(514,timeOut); //Write longest possible delay time to EEPROM.
FIND=true; //FIND A GIVEN VALUE:
Serial.println("DONE");
Serial.println(" ");
Serial.print("searching for "); Serial.print(delayTime); Serial.print(" ms. delay time.");
}
}
}
lastState = currentState;
if(runCheck==false){
//TAP_ TEMPO LOOP START *************************************************************************************
if(lastTapState == HIGH && currentTapState == LOW) { //als de TT-knop wordt ingedrukt
tapCount++; //wordt het aantal keer drukken geteld
switch(tapCount){
case 1: tap1 = time; break; //bij de eerste tap wordt de 'stopwatch' op 0 gezet
case 2: tap2 = (time - tap1); //bij de tweede wordt de tussentijd berekend
interval = tap2; //deze tussentijd wordt opgeslagen
tap1 = 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;
}
}
lastTapState=currentTapState;
if(lastInterval != interval){ //als er een verandering is in het interval tussen 2 taps
if(interval > timeOut)interval=(timeOut);
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-tap1) == (timeOut + 500)){ //na een tijd van timeOut (langst gemeten delaytijd) 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
blinkLed = (delayTime/2);
Serial.print ("searching delay time: "); Serial.print(delayTime); Serial.println(" ms.");
Serial.println(" ------------------------"); Serial.println(" ");
delay(2);
FIND = true;
}
// START FIND POTVALUE FOR GIVEN DELAYTIME: *****************************************************************
if(FIND==true){
for(int x=0; x<256; x++){
if(delayTime == potValue[x] ) { // find exact tapped delaytime is in data
Serial.print("potVal: ");
Serial.print(x);
Serial.print(", time: ");
Serial.print(potValue[x] ) ;
Serial.println(" = spot on!") ;
digiPotWrite(x);
FIND=false;
runCheck = false;
deviation=1;
break;
}
else if(delayTime == ( potValue[x] + deviation ) ) { //if not, let's try to find the closest value 1 ms longer,
Serial.print("potVal: ");
Serial.print(x);
Serial.print(", time: ");
Serial.print(potValue[x]);
Serial.print(" ms,");
Serial.println(" deviation: -");
Serial.print(deviation);
Serial.println(" ms");
digiPotWrite(x);
FIND=false;
runCheck = false;
deviation=1;
break;
}
else if(delayTime == (potValue[x] - deviation) ) { //if not let's try to find 1 ms. shorter than the tapped time.
Serial.print("potVal: ") ;
Serial.print(x) ;
Serial.print(", time: ") ;
Serial.print(potValue[x] ) ;
Serial.print(" ms,");
Serial.print(" deviation: +" ) ;
Serial.print(deviation);
Serial.println(" ms");
delay(1);
digiPotWrite(x);
FIND=false;
runCheck = false;
deviation=1;
break;
}
if( x==255 ) {
deviation++;
x=0;
}
if( deviation==20 ){
FIND=false;
runCheck = false;
Serial.println ("NOT FOUND!");
deviation=1;
break;
}
}
}
ledState = (time/blinkLed)%2; //ledje geeft tempo aan
digitalWrite (indLed,ledState);
//LFO SETTINGS*************************************************************************
LFOClock = (micros()/SPEED)%2;
speedReading = smoothSpeed(lastSpeedReading);
depthReading = smoothDepth(lastDepthReading);
if( speedReading < (lastSpeedReading - 1) || speedReading > (lastSpeedReading + 1) ||
depthReading < (lastDepthReading - 1) || depthReading > (lastDepthReading + 1) ||
delayTime != lastDelayTime)
{
int fact = map(delayTime,50,timeOut,127,0);
DEPTH=depthReading/(127.0 + fact + speedReading);
if(DEPTH < 0.01)DEPTH = 0;
SPEED = (speedReading*200) ;
lastSpeedReading = speedReading;
lastDepthReading = depthReading;
lastDelayTime = delayTime;
Serial.print("LFO> depth: "); Serial.print(DEPTH*100); Serial.print(" % ");Serial.print(" speed: ");Serial.println(speedReading);
}
if( LFOClock != lastLFOClock ){
n++;
if (n==180)n=0;
float z = sineWave[n]*DEPTH;
analogWrite(LFOPin, z+127);
lastLFOClock = LFOClock;
}
}//END RUNCHECK==FALSE
}
//END VOID LOOP************************************************************************
// Write to digipot:*******************************************************************
void digiPotWrite( int value) {
//MCP4251:
digitalWrite(SSDelayPotPin,LOW); //Slave Select delay-pot
SPI.transfer(B00000000); //Write P0
SPI.transfer(value); //data for P0 (0 ~ 255)
SPI.transfer(B00010000); //Write P1
SPI.transfer(value); //data for P1 (0 ~ 255)
digitalWrite(SSDelayPotPin,HIGH); //end write to delay-pot
// MCP42050:
// digitalWrite(SSDelayPotPin,LOW);
// SPI.transfer(commandByte); //Write P0 en P1
// SPI.transfer(value); //data voor P0 en P1 (0 ~ 255)
// digitalWrite(SSDelayPotPin,HIGH);
}
13 berichten
• Pagina 1 van 2 • 1, 2
Wie is er online?
Gebruikers in dit forum: adhaplahika en 18 gasten