Frage zum software modification

alda

Member
Hallo,

Es ist möglich, dass der Wert SEN_MOTOR_RIGHT und SEN_MOTOR_LEFT gezählt von 500 geladenen Werte? Dann ist das Ergebnis sehr viel stabiler.


motorRightSense = motorRightSense * 0.95 + ((double)abs(readSensor(SEN_MOTOR_RIGHT))) * 0.05;
motorLeftSense = motorLeftSense * 0.95 + ((double)abs(readSensor(SEN_MOTOR_LEFT))) * 0.05;

Danke

Alex
 
Hallo Alex,

Du kannst die Frequenz zur Abfrage des Stroms hier ändern:

void readSensors(){
...
nextTimeMotorSense = millis() + 50;
 
Hallo Alexander,

Ja, Code habe ich verstanden ( hoffe ich ). Aber ich sehe, gibt es nur ein Fehler.

Diese Werte welche schwanken ist Ampere nicht ( Beispiel ) :

Wert SEN_MOTOR_RIGHT ist geladen von aml50.h - case SEN_MOTOR_RIGHT: return(analogRead(pinMotorLeftSense)-motorSenseRightZero); break;

pinMotorLeftSense - Der Spannungswert am Analogeingang ( 0-1023 ). Wenn der Strom null ist, dann sendet der ALC972-5 einen MotorLeftSenseSpannung 2,5 V ( mit Vcc = 5V ) und das ist Wert 512 von Analogeingang.
motorSenseRightZero - ist 511 ( Kann eingestellt werden )

Wenn strom null ist, dann : (analogRead(pinMotorLeftSense)-motorSenseRightZero) = 512 - 1 = 1 - Nicht Ampere, aber digital analogwert und optimal ist mit Strom null auch diese Wert null haben. Das heist ändern motorSenseRightZero = 512. Dann null Strom = SEN_MOTOR_RIGHT - 512 = motorRightSense = 0.

Unter Last, die Spannung von der ALC zunimmt und auf Wert von Analogeingang aber .....
Beispiel :
pinMotorLeftSense mit Last is 514. Dann : (analogRead(pinMotorLeftSense)-motorSenseRightZero) = 514 - 512 = 2 - Nicht Ampere.

Um Ampere berechnen, finden Sie in diesem Web-Seite :
http://www.lucadentella.it/en/2011/11/29/sensore-di-corrente-con-arduino/
Das heißt ( ich nehme nur pinMotorSense wert ) : 514 = 0,0264 * 514 - 13,51 = 0,0596A
Für ALC972-5.

Aber schwanken ist zu hoch. Es ist viel stabiler mit diesem Code :


motorRightSense = 0;
for(int i = 0; i < 1000; i++) {
motorRightSense = motorRightSense + (.0264 * (512+(readSensor(SEN_MOTOR_RIGHT))) -13.51) / 1000;
delay(1);
}

Aber das ganze Steuersystem zu verlangsamen ( Aber auch mit 10 ist besser ). Auch auf 512 zurückzuführen wäre nicht nötig gewesen, wenn der Teilwert "motorSenseRightZero" gesetzt von -100 bis 100.

Alex
 
@Alex: könntest Du Deinen Text demnächst auf Englisch schreiben? ;-) Wenn es um technische Dinge geht ist das meines Erachtens die beste Sprache...

Ich versuche mal zu verstehen was Du geschrieben hast...
 
@Alex: the computed/shown values in Ardumower are not Ampere values :) - It's not any unit (and doesn't have to be).

The main program asks the robot config (aml59.h) to read the motor current (SEN_MOTOR_RIGHT) - that will read the current sensor, add some offset (motorSenseRightZero) and then return that value to the main program.

The main program will smooth the returned values (over time). Of course, the values will fluctuate more if they were scaled down, but the motor stop threshold (motorCurrentMax) would have to decrease too. So, in fact the fluctuation is the same.

Example - Let's imagine you have these values:
10, 9, 11, 10, 9, 11 - let's say the current threshold is 10

Now let's scale down them by factor 10:
1.0, 0.9, 1.1, 1.0, 0.9, 1.1 - the current threshold is now 1.0

