Skip to content

Instantly share code, notes, and snippets.

@psiborg
Last active May 20, 2023 14:58
Show Gist options
  • Save psiborg/437b316d10f5555472e78e8ac529dd12 to your computer and use it in GitHub Desktop.
Save psiborg/437b316d10f5555472e78e8ac529dd12 to your computer and use it in GitHub Desktop.
Raspberry Pi #rpi

General Commands

http://www.circuitbasics.com/useful-raspberry-pi-commands/

https://raspberryinsider.com/top-15-raspberry-pi-keyboard-shortcuts/

Retrieve new list of packages and perform upgrades

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

Open the Pi Configuration menu

raspi-config

Set the date and time (manually)

sudo date -s "Wed May 22 19:30:00 UTC 2019"

Sync time

sudo apt-get install -y ntp
sudo apt-get install -y ntpdate

sudo nano /etc/ntp.conf
  server time.nist.gov
  (Reboot)

ntpq -p

ls -al /etc/localtime
  lrwxrwxrwx 1 root root 35 Jun 14 20:12 /etc/localtime -> /usr/share/zoneinfo/America/Toronto

timedatectl status
sudo timedatectl set-ntp true

Show DNS info

cat /etc/resolv.conf

Get Wifi (SSID) info

iwgetid
iwconfig

Renew IP address for the eth0 interface:

sudo dhclient -r eth0
sudo dhclient eth0

Find IP addresses of connected devices on subnet:

sudo apt-get install -y nmap
sudo nmap -sn 192.168.1.0/24

Assign a static IP address

ip r | grep default
sudo cat /etc/resolv.conf

sudo nano /etc/dhcpcd.conf

interface wlan0
static ip_address=192.168.1.nn/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1 8.8.8.8

sudo reboot

hostname -I

Install public on a remote machine

ssh-keygen -t rsa
ssh-copy-id pi@{hostname}
ssh pi@{hostname}

Copy file to a remote machine

scp {filename} pi@{hostname}:/home/pi/{filename}

Remove keys belonging to hostname

ssh-keygen -R {hostname}

List all GPG keys

apt-key list

Print version of Raspian

cat /etc/os-release

Print distribution

lsb_release -a

Print system information

uname -a

Find Pi revision number

cat /proc/device-tree/model

cat /proc/cpuinfo

pinout

Install 7-Zip to compress files

sudo apt-get install -y p7zip-full

List packages

apt list --installed

Remove packages

sudo apt-get remove --purge geany*

Clean packages

sudo apt-get clean
sudo apt autoremove

Clear command line history

history -c

Expand SD card to fill max capacity

