Starke Spurabweichung (Drift) nach längerer Einschaltzeit

For me, Just disabling the super Spike eleminator wasnt enough to solve the drunken Problem. Bernards solution did it, but I left the If in the Code, that would only Count high Pin Interrupts and Not Count Low Pin Interrupts too.
 
Ich habe auch die Spurabweichung diese Woche gehabt beim Ardumower. Es blieb eindeutig ein paar Stellen dadurch stehen.
 
Now I change all what Bernard proposed and add on also:
- disabled SUPER_SPIKE_ELIMINATOR
- AGCM4 stack memory waste workaround: https://github.com/Ardumower/Sunray/commit/42822f658f0279d4c7d1511362c7d23ee086d346
Hope it was correct also to do upper both changes also?

Then I did also the AT+E test and I have to change TICKS_PER_REVOLUTION from 696 / 2 to 2056 / 2 - WOW!!
Interessting has been that right whell moved exaclty 10 turns, but left whell only 9,9 turns.
Nevertheless now Mower is mowing and driving straight on without being drunken, also with speed 0,35!
Now let him do his job and then charge on docking and will see tomorrow if its still ok
... ;-)
 
For me, Just disabling the super Spike eleminator wasnt enough to solve the drunken Problem. Bernards solution did it, but I left the If in the Code, that would only Count high Pin Interrupts and Not Count Low Pin Interrupts too.
what exactly did you do? can you post the code here - before and after your change? would be great, thanks
 
Its basically Bernards simple Tickcount in amdriver.cpp. but Not Counting the Hall Low and highs, but only the highs. Thats why you Had to increase your Ticks per Rotation that much. You have the Double amount of Ticks. Basically, thats why its was devided by 2 in the define... you could Just leave it.

Just compare Bernards Code with the original and you will understand.
 
@konny
Into amrobotdriver.cpp

Code:
attachInterrupt(pinOdometryLeft, OdometryLeftISR, CHANGE);
attachInterrupt(pinOdometryRight, OdometryRightISR, CHANGE);
attachInterrupt(pinMotorMowRpm, OdometryMowISR, CHANGE);

if you want to reduce the ticks interrupt ISR you can replace the "CHANGE" in the interrupt by "RISING" and repeat the AT+E process

Code:
attachInterrupt(pinOdometryLeft, OdometryLeftISR, RISING);
attachInterrupt(pinOdometryRight, OdometryRightISR, RISING);
attachInterrupt(pinMotorMowRpm, OdometryMowISR, CHANGE);

@Mr. Tree
Reading digital input inside ISR take time, and it can have impact on other fast part like the serial ,SD Card, or I2C one functionality .
it's the reason why i reduce the ISR code part at minimum code possible and add asm("DSB")
BUT NOT REALLY SURE IT HAVE IMPACT ON MOWER
 
So that would get rid of the unneccesary IF in the interrupt routine, yeah i see.
As far as i can say, just disabling superspike didnt do it. I did not test twice, but after it did it once again i changed to your solution and i never saw it again. Got rid of the supercode entirely too.
 
Now I change all what Bernard proposed and add on also:
- disabled SUPER_SPIKE_ELIMINATOR
- AGCM4 stack memory waste workaround: https://github.com/Ardumower/Sunray/commit/42822f658f0279d4c7d1511362c7d23ee086d346
Hope it was correct also to do upper both changes also?

Then I did also the AT+E test and I have to change TICKS_PER_REVOLUTION from 696 / 2 to 2056 / 2 - WOW!!
Interessting has been that right whell moved exaclty 10 turns, but left whell only 9,9 turns.
Nevertheless now Mower is mowing and driving straight on without being drunken, also with speed 0,35!
Now let him do his job and then charge on docking and will see tomorrow if its still ok
... ;-)
Hello, so today I have tested my Mower the 2nd day after all my changes above.
The Mower have been now about 20h on the docking station without beiing switched off.
Today again the mower runs straight forward, no drunken pilot - so it seems the mower now works fine.
Tanks to your fast and great support here, really very appreciated!!
Tomowwor I will mow again then after 40h...
 
Dont forget to make the mowmotor Interrupt rising too and Change it to simple Counting code, it wasnt changed in Bernards Last Post.
 
Ich habe heute eine Fläche fertig mähen lassen, wo er dann an einem bestimmten Dock Punkt stand und sich ausgeschaltet hat, da die Fläche eine abgetrennte Fläche für den Hund ist. Danach noch auf eine andere Fläche von Hand umgesetzt, dort wollte ich starten und da ruckte kurz der Mähmotor und dann fing er wieder an zu piepsen. Nochmal Stop gedrückt, ihn per Joystick kurz bewegt, dann den Startbutton und dann hat er gemäht. Muss mal bei Gelegenheit mit dem PC ran und schauen was er im Seriellen Monitor anzeigt, wenn er piepst. Ich habe deine letzte geänderte Firmware installiert die 314ide_drv.
 
