Difference between revisions of "iMX6 OpenRex EMC testing"

From Voipac Wiki
Jump to navigation Jump to search
 
(6 intermediate revisions by the same user not shown)
Line 5: Line 5:
 
Electromagnetic compatibility results for iMX6 OpenRex SBC are shown on this page. Test setup and scripts are described in details.<br /><br />
 
Electromagnetic compatibility results for iMX6 OpenRex SBC are shown on this page. Test setup and scripts are described in details.<br /><br />
  
These measurement were performed with boards using the actual hardware and software configuration of the web shop SBCs.
+
These measurements were performed with the standard webshop configurations of the SBC, using actual hardware and software.
  
 
== Connected cables/devices ==
 
== Connected cables/devices ==
* '''Power jack:''' [https://www.voipac.com/#iMX6-PSA-00000000 +5V power supply] which is included in iMX6 OpenRex SBC kit
+
* '''Power jack:''' [https://www.voipac.com/power-supply-5v-20w +5V power supply] which is among recommended accessories for iMX6 OpenRex SBC
 
* '''SD card (Sandisk):''' preloaded with filesystem, used for booting and for read/write test
 
* '''SD card (Sandisk):''' preloaded with filesystem, used for booting and for read/write test
 
* '''Ethernet:''' 1 meter CAT Ethernet [https://kb.juniper.net/InfoCenter/index?page=content&id=KB22174 loopback cable] connected. Forced to 100Mb and used for ping test
 
* '''Ethernet:''' 1 meter CAT Ethernet [https://kb.juniper.net/InfoCenter/index?page=content&id=KB22174 loopback cable] connected. Forced to 100Mb and used for ping test
Line 15: Line 15:
 
* '''USB micro to USB adapter:''' USB micro connector is set as a host and used during USB memory read/write test
 
* '''USB micro to USB adapter:''' USB micro connector is set as a host and used during USB memory read/write test
 
* '''Wifi PCIE mini card:''' inserted, but not actively used. No antennas connected
 
* '''Wifi PCIE mini card:''' inserted, but not actively used. No antennas connected
* '''Debug cable:''' [https://www.voipac.com/#iMX6-TTL-00000000 FTDI TTL-3V3 UART to USB cable], used only to setup the board, not used and not plugged in during the measurements<br />
+
* '''Debug cable:''' [https://www.voipac.com/ttl-232r-3v3-cable FTDI TTL-3V3 UART to USB cable], used only to setup the board, not used and not plugged in during the measurements<br />
 
* '''Headphones and microphone:''' [https://www.amazon.co.uk/Genius-HS-M04SU-Luxury-Cancelling-Headset/dp/B00O4FOE2W headphones with microphone] connected to the 4-pole audio jack
 
* '''Headphones and microphone:''' [https://www.amazon.co.uk/Genius-HS-M04SU-Luxury-Cancelling-Headset/dp/B00O4FOE2W headphones with microphone] connected to the 4-pole audio jack
 
<br />
 
<br />
Line 37: Line 37:
  
 
=== Graph description ===
 
=== Graph description ===
==== Lower band 30kHz - 1GHz ====
+
==== Lower band 30MHz - 1GHz ====
 
Radiated emission is measured and displayed as quasi-peak values. This relation is represented as a blue curve in the measurements. Class B limits are shown by red highlighted line '''22F3M_B'''.
 
Radiated emission is measured and displayed as quasi-peak values. This relation is represented as a blue curve in the measurements. Class B limits are shown by red highlighted line '''22F3M_B'''.
  
 
==== Higher band 1GHz - 4GHz ====
 
==== Higher band 1GHz - 4GHz ====
Two plots displaying the power density are used to show results in higher bands. Similar to lower frequencies a blue curve represents quasi-peak values. Class B limits applied for quasi-peak measurements is plotted as the higher placed red line '''22F_P_B'''.<br />
+
Two plots displaying the power density are used to show results in higher bands. Similar to lower frequencies a blue curve represents quasi-peak values. Class B limits applied for quasi-peak measurements are plotted as the higher placed red line '''22F_P_B'''.<br />
 
Black curve depicts average-power values. Threshold for average-power measurement is shown with the lower placed limit line called '''22F_AV_B'''.
 
Black curve depicts average-power values. Threshold for average-power measurement is shown with the lower placed limit line called '''22F_AV_B'''.
  
=== iMX6 OpenRex SBC Max - PASS ===
+
=== iMX6 OpenRex SBC Max PASS ===
 
Test description:
 
Test description:
 
* stressapptest for CPU and memory
 
* stressapptest for CPU and memory
Line 55: Line 55:
  
 
{|style="text-align:center;"
 
{|style="text-align:center;"
| style="width: 47%;" |'''Vertical polarization'''
+
| style="width: 47%;" |'''Vertical polarisation'''
 
| style="width: 6%;" |<br />
 
| style="width: 6%;" |<br />
| style="width: 47%;" |'''Horizontal polarization'''
+
| style="width: 47%;" |'''Horizontal polarisation'''
 
|-
 
|-
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_30kHz-1GHz_Ver_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_30MHz-1GHz_Ver_pol.png|370px]]<br /><br />
 
|<br />
 
|<br />
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_30kHz-1GHz_Hor_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_30MHz-1GHz_Hor_pol.png|370px]]<br /><br />
 
|-
 
|-
|colspan="3"|iMX6 OpenRex SBC Max: 30kHz - 1GHz
+
|colspan="3"|iMX6 OpenRex SBC Max: 30MHz - 1GHz
 
|}
 
|}
 
<br />
 
<br />
 
{|style="text-align:center;"
 
{|style="text-align:center;"
| style="width: 47%;" |'''Vertical polarization'''
+
| style="width: 47%;" |'''Vertical polarisation'''
 
| style="width: 6%;" |<br />
 
| style="width: 6%;" |<br />
| style="width: 47%;" |'''Horizontal polarization'''
+
| style="width: 47%;" |'''Horizontal polarisation'''
 
|-
 
|-
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_1GHz-4GHz_Ver_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_1GHz-4GHz_Ver_pol.png|370px]]<br /><br />
 
|<br />
 
|<br />
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_1GHz-4GHz_Hor_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Max-EMC-RE_1GHz-4GHz_Hor_pol.png|370px]]<br /><br />
 
|-
 
|-
 
|colspan="3"|iMX6 OpenRex SBC Max: 1GHz - 4GHz
 
|colspan="3"|iMX6 OpenRex SBC Max: 1GHz - 4GHz
 
|}
 
|}
  
