This blog post is about our current EV3 robot we're planning to use in the 2023/2024 FLL competition. Some features: 2 large motors for steering. 2 medium motors for attachments. 2 colour sensors for picking up the white and black lines, also used for line squaring. 1 gyro sensor. To enable attachments to be changed as quickly as possible we're using gravity to keep the gears connected, i.e. you don't need to fasten anything to the robot. Every attachment has 2x 12 tooth double bevel gear (part 32270) which comes in contact with the 2x 20 tooth double bevel gears (part 32269) on the robot. The medium motors are horizontally aligned on the robots, but we use 12 tooth double bevel gears to convert that to vertical alignments. These in turn are connected to 20 tooth double bevel gears, and the attachments in turn connect to these 20 tooth double bevel gears with their 12 tooth double bevel gears. The complete robot is modelled in Bricklink Studio 2 . You can download the rob
A 3G connection is normally not very stable - so we need something to periodically check it & reconnect when needed. I also wanted a summary email at the end of each day with the total traffic per client. I'm using the following settings/scripts:
Edit /etc/crontabs/root (create if not existing):
The first line will run /usr/bin/checkconnection every 5 minutes between 5:00 and 22:59. Then at 23:00 the day's statistics will be emailed and the 3G connection disconnected. The next morning at 5:00 it first checks if the email was sucessfully sent at 23:00, if so it will reboot the router (seems to be more stable if you reboot it every day), and part of the reboot will be to enable the 3G connection. If the email was not sent, checkconnection will reopen the connection and try to re-send. On success it will reboot the router.
The router automatically updates the date & time with a NTP server. Make sure you have the correct timezone defined in /etc/config/system.
The scripts:
/usr/bin/checkconnection: It first updates the 3g stats. Then if we have an email to be sent, we first send it (replace from@addres.com with your from address, to@address.com with your to address and smtp.com with your smtp server):
Edit /etc/crontabs/root (create if not existing):
# send stats & disconnect 3G at 23:00 everyday.
# check the connection every 5 minutes between 5:00 and 23:00 and reconnect if needed
# reboot at 5:00 if /tmp/stats.msg doesn't exist - will be sent in checkconnect
*/5 5-22 * * * /usr/bin/checkconnection
0 5 * * * if [ ! -s /tmp/stats.msg ]; then reboot ; fi
0 23 * * * /usr/bin/sendstats && ifdown wan
The first line will run /usr/bin/checkconnection every 5 minutes between 5:00 and 22:59. Then at 23:00 the day's statistics will be emailed and the 3G connection disconnected. The next morning at 5:00 it first checks if the email was sucessfully sent at 23:00, if so it will reboot the router (seems to be more stable if you reboot it every day), and part of the reboot will be to enable the 3G connection. If the email was not sent, checkconnection will reopen the connection and try to re-send. On success it will reboot the router.
The router automatically updates the date & time with a NTP server. Make sure you have the correct timezone defined in /etc/config/system.
The scripts:
/usr/bin/checkconnection: It first updates the 3g stats. Then if we have an email to be sent, we first send it (replace from@addres.com with your from address, to@address.com with your to address and smtp.com with your smtp server):
# write 3g stats to logfile
/usr/bin/wrtbwmon setup 3g-wan
/usr/bin/wrtbwmon update /tmp/log/wrtbwmon
# try to send out email if it's still pending
if [ -s /tmp/stats.msg ];
then
cat /tmp/stats.msg | mini_sendmail -ffrom@address.com -ssmtp.com to@address.com
if [ $? -eq 0 ] ; then reboot ; fi
fi
# if 3g is connected, we have nothing to do
if
ifconfig 3g-wan
then
# sometimes ifconfig 3g-wan shows information, but 3g-wan is not running
if
ifconfig | grep 3g-wan
then
exit 0
fi
# if we reach this, it means we need to restart 3g-wan
ifdown wan
fi
# if we get to this point, it means 3g is not connected
# check if we can access /dev/ttyUSB2 - if not reset the USB device
# and reconnect
if [ -e /dev/ttyUSB2 ];
then
ifup wan
else
/usr/bin/usb_modeswitch -c /etc/usb_modeswitch.d/custom
sleep 10
ifup wan
fi
/etc/usb_modeswitch.d/custom: It seems usb_modeswitch does not always recognise the USB modem, so we need sometimes need to no manually do a modeswitch. This is for a Huawei E1752 - search the web for other modems:
/usr/bin/wrtbwmon: This was originally taken from http://code.google.com/p/wrtbwmon/ and modified to suit my needs.
DefaultVendor=0x12d1
DefaultProduct=0x1446
TargetVendor=0x12d1
TargetProdct=0x1001
MessageEndpoint=0x01
MessageContent="55534243000000000000000000000011060000000000000000000000000000"
/usr/bin/wrtbwmon: This was originally taken from http://code.google.com/p/wrtbwmon/ and modified to suit my needs.
#!/bin/sh
#
# Traffic logging tool for OpenWRT-based routers
#
# Created by Emmanuel Brucy (e.brucy AT qut.edu.au)
#
# Based on work from Fredrik Erlandsson (erlis AT linux.nu)
# Based on traff_graph script by twist - http://wiki.openwrt.org/RrdTrafficWatch
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
LAN_IFACE=${2} || $(nvram get lan_ifname)
lock()
{
while [ -f /tmp/wrtbwmon.lock ]; do
if [ ! -d /proc/$(cat /tmp/wrtbwmon.lock) ]; then
echo "WARNING : Lockfile detected but process $(cat /tmp/wrtbwmon.lock) does not exist !"
rm -f /tmp/wrtbwmon.lock
fi
sleep 1
done
echo $$ > /tmp/wrtbwmon.lock
}
unlock()
{
rm -f /tmp/wrtbwmon.lock
}
case ${1} in
"setup" )
#Create the RRDIPT CHAIN (it doesn't matter if it already exists).
iptables -N RRDIPT 2> /dev/null
#Add the RRDIPT CHAIN to the FORWARD chain (if non existing).
iptables -L FORWARD --line-numbers -n | grep "RRDIPT" | grep "1" > /dev/null
if [ $? -ne 0 ]; then
iptables -L FORWARD -n | grep "RRDIPT" > /dev/null
if [ $? -eq 0 ]; then
echo "DEBUG : iptables chain misplaced, recreating it..."
iptables -D FORWARD -j RRDIPT
fi
iptables -I FORWARD -j RRDIPT
fi
#For each host in the ARP table
grep 192.168.1 /proc/net/arp | while read IP TYPE FLAGS MAC MASK IFACE ;
do
#Add iptable rules (if non existing).
iptables -nL RRDIPT | grep "${IP} " > /dev/null
if [ $? -ne 0 ]; then
echo "DEBUG : adding rule for IP ${IP}"
iptables -I RRDIPT -d ${IP} -j RETURN -i ${2}
iptables -I RRDIPT -s ${IP} -j RETURN -o ${2}
fi
done
;;
"update" )
[ -z "${2}" ] && echo "ERROR : Missing argument 2" && exit 1
# Uncomment this line if you want to abort if database not found
# [ -f "${2}" ] || exit 1
# Create an empty file if not existing
[ -f "${2}" ] || touch ${2}
lock
#Read and reset counters
iptables -L RRDIPT -vnxZ -t filter > /tmp/traffic_$$.tmp
grep -v "0x0" /proc/net/arp | grep -v 'IP address' | grep -v eth0.1 | while read IP TYPE FLAGS MAC MASK IFACE
do
#Add new data to the graph. Count in Kbs to deal with 16 bits signed values (up to 2G only)
#Have to use temporary files because of crappy busybox shell
grep ${IP} /tmp/traffic_$$.tmp | while read PKTS BYTES TARGET PROT OPT IFIN IFOUT SRC DST
do
[ "${DST}" = "${IP}" ] && echo $((${BYTES}/1000)) > /tmp/in_$$.tmp
[ "${SRC}" = "${IP}" ] && echo $((${BYTES}/1000)) > /tmp/out_$$.tmp
done
IN=$(cat /tmp/in_$$.tmp)
OUT=$(cat /tmp/out_$$.tmp)
rm -f /tmp/in_$$.tmp
rm -f /tmp/out_$$.tmp
if [ ${IN} -gt 0 -o ${OUT} -gt 0 ]; then
echo "DEBUG : New traffic for ${MAC} since last update : ${IN}k:${OUT}k"
LINE=$(grep ${MAC} ${2})
if [ -z "${LINE}" ]; then
echo "DEBUG : ${MAC} is a new host !"
PEAKUSAGE_IN=0
PEAKUSAGE_OUT=0
OFFPEAKUSAGE_IN=0
OFFPEAKUSAGE_OUT=0
else
PEAKUSAGE_IN=$(echo ${LINE} | cut -f2 -s -d, )
PEAKUSAGE_OUT=$(echo ${LINE} | cut -f3 -s -d, )
OFFPEAKUSAGE_IN=$(echo ${LINE} | cut -f4 -s -d, )
OFFPEAKUSAGE_OUT=$(echo ${LINE} | cut -f5 -s -d, )
fi
if [ "${3}" = "offpeak" ]; then
OFFPEAKUSAGE_IN=$((${OFFPEAKUSAGE_IN}+${IN}))
OFFPEAKUSAGE_OUT=$((${OFFPEAKUSAGE_OUT}+${OUT}))
else
PEAKUSAGE_IN=$((${PEAKUSAGE_IN}+${IN}))
PEAKUSAGE_OUT=$((${PEAKUSAGE_OUT}+${OUT}))
fi
grep -v "${MAC}" ${2} > /tmp/db_$$.tmp
mv /tmp/db_$$.tmp ${2}
echo ${MAC},${PEAKUSAGE_IN},${PEAKUSAGE_OUT},${OFFPEAKUSAGE_IN},${OFFPEAKUSAGE_OUT},$(date "+%d-%m-%Y %H:%M") >> ${2}
fi
done
#Free some memory
rm -f /tmp/*_$$.tmp
unlock
;;
"publish" )
[ -z "${2}" ] && echo "ERROR : Missing argument 2" && exit 1
[ -z "${3}" ] && echo "ERROR : Missing argument 3" && exit 1
USERSFILE="/etc/dnsmasq.conf"
[ -f "${USERSFILE}" ] || USERSFILE="/tmp/dnsmasq.conf"
[ -z "${4}" ] || USERSFILE=${4}
[ -f "${USERSFILE}" ] || USERSFILE="/dev/null"
# first do some number crunching - rewrite the database so that it is sorted
lock
mkdir -p /tmp/www
touch /tmp/sorted_$$.tmp
cat ${2} | while IFS=, read MAC PEAKUSAGE_IN PEAKUSAGE_OUT OFFPEAKUSAGE_IN OFFPEAKUSAGE_OUT LASTSEEN
do
echo ${PEAKUSAGE_IN},${PEAKUSAGE_OUT},${OFFPEAKUSAGE_IN},${OFFPEAKUSAGE_OUT},${MAC},${LASTSEEN} >> /tmp/sorted_$$.tmp
done
unlock
# create HTML page
echo "Traffic
Total Usage :
" >> ${3}
echo "" >> ${3}
echo "
" >> ${3}
User Peak download Peak upload Offpeak download Offpeak upload Last seen
echo "
This page was generated on `date`" 2>&1 >> ${3}
echo "" >> ${3}
#Free some memory
rm -f /tmp/*_$$.tmp
;;
*)
echo "Usage : $0 {setup|update|publish} [options...]"
echo "Options : "
echo " $0 setup"
echo " $0 update database_file [offpeak]"
echo " $0 publish database_file path_of_html_report [user_file]"
echo "Examples : "
echo " $0 setup"
echo " $0 update /tmp/usage.db offpeak"
echo " $0 publish /tmp/usage.db /www/user/usage.htm /jffs/users.txt"
echo "Note : [user_file] is an optional file to match users with their MAC address"
echo " Its format is : 00:MA:CA:DD:RE:SS,username , with one entry per line"
exit
;;
esac
/usr/bin/sendstats: Replace from@address.com with your from address, to@addres.com with your to address, and smtp.com with your smtp server.
echo "From: OpenWRT router" > /tmp/stats.msg rm /var/log/ppp
echo "To: to@address.com" >> /tmp/stats.msg
echo "Subject: Router statistics" >> /tmp/stats.msg
echo "" >> /tmp/stats.msg
echo "Uptime:" >> /tmp/stats.msg
uptime >> /tmp/stats.msg
echo "" >> /tmp/stats.msg
echo "wrtbwmon:" >> /tmp/stats.msg
cat /tmp/log/wrtbwmon >> /tmp/stats.msg
echo "" >> /tmp/stats.msg
echo "PPP log:" >> /tmp/stats.msg
cat /var/log/ppp >> /tmp/stats.msg
echo "" >> /tmp/stats.msg
#echo "/proc/net/arp:" >> /tmp/stats.msg
#cat /proc/net/arp >> /tmp/stats.msg
#echo "" >> /tmp/stats.msg
echo "ifconfig:" >> /tmp/stats.msg
ifconfig >> /tmp/stats.msg
echo "" >> /tmp/stats.msg
#echo "logread:" >> /tmp/stats.msg
#logread >> /tmp/stats.msg
rm /tmp/log/wrtbwmoncat /tmp/stats.msg | mini_sendmail -ffrom@address.com -ssmtp.com to@address.com
if [ $? -eq 0 ] ; then rm /tmp/stats.msg ; fi
/etc/ppp/ip-up.d/3glog: (everytime the 3g connects, write the date & time to a log file)
/etc/ppp/ip-down.d/3glog: (everytime the 3g disconnects, write the date & time & total bytes sent to a log file)
#!/bin/sh
logfile=/var/log/ppp
echo "`date` Connected $0 $1 $2 $3 $4 $5 $6" >> $logfile
# setup bandwidth monitoring
/usr/bin/wrtbwmon setup 3g-wan
/etc/ppp/ip-down.d/3glog: (everytime the 3g disconnects, write the date & time & total bytes sent to a log file)
#!/bin/sh
logfile=/var/log/ppp
echo "`date` Disconnected $0 $1 $2 $3 $4 $5 $6" >> $logfile
logread | tail | grep Sent >> $logfile
Comments