The fluctation in percent is the same (it's just another scale). Also the smoothing would be the same (just in another working scale).

So, the code doesn't need Ampere values (as it compares measured and smoothed valuse to the threshold). Of course, you could add some scale (in addition to the offset) in your robot config to it.


Regards,
Alexander
 
Hallo Alexander,

Yes, Code is quite clear ( I hope so ), but I see, that here is a error.

Measured current value which is jumping isn't current in Amps. Example :


Value "SEN_MOTOR_RIGHT" is readed from aml50.h:
case SEN_MOTOR_RIGHT: return(analogRead(pinMotorLeftSense)-motorSenseRightZero); break;

pinMotorLeftSense - it's value from analog input which is relevant to voltage connected to analog input and is 0-1023. When current is 0, ALC972-5 will send to analog input 2,5 V ( for Vcc = 5V ) and pinMotorLeftSense is 512.
motorSenseRightZero is 511 ( Can be adjusted )

So when current is 0, then : (analogRead(pinMotorLeftSense)-motorSenseRightZero) = 512 - 1 = 1 - But it isn't 1Ampere, it's one bit and it means that's necessary adjust zero position and change motorSenseRightZero to 512. After this adjustment : Zero current = SEN_MOTOR_RIGHT - 512 = motorRightSense = 0.

And with load :

pinMotorLeftSense will increase to aprox. 514. Then : (analogRead(pinMotorLeftSense)-motorSenseRightZero) = 514 - 512 = 2 - It isn't in Amps.

When we want value in Amps, we must measurement recalculate - see this web site :

www.lucadentella.it/en/2011/11/29/sensor...orrente-con-arduino/

i.e. for pinMotorSense = 514 : 0,0264 * 514 - 13,51 = 0,0596A
For ALC972-5.

So we have a value in amps, but it's jumping. To decrease jumping radically, we must measure more values and calculate average :

motorRightSense = 0;
for(int i = 0; i < 1000; i++) {
motorRightSense = motorRightSense + (.0264 * (512+(readSensor(SEN_MOTOR_RIGHT))) -13.51) / 1000;
delay(1);
}

This code is for 1000 measurements, but not unusable, because will decrease radically system reactions.

Now I'm using this code :
motorRightSense = (motorRightSense * 0.95) + ((double)abs(.0264 * ((readSensor(SEN_MOTOR_RIGHT))) -13.51)) * 0.05;
Which give me a correct current value, but unstable and "motorSenseRightZero" is normally 0 with possibility adjust -100 to 100 and code in aml50.h is :
case SEN_MOTOR_RIGHT: return(analogRead(pinMotorLeftSense)+motorSenseRightZero); break;
So SEN_MOTOR_RIGHT value is for zero current = 512.

But it's for ALC972-5. For ALC972-30 code is :
motorMowSense = (motorMowSense * 0.95) + ((double)abs(.0742 * ((readSensor(SEN_MOTOR_MOW))) -37.88)) * 0.05;

Hope it's more understable in English.

Alex
 
Hello Alexander,

your second answer cleared the situation. Why I was asking is, that I understand that you want present in pfodApp value in amps. Now it's clear.

Alex
 
Hello Alex,

We don't want Ampere values, we just use imaginary units and compare the values to some threshold value (motorCurrentMax).

Of course, we could read more measurements to better smooth the result, however
1. this requires too much CPU time (the Ardumower has quite a lot to do in one second)
2. this would increase the delay when comparing to the threshold value (threshold would be detected too slow)

So, no need to rescale to Ampere - just keep the units what they are (imaginary), fine tune the motorCurrentMax, and let the values fluctuate :)

The order of fluctuation (percent) is always the same independent of the unit (Ampere or not Ampere).

I hope this makes sense :)

Regards,
Alexander
 
Exactly, only the battery voltage and charger voltage and current use Volt and Ampere units.

As you can see, the charger current readings use a scale factor (chgFactor), and this scales to Ampere (actually Ampere * 100 because it has to use integer values internally):

case SEN_CHG_CURRENT: return((int)(((double)analogRead(pinChargeCurrent)-chgSenseZero) * chgFactor)); break;

So, you can use 'batFactor', 'chgSenseZero', and 'chgFactor' to fine tune to real Volt and Ampere values the charger voltage/current and battery voltage.
 
Oben