=== iMX6 OpenRex SBC Basic - PASS ===
+
=== iMX6 OpenRex SBC Basic PASS ===
 
Test description:
 
Test description:
 
* stressapptest for CPU and memory
 
* stressapptest for CPU and memory
Line 89: Line 89:
  
 
{|style="text-align:center;"
 
{|style="text-align:center;"
| style="width: 47%;" |'''Vertical polarization'''
+
| style="width: 47%;" |'''Vertical polarisation'''
 
| style="width: 6%;" |<br />
 
| style="width: 6%;" |<br />
| style="width: 47%;" |'''Horizontal polarization'''
+
| style="width: 47%;" |'''Horizontal polarisation'''
 
|-
 
|-
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_30kHz-1GHz_Ver_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_30MHz-1GHz_Ver_pol.png|370px]]<br /><br />
 
|<br />
 
|<br />
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_30kHz-1GHz_Hor_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_30MHz-1GHz_Hor_pol.png|370px]]<br /><br />
 
|-
 
|-
|colspan="3"|iMX6 OpenRex SBC Basic: 30kHz - 1GHz
+
|colspan="3"|iMX6 OpenRex SBC Basic: 30MHz - 1GHz
 
|}
 
|}
 
<br />
 
<br />
 
{|style="text-align:center;"
 
{|style="text-align:center;"
| style="width: 47%;" |'''Vertical polarization'''
+
| style="width: 47%;" |'''Vertical polarisation'''
 
| style="width: 6%;" |<br />
 
| style="width: 6%;" |<br />
| style="width: 47%;" |'''Horizontal polarization'''
+
| style="width: 47%;" |'''Horizontal polarisation'''
 
|-
 
|-
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_1GHz-4GHz_Ver_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_1GHz-4GHz_Ver_pol.png|370px]]<br /><br />
 