sudo raspi-config --expand-rootfs
sudo shutdown -r now
#!/bin/bash
: <<'DISCLAIMER'
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
This script is licensed under the terms of the MIT license.
Unless otherwise noted, code reproduced herein
was written for this script.
- The Pimoroni Crew -
DISCLAIMER
# script control variables
productname="na" # the name of the product to install
scriptname="audio" # the name of this script
spacereq=1 # minimum size required on root partition in MB
debugmode="no" # whether the script should use debug routines
debuguser="none" # optional test git user to use in debug mode
debugpoint="none" # optional git repo branch or tag to checkout
forcesudo="no" # whether the script requires to be ran with root privileges
promptreboot="no" # whether the script should always prompt user to reboot
mininstall="no" # whether the script enforces minimum install routine
customcmd="yes" # whether to execute commands specified before exit
gpioreq="no" # whether low-level gpio access is required
i2creq="no" # whether the i2c interface is required
i2sreq="no" # whether the i2s interface is required
spireq="no" # whether the spi interface is required
uartreq="no" # whether uart communication is required
armhfonly="yes" # whether the script is allowed to run on other arch
armv6="yes" # whether armv6 processors are supported
armv7="yes" # whether armv7 processors are supported
armv8="yes" # whether armv8 processors are supported
raspbianonly="no" # whether the script is allowed to run on other OSes
osreleases=( "Raspbian" "Kano" "Mate" "PiTop" "RetroPie" ) # list os-releases supported
oswarning=( "Debian" "Ubuntu" ) # list experimental os-releases
osdeny=( "Darwin" "Kali" "Linaro" "Volumio" ) # list os-releases specifically disallowed
FORCE=$1
ASK_TO_REBOOT=false
CURRENT_SETTING=false
MIN_INSTALL=false
FAILED_PKG=false
REMOVE_PKG=false
UPDATE_DB=false
AUTOSTART=~/.config/lxsession/LXDE-pi/autostart
BOOTCMD=/boot/cmdline.txt
CONFIG=/boot/config.txt
APTSRC=/etc/apt/sources.list
INITABCONF=/etc/inittab
BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
LOADMOD=/etc/modules
RASPOOL="http://mirrordirector.raspbian.org/raspbian/pool"
RPIPOOL="http://archive.raspberrypi.org/debian/pool"
DEBPOOL="http://ftp.debian.org/debian/pool"
GETPOOL="https://get.pimoroni.com"
# function define
confirm() {
if [ "$FORCE" == '-y' ]; then
true
else
read -r -p "$1 [y/N] " response < /dev/tty
if [[ $response =~ ^(yes|y|Y)$ ]]; then
true
else
false
fi
fi
}
prompt() {
read -r -p "$1 [y/N] " response < /dev/tty
if [[ $response =~ ^(yes|y|Y)$ ]]; then
true
else
false
fi
}
success() {
echo -e "$(tput setaf 2)$1$(tput sgr0)"
}
inform() {
echo -e "$(tput setaf 6)$1$(tput sgr0)"
}
warning() {
echo -e "$(tput setaf 1)$1$(tput sgr0)"
}
newline() {
echo ""
}
progress() {
count=0
until [ $count -eq 7 ]; do
echo -n "..." && sleep 1
((count++))
done;
if ps -C $1 > /dev/null; then
echo -en "\r\e[K" && progress $1
fi
}
sudocheck() {
if [ $(id -u) -ne 0 ]; then
echo -e "Install must be run as root. Try 'sudo ./$scriptname'\n"
exit 1
fi
}
sysclean() {
sudo apt-get clean && sudo apt-get autoclean
sudo apt-get -y autoremove &> /dev/null
}
sysupdate() {
if ! $UPDATE_DB; then
echo "Updating apt indexes..." && progress apt-get &
sudo apt-get update 1> /dev/null || { warning "Apt failed to update indexes!" && exit 1; }
sleep 3 && UPDATE_DB=true
fi
}
sysupgrade() {
sudo apt-get upgrade
sudo apt-get clean && sudo apt-get autoclean
sudo apt-get -y autoremove &> /dev/null
}
sysreboot() {
warning "Some changes made to your system require"
warning "your computer to reboot to take effect."
echo
if prompt "Would you like to reboot now?"; then
sync && sudo reboot
fi
}
arch_check() {
IS_ARMHF=false
IS_ARMv6=false
if uname -m | grep -q "armv.l"; then
IS_ARMHF=true
if uname -m | grep -q "armv6l"; then
IS_ARMv6=true
fi
fi
}
os_check() {
IS_MACOSX=false
IS_RASPBIAN=false
IS_SUPPORTED=false
IS_EXPERIMENTAL=false
OS_NAME="Unknown"
if uname -s | grep -q "Darwin"; then
OS_NAME="Darwin" && IS_MACOSX=true
elif cat /etc/os-release | grep -q "Kali"; then
OS_NAME="Kali"
elif [ -d ~/.kano-settings ] || [ -d ~/.kanoprofile ]; then
OS_NAME="Kano"
elif whoami | grep -q "linaro"; then
OS_NAME="Linaro"
elif [ -d ~/.config/ubuntu-mate ];then
OS_NAME="Mate"
elif [ -d ~/.pt-os-dashboard ] || [ -d ~/.pt-dashboard ] || [ -f ~/.pt-dashboard-config ]; then
OS_NAME="PiTop"
elif command -v emulationstation > /dev/null; then
OS_NAME="RetroPie"
elif cat /etc/os-release | grep -q "volumio"; then
OS_NAME="Volumio"
elif cat /etc/os-release | grep -q "Raspbian"; then
OS_NAME="Raspbian" && IS_RASPBIAN=true
elif cat /etc/os-release | grep -q "Debian"; then
OS_NAME="Debian"
elif cat /etc/os-release | grep -q "Ubuntu"; then
OS_NAME="Ubuntu"
fi
if [[ " ${osreleases[@]} " =~ " ${OS_NAME} " ]]; then
IS_SUPPORTED=true
fi
if [[ " ${oswarning[@]} " =~ " ${OS_NAME} " ]]; then
IS_EXPERIMENTAL=true
fi
}
raspbian_check() {
IS_SUPPORTED=false
IS_EXPERIMENTAL=false
if [ -f /etc/os-release ]; then
if cat /etc/os-release | grep -q "/sid"; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
elif cat /etc/os-release | grep -q "stretch"; then
IS_SUPPORTED=true && IS_EXPERIMENTAL=false
elif cat /etc/os-release | grep -q "jessie"; then
IS_SUPPORTED=true && IS_EXPERIMENTAL=false
elif cat /etc/os-release | grep -q "wheezy"; then
IS_SUPPORTED=true && IS_EXPERIMENTAL=false
else
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
fi
fi
}
home_dir() {
if [ $EUID -ne 0 ]; then
if $IS_MACOSX; then
USER_HOME=$(dscl . -read /Users/$USER NFSHomeDirectory | cut -d: -f2)
else
USER_HOME=$(getent passwd $USER | cut -d: -f6)
fi
else
warning "Running as root, please log in as a regular user with sudo rights!"
echo && exit 1
fi
}
space_chk() {
if command -v stat > /dev/null && ! $IS_MACOSX; then
if [ $spacereq -gt $(($(stat -f -c "%a*%S" /)/10**6)) ];then
echo
warning "There is not enough space left to proceed with installation"
if confirm "Would you like to attempt to expand your filesystem?"; then
curl -sS $GETPOOL/expandfs | sudo bash && exit 1
else
echo && exit 1
fi
fi
fi
}
timestamp() {
date +%Y%m%d-%H%M
}
check_network() {
sudo ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3 | head -n 1` &> /dev/null && return 0 || return 1
}
force_hdmi() {
if [ -e $CONFIG ] && ! grep -q "^hdmi_force_hotplug=1$" $CONFIG; then
if grep -q "^#hdmi_force_hotplug=1$" $CONFIG; then
sudo sed -i "s|^#hdmi_force_hotplug=1|hdmi_force_hotplug=1|" $CONFIG &> /dev/null
else
echo "hdmi_force_hotplug=1" | sudo tee -a $CONFIG &> /dev/null
fi
fi
}
hotplug_hdmi() {
if [ -e $CONFIG ] && grep -q "^hdmi_force_hotplug=1$" $CONFIG; then
sudo sed -i "s|^hdmi_force_hotplug=1|#hdmi_force_hotplug=1|" $CONFIG &> /dev/null
fi
}
add_dtoverlay() {
if grep -q "^dtoverlay=$1" $CONFIG; then
echo -e "\n$1 overlay already active"
elif grep -q "^#dtoverlay=$1" $CONFIG; then
sudo sed -i "/^#dtoverlay=$1$/ s|#||" $CONFIG
echo -e "\nAdding $1 overlay to $CONFIG"
ASK_TO_REBOOT=true
else
echo "dtoverlay=$1" | sudo tee -a $CONFIG &> /dev/null
echo -e "\nAdding $1 overlay to $CONFIG"
ASK_TO_REBOOT=true
fi
}
remove_dtoverlay() {
sudo sed -i "/^dtoverlay=$1$/ s|^|#|" $CONFIG
ASK_TO_REBOOT=true
}
enable_pi_audio() {
if grep -q "#dtparam=audio=on" $CONFIG; then
sudo sed -i "/^#dtparam=audio=on$/ s|#||" $CONFIG
echo -e "\nsnd_bcm2835 loaded (on-board audio enabled)"
ASK_TO_REBOOT=true
fi
}
disable_pi_audio() {
if grep -q "^dtparam=audio=on" $CONFIG; then
sudo sed -i "/^dtparam=audio=on$/ s|^|#|" $CONFIG
echo -e "\nsnd_bcm2835 unloaded (on-board audio disabled)"
ASK_TO_REBOOT=true
fi
}
test_audio() {
newline
if confirm "Do you wish to test your system now?"; then
echo -e "\nTesting..."
speaker-test -l5 -c2 -t wav
fi
}
disable_pulseaudio() {
sudo mv /etc/xdg/autostart/pulseaudio.desktop /etc/xdg/autostart/pulseaudio.disabled &> /dev/null
pulseaudio -k &> /dev/null
}
kill_volumealsa() {
sed -i "s|type=volumealsa|type=space|" $HOME/.config/lxpanel/LXDE/panels/panel &> /dev/null
sed -i "s|type=volumealsa|type=space|" $HOME/.config/lxpanel/LXDE-pi/panels/panel &> /dev/null
}
basic_asound() {
sudo echo -e "pcm.\041default {\n type hw\n card 1\n}" > $HOME/.asoundrc
sudo echo -e "ctl.\041default {\n type hw\n card 1\n}" >> $HOME/.asoundrc
sudo mv $HOME/.asoundrc /etc/asound.conf
}
route_audio() {
if [ $debugmode == "yes" ]; then
warning "passed parameter is $FORCE"
fi
if [ "$FORCE" == '1' ]; then
amixer cset numid=3 1 > /dev/null
success "Audio output mode changed to Analog!"
hotplug_hdmi
elif [ "$FORCE" == '2' ]; then
amixer cset numid=3 2 > /dev/null
success "Audio output mode changed to HDMI!"
hotplug_hdmi
elif [ "$FORCE" == '3' ]; then
amixer cset numid=3 2 > /dev/null
success "Audio signal will be forcefully sent to HDMI!"
force_hdmi
else
newline
echo "Please choose an audio output mode:" && newline
echo "0 : Automatic signal detection"
echo "1 : Output to analogue (headphone/speaker jack)"
echo "2 : Output to digital (HDMI port)"
echo "3 : Force route to digital (HDMI hotplug disabled)"
newline
read -r -p "Enter an option [0-3]:" choice < /dev/tty
if [ $debugmode == "yes" ]; then
echo "User chose option $choice"
fi
if [[ $choice =~ ^(0|1|2)$ ]]; then
amixer cset numid=3 $choice > /dev/null
success "Audio output mode changed!"
hotplug_hdmi
elif [[ $choice =~ ^(3)$ ]]; then
amixer cset numid=3 $choice > /dev/null
success "Audio signal will be forcefully sent to HDMI!"
force_hdmi
else
warning "Invalid option!"
route_audio
fi
fi
}
: <<'MAINSTART'
Perform all global variables declarations as well as function definition
above this section for clarity, thanks!
MAINSTART
# intro message
if [ $debugmode != "no" ]; then
if [ $debuguser != "none" ]; then
gitusername="$debuguser"
fi
if [ $debugpoint != "none" ]; then
gitrepobranch="$debugpoint"
fi
inform "\nDEBUG MODE ENABLED"
echo -e "git user $gitusername and $gitrepobranch branch/tag will be used\n"
else
echo -e "\nThis script will configure your Pi audio output!"
if [ "$FORCE" != '-y' ]; then
inform "\nAlways be careful when running scripts and commands copied"
inform "from the internet. Ensure they are from a trusted source.\n"
echo -e "If you want to see what this script does before running it,"
echo -e "you should run: 'curl $GETPOOL/$scriptname'\n"
fi
fi
# checks and init
arch_check
os_check
space_chk
home_dir
if [ $debugmode != "no" ]; then
echo "USER_HOME is $USER_HOME"
echo "OS_NAME is $OS_NAME"
echo "IS_SUPPORTED is $IS_SUPPORTED"
echo "IS_EXPERIMENTAL is $IS_EXPERIMENTAL"
echo
fi
if ! $IS_ARMHF; then
warning "This hardware is not supported, sorry!"
warning "Config files have been left untouched\n"
exit 1
fi
if $IS_ARMv8 && [ $armv8 == "no" ]; then
warning "Sorry, your CPU is not supported by this installer\n"
exit 1
elif $IS_ARMv7 && [ $armv7 == "no" ]; then
warning "Sorry, your CPU is not supported by this installer\n"
exit 1
elif $IS_ARMv6 && [ $armv6 == "no" ]; then
warning "Sorry, your CPU is not supported by this installer\n"
exit 1
fi
if [ $raspbianonly == "yes" ] && ! $IS_RASPBIAN;then
warning "This script is intended for Raspbian on a Raspberry Pi!\n"
exit 1
fi
if $IS_RASPBIAN; then
raspbian_check
if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
warning "\n--- Warning ---\n"
echo "The $productname installer"
echo "does not work on this version of Raspbian."
echo "Check https://github.com/$gitusername/$gitreponame"
echo "for additional information and support" && echo
exit 1
fi
fi
if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
warning "Your operating system is not supported, sorry!\n"
exit 1
fi
if $IS_EXPERIMENTAL; then
warning "Support for your operating system is experimental. Please visit"
warning "forums.pimoroni.com if you experience issues with this product.\n"
fi
if [ $forcesudo == "yes" ]; then
sudocheck
fi
if [ $uartreq == "yes" ]; then
echo "Note: $productname requires UART communication"
warning "The serial console will be disabled if you proceed!"
fi
if [ $spireq == "yes" ]; then
echo -e "Note: $productname requires SPI communication"
fi
if [ $i2creq == "yes" ]; then
echo -e "Note: $productname requires I2C communication"
fi
if [ $i2sreq == "yes" ]; then
echo -e "Note: $productname uses the I2S interface"
warning "The on-board audio chip will be disabled if you proceed!"
fi
newline
if confirm "Do you wish to continue?"; then
# environment preparation
if [ -e $CONFIG ] && grep -q -E "^dtparam=audio=on$" $CONFIG; then
bcm2835off="no"
elif [ -e $LOADMOD ] && grep -q "^snd-bcm2835" $LOADMOD; then
bcm2835off="no"
else
bcm2835off="yes"
fi
if [ $bcm2835off == "no" ]; then
newline
route_audio
if [ "$FORCE" != '-y' ] && [ "$FORCE" != '3' ]; then
test_audio
fi
newline
else
newline
warning "Default sound driver currently not loaded!"
if confirm "Do you wish to re-enable the on-board audio?"; then
enable_pi_audio
remove_dtoverlay i2s-mmap
remove_dtoverlay hifiberry-dac
sudo rm /etc/asound.conf &> /dev/null
sudo rm ~/.asound.rc &> /dev/null
newline
else
exit 1
fi
fi
if [ $promptreboot == "yes" ] || $ASK_TO_REBOOT; then
sysreboot && newline
fi
else
newline && echo "Aborting..." && newline
fi
exit 0

https://pimylifeup.com/raspberry-pi-boinc/

GUI

sudo apt-get install -y boinc

Command Line (Headless)

https://boinc.berkeley.edu/wiki/Boinccmd_tool

sudo apt-get install -y boinc-client

boinccmd --lookup_account http://setiathome.berkeley.edu "{YOUR_EMAIL}" "{YOUR_PASSWORD}"

boinccmd --project_attach http://setiathome.berkeley.edu {YOUR_ACCOUNT_KEY}

sudo nano /etc/boinc-client/global_prefs_override.xml

Paste the following:

<global_preferences>
   <run_on_batteries>0</run_on_batteries>
   <run_if_user_active>0</run_if_user_active>
   <run_gpu_if_user_active>0</run_gpu_if_user_active>
   <idle_time_to_run>3.000000</idle_time_to_run>
   <suspend_cpu_usage>25.000000</suspend_cpu_usage>
   <start_hour>0.000000</start_hour>
   <end_hour>23.000000</end_hour>
   <net_start_hour>0.000000</net_start_hour>
   <net_end_hour>0.000000</net_end_hour>
   <leave_apps_in_memory>0</leave_apps_in_memory>
   <confirm_before_connecting>1</confirm_before_connecting>
   <hangup_if_dialed>0</hangup_if_dialed>
   <dont_verify_images>0</dont_verify_images>
   <work_buf_min_days>0.100000</work_buf_min_days>
   <work_buf_additional_days>0.500000</work_buf_additional_days>
   <max_ncpus_pct>65.000000</max_ncpus_pct>
   <cpu_scheduling_period_minutes>60.000000</cpu_scheduling_period_minutes>
   <disk_interval>60.000000</disk_interval>
   <disk_max_used_gb>0.000000</disk_max_used_gb>
   <disk_max_used_pct>90.000000</disk_max_used_pct>
   <disk_min_free_gb>1.000000</disk_min_free_gb>
   <vm_max_used_pct>75.000000</vm_max_used_pct>
   <ram_max_used_busy_pct>50.000000</ram_max_used_busy_pct>
   <ram_max_used_idle_pct>90.000000</ram_max_used_idle_pct>
   <max_bytes_sec_up>0.000000</max_bytes_sec_up>
   <max_bytes_sec_down>0.000000</max_bytes_sec_down>
   <cpu_usage_limit>65.000000</cpu_usage_limit>
   <daily_xfer_limit_mb>0.000000</daily_xfer_limit_mb>
   <daily_xfer_period_days>0</daily_xfer_period_days>
</global_preferences>

Reload

boinccmd --read_global_prefs_override
boinccmd --read_cc_config

boinccmd --get_tasks

Stats

crontab -e

0 0 * * * /home/pi/boinc_stats.sh >> /home/pi/boinc_stats.log
0 */6 * * * /home/pi/boinc_seti.sh > /home/pi/boinc_seti.txt

crontab -l

Debugging

boinccmd --quit

sudo service boinc-client status
sudo service boinc-client start

cd /var/lib/boinc-client

more /var/log/boinc.log

sudo find . -name boinc*
#!/bin/bash
LOG=boinc_seti.txt
boinccmd --get_project_status | grep host_total_credit | cut -d ':' -f 2 | xargs
#!/bin/bash
LOG=boinc_stats.log
boinccmd --get_host_info | grep domain | cut -d ':' -f 2 | xargs
date
boinccmd --get_project_status | grep host_ | cut -d ':' -f 2 | xargs
echo
#!/bin/bash
dt=$(date '+%Y-%m-%d %H:%M:%S')
hn=$(hostname)
ps=$(boinccmd --get_project_status)
tc=$(echo "$ps" | grep host_total_credit | cut -d ':' -f 2 | xargs)
ac=$(echo "$ps" | grep host_expavg_credit | cut -d ':' -f 2 | xargs)
pn=$(echo "$ps" | grep -i "name: .*@Home" | cut -d ':' -f 2 | xargs)
echo "$hn": ["$dt"] total="$tc", average="$ac" [$pn]

Automatically enable HTTPS on your website with EFF's Certbot, deploying Let's Encrypt certificates on Debian 9 (stretch)

https://certbot.eff.org/lets-encrypt/debianstretch-other

sudo apt-get install -y certbot -t stretch-backports

sudo certbot certonly

sudo certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com -w /var/www/thing -d thing.is -d m.thing.is

sudo certbot certonly --standalone -d example.com -d www.example.com
crontab -e

0 0 * * * /home/pi/cleanup.sh >> /home/pi/cleanup.log
#!/bin/bash

dt=$(date '+%Y-%m-%d %H:%M:%S')
base_path='/home/pi/{your_path}'
days_old='+90'

echo "$dt:"
find "$base_path" -type f -mtime $days_old -delete
find "$base_path" -mindepth 1 -type d -mtime $days_old -delete

# touch -mt 202001010000 ./{filename}
Desktop Preferences
	Desktop
		Layout: No image
		Colour: (MRe Dark Petrol)
			R: 0
			G: 98
			B: 113
	Menu Bar
		Position: Bottom
		Colour: (Grey 4)
			R: 217
			G: 218
			B: 218
	System
		Highlight Colour: (MRe Logo Blue)
			R: 23
			G: 87
			B: 136

CPU Usage Monitor Settings
	Foreground Colour: (MRe Dark Red)
		R: 182
		G: 16
		B: 29
Desktop Preferences
	Desktop
		Layout: No image
		Colour:
			R: 51
			G: 51
			B: 51
	Menu Bar
		Position: Bottom
		Colour:
			R: 217
			G: 218
			B: 218
	System
		Highlight Colour:
			R: 23
			G: 87
			B: 136

CPU Usage Monitor Settings
	Foreground Colour:
		R: 11
		G: 134
		B: 250
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-`uname -m`.sh
    -OR-
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-armv7l.sh

md5sum Miniconda3-latest-Linux-armv7l.sh

bash Miniconda3-latest-Linux-armv7l.sh

source ~/.bashrc

python --version

conda

https://nycdatascience.com/blog/student-works/data-science-go-docker-raspberry-pi/3/

https://github.com/edenbaus/DataSciencePi

https://github.com/jakevdp/PythonDataScienceHandbook

install.sh:

#!/bin/bash

sudo apt-get install -y \
    curl \
    wget \
    screen \
    cmake \
    unzip \
    libtiff5-dev \
    libhdf5-dev \
    python3 \
    python3-dev \
    cython3 \
    python3-cffi \
    python3-setuptools \
    python3-pip \
    pkg-config \
    python3-tables \
    python3-wheel \
    python3-numpy \
    python3-scipy \
    libpng-dev \
    libjasper-dev \
    libavcodec-dev \
    libswscale-dev \
    libv4l-dev \
    libxvidcore-dev \
    libx264-dev \
    libatlas-base-dev \
    libfreetype6-dev\
    libxft-dev \
    libblas-dev \
    liblapack-dev \
    libatlas-base-dev \
    gfortran \
    libxml2-dev \
    libxslt-dev \
    build-essential \
    ipython3 \
    libncurses5-dev \
    libssl-dev \
    openssl \
    libreadline-dev \
    libbz2-dev \
    libncurses5-dev \
    libcurl4-openssl-dev \
    libjpeg-dev \
    r-base \
    r-base-core \
    r-base-dev \
    --no-install-recommends
sudo pip3 install --upgrade pip

cd ~/Projects
git clone https://github.com/jakevdp/PythonDataScienceHandbook.git
git clone https://github.com/edenbaus/DataSciencePi.git

cd DataSciencePi
sudo pip3 install -r requirements.txt
sudo pip3 install -r requirements2.txt

jupyter-notebook

pip3 list
sudo apt-get install -y colordiff
sudo apt-get install -y diffuse

https://howchoo.com/g/njy4zdm3mwy/how-to-run-a-raspberry-pi-cluster-with-docker-swarm

ssh-keygen -t rsa

ssh-copy-id pi@{Hostname}

docker swarm init --advertise-addr {IP Address}

sudo docker swarm join --token {Token ID} {IP Address}:2377

sudo docker service create --name viz --publish 8080:8080/tcp --constraint node.role==manager --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock alexellis2/visualizer-arm:latest

https://devopscook.com/docker-swarm-tutorial/

docker swarm init

docker swarm join-token manager
docker swarm join-token worker

docker node ls

docker swarm leave # from worker
docker node rm {Node ID} # from master

docker node [promote | demote]

docker node ps

docker service create httpd
docker service ls

docker service scale {Service Name}=4

docker service ps {Service Name}

sudo docker service create --name testhttpd --publish published=8081,target=80 httpd

https://www.donkeycar.com/

http://docs.donkeycar.com/

Install Dependencies

sudo apt-get install -y build-essential python3 python3-dev python3-virtualenv python3-numpy python3-picamera python3-pandas python3-rpi.gpio i2c-tools avahi-utils joystick libopenjp2-7-dev libtiff5-dev gfortran libatlas-base-dev libopenblas-dev libhdf5-serial-dev git

Install Optional OpenCV Dependencies

sudo apt-get install -y libilmbase-dev libopenexr-dev libgstreamer1.0-dev libjasper-dev libwebp-dev libatlas-base-dev libavcodec-dev libavformat-dev libswscale-dev libqtgui4 libqt4-test

Setup Virtual Env

cd ~
python3 -m virtualenv -p python3 env --system-site-packages
echo "source env/bin/activate" >> ~/.bashrc
source ~/.bashrc

Install Donkeycar Python Code

cd ~/Projects

git clone https://github.com/autorope/donkeycar
cd donkeycar
git checkout master
pip install -e .[pi]
pip install tensorflow==1.13.1

python -c "import tensorflow"

Install Optional OpenCV

pip install opencv-python
python -c "import cv2"

Create Donkeycar from Template

donkey createcar --path ~/mycar

Updating

donkey createcar --path ~/mycar --overwrite

Configure Options

nano ~/mycar/myconfig.py

Configure I2C PCA9685 (ensure I2C is enabled with sudo raspi-config)

sudo apt-get install i2c-tools
sudo i2cdetect -y 1

Calibration (for Latrax Teton 1/18)

donkey calibrate --channel 1

STEERING_RIGHT_PWM = 290
# Center = 375
STEERING_LEFT_PWM = 460

donkey calibrate --channel 0

THROTTLE_FORWARD_PWM = 420
# 390
THROTTLE_STOPPED_PWM = 370 (reverse pulse)
# 350
THROTTLE_REVERSE_PWM = 340

Calibration (for Traxxas Slash 1/16)

donkey calibrate --channel 1

STEERING_RIGHT_PWM = 490
# Center = 385
STEERING_LEFT_PWM = 280

donkey calibrate --channel 0

THROTTLE_FORWARD_PWM = 300
# 340
THROTTLE_STOPPED_PWM = 360
# 410
THROTTLE_REVERSE_PWM = 440

Get Driving

python manage.py drive

http://{hostname}:8887

$ sudo apt-get install -y firefox-esr
#!/bin/bash
DATE=$(date +"%Y%m%d-%H%M%S")
fswebcam -r 800x600 /home/pi/Pictures/fswebcam/$DATE.jpg

https://git-scm.com/docs

sudo apt-get install -y git

git config --global user.name "[name]"
git config --global user.email "[email address]"
git config --global color.ui auto

https://github.com/heldersepu/gmapcatcher

git clone https://github.com/heldersepu/GMapCatcher.git

#sudo apt-get install -y python # Python 2.7
#sudo apt-get install -y python-dev
#sudo apt-get install -y python-gtk2

#sudo apt-get build-dep python-imaging
#sudo apt-get install -y libjpeg62 libjpeg62-dev

#  -OR-

#pip install Pillow

./maps.py

Hide boot messages

http://pi.bek.no/hideBootMessages/

sudo nano /boot/cmdline.txt

Make these changes:

  • Replace “console=tty1” with “console=tty3” to redirect boot messages.
  • Add “logo.nologo” to hide Raspberry logo.
  • Add “quiet splash” for a non-text load screen.

https://github.com/kleinee/jns

cd ~/Projects
git clone https://github.com/kleinee/jns.git
cd jns/scripts

sudo ./inst_jns.sh

    -OR-

sudo ./prep.sh
sudo -u pi ./inst_stack.sh
sudo -u pi ./conf_jupyter.sh
./inst_lab_ext.sh

. /home/pi/.venv/jns/bin/activate
. /home/pi/.bashrc
jupyter notebook password
pip3 install fuzzywuzzy

sudo ./inst_tex.sh
sudo -u pi ./inst_pi_hardware.sh
sudo ./conf_service.sh
sudo ./inst_R-3.6.0.sh
sudo ./inst_opencv.sh

. /home/pi/.venv/jns/bin/activate
jupyter notebook
    -OR-
jupyter lab

    -OR-
./jupyter_start.sh

http://{hostname}:8889

sudo apt-get install -y libreoffice

To ununinstall:

sudo apt-get remove –purge libreoffice*
sudo apt-get clean
sudo apt-get autoremove

Note: asterisk is for metapackages

Lock Screen

https://thepihut.com/blogs/raspberry-pi-tutorials/how-to-lock-your-raspberry-pi-screen

sudo nano ~/.config/lxpanel/LXDE-pi/panels/panel
#sudo nano /etc/xdg/lxpanel/LXDE-pi/panels/panel

Add the "lock" item above logout:

Plugin {
  type=menu
  Config {
    padding=4
    image=start-here
    system {
    }
    separator {
    }
    item {
      image=system-run
      command=run
    }
    separator {
    }
    item {
      name=Lock
      image=gnome-lockscreen
      action=/usr/bin/dm-tool lock
    }
    item {
      image=system-shutdown
      command=logout
    }
  }
}
sudo reboot
sudo apt-get install -y mc

sudo nano /etc/mc/mc.ext
### Images ###

shell/.jpg
        Open=fbi %f
        View=fbi %f ALL_FORMATS

https://github.com/jacksonliam/mjpg-streamer

sudo apt-get install -y cmake libjpeg8-dev
sudo apt-get install -y gcc g++

cd ~/Projects
git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental/
make
sudo make install

export LD_LIBRARY_PATH=.
./mjpg_streamer -o "output_http.so -w ./www" -i "input_uvc.so"      # for USB webcam
./mjpg_streamer -o "output_http.so -w ./www" -i "input_raspicam.so" # for camera module
#!/bin/bash
cd ~/Projects/mjpg-streamer/mjpg-streamer-experimental/
export LD_LIBRARY_PATH=.
./mjpg_streamer -o "output_http.so -w ./www" -i "input_uvc.so"

Set up Motion

https://scottontechnology.com/raspberry-pi-webcam-server-using-motion/

https://motion-project.github.io/index.html

http://www.lavrsen.dk/foswiki/bin/view/Motion/RemoteControlHttp

sudo apt-get install -y motion

cd /etc/motion
sudo cp motion.conf motion.conf.bak

sudo nano /etc/motion/motion.conf

Adjust the following:

daemon on

rotate [0|90|180|270]
width 640
height 480
#framerate 10

threshold 30720 # = 640 * 480 * 0.1 [1 - 2147483647]
minimum_motion_frames [1-5]
#pre_capture 1
#post_capture 1
max_movie_time 300
output_pictures on
ffmpeg_video_codec mp4
timelapse_codec mpeg4

locate_motion_mode on
locate_motion_style [box|redbox|cross|redcross]

text_event %Y%m%d-%H%M%S
#exif_text %i%J/%K%L

#target_dir /var/lib/motion
target_dir {your_path}/motion

snapshot_interval 60 # lastsnap.jpg symlink

snapshot_filename %Y%m%d/%Y%m%d-%H%M%S-snapshot
picture_filename %Y%m%d/%Y%m%d-%H%M%S-%q
movie_filename %Y%m%d/%Y%m%d-%H%M%S

stream_localhost off
stream_auth_method 1
stream_authentication {username}:{password}
webcontrol_localhost off
webcontrol_authentication {username}:{password}
sudo nano /etc/default/motion

Adjust the following:

start_motion_daemon=yes

Disable Camera LED

sudo nano /boot/config.txt

Adjust the following:

disable_camera_led=1

Restart

#sudo chmod 777 /var/lib/motion

sudo service motion start
sudo service motion stop

http://{hostname}:8081

curl -s -o /dev/null http://{hostname}:8081/0/action/snapshot

Set up Apache

https://pimylifeup.com/raspberry-pi-apache/

sudo apt-get install -y apache2
cd /etc/apache2/
sudo nano /etc/apache2/apache2.conf
<Directory {your_path}/motion/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

<Directory {your_path}/data/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

<Directory {your_path}/logs/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

<Directory {your_path}/snapshot/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>
sudo systemctl reload apache2

cd /var/www/html
sudo ln -s {your_path}/motion motion

http://{ip_addr}/motion/

https://github.com/nodesource/distributions#debinstall

sudo -s

# Node.js v15.x
curl -sL https://deb.nodesource.com/setup_15.x | bash -
apt-get install -y nodejs

# Node.js v14.x
curl -sL https://deb.nodesource.com/setup_14.x | bash -
apt-get install -y nodejs

node --version
npm --version

For Raspian Lite

sudo apt-get install -y python3-pip
pip3 list

sudo apt-get install -y virtualenv

sudo apt-get install -y git

Prometheus

https://pimylifeup.com/raspberry-pi-prometheus/

https://github.com/prometheus/prometheus

Set up Prometheus service

sudo apt update
sudo apt full-upgrade

Check latest stable version at https://prometheus.io/download/

cd ~/Downloads
wget https://github.com/prometheus/prometheus/releases/download/v2.23.0/prometheus-2.23.0.linux-armv7.tar.gz
tar xfz prometheus-2.23.0.linux-armv7.tar.gz

mv prometheus-2.23.0.linux-armv7 ~/prometheus

sudo nano /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network-online.target

[Service]
User=pi
Restart=on-failure

ExecStart=/home/pi/prometheus/prometheus \
  --config.file=/home/pi/prometheus/prometheus.yml \
  --storage.tsdb.path=/home/pi/prometheus/data

[Install]
WantedBy=multi-user.target
sudo systemctl enable prometheus
sudo systemctl start prometheus
sudo systemctl status prometheus
hostname -I

http://{ip_addr}:9090

Set up device as a node

sudo mkdir /opt/node-exporter
cd /opt/node-exporter
sudo wget -O node-exporter.tar.gz https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-armv7.tar.gz
sudo tar -xvf node-exporter.tar.gz --strip-components=1
./node_exporter
sudo nano /etc/systemd/system/nodeexporter.service
[Unit]
Description=Prometheus Node Exporter
Documentation=https://prometheus.io/docs/guides/node-exporter/
After=network-online.target

[Service]
User=pi
Restart=on-failure

ExecStart=/opt/node-exporter/node_exporter

[Install]
WantedBy=multi-user.target
sudo systemctl enable nodeexporter
sudo systemctl start nodeexporter
sudo systemctl status nodeexporter

http://{ip_addr}:9100

Add node(s) to Prometheus

nano /home/pi/prometheus/prometheus.yml

  • job_name: 'node-01'

    static_configs:

    • targets: ['node-01:9100']

https://raspap.com/#quick-installer

wget -q https://git.io/voEUQ -O /tmp/raspap && bash /tmp/raspap

After the reboot at the end of the installation the wireless network will be configured as an access point as follows:

  • IP address: 10.3.141.1

    • Username: admin
    • Password: secret
  • DHCP range: 10.3.141.50 to 10.3.141.255

  • SSID: raspi-webgui

  • Password: ChangeMe

https://retropie.org.uk/docs/Manual-Installation/

sudo apt update && sudo apt upgrade

sudo apt install git lsb-release

cd
git clone --depth=1 https://github.com/RetroPie/RetroPie-Setup.git

cd RetroPie-Setup
chmod +x retropie_setup.sh
sudo ./retropie_setup.sh

Basic install

Manage packages > Manage optional packages > kodi > Install from pre-compiled binary

Manage packages > Manage optional packages > vice > Install from pre-compiled binary

Configuration / tools > samba

emulationstation

MAME High Score locations

/opt/retropie/configs/mame-mame4all/hi
/home/pi/RetroPie/roms/arcade/mame2003/hi
#!/bin/bash
while read HOST ; do ssh -n $HOST "hostname && sudo apt-get update && sudo apt-get upgrade -y" ; done < $1
#!/bin/bash
while read HOST ; do ssh -n $HOST "./boinc_stats.sh" ; done < $1
#!/bin/bash
while read HOST ; do ssh -n $HOST "boinccmd --project http://einstein.phys.uwm.edu update" ; done < $1
#!/bin/bash
while read HOST ; do ssh -n $HOST "sudo shutdown now" ; done < $1

https://www.raspberrypi.org/magpi/samba-file-server/

sudo apt-get install -y samba samba-common-bin
sudo mkdir -m 1777 /home/pi/Share
sudo nano /etc/samba/smb.conf

Add the following to the end of smb.conf

[share]
comment = Pi shared folder
path = /home/pi/Share
valid users = pi
browseable = no
writeable = yes
only guest = no
create mask = 0660
directory mask = 0771
public = yes
guest ok = yes

[music]
comment = music
path = "/home/pi/Music"
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = pi

[videos]
comment = videos
path = "/home/pi/Videos"
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = pi

# for RetroPie

[roms]
comment = roms
path = "/home/pi/RetroPie/roms"
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = pi

[bios]
comment = bios
path = "/home/pi/RetroPie/BIOS"
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = pi

[configs]
comment = configs
path = "/opt/retropie/configs"
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = pi

[splashscreens]
comment = splashscreens
path = "/home/pi/RetroPie/splashscreens"
writeable = yes
guest ok = yes
create mask = 0644
directory mask = 0755
force user = pi
sudo smbpasswd -a pi
sudo /etc/init.d/samba restart
sudo /etc/init.d/smbd restart # Buster

In Windows Explorer, go to:

\\{hostname}\share
#!/bin/bash
xscreensaver-command -lock
sudo apt-get install -y xscreensaver
#!/bin/bash
scrot --select ~/Pictures/scrot/'%Y%m%d-%H%M%S_$wx$h.png'
import os
#user = os.environ['USER']
#import time
import datetime
import sys
from sense_hat import SenseHat
sh = SenseHat()
sh.low_light = True
sh.set_rotation(180)
# Define the colours
red = (255, 0, 0)
yellow = (255, 255, 0)
green = (0, 255, 0)
seti = '/home/pi/boinc_seti.txt'
while True:
now = datetime.datetime.now()
if os.path.isfile(seti):
file = open(seti, 'r')
try:
seti_total_credit = file.readline()
except:
seti_total_credit = 0
finally:
file.close()
else:
seti_total_credit = 0
# Take readings from all three sensors
t = sh.get_temperature()
p = sh.get_pressure()
h = sh.get_humidity()
# Round the values to one decimal place
t = round(t, 1)
p = round(float(p) / 10, 1) # convert millibars to kPa
h = round(h, 1)
try:
stc = str(round(float(seti_total_credit), 2))
except:
stc = "N/A"
# Create the message
message = " S: " + stc
message += " T: " + str(t) + "C"
message += " P: " + str(p) + "kPa"
message += " H: " + str(h) + "%"
if t < 50:
fg = green
elif t >=50 and t < 70:
fg = yellow
else:
fg = red
print (now.strftime('%Y%m%d-%H%M%S:') + message)
# Display the scrolling message
hhmm = now.strftime('%H:%M')
sh.show_message(hhmm + message, scroll_speed=0.2, text_colour=fg)
#!/bin/bash
python -u billboard.py >> billboard.log 2>> billboard.err &
from sense_hat import SenseHat
sh = SenseHat()
sh.clear()
from sense_hat import SenseHat
import time
sh = SenseHat()
sh.low_light = True
sh.set_rotation(180)
# Basic 8-color palette
W = (255, 255, 255) # White
R = (255, 0, 0) # Red
G = (0, 255, 0) # Green
B = (0, 0, 255) # Blue
C = (0, 255, 255) # Cyan
M = (255, 0, 255) # Magenta
Y = (255, 255, 0) # Yellow
K = (0, 0, 0) # Key = Black
# Raspberry Pi logo
def raspi_logo():
logo = [
K, G, G, K, K, G, G, K,
K, K, G, G, G, G, K, K,
K, K, R, R, R, R, K, K,
K, R, R, R, R, R, R, K,
R, R, R, R, R, R, R, R,
R, R, R, R, R, R, R, R,
K, R, R, R, R, R, R, K,
K, K, R, R, R, R, K, K
]
return logo
# Color bars
def col_bars():
logo = [
W, W, W, W, W, W, W, W,
K, K, K, K, K, K, K, K,
R, R, R, R, R, R, R, R,
G, G, G, G, G, G, G, G,
B, B, B, B, B, B, B, B,
C, C, C, C, C, C, C, C,
M, M, M, M, M, M, M, M,
Y, Y, Y, Y, Y, Y, Y, Y
]
return logo
images = [raspi_logo, col_bars]
count = 0
while True:
sh.set_pixels(images[count % len(images)]())
time.sleep(5)
count += 1
# ==================================================================
# Raspberry Pi Sense HAT Client for Azure IoT Central
# ==================================================================
import datetime, time
import json
import random
import iotc
from iotc import IOTConnectType, IOTLogLevel
from sense_hat import SenseHat
sense = SenseHat()
sense.low_light = True
sense.set_rotation(180)
sense.clear()
deviceId = ""
scopeId = ""
deviceKey = ""
iotc = iotc.Device(scopeId, deviceKey, deviceId, IOTConnectType.IOTC_CONNECT_SYMM_KEY)
iotc.setLogLevel(IOTLogLevel.IOTC_LOGGING_API_ONLY)
# Basic color palette
W = (255, 255, 255) # White
R = (255, 0, 0) # Red
G = (0, 255, 0) # Green
B = (0, 0, 255) # Blue
C = (0, 255, 255) # Cyan
M = (255, 0, 255) # Magenta
Y = (255, 255, 0) # Yellow
K = (0, 0, 0) # Black
# Pac-Man Ghosts
def blinky(): # Shadow
logo = [
K, K, K, R, R, K, K, K,
K, R, R, R, R, R, R, K,
R, W, W, R, W, W, R, R,
R, W, K, R, W, K, R, R,
R, R, R, R, R, R, R, R,
R, R, R, R, R, R, R, R,
R, R, R, R, R, R, R, R,
K, R, K, R, K, R, K, R
]
return logo
def pinky(): # Speedy
logo = [
K, K, K, M, M, K, K, K,
K, M, M, M, M, M, M, K,
M, W, W, M, W, W, M, M,
M, W, K, M, W, K, M, M,
M, M, M, M, M, M, M, M,
M, M, M, M, M, M, M, M,
M, M, M, M, M, M, M, M,
K, M, K, M, K, M, K, M
]
return logo
def inky(): # Bashful
logo = [
K, K, K, C, C, K, K, K,
K, C, C, C, C, C, C, K,
C, W, W, C, W, W, C, C,
C, W, K, C, W, K, C, C,
C, C, C, C, C, C, C, C,
C, C, C, C, C, C, C, C,
C, C, C, C, C, C, C, C,
K, C, K, C, K, C, K, C
]
return logo
def clyde(): # Pokey
logo = [
K, K, K, Y, Y, K, K, K,
K, Y, Y, Y, Y, Y, Y, K,
Y, W, W, Y, W, W, Y, Y,
Y, W, K, Y, W, K, Y, Y,
Y, Y, Y, Y, Y, Y, Y, Y,
Y, Y, Y, Y, Y, Y, Y, Y,
Y, Y, Y, Y, Y, Y, Y, Y,
K, Y, K, Y, K, Y, K, Y
]
return logo
ghosts = [blinky, pinky, inky, clyde]
gCanSend = False
gCounter = 0
def onconnect(info):
global gCanSend
print("- [onconnect] => status:" + str(info.getStatusCode()))
if info.getStatusCode() == 0:
if iotc.isConnected():
gCanSend = True
def onmessagesent(info):
print("\t- [onmessagesent] => " + str(info.getPayload()))
def oncommand(info):
print("- [oncommand] => " + info.getTag() + " => " + str(info.getPayload()))
def onsettingsupdated(info):
print("- [onsettingsupdated] => " + info.getTag() + " => " + info.getPayload())
iotc.on("ConnectionStatus", onconnect)
iotc.on("MessageSent", onmessagesent)
iotc.on("Command", oncommand)
iotc.on("SettingsUpdated", onsettingsupdated)
iotc.connect()
while iotc.isConnected():
iotc.doNext() # do the async work needed to be done for MQTT
if gCanSend == True:
if gCounter % 20 == 0:
gCounter = 0
data = {}
dt = datetime.datetime
#data['timestamp'] = dt.now().strftime("%Y-%m-%dT%H:%M:%S%z")
data['timestamp'] = dt.now().replace(microsecond=0).isoformat()
data['timestamp_utc'] = dt.utcnow().replace(microsecond=0).isoformat()
# ------------------------------------------------------
# Environmental
# ------------------------------------------------------
temperature = sense.get_temperature()
data['temperature'] = temperature # Celsius
temperature_humidity = sense.get_temperature_from_humidity()
data['temperature_humidity'] = temperature_humidity
temperature_pressure = sense.get_temperature_from_pressure()
data['temperature_pressure'] = temperature_pressure
pressure = sense.get_pressure()
data['pressure'] = pressure # Millbars
humidity = sense.get_humidity()
data['humidity'] = humidity
# ------------------------------------------------------
# Gyroscope
# ------------------------------------------------------
sense.set_imu_config(False, True, False) # enable gyroscope only
gyroscope = sense.get_gyroscope()
data['gyroscope'] = gyroscope
gyroscope_raw = sense.get_gyroscope_raw()
data['gyroscope_raw'] = gyroscope_raw
orientation_rad = sense.get_orientation_radians()
data['orientation_rad'] = orientation_rad
orientation_deg = sense.get_orientation_degrees()
data['orientation_deg'] = orientation_deg
# ------------------------------------------------------
# Magnetometer (compass)
# ------------------------------------------------------
sense.set_imu_config(True, False, False) # enable compass only
compass_north = sense.get_compass()
data['compass_north'] = compass_north
compass_raw = sense.get_compass_raw()
data['compass_raw'] = compass_raw
# ------------------------------------------------------
# Accelerometer
# ------------------------------------------------------
sense.set_imu_config(False, False, True) # enable accelerometer only
accelerometer = sense.get_accelerometer()
data['accelerometer'] = accelerometer
accelerometer_raw = sense.get_accelerometer_raw()
data['accelerometer_raw'] = accelerometer_raw
# ------------------------------------------------------
#jsonStr = json.dumps(data, indent = 2, sort_keys = True)
jsonStr = json.dumps(data, sort_keys = True)
print("Sending telemetry...")
iotc.sendTelemetry(jsonStr)
# Show a random ghost on the Sense HAT LED screen
sense.set_pixels(ghosts[random.randint(0, len(ghosts) - 1)]())
time.sleep(3)
sense.clear()
gCounter += 1
# KITT-style light chaser for LEDs
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT) # red
GPIO.setup(16, GPIO.OUT) # orange
GPIO.setup(18, GPIO.OUT) # yellow
GPIO.setup(22, GPIO.OUT) # green
for i in range(0, 250, 1):
GPIO.output(12, GPIO.HIGH) # red on
time.sleep(.20)
GPIO.output(12, GPIO.LOW) # red off
GPIO.output(16, GPIO.HIGH) # orange on
time.sleep(.15)
GPIO.output(16, GPIO.LOW) # orange off
GPIO.output(18, GPIO.HIGH) # yellow on
time.sleep(.15)
GPIO.output(18, GPIO.LOW) # yellow off
GPIO.output(22, GPIO.HIGH) # green on
time.sleep(.20)
GPIO.output(22, GPIO.LOW) # green off
GPIO.output(18, GPIO.HIGH) # yellow on
time.sleep(.15)
GPIO.output(18, GPIO.LOW) # yellow off
GPIO.output(16, GPIO.HIGH) # orange on
time.sleep(.15)
GPIO.output(16, GPIO.LOW) # orange off
GPIO.cleanup()

https://pythonhosted.org/sense-hat/api/#sense-hat-api-reference

https://tutorials.technology/tutorials/61-Create-an-application-with-websockets-and-flask.html https://github.com/tutorialstechnology/flask_websockets

https://flask-socketio.readthedocs.io/en/latest/ https://github.com/miguelgrinberg/Flask-SocketIO

Install Flask and SocketIO packages:

cd ~/Projects
git clone https://github.com/miguelgrinberg/Flask-SocketIO.git
cd example
pip install -r requirements.txt
python app.py

http://{hostname}:5000

pip install flask-socketio

Run server script:

./sense-hat-server.sh
import datetime, time
import json
import random
from sense_hat import SenseHat
sense = SenseHat()
sense.low_light = True
sense.set_rotation(180)
sense.clear()
# Basic color palette
W = (255, 255, 255) # White
R = (255, 0, 0) # Red
G = (0, 255, 0) # Green
B = (0, 0, 255) # Blue
C = (0, 255, 255) # Cyan
M = (255, 0, 255) # Magenta
Y = (255, 255, 0) # Yellow
K = (0, 0, 0) # Black
# Pac-Man Ghosts
def blinky(): # Shadow
logo = [
K, K, K, R, R, K, K, K,
K, R, R, R, R, R, R, K,
R, W, W, R, W, W, R, R,
R, W, K, R, W, K, R, R,
R, R, R, R, R, R, R, R,
R, R, R, R, R, R, R, R,
R, R, R, R, R, R, R, R,
K, R, K, R, K, R, K, R
]
return logo
def pinky(): # Speedy
logo = [
K, K, K, M, M, K, K, K,
K, M, M, M, M, M, M, K,
M, W, W, M, W, W, M, M,
M, W, K, M, W, K, M, M,
M, M, M, M, M, M, M, M,
M, M, M, M, M, M, M, M,
M, M, M, M, M, M, M, M,
K, M, K, M, K, M, K, M
]
return logo
def inky(): # Bashful
logo = [
K, K, K, C, C, K, K, K,
K, C, C, C, C, C, C, K,
C, W, W, C, W, W, C, C,
C, W, K, C, W, K, C, C,
C, C, C, C, C, C, C, C,
C, C, C, C, C, C, C, C,
C, C, C, C, C, C, C, C,
K, C, K, C, K, C, K, C
]
return logo
def clyde(): # Pokey
logo = [
K, K, K, Y, Y, K, K, K,
K, Y, Y, Y, Y, Y, Y, K,
Y, W, W, Y, W, W, Y, Y,
Y, W, K, Y, W, K, Y, Y,
Y, Y, Y, Y, Y, Y, Y, Y,
Y, Y, Y, Y, Y, Y, Y, Y,
Y, Y, Y, Y, Y, Y, Y, Y,
K, Y, K, Y, K, Y, K, Y
]
return logo
ghosts = [blinky, pinky, inky, clyde]
from flask import Flask, request, Response
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
data = {}
now = datetime.datetime.now()
data['timestamp'] = now.isoformat() #now.strftime('%Y%m%d-%H%M%S:')
data['user-agent'] = request.headers.get('User-Agent')
# ------------------------------------------------------------------------
# Environmental
# ------------------------------------------------------------------------
temperature = sense.get_temperature()
data['temperature'] = temperature # celsius
temperature_humidity = sense.get_temperature_from_humidity()
data['temperature_humidity'] = temperature_humidity
temperature_pressure = sense.get_temperature_from_pressure()
data['temperature_pressure'] = temperature_pressure
pressure = sense.get_pressure()
data['pressure'] = pressure # millbars
humidity = sense.get_humidity()
data['humidity'] = humidity
# ------------------------------------------------------------------------
# Gyroscope
# ------------------------------------------------------------------------
sense.set_imu_config(False, True, False) # enable gyroscope only
gyroscope = sense.get_gyroscope()
data['gyroscope'] = gyroscope
gyroscope_raw = sense.get_gyroscope_raw()
data['gyroscope_raw'] = gyroscope_raw
orientation_rad = sense.get_orientation_radians()
data['orientation_rad'] = orientation_rad
orientation_deg = sense.get_orientation_degrees()
data['orientation_deg'] = orientation_deg
# ------------------------------------------------------------------------
# Magnetometer (compass)
# ------------------------------------------------------------------------
sense.set_imu_config(True, False, False) # enable compass only
compass_north = sense.get_compass()
data['compass_north'] = compass_north
compass_raw = sense.get_compass_raw()
data['compass_raw'] = compass_raw
# ------------------------------------------------------------------------
# Accelerometer
# ------------------------------------------------------------------------
sense.set_imu_config(False, False, True) # enable accelerometer only
accelerometer = sense.get_accelerometer()
data['accelerometer'] = accelerometer
accelerometer_raw = sense.get_accelerometer_raw()
data['accelerometer_raw'] = accelerometer_raw
# ------------------------------------------------------------------------
#
# ------------------------------------------------------------------------
jsonStr = json.dumps(data, indent=2, sort_keys=True)
sense.set_pixels(ghosts[random.randint(0, len(ghosts) - 1)]())
time.sleep(1)
sense.clear()
return Response(jsonStr, mimetype='application/json')
if __name__ == '__main__':
app.run(debug=True)
export FLASK_APP=sense-hat-server.py
flask run --host=0.0.0.0 --port=5001

https://projects.raspberrypi.org/en/projects/getting-started-with-the-sense-hat/

https://pythonhosted.org/sense-hat/

https://trinket.io/sense-hat

sudo apt-get install -y sense-hat

OSError: Cannot detect RPi-Sense FB device

Solution: Force the Raspberry Pi that a Sense HAT is connected

sudo nano /boot/config.txt

Add this line to the end:

dtoverlay=rpi-sense

Debugging: Probe addresses on a bus and report whether any devices are present:

sudo apt-get install -y i2c-tools

sudo i2cdetect -y 1

Output:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- UU -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- 5c -- -- 5f
60: -- -- -- -- -- -- -- -- -- -- 6a -- -- -- -- --
70: -- -- -- -- -- -- -- --

Check swapfile size

swapon -s
free -h

	Filename				Type		Size	Used	Priority
	/var/swap                              	file    	102396	0	-2

Increase swapfile size

sudo sed -i -e 's/CONF_SWAPSIZE=100/CONF_SWAPSIZE=1024/' /etc/dphys-swapfile
sudo /etc/init.d/dphys-swapfile restart

    -OR-

sudo dphys-swapfile swapoff
sudo nano /etc/dphys-swapfile

  CONF_SWAPSIZE=1024

sudo dphys-swapfile swapon

https://www.tensorflow.org/lite/guide/build_rpi

sudo apt-get install -y build-essential

git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow
./tensorflow/lite/tools/make/download_dependencies.sh
./tensorflow/lite/tools/make/build_rpi_lib.sh

ls -l tensorflow/lite/tools/make/gen/rpi_armv7l/lib/

  -rw-r--r-- 1 pi pi 3989170 Jun 18 20:48 libtensorflow-lite.a
#!/bin/bash
top -p `pgrep -d "," boinc\|\einstein\|\rosetta\|\setiathome\|\dockerd\|\httpd`

https://elinux.org/RPI_vcgencmd_usage

https://www.raspberrypi.org/documentation/raspbian/applications/vcgencmd.md

vcgencmd commands

commands="vcos, ap_output_control, ap_output_post_processing, vchi_test_init, vchi_test_exit, vctest_memmap, vctest_start, vctest_stop, vctest_set, vctest_get, pm_set_policy, pm_get_status, pm_show_stats, pm_start_logging, pm_stop_logging, version, commands, set_vll_dir, set_backlight, set_logging, get_lcd_info, arbiter, cache_flush, otp_dump, test_result, codec_enabled, get_camera, get_mem, measure_clock, measure_volts, scaling_kernel, scaling_sharpness, get_hvs_asserts, get_throttled, measure_temp, get_config, hdmi_ntsc_freqs, hdmi_adjust_clock, hdmi_status_show, hvs_update_fields, pwm_speedup, force_audio, hdmi_stream_channels, hdmi_channel_map, display_power, read_ring_osc, memtest, dispmanx_list, get_rsts, schmoo, render_bar, disk_notify, inuse_notify, sus_suspend, sus_status, sus_is_enabled, sus_stop_test_thread, egl_platform_switch, mem_validate, mem_oom, mem_reloc_stats, hdmi_cvt, hdmi_timings, file"

vcgencmd measure_temp

temp=44.9'C

vcgencmd measure_temp | egrep -o '[0-9]*\.[0-9]*'

44.9

vcgencmd vcos version

Sep 24 2019 17:37:19 Copyright (c) 2011 Broadcom version 6820edeee4ef3891b95fc01cf02a7abd7ca52f17 (clean) host buildbot

vcgencmd get_camera

supported=0 detected=0

vcgencmd get_throttled

throttled=0x80000

vcgencmd measure_clock arm
watch -n 1 vcgencmd measure_clock arm

frequency(45)=600000000

for src in arm core h264 isp v3d uart pwm emmc pixel vec hdmi dpi ; do \
echo -e "$src:\t$(vcgencmd measure_clock $src)" ; \
done
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
vcgencmd measure_volts core

volt=1.2000V

for id in core sdram_c sdram_i sdram_p ; do \
echo -e "$id:\t$(vcgencmd measure_volts $id)" ; \
done

Setting GPU memory:

Total RAM gpu_mem (recommended maximum)
256MB 128
512MB 384
1GB or greater 512 (256 on the Pi4)
vcgencmd get_mem arm

arm=948M

vcgencmd get_mem gpu

gpu=76M

vcgencmd codec_enabled H264

H264=enabled

for codec in H264 MPG2 WVC1 MPG4 MJPG WMV9 ; do \
echo -e "$codec:\t$(vcgencmd codec_enabled $codec)" ; \
done

To increase screen resolution for headless mode:

  • Preferences > Rapsberry Pi Configuration
  • In the "System" tab, click "Set Resolution" and change from "Default 720x480" to "DMT mode 85 1280x720 60Hz 16:9" then click "OK"
  • In the "Interfaces" tab, click "Enable" beside VNC then click "OK"
  • Click "OK" and restart
import pynmea2
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 19200, timeout=1)
print (ser)
try:
ser.write("AT+CGNSPWR=1\n")
ser.write("AT+CGNSSEQ=\"RMC\"\n")
ser.write("AT+CGNSINF\n")
ser.write("AT+CGNSTST=1\n")
time.sleep(3)
ser.write("AT+CGNSTST=0\n")
lines = ser.readlines()
print len(lines)
for line in reversed(lines):
#line = line.replace('\n', '')
if line.startswith('$GNRMC'):
print (line)
gnrmc = pynmea2.parse(line)
print ('datetime: ' + str(gnrmc.datetime))
print ('datestamp: ' + str(gnrmc.datestamp))
print ('timestamp: ' + str(gnrmc.timestamp))
print ('latitude: ' + str(gnrmc.latitude))
print ('longitude: ' + str(gnrmc.longitude))
print ('spd_over_grnd: ' + str(gnrmc.spd_over_grnd))
print ('true_course: ' + str(gnrmc.true_course))
break
ser.close()
except serial.SerialException as ex:
print (ex)
#!/usr/bin/python
# https://www.waveshare.com/gsm-gprs-gnss-hat.htm
# https://www.waveshare.com/wiki/GSM/GPRS/GNSS_HAT
import serial
import time
#ser = serial.Serial("/dev/ttyS0", 115200)
ser = serial.Serial("/dev/ttyUSB0", 115200)
W_buff = ["AT+CGNSPWR=1\r\n", "AT+CGNSSEQ=\"RMC\"\r\n", "AT+CGNSINF\r\n", "AT+CGNSURC=2\r\n", "AT+CGNSTST=1\r\n"]
ser.write(W_buff[0])
ser.flushInput()
data = ""
num = 0
try:
while True:
#print (ser.inWaiting())
while ser.inWaiting() > 0:
data += ser.read(ser.inWaiting())
if data != "":
print (data)
if num < 4: # the string have ok
print (num)
time.sleep(0.5)
ser.write(W_buff[num + 1])
num = num + 1
if num == 4:
time.sleep(0.5)
ser.write(W_buff[4])
data = ""
except keyboardInterrupt:
if ser != None:
ser.close()
# https://github.com/Knio/pynmea2
# https://www.tekmx.com/blog/convert-nmea-latitude-longitude-to-decimal
# pip install pynmea2
import pynmea2
line = "$GNRMC, ..."
gnrmc = pynmea2.parse(line)
print (gnrmc)
print ">>>"
print (str(gnrmc.datetime), str(gnrmc.datestamp), str(gnrmc.timestamp), gnrmc.latitude, gnrmc.longitude, gnrmc.spd_over_grnd, gnrmc.true_course)
ls -l /dev/ttyUSB*
sudo cat /dev/ttyUSB0
tail -f < /dev/ttyUSB0
screen /dev/ttyUSB0 115200
dd if=/dev/ttyUSB0
sudo lsusb
sudo apt-get install -y minicom
minicom --baudrate 115200 --device /dev/ttyUSB0
echo 'AT+CGNSSEQ="RMC"' > /dev/ttyUSB0
echo 'AT+CGNSINF' > /dev/ttyUSB0
echo 'AT+CGNSURC=2' > /dev/ttyUSB0
echo 'AT+CGNSTST=1' > /dev/ttyUSB0
echo 'AT+CGNSTST=0' > /dev/ttyUSB0

https://pypi.org/project/waveshare-rpi/

#!/bin/bash
function getIPAddress() {
local ip_route
ip_route=$(ip -4 route get 8.8.8.8 2>/dev/null)
if [[ -z "$ip_route" ]]; then
ip_route=$(ip -6 route get 2001:4860:4860::8888 2>/dev/null)
fi
[[ -n "$ip_route" ]] && grep -oP "src \K[^\s]+" <<< "$ip_route"
}
function welcome() {
local upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)"
local secs=$((upSeconds%60))
local mins=$((upSeconds/60%60))
local hours=$((upSeconds/3600%24))
local days=$((upSeconds/86400))
local UPTIME=$(printf "%d days, %02dh%02dm%02ds" "$days" "$hours" "$mins" "$secs")
# calculate rough CPU and GPU temperatures:
local cpuTempC
local cpuTempF
local gpuTempC
local gpuTempF
if [[ -f "/sys/class/thermal/thermal_zone0/temp" ]]; then
cpuTempC=$(($(cat /sys/class/thermal/thermal_zone0/temp)/1000)) && cpuTempF=$((cpuTempC*9/5+32))
fi
if [[ -f "/opt/vc/bin/vcgencmd" ]]; then
if gpuTempC=$(/opt/vc/bin/vcgencmd measure_temp); then
gpuTempC=${gpuTempC:5:2}
gpuTempF=$((gpuTempC*9/5+32))
else
gpuTempC=""
fi
fi
local df_out=()
local line
while read line; do
df_out+=("$line")
done < <(df -h /)
local rst="$(tput sgr0)"
local fgblk="${rst}$(tput setaf 0)" # Black - Regular
local fgred="${rst}$(tput setaf 1)" # Red
local fggrn="${rst}$(tput setaf 2)" # Green
local fgylw="${rst}$(tput setaf 3)" # Yellow
local fgblu="${rst}$(tput setaf 4)" # Blue
local fgpur="${rst}$(tput setaf 5)" # Purple
local fgcyn="${rst}$(tput setaf 6)" # Cyan
local fgwht="${rst}$(tput setaf 7)" # White
local bld="$(tput bold)"
local bfgblk="${bld}$(tput setaf 0)"
local bfgred="${bld}$(tput setaf 1)"
local bfggrn="${bld}$(tput setaf 2)"
local bfgylw="${bld}$(tput setaf 3)"
local bfgblu="${bld}$(tput setaf 4)"
local bfgpur="${bld}$(tput setaf 5)"
local bfgcyn="${bld}$(tput setaf 6)"
local bfgwht="${bld}$(tput setaf 7)"
local logo=(
""
""
""
""
""
""
""
""
""
""
""
)
local out
local i
for i in "${!logo[@]}"; do
#out+=" ${logo[$i]} "
case "$i" in
0)
out+="${fgred}$(date +"%A, %e %B %Y, %X")"
;;
1)
out+="${fgred}$(uname -srmo)"
;;
3)
out+="${fgcyn}${df_out[0]}"
;;
4)
out+="${fgwht}${df_out[1]}"
;;
5)
out+="${fgcyn}Uptime...........: ${fgwht}${UPTIME}"
;;
6)
out+="${fgcyn}Memory...........: ${fgwht}$(grep MemFree /proc/meminfo | awk {'print $2'})kB (Free) / $(grep MemTotal /proc/meminfo | awk {'print $2'})kB (Total)"
;;
7)
out+="${fgcyn}Running Processes: ${fgwht}$(ps ax | wc -l | tr -d " ")"
;;
8)
out+="${fgcyn}IP Address.......: ${fgwht}$(getIPAddress)"
;;
9)
out+="${fgcyn}Temperature......: ${fgwht}CPU: ${cpuTempC}°C/${cpuTempF}°F GPU: ${gpuTempC}°C/${gpuTempF}°F"
;;
10)
out+="${fgcyn}Shells...........: ${fgwht}emulationstation | kodi"
;;
esac
out+="${rst}\n"
done
echo -e "\n$out"
}
welcome

https://learn.sparkfun.com/tutorials/setting-up-a-raspberry-pi-3-as-an-access-point

https://www.raspberrypi.org/documentation/configuration/wireless/access-point.md

https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md

Set up Wifi Access Point

sudo apt-get -y install hostapd dnsmasq

sudo nano /etc/dhcpcd.conf

Append the following:

denyinterfaces wlan0
sudo nano /etc/network/interfaces

Append the following:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet static
    address 192.168.5.1
    netmask 255.255.255.0
    network 192.168.5.0
    broadcast 192.168.5.255
sudo nano /etc/hostapd/hostapd.conf

Append the following:

interface=wlan0
driver=nl80211
ssid={YOUR_SSID}
hw_mode=g
channel=6
ieee80211n=1
wmm_enabled=1
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_passphrase={YOUR_PASSWORD_MUST_BE_LONGER_THAN_7_CHARS}
rsn_pairwise=CCMP
sudo nano /etc/default/hostapd

Find the line #DAEMON_CONF="" and replace it with:

DAEMON_CONF="/etc/hostapd/hostapd.conf"
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.bak
sudo nano /etc/dnsmasq.conf

Add the following:

interface=wlan0 
listen-address=192.168.5.1
bind-interfaces 
server=8.8.8.8
domain-needed
bogus-priv
dhcp-range=192.168.5.100,192.168.5.200,24h

Enable Packet Forwarding

sudo nano /etc/sysctl.conf

Uncomment the following line:

net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT

sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

sudo nano /etc/rc.local

Just above the exit 0 line, add the following:

iptables-restore < /etc/iptables.ipv4.nat 

Restart

sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapd

sudo reboot

Troubleshooting

If you get this error ("Job for hostapd.service failed"), check the password length -- it must be longer than 7 chars.

https://pimylifeup.com/xbox-controllers-raspberry-pi/

sudo apt-get install xboxdrv
echo 'options bluetooth disable_ertm=Y' | sudo tee -a /etc/modprobe.d/bluetooth.conf

sudo reboot

Turn on Bluetooth pairing on controller

sudo bluetoothctl

    agent on
    default-agent

    scan on
        [NEW] Device {MAC_ADDRESS} Xbox Wireless Controller

    connect {MAC_ADDRESS}
    trust {MAC_ADDRESS}

    quit

sudo apt-get install joystick
sudo jstest /dev/input/js0
sudo xboxdrv --detach-kernel-driver --silent --mouse
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment