Perimeter wire: Unterschied zwischen den Versionen

Aus www.wiki.ardumower.de
Wechseln zu: Navigation, Suche
(Signal)
(Perimeter)
 
(282 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
 
=Abstract=
 
=Abstract=
A perimeter wire (or buried wire fence, BWF) is like a 'virtual fence': it stopps the robot when it reaches its boundaries. A perimeter is not always necessary for all surroundings (a lawn sensor might be an alternative).
+
A perimeter wire (or buried wire fence, BWF) is like a 'virtual fence': it stopps the robot when it reaches its boundaries. A perimeter is not always necessary for all surroundings.
  
 
Principle idea: You will install a perimeter loop (a wire) in your garden through which a signal is sent and this signal is detected by the robot. So, you'll need: a sender (to transmit the on the wire) and a receiver (to detect the signal in the robot).
 
Principle idea: You will install a perimeter loop (a wire) in your garden through which a signal is sent and this signal is detected by the robot. So, you'll need: a sender (to transmit the on the wire) and a receiver (to detect the signal in the robot).
  
How is the signal detected?  The signal is detected by one (or two) receiver coils. The closer the distance between coil and perimeter loop, the higher the signal strength. Also, something interesting happens when the robot crosses the perimeter loop: the signal changes its polarity, that means positive and negative voltages reverse each other. So, there are two basic principles to detect the perimeter loop. We have implemented both methods (perimeter v1 and v2) which are described below.
+
How is the signal detected?  The signal is detected by one receiver coils. The closer the distance between coil and perimeter loop, the higher the signal strength. Also, something interesting happens when the robot crosses the perimeter loop: the signal changes its polarity, that means positive and negative voltages reverse each other.  
  
 
<gallery>
 
<gallery>
 
File: Ardumower_perimeter.jpg | Perimeter wire
 
File: Ardumower_perimeter.jpg | Perimeter wire
File: Ardumower_perimeter_components.jpg | Components
 
 
File: Perimeter_signal_strength.jpg | Signal strength
 
File: Perimeter_signal_strength.jpg | Signal strength
 
File: Perimeter_gradient.png | Perimeter gradient
 
File: Perimeter_gradient.png | Perimeter gradient
File: Ardumower_perimeter_magneticfield.png | Perimeter magnetic field
+
File: Perimeter_excluding_objects.png | Excluding objects
 +
File: Perimeter_divide.png | Dividing areas
 
</gallery>
 
</gallery>
  
[http://hyperphysics.phy-astr.gsu.edu/hbase/magnetic/magcur.html Magnetic field calculator]
+
=Perimeter=
  
Videos:
+
[[Image:Yt-brand-standard-logo-95x40.png|thumb|180px|https://www.youtube.com/watch?v=NIer_kITelc&feature=youtu.be]]
[http://youtu.be/r4ZMgasMkH0 Magnetic field demonstration video]
+
  
=Perimeter v1 (for old v0.9.3 code, not recommended)=
+
This is the new version of the perimeter sender and receiver (that can be purchased via the [https://www.marotronics.de/index.php?k=7 shop] [[File: shopping.png|link=https://www.marotronics.de/index.php?k=7]]).
  
This was the first version of our perimeter sender and receiver. It has some drawbacks (orientation issues, no sender-off detection, no inside/outside state detection), so it's not recommended to build it anymore. Use the second version (v2) of our perimeter sender and receiver further below.
+
The perimeter sender outputs a digital code sequence (a 'pseudo-noise' code), and the receiver will detect that code using a software-based digital matched filter. Depending on wheter the match result peak is positive or negative, the robot is inside or outside of the perimeter wire.
  
==Sender==
+
Sender principle:
You can use the sender of a commercial lawn robot (the sender shown here is compatible with Tianchen or Rotenbach robot mowers), or you build one yourself.
+
# Sender PCB generates an output signal using an Arduino Nano (about 3 Khz)
 +
# The generated signal is amplified using a motor driver (MC33926), the motor driver output is connected to the perimeter wire (instead of a motor)
  
So, here's the sender:
+
Receiver principle:
 +
# A coil receives the signal
 +
# The signal is amplified using an operational amplifier (LM386)
 +
# The Arduino Mega samples the signal using its analog-to-digital converter (ADC) at 9615 Hz
 +
# The digital signal is filtered using a digital filter (matched filter algorithmn)
 +
# The matched filter output is evaluated (for perimeter inside/ouside detection, tracking etc.)
  
An Arduino (e.g. Nano) generates a square signal that is used to switch the direction of a motor driver (L298N) at 7.8 Khz. Thereby, the motor driver will switch the output between VCC and GND. A resonator circuit amplifies the signal spikes as it's dimensioned so that its resonation frequency is the same as the switching frequency (7.8 Khz). That way, the motor drive only needs to be operated at 5V (instead of 12V). The power supply should be able to supply 2W (400mA at 5V). One part of the signal is captured by the Arduino (ADC) through a diode and a voltage divider. This allows to detect if the perimeter loop is connected or not. A 150 mA current will flow through in the perimeter wire (wire cross section 2-3 mm^2) - the wire should not be longer than 500m.
+
The images below explain why the polarity of the received coil signal changes between inside and outside of the perimeter wire. The image shows the direction of the electric flux lines sent out from the perimeter wire and how they hit the coil for both inside and outside position.  
  
<gallery>
+
For a better understanding of the perimeter filter, see the [http://www.grauonline.de/alexwww/ardumower/filter/filter.html Matched filter simulation]. For more details about the filter, also see the [https://www.youtube.com/watch?v=NIer_kITelc Matched filter video]. Using a simple symmetric signal (which looks equal on positive and negative side of the zero point), you cannot differentiate between an 'inside perimeter' and 'outside perimeter' signal. When the mower is traversing the perimeter loop, the signal polarity changes (positive becomes negative and negative becomes positive). We want to detect this polarity change of the signal. Using an unsymmetrical signal, you can do this. You can see the difference in the simulator. The default signal (slider 'example signal') is a symmetric signal - press the 'Invert' button to invert the signal (change its polarity). In the correlation result (graph 'Matched filter') the polarity can not be detected. Now use an asymmetrical signal ('pseudonoise5_pw'). Press again 'Invert' to change signal polarity. Now you can see polarity of the signal in the filter output (graph 'Matched filter'). It's the sign of the peak (positive or negative sign).
File: Arduino_perimeter_sender.png ‎
+
</gallery>
+
 
+
Because it's sometimes difficult to find a specific coil, here are possible combinations (coil / capacitor) you can use (all will have a resonation frequency of 7.8 Khz):
+
*Combination 1: Coil: 160µH, Capacitor: 3,3µF/50V  (tested)
+
*Combination 2: Coil 33mH, Capacitor: 12nF (not tested)
+
 
+
====Power supply====
+
It is recommended to use a voltage step-down converter (e.g. module using LM2596) to generate the 5V voltage. Before connecting, set the voltage of the converter to 5V.  
+
 
+
'''Warning''' : never connect more than 5V on the Arduino 5V pins, or you will damage the Arduino. Therefore, always measure the 5V voltage before connecting it to the Arduino 5V pin!
+
 
+
====Functional test====
+
1. After uploading the code and connecting the perimeter wire, the Arduino LED should be ON. Now remove the perimeter wire -  the Arduino LED should go OFF.
+
2. If that doesn't work: Using a voltmeter, measure once at Arduino pin D9 and once at motor driver output pin (OUT_1) against ground - both should have a DC voltage of 2.5 Volt.
+
3. If you have an oscilloscope, replace the perimeter wire by the oscilloscope. The measured signal look like below:
+
 
+
The output signal shows a higher amplitude (high spikes) as the input signal:
+
  
 
<gallery>
 
<gallery>
File: Perimetersignal.jpg|signal on the sender output
+
File: Ardumower_perimeter2.jpg| Inside/outside detection using polarity change
File: Ardumower_perimeter_sender_schematics.png|resonator circuit basic principle
+
File: Fluxdirections.png| Flux directions
File: Arduino_perimeter_sender_photo.jpg
+
File: Perimeter_signal_steps.png | Perimeter signal at sender and receiver coil
 +
File: Matched_filter_principle.png| Matched filter
 +
File: Perimeter_signal_good_bad.png|What makes a good/bad signal
 
</gallery>
 
</gallery>
  
For a simple receiver test, you can simply connect the receiver coil to an oscilloscope. The measured oscilloscope signal should look like below:
+
==Sender==
 +
[[Image:Ina169_marotronics.jpg|thumb|200px| Note for Marotronics INA169: Short pads for 5A operation]]
 +
[[File: Ardumower_perimeter_overview.jpg|600px]]
  
This signal can be detected easily with a coil:
+
We use a motor driver as output amplifier and an Arduino Nano to generate the signal. The motor driver is driven by 3.2 Khz (two pulse widths 4808 Hz and 2404 Hz). We use a motor driver with integrated current limiting and thermal switch-off (e.g. MC33926).
  
<gallery>
+
[[File:warning.png]] The perimeter wire length should be in the range 20m - 450m and must be at least 5 Ohm and not more than 12 Ohm. The maximum perimeter area is 1000 m2.  
File: Coilsignal.jpg|coil signal at receiver coil
+
File: Fft.jpg|signal in frequency spectrum, superposed by motor noise
+
File: Ardumower_perimeter_spectrum_plot.jpg| frequency spectrum via pfodApp
+
</gallery>
+
  
==Receiver==
+
MC33926 wiring: The perimeter wire is connected between MC33926 M1OUT1 and M1OUT2.
The receiver uses 2 coils mounted left and right in the robot. The signal strenght of left and right coils is evaluated to be able to compare them.
+
  
Principle:
+
* [https://www.marotronics.de/Perimeter-Sender-Board-Prototyp-mit-Platinen-Zubehoer sender PCB in the shop]
# Amplification of alternating signal using OPAMP
+
* [https://github.com/Ardumower/ardumower/blob/master/pcb/Produzierte_Platinen/sender_v2_geschlossen/Perimeter%20sender%20v2.pdf sender PCB schematics]
# Optional: Bandpass-filtering to filter-out noise caused by motors etc.
+
* [https://github.com/Ardumower/ardumower/tree/master/pcb/Produzierte_Platinen/sender_v2_geschlossen/Platinenbilder sender PCB pictures]
# Evaluation of signal strength of left and right coil
+
  
Advantage of this version: analog controlling works great.
+
===Sender software===
Disadvantage: You cannot detect, where you are (inside/outside) if your missed the perimter crossing. Also, you cannot detect if you drive clockwise or anti-clockwise on the perimeter wire.
+
<b>NOTE</b>: If you have never worked with Arduino before or if your Arduino Nano does not seem to respond, please read our <b>[http://wiki.ardumower.de/index.php?title=Arduino_first_steps 'Arduino first steps' introduction]</b>.
  
<gallery>
+
<b>Download</b>: You can find the sender code in the 'sender' folder of the [http://wiki.ardumower.de/index.php?title=Ardumower_PCB#Download_and_flash_Arduino_code Ardumower Download]
File: Arduino_perimeter_receiver.png
+
</gallery>
+
  
A coil receives the sender's signal. A resonator circuit (LC) amplifies the received signal at resonation frequency (7.8 kHz). Then the signal is amplified using an LM386 (here: Arduino sound sensor using coil instead of microphone). A bandpass-filter  (digital filter, FFT) on the Arduino filters the desired frequency (7.8 Khz) and outputs a PWM signal (pulse width is proportional to signal strength). A lowpass-filter converts it to a DC voltage.
+
[[File:warning.png]] Note: Always verify that the pin configuration in your Arduino code (sender.ino) matches your actual circuit!
Note: Wiring between Nano and Mega has been simplified - see schematics for exact wiring.
+
  
We have tested the following combinations of amplifier und coils:
 
  
'Arduino sound sensor'
+
===Sender power control===
<gallery>
+
[[File:warning.png]] The perimeter wire resistance (R) must be at least 5 Ohm and not more than 12 Ohm. Ideally, a 12 ohms (50W) power resistor is placed in series with the perimeter wire, so you get a total resistance of the perimeter wire at 12-15 ohms.
File: Soundsensor.jpg| Amplifying signal using LM386 - Arduino Sound Sensor using coil instead microphone
+
File: YwRobot_Sensor.jpg |Arduino Sound Sensor using LM386
+
File: YwRobot_circuit.png |Arduino Sound Sensor schematics
+
File: Coil_85mh.jpg|85 mH coils
+
</gallery>
+
  
LM386 amplifier
+
To change the power (current/voltage) of the sender, proceed like this:
<gallery>
+
File: Lm386_amplifier.jpg| LM386 amplifier (200x amplification)
+
File: Lm386_modified.jpg| LM386 amplifier modified
+
File: Lm386_circuit.png| LM386 circuit
+
File: Coil_small.jpg| 104 mH coil
+
</gallery>
+
  
Important: When using this amplifier, capacitor C3 should be bypassed (will give a VCC/2 offset required for Arduino) and the coil will be connected to "IN" and "GND".
+
The motor driver output voltage can be changed between 6.5-12V via the potentiometer on the DC/DC converter. Adjust the potentiometer so that not more than 1 Ampere current flows.
  
'''NOTE''': It's recommended to directly mount the coil on the amplifier module. This ensures the 'small signal' of the coil is not distorted by other components (motors etc.)
+
Example:  
 +
Your perimeter wire resistance (R): 12 Ohm
 +
Your adjusted voltage at the DC/DC converter: 8 Volt
  
===Functional test===
+
The consumed current and power is then:
# Make sure that the sender works correctly (see further above).
+
Current: I = U / R = 8 Volt / 12 Ohm => 0.7 Ampere
# Increase the Arduino Sound Sensor potentiometer to maximum (rotate counter-clock-wise).
+
Power:  P = U * I = 8 Volt * 0.7 Ampere => 5.6 Watt
# After uploading the code, move one coil towards the perimeter wire. The Arduino LED should start to blink. Now, hold both coils at same distance over the perimeter wire. The Arduino LED should be always ON now.
+
# If that doesn't work, open the serial console (19200 baud), and verify the signal values.
+
  
===Choice for coil===
+
Power resistor: If your perimeter wire resistance (R) is below 5 Ohms, you will not be able to further reduce voltage below 6.5v (otherwise the motor driver will not work properly). Then you have to increase the perimeter wire resistance (R) by using a power resistor in series with your perimeter wire. Important: your power resistor must be suitable for the power! In the example above usng a 12 Ohm power resistor, it should be a 10 Watt type.
Induction math, only approximation:
+
  
L = 1nH x n² x ((D² / mm² ) / (l / mm))
+
===Sender automatic standby===
l = coil length
+
The sender can be switched off during the time the robot is in the charging station. To detect the robot, a current sensor (INA169, 5A) is connected between the charger and the charging pins.
D = coil diameter
+
  
Example: An inductance of 85 mH, and diamter of 10 mm, and length of 40 mm require about  5830 windings.
+
===Sender diagnostics===
 
+
The perimeter sender status is indicated by the sender LED (Arduino Nano LED):
This inductance of 85 mH results in a capacity of 4.7 nF and a resonation frequency of 7963 Hz.
+
* ON: perimeter wire loop is closed and working
 
+
* OFF: perimeter wire loop is opened and not working
f0 = 1 / (2 * PI * sqrt(L * C)) = 1 / (2 * PI * sqrt(0.085 H * 0.0000000047 F)) =  7963 Hz
+
* blinking: robot is charging and perimeter will be switched OFF (energy saving)
  
Because it's sometimes difficult to find a specific coil, here are possible combinations (coil / capacitor) you can use (all will have a resonation frequency of 7.8 Khz):
+
To find errors (or to better understand the sender), open the serial console via Arduino IDE (CTRL+SHIFT+M) at 19200 baud. Now you can see the possible states (robot in charging station, robot outside charging station etc.):
Combination 1: Coil: 85mH, Capacitor: 4.7nF  (tested)
+
Combination 2: Coil 104mH, Capacitor: 4nF (tested)
+
  
===Arrangement of coils===
 
The coils are arranged at the bottom of the robot, about 90 degress to each other, both turned 45 degress.
 
 
<gallery>
 
<gallery>
File: Ardumower_spulen.jpg| Arrangement of coils
+
  File:Perimeter_sender_console.png | Perimeter sender console output
File: L50_coils.jpg |Example (Ambrogio L50)
+
File: L50_parcours.jpg |Test parcours
+
 
</gallery>
 
</gallery>
  
===Measurements of signal strength===
+
==Receiver==
To compare measurements, the signal strength has been determined at several distances. The signal strength (i.e. the calculated ADC value) is shown in the Android pfodApp. The distance (cm) is the length calculated from the perimeter loop until the coil (coil built-in the robot).
+
  
<gallery>
+
[[File:Perimeter_v2_receiver_circuit.png |400px]]
File: Perimeter_plot.png
+
</gallery>
+
  
===Layout of the wire===
+
For receiving the signal, we use a coil (100 mH or 150 mH) in upright position (centered at front in robot) connected to an LM386 operational amplifier (to amplify the received signal). When using the [https://www.marotronics.de/Schleifenempfaenger-Kit-perimeter-receiver-Kit LM386 module], capacitor C3 on the LM386 module should be bypassed (which is needed so that the LM386 generates a signal between 0..5V and not the default range -5V..+5V). The LM386 output pin should be connected to an analog Arduino pin ('pinPerimeterLeft').
  
It's important that the wire layout is round and does not have corners! Let's assume that the wire has a corner, and the robots drives exactly over the corner, it will not be able to detect the wire as both wire and coils are aligned.
+
<gallery>  
 
+
File: Ardumower_chassis_components.png | Perimeter coil position
<gallery>
+
File: Ardumower_coil_position.jpg | One centered, upright coil
File: Schleifen_blind.jpg  | Not recommened: robot cannot detect sharp edges!
+
  File: Ardumower_lm386_circuit.png | LM386 module schematics
File: Ardumower_coil_signal.png| How does the signal change when rotating the coil?
+
File: Dcdc_noise.jpg | NOTE: Keep away coil/pre-amplifier from DC/DC converters
 +
File: Tire_coil_distance.jpg | Tire-coil distance effecting rotation angle
 
</gallery>
 
</gallery>
  
===Videos===
 
#[http://www.youtube.com/watch?v=FGaUSg-uUxk Perimeter stop test]
 
#[http://www.youtube.com/watch?v=8R8QaffNlJw Perimeter tracking test]
 
#[http://www.youtube.com/watch?v=CftrnetFVYc&feature=youtu.be Finding and tracking test L50]
 
#[http://www.youtube.com/watch?feature=player_embedded&v=fjuQViS2rHM Finding and tracking test Rotenbach]
 
  
=Perimeter v2 (for SVN version, recommended)=
+
[https://www.marotronics.de/Schleifenempfaenger-Kit-perimeter-receiver-Kit You can get the receiver kit in the shop]
  
[[Image:Yt-brand-standard-logo-95x40.png|thumb|180px|https://www.youtube.com/watch?v=NIer_kITelc&feature=youtu.be]]
 
  
This is the new version of the perimeter sender and receiver (that can be purchased via the [https://www.marotronics.de/index.php?k=7 shop] [[File: shopping.png|link=https://www.marotronics.de/index.php?k=7]]).
+
'''NOTE''': It's recommended to directly mount the coil on the amplifier module. This ensures the 'small signal' of the coil is not distorted by other components (motors, DC/DC converters etc.).  
  
While crossing the perimeter loop, something interesting happens: the signal changes its polarity, that means negative and positive voltages reverse each other. By using this principle, crossing the perimeter wire as well as the current state (robot is inside/outside) can be detected. As with perimeter v1, we will again use a motor driver to amplify the signal and an operational amplifier to amplify the received signal. The perimeter sender outputs a digital code sequence (aka 'pseudo-noise' code), and the receiver will detect that code using a software-based digital [http://en.wikipedia.org/wiki/Matched_filter matched filter]. Depending on wheter the match result peak is positive or negative, the robot is inside or outside of the perimeter wire.
+
'''Note''': Leave out capacitor 4.7nF in latest software versions ('using differential signal').  
  
Principle:
 
# Generate output signal by Arduino Nano
 
# Amplify output signal by motor driver (MC33926), motor driver output connected to the perimeter wire (instead of a motor)
 
# Receive input signal with perimeter coil
 
# Amplify input signal with an operational amplifier (aka opamp - LM386)
 
# ADC sampling using Arduino Mega
 
# Signal filterung and signal detection using a digital filter (software-based matched filter algorithmn)
 
# Evaluation of matched filter output (for perimeter inside/ouside detection, tracking etc.)
 
 
The images below explain why the polarity of the received coil signal changes between inside and outside of the perimeter wire. The image shows the direction of the electric flux lines sent out from the perimeter wire and how they hit the coil for both inside and outside position.
 
  
 +
===Settings===
 
<gallery>
 
<gallery>
File: Ardumower_perimeter2.jpg| Inside/outside detection using polarity change
+
  File:Cheat_sheet.png | Perimeter settings
File: Fluxdirections.png| Flux directions
+
 
</gallery>
 
</gallery>
  
== Signal ==
+
At first, activate the perimeter in the Ardumower software (pfodApp->Options->Perimeter Use: YES). It is recommended to keep the default perimeter settings.
To receive the perimeter signal everywhere on the lawn, the key is to maximize signal-to-noise ratio (SNR). There are two approaches to maximize SNR:
+
# increase signal strength (power) or
+
# increase the signal length
+
  
We use a combination of both. The sender sends a repeating sequence of a digital code ('pseudonoise4_pw') at 9615 Hz :
+
The perimeter settings are:
  
1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1
+
* Timed-out if below smag (timedOutIfBelowSmag) - default setting: 300 | If smag below this value, sender is considered as off (perimeter timeout appears)
 +
* Timeout (s) if not inside  (timeOutSecIfNotInside) - default setting: 8
 +
* Trigger timeout (perimeterTriggerTimeout) - default setting: 0 | Perimeter outside trigger timeout when escaping from inside (ms)
 +
* Perimeter out roll time max (perimeterOutRollTimeMax) - default setting: 2000 | Max (random generator) roll time after perimeter out (ms)
 +
* Perimeter out roll time min (perimeterOutRollTimeMin) - default setting: 750 | Min (random generator) roll time after perimeter out (ms)
 +
* Perimeter out reverse time (perimeterOutRevTime) - default setting: 2200 | Time to drive reverse after perimeter out (ms)
 +
* Perimeter tracking roll time (perimeterTrackRollTime) - default setting: 1500 | Hit obstacle while tracking: roll time
 +
* Perimeter tracking reverse time (perimeterTrackRevTime) - default setting: 2200 | Hit obstacle while tracking: reverse time
 +
* Transition timeout (trackingPerimeterTransitionTimeOut) - default setting: 2000 | Max. time required for a in/out transition during tracking, robot will start rotating after this timeout
 +
* Track error timeout (trackingErrorTimeOut) - default setting: 10000 | Max. time required for a in/out transition during tracking, robot will go into error after this time
 +
* Track_P (perimeterPID.Kp) - default setting:51 | Perimeter PID "P" setting
 +
* Track_I (perimeterPID.Ki) - default setting:12.5 | Perimeter PID "I" setting 
 +
* Track_D (perimeterPID.Kd) - default setting:0.8 | Perimeter PID "D" setting
 +
* Use differential signal (useDifferentialPerimeterSignal) - default setting: YES | Use differential signal (see signal section)
 +
* Swap coil polarity (swapCoilPolarity) - default setting:NO
 +
* Block inner wheel  (trackingBlockInnerWheelWhilePerimeterStruggling) - default setting: YES | robot is wheel-spinning while tracking => roll to get ground again
  
'1' means signal a positive pulse, '-1' a negative pulse. Because the shortest signal change generated is '-1,1', the lowest generated 'tone' (if you would make this hearable) is 2404 Hz. The longest signal change generated is '1,1,-1,-1', and so the highest generated 'tone' is 4808 Hz.
+
===Coil/amplifier-to-motor distances===
 
+
Ensure all minimum distances to the following components:
The coil only sees 'changes' of the sender signal - so (without using a capacitor in series with the coil) the received signal would be:
+
* Coil to gear motor: > 15cm
 
+
* Coil to mower motor: > 10cm
1,0,-1, 0,1,-1,1,-1, 0,1,-1,1,0,-1, 0,1,-1, 0,1,-1, 0,1,0,-1
+
* Coil to DC/DC converter: > 10cm
 
+
However, using a capacitor in series with the coil, the received signal looks like the sender signal again.
+
 
+
The Arduino ADC samples the receiving signal at 9615 Hz.
+
 
+
==Filter==
+
The signal chosen has specific characteristic: it does not [http://en.wikipedia.org/wiki/Matched_filter correlate] in parts with itself - only as a whole sequence (because it looks 'random'). Because of this characteristic, the starts of the signal can be detected by a [http://en.wikipedia.org/wiki/Matched_filter matched filter] (aka 'correlation' with the search signal) and they generate a high peak in the matched filter result, even when high noise was added (due to motors etc.). The polarity of the peak (positive or negative) determines if the coil is inside or outside of the perimeter wire.
+
 
+
You can see how it works: For a better understanding of the perimeter signal and the filter, the matched filter is simulated here:  
+
[http://www.grauonline.de/alexwww/ardumower/filter/filter.html Matched filter simulation]
+
 
+
# Choose the perimeter signal at the right side (Set slider 'example signals': pseudonoise4_pw).
+
# Increase the noise a little bit (Set slider 'noise' to 2).
+
# At the left bottom plot ('Matched filter') you can see that the repeated signal was detected 3 times.
+
# Now simulate moving the coil outside of the perimeter wire. Click on 'Invert' to set amplifcation to '-1'. The matched filter results a negative match.
+
 
+
See also: [https://www.youtube.com/watch?v=NIer_kITelc Video about the matched filter]
+
  
 
<gallery>
 
<gallery>
  File: Matched_filter_principle.png| Matched filter
+
File: Dcdc_noise.jpg | NOTE: Keep away coil/pre-amplifier from DC/DC converters and motors!
  File: Perimeter_signal_good_bad.png|What makes a good/bad signal
+
 
</gallery>
 
</gallery>
  
==Sender==
+
===Signal measurements===
<gallery>
+
The sender / coil / LM386 amplifier outputs should look like this: (for more details about the signal, see section signal above)
File: Schleifensender_Ardumower_V2.JPG | Sender circuit
+
<gallery>
File: Perimeter_sender_box.jpg| Sender box (example)
+
File: Perimeter_signal_steps.png | Perimeter signal at sender, receiver coil, and LM386 (principle)
File: Perimeter2_sender_open.jpg| Sender signal (open perimeter)
+
File: coil_signal_without_capacitor.png | sender signal, coil signal (5V sender, 5 ohm loop - blue: perimeter, yellow: coil, gray: LM386 amplifier out)
File: Sender_v2_signal_sender_open_oszi.jpg| Sender signal (open perimeter)
+
File: Perimeter2_sender_open.jpg| Sender signal (6.5V, open perimeter)
File: Sender_v2_signal_oszi.jpg| Sender signal (closed perimeter)
+
File: Lm_output_dc_noise.jpg | LM386 output, with DC noise
 
</gallery>
 
</gallery>
 
We use a motor driver as output amplifier and an Arduino Nano to generate the signal. The motor driver is driven by 3.2 Khz (two pulse widths 4808 Hz and 2404 Hz). The circuit draws max. 20W (12V, 1.7A). We use a motor driver with integrated current limiting and thermal switch-off (e.g. MC33926). The perimeter wire length should be in the range 20m - 450m.
 
 
sender circuit:
 
 
<blockquote style="background-color: lightgrey; border: solid thin grey;">
 
<pre>
 
motor driver M1OUT1    o---------- perimeter loop (20-450 meters)--+
 
                                                                    |
 
motor driver M1OUT2    o---------- perimeter loop -----------------+
 
motor driver Vin        o-- 12V
 
motor driver M1IN1      o-- Arduino Nano pinIN1
 
motor driver M1IN2      o-- Arduino Nano pinIN2
 
motor driver M1PWM_nD2  o-- Arduino Nano pinPWM
 
motor driver M1nSF      o-- Arduino Nano pinFault
 
motor driver M1FB      o-- Arduino Nano pinFeedback
 
motor driver EN        o-- Arduino Nano pinEnable
 
motor driver VDD        o-- Arduino +5V
 
motor driver M1D1      o-- GND (via Jumper)
 
motor driver SLEW      o-- VDD (via Jumper)
 
 
              |---------o-- GND
 
Potentiometer 100k -----o-- Arduino Nano pinPot
 
              |---------o-- Arduino +5V
 
 
ACS712-05 OUT ------o-- Arduino Nano pinChargeCurrent   
 
ACS712-05 A  ------o-- charging pin (+)
 
ACS712-05 B  ------o-- battery charger +24V
 
battery charger GND-o-- charging pin (-)
 
</pre>
 
</blockquote>
 
 
'''Example of sender implementation on a dot matrix board:  [http://www.braunschweiger.org/content/download/SenderR212.pdf]
 
[http://www.braunschweiger.org/content/images/SenderR212_Front.jpg] [http://www.braunschweiger.org/content/images/SenderR212_Back.jpg]'''
 
 
===Sender current control===
 
To increase/decrease the current, the motor driver supply voltage can be changed (e.g. you could use 5V supply voltage for the motor driver instead of 12V). That's one way to do it.
 
 
Another way to control the current is to 'PWM' the generated signal which means the signal is switched on and off very quickly resulting in an effective current change. The duty cycle controls how long the on/off ratio is. Duty cycle 100% (duty=1.0 or dutyPWM=255) means no off-time, and duty cycle 50% (duty=0.5 or dutyPWM=127) means 50% off time, 50% on time.
 
 
So you have two ways to control the current. For a 50m perimeter wire, I would start with 5V and duty=100%. For my 120m perimeter, I'm using 12V and duty=100%. For my indoor 5m test perimeter wire, I'm using 5V and duty=3%. The duty can be set via the potentimeter connected to Arduino pin 'pinPot' shown above.
 
 
You can find the optimum current like this: First set IMAX pot to zero (0), and place robot in the center of the garden. Now, slowly increase IMAX pot, until 'sig' in the pfodApp plot ("Plot->Perimeter") increases (wait 10 seconds). Where 'sig' reaches its maximum, keep IMAX pot setting.
 
 
===Sender automatic standby===
 
The sender can be switched off during the time the robot is in the charging station. To detect the robot, a current sensor (ACS712) is connected between the charger and the charging pins.
 
 
===Sender software===
 
 
<b>NOTE</b>: If you have never worked with Arduino before, read our <b>[http://wiki.ardumower.de/index.php?title=Arduino_first_steps 'Arduino first steps' introduction]</b>.
 
 
[[File:warning.png]] Note: Always verify that the pin configuration in your Arduino code (sender.ino) matches your actual circuit!
 
 
In the sender.ino you have two options:
 
 
* Define if you have connected a potentiometer for current control:  #define USE_POT 1    (or 0)
 
* Define if you have connected a charging current sensor for automatic sender standby:  #define USE_CHG_CURRENT 1  (or 0)
 
 
===Sender diagnostics===
 
The perimeter sender status is indicated by the sender LED (Arduino Nano LED):
 
* ON: perimeter wire loop is closed and working
 
* OFF: perimeter wire loop is opened and not working
 
* blinking: robot is charging and perimeter will be switched OFF (energy saving)
 
 
===Test sender with your PC's sound card===
 
You can use your sound card to try out the sender with just a coil:
 
 
# Connect a coil (100 mH) to your sound card microphone/line input (max 1V)
 
# Launch the [http://www.grauonline.de/alexwww/ardumower/oscilloscope/oscilloscope.html web oscilloscope], and choose Filter 'Matched', Frequency '9615' Hz, Visualization Math 'MinMax'
 
# The output signal should reflect the distance to your perimeter loop - the polarity (negative/positive) should indicate the side of the loop (inside/outside)
 
 
Try to move the coil as close as possible to the perimeter loop (for both inside/outside case) (Keep in mind that this is without pre-amplifier, so the signal will be only valid close to the loop - the microphone input cannot be higher than 1V, so we cannot use the pre-amplifier here).
 
 
<gallery>
 
File:Ardumower_web_oscilloscope_time_signal_received.jpg | Actual received time signal (Filter Off, Time scale: x5)
 
File:Ardumower_web_oscilloscope_time_signal.jpg | Ideal time signal, generated by sender (Filter Off, Time scale: x5)
 
File:Ardumower_web_oscilloscope.jpg  | Matched filter signal (Frequency: 9615 Hz, Math: MinMax)
 
File:Perimeter_signal_good_bad.png | What makes a good/bad signal
 
</gallery>
 
 
[https://www.youtube.com/watch?v=vg5Xg0__66A Video explaining all steps]
 
 
==Receiver==
 
 
For receiving the signal, we use a coil (100 mH) in upright position (centered at front in robot), connected through a capacitor (4.7nF) to an LM386 operational amplifier (to amplify the received signal). When using the LM386 module, capacitor C3 on the LM386 module should be bypassed (which is needed so that the LM386 generates a signal between 0..5V and not the default range -5V..+5V). The LM386 output pin should be connected to an analog Arduino pin ('pinPerimeterLeft').
 
 
The signal output of LM386 should look like this. For more details, see section signal.
 
 
<gallery>
 
File: Perimeter_v2_receiver_circuit.jpg| Receiver circuit and shortened capacitor C3
 
File: Ardumower one center coil.jpg| One centered, upright coil
 
File: Perimeter2_receiver_coil.jpg| Receiver signal
 
File: Perimeter2_receiver_coil_pwm.jpg| Pulse modulated perimeter signal
 
</gallery>
 
 
receiver circuit:
 
 
<blockquote style="background-color: lightgrey; border: solid thin grey;">
 
<pre>
 
                                      LM386 IN  o------- capacitor 4.7nF ----------- coil 100 mH
 
Arduino pinPerimeterLeft  o------o  LM386 OUT
 
                                      LM386 GND o----------------------------------- coil
 
</pre>
 
</blockquote>
 
 
'''NOTE''': It's recommended to directly mount the coil on the amplifier module. This ensures the 'small signal' of the coil is not distorted by other components (motors etc.)
 
  
 
===Receiver ADC calibration===
 
===Receiver ADC calibration===
[[File:warning.png]] Note: Run the ADC calibration once ("pfodApp->ADC Calibration"), so that the received signal is symmetric around zero.
+
[[File:warning.png]] The ADC calibration ensures that the zero point (silence) is detected correctly, and so later the received signal is symmetric around zero.
 
+
# The perimeter sender and robot motors must be switched off during calibration!
* The perimeter transmitter must be switched off during calibration.
+
# If you cannot avoid that another sender is disturbing during calibration, remove the coil during calibration (connect LM386 input line to GND)
* If you cannot avoid that another sender is disturbing during calibration, remove the coil during calibration (connect LM386 input line to GND).
+
# Run the ADC calibration once ("pfodApp->ADC Calibration")
  
When calibrated correctly, the signal in the pfodApp plot ('sig') should be around zero (0) when the perimeter transmitter is switched off. When the perimeter transmitter is switched on, the plotted signal ('sig') should have the same maximum amplitude for both positive and negative axis (is 'symmetric around zero').
+
When calibrated correctly, the signal in the pfodApp plot ('sig') should be around zero (0) when the perimeter sender is switched off. When the perimeter sender is switched on, the plotted signal ('sig') should have the same maximum amplitude for both positive and negative axis (is 'symmetric around zero').
  
 
<gallery>
 
<gallery>
Zeile 348: Zeile 180:
 
</gallery>
 
</gallery>
  
===Receiver diagnostics===
+
===Receiver diagnostics/troubleshooting===
  
 
The receiver signal, filter result and signal quality can be monitored via Android phone (pfodApp->Plot->Perimeter):
 
The receiver signal, filter result and signal quality can be monitored via Android phone (pfodApp->Plot->Perimeter):
  
 
<gallery>
 
<gallery>
  File: PerimeterV2screenshot.png  
+
  File: Perimeter_snr.png | Signal-to-noise ratio (SNR)
 +
File: Perimeter_signal_38khz.png | signal, filter result, LP filter result, inside/outside, counter, on/off, quality
 +
File: Perimeter_plot_moving_from_inside_to_outside.png | Moving from inside to outside
 +
File: Perimeter_plot_signal_strength.png
 +
File: Perimeter_v2_plot_new.png
 
  File: Ardumower_perimeter2_test.jpg
 
  File: Ardumower_perimeter2_test.jpg
 
</gallery>
 
</gallery>
  
 
Plot signal description:
 
Plot signal description:
  sig:  coil signal (raw pulse sequence after ADC)
+
  sig:  coil signal (raw pulse sequence after ADC) - it's a short snapshot (32 samples), and it's taken every 20 seconds
 +
      (so you need to wait 20 seconds for the next snapshot)
 
  mag:  filter result: inside (negative) or outside (positive), magnitude: distance to perimeter wire/magnetic signal strength (RSSI)
 
  mag:  filter result: inside (negative) or outside (positive), magnitude: distance to perimeter wire/magnetic signal strength (RSSI)
 
       - this is used for <b>perimeter tracking</b>
 
       - this is used for <b>perimeter tracking</b>
 
  smag: filter result, low-pass filtered, without sign (smooth mag) - this is used for <b>'sender-off' detection</b>
 
  smag: filter result, low-pass filtered, without sign (smooth mag) - this is used for <b>'sender-off' detection</b>
 +
      The threshold can bet set via pfodApp (Settings->Perimeter->Timed-out if below smag)
 
  in:  binary result, low-pass filtered: inside (1) oder outside (0) - this is used for <b>perimeter boundary detection</b>
 
  in:  binary result, low-pass filtered: inside (1) oder outside (0) - this is used for <b>perimeter boundary detection</b>
 +
      If the robot is not inisde for a certain time, it will go into error. The threshold can bet set via pfodApp
 +
      (Settings->Perimeter->Timeout (s) if not inside)
 
  cnt:  number of "inside-outside" transitions (counter)
 
  cnt:  number of "inside-outside" transitions (counter)
  on:  perimeter sender active (1) or inactive (0), evaluation based on smag result
+
  on:  perimeter sender active, robot is inside and smag is high enough (1) or inactive/outside/smag too low (0)
  qty:  filter quality (how distinguisable inside and outside were in filter result)
+
  qty:  <b>signal quality</b> (how distinguisable inside and outside were in filter result
 +
      computes ratio:  match score with template signal / match score with inverse template signal             
 +
      1.0 means poor quality, you should get 1.5 or higher)
  
The 'mag' plot should be clear: Inside the perimeter loop, the signal should be a negative curve, outside it should be a positive curve. If your 'mag' curve is not clear, try to optimize:
+
The 'mag' plot should be clear (without spikes): Inside the perimeter loop, the signal should be a clear negative curve, outside it should be a clear positive curve. If your 'mag' curve is not clear (and has spikes), try to troubleshoot/optimize:
  
* Adjust sender potentiometer (IMAX): for longer perimeter (>80m) increase, for shorter perimeter (>25m) decrease IMAX
+
* Verify, your coil is connected correctly at 'pinPerimeterLeft' (you still may get a poor signal when connected at a wrong Arduino pin!)
* Minimize cable length between coil and LM386-amplifier (omit cables)
+
* Decrease the threshold for a smag timeout via 'pfodApp->Options->Perimeter->Timed-out if below smag'
* Increase distance between coil and mower motor
+
* Reverse coil if the in/out is inverted or reverse the perimeter wire
 +
* Minimize cable length between coil and LM386-pre-amplifier (directly mount coil onto pre-amplifier)
 +
* Increase distance between coil and mower motor/DC converter (move away coil 30cm or more from any motors or DC converters)
 +
* Add some magnetic shield (e.g. your battery) between coil and motors/DC converter
 +
 
 +
==Broken perimeter wire==
 +
Once in a while your perimeter wire may get broken, and your perimeter loop resistance will probably increase to a few Megaohms (MOhm). If that is the case, you can find the location of the break like this:
 +
 
 +
# Using a metal plate, plug one wire of the perimeter sender output into earth ground (the other wire of the sender output is still connected to the perimeter wire)
 +
# Optional: increase your sender output voltage to 20 Volts (NOTE: the MC33926 driver can NOT operate higher than 28v, and your sender Arduino Nano may not operate higher than 20v)
 +
# Method 1 (using two LM386 amplifiers and earphone): Connect 1st LM386 amplifier (NOTE: do NOT remove capacitor C3!) signal output to a 2nd LM386 input. Connect 2nd LM386 output to an earphone.
 +
# Method 2 (using one LM386 amplifier and a PC): Connect the LM386 amplifier (NOTE: do NOT remove capacitor C3!) signal output (signal and GND) to your PC's microphone input, launch the [http://www.grauonline.de/alexwww/ardumower/oscilloscope/oscilloscope.html web oscilloscope], and switch into frequency view (choose visualization 'frequency spectrum')
 +
# Turn on the perimeter sender - while traversing the perimeter wire, you will notice a peak frequency of 3.2 Khz in the Web oscilloscope
 +
# Now start at the side of the perimeter wire (the side that is still connected to the perimeter wire), and walk along the perimeter wire - the peak frequency of 3.2 Khz should always be there (and hearable)
 +
# At the location where the wire is broken, the 3.2 Khz frequency is gone (and no longer hearable)! [https://youtu.be/J6X_dktw4ZE Demonstration video]
 +
 
 +
<gallery>
 +
File: Peri_broken2.jpg | Plug one wire into ground (earth)
 +
File: Peri_broken4.jpg | Method 1: Connect 1st LM386 amplifier output to 2nd LM386 input, 2nd output to earphone
 +
File: Peri_broken1.jpg | Method 2: Connect LM386 amplifier output to your PC's microphone input
 +
File: Peri_broken3.jpg | Method 2: Launch the web oscilloscope, and set frequency view
 +
</gallery>
  
 
===Videos===
 
===Videos===
Zeile 377: Zeile 240:
 
#[https://www.youtube.com/watch?v=QCA6Dm3rs3M 120m perimeter wire test]
 
#[https://www.youtube.com/watch?v=QCA6Dm3rs3M 120m perimeter wire test]
 
#[https://www.youtube.com/watch?v=NIer_kITelc Perimeter wire and matched filter theory (German)]
 
#[https://www.youtube.com/watch?v=NIer_kITelc Perimeter wire and matched filter theory (German)]
 +
#[https://www.youtube.com/watch?v=VxJN2xb55dU&feature=youtu.be Sender PCB]
 +
#[http://www.youtube.com/watch?v=FGaUSg-uUxk Perimeter stop test]
 +
#[http://www.youtube.com/watch?v=8R8QaffNlJw Perimeter tracking test]
 +
#[http://www.youtube.com/watch?v=CftrnetFVYc&feature=youtu.be Finding and tracking test L50]
 +
#[http://www.youtube.com/watch?feature=player_embedded&v=fjuQViS2rHM Finding and tracking test Rotenbach]
 +
#[http://youtu.be/r4ZMgasMkH0 Magnetic field demonstration video]
  
 
=Tracking of perimeter=
 
=Tracking of perimeter=
Zeile 388: Zeile 257:
 
You can find more information about PID controllers here:  
 
You can find more information about PID controllers here:  
 
[http://www.ardumower.de/index.php/de/forum/anleitungen-hilfe/121-pid-regelung-fuer-drehzahl-drehung-etc-richtig-einstellen Forum].
 
[http://www.ardumower.de/index.php/de/forum/anleitungen-hilfe/121-pid-regelung-fuer-drehzahl-drehung-etc-richtig-einstellen Forum].
 
=Sensor fusion=
 
The perimeter magnetic field could be used as input for a [http://wiki.ardumower.de/index.php?title=Sensor_fusion robot position estimation].
 
  
 
=Further links=
 
=Further links=

Aktuelle Version vom 2. Juli 2016, 16:24 Uhr

Abstract

A perimeter wire (or buried wire fence, BWF) is like a 'virtual fence': it stopps the robot when it reaches its boundaries. A perimeter is not always necessary for all surroundings.

Principle idea: You will install a perimeter loop (a wire) in your garden through which a signal is sent and this signal is detected by the robot. So, you'll need: a sender (to transmit the on the wire) and a receiver (to detect the signal in the robot).

How is the signal detected? The signal is detected by one receiver coils. The closer the distance between coil and perimeter loop, the higher the signal strength. Also, something interesting happens when the robot crosses the perimeter loop: the signal changes its polarity, that means positive and negative voltages reverse each other.

Perimeter

This is the new version of the perimeter sender and receiver (that can be purchased via the shop Shopping.png).

The perimeter sender outputs a digital code sequence (a 'pseudo-noise' code), and the receiver will detect that code using a software-based digital matched filter. Depending on wheter the match result peak is positive or negative, the robot is inside or outside of the perimeter wire.

Sender principle:

  1. Sender PCB generates an output signal using an Arduino Nano (about 3 Khz)
  2. The generated signal is amplified using a motor driver (MC33926), the motor driver output is connected to the perimeter wire (instead of a motor)

Receiver principle:

  1. A coil receives the signal
  2. The signal is amplified using an operational amplifier (LM386)
  3. The Arduino Mega samples the signal using its analog-to-digital converter (ADC) at 9615 Hz
  4. The digital signal is filtered using a digital filter (matched filter algorithmn)
  5. The matched filter output is evaluated (for perimeter inside/ouside detection, tracking etc.)

The images below explain why the polarity of the received coil signal changes between inside and outside of the perimeter wire. The image shows the direction of the electric flux lines sent out from the perimeter wire and how they hit the coil for both inside and outside position.

For a better understanding of the perimeter filter, see the Matched filter simulation. For more details about the filter, also see the Matched filter video. Using a simple symmetric signal (which looks equal on positive and negative side of the zero point), you cannot differentiate between an 'inside perimeter' and 'outside perimeter' signal. When the mower is traversing the perimeter loop, the signal polarity changes (positive becomes negative and negative becomes positive). We want to detect this polarity change of the signal. Using an unsymmetrical signal, you can do this. You can see the difference in the simulator. The default signal (slider 'example signal') is a symmetric signal - press the 'Invert' button to invert the signal (change its polarity). In the correlation result (graph 'Matched filter') the polarity can not be detected. Now use an asymmetrical signal ('pseudonoise5_pw'). Press again 'Invert' to change signal polarity. Now you can see polarity of the signal in the filter output (graph 'Matched filter'). It's the sign of the peak (positive or negative sign).

Sender

Note for Marotronics INA169: Short pads for 5A operation

Ardumower perimeter overview.jpg

We use a motor driver as output amplifier and an Arduino Nano to generate the signal. The motor driver is driven by 3.2 Khz (two pulse widths 4808 Hz and 2404 Hz). We use a motor driver with integrated current limiting and thermal switch-off (e.g. MC33926).

Warning.png The perimeter wire length should be in the range 20m - 450m and must be at least 5 Ohm and not more than 12 Ohm. The maximum perimeter area is 1000 m2.

MC33926 wiring: The perimeter wire is connected between MC33926 M1OUT1 and M1OUT2.

Sender software

NOTE: If you have never worked with Arduino before or if your Arduino Nano does not seem to respond, please read our 'Arduino first steps' introduction.

Download: You can find the sender code in the 'sender' folder of the Ardumower Download

Warning.png Note: Always verify that the pin configuration in your Arduino code (sender.ino) matches your actual circuit!


Sender power control

Warning.png The perimeter wire resistance (R) must be at least 5 Ohm and not more than 12 Ohm. Ideally, a 12 ohms (50W) power resistor is placed in series with the perimeter wire, so you get a total resistance of the perimeter wire at 12-15 ohms.

To change the power (current/voltage) of the sender, proceed like this:

The motor driver output voltage can be changed between 6.5-12V via the potentiometer on the DC/DC converter. Adjust the potentiometer so that not more than 1 Ampere current flows.

Example:

Your perimeter wire resistance (R): 12 Ohm
Your adjusted voltage at the DC/DC converter: 8 Volt

The consumed current and power is then:

Current: I = U / R = 8 Volt / 12 Ohm => 0.7 Ampere
Power:  P = U * I = 8 Volt * 0.7 Ampere => 5.6 Watt

Power resistor: If your perimeter wire resistance (R) is below 5 Ohms, you will not be able to further reduce voltage below 6.5v (otherwise the motor driver will not work properly). Then you have to increase the perimeter wire resistance (R) by using a power resistor in series with your perimeter wire. Important: your power resistor must be suitable for the power! In the example above usng a 12 Ohm power resistor, it should be a 10 Watt type.

Sender automatic standby

The sender can be switched off during the time the robot is in the charging station. To detect the robot, a current sensor (INA169, 5A) is connected between the charger and the charging pins.

Sender diagnostics

The perimeter sender status is indicated by the sender LED (Arduino Nano LED):

  • ON: perimeter wire loop is closed and working
  • OFF: perimeter wire loop is opened and not working
  • blinking: robot is charging and perimeter will be switched OFF (energy saving)

To find errors (or to better understand the sender), open the serial console via Arduino IDE (CTRL+SHIFT+M) at 19200 baud. Now you can see the possible states (robot in charging station, robot outside charging station etc.):

Receiver

Perimeter v2 receiver circuit.png

For receiving the signal, we use a coil (100 mH or 150 mH) in upright position (centered at front in robot) connected to an LM386 operational amplifier (to amplify the received signal). When using the LM386 module, capacitor C3 on the LM386 module should be bypassed (which is needed so that the LM386 generates a signal between 0..5V and not the default range -5V..+5V). The LM386 output pin should be connected to an analog Arduino pin ('pinPerimeterLeft').


You can get the receiver kit in the shop


NOTE: It's recommended to directly mount the coil on the amplifier module. This ensures the 'small signal' of the coil is not distorted by other components (motors, DC/DC converters etc.).

Note: Leave out capacitor 4.7nF in latest software versions ('using differential signal').


Settings

At first, activate the perimeter in the Ardumower software (pfodApp->Options->Perimeter Use: YES). It is recommended to keep the default perimeter settings.

The perimeter settings are:

  • Timed-out if below smag (timedOutIfBelowSmag) - default setting: 300 | If smag below this value, sender is considered as off (perimeter timeout appears)
  • Timeout (s) if not inside (timeOutSecIfNotInside) - default setting: 8
  • Trigger timeout (perimeterTriggerTimeout) - default setting: 0 | Perimeter outside trigger timeout when escaping from inside (ms)
  • Perimeter out roll time max (perimeterOutRollTimeMax) - default setting: 2000 | Max (random generator) roll time after perimeter out (ms)
  • Perimeter out roll time min (perimeterOutRollTimeMin) - default setting: 750 | Min (random generator) roll time after perimeter out (ms)
  • Perimeter out reverse time (perimeterOutRevTime) - default setting: 2200 | Time to drive reverse after perimeter out (ms)
  • Perimeter tracking roll time (perimeterTrackRollTime) - default setting: 1500 | Hit obstacle while tracking: roll time
  • Perimeter tracking reverse time (perimeterTrackRevTime) - default setting: 2200 | Hit obstacle while tracking: reverse time
  • Transition timeout (trackingPerimeterTransitionTimeOut) - default setting: 2000 | Max. time required for a in/out transition during tracking, robot will start rotating after this timeout
  • Track error timeout (trackingErrorTimeOut) - default setting: 10000 | Max. time required for a in/out transition during tracking, robot will go into error after this time
  • Track_P (perimeterPID.Kp) - default setting:51 | Perimeter PID "P" setting
  • Track_I (perimeterPID.Ki) - default setting:12.5 | Perimeter PID "I" setting
  • Track_D (perimeterPID.Kd) - default setting:0.8 | Perimeter PID "D" setting
  • Use differential signal (useDifferentialPerimeterSignal) - default setting: YES | Use differential signal (see signal section)
  • Swap coil polarity (swapCoilPolarity) - default setting:NO
  • Block inner wheel (trackingBlockInnerWheelWhilePerimeterStruggling) - default setting: YES | robot is wheel-spinning while tracking => roll to get ground again

Coil/amplifier-to-motor distances

Ensure all minimum distances to the following components:

* Coil to gear motor: > 15cm
* Coil to mower motor: > 10cm 
* Coil to DC/DC converter: > 10cm

Signal measurements

The sender / coil / LM386 amplifier outputs should look like this: (for more details about the signal, see section signal above)

Receiver ADC calibration

Warning.png The ADC calibration ensures that the zero point (silence) is detected correctly, and so later the received signal is symmetric around zero.

  1. The perimeter sender and robot motors must be switched off during calibration!
  2. If you cannot avoid that another sender is disturbing during calibration, remove the coil during calibration (connect LM386 input line to GND)
  3. Run the ADC calibration once ("pfodApp->ADC Calibration")

When calibrated correctly, the signal in the pfodApp plot ('sig') should be around zero (0) when the perimeter sender is switched off. When the perimeter sender is switched on, the plotted signal ('sig') should have the same maximum amplitude for both positive and negative axis (is 'symmetric around zero').

Receiver diagnostics/troubleshooting

The receiver signal, filter result and signal quality can be monitored via Android phone (pfodApp->Plot->Perimeter):

Plot signal description:

sig:  coil signal (raw pulse sequence after ADC) - it's a short snapshot (32 samples), and it's taken every 20 seconds 
      (so you need to wait 20 seconds for the next snapshot)
mag:  filter result: inside (negative) or outside (positive), magnitude: distance to perimeter wire/magnetic signal strength (RSSI)
      - this is used for perimeter tracking
smag: filter result, low-pass filtered, without sign (smooth mag) - this is used for 'sender-off' detection
      The threshold can bet set via pfodApp (Settings->Perimeter->Timed-out if below smag)
in:   binary result, low-pass filtered: inside (1) oder outside (0) - this is used for perimeter boundary detection
      If the robot is not inisde for a certain time, it will go into error. The threshold can bet set via pfodApp
      (Settings->Perimeter->Timeout (s) if not inside)
cnt:  number of "inside-outside" transitions (counter)
on:   perimeter sender active, robot is inside and smag is high enough (1) or inactive/outside/smag too low (0)
qty:  signal quality (how distinguisable inside and outside were in filter result
      computes ratio:  match score with template signal / match score with inverse template signal              
      1.0 means poor quality, you should get 1.5 or higher)

The 'mag' plot should be clear (without spikes): Inside the perimeter loop, the signal should be a clear negative curve, outside it should be a clear positive curve. If your 'mag' curve is not clear (and has spikes), try to troubleshoot/optimize:

  • Verify, your coil is connected correctly at 'pinPerimeterLeft' (you still may get a poor signal when connected at a wrong Arduino pin!)
  • Decrease the threshold for a smag timeout via 'pfodApp->Options->Perimeter->Timed-out if below smag'
  • Reverse coil if the in/out is inverted or reverse the perimeter wire
  • Minimize cable length between coil and LM386-pre-amplifier (directly mount coil onto pre-amplifier)
  • Increase distance between coil and mower motor/DC converter (move away coil 30cm or more from any motors or DC converters)
  • Add some magnetic shield (e.g. your battery) between coil and motors/DC converter

Broken perimeter wire

Once in a while your perimeter wire may get broken, and your perimeter loop resistance will probably increase to a few Megaohms (MOhm). If that is the case, you can find the location of the break like this:

  1. Using a metal plate, plug one wire of the perimeter sender output into earth ground (the other wire of the sender output is still connected to the perimeter wire)
  2. Optional: increase your sender output voltage to 20 Volts (NOTE: the MC33926 driver can NOT operate higher than 28v, and your sender Arduino Nano may not operate higher than 20v)
  3. Method 1 (using two LM386 amplifiers and earphone): Connect 1st LM386 amplifier (NOTE: do NOT remove capacitor C3!) signal output to a 2nd LM386 input. Connect 2nd LM386 output to an earphone.
  4. Method 2 (using one LM386 amplifier and a PC): Connect the LM386 amplifier (NOTE: do NOT remove capacitor C3!) signal output (signal and GND) to your PC's microphone input, launch the web oscilloscope, and switch into frequency view (choose visualization 'frequency spectrum')
  5. Turn on the perimeter sender - while traversing the perimeter wire, you will notice a peak frequency of 3.2 Khz in the Web oscilloscope
  6. Now start at the side of the perimeter wire (the side that is still connected to the perimeter wire), and walk along the perimeter wire - the peak frequency of 3.2 Khz should always be there (and hearable)
  7. At the location where the wire is broken, the 3.2 Khz frequency is gone (and no longer hearable)! Demonstration video

Videos

  1. Perimeter2 demo
  2. 120m perimeter wire test
  3. Perimeter wire and matched filter theory (German)
  4. Sender PCB
  5. Perimeter stop test
  6. Perimeter tracking test
  7. Finding and tracking test L50
  8. Finding and tracking test Rotenbach
  9. Magnetic field demonstration video

Tracking of perimeter

The tracking of the perimeter wire is performed using a (software) digital PID controller. The controller's parameters (P,I,D) can be configured via the phone (pfodApp).

You can find more information about PID controllers here: Forum.

Further links

  1. Another idea for navigation are infrared landmarks
  2. More details about the matched filter
  3. Sound card oscilloscope including matched filter