Perimeter v2 - improved receiver code

nero76

Moderator
Hello,

It seems I could improve perimeter v2 further (especially for short perimeter loops).

Theory: It works by removing the capacitor C1 (4,7n) on the receiver circuit which results in a so called 'differential signal', in other words skipping step 4 in this image: http://wiki.ardumower.de/images/f/fd/Perimeter_signal_steps.png

Steps: If you want to try this out, here are the steps:

1. Remove capacitor C1 (4,7n) in the receiver circuit: http://wiki.ardumower.de/images/e/eb/Perimeter_v2_receiver_circuit.jpg
2. Download latest Ardumower code from Github (05.April 2015 or later).

3. Via your Android device (pfodApp/ArduRemote), choose 'Settings->Perimeter->Use differential signal = YES'. Now you can compare the signal quality ('qty') via pfodApp ('Plot->Perimeter').


NOTE: You can always switch back to the normal signal again by simply chooseing 'Settings->Perimeter->Use differential signal = NO' in the pfodApp.

Also, there's a new option 'Swap coil polarity' in the settings too, so you can easily swap the polarity of the coil.


All your feedback on the differential signal test is welcome.

Regards,
Alexander
 
Hi!

I'm using latest software, and I removed C1 capacitor, and its receiving a signal measured with pfodApp, from -500 to -2700.
But I don't know, why signal changing polarity whenever robot starts running, so it's almost all time in REV mode..
I checked all, shielded from motors to DC-DC converters, but no difference.
It shows INSIDE before starting, but sec or two after turning on auto mode, just for moment, shows OUTSIDE, and robot change state.
very annoying.. please help!
Casper! :unsure:
 
Hello Casper,

I assume your robot did not do this in the older versions. I had the same problem, the perimeter signal was fine when no gear motor was running. I put the perimeter coil+receiver 1 meter away from any motors, then started the robot. The signal quality did go down, and perimeter quickly toggles between inside and outside.

1) The reason in my situation was:
To get a precise ADC measurement, latest receiver code uses 38 khz ADC sampling rate. That works fine. However, now the Arduino is more often in the ADC interrupt code, and now the motors make a problem: The interrupt routine for the Ardumower motor encoders (producing 1060 ticks per turn, so 580 ticks per second @30 rpm speed - for two motors and two channels: 2300 ticks per second!) do BLOCK the perimeter receiver ADC interrupt.

2) Solution in my situation was:
Let the odometry interrupt allow nesting (so ADC interrupt can run while Arduino is in odometry interrupt).

In mower.cpp, make sure there is a 'ISR_NOBLOCK' keyword in the odometry interrupt routine like shown below:

Code:
// odometry signal change interrupt
// mower motor speed sensor interrupt
// NOTE: when choosing a higher perimeter sample rate (38 kHz) and using odometry interrupts, 
// the Arduino Mega cannot handle all ADC interrupts anymore - the result will be a 'noisy'
// perimeter filter output (mag value) which disappears when disabling odometry interrupts.
// SOLUTION: allow odometry interrupt handler nesting (see odometry interrupt function)
// [URL]http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html[/URL] ISR(PCINT2_vect, ISR_NOBLOCK){
...
}


3) Alternatively, you can reduce ADC sampling rate in adcman.cpp to old 9616 Hz again (see below). However this will reduce perimeter magnitude precision (it's ok and will work anyway). I wanted higher magnitude precision for my experiments.


Code:
ADCManager::ADCManager(){
...
  // NOTE: when choosing a higher perimeter sample rate (38 kHz) and using odometry interrupts, 
  // the Arduino Mega cannot handle all ADC interrupts anymore - the result will be a 'noisy'
  // perimeter filter output (mag value) which disappears when disabling odometry interrupts.
  // SOLUTION: allow odometry interrupt handler nesting (see odometry interrupt function)
  //sampleRate = SRATE_19231;
  //sampleRate = SRATE_38462;
  sampleRate = SRATE_9615;



4) If all that doesn't help in your situation, you might have another issue (e.g. real motor noise disturbing your differential signal). I think the differential signal (without capacitor C1) is more easy to disturb. You might have to increase distance between coil and motor, put coil directly onto amplifier PCB, and shield coil and amplifier from motor (e.g. by putting the battery in between).

If real motor noise is the problem, you can still use non-differential signal if you like (via pfodApp->Perimeter->Use differential signal NO) and using capacitor C1. However we did go for differential signal, as the combination of coil+C1 does not fit to all different types of perimeter wire systems (different wire lengths, perimeter current etc). A differential signal seem to fit better for different sender systems.

Regards,
Alexander
 
@Casper: addendum: Please provide feedback if you found a solution (and which). Only feedback will help us to change hardware and software so that it runs smoothly everywhere... Thank you!
 
Hi all.
Thanks to Alexanders suggestion,
I did everything what was in my knowledge, to found a solution.
In the end, I found out, that is whole problem in disturbance of signal. I made al measurements from sender, to coil and amplifier, but always, received signal was quite unstable. Switching between outside and inside loop actually started even before motors ran.
That was a thing, I dint pay attention in begin.
At last, I put coil and amplifier outside the mower, app. 15cm in front the mower, and finally start listen the real signal from wire.
Now I have to find out, how to shield and put together, my converted Tianchen mower, to be complex and look a little better.

I will post results soon.

Thanks guys!

Casper
 
Oben