|<br />
 
|<br />
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_1GHz-4GHz_Hor_pol.jpg|370px]]<br /><br />
+
|style="width:396px; border:1px solid black;" |<br />[[image:iMX6_OpenRex_SBC_Basic-EMC-RE_1GHz-4GHz_Hor_pol.png|370px]]<br /><br />
 
|-
 
|-
 
|colspan="3"|iMX6 OpenRex SBC Basic: 1GHz - 4GHz
 
|colspan="3"|iMX6 OpenRex SBC Basic: 1GHz - 4GHz
Line 130: Line 130:
 
=== Starting DHCP server ===
 
=== Starting DHCP server ===
 
The boards were mainly operated through SSH sessions. Thus it is very useful to have the same IP address all the time. The easiest way to do so is to run DHCP server on the controlling computer. To allow boards using the same address enable persistent leases with a long duration (2880 min used below):<br />
 
The boards were mainly operated through SSH sessions. Thus it is very useful to have the same IP address all the time. The easiest way to do so is to run DHCP server on the controlling computer. To allow boards using the same address enable persistent leases with a long duration (2880 min used below):<br />
[[image:iMX6_TinyRex_Development_kit-Env_chamber-DHCP_settings.jpg|400px]]
+
[[image:iMX6_OpenRex_SBC-Environmental_chamber-DHCP_setting.png|360px]]
  
 
=== Preserving SSH session ===
 
=== Preserving SSH session ===
To minimize the possiblity of results being affected, the control computer was disconnected and taken outside of the test chamber (after the board was setup).<br /><br />
+
To minimise the possibility of results being affected, the control computer was disconnected and taken outside of the test chamber (after the board was setup).<br /><br />
  
 
When Ethernet cable connected to a board is unplugged, Linux terminates all the processes started within SSH sessions by default. [https://www.gnu.org/software/screen/manual/screen.html ''Screen''] command allows to keep these sessions running. This command allow tasks to continue even if the cable is disconnected (and Ethernet loopback is plugged right away). It is important to make sure the filesystem includes this command:
 
When Ethernet cable connected to a board is unplugged, Linux terminates all the processes started within SSH sessions by default. [https://www.gnu.org/software/screen/manual/screen.html ''Screen''] command allows to keep these sessions running. This command allow tasks to continue even if the cable is disconnected (and Ethernet loopback is plugged right away). It is important to make sure the filesystem includes this command:

Latest revision as of 14:37, 6 April 2023

Electromagnetic compatibility results for iMX6 OpenRex SBC are shown on this page. Test setup and scripts are described in details.

These measurements were performed with the standard webshop configurations of the SBC, using actual hardware and software.

Connected cables/devices

  • Power jack: +5V power supply which is among recommended accessories for iMX6 OpenRex SBC
  • SD card (Sandisk): preloaded with filesystem, used for booting and for read/write test
  • Ethernet: 1 meter CAT Ethernet loopback cable connected. Forced to 100Mb and used for ping test
  • HDMI monitor: connected through 1.8m HDMI cable, monitor plugged into power but turned off.
  • 2x USB flash drive: each connected through a 2m extension cable. Both used during read/write test
  • USB micro to USB adapter: USB micro connector is set as a host and used during USB memory read/write test
  • Wifi PCIE mini card: inserted, but not actively used. No antennas connected
  • Debug cable: FTDI TTL-3V3 UART to USB cable, used only to setup the board, not used and not plugged in during the measurements
  • Headphones and microphone: headphones with microphone connected to the 4-pole audio jack


iMX6 OpenRex SBC-EMC-Board with antenna.jpg

Test description

The main purpose of testing was to measure Radiated emission of iMX6 OpenRex SBC performing under heavy load. Following threads were running during the measurements:

  • CPU stress test
  • Memory stress test
  • Playing a video file
  • Playing an audio file
  • SD card test (read & write)
  • 2x USB test (USB memory drive read & write stress test)
  • Microcontroller running LED blinking program
  • Ethernet ping (and Ethernet SSH session)


iMX6 OpenRex SBC-EMC setup.jpg

Results

All the results were measured in compliance with the emission limits for FCC Class B (EMC standard EN 55022B). The board without any enclosure passed these limits. Class B devices are suitable for both residential and industrial applications as the norm standards use more restrictive limits.

Graph description

Lower band 30MHz - 1GHz

Radiated emission is measured and displayed as quasi-peak values. This relation is represented as a blue curve in the measurements. Class B limits are shown by red highlighted line 22F3M_B.

Higher band 1GHz - 4GHz

Two plots displaying the power density are used to show results in higher bands. Similar to lower frequencies a blue curve represents quasi-peak values. Class B limits applied for quasi-peak measurements are plotted as the higher placed red line 22F_P_B.
Black curve depicts average-power values. Threshold for average-power measurement is shown with the lower placed limit line called 22F_AV_B.

iMX6 OpenRex SBC Max – PASS

Test description:

  • stressapptest for CPU and memory
  • Ethernet loopback
  • running heavy testing script for USB and SD card read/write test
  • HDMI output tested with 720p video stream
  • audio output
  • Ethernet SSH session


Vertical polarisation
Horizontal polarisation

iMX6 OpenRex SBC Max-EMC-RE 30MHz-1GHz Ver pol.png



iMX6 OpenRex SBC Max-EMC-RE 30MHz-1GHz Hor pol.png

iMX6 OpenRex SBC Max: 30MHz - 1GHz


Vertical polarisation
Horizontal polarisation

iMX6 OpenRex SBC Max-EMC-RE 1GHz-4GHz Ver pol.png



iMX6 OpenRex SBC Max-EMC-RE 1GHz-4GHz Hor pol.png

iMX6 OpenRex SBC Max: 1GHz - 4GHz

iMX6 OpenRex SBC Basic – PASS

Test description:

  • stressapptest for CPU and memory
  • Ethernet loopback
  • running heavy testing script for USB and SD card read/write test
  • HDMI output tested with 720p video stream
  • audio output
  • Ethernet SSH session


Vertical polarisation
Horizontal polarisation

iMX6 OpenRex SBC Basic-EMC-RE 30MHz-1GHz Ver pol.png



iMX6 OpenRex SBC Basic-EMC-RE 30MHz-1GHz Hor pol.png

iMX6 OpenRex SBC Basic: 30MHz - 1GHz


Vertical polarisation
Horizontal polarisation

iMX6 OpenRex SBC Basic-EMC-RE 1GHz-4GHz Ver pol.png



iMX6 OpenRex SBC Basic-EMC-RE 1GHz-4GHz Hor pol.png

iMX6 OpenRex SBC Basic: 1GHz - 4GHz

Preparing the test

Boot device and software

All the boards were using bootloader stored in SPI flash memory with the rest of firmware located on SD card. U-Boot settings were not adjusted as the default configuration was used. The only change compared to standard software package was running a multimedia filesystem. To prepare a fresh SD card follow these instructions. Here is an example of creating a SD card suitable for Max configuration:

mkdir -pv ~/workdir/imx6/rootfs/yocto
cd ~/workdir/imx6/rootfs/yocto
wget http://downloads.voipac.com/files/iMX6_OpenRex_SBC/software/yocto/binaries/fsl-image-gui-imx6-openrexmax-2.4.sdcard.gz
gunzip -c fsl-image-gui-imx6-openrexmax-2.4.sdcard.gz | sudo dd of=/dev/mmcblk0 conv=sync bs=64K

Downloading stress test

Stressapptest package was selected to create a high CPU and memory load. Placing this file into the same directory where the testing script will be stored is important:

wget http://downloads.voipac.com/files/iMX6_OpenRex_SBC/documents/EMC_radiated_emission/stressapptest

Starting DHCP server

The boards were mainly operated through SSH sessions. Thus it is very useful to have the same IP address all the time. The easiest way to do so is to run DHCP server on the controlling computer. To allow boards using the same address enable persistent leases with a long duration (2880 min used below):
iMX6 OpenRex SBC-Environmental chamber-DHCP setting.png

Preserving SSH session

To minimise the possibility of results being affected, the control computer was disconnected and taken outside of the test chamber (after the board was setup).

When Ethernet cable connected to a board is unplugged, Linux terminates all the processes started within SSH sessions by default. Screen command allows to keep these sessions running. This command allow tasks to continue even if the cable is disconnected (and Ethernet loopback is plugged right away). It is important to make sure the filesystem includes this command:

sudo apt-get install screen

Programming microcontroller

MCU needs to be flashed before test can start. It is advised to do this in the preparation stage in the lab. Follow these steps to program microcontroller with a blinking example.

Copying files needed for testing

cd /media
wget http://downloads.voipac.com/files/iMX6_OpenRex_SBC/documents/EMC_radiated_emission/blackbird.wav
cp blackbird.wav blackbird2.wav
wget http://downloads.voipac.com/files/iMX6_OpenRex_SBC/documents/EMC_radiated_emission/openrex-emc-test.sh

Running the script

Plug the board into mains and connect to it via SSH session. Screen environment is opened:

screen -S openrex

Testing scripts command consists of following arguments

  • the first parameter - version of tested board (-max or -basic)
  • the second parameter - USB drive 1 location
  • the third parameter - USB drive 2 location
  • the fourth parameter - SD card location


Running the test:

  • iMX6 OpenRex SBC Max:
./openrex-emc-test.sh -max sda1 sdb1 mmcblk1p2 | tee -i orx-emc-testing.log
  • iMX6 OpenRex SBC Basic:
./openrex-emc-test.sh -basic sda1 sdb1 mmcblk1p2 | tee -i orx-emc-testing.log


Pressing Ctrl+A followed by Ctrl+D terminates screen session. Disconnect Ethernet cable and plug loopback cable instead. Radiated emissions can be measured now.

After the measurement is done screen terminal can be invoked by connecting it to the PC and using:

screen -rS openrex


The complete script can be found in the download section or down below:

#!/bin/sh
 
# OpenRex EMC  testing script

mountDevice() {
  mount /dev/$1 /media/$2
  cat /etc/mtab | grep -F "/dev/$1 /media/$2"
  if [ "$?" -eq "0" ]; then
    echo "$2 mounted"
  else
    echo "$2 not mounted"; exit 2
  fi
}
# prepare files
cd /home/ubuntu/
mkdir -p openrex/
cd openrex/
mkdir -p emc-testing/
cd emc-testing/
touch orx-emc-testing.log
 
echo '\033[9;0]' > /dev/tty1 # disable blanking the display
 
imx6solo=0
imx6quad=0
imx6quad_sata_cp=0
imx6quad_sata_stress=0
case $1 in
  -basic)  imx6solo=1 ;;
  -max)  imx6quad=1 ;;
  -max_sata_cp) imx6quad_sata_cp=1 ;;
  -max_sata_stress) imx6quad_sata_stress=1 ;;
  *)
esac
 
# mount devices
mountDevice $2 usb0
mountDevice $3 usb1
mountDevice $4 mmc0
if [ "${imx6quad_sata_cp}" -eq "1" ] || [ "${imx6quad_sata_stress}" -eq "1" ]; then
  mountDevice $5 sata
fi
 
updateLogFiles() {
  currentTime=`date +%Y-%m-%d.%H_%M`
  mv orx-emc-testing.log orx-emc-testing.log.$currentTime
}
 
finish_test_now() {
  echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) Ctrl+C Detected: End of the test"
  precced=0;
  #kill -INT $vid_pid $str_pid $ping_pid $aud_pid;
  sleep 3;
  test_status=`cat orx-emc-testing.log | grep -i "error" | grep -v -e "0 errors" -e "no corrected errors"`
  if [ -z "$test_status" ]
  then
  echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) PASS - Script ended without detected errors."
  else
  cat orx-emc-testing.log | grep -i "error" | grep -v -e "0 errors" -e "no corrected errors" -e "List of detected errors:"
  fi
  updateLogFiles
  exit;
}
 
# kill all processes if Ctrl+C is detected
trap finish_test_now 2
 
# connect ethernet loopback and force the ethernet to 100Mbit
mii-tool -F 100baseTx-HD
 
# stressapptest - one thread CPU, one thread memory
if [ "${imx6solo}" -eq "1" ]; then
  stressapptest -s 600000 -M 100 -m 1 -C 1 --printsec 10 &
  str_pid=$!
fi
if [ "${imx6quad}" -eq "1" ] || [ "${imx6quad_sata_cp}" -eq "1" ]; then
  stressapptest -s 600000 -M 500 -m 1 -C 1 --printsec 10 &
  str_pid=$!
fi
 
if [ "${imx6quad_sata_stress}" -eq "1" ]; then
  stressapptest -f /media/sata/tmp-file1 -s 600000 -M 500 -m 1 -C 1 --printsec 10 &
  str_pid=$!
fi
echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) Starting stressapptest with PID: " $str_pid
 
# play a video file in an infinite loop
echo 0 > /sys/class/graphics/fb0/blank
mplayer -vo fbdev2:/dev/fb0 -quiet -vf scale -zoom -loop 0 -xy 1024 /home/ubuntu/Clouds.avi < /dev/null &
vid_pid=$!
echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) Starting video file playback with PID: " $vid_pid
 
# ping
ping 192.168.0.160 &
ping_pid=$!
echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) Starting ping: " $ping_pid
 
# play a audio file
mplayer -loop 0 -really-quiet /home/ubuntu/blackbird.wav &
aud_pid=$!
 
proceed=1
file1="blackbird.wav"
file2="blackbird2.wav"
 
cp1_from="/media/mmc0/"
cp1_to="/media/usb0/"
 
if [ "${imx6solo}" -eq "1" ] || [ "${imx6quad}" -eq "1" ]; then
  cp2_from="/media/mmc0/"
  cp2_to="/media/usb1/"
fi
 
if [ "${imx6quad_sata_cp}" -eq "1" ] || [ "${imx6quad_sata_stress}" -eq "1" ]; then
  cp2_from="/media/sata/"
  cp2_to="/media/usb1/"
fi
 
#copy files in case they are missing
cp /media/$file1 $cp1_from$file1
cp /media/$file1 $cp1_to$file1
cp /media/$file2 $cp2_from$file2
cp /media/$file2 $cp2_to$file2
 
while [ $proceed -eq 1 ]
do
  cp1_done=`ps cax | grep $cp1_pid | grep cp`
  if [ -z "$cp1_done" ]; then # copy finished
    if cmp -s $cp1_from$file1 $cp1_to$file1; then
      echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) PASS: Copying file from $cp1_from to $cp1_to successful"
    else
      echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) ERROR: Difference between files on $cp1_from and $cp1_to detected"
      cp /media/$file1 $cp1_to$file1
      echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) File copied from /media/ to $cp1_to"
    fi
    cp1_temp=$cp1_from # swap destinations
    cp1_from=$cp1_to
    cp1_to=$cp1_temp
 
    rm $cp1_to$file1 # remove destination file
 
    cp $cp1_from$file1 $cp1_to$file1 &
    cp1_pid=$!
    echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) Started copying file from $cp1_from to $cp1_to"
  fi
 
  cp2_done=`ps cax | grep $cp2_pid | grep cp`
  if [ -z "$cp2_done" ]; then # copy finished
    if cmp -s $cp2_from$file2 $cp2_to$file2; then
      echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) PASS: Copying file from $cp2_from to $cp2_to successful"
    else
      echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) ERROR: Difference between files on $cp2_from and $cp2_to detected"
      cp /media/$file2 $cp2_to$file2
      echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z) File copied from /media/ to $cp2_to"
    fi
    cp2_temp=$cp2_from # swap destinations
    cp2_from=$cp2_to
    cp2_to=$cp2_temp
 
    rm $cp2_to$file2 # remove destination file
 
    cp $cp2_from$file2 $cp2_to$file2 &
    cp2_pid=$!
    echo "$(date +\%Y/\%m/\%d-\%T)($(date +\%Z)) Started copying file from $cp2_from to $cp2_to"
  fi
 
done


The original article can be accessed on the iMX6Rex.com website.