Das hat hier zwar nichts zu suchen... aber hast du abgewartet? Vllt hat die kidnap Funktion gegriffen weil du ihn händisch umhergetragen hast?
 
Wenn ich es richtig beobachtet habe, wird die kidnap Funktion resetted, wenn man Stop + Start auslöst. (Selten versetze ich den Mäher auch von Hand und kann die Kidnap Funktion mit Stop + Start quasi aushebeln)
 
Dont forget to make the mowmotor Interrupt rising too and Change it to simple Counting code, it wasnt changed in Bernards Last Post.
So you mean to change this original Code:
void OdometryMowISR(){
if (digitalRead(pinMotorMowRpm) == LOW) return;
if (millis() < motorMowTicksTimeout) return; // eliminate spikes
#ifdef SUPER_SPIKE_ELIMINATOR
unsigned long duration = millis() - motorMowTransitionTime;
if (duration > 5) duration = 0;
motorMowTransitionTime = millis();
motorMowDurationMax = 0.7 * max(motorMowDurationMax, ((float)duration));
motorMowTicksTimeout = millis() + motorMowDurationMax;
#else
motorMowTicksTimeout = millis() + 1;
#endif
odomTicksMow++;
}

into this new one:
void OdometryMowISR(){
odomTicksMow++;
asm("dsb");
}

correct?
And what is btw asm("dsb"); doing exactly?
But for Mow-Motor no Ticks-per-revolution to be adapted because not exsiting, right?
 
Correct, and then RISING in the attachInterrupt define.

It does exist, but it is hardcoded with 6 Ticks per Rotation in the original Code, Not in the config.h.

I dont know what IT does exactly, its doing Something with the memory. Bernard knows probably.
 
Bernard knows probably.
For asm("dsb") i need to say that i don't know if it's mandatory for AGCM4 and the exact functionality , but in fast TEENSY i have made a lot of test and the result is that interrupt work better with this line of code.
And if you have odometry on Mow motor , you also need to change the code like describe in @konny post.

@Mr. Tree
I don't remember where , but i see a post with mow motor activation strange behaviour, remember that code for tilt is not ok into linetracker.cpp
because setmowstate is always write in the main loop of the code.
 
Yes, i already changed that quite a while ago to be a Switch only firing when there is a Change in bool. (y)

As far as i can say, I observed the mower now for almost 3 years. The robustness in Performance overall changed definitely to the better with your simple Odo Code solution.

None the less, there is still Something awkward. I have an RPM Trigger for the mowmotor, when mower shall be slower or Reverse If RPM Stalls to certain values. Whenever the bumper triggers, IT might read a Stall in rpm too. There is No Code that could relate to this. Its Something with the Interrupt of bumper that leads to Low readings of the other Interrupts of Odo.
 
Zuletzt bearbeitet:
It's strange, but for Bumper the code is OK but certainly not optimum for fast use
Interrupt on pinbumper generate one isr ,and inside that ISR we read again the pinbumper ???

Code:
void AmBumperDriver::begin(){   
  pinMode(pinBumperLeft, INPUT_PULLUP);                   
  pinMode(pinBumperRight, INPUT_PULLUP);                   
  attachInterrupt(pinBumperLeft, BumperLeftInterruptRoutine, CHANGE);
    attachInterrupt(pinBumperRight, BumperRightInterruptRoutine, CHANGE);
}

Replace CHANGE by RISING or FALLING according your bumper NC or NO

Code:
// ------------------------------------------------------------------------------------
void BumperLeftInterruptRoutine(){
  leftPressed = (digitalRead(pinBumperLeft) == LOW); 
}

void BumperRightInterruptRoutine(){
  rightPressed = (digitalRead(pinBumperRight) == LOW); 
}

Replace by:
Code:
void BumperLeftInterruptRoutine(){
  leftPressed = true;
}

void BumperRightInterruptRoutine(){
  rightPressed = true;


and test

If it don't work you certainly need to reset the leftpressed to false after management of the bumper function.
 
Die "SUPER_SPIKE_ELIMINATOR" ist übrigens auch beim neuen Release immer noch Default aktiv... ich frag besser gar nicht...
 
jepp. Schade, dass da nichts nennenswertes mehr passiert. Das Konzept ist extrem cool…. aber leider tot. Ob ich auf der Basis den Weg zu ROS mitgehe? Wohl eher nicht. Bin trotzdem gespannt, wie es hier weitergeht. Die Comunity ist ja weiterhin unverdrossen und das auch gut so.
 
Oben