woensdag 17 oktober 2012

Sample tijd berekenen


Doel
We willen berekenen of onze microcontroller voldoende snel is om binnen een cyclus de sensorwaarden uit te lezen en ze te verwerken. De PID regeling laten we voorlopig buiten beschouwing aangezien we afhankelijk van de tijd die we nog over hebben  van onze cyclus nog kunnen beslissen of we de PID regeling nog door een andere microcontroller laten uitvoeren.
We maken dus een vergelijking tussen de sample tijd en de cyclustijd.


Berekening van de tijd voor de verwerking van de meetwaarden
Normaliseren
We krijgen van elke sensor een verschillende meetwaarde, en omdat we geen peren met appels kunnen vergelijking gaan we deze normaliseren. Dit omdat we de verschillende sensorbereiken en de gemeten meetwaarden in éénzelfde schaal willen zetten.
Hiervoor zit er een functie in de arduino-programeertaal: map(a,b,c,d,e,).
De variabelen zijn:
- a: de gemeten waarde
- b: de minimum grens van het oude meetbereik
- c: de maximum grens van het oude meetbereik
- d: de minimum grens van het nieuwe meetbereik
- e: de maximum grens van het nieuwe meetbereik


Minimum uit een array halen 
We hebben per sensor een waarde, in ons geval 6 waarden.
Nu moeten we echter de sensor met de kleinste meetwaarde en de meetwaarde van deze links en rechts ernaast weten om deze straks in onze interpollatie te gebruiken.Hierbij komen we tot de conclusie dat onze buitenste sensoren nooit de kleinste meetwaarde mogen leveren. We hebben namelijk 3 referentiepunten nodig. Waarvan het middenste referentiepunt de kleinste moet zijn. Wanneer dit één van de buitenste sensoren is , hebben we maar 1 referentie bij nl. links of rechts ervan. Daarom dat we van sensor 1 tot en met 4 de kleinste zoeken. Sensor 0 en sensor 5 zijn onze buitenste sensoren die enkel als referentiepunt mogen dienen. Hieronder vind u het gebruikte algoritme.


kleinste=100
For (sensor1meetwaarde to sensor4meetwaarde)
If sensor(x)meetwaarde<kleinste
then
kleinste=sensor(x)meetwaarde
Interpoleren 
sensorLocatie=sensor(x)locatie
end if
end for 

Interpoleren
We weten nu waar in de buurt onze lijn zich bevind. We willen echter exact weten waar het midden van onze lijn zich bevind om ons te perfect boven de lijn te positioneren. Met behulp van volgende formule en de 3 sensors in de buurt van de lijn is dit mogelijk.
=[(Y1-Y3)/2 ]* (1/Y1+Y3-2Y2)




Zoals je weet wordt een parabool gedefinieerd door een kwadratische vergelijking van de vorm y=ax2+bx+c. Elke parabool wordt gedefinieerd door 3 punten. Hier Y1,Y2,Y3 met respectievelijke x-waarden -1,0,1

Na subtitutie van volgende waarden in de vergelijkingen komen we op :
Y1=a-b+c
Y2=c
Y3=a+b+c
We willen echter het minimum want zoals reeds gezegd ligt daar ons lijn. Het minimum bekomen we door een afleiding temaken van de basis formule.
y' = (y=ax2+bx+c)' = 2a+b => x= -b/2a
nu proberen we Y1,Y2,Y3 via subtitutie in deze vergelijking te krijgen

-b=> Y1-Y3= a-b+c-a-b+c=-2b =>-2b/2 = (Y1-Y3)/2
2a=> Y1+Y3-2Y2= a-b+c+a+b+c-2c=2a

 -b/2a=[(Y1-Y3)/2 ]* (1/Y1+Y3-2Y2)
Merk op dat de rode 1 die we hier gebruiken is de afstand tussen de sensoren in het programma. We zetten deze als een variable zodat we hierin kunnen variëren om zo de beste instelling te kiezen.


Lengte programma
De lengte van het programma verschilt per test. Dit is omdat de berekeningen licht anders zijn als de lijn zich onder de buitenste sensors bevindt.
De maximumtijd die het programma duurt is 1200 microseconden.


Code
int sensorPin[] = {A0,A1,A2,A3,A4,A5};
int sensorValue[6];
int minimum[] = {0,0,0,0,0,0};//minimum waarde per sensor
int maximum[] = {1023,1023,1023,1023,1023,1023};//maximum waarde per //sensor
int sensorWaarden[] = {-250,-150,-50,50,150,250};
int kleinste=100;
int sensorLocatie=1;
int lijnValueTeller,lijnValueNoemer,lijnValue;

void setup() {
  Serial.begin(9600);
}

void loop() {
 
  //uitlezen en normaliseren per sensor
  for (int i=0;i<6;i++) {
    sensorValue[i]=analogRead(sensorPin[i]);//waarde uitlezen
    sensorValue[i]=map(sensorValue[i],minimum[i],maximum[i],0,100); 

    //waarden in range [0-100] omzetten
    // sensorValue[i]=constrain(sensorValue[i],0,100);//waarden 

    // buiten range aanpassen
    // (waarde<0 => waarde=0, waarde>0 => waarde=100)
  }
 
  //kleinste uit array halen, sensor 0 en 5 worden niet meegerekend omdat deze de buitenste sensoren zijn


  kleinste=100;
  for (int i=1;i<5;i++) {
    if (sensorValue[i]<kleinste) {
      kleinste=sensorValue[i];
      sensorLocatie=i;
    }
  }
 
  //positie lijn berekenen (interpoleren)
  lijnValueTeller=(sensorValue[sensorLocatie-

    1]-sensorValue[sensorLocatie+1])*100;
  lijnValueNoemer=(sensorValue[sensorLocatie-

    1]+sensorValue[sensorLocatie+1]-2*sensorValue[sensorLocatie])*2;
  lijnValue=lijnValueTeller/lijnValueNoemer;
  lijnValue+=sensorWaarden[sensorLocatie];
}


Geen opmerkingen:

Een reactie posten