diff --git a/.gitignore b/.gitignore
index f2cff743..acb007e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,3 +45,8 @@ pi_zero2
image_file.bin
logt.txt
telem.txt.bk
+failure_mode.txt
+sim_mode_auto
+direwolf-pacsatsim-tmp.conf
+groundstation/direwolf-pacsat-tmp.conf
+tlm.bin
diff --git a/Makefile b/Makefile
index bf295216..a2c69fcb 100644
--- a/Makefile
+++ b/Makefile
@@ -41,9 +41,10 @@ cubesatsim: libax5043.a
cubesatsim: afsk/ax25.o
cubesatsim: afsk/ax5043.o
cubesatsim: TelemEncoding.o
+cubesatsim: sensor_extension.o
cubesatsim: main.o
cubesatsim: codecAO40.o
- gcc -std=gnu99 $(DEBUG_BEHAVIOR) -o cubesatsim -Wall -Wextra -L./ afsk/ax25.o afsk/ax5043.o TelemEncoding.o codecAO40.o main.o -lwiringPi -lax5043 -lm
+ gcc -std=gnu99 $(DEBUG_BEHAVIOR) -o cubesatsim -Wall -Wextra -L./ afsk/ax25.o afsk/ax5043.o TelemEncoding.o sensor_extension.o codecAO40.o main.o -lwiringPi -lax5043 -lm
telem: telem.o
gcc -std=gnu99 $(DEBUG_BEHAVIOR) -o telem -Wall -Wextra -L./ telem.o -lwiringPi
@@ -52,6 +53,9 @@ TelemEncoding.o: TelemEncoding.c
TelemEncoding.o: TelemEncoding.h
gcc -std=gnu99 $(DEBUG_BEHAVIOR) -Wall -Wextra -c TelemEncoding.c
+sensor_extension.o: sensor_extension.c
+ gcc -std=gnu99 $(DEBUG_BEHAVIOR) -Wall -Wextra -c sensor_extension.c
+
codecAO40.o: codecAO40.c
codecAO40.o: codecAO40.h
gcc -std=gnu99 $(DEBUG_BEHAVIOR) -Wall -Wextra -c codecAO40.c
diff --git a/README.md b/README.md
index 3b13fdc3..608132c6 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ The CubeSat Simulator https://github.com/alanbjohnston/CubeSatSim/wiki is a low
The three custom PCBs are the Main, Battery and Solar boards. Information including schematics and gerbers is in https://CubeSatSim.org/hardware
-
+
For information about the AMSAT STEM education program based on the CubeSatSim, see https://CubeSatSim.org/EducatorsGuide
@@ -18,9 +18,9 @@ See the Wiki Software Install page for more details: https://github.com/alanbjoh
There are two ways to get the CubeSatSim(TM) software for your Pi.
-One option is to download the disk image file and write it to a 16GB micro SD card or larger. The image is based on Raspberry Pi OS (Rasbian) Lite, dated December 2020. All software is installed, you just need to login to change your password and set your amateur radio callsign if you have one. You can run the ./update.sh script to update all packages and update and compile the latest CubeSatSim software.
+One option is to download the disk image file and write it to a 16GB micro SD card or larger. The image is based on Raspberry Pi OS (Bulleye) Lite. All software is installed, you just need to login to change your password and set your amateur radio callsign if you have one. You can run the ./update.sh script to update all packages and update and compile the latest CubeSatSim software.
-The other option is to start with a Raspberry Pi OS (Rasbian) image (Bullseye or Buster works) and run the installation script ./install.sh which will install and compile all the related software. This includes the following packages:
+The other option is to start with a Raspberry Pi OS (Rasbian) image (only Bullseye works, Bookworm or Trixie are not compatible) and run the installation script ./install.sh which will install and compile all the related software. This includes the following packages:
- wiringpi
- git
- libasound2-dev
@@ -36,11 +36,23 @@ See the Wiki Software Install page for details: [https://github.com/alanbjohnsto
## Installation Script Option Steps
-CubeSatSim runs on the Bullseye or Buster version of Raspberry Pi OS (Desktop or Lite), although a Pi Zero or Pi Zero W should only run Lite. Your Pi will need to have internet access to update settings and install packages.
+CubeSatSim runs on the Bullseye version of Raspberry Pi OS (Desktop or Lite), although a Pi Zero or Pi Zero W should only run Lite. Your Pi will need to have internet access to update settings and install packages.
+
+For the status of our efforts to get the code running on Bookworm, see https://github.com/alanbjohnston/CubeSatSim/discussions/389
+
+Here is a Bullseye Pi OS image that works: https://downloads.raspberrypi.org/raspios_full_armhf/images/raspios_full_armhf-2023-05-03/ Here is the file download link: https://downloads.raspberrypi.org/raspios_full_armhf/images/raspios_full_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-full.img.xz
+
+You can use this with the Raspberry Pi Imager, but under `OS` you need to choose the `Use Custom` option at the very bottom of the list, then select the downloaded image `2023-05-03-raspios-bullseye-armhf-full.img.xz`
+
+Unfortunately, Customization is not supported with a Custom image, so you can't preset your username, password, localization, and WiFi settings.
+
+So after you write this image to your microSD card, you will need to connect a monitor and keyboard to your Pi Zero 2 to set these things (make sure you set `pi` as the username). After that, you can connect it to your WiFi and turn on ssh and vnc for remote access.
+
+You can then follow the software installation steps and it work work. The only hiccup is that if you run the installer script while running the Desktop, the Direwolf installation will freeze. But you can just cycle the power to the Pi Zero 2, then run the installer script again and it will complete successfully. Alternatively, if you use `sudo raspi-config` to change to Boot to Console (System/ Boot Auto Login/ Console or Console Auto Login) then the installer script will complete without any issues.
*Note:* CubeSatSim expects to be installed as the `pi` user and references many paths in `/home/pi/*`. Installing as a different user will result in configuration files not saving along with many other issues.
-To get the software follow these steps:
+To install the software follow these steps:
`sudo apt-get update`
diff --git a/asound.conf b/asound.conf
index 783b59f7..a752802a 100644
--- a/asound.conf
+++ b/asound.conf
@@ -6,7 +6,7 @@ pcm.!default {
ctl.!default {
type hw
- card 2
+ card "Device"
}
# Playback with software volume and mixing
@@ -15,15 +15,16 @@ pcm.softvol {
slave.pcm "shared_speaker"
control {
name "Master"
- card 2
+ card "Device"
}
}
pcm.shared_speaker {
type dmix
ipc_key 1024
+ ipc_perm 0666
slave {
- pcm "hw:2,0"
+ pcm "hw:CARD=Device,DEV=0"
rate 48000
period_time 0
period_size 1024
@@ -35,8 +36,9 @@ pcm.shared_speaker {
pcm.shared_mic {
type dsnoop
ipc_key 2048
+ ipc_perm 0666
slave {
- pcm "hw:2,0"
+ pcm "hw:CARD=Device,DEV=0"
# channels 1
rate 48000
period_time 0
diff --git a/command b/command
index f4c96b1d..73839a05 100755
--- a/command
+++ b/command
@@ -1,9 +1,17 @@
#!/bin/bash
-echo -e "\nCommand and Control script for CubeSatSim v2.1\n"
+echo -e "\nCommand and Control script for CubeSatSim v2.2\n"
sudo modprobe snd-aloop
+sudo modprobe snd-aloop
+
+value=`cat /home/pi/CubeSatSim/.mode`
+echo "$value" > /dev/null
+set -- $value
+
+MODE=$1
+
FILE=/home/pi/CubeSatSim/command_control
if [ -f "$FILE" ]; then
echo "Radio command and control is ON"
@@ -58,11 +66,11 @@ if [[ $(arecord -l | grep "USB Audio Device") ]] && [ -f "$FILE" ]; then
echo "debug mode"
- direwolf -c /home/pi/CubeSatSim/direwolf-cc.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py d
+ direwolf -P+ -D1 -r 48000 -c /home/pi/CubeSatSim/direwolf-cc.conf -t 0l | /home/pi/venv/bin/python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py d
else
- direwolf -c /home/pi/CubeSatSim/direwolf-cc.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py
+ direwolf -P+ -D1 -r 48000 -c /home/pi/CubeSatSim/direwolf-cc.conf -t 0l | /home/pi/venv/bin/python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py
fi
else
@@ -107,11 +115,11 @@ else
# echo "debug mode"
-# direwolf -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py d
+# direwolf -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf.conf -t 0l | /home/pi/venv/bin/python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py d
# else
-# direwolf -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py
+# direwolf -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf.conf -t 0l | /home/pi/venv/bin/python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py
# fi
@@ -124,17 +132,32 @@ else
fi
- if [ "$1" = "d" ]; then
-
- echo "debug mode"
-
- python3 /home/pi/CubeSatSim/squelch_cc.py d
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+ MODE=$1
+
+ if [ ! "$MODE" = "P" ] && [ ! "$MODE" = "P" ] ; then
+
+ if [ "$1" = "d" ]; then
+
+ echo "debug mode"
+
+ /home/pi/venv/bin/python3 /home/pi/CubeSatSim/squelch_cc.py d
+
+ else
+
+ /home/pi/venv/bin/python3 /home/pi/CubeSatSim/squelch_cc.py
+
+ fi
+
else
-
- python3 /home/pi/CubeSatSim/squelch_cc.py
-
- fi
+
+ echo "Not running Carrier (squelch) Command and Control since PacSat or PacSat Ground Station mode!"
+ sleep 60
+
+ fi
fi
sudo killall -9 direwolf &>/dev/null
diff --git a/config b/config
index 36192384..36379864 100755
--- a/config
+++ b/config
@@ -1,216 +1,119 @@
#!/bin/bash
-function transmit_command_aprs {
+function transmit_command {
- FILE=/home/pi/CubeSatSim/transmit_dtmf
- if [ -f "$FILE" ]; then
-
- echo "Stopping command and control"
- sudo systemctl stop command
-
- echo "Transmit DTMF start"
- gpio write 28 0 # ptt
- gpio write 2 1 # tx LED
- timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-aprs.conf -t 0l
- gpio write 2 0 # tx LED
- gpio write 28 1 #ptt
- echo "Transmit stop"
-
- echo "Resuming command and control"
- sudo systemctl start command
-
- else
-
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=a"
- sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
- echo $STRING > /home/pi/CubeSatSim/t.txt
- echo
- echo -n "Sending APRS packet to change mode to APRS "
- echo $STRING
- sudo touch /home/pi/CubeSatSim/ready
- sleep 3
-
- fi
-
- exit
-}
-
-function transmit_command_fsk {
-
- FILE=/home/pi/CubeSatSim/transmit_dtmf
- if [ -f "$FILE" ]; then
-
- echo "Stopping command and control"
- sudo systemctl stop command
-
- echo "Transmit DTMF start"
- gpio write 28 0 # ptt
- gpio write 2 1 # tx LED
- timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-fsk.conf -t 0l
- gpio write 2 0 # tx LED
- gpio write 28 1 #ptt
- echo "Transmit stop"
-
- echo "Resuming command and control"
- sudo systemctl start command
-
- else
-
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=f"
- sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
- echo $STRING > /home/pi/CubeSatSim/t.txt
- echo
- echo -n "Sending APRS packet to change mode to FSK"
- echo $STRING
- sudo touch /home/pi/CubeSatSim/ready
- sleep 3
-
- fi
-
- exit
-}
-
-function transmit_command_bpsk {
-
- FILE=/home/pi/CubeSatSim/transmit_dtmf
- if [ -f "$FILE" ]; then
-
- echo "Stopping command and control"
- sudo systemctl stop command
-
- echo "Transmit DTMF start"
- gpio write 28 0 # ptt
- gpio write 2 1 # tx LED
- timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-bpsk.conf -t 0l
- gpio write 2 0 # tx LED
- gpio write 28 1 #ptt
- echo "Transmit stop"
-
- echo "Resuming command and control"
- sudo systemctl start command
-
- else
-
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=b"
- sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
- echo $STRING > /home/pi/CubeSatSim/t.txt
- echo
- echo -n "Sending APRS packet to change mode to BPSK"
- echo $STRING
- sudo touch /home/pi/CubeSatSim/ready
- sleep 3
-
- fi
-
- exit
-}
+ MODE=$1
+ echo "CubeSatSim is in Transmit Commands mode"
+ echo
-function transmit_command_sstv {
+ value=`cat /home/pi/CubeSatSim/sim.cfg`
+ echo "$value" > /dev/null
+ set -- $value
+
+ echo -n "TX Frequency is: "
+ echo -n ${7}
+ echo " MHz"
FILE=/home/pi/CubeSatSim/transmit_dtmf
if [ -f "$FILE" ]; then
- echo "Stopping command and control"
- sudo systemctl stop command
-
- echo "Transmit DTMF start"
- gpio write 28 0 # ptt
- gpio write 2 1 # tx LED
- timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-sstv.conf -t 0l
- gpio write 2 0 # tx LED
- gpio write 28 1 #ptt
- echo "Transmit stop"
-
- echo "Resuming command and control"
- sudo systemctl start command
-
- else
-
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=s"
- sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
- echo $STRING > /home/pi/CubeSatSim/t.txt
echo
- echo -n "Sending APRS packet to change mode to SSTV"
- echo $STRING
- sudo touch /home/pi/CubeSatSim/ready
- sleep 3
+ echo "Sending DTMF tones to change to mode "$MODE
- fi
-
- exit
-}
+ case $MODE in
+
+ a)
+ number=1
+ ;;
+ f)
+ number=2
+ ;;
+ b)
+ number=3
+ ;;
+ s)
+ number=4
+ ;;
+ m)
+ number=5
+ ;;
+ e)
+ number=6
+ ;;
+ j)
+ number=7
+ ;;
+ p)
+ number=8
+ ;;
+ o)
+ number=10
+ ;;
+ *)
+ number=0
+ ;;
+ esac
-function transmit_command_cw {
+# echo $number
- FILE=/home/pi/CubeSatSim/transmit_dtmf
- if [ -f "$FILE" ]; then
+ cat /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf.conf > /home/pi/CubeSatSim/direwolf-tmp.conf && echo 'CBEACON dest="DTMF-3" info="'$number' #" delay=0' >> /home/pi/CubeSatSim/direwolf-tmp.conf
- echo "Stopping command and control"
- sudo systemctl stop command
+# echo "Stopping command and control"
+# sudo systemctl stop command
- echo "Transmit DTMF start"
+# echo "Transmit start"
gpio write 28 0 # ptt
gpio write 2 1 # tx LED
- timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-cw.conf -t 0l
+ timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf-tmp.conf -t 0l > /dev/null 2>&1
gpio write 2 0 # tx LED
gpio write 28 1 #ptt
- echo "Transmit stop"
+# echo "Transmit stop"
- echo "Resuming command and control"
- sudo systemctl start command
+# echo "Resuming command and control"
+# sudo systemctl start command
else
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=m"
+ STRING="$1-11>APCSS:=3901.40N\07704.39WShi hi MODE="$MODE
sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
echo $STRING > /home/pi/CubeSatSim/t.txt
echo
- echo -n "Sending APRS packet to change mode to CW"
+ echo -n "Sending APRS packet to change mode to "$MODE" "
echo $STRING
sudo touch /home/pi/CubeSatSim/ready
sleep 3
fi
- exit
+ echo
+ echo "To change the mode of this CubeSatSim use config -n"
}
-function transmit_command_beacon {
-
- FILE=/home/pi/CubeSatSim/transmit_dtmf
- if [ -f "$FILE" ]; then
-
- echo "Stopping command and control"
- sudo systemctl stop command
-
- echo "Transmit DTMF start"
- gpio write 28 0 # ptt
- gpio write 2 1 # tx LED
- timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-beacon.conf -t 0l
- gpio write 2 0 # tx LED
- gpio write 28 1 #ptt
- echo "Transmit stop"
+function check_restart {
- echo "Resuming command and control"
- sudo systemctl start command
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+ if [ "$1" = "p" ] || [ "$1" = "P" ] ; then
+ reboot=1
+ elif [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] || [ "$1" == "j" ] ; then
+ FILE=/home/pi/CubeSatSim/battery_saver
+ if [ -f "$FILE" ]; then
+ restart=1
+# echo "Need to restart since batt saver"
+ else
+ reboot=1
+# echo "Need to reboot"
+ fi
else
-
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=o"
- sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
- echo $STRING > /home/pi/CubeSatSim/t.txt
- echo
- echo -n "Sending APRS packet to toggle Beacon"
- echo $STRING
- sudo touch /home/pi/CubeSatSim/ready
- sleep 3
-
- fi
-
- exit
+ restart=1
+# echo "Need to restart"
+ fi
}
-echo "CubeSatSim v2.1 configuration tool"
+echo
+echo "CubeSatSim v2.2 configuration tool"
echo
# echo $1
# echo $2
@@ -222,8 +125,13 @@ sudo modprobe snd-aloop
if [ -z "$2" ] ; then
noreboot=0
else
- noreboot=1
- echo "Reboot disabled"
+ if [ "$2" = "n" ] ; then
+ echo "Reboot disabled"
+ noreboot=1
+ else
+ fail=$2
+ fi
+
fi
# echo "No reboot"
@@ -236,6 +144,7 @@ if [ "$1" = "" ]; then
value=`cat /home/pi/CubeSatSim/.mode`
echo "$value" > /dev/null
set -- $value
+ MODE=$1
if [ "$1" = "a" ]; then
echo "Mode is APRS"
@@ -259,6 +168,10 @@ if [ "$1" = "" ]; then
else
echo -n "APRS"
fi
+ elif [ "$1" = "p" ]; then
+ echo "Mode is Pacsat"
+ elif [ "$1" = "P" ]; then
+ echo "Mode is Pacsat Ground Station"
else
echo
fi
@@ -268,13 +181,89 @@ if [ "$1" = "" ]; then
set -- $value
if [ "$5" = "y" ] || [ "$5" = "yes" ] ; then
-# sim="yes"
echo "Simulated Telemetry is ON"
else
-# sim="no"
- echo "Simulated Telemetry is OFF"
+ FILE=/home/pi/CubeSatSim/sim_mode_auto
+ if [ -f "$FILE" ]; then
+ echo "Simulated Telemetry is automatically turned ON"
+# elif [[ $(timeout 2 i2cdetect -y 1 | grep -e "44" -e "45") ]]; then # check for battery board sensors
+# # Check the exit code of the last command
+# if [ $? -ne 0 ]; then
+# echo "Simulated Telemetry is automatically turned ON"
+# else
+# echo "Simulated Telemetry is OFF"
+# fi
+ else
+ echo "Simulated Telemetry is OFF"
+ fi
+ fi
+# echo
+
+ FILE=/home/pi/CubeSatSim/failure_mode.txt
+ if [ -f "$FILE" ]; then
+ if [[ $(grep "\-1" $FILE) ]]; then
+ echo "No simulated failure"
+ else
+ fail=$(<$FILE)
+ echo -n "Simulated "
+# cat $FILE
+
+ case $fail in
+
+ 1)
+ echo "+Y Solar Panel Unplugged (1)"
+ ;;
+ 2)
+ echo "+X Solar Panel Failure (2)"
+ ;;
+ 3)
+ echo "-X Solar Panel Degredation (3)"
+ ;;
+ 4)
+ echo "-Y Solar Panel Short Circuit (4)"
+ ;;
+ 5)
+ echo "Failed I2C Bus 1 (5)"
+ ;;
+ 6)
+ echo "Failed I2C Bus 3 (6)"
+ ;;
+ 7)
+ echo "Failed Camera (7)"
+ ;;
+ 8)
+ echo "Failed Payload (8)"
+ ;;
+ 9)
+ echo "Failed BME Sensor (9)"
+ ;;
+ 10)
+ echo "Failed MPU Sensor (10)"
+ ;;
+ "11")
+ echo "Failed FM Audio (11)"
+ ;;
+ *)
+ echo "Unknown Failure"
+ ;;
+ esac
+# echo $fail
+ fi
+ else
+ echo "No simulated failure"
+ fi
+
+ if [ "${12}" = "y" ] || [ "${12}" = "yes" ] ; then
+ echo "Random Failure Mode is ON with time period" ${13} "seconds"
+ else
+ echo "Random Failure Mode is OFF"
fi
- echo
+
+ echo -n "TX Frequency is: "
+ echo -n ${7}
+ echo -n " MHz, RX Frequency is: "
+ echo -n ${8}
+ echo " MHz"
if [ "$9" = "yes" ] || [ "$9" = "y" ]; then
echo "Balloon mode is ON"
@@ -282,7 +271,7 @@ if [ "$1" = "" ]; then
echo "Balloon mode is OFF"
fi
- echo
+# echo
echo -n "Current command count is: "
cat /home/pi/CubeSatSim/command_count.txt
echo
@@ -291,9 +280,14 @@ if [ "$1" = "" ]; then
# cat /home/pi/CubeSatSim/command_tx
# echo
- echo -n "Squelch level is: "
- echo $6
- echo
+# echo $MODE
+ if [ "$MODE" = "p" ] || [ "$MODE" = "P" ] ; then
+ echo "Squelch is off since PacSat or PacSat Ground Station mode"
+ else
+ echo -n "Squelch level is: "
+ echo $6
+ fi
+# echo
FILE=/home/pi/CubeSatSim/command_control
if [ -f "$FILE" ]; then
@@ -303,23 +297,31 @@ if [ "$1" = "" ]; then
if [ -f "$FILE" ]; then
echo "Radio DTMF/APRS command and control is ON"
else
- echo "Radio carrier command and control is ON"
+ if [ "$MODE" = "p" ] || [ "$MODE" = "P" ] ; then
+ echo "Radio carrier command and control is off since PacSat or PacSat Ground Station mode"
+ else
+ echo "Radio carrier command and control is ON"
+ fi
fi
else
- echo "Radio carrier command and control is ON"
+ if [ "$MODE" = "p" ] || [ "$MODE" = "P" ] ; then
+ echo "Radio carrier command and control is off since PacSat or PacSat Ground Station mode"
+ else
+ echo "Radio carrier command and control is ON"
+ fi
fi
else
echo "Radio command and control is OFF"
fi
- echo
+# echo
echo -n "RX PL code is: "
echo -n ${10}
# echo
echo -n " TX PL code is: "
echo ${11}
- echo
+# echo
FILE=/home/pi/CubeSatSim/battery_saver
if [ -f "$FILE" ]; then
@@ -328,7 +330,7 @@ if [ "$1" = "" ]; then
echo "Battery saver mode is OFF"
fi
- echo
+# echo
FILE=/home/pi/CubeSatSim/beacon_off
if [ -f "$FILE" ]; then
echo "Transmit beacon telemetry is OFF"
@@ -336,11 +338,37 @@ if [ "$1" = "" ]; then
echo "Transmit beacon telemetry is ON"
fi
+ if [[ $(arecord -l | grep "USB Audio Device") ]] ; then
+ echo "USB Sound Card detected"
+ soundcard=1
+ else
+ echo "No USB Sound Card detected"
+ soundcard=0
+ fi
+
+ gpio -g mode 7 up
+ if [[ $(gpio -g read 7 | grep 0) ]] ; then
+ echo "FM TXC is present"
+ txc=1
+ else
+ echo "FM TXC not present"
+ txc=0
+ fi
+
+ timeout 1 rtl_test &> out.txt
+ if [[ $(grep "No supported" out.txt) ]] ; then
+# echo "No RTL-SDR detected"
+ rtl=0
+ else
+ echo "RTL-SDR detected"
+ rtl=1
+ fi
+
echo
echo -e "Current sim.cfg configuration file:"
# echo
- echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
echo
echo "To change, include an OPTION"
@@ -362,22 +390,14 @@ elif [ "$1" = "-a" ]; then
if [ "$1" == "n" ]; then
- transmit_command_aprs
+ transmit_command "a"
else
echo "changing CubeSatSim to AFSK mode"
+ check_restart
sudo echo "a" > /home/pi/CubeSatSim/.mode
- if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] || [ "$1" == "j" ] ; then
- FILE=/home/pi/CubeSatSim/battery_saver
- if [ -f "$FILE" ]; then
- restart=1
- else
- reboot=1
- fi
- else
- restart=1
- fi
+
fi
elif [ "$1" = "-m" ]; then
@@ -388,22 +408,14 @@ elif [ "$1" = "-m" ]; then
if [ "$1" == "n" ]; then
- transmit_command_cw
+ transmit_command "m"
else
echo "changing CubeSatSim to CW mode"
+ check_restart
sudo echo "m" > /home/pi/CubeSatSim/.mode
- if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] || [ "$1" == "j" ] ; then
- FILE=/home/pi/CubeSatSim/battery_saver
- if [ -f "$FILE" ]; then
- restart=1
- else
- reboot=1
- fi
- else
- restart=1
- fi
+
fi
elif [ "$1" = "-f" ]; then
@@ -414,13 +426,17 @@ elif [ "$1" = "-f" ]; then
if [ "$1" == "n" ]; then
- transmit_command_fsk
+ transmit_command "f"
else
echo "changing CubeSatSim to FSK mode"
sudo echo "f" > /home/pi/CubeSatSim/.mode
- restart=1
+ if [ "$1" = "p" ] || [ "$1" = "P" ] ; then
+ reboot=1
+ else
+ restart=1
+ fi
fi
elif [ "$1" = "-b" ]; then
@@ -431,13 +447,17 @@ elif [ "$1" = "-b" ]; then
if [ "$1" == "n" ]; then
- transmit_command_bpsk
+ transmit_command "b"
else
echo "changing CubeSatSim to BPSK mode"
sudo echo "b" > /home/pi/CubeSatSim/.mode
- restart=1
+ if [ "$1" = "p" ] || [ "$1" = "P" ] ; then
+ reboot=1
+ else
+ restart=1
+ fi
fi
elif [ "$1" = "-s" ]; then
@@ -448,23 +468,14 @@ elif [ "$1" = "-s" ]; then
if [ "$1" == "n" ]; then
- transmit_command_sstv
+ transmit_command "s"
else
echo "changing CubeSatSim to SSTV mode"
+ check_restart
sudo echo "s" > /home/pi/CubeSatSim/.mode
- if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] || [ "$1" == "j" ] ; then
- FILE=/home/pi/CubeSatSim/battery_saver
- if [ -f "$FILE" ]; then
- restart=1
- else
- reboot=1
- fi
- else
- restart=1
- fi
fi
elif [ "$1" = "-t" ]; then
@@ -479,14 +490,14 @@ elif [ "$1" = "-t" ]; then
set -- $value
if [ "$5" = "yes" ] || [ "$5" = "y" ]; then
- echo "Simualted Telemetry is ON"
+ echo "Simulated Telemetry is ON"
else
- echo "Simualted Telemetry is OFF"
+ echo "Simulated Telemetry is OFF"
fi
echo
-# $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
+# $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${12} ${13}
echo "Do you want Simulated Telemetry ON (y/n) "
read sim
@@ -498,13 +509,14 @@ elif [ "$1" = "-t" ]; then
else
sim="no"
echo "Simulated Telemetry is OFF"
+ echo "-1" > /home/pi/CubeSatSim/failure_mode.txt # make sure to turn off any simulated failures
fi
# echo
echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
# echo
- echo $1 $2 $3 $4 $sim $6 $7 $8 $9 ${10} ${11}
- echo $1 $2 $3 $4 $sim $6 $7 $8 $9 ${10} ${11} > /home/pi/CubeSatSim/sim.cfg
+ echo $1 $2 $3 $4 $sim $6 $7 $8 $9 ${10} ${11} ${12} ${13}
+ echo $1 $2 $3 $4 $sim $6 $7 $8 $9 ${10} ${11} ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
echo
## echo "Rebooting CubeSatSim with new configuration file"
## echo
@@ -527,11 +539,13 @@ elif [ "$1" = "-c" ]; then
echo "$value" > /dev/null
set -- $value
+ oldcallsign="$1"
+
echo "Current value of CALLSIGN is"
- echo $1
+ echo $oldcallsign
echo
-# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
+# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${12} ${13}
echo "Enter callsign in all capitals: "
read callsign
@@ -545,8 +559,8 @@ elif [ "$1" = "-c" ]; then
echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
- echo $callsign $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
- echo $callsign $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} > /home/pi/CubeSatSim/sim.cfg
+ echo $callsign $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
+ echo $callsign $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
fi
if [ "$norestart" = "1" ]; then
@@ -579,7 +593,7 @@ elif [ "$1" = "-r" ]; then
echo $2
echo
-# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
+# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
echo -e "Enter Reset Count (integer): "
@@ -599,8 +613,8 @@ elif [ "$1" = "-r" ]; then
echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
- echo $1 $resets $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
- echo $1 $resets $3 $4 $5 $6 $7 $8 $9 ${10} ${11} > /home/pi/CubeSatSim/sim.cfg
+ echo $1 $resets $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
+ echo $1 $resets $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
fi
if [ "$norestart" = "1" ]; then
@@ -634,7 +648,7 @@ elif [ "$1" = "-l" ]; then
echo $3
echo
-# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
+# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
echo -e "Enter latitude (decimal degrees, positive is north): "
@@ -676,8 +690,8 @@ elif [ "$1" = "-l" ]; then
fi
echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
- echo $1 $2 $lat $long $5 $6 $7 $8 $9 ${10} ${11}
- echo $1 $2 $lat $long $5 $6 $7 $8 $9 ${10} ${11} > /home/pi/CubeSatSim/sim.cfg
+ echo $1 $2 $lat $long $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
+ echo $1 $2 $lat $long $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
if [ "$norestart" = "1" ]; then
echo
@@ -714,6 +728,7 @@ elif [ "$1" = "-C" ]; then
sudo systemctl stop cubesatsim
sudo systemctl stop transmit
sudo systemctl stop command
+ sudo systemctl stop pacsatsim
sudo mv -f /home/pi/CubeSatSim/telem.txt /home/pi/CubeSatSim/telem.txt.bk
@@ -727,7 +742,6 @@ elif [ "$1" = "-C" ]; then
elif [ "$1" = "-T" ]; then
- echo
echo "Change command and control state"
echo
@@ -740,7 +754,7 @@ elif [ "$1" = "-T" ]; then
echo
if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then
- echo "Command and control set to OFF"
+ echo "Turning command and control OFF"
sudo rm /home/pi/CubeSatSim/command_control > /dev/null 2>&1
# reboot=1
echo "restarting command and control"
@@ -751,21 +765,40 @@ elif [ "$1" = "-T" ]; then
fi
else
- echo "Radio command and control is OFF"
+ echo "Radio command and control is OFF"
echo
echo "Do you want to set command and control to ON (y/n) "
read reset
echo
if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then
- echo "Command and control set to ON"
- sudo touch /home/pi/CubeSatSim/command_control
- echo "restarting command and control"
-# reboot=1
- sudo systemctl restart command
- echo "restarting transmit"
- sudo systemctl restart transmit
-## sudo reboot now
+
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+
+ if [ "$1" != "n" ] ; then
+ echo "Turning command and control ON"
+
+ value=`cat /home/pi/CubeSatSim/sim.cfg`
+ echo "$value" > /dev/null
+ set -- $value
+
+ echo -n "RX Frequency is: "
+ echo -n ${8}
+ echo " MHz"
+ echo
+
+ sudo touch /home/pi/CubeSatSim/command_control
+ echo "restarting command and control"
+# reboot=1
+ sudo systemctl restart command
+ echo "restarting transmit"
+ sudo systemctl restart transmit
+## sudo reboot now
+ else
+ echo "Can't turn on Command and control in Transmit Commands mode."
+ fi
fi
fi
@@ -883,7 +916,7 @@ elif [ "$1" = "-R" ]; then
echo
echo "Current commands count is:"
- cat /home/pi/CubeSatSim/commands_count.txt
+ cat /home/pi/CubeSatSim/command_count.txt
echo
echo "Do you want to reset the commands count to zero (y/n) "
@@ -969,7 +1002,7 @@ elif [ "$1" = "-q" ]; then
echo $6
echo
-# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
+# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
echo -e "Enter squelch (integer 1 - 8): "
@@ -991,8 +1024,8 @@ elif [ "$1" = "-q" ]; then
# echo
echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
# echo
- echo $1 $2 $3 $4 $5 $sq $7 $8 $9 ${10} ${11}
- echo $1 $2 $3 $4 $4 $sq $7 $8 $9 ${10} ${11} > /home/pi/CubeSatSim/sim.cfg
+ echo $1 $2 $3 $4 $5 $sq $7 $8 $9 ${10} ${11} ${12} ${13}
+ echo $1 $2 $3 $4 $4 $sq $7 $8 $9 ${10} ${11} ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
echo
echo "Restarting CubeSatSim with new configuration file"
## echo
@@ -1014,7 +1047,7 @@ elif [ "$1" = "-P" ]; then
echo
echo "Editing the PL (Private Line) CTCSS/CDCSS setting in"
- echo "the configuration file for CubeSatSim"
+ echo "the configuration file for CubeSatSim"
echo
value=`cat /home/pi/CubeSatSim/sim.cfg`
@@ -1028,7 +1061,7 @@ elif [ "$1" = "-P" ]; then
echo ${11}
echo
-# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
+# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
echo -e "Enter RX PL value integer 0: None, 01-38: CTCSS (analog, 39-121:CDCSS (digital)"
@@ -1071,8 +1104,8 @@ elif [ "$1" = "-P" ]; then
# echo
echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
# echo
- echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $rxpl $txpl
- echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $rxpl $txpl > /home/pi/CubeSatSim/sim.cfg
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $rxpl $txpl ${12} ${13}
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $rxpl $txpl ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
echo
## echo "Rebooting CubeSatSim with new configuration file"
## echo
@@ -1102,7 +1135,7 @@ elif [ "$1" = "-F" ]; then
echo $8
echo
-# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
+# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
echo "Enter tx frequency as 4XX.XXXX: "
read tx
@@ -1121,23 +1154,24 @@ elif [ "$1" = "-F" ]; then
rx="$8"
echo "Keeping value of" $rx
fi
-# else
-
- echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
+ echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
- echo $1 $2 $3 $4 $5 $6 $tx $rx $9 ${10} ${11}
- echo $1 $2 $3 $4 $5 $6 $tx $rx $9 ${10} ${11} > /home/pi/CubeSatSim/sim.cfg
-# fi
-
-# if [ "$norestart" = "1" ]; then
-# echo
+ echo $1 $2 $3 $4 $5 $6 $tx $rx $9 ${10} ${11} ${12} ${13}
+ echo $1 $2 $3 $4 $5 $6 $tx $rx $9 ${10} ${11} ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
+
+ echo
+ echo "Restarting CubeSatSim with new configuration file"
+
+# if [[ $(sudo systemctl is-active gpsd.socket | grep inactive) ]]; then
+ sudo systemctl restart transmit
# else
- echo
- echo "Restarting CubeSatSim with new configuration file"
-## echo
+# echo
+# echo "temporarily disabling gpsd and rebooting to program FM module"
+# echo "this will take about 40 seconds"
+# sudo systemctl stop gpsd.socket
+ sudo systemctl restart transmit
+# sleep 10
# reboot=1
-## sudo reboot now
- sudo systemctl restart transmit
# fi
elif [ "$1" = "-o" ]; then
@@ -1145,10 +1179,11 @@ elif [ "$1" = "-o" ]; then
value=`cat /home/pi/CubeSatSim/.mode`
echo "$value" > /dev/null
set -- $value
+ MODE=$1
- if [ "$1" == "n" ]; then
+ if [ "$MODE" == "n" ]; then
- transmit_command_beacon
+ transmit_command "o"
else
echo
@@ -1157,36 +1192,21 @@ elif [ "$1" = "-o" ]; then
FILE=/home/pi/CubeSatSim/beacon_off
if [ -f "$FILE" ]; then
- echo "Transmit beacon telemetry is off"
-# echo
-# echo "Do you want to turn beacon telemetry ON (y/n) "
-# read reset
-
- reset="y"
+ echo "Transmit beacon telemetry is off"
echo
- if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then
- echo "Turn beacon telemetry ON"
- sudo rm /home/pi/CubeSatSim/beacon_off > /dev/null 2>&1
- sudo systemctl restart transmit
- # restart=1
- fi
-
+ echo "Turn beacon telemetry ON"
+ sudo rm /home/pi/CubeSatSim/beacon_off > /dev/null 2>&1
+ sudo systemctl restart transmit
else
- echo "Transmit beacon telemetry is on"
-# echo
-# echo "Do you want to turn beacon telemetry OFF (y/n) "
-# read reset
- reset="y"
+ echo "Transmit beacon telemetry is on"
echo
- if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then
- echo "Turn beacon telemetry OFF"
- touch /home/pi/CubeSatSim/beacon_off
- sudo systemctl restart transmit
- # restart=1
- fi
+ echo "Turn beacon telemetry OFF"
+ touch /home/pi/CubeSatSim/beacon_off
+ sudo systemctl restart transmit
fi
+ sleep 3
fi
elif [ "$1" = "-H" ]; then
@@ -1208,7 +1228,7 @@ elif [ "$1" = "-H" ]; then
echo
-# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
+# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
echo "Do you want Balloon mode ON (y/n) "
read hab
@@ -1225,8 +1245,8 @@ elif [ "$1" = "-H" ]; then
# echo
echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
# echo
- echo $1 $2 $3 $4 $5 $6 $7 $8 $hab ${10} ${11}
- echo $1 $2 $3 $4 $5 $6 $7 $8 $hab ${10} ${11} > /home/pi/CubeSatSim/sim.cfg
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $hab ${10} ${11} ${12} ${13}
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $hab ${10} ${11} ${12} ${13} > /home/pi/CubeSatSim/sim.cfg
echo
## echo "Rebooting CubeSatSim with new configuration file"
## echo
@@ -1252,102 +1272,127 @@ elif [ "$1" = "-v" ]; then
elif [ "$1" = "-e" ]; then
- echo "changing CubeSatSim to Repeater mode"
- sudo echo "e" > /home/pi/CubeSatSim/.mode
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
- restart=1
+ if [ "$1" == "n" ]; then
+
+ transmit_command "e"
+
+ else
+
+ echo "changing CubeSatSim to Repeater mode"
+ sudo echo "e" > /home/pi/CubeSatSim/.mode
+ if [ "$1" = "p" ] || [ "$1" = "P" ] ; then
+ reboot=1
+ else
+ restart=1
+ fi
+ fi
elif [ "$1" = "-n" ]; then
- echo "changing CubeSatSim to Transmit Commands mode"
+# echo "changing CubeSatSim to Transmit Commands mode"
+
+ new=$2
value=`cat /home/pi/CubeSatSim/.mode`
echo "$value" > /dev/null
set -- $value
if [ "$1" = "n" ]; then
- echo "Turning Transmit Command and Control mode OFF"
- echo "Switching to BPSK mode"
- sudo echo "b" > /home/pi/CubeSatSim/.mode
- reboot=1
+ echo "Turning Transmit Commands mode OFF"
+ if [ "$new" = "a" ] || [ "$new" = "s" ] || [ "$new" = "m" ] ; then
+ check_restart
+ echo "Switching to mode "$new
+ sudo echo $new > /home/pi/CubeSatSim/.mode
+ elif [ "$new" = "f" ] || [ "$new" = "b" ] || [ "$new" = "e" ] || [ "$new" = "j" ] ; then
+ echo "Switching to mode "$new
+ sudo echo $new > /home/pi/CubeSatSim/.mode
+ restart=1
+ elif [ "$1" = "p" ] || [ "$1" = "P" ] ; then
+ echo "Switching to PacSat mode"
+ sudo echo $new > /home/pi/CubeSatSim/.mode
+ reboot=1
+ else
+ echo "Switching to BPSK mode"
+ sudo echo "b" > /home/pi/CubeSatSim/.mode
+ reboot=1
+ fi
+ sudo systemctl restart command
else
- echo "Turning Transmit Command and Control mode ON"
+ echo "Switching to Transmit Commands mode"
+
+ value=`cat /home/pi/CubeSatSim/sim.cfg`
+ echo "$value" > /dev/null
+ set -- $value
+
+ echo -n "TX Frequency is: "
+ echo -n ${7}
+ echo " MHz"
+ echo
+
+ check_restart
sudo echo "n" > /home/pi/CubeSatSim/.mode
- restart=1
+ sudo systemctl stop command
fi
elif [ "$1" = "-A" ]; then
- echo "Transmit APRS control packets to control another CubeSatSim"
+ echo "Transmit APRS Commands to control another CubeSatSim"
+ echo
+
+ value=`cat /home/pi/CubeSatSim/sim.cfg`
+ echo "$value" > /dev/null
+ set -- $value
+
+ echo -n "TX Frequency is: "
+ echo -n ${7}
+ echo " MHz"
echo
value=`cat /home/pi/CubeSatSim/.mode`
echo "$value" > /dev/null
set -- $value
+ if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] || [ "$1" == "j" ] ; then
+ echo "The CubeSatSim/config -A command can only be run in APRS, SSTV, CW, or Transmit Commands modes."
+ echo "Switch to one of these modes (a, s, m, or n) then re-run this command."
+ exit
+ fi
+
if [ "$1" != "n" ]; then
sudo systemctl stop cubesatsim
sudo systemctl stop transmit
- # sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
- sudo python3 -u /home/pi/CubeSatSim/transmit.py x > /dev/null 2>&1 & # Force APRS mode
+# sudo python3 -u /home/pi/CubeSatSim/transmit.py x > /dev/null 2>&1 & # Force APRS mode
fi
+ sudo systemctl stop command
- sim="y"
+ MODE="0"
- while [ "$sim" = "y" ]
+ while [ "$MODE" != "x" ];
do
- echo "Enter the mode number to change: 1=APRS, 2=FSK, 3=BPSK, 4=SSTV, 5=CW"
+ echo "Enter the mode to change: a=APRS, f=FSK, b=BPSK, s=SSTV, m=CW, e=Repeater, j=FUNcube, p=PacSat, o=Beacon on/off x=Exit this mode"
read MODE
-
- case $MODE in
-
- 1)
- echo "Mode 1 is APRS"
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=a"
- ;;
- 2)
- echo "Mode 2 is FSK"
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=f"
- ;;
- 3)
- echo "Mode 3 is BPSK"
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=b"
- ;;
- 4)
- echo "Mode 4 is SSTV"
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=s"
- ;;
- 5)
- echo "Mode 5 is CW"
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=m"
- ;;
- *)
- echo "Unknown mode"
- STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=?"
- ;;
- esac
- sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
- echo $STRING > /home/pi/CubeSatSim/t.txt
- echo
- echo -n "Sending APRS packet "
- echo $STRING
- sudo touch /home/pi/CubeSatSim/ready
- sleep 5
- sudo touch /home/pi/CubeSatSim/ready
+
+ if [ "$MODE" != "x" ]; then
+ transmit_command $MODE
+ fi
echo
- echo "Do you want to send another APRS command packet (y/n) "
- read sim
- echo
+
done
- sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1
-# sudo systemctl restart cubesatsim
- if [ "$1" != "n" ]; then
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+ if [ "$1" != "n" ] ; then
+ sudo systemctl restart command
reboot=1
fi
@@ -1378,7 +1423,7 @@ elif [ "$1" = "-g" ]; then
if [ "$rset" = "y" ] || [ "$rset" = "yes" ] ; then
- echo "Resetting"
+ echo "Resetting and shutting down."
echo "AMSAT 0 0 0 no 3 434.9 435 no 0 0" > /home/pi/CubeSatSim/sim.cfg
@@ -1392,7 +1437,9 @@ elif [ "$1" = "-g" ]; then
sudo rm /home/pi/CubeSatSim/beacon_off > /dev/null 2>&1
- sudo echo "0" > /home/pi/CubeSatSim/command_count.txt
+ sudo echo "0" > /home/pi/CubeSatSim/command_count.txt
+
+ sudo rm /home/pi/CubeSatSim/failure_mode.txt > /dev/null 2>&1
sudo systemctl stop cubesatsim
sudo systemctl stop transmit
@@ -1406,6 +1453,8 @@ elif [ "$1" = "-g" ]; then
rm -rf ~/.config/chromium/Singleton*
cat /dev/null > ~/.bash_history && history -c
+
+ sudo shutdown now
# reboot=1
else
@@ -1419,16 +1468,411 @@ elif [ "$1" = "-j" ]; then
echo "$value" > /dev/null
set -- $value
-# if [ "$1" == "n" ]; then
+ if [ "$1" == "n" ]; then
-# transmit_command_bpsk
+ transmit_command "j"
-# else
+ else
echo "changing CubeSatSim to FUNcube mode"
sudo echo "j" > /home/pi/CubeSatSim/.mode
restart=1
-# fi
+ fi
+
+elif [ "$1" = "-M" ]; then
+
+ if [ $fail ]; then
+ MODE=$fail
+ else
+
+ FILE=/home/pi/CubeSatSim/failure_mode.txt
+ if [ -f "$FILE" ]; then
+ if [[ $(grep "\-1" $FILE) ]]; then
+ echo "Currently, no simulated failure (0)"
+ else
+ fail=$(<$FILE)
+ echo -n "Currently, simulated "
+ case $fail in
+
+ 1)
+ echo "+Y Solar Panel Unplugged (1)"
+ ;;
+ 2)
+ echo "+X Solar Panel Failure (2)"
+ ;;
+ 3)
+ echo "-X Solar Panel Degredation (3)"
+ ;;
+ 4)
+ echo "-Y Solar Panel Short Circuit (4)"
+ ;;
+ 5)
+ echo "Failed I2C Bus 1 (5)"
+ ;;
+ 6)
+ echo "Failed I2C Bus 3 (6)"
+ ;;
+ 7)
+ echo "Failed Camera (7)"
+ ;;
+ 8)
+ echo "Failed Payload (8)"
+ ;;
+ 9)
+ echo "Failed BME Sensor (9)"
+ ;;
+ "10")
+ echo "Failed MPU Sensor (10)"
+ ;;
+ "11")
+ echo "Failed FM Audio (11)"
+ ;;
+ *)
+ echo "Unknown Failure"
+ ;;
+ esac
+ fi
+ else
+ echo "Currently, no simulated failure"
+ fi
+
+ echo
+ echo "Set simulated failure mode (or Return to turn OFF)"
+ echo
+
+ echo " 0 No Failure (turn OFF)"
+ echo " 1 +Y Solar Panel Unplugged"
+ echo " 2 +X Solar Panel Failure"
+ echo " 3 -X Solar Panel Degredation"
+ echo " 4 -Y Solar Panel Short Circuit"
+ echo " 5 Failed I2C Bus 1"
+ echo " 6 Failed I2C Bus 3"
+ echo " 7 Failed Camera"
+ echo " 8 Failed Payload"
+ echo " 9 Failed BME Sensor"
+ echo "10 Failed MPU Sensor"
+ echo "11 Failed FM Audio"
+ echo
+
+ echo "Enter the failure number to set: 0 - 11"
+ read MODE
+ echo
+ fi
+
+ if [ "$MODE" = "0" ]; then
+ echo "Setting No Simulated Failure"
+ MODE=-1
+# elif [ "$MODE" = "12" ]; then
+
+# if [ "$norestart" = "1" ]; then
+# echo
+# else
+# reboot=1
+# fi
+
+ else
+ case $MODE in
+ 1)
+ echo "+Y Solar Panel Unplugged"
+ ;;
+ 2)
+ echo "Setting Simulated +X Solar Panel Failure"
+ ;;
+ 3)
+ echo "Setting Simulated -X Solar Panel Degredation"
+ ;;
+ 4)
+ echo "Setting Simulated -Y Solar Panel Short Circuit"
+ ;;
+ 5)
+ echo "Setting Simulated Failed I2C Bus 1"
+ ;;
+ 6)
+ echo "Setting Simulated Failed I2C Bus 3"
+ ;;
+ 7)
+ echo "Setting Simulated Failed Camera"
+ ;;
+ 8)
+ echo "Setting Simulated Failed Payload"
+ ;;
+ 9)
+ echo "Setting Simulated Failed BME Sensor"
+ ;;
+ "10")
+ echo "Setting Simulated Failed MPU Sensor"
+ ;;
+ "11")
+ echo "Setting Failed FM Audio"
+ ;;
+ *)
+ echo "Setting No Simulated Failure"
+ MODE=-1
+ ;;
+ esac
+ fi
+
+# echo $MODE
+ echo
+ sudo rm /home/pi/CubeSatSim/failure_mode.txt
+ echo $MODE > /home/pi/CubeSatSim/failure_mode.txt
+
+ echo "Changing simulated failure mode to $MODE" | wall
+
+elif [ "$1" = "-N" ]; then
+
+ FILE=/home/pi/CubeSatSim/failure_mode.txt
+ if [ -f "$FILE" ]; then
+ if [[ $(grep "\-1" $FILE) ]]; then
+ echo "No simulated failure"
+ fail=0
+ else
+ echo "Simulated failure mode"
+ fail=$(<$FILE)
+ echo $fail
+ fi
+ else
+ echo "No simulated failure"
+ fail=0
+ fi
+
+ if [ $fail == 0 ]; then
+ echo "Changing to next mode"
+
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+
+ if [ "$1" = "a" ]; then
+ echo "Current mode is APRS"
+ echo "Next mode is FSK"
+ /home/pi/CubeSatSim/config -f
+ elif [ "$1" = "m" ]; then
+ echo "Current mode is CW"
+ echo "Next mode is FunCube"
+ /home/pi/CubeSatSim/config -j
+ elif [ "$1" = "f" ]; then
+ echo "Current mode is FSK"
+ echo "Next mode is BPSK"
+ /home/pi/CubeSatSim/config -b
+ elif [ "$1" = "b" ]; then
+ echo "Current mode is BPSK"
+ echo "Next mode is SSTV"
+ /home/pi/CubeSatSim/config -s
+ elif [ "$1" = "s" ]; then
+ echo "Current mode is SSTV"
+ echo "Next mode is CW"
+ /home/pi/CubeSatSim/config -m
+ elif [ "$1" = "e" ]; then
+ echo "Current mode is Repeater"
+ echo "Next mode is APRS"
+ /home/pi/CubeSatSim/config -a
+ elif [ "$1" = "j" ]; then
+ echo "Current mode is FUNcube"
+ echo "Next mode is Repeater"
+ /home/pi/CubeSatSim/config -e
+ else
+ echo "Unknown mode"
+ fi
+ else
+ echo "Changing to next simulated failure mode"
+ fail=$((fail + 1))
+# if [ $fail == 12 ]; then
+ if [ "$fail" -gt "11" ]; then
+ fail=1
+ fi
+ echo $fail
+ /home/pi/CubeSatSim/config -M $fail
+
+ fi
+
+elif [ "$1" = "-U" ]; then
+
+ echo
+ echo "Changing the Random Simulated Failure setting in"
+ echo "the configuration file for CubeSatSim"
+ echo
+
+ value=`cat /home/pi/CubeSatSim/sim.cfg`
+ echo "$value" > /dev/null
+ set -- $value
+
+ if [ "${12}" = "yes" ] || [ "${12}" = "y" ]; then
+ echo "Random Simulated Failure is ON"
+ else
+ echo "Random Simulated Failure is OFF"
+ fi
+
+ echo
+
+# $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${12} ${13}
+
+ echo "Do you want Random Simulated Failure ON (y/n) "
+ read sim
+ echo
+
+ if [ "$sim" = "y" ] || [ "$sim" = "yes" ] ; then
+ sim="yes"
+ echo "Random Simulated Failure is ON"
+ echo
+ echo "A new random failure is selected every"
+ echo ${13} "seconds."
+ echo
+ echo "Enter a new value or Return keeps current value."
+
+ echo "Enter time in seconds (integer): "
+
+ read time
+
+ if [ -z $time ] ; then
+ time="${13}"
+ echo "Keeping value of " $time " seconds"
+ fi
+
+ if ! [[ $time =~ ^[0-9]+$ ]] ; then
+ echo "Error: not an integer!"
+ time="${13}"
+ echo "Keeping value of" $time
+ fi
+
+ else
+ sim="no"
+ echo "Random Simulated Failure is OFF"
+ time="${13}"
+# echo "-1" > /home/pi/CubeSatSim/failure_mode.txt # make sure to turn off any simulated failures
+ fi
+
+# echo
+ echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
+# echo
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} $sim $time
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} $sim $time > /home/pi/CubeSatSim/sim.cfg
+ echo
+
+ if [ "${12}" != "$sim" ] || [ "${13}" != "$time" ] ; then
+ reboot=1
+ fi
+
+elif [ "$1" = "-u" ]; then
+
+ echo
+ echo "Change gpsd state"
+ echo
+
+ if [[ $(sudo systemctl is-active gpsd.socket | grep inactive) ]]; then
+ echo "gpsd is inactive"
+ echo
+ echo "Do you want to turn gpsd to ON (y/n) "
+ read reset
+ echo
+
+ if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then
+ echo "gpsd set to ON"
+ sudo systemctl enable gpsd
+ sudo systemctl enable gpsd.socket
+ echo
+ echo "Here is the current gpsd configuration /etc/default/gpsd which will work with many GPS modules:"
+ echo
+
+ cat /etc/default/gpsd
+
+ echo
+ echo "To change this configuration edit the file with sudo nano /etc/default/gpsd then restart gpsd."
+ echo
+ echo "To monitor your gps device, use the gpsmon command."
+ echo
+ reboot=1
+ fi
+
+ else
+ echo "gpsd is active"
+ echo
+ echo "Do you want to turn gpsd to OFF (y/n) "
+ read reset
+ echo
+
+ if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then
+ echo "gpsd set to OFF"
+ sudo systemctl disable gpsd
+ sudo systemctl disable gpsd.socket
+reboot=1
+ fi
+
+ fi
+
+elif [ "$1" = "-G" ]; then
+
+ echo "Changing to PacSatSim mode"
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+
+# echo "changing CubeSatSim to Pacsat mode"
+
+ reboot=1
+ sudo echo "p" > /home/pi/CubeSatSim/.mode
+# if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] ; then
+# FILE=/home/pi/CubeSatSim/battery_saver
+# if [ -f "$FILE" ]; then
+# restart=1
+# else
+# reboot=1
+# fi
+# else
+# restart=1
+# fi
+
+elif [ "$1" = "-I" ]; then
+
+ echo "Changing to PacSat Ground Station mode"
+ echo
+ echo "Run the Pacsat Ground Station in the Desktop"
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+
+# echo "changing CubeSatSim to Pacsat mode"
+
+ reboot=1
+ sudo echo "P" > /home/pi/CubeSatSim/.mode
+
+ value=`cat /home/pi/CubeSatSim/sim.cfg`
+ echo "$value" > /dev/null
+ set -- $value
+
+ if [ "${7}" = "434.9" ] && [ "${8}" = "435" ]; then
+ echo "The default transmit frequency of 434.9 MHz is set"
+ echo
+ echo "Do you want to change it (for example to 435 MHz)?"
+
+ read input
+ echo
+
+ if [ "$input" = "y" ] || [ "$input" = "yes" ] ; then
+ /home/pi/CubeSatSim/config -F n
+ fi
+ fi
+
+
+# if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] ; then
+# FILE=/home/pi/CubeSatSim/battery_saver
+# if [ -f "$FILE" ]; then
+# restart=1
+# else
+# reboot=1
+# fi
+# else
+# restart=1
+# fi
+
+elif [ "$1" = "-k" ]; then
+
+ echo
+ echo "Reset PacSatSim configuration"
+ echo
+ sudo systemctl stop pacsatsim &>/dev/null
+ sudo rm -r /home/pi/PacSat
+ reboot=1
elif [ "$1" = "-h" ]; then
@@ -1445,28 +1889,37 @@ elif [ "$1" = "-h" ]; then
echo " -j Change to FUNcube mode"
echo " -n Change to Transmit Commands mode"
echo " -e Change to Repeater mode"
+ echo " -j Change to FUNcube mode"
+ echo " -G Change to PacSatSim mode"
+ echo " -I Change to PacSat Ground Station mode"
echo " -i Restart CubeSatsim software"
echo " -c Change the CALLSIGN in the configuration file sim.cfg"
echo " -t Change the Simulated Telemetry setting in sim.cfg"
echo " -r Change the Resets Count in the configuration file sim.cfg"
echo " -l Change the Latitude and Longitude in the configuration file sim.cfg"
echo " -S Scan both I2C buses on the Raspberry Pi"
- echo " -C Clear logs"
+ echo " -C Clear logs and reboot"
echo " -T Change command and control state"
echo " -d Change command and control Direwolf state"
echo " -R Change the Commands Count in the file command_count.txt"
echo " -B Change Safe Mode (battery saver mode) manually"
echo " -q Change the Squelch setting for command receiver"
+ echo " -Q Read the current Squelch for 10 seconds"
echo " -F Change the RX and TX frequency"
echo " -H Change the Balloon (HAB) mode"
- echo " -p Display payload sensor data"
+ echo " -p Display payload sensor data for 3 seconds"
echo " -v Display voltage and current data"
- echo " -P Change the PL (Private Line) CTCSS/CDCSS codes for RX and TX"
+ echo " -P Change the PL (Private Line) CTCSS/CDCSS codes for FM RX and TX"
echo " -A Transmit APRS control packets to control another CubeSatSim"
echo " -D Change Transmit Commands state APRS or DTMF"
echo " -o Change telemetry beacon transmit state"
echo " -L Change microphone level for command and control"
echo " -g Reset configuration back to default settings"
+ echo " -M Set simulated failure mode"
+ echo " -U Change the random failure mode setting"
+ echo " -N Set next mode or failure"
+ echo " -u Change gpsd state"
+ echo " -k Reset the PacSatSim Configuration"
echo
exit
diff --git a/direwolf-cc.conf b/direwolf-cc.conf
index 26f8805b..af71089d 100644
--- a/direwolf-cc.conf
+++ b/direwolf-cc.conf
@@ -1,2 +1,9 @@
ADEVICE shared_mic hw:CARD=Loopback,DEV=1
DTMF
+MYCALL AMSAT
+CHANNEL 0
+MODEM 1200
+FULLDUP OFF
+TXDELAY 0
+AGWPORT 8200
+KISSPORT 8201
diff --git a/direwolf/direwolf-pacsatsim.conf b/direwolf/direwolf-pacsatsim.conf
new file mode 100644
index 00000000..b96fc68f
--- /dev/null
+++ b/direwolf/direwolf-pacsatsim.conf
@@ -0,0 +1,9 @@
+CHANNEL 0
+MODEM 1200
+DWAIT 0
+SLOTTIME 10
+PERSIST 63
+TXDELAY 1000
+TXTAIL 10
+FULLDUP OFF
+DIGIPEAT 0 0 ^WIDE[3-7]-[1-7]$|^TEST$ ^WIDE[12]-[12]$ TRACE
diff --git a/direwolf/direwolf-transmit-dtmf-beacon.conf b/direwolf/direwolf-transmit-dtmf-beacon.conf
deleted file mode 100644
index 6c022dea..00000000
--- a/direwolf/direwolf-transmit-dtmf-beacon.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0
-MYCALL AMSAT
-CHANNEL 0
-MODEM 1200
-CBEACON dest="DTMF-3" info="10 #" delay=0
diff --git a/direwolf/direwolf-transmit-dtmf-bpsk.conf b/direwolf/direwolf-transmit-dtmf-bpsk.conf
deleted file mode 100644
index a0ae9b54..00000000
--- a/direwolf/direwolf-transmit-dtmf-bpsk.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0
-MYCALL AMSAT
-CHANNEL 0
-MODEM 1200
-CBEACON dest="DTMF-3" info="3 #" delay=0
diff --git a/direwolf/direwolf-transmit-dtmf-cw.conf b/direwolf/direwolf-transmit-dtmf-cw.conf
deleted file mode 100644
index 8629754f..00000000
--- a/direwolf/direwolf-transmit-dtmf-cw.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0
-MYCALL AMSAT
-CHANNEL 0
-MODEM 1200
-CBEACON dest="DTMF-3" info="5 #" delay=0
diff --git a/direwolf/direwolf-transmit-dtmf-fsk.conf b/direwolf/direwolf-transmit-dtmf-fsk.conf
deleted file mode 100644
index f197e583..00000000
--- a/direwolf/direwolf-transmit-dtmf-fsk.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0
-MYCALL AMSAT
-CHANNEL 0
-MODEM 1200
-CBEACON dest="DTMF-3" info="2 #" delay=0
diff --git a/direwolf/direwolf-transmit-dtmf-sstv.conf b/direwolf/direwolf-transmit-dtmf-sstv.conf
deleted file mode 100644
index c58cb77f..00000000
--- a/direwolf/direwolf-transmit-dtmf-sstv.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0
-MYCALL AMSAT
-CHANNEL 0
-MODEM 1200
-CBEACON dest="DTMF-3" info="4 #" delay=0
diff --git a/direwolf/direwolf-transmit-dtmf-aprs.conf b/direwolf/direwolf-transmit-dtmf.conf
similarity index 68%
rename from direwolf/direwolf-transmit-dtmf-aprs.conf
rename to direwolf/direwolf-transmit-dtmf.conf
index 786102cd..f5853dff 100644
--- a/direwolf/direwolf-transmit-dtmf-aprs.conf
+++ b/direwolf/direwolf-transmit-dtmf.conf
@@ -1,5 +1,7 @@
ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0
+PTT GPIO 20
MYCALL AMSAT
CHANNEL 0
MODEM 1200
-CBEACON dest="DTMF-3" info="1 #" delay=0
+KISSPORT 8003
+AGWPORT 8004
diff --git a/direwolf/direwolf.conf b/direwolf/direwolf.conf
deleted file mode 100644
index 701d80b4..00000000
--- a/direwolf/direwolf.conf
+++ /dev/null
@@ -1 +0,0 @@
-ADEVICE plughw:CARD=Loopback,DEV=1 plughw:CARD=Loopback,DEV=0
diff --git a/dtmf_aprs_cc.py b/dtmf_aprs_cc.py
index ad4ef5cf..9ac5909f 100644
--- a/dtmf_aprs_cc.py
+++ b/dtmf_aprs_cc.py
@@ -1,15 +1,20 @@
import sys
from os import system
-import RPi.GPIO as GPIO
-from RPi.GPIO import output
from time import sleep
import logging
logging.basicConfig(format='%(message)s')
# logging.warning('CC-Warning!')
+def blink(times):
+ for i in range(times):
+ system("gpio write 27 0")
+ sleep(0.1)
+ system("gpio write 27 1")
+ sleep(0.1)
+
if __name__ == "__main__":
powerPin = 16
- txLed = 27
+ txLed = 17
change_mode = False
debug_mode = False
counter = 1
@@ -17,259 +22,167 @@ if __name__ == "__main__":
# print("There are arguments!")
if ('d' == sys.argv[1]):
debug_mode = True
-
- for line in sys.stdin:
-# if (debug_mode):
- print(line, end =" ")
- logging.warning(line)
-
-# if '^c' == line.rstrip():
-# break
-
- if ((line.find("MODE=a")) > 0):
- system("echo '\nAPRS Mode!!\n'")
- mode = 'a'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t1#")) > 0):
- system("echo '\nAPRS Mode!!\n'")
- mode = 'a'
- change_mode = True
- if ((line.find("MODE=f")) > 0):
- system("echo '\nFSK Mode!!\n'")
- mode = 'f'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t2#")) > 0):
- system("echo '\nFSK Mode!!\n'")
- mode = 'f'
- change_mode = True
- if ((line.find("MODE=b")) > 0):
- system("echo '\nBPSK Mode!!\n'")
- mode = 'b'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t3#")) > 0):
- system("echo '\nBPSK Mode!!\n'")
- mode = 'b'
- change_mode = True
- if ((line.find("MODE=s")) > 0):
- system("echo '\nSSTV Mode!!\n'")
- mode = 's'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t4#")) > 0):
- system("echo '\nSSTV Mode!!\n'")
- mode = 's'
- change_mode = True
- if ((line.find("MODE=m")) > 0):
- system("echo '\nCW Mode!!\n'")
- mode = 'm'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t5#")) > 0):
- system("echo '\nCW Mode!!\n'")
- mode = 'm'
- change_mode = True
- if ((line.find("MODE=e")) > 0):
- system("echo '\nRepeater Mode!!\n'")
- mode = 'e'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t6#")) > 0):
- system("echo '\nRepeater Mode!!\n'")
- mode = 'e'
- change_mode = True
- if ((line.find("MODE=j")) > 0):
- system("echo '\nFUNcube Mode!!\n'")
- mode = 'j'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t7#")) > 0):
- system("echo '\nFUNcube Mode!!\n'")
- mode = 'j'
- change_mode = True
- if ((line.find("MODE=n")) > 0):
- system("echo '\nTransmit Commands Mode!!\n'")
- mode = 'n'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t11#")) > 0):
- system("echo '\nTransmit Commands Mode!!\n'")
- mode = 'n'
- change_mode = True
- if ((line.find("MODE=o")) > 0):
- system("echo '\nBeacon Mode toggle!!\n'")
- mode = 'o'
- change_mode = True
- counter = (counter + 1) % 2
- if ((line.find("DTMF>APDW15:t10#")) > 0):
- system("echo '\nBeacon Mode toggle!!\n'")
- mode = 'o'
- change_mode = True
-
-# if (debug_mode == False) and (change_mode == True) and (counter == 1): # skip every other APRS command since Direwolf prints them twice
- if (debug_mode == False) and (change_mode == True): # skip every other APRS command since Direwolf prints them twice
- GPIO.setmode(GPIO.BCM)
- GPIO.setwarnings(False)
- GPIO.setup(powerPin, GPIO.OUT)
- GPIO.setup(txLed, GPIO.OUT)
-
- if (mode == 'f'):
- GPIO.output(powerPin, 0) # blink two times
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(1)
-
- elif (mode == 'b'):
- GPIO.output(powerPin, 0) # blink three times
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(1)
-
- elif (mode == 's'):
- GPIO.output(powerPin, 0) # blink four times
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(1)
+ while True:
+ try:
+ for line in sys.stdin:
+ # if (debug_mode):
+ print(line, end =" ")
+ logging.warning(line)
+
+ # if '^c' == line.rstrip():
+ # break
- elif (mode == 'm'):
- GPIO.output(powerPin, 0) # blink five times
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1);
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(1)
+ if ((line.find("MODE=a")) > 0):
+ system("echo '\nAPRS Mode!!\n'")
+ mode = 'a'
+ change_mode = True
+
+ elif ((line.find(":t1#")) > 0):
+ system("echo '\nAPRS Mode!!\n'")
+ mode = 'a'
+ change_mode = True
+ elif ((line.find("MODE=f")) > 0):
+ system("echo '\nFSK Mode!!\n'")
+ mode = 'f'
+ change_mode = True
+
+ elif ((line.find(":t2#")) > 0):
+ system("echo '\nFSK Mode!!\n'")
+ mode = 'f'
+ change_mode = True
+
+ elif ((line.find("MODE=b")) > 0):
+ system("echo '\nBPSK Mode!!\n'")
+ mode = 'b'
+ change_mode = True
+
+ elif ((line.find(":t3#")) > 0):
+ system("echo '\nBPSK Mode!!\n'")
+ mode = 'b'
+ change_mode = True
+ elif ((line.find("MODE=s")) > 0):
+ system("echo '\nSSTV Mode!!\n'")
+ mode = 's'
+ change_mode = True
+
+ elif ((line.find(":t4#")) > 0):
+ system("echo '\nSSTV Mode!!\n'")
+ mode = 's'
+ change_mode = True
+
+ elif ((line.find("MODE=m")) > 0):
+ system("echo '\nCW Mode!!\n'")
+ mode = 'm'
+ change_mode = True
+
+ elif ((line.find(":t5#")) > 0):
+ system("echo '\nCW Mode!!\n'")
+ mode = 'm'
+ change_mode = True
+
+ elif ((line.find("MODE=e")) > 0):
+ system("echo '\nRepeater Mode!!\n'")
+ mode = 'e'
+ change_mode = True
+
+ elif ((line.find(":t6#")) > 0):
+ system("echo '\nFUNcube Mode!!\n'")
+ mode = 'j'
+ change_mode = True
+
+ elif ((line.find("MODE=G")) > 0):
+ system("echo '\nPacSatSim Mode!!\n'")
+ mode = 'p'
+ change_mode = True
+
+ elif ((line.find(":t8#")) > 0):
+ system("echo '\nPacSatSim Mode!!\n'")
+ mode = 'p'
+ change_mode = True
+
+ elif ((line.find("MODE=n")) > 0):
+ system("echo '\nTransmit Commands Mode!!\n'")
+ mode = 'n'
+ change_mode = True
+
+ elif ((line.find(":t11#")) > 0):
+ system("echo '\nTransmit Commands Mode!!\n'")
+ mode = 'n'
+ change_mode = True
- elif (mode == 'e'):
- GPIO.output(powerPin, 0) # blink six times
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1);
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(1)
-
- elif (mode == 'j'):
- GPIO.output(powerPin, 0) # blink seven times
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1);
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(0.1)
- GPIO.output(powerPin, 0)
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(1)
-
- elif (mode == 'a'):
- mode = 'a'
- GPIO.output(powerPin, 0) # blink one time
- sleep(0.1)
- GPIO.output(powerPin, 1)
- sleep(1)
-
- try:
- file = open("/home/pi/CubeSatSim/command_count.txt", "r")
- string = file.read()
- file.close()
- command_count = int(string)
- command_count += 1
- filec = open("/home/pi/CubeSatSim/command_count.txt", "w")
- command_count_string = str(command_count)
- print(command_count_string)
- string = filec.write(command_count_string)
- filec.close()
- except:
- print("Can't write command_count file!")
- print("Command_count: ")
- print(command_count)
-
- GPIO.output(txLed, 0)
- GPIO.output(powerPin, 0)
- system("sudo systemctl stop rpitx")
-# system("sudo systemctl stop cubesatsim")
-
- print("\n/home/pi/CubeSatSim/config -" + mode)
- system("/home/pi/CubeSatSim/config -" + mode)
+ elif ((line.find("MODE=o")) > 0):
+ system("echo '\nBeacon Mode toggle!!\n'")
+ mode = 'o'
+ change_mode = True
+# counter = (counter + 1) % 2
+
+ elif ((line.find(":t10#")) > 0):
+ system("echo '\nBeacon Mode toggle!!\n'")
+ mode = 'o'
+ change_mode = True
+
+ if (debug_mode == False) and (change_mode == True) and (counter == 1): # skip every other APRS command since Direwolf prints them twice
+
+ if (mode == 'f'):
+ blink(2)
+ sleep(1)
+
+ elif (mode == 'b'):
+ blink(3)
+ sleep(1)
+
+ elif (mode == 's'):
+ blink(4)
+ sleep(1)
+
+ elif (mode == 'm'):
+ blink(5)
+ sleep(1)
+
+ elif (mode == 'e'):
+ blink(6)
+ sleep(1)
+
+ elif (mode == 'j'):
+ blink(7)
+ sleep(1)
+
+ elif (mode == 'p'):
+ blink(8)
+ sleep(1)
+
+ elif (mode == 'a'):
+ blink(1)
+ sleep(1)
+
+ try:
+ file = open("/home/pi/CubeSatSim/command_count.txt", "r")
+ string = file.read()
+ file.close()
+ command_count = int(string)
+ command_count += 1
+ filec = open("/home/pi/CubeSatSim/command_count.txt", "w")
+ command_count_string = str(command_count)
+ print(command_count_string)
+ string = filec.write(command_count_string)
+ filec.close()
+ except:
+ print("Can't write command_count file!")
+ print("Command_count: ")
+ print(command_count)
+ system("gpio write " + str(txLed) + " 0")
+ system("gpio write " + str(powerPin) + " 0")
+ system("sudo systemctl stop transmit")
+ # system("sudo systemctl stop cubesatsim")
+
+ print("\n/home/pi/CubeSatSim/config -" + mode)
+ system("/home/pi/CubeSatSim/config -" + mode)
+
+ change_mode = False
+ except:
+ print("Error reading line (probably due to UTF-8 issue)")
-
- change_mode = False
-
print("Waiting 5 seconds to allow unplug and plug of soundcard")
sleep(5)
print("Done")
diff --git a/gps_client.py b/gps_client.py
new file mode 100644
index 00000000..87c4aa45
--- /dev/null
+++ b/gps_client.py
@@ -0,0 +1,72 @@
+#! /usr/bin/env python3
+"""
+example Python gpsd client
+run this way: python3 example1.py.txt
+"""
+
+# from https://gpsd.gitlab.io/gpsd/gpsd-client-example-code.html
+
+# this client is for the CubeSatSim Lite which does not have a Pico microcontroller
+
+try:
+
+ import gps # the gpsd interface module
+ import time
+
+ mode = -1
+ lat = 0
+ lon = 0
+ alt = 0
+
+ session = gps.gps(mode=gps.WATCH_ENABLE)
+
+ start = time.perf_counter()
+
+ try:
+# while (session.read() == 0) and ((time.perf_counter() - start) < 2) and (mode < 2):
+ while ((time.perf_counter() - start) < 2) and (mode < 2):
+ if session.waiting(2.0):
+ session.read()
+
+ # print(gps.MODE_SET)
+ # print(session.valid)
+ if (session.valid):
+ # not useful, probably not a TPV message
+ # continue
+
+ # print('Mode: %s(%d) Time: ' %
+ # (("Invalid", "NO_FIX", "2D", "3D")[session.fix.mode],
+ # session.fix.mode), end="")
+ # print time, if we have it
+# print("%d " % session.fix.mode, end="")
+ if (session.fix.mode > mode):
+ mode = session.fix.mode
+ # if gps.TIME_SET & session.valid:
+ # print(session.fix.time, end="")
+ # else:
+ # print('n/a', end="")
+
+ if gps.isfinite(session.fix.latitude):
+ lat = session.fix.latitude
+ if gps.isfinite(session.fix.longitude):
+ lon = session.fix.longitude
+ if gps.isfinite(session.fix.altitude):
+ alt = session.fix.altitude
+# print("%.6f %.6f %.6f" % (session.fix.latitude, session.fix.longitude, session.fix.altitude))
+
+ # else:
+ # print(" 0 0 0")
+
+ except KeyboardInterrupt:
+ # got a ^C. Say bye, bye
+ print('')
+
+ # Got ^C, or fell out of the loop. Cleanup, and leave.
+ session.close()
+ print("%d %.6f %.6f %.1f" % (mode, lat, lon, alt))
+# exit(0)
+
+except:
+ print("-1 0 0 0")
+ exit(0)
+
diff --git a/groundstation/SDRpp.desktop b/groundstation/SDRpp.desktop
new file mode 100644
index 00000000..f4f4ba38
--- /dev/null
+++ b/groundstation/SDRpp.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Type=Application
+Exec=/home/pi/CubeSatSim/groundstation/sdrpp.sh
+Name=SDRpp
+Comment=SDRpp
+Icon=/home/pi/Icons/sdrpp.png
+Path=/home/pi
+Terminal=true
+Categories=HamRadio
+Keywords=Ham Radio;SDR
diff --git a/groundstation/aprs.desktop b/groundstation/aprs.desktop
index b9ee2512..a7d0062a 100644
--- a/groundstation/aprs.desktop
+++ b/groundstation/aprs.desktop
@@ -2,7 +2,7 @@
Name=APRS Decode using Direwolf
GenericName=Decodes APRS using rtl_fm and Direwolf
Comment=APRS signals
-Exec=/home/pi/CubeSatSim/groundstation/aprs.sh
+Exec=/usr/bin/x-terminal-emulator --geometry=120x40 -e "/home/pi/CubeSatSim/groundstation/packet.sh"
Icon=/home/pi/Icons/aprs.png
Terminal=true
Type=Application
diff --git a/groundstation/aprs.sh b/groundstation/aprs.sh
index 2e1c6873..427c36cb 100755
--- a/groundstation/aprs.sh
+++ b/groundstation/aprs.sh
@@ -3,12 +3,14 @@
sudo modprobe snd-aloop
-sudo systemctl stop openwebrx
+sudo systemctl stop openwebrx &>/dev/null
-sudo systemctl stop rtl_tcp
+sudo systemctl stop rtl_tcp &>/dev/null
pkill -o chromium &>/dev/null
+sudo killall -9 sdrpp &>/dev/null
+
sudo killall -9 rtl_fm &>/dev/null
sudo killall -9 direwolf &>/dev/null
@@ -78,7 +80,7 @@ echo -e "Auto decoding APRS packets on $frequency Hz"
#sudo rtl_fm -f 144.39M -s 22050 -g 48 - | multimon-ng -a AFSK1200 -A -t raw -
-direwolf -r 48000 -t 0 &
+direwolf -c /home/pi/CubeSatSim/groundstation/direwolf.conf -r 48000 -t 0 &
sleep 5
@@ -87,6 +89,7 @@ echo "$value" > /dev/null
set -- $value
#rtl_fm -M fm -f 144.39M -s 48k | aplay -D hw:${2:0:1},0,0 -r 48000 -t raw -f S16_LE -c 1
-rtl_fm -M fm -f $frequency -s 48k | tee >(aplay -D hw:${2:0:1},0,0 -r 48000 -t raw -f S16_LE -c 1) | aplay -D hw:0,0 -r 48000 -t raw -f S16_LE -c 1
+#rtl_fm -M fm -f $frequency -s 48k | tee >(aplay -D hw:${2:0:1},0,0 -r 48000 -t raw -f S16_LE -c 1) | aplay -D hw:0,0 -r 48000 -t raw -f S16_LE -c 1
+rtl_fm -M fm -f $frequency -s 48k | aplay -D hw:${2:0:1},0,0 -r 48000 -t raw -f S16_LE -c 1
sleep 5
diff --git a/groundstation/autostart/chromium.desktop b/groundstation/autostart/chromium.desktop
index fc57834e..5fd6bef0 100644
--- a/groundstation/autostart/chromium.desktop
+++ b/groundstation/autostart/chromium.desktop
@@ -2,4 +2,4 @@
[Desktop Entry]
Type=Application
Name=Chromium with WebSDR
-Exec=chromium-browser --check-for-update-interval=1 --simulate-critical-update --noerrdialogs --disable-infobars http://127.0.0.1:8073
+Exec=chromium-browser --check-for-update-interval=1 --simulate-critical-update --noerrdialogs --disable-infobars --app=http://localhost:8073
diff --git a/groundstation/bookmarks.json b/groundstation/bookmarks.json
index f8bae496..b3c55a2c 100644
--- a/groundstation/bookmarks.json
+++ b/groundstation/bookmarks.json
@@ -1,137 +1,57 @@
[
- {
- "name": "ISS APRS",
- "frequency": 145825000,
- "modulation": "nfm"
- },
- {
- "name": "ISS SSTV/Voice",
- "frequency": 145800000,
- "modulation": "nfm"
- },
- {
- "name": "ARISS Repeater Downlink",
- "frequency": 437800000,
- "modulation": "nfm"
- },
- {
- "name": "AO-27",
- "frequency": 436795000,
- "modulation": "nfm"
- },
- {
- "name": "AO-73",
- "frequency": 145815000,
- "modulation": "usb"
- },
- {
- "name": "Fox-1B AO-91",
- "frequency": 145960000,
- "modulation": "nfm"
- },
- {
- "name": "Fox-1D AO-92",
- "frequency": 145880000,
- "modulation": "nfm"
- },
- {
- "name": "HuskySat-1 HO-107",
- "frequency": 435800000,
- "modulation": "usb"
- },
- {
- "name": "Fox-1E",
- "frequency": 435750000,
- "modulation": "usb"
- },
- {
- "name": "MAX VALIER",
- "frequency": 145860000,
- "modulation": "usb"
- },
- {
- "name": "NOAA WX Radio 1",
- "frequency": 162400000,
- "modulation": "nfm"
- },
- {
- "name": "NOAA WX Radio 2",
- "frequency": 162425000,
- "modulation": "nfm"
- },
- {
- "name": "NOAA WX Radio 3",
- "frequency": 162450000,
- "modulation": "nfm"
- },
- {
- "name": "NOAA WX Radio 4",
- "frequency": 162475000,
- "modulation": "nfm"
- },
- {
- "name": "NOAA WX Radio 5",
- "frequency": 162500000,
- "modulation": "nfm"
- },
- {
- "name": "NOAA WX Radio 6",
- "frequency": 162525000,
- "modulation": "nfm"
- },
- {
- "name": "NOAA WX Radio 7",
- "frequency": 162550000,
- "modulation": "nfm"
- },
- {
- "name": "CAS-4A",
- "frequency": 145855000,
- "modulation": "usb"
- },
- {
- "name": "CAS-4B",
- "frequency": 145910000,
- "modulation": "usb"
- },
- {
- "name": "XW-2A",
- "frequency": 145660000,
- "modulation": "usb"
- },
- {
- "name": "XW-2B",
- "frequency": 145725000,
- "modulation": "usb"
- },
- {
- "name": "XW-2C",
- "frequency": 145790000,
- "modulation": "usb"
- },
- {
- "name": "XW-2F",
- "frequency": 145975000,
- "modulation": "usb"
- },
- {
- "name": "NOAA-19",
- "frequency": 137100000,
- "modulation": "nfm"
- },
- {
- "name": "NOAA-18",
- "frequency": 137912500,
- "modulation": "nfm"
- },
- {
- "name": "NOAA-15",
- "frequency": 137620000,
- "modulation": "nfm"
- },
- {
- "name": "CubeSatSim",
- "frequency": 434900000,
- "modulation": "packet"
- }
+ {
+ "name": "NOAA WX Radio 1",
+ "frequency": 162400000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "NOAA WX Radio 2",
+ "frequency": 162425000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "NOAA WX Radio 3",
+ "frequency": 162450000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "NOAA WX Radio 4",
+ "frequency": 162475000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "NOAA WX Radio 5",
+ "frequency": 162500000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "NOAA WX Radio 6",
+ "frequency": 162525000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "NOAA WX Radio 7",
+ "frequency": 162550000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "CubeSatSim",
+ "frequency": 434900000,
+ "modulation": "packet"
+ },
+ {
+ "name": "ISS SSTV/Voice",
+ "frequency": 145800000,
+ "modulation": "nfm"
+ },
+ {
+ "name": "ISS APRS",
+ "frequency": 145825000,
+ "modulation": "packet"
+ },
+ {
+ "name": "ISS Voice Repeater",
+ "frequency": 437800000,
+ "modulation": "nfm"
+ }
]
diff --git a/groundstation/cubicsdr.desktop b/groundstation/cubicsdr.desktop
index 1599f5df..2cf19759 100644
--- a/groundstation/cubicsdr.desktop
+++ b/groundstation/cubicsdr.desktop
@@ -3,7 +3,7 @@ Type=Application
Exec=/home/pi/CubeSatSim/groundstation/cubicsdr.sh
Name=SDR FM Broadcast
Comment=CubicSDR FM Broadcast
-Icon=/home/pi/Downloads/cubicsdr.png
+Icon=/home/pi/Icons/cubicsdr.png
Path=/home/pi
Terminal=true
Categories=HamRadio
diff --git a/groundstation/cubicsdr.sh b/groundstation/cubicsdr.sh
index 5d66f4c3..3b125dc6 100755
--- a/groundstation/cubicsdr.sh
+++ b/groundstation/cubicsdr.sh
@@ -9,19 +9,21 @@ echo "Note: Select Generic RTL2832 device then click Start to begin"
echo
-sudo systemctl stop openwebrx
+sudo systemctl stop openwebrx &>/dev/null
sudo killall -9 java &>/dev/null
-sudo systemctl stop rtl_tcp
+sudo systemctl stop rtl_tcp &>/dev/null
pkill -o chromium &>/dev/null
+sudo killall -9 sdrpp &>/dev/null
+
sudo killall -9 rtl_fm &>/dev/null
sudo killall -9 direwolf &>/dev/null
-sudo killall -9 aplay &>/dev/null
+#sudo killall -9 aplay &>/dev/null
sudo killall -9 qsstv &>/dev/null
@@ -39,11 +41,28 @@ sudo killall -9 sdrpp &>/dev/null
sudo killall -9 zenity &>/dev/null
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
sudo killall -9 rtl_fm &>/dev/null
zenity --info --width=650 --height=140 --title="Instructions" --text="When CubicSDR opens, select Generic RTL2832U device then click Start to begin.\n\nThen click on a signal in the watefall to listen." &
+sleep 5
+
+setsid CubicSDR
+
+sleep 10
+#$SHELL
+#sudo kill `ps -aux | grep sstv_decode_prompt| grep -v grep | awk '{ print $2 }'` &>/dev/null && killall inotifywait &>/dev/null
+
+sudo killall -9 zenity &>/dev/null
+
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
+zenity --info --width=650 --height=140 --title="Instructions" --text="When CubicSDR opens, select Generic RTL2832U device then click Start to begin.\n\nThen click on a signal in the watefall to listen." &
sleep 5
diff --git a/groundstation/direwolf.conf b/groundstation/direwolf.conf
index ce8b6823..d70427b9 100644
--- a/groundstation/direwolf.conf
+++ b/groundstation/direwolf.conf
@@ -1 +1 @@
-ADEVICE plughw:CARD=Loopback,DEV=1 plughw:CARD=b1,DEV=0
+ADEVICE plughw:CARD=Loopback,DEV=1 default
diff --git a/groundstation/direwolf/direwolf-pacsat.conf b/groundstation/direwolf/direwolf-pacsat.conf
new file mode 100644
index 00000000..3b9d337b
--- /dev/null
+++ b/groundstation/direwolf/direwolf-pacsat.conf
@@ -0,0 +1,9 @@
+CHANNEL 0
+MODEM 1200
+KISSPORT 8100
+AGWPORT 8002
+DWAIT 20
+SLOTTIME 300
+PERSIST 63
+TXDELAY 1000
+FULLDUP OFF
diff --git a/groundstation/fox-download.desktop b/groundstation/fox-download.desktop
index d58827d0..4e4bcf40 100644
--- a/groundstation/fox-download.desktop
+++ b/groundstation/fox-download.desktop
@@ -2,7 +2,7 @@
Type=Application
Exec=/home/pi/CubeSatSim/groundstation/fox-download.sh
Name=FoxTelem Download
-Comment=FIAB-v3
+Comment=FIAB-v4
Icon=/home/pi/Icons/FoxTelemDownload.png
Path=/home/pi
Terminal=true
diff --git a/groundstation/fox-profile.desktop b/groundstation/fox-profile.desktop
index c03f40d4..8b7aaabe 100644
--- a/groundstation/fox-profile.desktop
+++ b/groundstation/fox-profile.desktop
@@ -2,8 +2,8 @@
Type=Application
Exec=/home/pi/CubeSatSim/groundstation/fox-profile.sh
Name=Change FoxTelem Profile
-Comment=FIAB-v3
-Icon=/home/pi/Downloads/foxtelem.png
+Comment=FIAB-v4
+Icon=/home/pi/Icons/foxtelem.png
Path=/home/pi
Terminal=true
Categories=HamRadio
diff --git a/groundstation/fox-run.sh b/groundstation/fox-run.sh
index fa456cd1..d321719d 100755
--- a/groundstation/fox-run.sh
+++ b/groundstation/fox-run.sh
@@ -5,6 +5,8 @@ echo "Startup script to run FoxTelem for FIAB v4"
echo
+source /home/pi/venv/bin/activate
+
sudo killall -9 FoxTelem &>/dev/null
sudo killall -9 zenity &>/dev/null
@@ -12,7 +14,7 @@ sudo killall -9 zenity &>/dev/null
FILE=/home/pi/FoxTelemetryData/.foxprofile
if [ ! -f "$FILE" ]; then
- profile=$(zenity --text="Choose your default FoxTelem profile:" --list 2>/dev/null --width=410 --height=120 --title="Set FoxTelem Profile" --column="Profile" --column="Receive and decode telemetry from" Fox-in-a-Box "AMSAT Fox satellites" "CubeSatSim" "AMSAT CubeSat Simulator")
+ profile=$(zenity --text="Choose your default FoxTelem profile:" --list 2>/dev/null --width=410 --height=120 --title="Set FoxTelem Profile" --column="Profile" --column="Receive and decode telemetry from" Fox-in-a-Box "AMSAT Satellites" "CubeSatSim" "AMSAT CubeSat Simulator")
echo $profile
diff --git a/groundstation/fox.sh b/groundstation/fox.sh
index 9e1f4130..27050f9a 100755
--- a/groundstation/fox.sh
+++ b/groundstation/fox.sh
@@ -5,12 +5,14 @@ echo "Script to run FoxTelem for ARISS Radio Pi"
echo
-sudo systemctl stop openwebrx
+sudo systemctl stop openwebrx &>/dev/null
-sudo systemctl stop rtl_tcp
+sudo systemctl stop rtl_tcp &>/dev/null
pkill -o chromium &>/dev/null
+sudo killall -9 sdrpp &>/dev/null
+
sudo killall -9 rtl_tcp &>/dev/null
sudo killall -9 rtl_fm &>/dev/null
@@ -23,12 +25,15 @@ sudo killall -9 sdrpp &>/dev/null
sudo killall -9 direwolf &>/dev/null
-sudo killall -9 aplay &>/dev/null
+#sudo killall -9 aplay &>/dev/null
sudo killall -9 qsstv &>/dev/null
sudo killall -9 zenity &>/dev/null
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
sudo killall -9 rtl_fm &>/dev/null
sleep 5
diff --git a/groundstation/foxtelem.desktop b/groundstation/foxtelem.desktop
index 9dc42ab9..c01913be 100644
--- a/groundstation/foxtelem.desktop
+++ b/groundstation/foxtelem.desktop
@@ -2,8 +2,8 @@
Type=Application
Exec=/home/pi/CubeSatSim/groundstation/fox-run.sh
Name=FoxTelem
-Comment=FIAB-v3
-Icon=/home/pi/Downloads/foxtelem.png
+Comment=FIAB-v4
+Icon=/home/pi/Icons/foxtelem.png
Path=/home/pi
Terminal=true
Categories=HamRadio
diff --git a/groundstation/gpredict.desktop b/groundstation/gpredict.desktop
index 20a6ab49..69d11ecb 100644
--- a/groundstation/gpredict.desktop
+++ b/groundstation/gpredict.desktop
@@ -3,7 +3,7 @@ Type=Application
Exec=/usr/bin/gpredict
Name=Gpredict
Comment=ISS and Satellite Tracking for ARISS Radio Pi
-Icon=/home/pi/Downloads/gpredict.png
+Icon=/home/pi/Icons/gpredict.png
Path=/home/pi
Terminal=false
Categories=HamRadio
diff --git a/groundstation/loc-add-foxtelem.py b/groundstation/loc-add-foxtelem.py
index 64c47bbd..1f4279cc 100644
--- a/groundstation/loc-add-foxtelem.py
+++ b/groundstation/loc-add-foxtelem.py
@@ -118,6 +118,16 @@ if (latitude != 0) and (longitude != 0):
system(longSedStr)
print("\nKLAtracker configuration updated with your latitude and longitude")
+
+ latSedStr = 'sed -i "s/latitude=.*/latitude=' + str(latitude) + '/g" /home/pi/PacSatGround/PacSatGround.properties'
+ #print (latSedStr)
+ system(latSedStr)
+
+ longSedStr = 'sed -i "s/longitude=.*/longitude=' + str(longitude) + '/g" /home/pi/PacSatGround/PacSatGround.properties'
+ #print (longSedStr)
+ system(longSedStr)
+
+ print("\nPacsat configuration updated with your latitude and longitude")
receiver_gpsSedStr = 'sudo sed -i "s/ ' + dquote + 'lat' + dquote + ': .*/ ' + dquote + 'lat' + dquote + ': ' + str(latitude) + ',/g" /var/lib/openwebrx/settings.json'
#print (receiver_gpsSedStr)
diff --git a/groundstation/loc.sh b/groundstation/loc.sh
index bdbedc77..94558962 100755
--- a/groundstation/loc.sh
+++ b/groundstation/loc.sh
@@ -12,4 +12,3 @@ python3 /home/pi/CubeSatSim/groundstation/loc-foxtelem.py
#/usr/bin/gpredict
nohup /usr/bin/gpredict /dev/null 2>&1 &
-
diff --git a/groundstation/packet.sh b/groundstation/packet.sh
index 3835a581..c8fdef00 100755
--- a/groundstation/packet.sh
+++ b/groundstation/packet.sh
@@ -14,6 +14,8 @@ pkill -o chromium &>/dev/null
sudo killall -9 rtl_fm &>/dev/null
+sudo killall -9 sdrpp &>/dev/null
+
sudo killall -9 direwolf &>/dev/null
sudo killall -9 aplay &>/dev/null
@@ -207,5 +209,4 @@ rtl_fm -M fm -f $frequency -s 48k | tee >(aplay -D hw:${2:0:1},0,0 -r 48000 -t r
rtl_fm -M fm -f $frequency -s 48k | aplay -D hw:${2:0:1},0,0 -r 48000 -t raw -f S16_LE -c 1
-
sleep 5
diff --git a/groundstation/pacsat-config.sh b/groundstation/pacsat-config.sh
new file mode 100755
index 00000000..f5b64ff3
--- /dev/null
+++ b/groundstation/pacsat-config.sh
@@ -0,0 +1,206 @@
+#!/bin/bash
+# script to run FoxTelem
+
+echo "Script to configure the PacSat Ground Station for FIAB v4"
+
+echo
+
+#source /home/pi/venv/bin/activate
+
+sudo killall -9 java &>/dev/null
+
+sudo killall -9 zenity &>/dev/null
+
+sudo killall -9 direwolf &>/dev/null
+
+#FILE=/home/pi/.pacsatprofile
+#if [ ! -f "$FILE" ]; then
+
+# profile=$(zenity --text="Choice:" --list 2>/dev/null --width=410 --height=120 --title="PacSat Ground Station Choice" --column="Choice" --column="Result" "PacSat" "Receive from CubeSatSim PacSatSim" "Configure" "Configure PacSat Ground Station" "Loopback" "Run a Locally Simulated PacSat")
+# echo $profile
+
+ echo "Here are the PacSat configuration choices:"
+ echo
+ echo " 1. PacSat Ground Station Configuration"
+ echo
+ echo " 2. PacSat Ground Station Simulation Configuration"
+ echo
+ echo " 3. Set Frequencies"
+ echo
+ echo " 4. Reset PacSat Satellite"
+ echo
+ echo "Which do you choose? Enter 1 - 4"
+ echo
+
+ read -r ANS
+
+ if [ -z "$ANS" ]; then
+
+ echo "No choice made. Exiting."
+
+ sleep 3
+
+ exit
+
+ fi
+
+ if [ "$ANS" = "1" ] || [ "$ANS" = "2" ] ; then
+
+ if [ "$ANS" = "1" ] ; then
+ echo "Here are your PacSat Ground Station Configuration choices:"
+ else
+ echo "Here are your PacSat Ground Station Simulation Configuration choices:"
+ fi
+ echo
+ echo " 1. PacSat Ground Station Callsign"
+ echo
+ echo " 2. Set Remote PacSat Satellite Callsign in Ground Station configuration"
+ echo
+ echo " 3. Reset PacSat Ground Station Configuration"
+ echo
+
+ read -r CH
+
+
+ if [ -z "$CH" ]; then
+
+ echo "No choice made. Exiting."
+
+ sleep 3
+
+ exit
+
+ fi
+
+ if [ "$CH" = "1" ] ; then
+
+ echo
+ if [ "$ANS" = "1" ] ; then
+ oldcallsign=$(grep -oP '(?<=callsign=).*$' /home/pi/PacSatGround/PacSatGround.properties)
+ else
+ oldcallsign=$(grep -oP '(?<=callsign=).*$' /home/pi/PacSatGroundLoop/PacSatGround.properties)
+ fi
+ echo "Callsign in PacSatGround.properties is "
+ echo $oldcallsign
+
+ echo "Enter new callsign in all capitals: "
+ echo
+ read callsign
+
+ if [ -z $callsign ] ; then
+
+ callsign="$1"
+ echo "Keeping value of" $oldcallsign
+
+ else
+
+ echo "Configured callsign is "
+ echo $callsign
+
+ if [ ! "$callsign" = "$oldcallsign" ] ; then
+
+ if [ "$ANS" = "1" ] ; then
+ sudo sed -i "s/callsign=$oldcallsign/callsign=$callsign/g" /home/pi/PacSatGround/PacSatGround.properties
+ cat /home/pi/PacSatGround/PacSatGround.properties
+ else
+ sudo sed -i "s/callsign=$oldcallsign/callsign=$callsign/g" /home/pi/PacSatGroundLoop/PacSatGround.properties
+ cat /home/pi/PacSatGroundLoop/PacSatGround.properties
+ fi
+
+ fi
+ fi
+
+ elif [ "$CH" = "2" ] ; then
+
+ echo "You have chosen to set the remote CubeSatSim PacSat Satellite callsign in ground station configuration"
+ echo
+
+ PROPERTIES=/home/pi/PacSatGround/spacecraft/PacSatSim.properties
+ PROPERTIES_L=/home/pi/PacSatGroundLoop/spacecraft/PacSatSim.properties
+
+ if [ "$ANS" = "1" ] ; then
+ oldcallsign=$(grep -oP '(?<=bbsCallsign=).*(?=-)' $PROPERTIES )
+ else
+ oldcallsign=$(grep -oP '(?<=bbsCallsign=).*(?=-)' $PROPERTIES_L )
+ fi
+ echo "Current value of remote PacSat callsign is"
+ echo $oldcallsign
+ echo
+
+ echo "Enter new callsign in all capitals: "
+ echo
+ read callsign
+
+ if [ -z $callsign ] ; then
+
+ callsign="$1"
+ echo "Keeping value of" $oldcallsign
+
+ else
+ if [ "$ANS" = "1" ] ; then
+ sudo sed -i "s/$oldcallsign/$callsign/g" $PROPERTIES
+ else
+ sudo sed -i "s/$oldcallsign/$callsign/g" $PROPERTIES_L
+ fi
+ echo
+ echo "Changing callsign to "
+ echo $callsign
+ echo
+ echo "You will see the change next time you run the PacSat Ground Station"
+ echo "You can close this window"
+ fi
+
+ elif [ "$CH" = "3" ] ; then
+
+ echo "You have chosen to reset the PacSat Ground Station Configuration"
+ echo
+# echo "Next time you run the Ground Station you will need to Add the PacSatSim spacecraft"
+# echo
+
+ if [ "$ANS" = "1" ] ; then
+ sudo rm -r /home/pi/PacSatGround
+ # cd
+ # sudo rm PacSatGround.zip
+ # wget https://github.com/alanbjohnston/CubeSatSim/raw/refs/heads/master-b-p-s/spacecraft/PacSatGround_0.46o/PacSatGround.zip
+ # unzip PacSatGround.zip -d PacSatGround
+ # sudo rm PacSatGround.zip
+ else
+ sudo rm -r /home/pi/PacSatGroundLoop
+ # cd
+ # sudo rm PacSatGround.zip
+ # wget https://github.com/alanbjohnston/CubeSatSim/raw/refs/heads/master-b-p-s/spacecraft/PacSatGround_0.46o/PacSatGround.zip
+ # unzip PacSatGround.zip -d PacSatGroundLoop
+ # sudo rm PacSatGround.zip
+ fi
+ echo "You can close this window now"
+ else
+
+ echo "Please choose an option 1-3"
+ echo
+
+ fi
+
+ elif [ "$ANS" = "3" ] ; then
+
+ echo "You have chosen to set the Frequency of the PacSat Ground Station"
+ echo
+
+ /home/pi/CubeSatSim/config -F n
+
+ elif [ "$ANS" = "4" ] ; then
+
+ echo "You have chosen to reset the PacSat Satellite"
+ echo
+
+ /home/pi/CubeSatSim/config -k n
+
+ else
+
+ echo "Please enter only 1 to 4"
+
+ fi
+
+
+# sleep 10
+
+#$SHELL
diff --git a/groundstation/pacsat-run.sh b/groundstation/pacsat-run.sh
new file mode 100755
index 00000000..d19b9dba
--- /dev/null
+++ b/groundstation/pacsat-run.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+# script to run FoxTelem
+
+echo "Startup script to run the PacSat Ground Station for FIAB v4"
+
+echo
+
+# source /home/pi/venv/bin/activate
+
+sudo killall -9 java &>/dev/null
+
+sudo killall -9 zenity &>/dev/null
+
+sudo killall -9 direwolf &>/dev/null
+
+#FILE=/home/pi/.pacsatprofile
+#if [ ! -f "$FILE" ]; then
+
+ profile=$(zenity --text="Choose what you want to do:" --list 2>/dev/null --width=410 --height=220 --title="PacSat Ground Station" --column="Choice" --column="Result" "PacSat" "Run PacSat Ground Station" "Configure" "Configure the Pacsat Ground Station" "Simulate" "Run a Locally Simulated PacSat")
+
+ echo $profile
+
+ if [ -z "$profile" ]; then
+
+ echo "No choice made. Exiting."
+
+ sleep 3
+
+ exit
+
+ #echo "You need to choose your default FoxTelem profile."
+ #echo
+ #echo "The choices are:"
+ #echo
+ #echo "1. Fox-in-a-Box. Use this profile if you want to receive and decode telemetry from the AMSAT Fox satellites. If you enter a callsign and a grid square, you can upload to the AMSAT telemetry server."
+ #echo
+ #echo "2. CubeSatSim Ground Station. Use this profile if you want to receive and decode telemetry from an AMSAT CubeSatSim or CubeSatSim Lite."
+ #echo
+ #echo "Which profile do you choose? Enter 1 or 2"
+
+ #read -r ANS
+
+ fi
+
+ if [ "$ANS" = "1" ] || [ "$profile" = "PacSat" ] ; then
+
+ echo "You have chosen to run the PacSat Ground Station"
+ # echo "p" > /home/pi/.pacsatprofile
+ echo
+
+ /home/pi/CubeSatSim/groundstation/pacsat.sh
+
+
+ elif [ "$ANS" = "2" ] || [ "$profile" = "Configure" ] ; then
+
+ echo "You have chosen to configure the PacSat Ground Station"
+ echo
+
+ /home/pi/CubeSatSim/groundstation/pacsat-config.sh
+
+ elif [ "$ANS" = "3" ] || [ "$profile" = "Simulate" ] ; then
+
+ sudo systemctl stop transmit
+
+ echo "You have chosen the PacSat Ground Station with Local Simulated Satellite"
+
+ sleep 1
+
+ /usr/bin/x-terminal-emulator --geometry=120x40 -e "bash /home/pi/CubeSatSim/pacsatsim.sh l"
+
+ sleep 1
+
+ /home/pi/CubeSatSim/groundstation/pacsat.sh l
+
+ else
+
+ echo "Please enter only 1 or 2 or 3"
+
+ fi
+
+sudo killall -9 direwolf &>/dev/null
+
+sleep 10
+
+#$SHELL
diff --git a/groundstation/pacsat.desktop b/groundstation/pacsat.desktop
new file mode 100644
index 00000000..7097509e
--- /dev/null
+++ b/groundstation/pacsat.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Name=Pacsat
+GenericName=Pacsat Loopback
+Comment=Pacsat
+Exec=/usr/bin/x-terminal-emulator --geometry=120x40 -e "/home/pi/CubeSatSim/groundstation/pacsat-run.sh"
+Icon=/home/pi/Icons/pacsat.png
+Terminal=true
+Type=Application
+Categories=HamRadio;
+Keywords=APRS;
diff --git a/groundstation/pacsat.sh b/groundstation/pacsat.sh
new file mode 100755
index 00000000..58c803c7
--- /dev/null
+++ b/groundstation/pacsat.sh
@@ -0,0 +1,317 @@
+#!/bin/bash
+
+# script to auto decode packets using Direwolf and FM TXC and run Pacsat Ground Station
+
+sudo pkill -f "/home/pi/CubeSatSim/groundstation/direwolf-pacsat-tmp.conf"
+
+loopback=0
+vox=0
+safe=0
+card=0
+pwm=0
+
+if [ "$1" = "l" ] ; then
+
+ loopback=1
+
+elif [ "$1" = "v" ] ; then
+
+ vox=1
+
+elif [ "$1" = "c" ] ; then
+
+ card=1
+
+else
+
+ pwm=1
+
+fi
+
+if [[ $(arecord -l | grep "USB Audio Device") ]] ; then
+ echo "USB Sound Card detected"
+ soundcard=1
+else
+ echo "No USB Sound Card detected"
+ soundcard=0
+fi
+
+gpio -g mode 7 up
+if [[ $(gpio -g read 7 | grep 0) ]] ; then
+ echo "TXC is present"
+ txc=1
+else
+ echo "TXC not present"
+ txc=0
+fi
+
+timeout 1 rtl_test &> out.txt
+if [[ $(grep "No supported" out.txt) ]] ; then
+ echo "No RTL-SDR detected"
+ rtl=0
+else
+ echo "RTL-SDR detected."
+ rtl=1
+fi
+
+FILE=/home/pi/CubeSatSim/battery_saver
+if [ -f "$FILE" ]; then
+
+ safe=1
+
+fi
+
+value=`cat /home/pi/CubeSatSim/.mode`
+echo "$value" > /dev/null
+set -- $value
+
+MODE=$1
+
+if [ ! "$MODE" = "P" ] && [ ! "$loopback" = "1" ] ; then
+
+ echo
+ echo "Mode is not PacSat Ground Station"
+ echo
+ echo "Would you like to change to PacSat Ground Station mode and reboot? (y/n)?"
+
+ read -r ANS
+
+ if [ "$ANS" = "y" ]; then
+
+ /home/pi/CubeSatSim/config -I
+ exit
+
+ else
+
+ echo
+ echo "You can run the PacSat Ground Station after you change mode and reboot."
+ sleep 10
+ exit
+
+ fi
+
+elif [ "$loopback" = "1" ] ; then
+
+# if [ ! "$MODE" = "p" ] ; then
+ echo
+ echo "Switching to PacSat mode for the Simulated PacSat Satellite"
+ echo
+ /home/pi/CubeSatSim/config -G n
+# fi
+
+ if [ ! -d "/home/pi/PacSatGroundLoop" ] ; then
+# if [ ! "$loopback" = "1" ] ; then # don't do this for now.
+
+ cd
+ sudo rm PacSatGroundLoop.zip &>/dev/null
+ wget https://github.com/alanbjohnston/CubeSatSim/raw/refs/heads/master-b/spacecraft/PacSatGround_0.46o/PacSatGround.zip
+ unzip PacSatGround.zip -d PacSatGroundLoop
+ sudo rm PacSatGround.zip
+
+ sudo sed -i 's/logfile_dir=\/home\/pi\/PacSatGround/logfile_dir=\/home\/pi\/PacSatGroundLoop/g' /home/pi/PacSatGroundLoop/PacSatGround.properties
+
+ FILE=/home/pi/Desktop/PacsatGround/spacecraft/PacSatSim.properties
+ if [ -f "$FILE" ]; then
+ FILE2=/home/pi/PacSatGroundLoop/spacecraft/PacSatSim.properties
+ sudo rm $FILE2
+ cp $FILE $FILE2
+ else
+ echo
+ echo "The first time you run the Ground Station, you will need to select Yes to override files, then put in your callsign"
+ sleep 10
+ fi
+ fi
+
+else
+
+ echo
+ echo "Mode is PacSat Ground Station"
+ echo
+
+ if [ ! -d "/home/pi/PacSatGround" ] ; then
+
+ cd
+ sudo rm PacSatGround.zip &>/dev/null
+ wget https://github.com/alanbjohnston/CubeSatSim/raw/refs/heads/master-b/spacecraft/PacSatGround_0.46o/PacSatGround.zip
+ unzip PacSatGround.zip -d PacSatGround
+ sudo rm PacSatGround.zip
+
+ FILE=/home/pi/Desktop/PacsatGround/spacecraft/PacSatSim.properties
+ if [ -f "$FILE" ]; then
+ FILE2=/home/pi/PacSatGround/spacecraft/PacSatSim.properties
+ sudo rm $FILE2
+ cp $FILE $FILE2
+ else
+ echo
+ echo "The first time you run the Ground Station, you will need to select Yes to override files, then put in your callsign"
+ sleep 10
+ fi
+
+ fi
+
+fi
+
+value=`cat /home/pi/CubeSatSim/sim.cfg`
+echo "$value" > /dev/null
+set -- $value
+
+callsign="$1"
+txfrequency="$7e3"
+rxfrequency="$8e3"
+
+echo -n "Callsign is "
+echo $callsign
+echo -n "Transmit Frequency is "
+echo $txfrequency
+echo -n "Receive Frequency is "
+echo $rxfrequency
+echo
+sleep 2
+
+sudo sed -i "s/TNC_TX_DELAY=.*$/TNC_TX_DELAY=750/g" /home/pi/PacSatGround/PacSatGround.properties
+sudo sed -i "s/TNC_TX_DELAY=.*$/TNC_TX_DELAY=750/g" /home/pi/PacSatGroundLoop/PacSatGround.properties
+
+sudo modprobe snd-aloop
+
+#sudo systemctl stop cubesatsim >/dev/null 2>&1
+
+#sudo systemctl stop transmit >/dev/null 2>&1
+
+sudo systemctl stop command >/dev/null 2>&1
+
+#/home/pi/CubeSatSim/config -I
+
+sudo systemctl stop command >/dev/null 2>&1
+
+sudo systemctl stop openwebrx >/dev/null 2>&1
+
+sudo systemctl stop rtl_tcp >/dev/null 2>&1
+
+pkill -o chromium &>/dev/null
+
+sudo killall -9 rtl_fm &>/dev/null
+
+#sudo killall -9 direwolf &>/dev/null
+
+sudo killall -9 sdrpp &>/dev/null
+
+#sudo killall -9 aplay &>/dev/null
+
+sudo killall -9 qsstv &>/dev/null
+
+sudo killall -9 rtl_tcp &>/dev/null
+
+sudo killall -9 java &>/dev/null
+
+sudo killall -9 CubicSDR &>/dev/null
+
+sudo killall -9 zenity &>/dev/null
+
+#sudo systemctl restart pacsatsim
+
+#sudo /etc/init.d/alsa-utils stop
+#sudo /etc/init.d/alsa-utils start
+
+sudo usermod -a -G gpio pi
+
+if [ "$loopback" = "1" ] ; then
+
+ echo "Using Audio Loopback"
+ ADEVICE="ADEVICE plughw:CARD=Loopback,DEV=1"
+ PTT="PTT GPIOD gpiochip0 17"
+
+elif [ "$safe" = "1" ] ; then
+
+ ADEVICE="ADEVICE shared_mic plughw:CARD=Loopback,DEV=0"
+ PTT="PTT GPIOD gpiochip0 17"
+
+ if [ ! "$txc" = "1" ] ; then
+ echo "Safe mode - battery saver won't work since no TXC present"
+ sleep 5
+ elif [ ! "$soundcard" = "1" ] ; then
+ echo "Safe mode - battery saver won't work since no sound card present"
+ sleep 5
+ else
+ echo "Safe mode - battery saver"
+ fi
+
+elif [ "$vox" = "1" ] ; then
+
+ ADEVICE="ADEVICE plughw:CARD=Device,DEV=0"
+ PTT="PTT GPIOD gpiochip0 17"
+
+ if [ "$soundcard" = "1" ] ; then
+ echo "Using Soundcard Audio TX and RX (VOX, no PTT)"
+ else
+ echo "Soundcard Audio TX and RX (VOX, no PTT) will not work since no sound card present"
+ sleep 5
+ fi
+
+elif [ "$pwm" = "1" ] ; then
+
+ ADEVICE="ADEVICE shared_mic plughw:CARD=Headphones,DEV=0"
+ PTT="PTT GPIOD gpiochip0 -20"
+
+ if [ ! "$txc" = "1" ] ; then
+ echo "FM TXC using Soundcard input (JP13), PWM output won't work since no TXC present"
+ sleep 5
+ elif [ ! "$soundcard" = "1" ] ; then
+ echo "FM TXC using Soundcard input (JP13), PWM output won't work since no sound card present"
+ sleep 5
+ else
+ echo "FM TXC using Soundcard input (JP13), PWM output"
+ fi
+
+else
+
+ echo "FM TXC using Soundcard input (JP13) and output (JP14)"
+ ADEVICE="ADEVICE shared_mic plughw:CARD=Device,DEV=0"
+ PTT="PTT GPIOD gpiochip0 -20"
+
+ if [ ! "$txc" = "1" ] ; then
+ echo "FM TXC using Soundcard input (JP13) and output (JP14) won't work since no TXC present"
+ sleep 5
+ elif [ ! "$soundcard" = "1" ] ; then
+ echo "FM TXC using Soundcard input (JP13), output (JP14) won't work since no sound card present"
+ sleep 5
+ else
+ echo "FM TXC using Soundcard input (JP13), output JP14"
+ fi
+
+fi
+
+DIREWOLF_CONF="/home/pi/CubeSatSim/groundstation/direwolf-pacsat-tmp.conf"
+
+echo "$ADEVICE" > $DIREWOLF_CONF
+echo "MYCALL $callsign-1" >> $DIREWOLF_CONF
+echo "$PTT" >> $DIREWOLF_CONF
+cat /home/pi/CubeSatSim/groundstation/direwolf/direwolf-pacsat.conf >> $DIREWOLF_CONF
+
+echo
+echo "$DIREWOLF_CONF"
+echo
+cat $DIREWOLF_CONF
+echo
+
+direwolf -r 48000 -c $DIREWOLF_CONF -t 0 &
+
+cd /home/pi/Desktop/PacsatGround/
+
+if [ "$loopback" = "1" ] ; then
+
+ setsid java -Xmx512M -jar PacSatGround.jar "/home/pi/PacSatGroundLoop" # removed &
+
+else
+
+ setsid java -Xmx512M -jar PacSatGround.jar "/home/pi/PacSatGround" # removed &
+
+fi
+
+sleep 10
+
+#echo "Stopping Pacsatsim"
+
+#$SHELL
+
+
+
diff --git a/groundstation/rtl-tcp.desktop b/groundstation/rtl-tcp.desktop
index 117acb9c..7ae3c038 100644
--- a/groundstation/rtl-tcp.desktop
+++ b/groundstation/rtl-tcp.desktop
@@ -3,7 +3,7 @@ Type=Application
Exec=/home/pi/CubeSatSim/groundstation/rtl-tcp.sh
Name=RTL-TCP
Comment=RTL-TCP for SDR#
-Icon=/home/pi/Downloads/SDRSharp.png
+Icon=/home/pi/Icons/SDRSharp.png
Path=/home/pi
Terminal=true
Categories=HamRadio
diff --git a/groundstation/rtl-tcp.sh b/groundstation/rtl-tcp.sh
index dc10376c..3d49d11d 100755
--- a/groundstation/rtl-tcp.sh
+++ b/groundstation/rtl-tcp.sh
@@ -23,13 +23,15 @@ echo "Note: you need to be on the Wifi network: $ssid"
echo
-sudo systemctl stop openwebrx
+sudo systemctl stop openwebrx &>/dev/null
sleep 2
pkill -o chromium &>/dev/null
-sudo systemctl stop rtl_tcp
+sudo systemctl stop rtl_tcp &>/dev/null
+
+sudo killall -9 sdrpp &>/dev/null
sudo killall -9 java &>/dev/null
@@ -45,10 +47,13 @@ sudo killall -9 qsstv &>/dev/null
sudo killall -9 direwolf &>/dev/null
-sudo killall -9 aplay &>/dev/null
+#sudo killall -9 aplay &>/dev/null
sudo killall -9 zenity &>/dev/null
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
sudo killall -9 rtl_fm &>/dev/null
sudo /bin/sh -c 'rtl_tcp -a $(hostname -I|cut -f1 -d " ")'
diff --git a/groundstation/rtl_tcp.service b/groundstation/rtl_tcp.service
index 403425a3..ff899e9b 100644
--- a/groundstation/rtl_tcp.service
+++ b/groundstation/rtl_tcp.service
@@ -3,7 +3,7 @@ Description=RTL-TCP
[Service]
TimeoutStopSec = 5
-ExecStart=/bin/sh -c '/usr/local/bin/rtl_tcp -a $(hostname -I)'
+ExecStart=/bin/sh -c 'rtl_tcp -a $(hostname -I|cut -f1 -d " ")'
WorkingDirectory=/home/pi
StandardOutput=inherit
StandardError=inherit
diff --git a/groundstation/rtltcp.socket b/groundstation/rtltcp.socket
new file mode 100644
index 00000000..d8a67a14
--- /dev/null
+++ b/groundstation/rtltcp.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=RTL TCP Socket
+PartOf=rtltcp.service
+
+[Socket]
+ListenStream=[::]:1234
+
+[Install]
+WantedBy=sockets.target
diff --git a/groundstation/sdr.sh b/groundstation/sdr.sh
index 4603b153..54ddb7a3 100755
--- a/groundstation/sdr.sh
+++ b/groundstation/sdr.sh
@@ -24,6 +24,8 @@ echo "Note: you need to be on the Wifi network: $ssid"
echo
+sudo killall -9 sdrpp &>/dev/null
+
sudo killall -9 java &>/dev/null
sudo killall -9 rtl_fm &>/dev/null
@@ -38,13 +40,18 @@ sudo killall -9 sdrpp &>/dev/null
sudo killall -9 qsstv &>/dev/null
-sudo killall -9 aplay &>/dev/null
+#sudo killall -9 aplay &>/dev/null
sudo killall -9 direwolf &>/dev/null
sudo killall -9 zenity &>/dev/null
-sudo systemctl stop rtl_tcp
+sudo systemctl stop rtl_tcp &>/dev/null
+
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
+sudo killall -9 rtl_fm &>/dev/null
sudo killall -9 rtl_fm &>/dev/null
@@ -52,7 +59,7 @@ sudo systemctl restart openwebrx
sleep 10
-setsid chromium-browser --check-for-update-interval=1 --simulate-critical-update --noerrdialogs --disable-infobars http://127.0.0.1:8073 &>/dev/null &
+setsid chromium-browser --check-for-update-interval=1 --simulate-critical-update --noerrdialogs --disable-infobars --app=http://localhost:8073 &>/dev/null &
sleep 10
diff --git a/groundstation/sdrpp.sh b/groundstation/sdrpp.sh
new file mode 100755
index 00000000..2dd97fd1
--- /dev/null
+++ b/groundstation/sdrpp.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# script to run sdrpp
+
+echo "Script to run SDRpp for ARISS Radio Pi"
+
+echo
+
+sudo systemctl stop openwebrx
+
+sudo killall -9 java &>/dev/null
+
+sudo killall -9 sdrpp &>/dev/null
+
+sudo systemctl stop rtl_tcp
+
+pkill -o chromium &>/dev/null
+
+sudo killall -9 rtl_fm &>/dev/null
+
+sudo killall -9 direwolf &>/dev/null
+
+#sudo killall -9 aplay &>/dev/null
+
+sudo killall -9 qsstv &>/dev/null
+
+sudo killall -9 rtl_tcp &>/dev/null
+
+sudo killall -9 CubicSDR &>/dev/null
+
+#sudo kill `ps -aux | grep cubicsdr-packet | grep -v grep | awk '{ print $2 }'` &>/dev/null && killall inotifywait &>/dev/null
+
+#sudo kill `ps -aux | grep packet | grep -v grep | awk '{ print $2 }'` &>/dev/null && killall inotifywait &>/dev/null
+
+#sudo kill `ps -aux | grep sstv_decode_prompt| grep -v grep | awk '{ print $2 }'` &>/dev/null && killall inotifywait &>/dev/null
+
+sudo killall -9 zenity &>/dev/null
+
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
+sleep 5
+
+setsid sdrpp &
+
+sleep 10
+
+#$SHELL
diff --git a/groundstation/set location.desktop b/groundstation/set location.desktop
index e2b80016..9adc6f66 100644
--- a/groundstation/set location.desktop
+++ b/groundstation/set location.desktop
@@ -3,7 +3,7 @@ Type=Application
Exec=/home/pi/CubeSatSim/groundstation/loc.sh
Name=Set My Location
Comment=Set Location for Gpredict
-Icon=/home/pi/Downloads/gpredict.png
+Icon=/home/pi/Icons/gpredict.png
Path=/home/pi
Terminal=true
Categories=HamRadio
diff --git a/groundstation/settings.json b/groundstation/settings.json
new file mode 100644
index 00000000..69033009
--- /dev/null
+++ b/groundstation/settings.json
@@ -0,0 +1,808 @@
+{
+ "version": 8,
+ "sdrs": {
+ "rtlsdr": {
+ "name": "RTL-SDR",
+ "type": "rtl_sdr",
+ "profiles": {
+ "70cm": {
+ "name": "70cm Ham Band 435 MHz (CubeSatSim)",
+ "center_freq": 435000000,
+ "rf_gain": 10.0,
+ "samp_rate": 2400000,
+ "start_freq": 434900000,
+ "start_mod": "nfm",
+ "tuning_step": 1000,
+ "direct_sampling": 0
+ },
+ "2m": {
+ "name": "WX Band 161 MHz",
+ "center_freq": 162400000,
+ "rf_gain": 29,
+ "samp_rate": 2048000,
+ "start_freq": 157000000,
+ "start_mod": "nfm"
+ },
+ "e59a4765-4139-4ab8-89c5-d8ac3343ba70": {
+ "name": "2m Ham Band 146 MHz (ISS)",
+ "center_freq": 145000000,
+ "samp_rate": 2400000,
+ "start_freq": 145000000,
+ "start_mod": "nfm",
+ "rf_gain": 42.0,
+ "direct_sampling": 0
+ },
+ "faf80b0b-1a96-4a9b-96fa-ce40b109c7e0": {
+ "name": "70cm Ham Band 438 MHz (ISS)",
+ "rf_gain": 29.0,
+ "center_freq": 438000000,
+ "samp_rate": 2400000,
+ "start_freq": 437800000,
+ "start_mod": "nfm"
+ },
+ "a4fd4a5d-d2d0-4949-87e2-bda83cd83a37": {
+ "name": "FM Band 95 MHz",
+ "rf_gain": 29.0,
+ "center_freq": 95000000,
+ "samp_rate": 2400000,
+ "start_freq": 94000000,
+ "start_mod": "wfm"
+ },
+ "ce2bca29-78cb-45d8-ab46-8dea3135981c": {
+ "name": "10m Ham Band 28 MHz",
+ "rf_gain": 29.0,
+ "center_freq": 28000000,
+ "samp_rate": 2400000,
+ "start_freq": 28000000,
+ "start_mod": "usb",
+ "direct_sampling": 0
+ },
+ "d6cdbf2d-74e4-4cac-aaa8-e793103a8e89": {
+ "name": "6m Ham Band 51 MHz",
+ "rf_gain": 29.0,
+ "center_freq": 51000000,
+ "samp_rate": 2400000,
+ "start_freq": 51000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "e2aba387-1d3b-4ca8-b280-e119282b8812": {
+ "name": "90 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 90000000,
+ "samp_rate": 2400000,
+ "start_freq": 90000000,
+ "start_mod": "wfm"
+ },
+ "f700b99d-3c51-4524-b151-a0809b868ecc": {
+ "name": "92 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 92000000,
+ "samp_rate": 2400000,
+ "start_freq": 92000000,
+ "start_mod": "wfm"
+ },
+ "dc6af94f-d607-4fee-a522-7f375f66a62c": {
+ "name": "94 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 94000000,
+ "samp_rate": 2400000,
+ "start_freq": 94000000,
+ "start_mod": "wfm"
+ },
+ "6887e85a-a4dc-4245-810f-99801fc5e824": {
+ "name": "96 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 96000000,
+ "samp_rate": 2400000,
+ "start_freq": 96000000,
+ "start_mod": "wfm"
+ },
+ "a2182ed6-70a8-4377-b233-ac6f8ccc91d7": {
+ "name": "98 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 96000000,
+ "samp_rate": 2400000,
+ "start_freq": 96000000,
+ "start_mod": "wfm"
+ },
+ "57e38353-fb86-4935-899b-e365228b8ae5": {
+ "name": "100 MHz FM Band",
+ "center_freq": 100000000,
+ "samp_rate": 2400000,
+ "start_freq": 100000000,
+ "start_mod": "wfm"
+ },
+ "5e9ec6dd-905d-4781-bd13-9cb702f58e84": {
+ "name": "102 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 102000000,
+ "samp_rate": 2400000,
+ "start_freq": 102000000,
+ "start_mod": "wfm"
+ },
+ "ef2c703c-2e22-4e87-82b5-581420d704bd": {
+ "name": "104 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 104000000,
+ "samp_rate": 2400000,
+ "start_freq": 104000000,
+ "start_mod": "wfm"
+ },
+ "34cc3ddf-8018-4288-acb9-29e6940bc37e": {
+ "name": "106 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 106000000,
+ "samp_rate": 2400000,
+ "start_freq": 106000000,
+ "start_mod": "wfm"
+ },
+ "b4693683-ccf5-474d-a2d9-9a47b0a18ee2": {
+ "name": "108 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 108000000,
+ "samp_rate": 2400000,
+ "start_freq": 108000000,
+ "start_mod": "wfm"
+ },
+ "34224d77-7b61-467c-b78f-18c7f3af1a0c": {
+ "name": "110 MHz FM Band",
+ "rf_gain": 29.0,
+ "center_freq": 110000000,
+ "samp_rate": 2400000,
+ "start_freq": 110000000,
+ "start_mod": "wfm"
+ },
+ "8dd82d97-73db-4fa7-ac41-263c3026ea1d": {
+ "name": "112 MHz",
+ "rf_gain": 29.0,
+ "center_freq": 112000000,
+ "samp_rate": 2400000,
+ "start_freq": 112000000,
+ "start_mod": "nfm"
+ },
+ "79304b30-f10d-469e-9617-50a19bfdb435": {
+ "name": "114 MHz",
+ "rf_gain": 29.0,
+ "center_freq": 114000000,
+ "samp_rate": 2400000,
+ "start_freq": 114000000,
+ "start_mod": "nfm"
+ },
+ "c00bf096-27b8-4262-832c-df1a308d7eb9": {
+ "name": "116 MHz",
+ "rf_gain": 29.0,
+ "center_freq": 116000000,
+ "samp_rate": 2400000,
+ "start_freq": 116000000,
+ "start_mod": "nfm"
+ },
+ "669d25a6-6c15-4131-a330-3c33dd2147f0": {
+ "name": "118 Mhz Air Band",
+ "rf_gain": 29.0,
+ "center_freq": 118000000,
+ "samp_rate": 2400000,
+ "start_freq": 118000000,
+ "start_mod": "am"
+ },
+ "948248fa-43d9-4e7d-bf86-afaadd391779": {
+ "name": "120 MHz Air Band",
+ "rf_gain": 29.0,
+ "center_freq": 120000000,
+ "samp_rate": 2400000,
+ "start_freq": 120000000,
+ "start_mod": "am"
+ },
+ "b634273b-8fc8-4e87-b5c4-e6226d4be0ac": {
+ "name": "122 MHz Air Band",
+ "rf_gain": 42.0,
+ "center_freq": 122000000,
+ "samp_rate": 2400000,
+ "start_freq": 121000000,
+ "start_mod": "nfm"
+ },
+ "c55289a2-8286-4a3d-a505-37ba2867571a": {
+ "name": "124 Mhz Air Band",
+ "rf_gain": 42.0,
+ "center_freq": 124000000,
+ "samp_rate": 2400000,
+ "start_freq": 124000000,
+ "start_mod": "am"
+ },
+ "4fe488b7-f369-43ba-bb49-91e1a185be7a": {
+ "name": "126 MHz Air Band",
+ "rf_gain": 29.0,
+ "center_freq": 126000000,
+ "samp_rate": 2400000,
+ "start_freq": 126000000,
+ "start_mod": "am"
+ },
+ "e79639a2-1384-4e92-8e46-f6e5670ec9fd": {
+ "name": "128 MHz Air Band",
+ "rf_gain": 42.0,
+ "center_freq": 128000000,
+ "samp_rate": 2400000,
+ "start_freq": 128000000,
+ "start_mod": "am"
+ },
+ "319f3fb2-b98a-4620-85a7-a99d5a722bd5": {
+ "name": "130 MHz Air Band",
+ "rf_gain": 42.0,
+ "center_freq": 130000000,
+ "samp_rate": 2400000,
+ "start_freq": 130000000,
+ "start_mod": "am"
+ },
+ "63c5c2ce-07de-496c-81f6-b188a7adbf39": {
+ "name": "132 MHz Air Band",
+ "rf_gain": 42.0,
+ "center_freq": 132000000,
+ "samp_rate": 2400000,
+ "start_freq": 132000000,
+ "start_mod": "am"
+ },
+ "386bdc7b-eb10-4e05-972a-69d730a23cd8": {
+ "name": "134 MHz Air Band",
+ "rf_gain": 29.0,
+ "center_freq": 134000000,
+ "samp_rate": 2400000,
+ "start_freq": 134000000,
+ "start_mod": "am"
+ },
+ "ae8ea8b1-23de-45ef-b8c4-3b83a188e65d": {
+ "name": "136 MHz Air Band",
+ "rf_gain": 42.0,
+ "center_freq": 136000000,
+ "samp_rate": 2400000,
+ "start_freq": 136000000,
+ "start_mod": "am"
+ },
+ "c0b1a28c-5e07-400a-a5f3-07c62db27587": {
+ "name": "138 MHz NOAA Weather Satellite Band",
+ "rf_gain": 42.0,
+ "center_freq": 138000000,
+ "samp_rate": 2400000,
+ "start_freq": 138000000,
+ "start_mod": "nfm"
+ },
+ "20f7ce56-fd85-4b3e-8fac-94cbe9ba0e1d": {
+ "name": "140 MHz ",
+ "rf_gain": 42.0,
+ "center_freq": 140000000,
+ "samp_rate": 2400000,
+ "start_freq": 140000000,
+ "start_mod": "nfm"
+ },
+ "882079f8-5697-428a-ae9d-bcc091269c7f": {
+ "name": "142 MHz ",
+ "rf_gain": 42.0,
+ "center_freq": 142000000,
+ "samp_rate": 2400000,
+ "start_freq": 142000000,
+ "start_mod": "nfm"
+ },
+ "da1b3f12-2eba-40e9-8c62-33493adf74b3": {
+ "name": "144 MHz 2m Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 144000000,
+ "samp_rate": 2400000,
+ "start_freq": 144000000,
+ "start_mod": "nfm"
+ },
+ "8d9cf1e1-44c5-41c4-bcea-7b1c69446e62": {
+ "name": "146 MHz 2m Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 146000000,
+ "samp_rate": 2400000,
+ "start_freq": 146000000,
+ "start_mod": "nfm"
+ },
+ "eec8aa0d-3485-43d2-baa4-82f7d9e14df6": {
+ "name": "148 MHz 2m Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 148000000,
+ "samp_rate": 2400000,
+ "start_freq": 148000000,
+ "start_mod": "nfm"
+ },
+ "bf66a908-1988-4aec-b998-06e2bc7d0a84": {
+ "name": "150 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 150000000,
+ "samp_rate": 2400000,
+ "start_freq": 150000000,
+ "start_mod": "nfm"
+ },
+ "0389f270-b919-4aae-a313-f73697059f70": {
+ "name": "152 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 152000000,
+ "samp_rate": 2400000,
+ "start_freq": 152000000,
+ "start_mod": "nfm"
+ },
+ "6ef9d955-76aa-46c0-8463-2c23def5e37b": {
+ "name": "154 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 154000000,
+ "samp_rate": 2400000,
+ "start_freq": 154000000,
+ "start_mod": "nfm"
+ },
+ "5d0a64c7-3bce-408e-94d9-c8315bef7540": {
+ "name": "156 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 156000000,
+ "samp_rate": 2400000,
+ "start_freq": 156000000,
+ "start_mod": "nfm"
+ },
+ "5b869cae-ffa7-4554-96af-7acd497bbaf3": {
+ "name": "158 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 158000000,
+ "samp_rate": 2400000,
+ "start_freq": 158000000,
+ "start_mod": "nfm"
+ },
+ "0de7c5d4-14fc-4655-9a81-2bcebb2f4147": {
+ "name": "160 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 160000000,
+ "samp_rate": 2400000,
+ "start_freq": 160000000,
+ "start_mod": "nfm"
+ },
+ "8ca54821-8b80-4938-a35c-9fe25e2320d1": {
+ "name": "162 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 162000000,
+ "samp_rate": 2400000,
+ "start_freq": 162000000,
+ "start_mod": "nfm"
+ },
+ "f74d262d-9e98-4030-86b2-45676121ff1e": {
+ "name": "164 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 164000000,
+ "samp_rate": 2400000,
+ "start_freq": 164000000,
+ "start_mod": "nfm"
+ },
+ "bfc9c686-6c06-4de2-b1d5-c8f012131042": {
+ "name": "168 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 168000000,
+ "samp_rate": 2400000,
+ "start_freq": 167000000,
+ "start_mod": "nfm"
+ },
+ "5468e597-d529-42fe-9fcf-0ff4fa9e2d06": {
+ "name": "170 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 170000000,
+ "samp_rate": 2400000,
+ "start_freq": 170000000,
+ "start_mod": "nfm"
+ },
+ "e124cc6e-7177-4d5f-ae5b-2ec6a6fa2956": {
+ "name": "172 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 172000000,
+ "samp_rate": 2400000,
+ "start_freq": 172000000,
+ "start_mod": "nfm"
+ },
+ "1ce0f3ed-4763-4f00-916a-4f72d29ba410": {
+ "name": "174 MHz ",
+ "rf_gain": 42.0,
+ "center_freq": 174000000,
+ "samp_rate": 2400000,
+ "start_freq": 174000000,
+ "start_mod": "nfm"
+ },
+ "639b1496-a2b9-4a42-ad28-3cda89fbe2fb": {
+ "name": "420 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 420000000,
+ "samp_rate": 2400000,
+ "start_freq": 420000000,
+ "start_mod": "nfm"
+ },
+ "bbc9b57e-ea86-43ef-be65-cb2337615ae5": {
+ "name": "422 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 422000000,
+ "samp_rate": 2400000,
+ "start_freq": 422000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "3aed286d-7d13-4338-8621-d1c0dfdf3ac6": {
+ "name": "424 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 424000000,
+ "samp_rate": 2400000,
+ "start_freq": 424000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "9ae664b4-48f3-410a-8995-edc60127d746": {
+ "name": "426 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 426000000,
+ "samp_rate": 2400000,
+ "start_freq": 426000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "24d2467b-6740-42b5-8d3f-8f389fc0860b": {
+ "name": "428 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 428000000,
+ "samp_rate": 2400000,
+ "start_freq": 428000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "debbc3ab-081d-41e7-80fe-7d564838154e": {
+ "name": "430 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 430000000,
+ "samp_rate": 2400000,
+ "start_freq": 430000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "649233e0-fc85-415d-b88e-94750f49ca4b": {
+ "name": "432 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 432000000,
+ "samp_rate": 2400000,
+ "start_freq": 432000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "bed3b482-fd3b-45ee-b924-200aa4223ace": {
+ "name": "434 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 434000000,
+ "samp_rate": 2400000,
+ "start_freq": 434000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "58dfac9e-6030-4bb3-ba28-465285baa25e": {
+ "name": "436 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 436000000,
+ "samp_rate": 2400000,
+ "start_freq": 436000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "4c293b84-cd43-495f-95a5-1fcabfe4e4c7": {
+ "name": "438 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 438000000,
+ "samp_rate": 2400000,
+ "start_freq": 438000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "0e763161-a0e8-411a-abe6-c1af13045f27": {
+ "name": "440 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 440000000,
+ "samp_rate": 2400000,
+ "start_freq": 440000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "6dda77d3-e859-41b7-9b0b-22c2dee47472": {
+ "name": "442 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 442000000,
+ "samp_rate": 2400000,
+ "start_freq": 442000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "285813ef-aa6d-433f-a316-074f47e02073": {
+ "name": "444 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 444000000,
+ "samp_rate": 2400000,
+ "start_freq": 444000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "e0842b63-6857-4554-874b-fad99e4db03a": {
+ "name": "446 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 446000000,
+ "samp_rate": 2400000,
+ "start_freq": 446000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "c7b21c80-cfef-42e8-a6fe-c5eea4556c7e": {
+ "name": "448 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 448000000,
+ "samp_rate": 2400000,
+ "start_freq": 448000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "d98b4d4a-8247-4a99-9fc7-89780e5e1fef": {
+ "name": "450 MHz 70cm Ham Band",
+ "rf_gain": 42.0,
+ "center_freq": 450000000,
+ "samp_rate": 2400000,
+ "start_freq": 450000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "a09a546f-c56f-41b5-ae34-c5511afbcef5": {
+ "name": "460 MHz",
+ "rf_gain": 42.0,
+ "center_freq": 460000000,
+ "samp_rate": 2400000,
+ "start_freq": 460000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "232b2ae6-88dd-4e58-b489-37f310e5e204": {
+ "name": "462 MHz FRS/GMRS",
+ "rf_gain": 42.0,
+ "center_freq": 462000000,
+ "samp_rate": 2400000,
+ "start_freq": 462000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "41db9b38-87d7-40a0-9f90-1f0c77c054d9": {
+ "name": "464 MHz FRS/GMRS",
+ "rf_gain": 42.0,
+ "center_freq": 464000000,
+ "samp_rate": 2400000,
+ "start_freq": 464000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "e9bb7781-eb9b-4314-b399-2d96c52716f0": {
+ "name": "466 MHz FRS/GMRS",
+ "rf_gain": 42.0,
+ "center_freq": 466000000,
+ "samp_rate": 2400000,
+ "start_freq": 466000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "5d9e07e8-eb42-4832-82c9-016f05d89027": {
+ "name": "468 MHz FRS/GMRS",
+ "rf_gain": 42.0,
+ "center_freq": 468000000,
+ "samp_rate": 2400000,
+ "start_freq": 468000000,
+ "start_mod": "nfm",
+ "direct_sampling": 0
+ },
+ "20m": {
+ "name": "20m",
+ "center_freq": 14150000,
+ "samp_rate": 384000,
+ "start_freq": 14070000,
+ "start_mod": "usb",
+ "tuning_step": "500",
+ "rf_gain": 42.0,
+ "direct_sampling": 1
+ },
+ "30m": {
+ "name": "30m",
+ "center_freq": 10125000,
+ "samp_rate": 192000,
+ "start_freq": 10142000,
+ "start_mod": "usb",
+ "tuning_step": "500",
+ "rf_gain": 42.0,
+ "direct_sampling": 1
+ },
+ "40m": {
+ "name": "40m",
+ "center_freq": 7100000,
+ "samp_rate": 256000,
+ "start_freq": 7070000,
+ "start_mod": "lsb",
+ "tuning_step": "500",
+ "rf_gain": 42.0,
+ "direct_sampling": 1
+ },
+ "80m": {
+ "name": "80m",
+ "center_freq": 3650000,
+ "samp_rate": 384000,
+ "start_freq": 3570000,
+ "start_mod": "lsb",
+ "tuning_step": "500",
+ "rf_gain": 42.0,
+ "direct_sampling": 1
+ },
+ "49m": {
+ "name": "49m Broadcast",
+ "center_freq": 6050000,
+ "samp_rate": 384000,
+ "start_freq": 6070000,
+ "start_mod": "am",
+ "tuning_step": "1000",
+ "rf_gain": 42.0,
+ "direct_sampling": 1
+ },
+ "c1982ce1-7504-455e-908c-dc097fa031a8": {
+ "name": "1090 MHz ADS-B Band",
+ "rf_gain": 42.0,
+ "center_freq": 1090000000,
+ "samp_rate": 2400000,
+ "start_freq": 1090000000,
+ "start_mod": "adsb",
+ "tuning_step": 1,
+ "direct_sampling": 0
+ },
+ "cb7f2f8e-e317-4a5e-9504-826dd3781791": {
+ "name": "978 MHz ADS-B Band",
+ "rf_gain": 42.0,
+ "center_freq": 978000000,
+ "samp_rate": 2400000,
+ "start_freq": 978000000,
+ "start_mod": "adsb",
+ "tuning_step": 1
+ }
+ }
+ },
+ "airspy": {
+ "name": "Airspy HF+",
+ "type": "airspyhf",
+ "rf_gain": "auto",
+ "profiles": {
+ "20m": {
+ "name": "20m",
+ "center_freq": 14150000,
+ "samp_rate": 384000,
+ "start_freq": 14070000,
+ "start_mod": "usb",
+ "tuning_step": "500"
+ },
+ "30m": {
+ "name": "30m",
+ "center_freq": 10125000,
+ "samp_rate": 192000,
+ "start_freq": 10142000,
+ "start_mod": "usb",
+ "tuning_step": "500"
+ },
+ "40m": {
+ "name": "40m",
+ "center_freq": 7100000,
+ "samp_rate": 256000,
+ "start_freq": 7070000,
+ "start_mod": "lsb",
+ "tuning_step": "500"
+ },
+ "80m": {
+ "name": "80m",
+ "center_freq": 3650000,
+ "samp_rate": 384000,
+ "start_freq": 3570000,
+ "start_mod": "lsb",
+ "tuning_step": "500"
+ },
+ "49m": {
+ "name": "49m Broadcast",
+ "center_freq": 6050000,
+ "samp_rate": 384000,
+ "start_freq": 6070000,
+ "start_mod": "am",
+ "tuning_step": "1000"
+ }
+ }
+ },
+ "sdrplay": {
+ "name": "SDRPlay device",
+ "type": "sdrplay",
+ "antenna": "Antenna A",
+ "rf_gain": "auto",
+ "profiles": {
+ "20m": {
+ "name": "20m",
+ "center_freq": 14150000,
+ "samp_rate": 500000,
+ "start_freq": 14070000,
+ "start_mod": "usb",
+ "tuning_step": "500"
+ },
+ "30m": {
+ "name": "30m",
+ "center_freq": 10125000,
+ "samp_rate": 250000,
+ "start_freq": 10142000,
+ "start_mod": "usb",
+ "tuning_step": "500"
+ },
+ "40m": {
+ "name": "40m",
+ "center_freq": 7100000,
+ "samp_rate": 500000,
+ "start_freq": 7070000,
+ "start_mod": "lsb",
+ "tuning_step": "500"
+ },
+ "80m": {
+ "name": "80m",
+ "center_freq": 3650000,
+ "samp_rate": 500000,
+ "start_freq": 3570000,
+ "start_mod": "lsb",
+ "tuning_step": "500"
+ },
+ "49m": {
+ "name": "49m Broadcast",
+ "center_freq": 6000000,
+ "samp_rate": 500000,
+ "start_freq": 6070000,
+ "start_mod": "am",
+ "tuning_step": "1000"
+ }
+ }
+ }
+ },
+ "receiver_name": "ARISS Radio Pi",
+ "receiver_location": "Budapest, Hungary",
+ "receiver_asl": 200,
+ "receiver_admin": "example@example.com",
+ "receiver_gps": {
+ "lat": 39.95233,
+ "lon": -75.16379
+ },
+ "photo_title": "Panorama of Budapest from Sch\u00f6nherz Zolt\u00e1n Dormitory",
+ "photo_desc": "",
+ "max_clients": 20,
+ "keep_files": 20,
+ "session_timeout": 0,
+ "usage_policy_url": "policy",
+ "allow_chat": true,
+ "allow_audio_recording": true,
+ "allow_center_freq_changes": false,
+ "magic_key": "memagic",
+ "receiver_keys": [],
+ "waterfall_scheme": "GoogleTurboWaterfall",
+ "fft_fps": 9,
+ "fft_size": 4096,
+ "fft_voverlap_factor": 0.3,
+ "waterfall_levels": {
+ "min": -88.0,
+ "max": -20.0
+ },
+ "waterfall_auto_levels": {
+ "min": 3.0,
+ "max": 10.0
+ },
+ "waterfall_auto_level_default_mode": false,
+ "waterfall_auto_min_range": 50,
+ "audio_compression": "adpcm",
+ "fft_compression": "adpcm",
+ "tuning_precision": 2,
+ "eibi_bookmarks_range": 0,
+ "repeater_range": 0,
+ "map_type": "google",
+ "google_maps_api_key": "",
+ "openweathermap_api_key": "",
+ "map_position_retention_time": 7200,
+ "map_ignore_indirect_reports": false,
+ "map_prefer_recent_reports": true,
+ "callsign_url": "https://www.qrzcq.com/call/{}",
+ "vessel_url": "https://www.vesselfinder.com/vessels/details/{}",
+ "flight_url": "https://flightaware.com/live/flight/{}",
+ "modes_url": "https://flightaware.com/live/modes/{}/redirect"
+}
+
diff --git a/groundstation/sstv_decode_prompt.sh b/groundstation/sstv_decode_prompt.sh
index ea3c396d..5a398622 100755
--- a/groundstation/sstv_decode_prompt.sh
+++ b/groundstation/sstv_decode_prompt.sh
@@ -4,10 +4,12 @@ echo "Script to decode SSTV using QSSTV with rtl_fm"
echo
-sudo systemctl stop openwebrx
+sudo systemctl stop openwebrx &>/dev/null
sudo modprobe snd-aloop
+sudo killall -9 sdrpp &>/dev/null
+
sudo killall -9 qsstv &>/dev/null
sudo killall -9 rtl_fm &>/dev/null
@@ -16,7 +18,7 @@ sudo killall -9 aplay &>/dev/null
sudo killall -9 direwolf &>/dev/null
-sudo systemctl stop rtl_tcp
+sudo systemctl stop rtl_tcp &>/dev/null
pkill -o chromium &>/dev/null
@@ -30,6 +32,9 @@ sudo killall -9 sdrpp &>/dev/null
sudo killall -9 zenity &>/dev/null
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
sudo killall -9 rtl_fm &>/dev/null
#echo "s" >> .mode
diff --git a/groundstation/webSDR.desktop b/groundstation/webSDR.desktop
index 277bbae2..387dfd95 100644
--- a/groundstation/webSDR.desktop
+++ b/groundstation/webSDR.desktop
@@ -3,7 +3,7 @@ Type=Application
Exec=/home/pi/CubeSatSim/groundstation/sdr.sh
Name=Web SDR
Comment=openwebrx for Web SDR
-Icon=/home/pi/Downloads/openwebrx.png
+Icon=/home/pi/Icons/openwebrx.png
Path=/home/pi
Terminal=true
Categories=HamRadio
diff --git a/hardware/lite/v2/README.md b/hardware/lite/v2/README.md
new file mode 100644
index 00000000..3810277c
--- /dev/null
+++ b/hardware/lite/v2/README.md
@@ -0,0 +1,13 @@
+Here is information about the CubeSatSim Lite v2 hardware
+
+cubesatsim-Lite_2.0.1_gerbers.zip -- All gerber files used to fabricate PCBs
+
+cubesatsim-Lite_2.0.1_schematic.pdf -- Schematic
+
+cubesatsim-Lite_2.0.1.mnt -- SMD file
+
+cubesatsim-lLite_2.0.1_pcb.png -- image of board
+
+cubesatsim-Lite_2.0.1_bom.csv.txt -- Bill of Materials (BOM)
+
+For more information see https://github.com/alanbjohnston/CubeSatSim/wiki/CubeSatSim-Lite
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1.mnb b/hardware/lite/v2/cubesatsim-Lite-v2.0.1.mnb
new file mode 100644
index 00000000..e97af237
--- /dev/null
+++ b/hardware/lite/v2/cubesatsim-Lite-v2.0.1.mnb
@@ -0,0 +1,5 @@
+JP1 44.68 53.87 0 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK
+JP2 23.14 59.97 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP3 21.74 56.03 270 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK
+JP6 33.99 59.61 0 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK
+JP7 16.00 63.09 90 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1.mnt b/hardware/lite/v2/cubesatsim-Lite-v2.0.1.mnt
new file mode 100644
index 00000000..9e31062d
--- /dev/null
+++ b/hardware/lite/v2/cubesatsim-Lite-v2.0.1.mnt
@@ -0,0 +1,26 @@
+C1 8.36 61.93 0 18pF C0603
+C2 10.03 61.90 0 16pF C0603
+C3 56.06 58.32 90 18pF C0603
+C4 55.47 62.84 270 16pF C0603
+C7 49.23 56.57 0 DNI/47uF C0603
+C8 50.47 47.68 270 DNI/100nF C0603
+E1 3.63 53.23 270 ANT-916-CHP-T XDCR_ANT-916-CHP-T
+E2 61.39 53.21 270 ANT-916-CHP-T XDCR_ANT-916-CHP-T
+J1 32.55 66.61 0 CONN_20X2 2X20
+J13 9.25 45.02 180 SJ1-2503A CONN_SJ1-2503A
+J14 55.07 45.08 180 SJ1-2503A CONN_SJ1-2503A
+L1 9.22 59.44 180 13nH L0603
+L2 56.24 60.55 270 13nH L0603
+LED5 19.08 42.09 270 GREEN LED-0603
+LED6 43.94 41.91 270 BLUE LED-0603
+R2 46.63 62.48 180 DNI/1k R0603
+R4 51.18 62.51 180 DNI/1k R0603
+R10 12.70 41.91 90 DNI/1k 0603-RES
+R11 51.66 41.91 90 DNI/100 0603-RES
+R16 13.79 60.22 0 DNI/68 R0805
+R17 18.44 60.33 270 DNI/180 R0603
+R18 26.67 60.22 180 DNI/68 R0805
+R21 48.90 51.23 0 DNI/100 R0603
+R22 55.14 51.99 0 DNI/220 R0603
+S2 7.80 51.82 90 DTSM-6 DTSM-6
+U6 32.94 51.75 270 SR105U SR_FRS_0W5
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_bom.csv.txt b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_bom.csv.txt
new file mode 100644
index 00000000..44718daa
--- /dev/null
+++ b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_bom.csv.txt
@@ -0,0 +1,53 @@
+"Part";"Value";"Device";"Package";"Description";"";
+"C1";"18pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C2";"16pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C3";"18pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C4";"16pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C5";"47uF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";"";
+"C6";"100nF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";"";
+"C7";"DNI/47uF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C8";"DNI/100nF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"E1";"ANT-916-CHP-T";"ANT-916-CHP-T";"XDCR_ANT-916-CHP-T";"868MHz ISM, LoRa, Sensor Networks, SigFox Chip RF Antenna 863MHz ~ 873MHz 0.5dBi Solder Surface Mount Check prices";"";
+"E2";"ANT-916-CHP-T";"ANT-916-CHP-T";"XDCR_ANT-916-CHP-T";"868MHz ISM, LoRa, Sensor Networks, SigFox Chip RF Antenna 863MHz ~ 873MHz 0.5dBi Solder Surface Mount Check prices";"";
+"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J2";"";"CONN_021X02_NO_SILK";"1X02_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J6";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"J10";"DNI/Sparkfun QWIIC Breakout";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J12";"DNI/1x4 pin header";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J13";"SJ1-2503A";"SJ1-2503A";"CONN_SJ1-2503A";"";"";
+"J14";"SJ1-2503A";"SJ1-2503A";"CONN_SJ1-2503A";"";"";
+"J15";"";"CONN_06NO_SILK_NO_POP";"1X06_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP1";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP2";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP3";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP6";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP7";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"L1";"13nH";"SMD-FERRITE-CHIP-120-OHM-500MA(0603)";"L0603";"303030001";"";
+"L2";"13nH";"SMD-FERRITE-CHIP-120-OHM-500MA(0603)";"L0603";"303030001";"";
+"LED3";"Green 5mm";"LED3MM";"LED3MM";"LED";"";
+"LED4";"Blue 5mm";"LED3MM";"LED3MM";"LED";"";
+"LED5";"GREEN";"LED-GREEN0603";"LED-0603";"Green SMD LED";"";
+"LED6";"BLUE";"LED-BLUE0603";"LED-0603";"Blue SMD LED";"";
+"R1";"1K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R2";"DNI/1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R3";"1K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R4";"DNI/1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R7";"1k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R8";"DNI/100";"RESISTOR0603";"0603-RES";"Resistor";"";
+"R10";"DNI/1k";"RESISTOR0603-RES";"0603-RES";"Resistor";"";
+"R11";"100";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R13";"68";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R14";"180";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R15";"68";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R16";"DNI/68";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R17";"DNI/180";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R18";"DNI/68";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R19";"100";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R20";"220";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R21";"DNI/100";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R22";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"S1";"RA-SPST";"RA-SPST";"RA-SPST";"";"";
+"S2";"DTSM-6";"DTSM-6";"DTSM-6";"";"";
+"U1";"SR105U";"SR_FRS_0W5";"SR_FRS_0W5";"";"";
+"X2";"SMA-VERT";"SMA-VERT";"SMA-VERT";"";"";
+"X3";"SMA-VERT";"SMA-VERT";"SMA-VERT";"";"";
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_bottom.png b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_bottom.png
new file mode 100644
index 00000000..ecafa19d
Binary files /dev/null and b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_bottom.png differ
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_centroid.zip b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_centroid.zip
new file mode 100644
index 00000000..314a9832
Binary files /dev/null and b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_centroid.zip differ
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_gerbers.zip b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_gerbers.zip
new file mode 100644
index 00000000..ad1a58ef
Binary files /dev/null and b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_gerbers.zip differ
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_pcb.png b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_pcb.png
new file mode 100644
index 00000000..be0e7e5d
Binary files /dev/null and b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_pcb.png differ
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_pour.png b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_pour.png
new file mode 100644
index 00000000..6eb98adf
Binary files /dev/null and b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_pour.png differ
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_schematic.pdf b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_schematic.pdf
new file mode 100644
index 00000000..b3b16fc0
Binary files /dev/null and b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_schematic.pdf differ
diff --git a/hardware/lite/v2/cubesatsim-Lite-v2.0.1_top.png b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_top.png
new file mode 100644
index 00000000..2f3b0145
Binary files /dev/null and b/hardware/lite/v2/cubesatsim-Lite-v2.0.1_top.png differ
diff --git a/hardware/lite/vB5/README.md b/hardware/lite/vB5/README.md
index af044d35..8d6f40d6 100644
--- a/hardware/lite/vB5/README.md
+++ b/hardware/lite/vB5/README.md
@@ -10,4 +10,4 @@ cubesatsim-lite-0.5_pcb.png -- image of board
cubesatsim-lite-0.5.csv.txt -- Bill of Materials (BOM)
-For more information see https://github.com/alanbjohnston/CubeSatSim/wiki/CubeSatSim-Lite
+For more information see https://github.com/alanbjohnston/CubeSatSim/wiki/CubeSatSim-Lite-Beta-vB5
diff --git a/hardware/v2.1/CubeSatSim Main v2.1.0 BOM.xls b/hardware/v2.1/CubeSatSim Main v2.1.0 BOM.xls
new file mode 100644
index 00000000..ae5f101c
Binary files /dev/null and b/hardware/v2.1/CubeSatSim Main v2.1.0 BOM.xls differ
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_bom.csv.txt b/hardware/v2.1/cubesatsim-battery-v2.1.0_bom.csv.txt
new file mode 100644
index 00000000..a60a8138
--- /dev/null
+++ b/hardware/v2.1/cubesatsim-battery-v2.1.0_bom.csv.txt
@@ -0,0 +1,23 @@
+"Part";"Value";"Device";"Package";"Description";"";
+"BT1";"1024";"1024";"BAT_1024";"Check availability";"";
+"BT2";"1012";"1012";"BAT_1012";"Check availability";"";
+"C1";"DNI/0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";
+"F1";"PTC";"PTCPTH";"PTC";"Resettable Fuse PTC";"";
+"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP1";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP2";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP3";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP4";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP5";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP6";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP7";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP8";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP10";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP11";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP13";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP14";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"R1";"DNI/R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R2";"10k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R3";"10k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"U1";"INA219 purple board";"INA219";"INA219";"";"";
+"U2";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"";
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_bottom.png b/hardware/v2.1/cubesatsim-battery-v2.1.0_bottom.png
new file mode 100644
index 00000000..58d2adcd
Binary files /dev/null and b/hardware/v2.1/cubesatsim-battery-v2.1.0_bottom.png differ
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_centroid.zip b/hardware/v2.1/cubesatsim-battery-v2.1.0_centroid.zip
new file mode 100644
index 00000000..ab278a89
Binary files /dev/null and b/hardware/v2.1/cubesatsim-battery-v2.1.0_centroid.zip differ
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_gerbers.zip b/hardware/v2.1/cubesatsim-battery-v2.1.0_gerbers.zip
new file mode 100644
index 00000000..428226d4
Binary files /dev/null and b/hardware/v2.1/cubesatsim-battery-v2.1.0_gerbers.zip differ
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_pcb.png b/hardware/v2.1/cubesatsim-battery-v2.1.0_pcb.png
new file mode 100644
index 00000000..a8b4d242
Binary files /dev/null and b/hardware/v2.1/cubesatsim-battery-v2.1.0_pcb.png differ
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_pour.png b/hardware/v2.1/cubesatsim-battery-v2.1.0_pour.png
new file mode 100644
index 00000000..b9e7ebdc
Binary files /dev/null and b/hardware/v2.1/cubesatsim-battery-v2.1.0_pour.png differ
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_schematic.pdf b/hardware/v2.1/cubesatsim-battery-v2.1.0_schematic.pdf
new file mode 100644
index 00000000..f0375bc0
Binary files /dev/null and b/hardware/v2.1/cubesatsim-battery-v2.1.0_schematic.pdf differ
diff --git a/hardware/v2.1/cubesatsim-battery-v2.1.0_top.png b/hardware/v2.1/cubesatsim-battery-v2.1.0_top.png
new file mode 100644
index 00000000..7c8db0c7
Binary files /dev/null and b/hardware/v2.1/cubesatsim-battery-v2.1.0_top.png differ
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0.mnb b/hardware/v2.1/cubesatsim-main-v2.1.0.mnb
new file mode 100644
index 00000000..b8b888f9
--- /dev/null
+++ b/hardware/v2.1/cubesatsim-main-v2.1.0.mnb
@@ -0,0 +1,18 @@
+D1 63.55 60.58 0 BYW27-400 D-2.5
+D2 72.01 10.49 0 1N5817 D-2.5
+D3 66.45 10.62 180 1N4148 D-2.5
+D8 59.31 7.52 270 DNI/5V1 Zener 1W ZDIO-2.5
+D10 77.50 10.46 0 1N5817 D-2.5
+JP1 72.17 8.66 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP2 24.73 60.99 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP3 16.08 58.12 270 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK
+JP4 59.36 56.39 180 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK
+JP5 75.08 56.48 270 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP6 26.21 35.94 180 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK
+JP7 15.95 62.24 90 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP8 47.28 30.91 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP9 44.21 61.82 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP10 63.61 56.54 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+JP11 14.63 52.17 180 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK
+U7 36.42 49.89 0 DRA818V DORJI_DRA818V
+X1 71.86 61.21 270 SC1464-ND PG203J
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0.mnt b/hardware/v2.1/cubesatsim-main-v2.1.0.mnt
new file mode 100644
index 00000000..c33a4c37
--- /dev/null
+++ b/hardware/v2.1/cubesatsim-main-v2.1.0.mnt
@@ -0,0 +1,39 @@
+C1 18.75 76.02 270 18pF C0603
+C2 18.69 71.88 270 16pF C0603
+C3 16.38 10.11 180 18pF C0603
+C4 20.68 10.16 180 16pF C0603
+C7 55.60 56.62 0 DNI/47uF C0603
+C8 59.00 47.55 270 DNI/100nF C0603
+C10 66.83 3.91 270 DNI/100nF C0603
+D5 63.42 62.53 0 DNI/1N4007FL SOD-123FL
+D6 72.16 8.69 180 DNI/B5817WS SOD-323F
+D7 66.47 8.84 0 DNI/4148WS SOD-323F
+E1 6.80 76.35 180 ANT-916-CHP-T XDCR_ANT-916-CHP-T
+E2 19.18 3.81 0 ANT-916-CHP-T XDCR_ANT-916-CHP-T
+F2 63.68 57.18 180 DNI/MF-FSML100/8-2 0603
+J1 32.55 66.61 0 CONN_20X2 2X20
+J8 36.17 72.01 0 Sparkfun USB-C Breakout 1X06_NO_SILK
+J9 36.35 74.15 180 DNI/USB4105-GF-A or GT-USB-7010B USB-C-16P-2LAYER-PADS
+J13 8.92 31.68 0 SJ1-2503A CONN_SJ1-2503A
+J14 15.95 31.76 0 SJ1-2503A CONN_SJ1-2503A
+L1 16.76 73.94 90 13nH L0603
+L2 18.49 12.17 180 13nH L0603
+R2 54.00 62.26 0 DNI/1k R0603
+R4 58.39 62.26 180 DNI/1k R0603
+R5 29.46 76.45 180 DNI/5.1k R0603
+R6 43.18 76.48 0 DNI/5.1k R0603
+R10 64.26 72.06 0 DNI/1k R0603
+R11 24.16 72.06 0 DNI/100 R0603
+R12 47.55 72.42 0 DNI/220 R0603
+R16 20.07 60.05 0 DNI/68 R0805
+R17 24.71 60.15 270 DNI/180 R0603
+R18 32.94 60.20 180 DNI/68 R0805
+R21 55.42 51.26 0 DNI/100 R0603
+R22 59.33 44.63 0 DNI/220 R0603
+R25 67.59 40.77 90 DNI/4.7k R0603
+R26 76.53 40.79 90 DNI/4.7k R0603
+R28 61.98 8.81 0 DNI/10k R0603
+R31 3.86 44.37 0 DNI/220 R0603
+R32 3.40 60.55 180 DNI/1k R0603
+U1 54.36 27.48 270 Raspberry Pi Pico PICO-PKG-NO_DEBUG
+U6 39.24 51.22 270 SR105U SR_FRS_0W5
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_bom.csv.txt b/hardware/v2.1/cubesatsim-main-v2.1.0_bom.csv.txt
new file mode 100644
index 00000000..b75fcd21
--- /dev/null
+++ b/hardware/v2.1/cubesatsim-main-v2.1.0_bom.csv.txt
@@ -0,0 +1,94 @@
+"Part";"Value";"Device";"Package";"Description";"";
+"C1";"18pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C2";"16pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C3";"18pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C4";"16pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C5";"47uF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";"";
+"C6";"100nF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";"";
+"C7";"DNI/47uF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C8";"DNI/100nF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"C9";"100nF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";"";
+"C10";"DNI/100nF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";"";
+"D1";"BYW27-400";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D2";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D3";"1N4148";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D5";"DNI/1N4007FL";"DIODE_SOD-123FL";"SOD-123FL";"Diode";"";
+"D6";"DNI/B5817WS";"DIODESOD-323F";"SOD-323F";"Diode";"";
+"D7";"DNI/4148WS";"DIODESOD-323F";"SOD-323F";"Diode";"";
+"D8";"DNI/5V1 Zener 1W";"ZENER-DIODEZD-2.5";"ZDIO-2.5";"Z-Diode";"";
+"D10";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"E1";"ANT-916-CHP-T";"ANT-916-CHP-T";"XDCR_ANT-916-CHP-T";"868MHz ISM, LoRa, Sensor Networks, SigFox Chip RF Antenna 863MHz ~ 873MHz 0.5dBi Solder Surface Mount Check prices";"";
+"E2";"ANT-916-CHP-T";"ANT-916-CHP-T";"XDCR_ANT-916-CHP-T";"868MHz ISM, LoRa, Sensor Networks, SigFox Chip RF Antenna 863MHz ~ 873MHz 0.5dBi Solder Surface Mount Check prices";"";
+"F1";"RHEF100-2";"PTCPTH";"PTC";"Resettable Fuse PTC";"";
+"F2";"DNI/MF-FSML100/8-2";"PTC0603";"0603";"Resettable Fuse PTC";"";
+"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J4";"MPU6050";"M08NO_SILK_FEMALE_PTH";"1X08_NO_SILK@1";"Header 8";"";
+"J5";"BME280";"M04NO_SILK_ALL_ROUND";"1X04_NO_SILK_ALL_ROUND";"Header 4";"";
+"J6";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"J7";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"J8";"Sparkfun USB-C Breakout";"CONN_06NO_SILK_FEMALE_PTH";"1X06_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J9";"DNI/USB4105-GF-A or GT-USB-7010B";"USB_C_2-LAYER_PADS";"USB-C-16P-2LAYER-PADS";"USB Type C 16Pin Connector";"";
+"J10";"DNI/Sparkfun QWIIC Breakout";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J12";"DNI/1x4 pin header";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J13";"SJ1-2503A";"SJ1-2503A";"CONN_SJ1-2503A";"";"";
+"J14";"SJ1-2503A";"SJ1-2503A";"CONN_SJ1-2503A";"";"";
+"J15";"";"CONN_06NO_SILK_NO_POP";"1X06_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP1";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP2";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP3";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP4";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP5";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP6";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP7";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP8";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP9";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP10";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP11";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"L1";"13nH";"SMD-FERRITE-CHIP-120-OHM-500MA(0603)";"L0603";"303030001";"";
+"L2";"13nH";"SMD-FERRITE-CHIP-120-OHM-500MA(0603)";"L0603";"303030001";"";
+"LED1";"White 5mm";"LED3MM";"LED3MM";"LED";"";
+"LED2";"Yellow 5mm";"LED3MM";"LED3MM";"LED";"";
+"LED3";"Green 5mm";"LED3MM";"LED3MM";"LED";"";
+"LED4";"Blue 5mm";"LED3MM";"LED3MM";"LED";"";
+"LED5";"Red 5mm";"LED3MM";"LED3MM";"LED";"";
+"R1";"1K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R2";"DNI/1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R3";"1K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R4";"DNI/1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R5";"DNI/5.1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R6";"DNI/5.1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R7";"1k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R8";"100";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R9";"220";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R10";"DNI/1k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R11";"DNI/100";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R12";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R13";"68";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R14";"180";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R15";"68";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R16";"DNI/68";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R17";"DNI/180";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R18";"DNI/68";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R19";"100";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R20";"220";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R21";"DNI/100";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R22";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R23";"4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R24";"4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R25";"DNI/4.7k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R26";"DNI/4.7k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R27";"10K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R28";"DNI/10k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";"";
+"R29";"220";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R30";"1k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R31";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R32";"DNI/1k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";"";
+"R33";"DNI/4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"R34";"DNI/4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";"";
+"S1";"RA-SPST";"RA-SPST";"RA-SPST";"";"";
+"U1";"Raspberry Pi Pico";"RASPBERRY_PICO-NO_DEBUG";"PICO-PKG-NO_DEBUG";"";"";
+"U6";"SR105U";"SR_FRS_0W5";"SR_FRS_0W5";"";"";
+"U7";"DRA818V";"DRA818V";"DORJI_DRA818V";"Check availability";"";
+"X1";"SC1464-ND";"PG203J";"PG203J";"MIC/HEADPHONE JACK";"";
+"X2";"SMA-VERT";"SMA-VERT";"SMA-VERT";"";"";
+"X3";"SMA-VERT";"SMA-VERT";"SMA-VERT";"";"";
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_bottom.png b/hardware/v2.1/cubesatsim-main-v2.1.0_bottom.png
new file mode 100644
index 00000000..c5a4429a
Binary files /dev/null and b/hardware/v2.1/cubesatsim-main-v2.1.0_bottom.png differ
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_centroid.zip b/hardware/v2.1/cubesatsim-main-v2.1.0_centroid.zip
new file mode 100644
index 00000000..27156c2c
Binary files /dev/null and b/hardware/v2.1/cubesatsim-main-v2.1.0_centroid.zip differ
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_gerbers.zip b/hardware/v2.1/cubesatsim-main-v2.1.0_gerbers.zip
new file mode 100644
index 00000000..095b9c1a
Binary files /dev/null and b/hardware/v2.1/cubesatsim-main-v2.1.0_gerbers.zip differ
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_pcb.png b/hardware/v2.1/cubesatsim-main-v2.1.0_pcb.png
new file mode 100644
index 00000000..92150f61
Binary files /dev/null and b/hardware/v2.1/cubesatsim-main-v2.1.0_pcb.png differ
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_pour.png b/hardware/v2.1/cubesatsim-main-v2.1.0_pour.png
new file mode 100644
index 00000000..5c4dce49
Binary files /dev/null and b/hardware/v2.1/cubesatsim-main-v2.1.0_pour.png differ
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_schematic.pdf b/hardware/v2.1/cubesatsim-main-v2.1.0_schematic.pdf
new file mode 100644
index 00000000..46ae259f
Binary files /dev/null and b/hardware/v2.1/cubesatsim-main-v2.1.0_schematic.pdf differ
diff --git a/hardware/v2.1/cubesatsim-main-v2.1.0_top.png b/hardware/v2.1/cubesatsim-main-v2.1.0_top.png
new file mode 100644
index 00000000..180a19c5
Binary files /dev/null and b/hardware/v2.1/cubesatsim-main-v2.1.0_top.png differ
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0._gerbers.zip b/hardware/v2.1/cubesatsim-solar-v2.1.0._gerbers.zip
new file mode 100644
index 00000000..ed8ec3cb
Binary files /dev/null and b/hardware/v2.1/cubesatsim-solar-v2.1.0._gerbers.zip differ
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0.mnb b/hardware/v2.1/cubesatsim-solar-v2.1.0.mnb
new file mode 100644
index 00000000..3ac6ed08
--- /dev/null
+++ b/hardware/v2.1/cubesatsim-solar-v2.1.0.mnb
@@ -0,0 +1,12 @@
+D1 37.58 48.87 180 1N5817 D-2.5
+D2 37.66 42.52 180 1N5817 D-2.5
+D3 37.50 35.95 180 1N5817 D-2.5
+D4 42.94 48.94 0 1N5817 D-2.5
+D5 42.94 42.42 0 1N5817 D-2.5
+D6 42.79 36.07 0 1N5817 D-2.5
+JP9 1.35 57.85 270 VDD-EN SMT-JUMPER_2_NC_TRACE_SILK
+JP18 24.75 62.60 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK
+U5 71.44 19.89 90 INA219 purple board INA219
+U6 8.59 48.95 270 INA219 purple board INA219
+U7 8.46 20.29 270 INA219 purple board INA219
+U8 71.36 48.21 90 INA219 purple board INA219
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0.mnt b/hardware/v2.1/cubesatsim-solar-v2.1.0.mnt
new file mode 100644
index 00000000..54cb3f58
--- /dev/null
+++ b/hardware/v2.1/cubesatsim-solar-v2.1.0.mnt
@@ -0,0 +1,29 @@
+C2 17.54 37.77 0 0.1µF 0603
+C3 17.41 21.59 0 0.1µF 0603
+C4 17.56 11.14 0 0.1µF 0603
+C5 17.53 50.09 0 0.1µF 0603
+C6 61.82 19.28 180 0.1µF 0603
+C7 62.06 38.65 180 0.1µF 0603
+D7 42.95 38.00 0 1A/23V/620mV SOD-323
+D8 43.08 44.40 0 1A/23V/620mV SOD-323
+D9 43.43 50.75 0 1A/23V/620mV SOD-323
+D10 37.72 50.67 180 1A/23V/620mV SOD-323
+D11 37.62 37.92 180 1A/23V/620mV SOD-323
+D12 37.90 44.40 180 1A/23V/620mV SOD-323
+J1 32.55 66.61 0 CONN_20X2 2X20
+R1 11.58 43.79 270 R100 R0805
+R2 11.68 15.01 270 R100 R0805
+R5 24.84 14.99 90 R100 R0805
+R6 24.87 43.84 270 R100 R0805
+R9 68.07 25.10 90 R100 R0805
+R10 68.19 53.47 90 R100 R0805
+R11 42.91 62.08 0 DNI-4.7k R0603
+R12 36.87 62.08 0 DNI-4.7k R0603
+U2 17.53 44.60 0 INA219AIDR D0008A_N
+U3 48.65 48.20 90 INA219 purple board INA219
+U4 30.84 48.90 270 INA219 purple board INA219
+U10 17.45 26.75 0 INA219AIDR D0008A_N
+U11 17.68 16.66 0 INA219AIDR D0008A_N
+U12 17.50 55.36 0 INA219AIDR D0008A_N
+U13 61.72 24.82 0 INA219AIDR D0008A_N
+U14 61.58 44.20 0 INA219AIDR D0008A_N
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0_bom.csv.txt b/hardware/v2.1/cubesatsim-solar-v2.1.0_bom.csv.txt
new file mode 100644
index 00000000..200e9fdb
--- /dev/null
+++ b/hardware/v2.1/cubesatsim-solar-v2.1.0_bom.csv.txt
@@ -0,0 +1,71 @@
+"Part";"Value";"Device";"Package";"Description";"";
+"C2";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";
+"C3";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";
+"C4";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";
+"C5";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";
+"C6";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";
+"C7";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";
+"D1";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D2";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D3";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D4";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D5";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D6";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";"";
+"D7";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";"";
+"D8";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";"";
+"D9";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";"";
+"D10";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";"";
+"D11";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";"";
+"D12";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";"";
+"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"J5";"DNI/Sparkfun QWIIC Breakout";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP1";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP2";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP3";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP4";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP5";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP6";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP7";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP8";"Micro JST";"CONN_021X02_NO_SILK";"1X02_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP9";"VDD-EN";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";
+"JP10";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP11";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP12";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP13";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP14";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP15";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP16";"";"CONN_01PTH_NO_SILK_YES_STOP";"1X01_NO_SILK";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP17";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP18";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";
+"JP19";"";"CONN_01PTH_NO_SILK_YES_STOP";"1X01_NO_SILK";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";
+"JP20";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP21";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP22";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP23";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP24";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP25";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"JP26";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";
+"R1";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R2";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R3";"4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R4";"4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R5";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R6";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R7";"DNI-4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R8";"DNI-4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";"";
+"R9";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R10";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";
+"R11";"DNI-4.7k";"R-US_R0603";"R0603";"RESISTOR, American symbol";"";
+"R12";"DNI-4.7k";"R-US_R0603";"R0603";"RESISTOR, American symbol";"";
+"U2";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"";
+"U3";"INA219 purple board";"INA219";"INA219";"";"";
+"U4";"INA219 purple board";"INA219";"INA219";"";"";
+"U5";"INA219 purple board";"INA219";"INA219";"";"";
+"U6";"INA219 purple board";"INA219";"INA219";"";"";
+"U7";"INA219 purple board";"INA219";"INA219";"";"";
+"U8";"INA219 purple board";"INA219";"INA219";"";"";
+"U10";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"";
+"U11";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"";
+"U12";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"";
+"U13";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"";
+"U14";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"";
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0_bottom.png b/hardware/v2.1/cubesatsim-solar-v2.1.0_bottom.png
new file mode 100644
index 00000000..ee63809f
Binary files /dev/null and b/hardware/v2.1/cubesatsim-solar-v2.1.0_bottom.png differ
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0_centroid.zip b/hardware/v2.1/cubesatsim-solar-v2.1.0_centroid.zip
new file mode 100644
index 00000000..e80ca696
Binary files /dev/null and b/hardware/v2.1/cubesatsim-solar-v2.1.0_centroid.zip differ
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0_pcb.png b/hardware/v2.1/cubesatsim-solar-v2.1.0_pcb.png
new file mode 100644
index 00000000..5ab20a76
Binary files /dev/null and b/hardware/v2.1/cubesatsim-solar-v2.1.0_pcb.png differ
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0_pour.png b/hardware/v2.1/cubesatsim-solar-v2.1.0_pour.png
new file mode 100644
index 00000000..8dd7bf7a
Binary files /dev/null and b/hardware/v2.1/cubesatsim-solar-v2.1.0_pour.png differ
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0_schematic.pdf b/hardware/v2.1/cubesatsim-solar-v2.1.0_schematic.pdf
new file mode 100644
index 00000000..77e59fb7
Binary files /dev/null and b/hardware/v2.1/cubesatsim-solar-v2.1.0_schematic.pdf differ
diff --git a/hardware/v2.1/cubesatsim-solar-v2.1.0_top.png b/hardware/v2.1/cubesatsim-solar-v2.1.0_top.png
new file mode 100644
index 00000000..2c8e3ee3
Binary files /dev/null and b/hardware/v2.1/cubesatsim-solar-v2.1.0_top.png differ
diff --git a/hardware/v2.1/readme.md b/hardware/v2.1/readme.md
new file mode 100644
index 00000000..6e079749
--- /dev/null
+++ b/hardware/v2.1/readme.md
@@ -0,0 +1,33 @@
+
+
+
+
+Here is information about the CubeSatSim PCBs, version v2.1
+
+There are 3 boards: Main, Solar, and Battery
+
+Here's what the files are:
+
+*_gerbers.zip -- All gerber files used to fabricate PCBs along with .TXT drill file
+
+*_schematic.pdf -- Schematic
+
+*_pcb.png -- View of board
+
+*_pour.png -- View of board with fill
+
+*_top.png -- Top view of PCB generated by gerbers
+
+*_bottom.png -- Bottom view of PCB generated by gerbers
+
+*.mnt -- top SMD component placement data
+
+*.mnb -- bottom SMD component placement data
+
+*_bom.csv.txt -- Bill of Materials in CSV format
+
+I use PCBWay to fabricate PCBs https://pcbway.com
+
+Here is the bill of materials: https://CubeSatSim.org/bom
+
+Wiki instructions: https://github.com/alanbjohnston/CubeSatSim/wiki/
diff --git a/install b/install
index 76b2c3da..964e13ed 100755
--- a/install
+++ b/install
@@ -1,13 +1,322 @@
#!/bin/bash
-echo -e "\ninstallation script for CubeSatSim v2.1\n"
+FLAG=0
+checkout=0
+BULLSEYE=0
+UPDATE=0
+
+FILE=/home/pi/CubeSatSim/cubesatsim # code has already been compiled
+if [ -f "$FILE" ]; then
+
+ UPDATE=1
+
+ echo -e "\nUpdate script for CubeSatSim v2.2\n"
+
+ sudo rm /home/pi/CubeSatSim/telem.wav &>/dev/null
+ sudo rm /home/pi/CubeSatSim/t.txt &>/dev/null
+ sudo rm /home/pi/CubeSatSim/uptime &>/dev/null
+
+ if [ -z "$1" ] ; then
+ checkout=0
+ else
+ checkout=1
+ branch="$1"
+ echo -n "changing to branch "
+ echo $branch
+ FLAG=1
+ fi
+
+ if [ "$2" = "n" ] ; then
+ noreboot=1
+ else
+ noreboot=0
+ fi
+
+else
+
+ echo -e "\nInstallation script for CubeSatSim v2.2\n"
+
+ touch /home/pi/CubeSatSim/command_control_direwolf
+
+ echo "creating $FILE"
+ echo "AMSAT 0 0 0 no 3 434.9 435 no 0 0 no 60" > /home/pi/CubeSatSim/sim.cfg
+
+ /home/pi/CubeSatSim/config -c -n
+
+ /home/pi/CubeSatSim/config -l -n
+
+fi
+
+if [[ $(grep '11.' /etc/debian_version) ]]; then
+
+ BULLSEYE=1
+
+ echo "Debian 11 (Bullseye) detected"
+
+ sudo cp /boot/config.txt /boot/config.txt.0
+
+ sudo cp /boot/cmdline.txt /boot/cmdline.txt.0
+
+ sudo raspi-config nonint do_i2c 0
+
+ sudo raspi-config nonint do_camera 0
+
+ sudo raspi-config nonint do_legacy 0
+
+ sudo sed -i 's/console=serial0,115200 //g' /boot/cmdline.txt
+
+ sudo sed -i 's/console=tty1 r/console=tty1 maxcpus=2 r/g' /boot/cmdline.txt # single core if Pi Zero 2
+# sudo sed -i 's/console=tty1 maxcpus=1 r/console=tty1 r/g' /boot/cmdline.txt
+
+ sudo sed -i 's/maxcpus=1/maxcpus=2/g' /boot/cmdline.txt # single core if Pi Zero 2
+
+ sudo sed -i 's/#dtparam=i2c_arm=on/dtparam=i2c_arm=on/g' /boot/config.txt
+
+ if [[ $(grep 'dtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24' /boot/config.txt) ]]; then
+ echo "dtoverlay=i2c-gpio already in /boot/config.txt"
+ else
+ echo "adding dtoverlay=i2c-gpio to /boot/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'enable_uart=1' /boot/config.txt) ]]; then
+ echo "enable_uart=1 already in /boot/config.txt"
+ else
+ echo "adding enable_uart=1 to /boot/config.txt"
+ sudo sh -c 'echo "\nenable_uart=1" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=disable-bt' /boot/config.txt) ]]; then
+ echo "dtoverlay=disable-bt already in /boot/config.txt"
+ else
+ echo "adding dtoverlay=disable-bt to /boot/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=disable-bt" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=dwc2' /boot/config.txt) ]]; then
+ echo "dtoverlay=dwc2 aalready in /boot/config.txt"
+ else
+ echo "adding dtoverlay=dwc2 to /boot/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=dwc2" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'modules-load=dwc2,g_ether' /boot/cmdline.txt) ]]; then
+ echo "modules-load=dwc2,g_ether already in /boot/cmdline.txt"
+ else
+ echo "adding modules-load=dwc2,g_ether to /boot/cmdline.txt"
+ sudo sed -i 's/ rootwait/ rootwait modules-load=dwc2,g_ether/g' /boot/cmdline.txt
+ fi
+
+ if [[ $(grep 'dtparam=audio=on' /boot/config.txt) ]]; then
+ echo "dtparam=audio=on already in /boot/config.txt"
+ else
+ echo "adding dtparam=audio=on to /boot/config.txt"
+ sudo sh -c 'echo "\ndtparam=audio=on" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=audremap,enable_jack=on' /boot/config.txt) ]]; then
+ echo "dtoverlay=audremap,enable_jack=on already in /boot/config.txt"
+ else
+ echo "adding dtoverlay=audremap,enable_jack=on to /boot/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=audremap,enable_jack=on" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=pwm,pin=18,func=2' /boot/config.txt) ]]; then
+ echo "dtoverlay=pwm,pin=18,func=2 already in /boot/config.txt"
+ else
+ echo "adding overlay=pwm,pin=18,func=2 to /boot/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=pwm,pin=18,func=2" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'disable_splash=1' /boot/config.txt) ]]; then
+ echo "disable_splash=1 already in /boot/config.txt"
+ else
+ echo "adding disable_splash=1 to /boot/config.txt"
+ sudo sh -c 'echo "\ndisable_splash=1" >> /boot/config.txt'
+ fi
+
+ if [[ $(grep 'boot_delay=0' /boot/config.txt) ]]; then
+ echo "boot_delay=0 already in /boot/config.txt"
+ else
+ echo "adding boot_delay=0 to /boot/config.txt"
+ sudo sh -c 'echo "\nboot_delay=0" >> /boot/config.txt'
+ fi
+
+ if ! grep -q force_turbo=1 /boot/config.txt ; then sudo sh -c 'echo "force_turbo=1" >> /boot/config.txt'; fi
+
+ sudo sh -c 'echo "\n" >> /boot/config.txt'
+ fi
+
+if [[ $(grep 'bookworm' /etc/os-release) ]]; then
+
+ echo "Debian 12 (Bookworm) detected"
+
+ sudo cp /boot/firmware/config.txt /boot/firmware/config.txt.0
+
+ sudo cp /boot/firmware/cmdline.txt /boot/firmware/cmdline.txt.0
+
+ sudo raspi-config nonint do_i2c 0
+
+ sudo raspi-config nonint do_camera 0
+
+ sudo raspi-config nonint do_legacy 0
+
+ sudo sed -i 's/console=serial0,115200 //g' /boot/firmware/cmdline.txt
+
+ sudo sed -i 's/console=tty1 r/console=tty1 maxcpus=2 r/g' /boot/firmware/cmdline.txt # single core if Pi Zero 2
+# sudo sed -i 's/console=tty1 maxcpus=1 r/console=tty1 r/g' /boot/firmware/cmdline.txt
+
+ sudo sed -i 's/maxcpus=1/maxcpus=2/g' /boot/firmware/cmdline.txt # single core if Pi Zero 2
+
+ sudo sed -i 's/#dtparam=i2c_arm=on/dtparam=i2c_arm=on/g' /boot/firmware/config.txt
+
+ sudo sed -i 's/#dtoverlay=vc4-fkms-v3d/dtoverlay=vc4-fkms-v3d/g' /boot/firmware/config.txt
+ sudo sed -i 's/#dtoverlay=vc4-kms-v3d/dtoverlay=vc4-kms-v3d/g' /boot/firmware/config.txt
+
+
+ if [[ $(grep 'dtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24' /boot/firmware/config.txt) ]]; then
+ echo "dtoverlay=i2c-gpio already in /boot/firmware/config.txt"
+ else
+ echo "adding dtoverlay=i2c-gpio to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'enable_uart=1' /boot/firmware/config.txt) ]]; then
+ echo "enable_uart=1 already in /boot/firmware/config.txt"
+ else
+ echo "adding enable_uart=1 to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\nenable_uart=1" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=disable-bt' /boot/firmware/config.txt) ]]; then
+ echo "dtoverlay=disable-bt already in /boot/firmware/config.txt"
+ else
+ echo "adding dtoverlay=disable-bt to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=disable-bt" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=dwc2' /boot/firmware/config.txt) ]]; then
+ echo "dtoverlay=dwc2 aalready in /boot/firmware/config.txt"
+ else
+ echo "adding dtoverlay=dwc2 to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=dwc2" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'modules-load=dwc2,g_ether' /boot/firmware/cmdline.txt) ]]; then
+ echo "modules-load=dwc2,g_ether already in /boot/firmware/cmdline.txt"
+ else
+ echo "adding modules-load=dwc2,g_ether to /boot/firmware/cmdline.txt"
+ sudo sed -i 's/ rootwait/ rootwait modules-load=dwc2,g_ether/g' /boot/firmware/cmdline.txt
+ fi
+
+ if [[ $(grep 'dtparam=audio=on' /boot/firmware/config.txt) ]]; then
+ echo "dtparam=audio=on already in /boot/firmware/config.txt"
+ else
+ echo "adding dtparam=audio=on to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ndtparam=audio=on" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=audremap,enable_jack=on' /boot/firmware/config.txt) ]]; then
+ echo "dtoverlay=audremap,enable_jack=on already in /boot/firmware/config.txt"
+ else
+ echo "adding dtoverlay=audremap,enable_jack=on to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=audremap,enable_jack=on" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'dtoverlay=pwm,pin=18,func=2' /boot/firmware/config.txt) ]]; then
+ echo "dtoverlay=pwm,pin=18,func=2 already in /boot/firmware/config.txt"
+ else
+ echo "adding to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ndtoverlay=pwm,pin=18,func=2" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'disable_splash=1' /boot/firmware/config.txt) ]]; then
+ echo "disable_splash=1 already in /boot/firmware/config.txt"
+ else
+ echo "adding disable_splash=1 to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ndisable_splash=1" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'boot_delay=0' /boot/firmware/config.txt) ]]; then
+ echo "boot_delay=0 already in /boot/firmware/config.txt"
+ else
+ echo "adding boot_delay=0 to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\nboot_delay=0" >> /boot/firmware/config.txt'
+ fi
+
+ if [[ $(grep 'camera_auto_detect=1' /boot/firmware/config.txt) ]]; then
+ echo "camera_auto_detect=1 already in /boot/firmware/config.txt"
+ else
+ echo "adding camera_auto_detect=1 to /boot/firmware/config.txt"
+ sudo sh -c 'echo "\ncamera_auto_detect=1" >> /boot/firmware/config.txt'
+ fi
+
+ if ! grep -q force_turbo=1 /boot/firmware/config.txt ; then sudo sh -c 'echo "force_turbo=1" >> /boot/firmware/config.txt'; fi
+
+ sudo sh -c 'echo "\n" >> /boot/firmware/config.txt'
+
+elif [[ $(grep 'trixie' /etc/os-release) ]]; then
+
+ echo "Trixie detected, installation continuing."
+ echo "Your Pi OS version is not Bookworm or Bullseye."
+ echo "The software installation will likely not work."
+ echo "See the README.md for how to install using Bookworm."
+ echo
+
+ echo "Are you sure you want to continue the installation (y/n)?"
+
+ read -r ANS
+
+ if [ "$ANS" = "n" ]; then
+ exit 1
+ fi
+fi
FILE=/home/pi/CubeSatSim/sim.cfg
if [ -f "$FILE" ]; then
echo "$FILE exists."
+
+ changed=0
+ value=`cat /home/pi/CubeSatSim/sim.cfg`
+ # echo "$value"
+ echo "$value" > /dev/null
+ set -- $value
+
+ if [ -z "$1" ] ; then n1="AMSAT" ; changed=1 ; else n1=$1 ; fi # callsign
+ if [ -z "$2" ] ; then n2="0" ; changed=1 ; else n2=$2 ; fi # reset count
+ if [ -z "$3" ] ; then n3="0" ; changed=1 ; else n3=$3 ; fi # lat
+ if [ -z "$4" ] ; then n4="0" ; changed=1 ; else n4=$4 ; fi # lon
+ if [ -z "$5" ] ; then n5="no" ; changed=1 ; else n5=$5 ; fi # sim mode
+ if [ -z "$6" ] ; then n6="3" ; changed=1 ; else n6=$6 ; fi # squelch
+ if [ -z "$7" ] ; then n7="434.9000" ; changed=1 ; else n7=$7 ; fi # transmit frequency
+ if [ -z "$8" ] ; then n8="435.0000" ; changed=1 ; else n8=$8 ; fi # receive frequency
+ if [ -z "$9" ] ; then n9="no" ; changed=1 ; else n9=$9 ; fi # hab mode
+ if [ -z "${10}" ] ; then m1="0" ; changed=1 ; else m1=${10} ; fi # rx pl code
+ if [ -z "${11}" ] ; then m2="0" ; changed=1 ; else m2=${11} ; fi # tx pl code
+ if [ -z "${12}" ] ; then m3="no" ; changed=1 ; else m3=${12} ; fi # random fail
+ if [ -z "${13}" ] ; then m4="60" ; changed=1 ; else m4=${13} ; fi # random fail period
+
+ if [ $changed -eq 1 ]; then
+ echo -e "Current sim.cfg configuration file:"
+ echo
+ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13}
+ echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
+ echo
+ echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $m1 $m2 $m3 $m4
+ echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $m1 $m2 $m3 $m4> /home/pi/CubeSatSim/sim.cfg
+ echo
+ fi
+
else
echo "creating $FILE"
- echo "AMSAT 1 0.0 0.0" > /home/pi/CubeSatSim/sim.cfg
+ echo "AMSAT 0 0 0 no 3 434.9 435 no 0 0 no 60" > /home/pi/CubeSatSim/sim.cfg
+fi
+
+if [[ $(grep 'cubesatsim' /etc/motd) ]]; then
+ echo "motd already updated"
+else
+ echo "updating motd"
+ sudo sh -c 'cat /home/pi/CubeSatSim/motd.txt >> /etc/motd'
fi
FILE=/home/pi/CubeSatSim/command_tx
@@ -25,46 +334,119 @@ else
echo "creating $FILE"
echo "0\n" > /home/pi/CubeSatSim/command_count.txt
fi
+
+sudo apt-get update && sudo apt-get dist-upgrade -y
-cd
+# if [ $BULLSEYE -eq 1 ]; then
+# sudo apt purge -y python3-pip
+# sudo apt install -y python3-pip
+# fi
-CubeSatSim/config -c -n
+cp /home/pi/CubeSatSim/groundstation/pacsat.desktop /home/pi/Desktop/pacsat.desktop
-CubeSatSim/config -l -n
-
-sudo apt-get update && sudo apt-get dist-upgrade -y
+if [ ! -d "/home/pi/venv" ]; then
+
+ cd
+ sudo apt install -y python3-venv
+ sudo python3 -m venv venv
+ source /home/pi/venv/bin/activate
+
+ curl https://bootstrap.pypa.io/get-pip.py | sudo /home/pi/venv/bin/python3
+
+ sudo /home/pi/venv/bin/pip3 install adafruit_extended_bus
+ sudo /home/pi/venv/bin/pip3 install adafruit-circuitpython-ina219
+
+fi
sudo apt-get remove pulseaudio -y
+sudo apt-get install -y gcc g++ make cmake libasound2-dev libudev-dev libavahi-client-dev libgpiod-dev raspi-config
+
# removed wiringpi and python-picamera python3-picamera
sudo apt-get install -y git libasound2-dev i2c-tools build-essential libgd-dev libmagic-dev minicom
-cd /tmp
+if [ -d "/home/pi/direwolf" ]; then
+
+ cd
+ cd direwolf
+ # Get the URL of the 'origin' remote
+ REPO_URL=$(git config --get remote.origin.url)
+
+ # Check if the command was successful and a URL was retrieved
+ if [ $? -eq 0 ] && [ -n "$REPO_URL" ]; then
+
+ if [ ! "$REPO_URL" = "https://github.com/wb2osz/direwolf.git" ]; then
+
+ echo "Current Direwolf git repository URL is $REPO_URL"
+ sudo rm -r /home/pi/direwolf
+ fi
+ else
+ echo "Could not find the URL for the 'origin' remote for Direwolf"
+ fi
+fi
-# wget https://project-downloads.drogon.net/wiringpi-latest.deb
+if [ ! -d "/home/pi/direwolf" ]; then
-# sudo dpkg -i wiringpi-latest.deb
+ echo "Installing Direwolf from https://github.com/wb2osz/direwolf.git"
+ cd
+ git clone https://github.com/wb2osz/direwolf.git
+ cd direwolf
+ mkdir build
+ cd build
+ cmake ..
+ make -j4
+ sudo make install
+ make install-conf
-cd
+fi
-git clone https://github.com/alanbjohnston/WiringPi
-cd WiringPi
-./build debian
+ sudo apt-get install -y gpsd gpsd-clients libgps-dev python3-gps
+ sudo systemctl disable gpsd
+ sudo systemctl disable gpsd.socket
-sudo dpkg -i debian-template/wiringpi-2.61-1.deb
+if [ ! -d "/home/pi/WiringPi" ]; then
+ cd
+ git clone https://github.com/alanbjohnston/WiringPi
+ cd WiringPi
+ ./build debian
+ sudo dpkg -i debian-template/wiringpi-2.61-1.deb
+fi
cd
-#changed to python3-smbus
-sudo apt install -y python3-pip python3-smbus libjpeg-dev zlib1g-dev libfreetype6-dev libopenjp2-7 libtiff5 python3-pil python3-serial libusb-1.0
+if [ ! $BULLSEYE -eq 1 ]; then
+ sudo apt install -y libtiff6
+fi
-sudo pip3 install --upgrade setuptools
+sudo apt install -y python3-pip python3-smbus libjpeg-dev zlib1g-dev libfreetype6-dev libopenjp2-7 python3-pil python3-serial libusb-1.0-0 libusb-1.0-0-dev
-sudo pip3 install adafruit-blinka RPI.GPIO adafruit-extended-bus adafruit-circuitpython-ina219
+if [ $BULLSEYE -eq 1 ] || [ $UPDATE -eq 0 ] ; then
-cd ~/CubeSatSim
+ sudo pip3 install --upgrade setuptools
+
+ sudo pip3 install adafruit-blinka RPI.GPIO adafruit-extended-bus adafruit-circuitpython-ina219
+
+fi
+
+cd /home/pi/CubeSatSim
+
+git pull --no-rebase > .updated
+
+if [ $checkout -eq 1 ]; then
+ git checkout $branch
+ git pull --no-rebase > .updated
+ FLAG=1
+ echo "Running update again"
+ /home/pi/CubeSatSim/install
+ exit
+fi
-git pull --no-rebase
+grep 'install' /home/pi/CubeSatSim/.updated
+if [[ $(grep 'install' /home/pi/CubeSatSim/.updated) ]]; then
+ echo "install script updated, running again"
+ /home/pi/CubeSatSim/install
+ exit
+fi
make debug
@@ -76,227 +458,403 @@ else
echo "b" > .mode
fi
-cd
-
-git clone https://github.com/alanbjohnston/direwolf.git
-
-cd direwolf
-
-make -j
+if [ ! -d "/home/pi/pi-power-button" ]; then
-sudo make install
-
-make install-rpi
-
-
-cd
+ cd
+ git clone https://github.com/alanbjohnston/pi-power-button.git
+ cd pi-power-button
+ git checkout master
+ ./script/install
+ sudo apt-get install -y libraspberrypi-dev
-git clone https://github.com/alanbjohnston/pi-power-button.git
+fi
-cd pi-power-button
+cd /home/pi/pi-power-button
+git pull --no-rebase > .updated_p
git checkout master
+grep 'changed' /home/pi/pi-power-button/.updated_p
+if [[ $(grep 'changed' /home/pi/pi-power-button/.updated_p) ]]; then
-./script/install
-
-cd
-
-echo "Installing SSDV for FUNcube mode"
-git clone https://github.com/alanbjohnston/ssdv.git # install ssdv for FUNcube images
-cd ssdv
-make
-cd
-
-echo "Installing fctelem binary v0.2 for FUNcube mode"
-mkdir /home/pi/fctelem
-mkdir /home/pi/fctelem/public_html
-cd fctelem
-wget https://github.com/alanbjohnston/go/releases/download/v0.2/fctelem.zip
-unzip fctelem.zip
-
-cd
-echo "Installing fcdctl to set FUNcubeDongle Pro gain"
-# sudo rm /var/lib/dpkg/info/python3-pip.list
-# sudo apt install python3-pip --reinstall
-# sudo apt-get install -y python3-smbus libusb-1.0
-cd
-git clone https://github.com/csete/fcdctl.git
-cd fcdctl
-make fcdpp
-
-git clone https://github.com/alanbjohnston/PiSSTVpp.git
-
-cd PiSSTVpp
-
-make pisstvpp
-
-echo "Copying SSTV image 1"
-cp /home/pi/CubeSatSim/sstv/sstv_image_1_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg
+ echo "updating pi-power-button."
+ script/install
+ FLAG=1
+fi
-echo "Copying SSTV image 2"
-cp /home/pi/CubeSatSim/sstv/sstv_image_2_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg
+if [ ! -d "/home/pi/g0kla_common" ]; then
+ cd
+ git clone https://github.com/alanbjohnston/g0kla_common.git
+ cd g0kla_common/Debug/
+ make clean
+ make all
+ sudo ./install.sh
-cd
+else
+ cd /home/pi/g0kla_common/Debug/
+
+ git pull --no-rebase > .updated
+ grep 'changed' /home/pi/g0kla_common/Debug/.updated
+ if [[ $(grep 'changed' /home/pi/g0kla_common/Debug/.updated) ]]; then
+
+ echo "updating g0kla_common"
+ make clean
+ make all
+ FLAG=1
+ fi
+fi
-git clone https://github.com/alanbjohnston/rpitx.git
+FILE=/home/pi/pi_pacsat/Debug/pi_pacsat # code has already been compiled
+if [ ! -f "$FILE" ]; then
+
+ cd
+ #git clone https://github.com/alanbjohnston/pi_pacsat.git
+ git clone https://github.com/ac2cz/pi_pacsat.git
+ cd pi_pacsat
+ #git checkout master-debug
+ cd Debug
+ make clean
+ make all
+
+# mkdir /home/pi/PacSat
+# mkdir /home/pi/PacSat/pacsat
+# mkdir /home/pi/PacSat/pacsat/dir
+
+# export LD_LIBRARY_PATH=/mnt/usb-disk/ariss/lib:/usr/local/lib/iors_common:$LD_LIBRARY_PATH
+
+# #value=`cat /home/pi/CubeSatSim/sim.cfg`
+# #echo "$value" > /dev/null
+# #set -- $value
+
+# echo "bit_rate=9600" > pacsat.config
+# echo "bbs_callsign=AMSAT-12" >> pacsat.config
+# echo "broadcast_callsign=AMSAT-11" >> pacsat.config
+# echo "digi_callsign=AMSAT-1" >> pacsat.config
+# echo "max_frames_in_tx_buffer=5" >> pacsat.config
+
+# echo "pb_open=1" > pacsat.state
+# echo "uplink_open=1" >> pacsat.state
+# echo "pb_max_period_for_client_in_seconds=60" >> pacsat.state
+# echo "uplink_max_period_for_client_in_seconds=60" >> pacsat.state
-cd rpitx
+else
+ cd /home/pi/pi_pacsat/Debug/
+
+ git pull --no-rebase > .updated
+ grep 'changed' /home/pi/pi_pacsat/Debug/.updated
+ if [[ $(grep 'changed' /home/pi/pi_pacsat/Debug/.updated) ]]; then
+
+ echo "updating pi_pacsat"
+ make clean
+ make all
+ FLAG=1
+ fi
+fi
-./install.sh
+FILE=/home/pi/pacsat_telem/Debug/pacsat_telem # code has already been compiled
+if [ ! -f "$FILE" ]; then
+ cd
+ sudo apt-get install -y libbsd-dev
+ git clone https://github.com/alanbjohnston/pacsat_telem.git
+ cd pacsat_telem
+ git checkout master-fox
+ cd Debug
+ make clean
+ make all
+fi
-cd
+cd /home/pi/pacsat_telem/Debug/
-sudo cp ~/CubeSatSim/systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service
+git pull --no-rebase > .updated
+# git checkout master-fox
+grep 'changed' /home/pi/pacsat_telem/Debug/.updated
+if [[ $(grep 'changed' /home/pi/pacsat_telem/Debug/.updated) ]]; then
-sudo systemctl enable cubesatsim
+ echo "updating pacsat_telem"
+ make clean
+ make all
+ FLAG=1
+fi
-sudo cp ~/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service
+sudo sed -i 's/#hdmi_group=1/hdmi_group=2/g' /boot/config.txt
+sudo sed -i 's/#hdmi_mode=1/hdmi_mode=16/g' /boot/config.txt
+sudo sed -i 's/#hdmi_force_hotplug=1/hdmi_force_hotplug=1/g' /boot/config.txt
-# sudo systemctl enable transmit
+sudo raspi-config nonint do_vnc 0
-sudo cp ~/CubeSatSim/systemd/command.service /etc/systemd/system/command.service
-sudo systemctl enable command
-sudo cp /home/pi/CubeSatSim/asound.conf /etc/asound.conf
+if [ ! -d "/home/pi/Desktop/PacsatGround" ]; then
-sudo cp /boot/config.txt /boot/config.txt.0
+ cd /tmp
+ wget https://www.g0kla.com/pacsat/downloads/test/PacsatGround_unix_0_46q.tar.gz
+ tar -xzf PacsatGround_unix_0_46q.tar.gz -C /home/pi/Desktop
+ rm PacsatGround_unix_0_46q.tar.gz
+# cp /home/pi/CubeSatSim/spacecraft/PacSatGround_0.46o/* /home/pi/Desktop/PacsatGround/spacecraft/
+# mkdir /home/pi/PacSatGround
+ sudo usermod -a -G gpio pi
+ sudo apt-get install default-jdk -y
-sudo cp /boot/cmdline.txt /boot/cmdline.txt.0
+fi
+cd
-sudo raspi-config nonint do_i2c 0
+if [ ! -d "/home/pi/PiSSTVpp" ]; then
-sudo raspi-config nonint do_camera 0
+ sudo apt-get update -y
+ sudo apt-get install -y python-picamera python3-picamera build-essential libgd-dev libmagic-dev
+ cd
+ git clone https://github.com/alanbjohnston/PiSSTVpp.git
+ cd PiSSTVpp
+ make pisstvpp
-sudo raspi-config nonint do_legacy 0
+fi
-#if [ "$1" = "u" ]; then
-#fi
+if [ ! -d "/home/pi/rpitx" ]; then
-## sudo sed -i 's/console=serial0,115200 //g' /boot/cmdline.txt
-
+ cd
+ git clone https://github.com/alanbjohnston/rpitx.git
+ cd rpitx
+ ./install.sh
+ cd
+else
- sudo sed -i 's/console=serial0,115200 //g' /boot/cmdline.txt
+ if [[ $(grep 'SYNCWITHPWM' /home/pi/rpitx/src/librpitx/src/fskburst.h) ]]; then
+ echo "rpitx library already updated"
+ else
+ echo "updating rpitx"
+ cd /home/pi/rpitx
+ git pull
+ ./update.sh
+ cd
+ fi
+fi
- sudo sed -i 's/console=tty1 r/console=tty1 maxcpus=1 r/g' /boot/cmdline.txt # single core if Pi Zero 2
+FILE=/etc/systemd/system/cubesatsim.service
+if [ -f "$FILE" ]; then
+ if [[ $(diff /home/pi/CubeSatSim/systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service) ]]; then
+ echo "changed cubesatsim.service."
+ sudo cp /home/pi/CubeSatSim/systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service
+ FLAG=1
+ else
+ echo "no changes to cubesatsim.service."
+ fi
+else
+ echo "creating cubesatsim.service."
+ sudo cp /home/pi/CubeSatSim/systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service
+ sudo systemctl enable cubesatsim
- sudo sed -i 's/maxcpus=2/maxcpus=1/g' /boot/cmdline.txt # single core if Pi Zero 2
+ FLAG=1
+fi
- sudo sed -i 's/#dtparam=i2c_arm=on/dtparam=i2c_arm=on/g' /boot/config.txt
-
- if [[ $(grep 'dtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24' /boot/config.txt) ]]; then
- echo "dtoverlay=i2c-gpio already in /boot/config.txt"
- else
- echo "adding dtoverlay=i2c-gpio to /boot/config.txt"
- sudo sh -c 'echo "\ndtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24" >> /boot/config.txt'
- fi
+FILE=/etc/systemd/system/rpitx.service
+if [ -f "$FILE" ]; then
+ sudo systemctl disable rpitx
+ sudo rm /etc/systemd/system/rpitx.service
+fi
- if [[ $(grep 'enable_uart=1' /boot/config.txt) ]]; then
- echo "enable_uart=1 already in /boot/config.txt"
- else
- echo "adding enable_uart=1 to /boot/config.txt"
- sudo sh -c 'echo "\nenable_uart=1" >> /boot/config.txt'
- fi
-
- if [[ $(grep 'dtoverlay=disable-bt' /boot/config.txt) ]]; then
- echo "dtoverlay=disable-bt already in /boot/config.txt"
- else
- echo "adding dtoverlay=disable-bt to /boot/config.txt"
- sudo sh -c 'echo "\ndtoverlay=disable-bt" >> /boot/config.txt'
- fi
-
- if [[ $(grep 'dtoverlay=dwc2' /boot/config.txt) ]]; then
- echo "dtoverlay=dwc2 aalready in /boot/config.txt"
+FILE=/etc/systemd/system/transmit.service
+if [ -f "$FILE" ]; then
+ if [[ $(diff /home/pi/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service) ]]; then
+ echo "changed transmit.service."
+ sudo cp /home/pi/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service
+ FLAG=1
else
- echo "adding dtoverlay=dwc2 to /boot/config.txt"
- sudo sh -c 'echo "\ndtoverlay=dwc2" >> /boot/config.txt'
+ echo "no change to transmit.service."
fi
+else
+ echo "creating transmit.service."
+ sudo cp /home/pi/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service
+ FLAG=1
+fi
- if [[ $(grep 'modules-load=dwc2,g_ether' /boot/cmdline.txt) ]]; then
- echo "modules-load=dwc2,g_ether already in /boot/cmdline.txt"
- else
- echo "adding modules-load=dwc2,g_ether to /boot/cmdline.txt"
- sudo sed -i 's/ rootwait/ rootwait modules-load=dwc2,g_ether/g' /boot/cmdline.txt
- fi
-
- if [[ $(grep 'dtparam=audio=on' /boot/config.txt) ]]; then
- echo "dtparam=audio=on already in /boot/config.txt"
+FILE=/etc/systemd/system/command.service
+if [ -f "$FILE" ]; then
+ if [[ $(diff /home/pi/CubeSatSim/systemd/command.service /etc/systemd/system/command.service) ]]; then
+ echo "changed command.service."
+ sudo cp /home/pi/CubeSatSim/systemd/command.service /etc/systemd/system/command.service
+ FLAG=1
else
- echo "adding dtparam=audio=on to /boot/config.txt"
- sudo sh -c 'echo "\ndtparam=audio=on" >> /boot/config.txt'
+ echo "no change to command.service."
fi
+else
+ echo "creating command.service."
+ sudo cp /home/pi/CubeSatSim/systemd/command.service /etc/systemd/system/command.service
+ sudo systemctl enable command
+ FLAG=1
+fi
- if [[ $(grep 'dtoverlay=audremap,enable_jack=on' /boot/config.txt) ]]; then
- echo "dtoverlay=audremap,enable_jack=on already in /boot/config.txt"
+FILE=/etc/systemd/system/pacsatsim.service
+if [ -f "$FILE" ]; then
+ if [[ $(diff /home/pi/CubeSatSim/systemd/pacsatsim.service /etc/systemd/system/pacsatsim.service) ]]; then
+ echo "changed pacsatsim.service."
+ sudo cp /home/pi/CubeSatSim/systemd/pacsatsim.service /etc/systemd/system/pacsatsim.service
+ FLAG=1
else
- echo "adding dtoverlay=audremap,enable_jack=on to /boot/config.txt"
- sudo sh -c 'echo "\ndtoverlay=audremap,enable_jack=on" >> /boot/config.txt'
+ echo "no change to pacsatsim.service."
fi
+else
+ echo "creating pacsatsim.service."
+ sudo cp /home/pi/CubeSatSim/systemd/pacsatsim.service /etc/systemd/system/pacsatsim.service
+ FLAG=1
+fi
- if [[ $(grep 'dtoverlay=pwm,pin=18,func=2' /boot/config.txt) ]]; then
- echo "dtoverlay=pwm,pin=18,func=2 already in /boot/config.txt"
+FILE=/etc/asound.conf
+if [ -f "$FILE" ]; then
+ if [[ $(diff /home/pi/CubeSatSim/asound.conf /etc/asound.conf) ]]; then
+ echo "changed /etc/asound.conf."
+ sudo cp /home/pi/CubeSatSim/asound.conf /etc/asound.conf
+ FLAG=1
else
- echo "adding to /boot/config.txt"
- sudo sh -c 'echo "\ndtoverlay=pwm,pin=18,func=2" >> /boot/config.txt'
+ echo "no change to /etc/asound.conf."
fi
+else
+ echo "creating /etc/asound.conf."
+ sudo cp /home/pi/CubeSatSim/asound.conf /etc/asound.conf
+ FLAG=1
+fi
- if [[ $(grep 'disable_splash=1 ' /boot/config.txt) ]]; then
- echo "disable_splash=1 already in /boot/config.txt"
- else
- echo "adding to /boot/config.txt"
- sudo sh -c 'echo "\ndisable_splash=1" >> /boot/config.txt'
- fi
+FILE=/home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg
+if [ ! -f "$FILE" ]; then
+ echo "Copying SSTV image 1."
+ cp /home/pi/CubeSatSim/sstv/sstv_image_1_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg
+fi
+
+FILE=/home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg
+if [ ! -f "$FILE" ]; then
+ echo "Copying SSTV image 2."
+ cp /home/pi/CubeSatSim/sstv/sstv_image_2_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg
+fi
- if [[ $(grep 'boot_delay=0' /boot/config.txt) ]]; then
- echo "boot_delay=0 already in /boot/config.txt"
- else
- echo "adding to /boot/config.txt"
- sudo sh -c 'echo "\nboot_delay=0" >> /boot/config.txt'
- fi
+sudo sed -i 's/DEVICES=""/DEVICES="\/dev\/serial0"/g' /etc/default/gpsd
+
+sudo sed -i 's/GPSD_OPTIONS=""/GPSD_OPTIONS="-s 9600"/g' /etc/default/gpsd
+
+if [ ! -d "/home/pi/fctelem" ]; then
+ echo "Installing fctelem binary v0.2 for FUNcube mode"
+ cd
+ mkdir /home/pi/fctelem
+ mkdir /home/pi/fctelem/public_html
+ cd fctelem
+ wget https://github.com/alanbjohnston/go/releases/download/v0.2/fctelem.zip
+ unzip -u fctelem.zip
+ FLAG=1
+elif [ ! -f "/home/pi/fctelem/v0.2" ]; then
+ echo "Updating fctelem binary to version v0.2 for FUNcube mode"
+ cd
+ cd /home/pi/fctelem
+ sudo mv fctelem fctelem.bk
+ sudo mv fcdecode.conf fcdecode.conf.bk
+ sudo mv fctelem.zip fctelem.zip.1
+ wget https://github.com/alanbjohnston/go/releases/download/v0.2/fctelem.zip
+ unzip -u fctelem.zip
+ FLAG=1
+fi
- if ! grep -q force_turbo=1 /boot/config.txt ; then sudo sh -c 'echo "force_turbo=1" >> /boot/config.txt'; fi
-
-sudo sh -c 'echo "\n" >> /boot/config.txt'
-
-changed=0
-value=`cat /home/pi/CubeSatSim/sim.cfg`
-echo "$value" > /dev/null
-set -- $value
-
-if [ -z "$1" ] ; then n1="AMSAT" ; changed=1 ; else n1=$1 ; fi # callsign
-if [ -z "$2" ] ; then n2="0" ; changed=1 ; else n2=$2 ; fi # reset count
-if [ -z "$3" ] ; then n3="0" ; changed=1 ; else n3=$3 ; fi # lat
-if [ -z "$4" ] ; then n4="0" ; changed=1 ; else n4=$4 ; fi # lon
-if [ -z "$5" ] ; then n5="no" ; changed=1 ; else n5=$5 ; fi # sim mode
-if [ -z "$6" ] ; then n6="3" ; changed=1 ; else n6=$6 ; fi # squelch
-if [ -z "$7" ] ; then n7="434.9000" ; changed=1 ; else n7=$7 ; fi # transmit frequency
-if [ -z "$8" ] ; then n8="435.0000" ; changed=1 ; else n8=$8 ; fi # receive frequency
-if [ -z "$9" ] ; then n9="no" ; changed=1 ; else n9=$9 ; fi # hab mode
-if [ -z "${10}" ] ; then n10="0" ; changed=1 ; else n10=${10} ; fi # rx pl code
-if [ -z "${11}" ] ; then n11="0" ; changed=1 ; else n11=${11} ; fi # tx pl code
-
-if [ $changed -eq 1 ]; then
- echo -e "Current sim.cfg configuration file:"
- echo
- echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
- echo -e "\nCubeSatSim configuraation sim.cfg file updated to: \n"
- echo
- echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $n10 $n11
- echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $n10 $n11 > /home/pi/CubeSatSim/sim.cfg
- echo
+if [ ! -f "/home/pi/MPU6050-C-CPP-Library-for-Raspberry-Pi/mpu6050" ]; then
+ echo "Installing MPU6050-C-CPP-Library-for-Raspberry-Pi"
+ sudo apt-get install -y libi2c-dev
+ cd
+ git clone https://github.com/alanbjohnston/MPU6050-C-CPP-Library-for-Raspberry-Pi.git
+ cd MPU6050-C-CPP-Library-for-Raspberry-Pi
+ sudo make install
+ make payload
fi
-echo "Would you like to reboot to complete the installation (y/n)?"
+cd /home/pi/MPU6050-C-CPP-Library-for-Raspberry-Pi
+git checkout master
+git pull --no-rebase > .updated_p
-read -r ANS
+if [[ $(grep 'changed' /home/pi/MPU6050-C-CPP-Library-for-Raspberry-Pi/.updated_p) ]]; then
+ echo "updating MPU6050-C-CPP-Library-for-Raspberry-Pi"
+ sudo make install
+ make payload
+else
+ echo "nothing to do for MPU6050-C-CPP-Library-for-Raspberry-Pi."
+fi
+
+if [ ! -f "/home/pi/raspberry-pi-bme280/bme280" ]; then
+ echo "Installing raspberry-pi-bme280"
+ sudo apt-get install -y libi2c-dev
+ cd
+ git clone https://github.com/alanbjohnston/raspberry-pi-bme280.git
+ cd raspberry-pi-bme280
+ git checkout payload
+ make
+fi
-if [ "$ANS" = "y" ]; then
+cd /home/pi/raspberry-pi-bme280
+git checkout payload
+git pull --no-rebase > .updated_p
- sudo reboot now
+if [[ $(grep 'changed' /home/pi/raspberry-pi-bme280/.updated_p) ]]; then
+
+ echo "updating raspberry-pi-bme280"
+ make
else
+ echo "nothing to do for raspberry-pi-bme280."
+fi
+
+if [ ! -f "/home/pi/fcdctl/fcdctl" ]; then
+ echo "Installing fcdctl to set FUNcubeDongle Pro gain"
+ sudo rm /var/lib/dpkg/info/python3-pip.list
+ sudo apt install python3-pip --reinstall
+ sudo apt-get install -y python3-smbus libusb-1.0
+ cd
+ git clone https://github.com/csete/fcdctl.git
+ cd fcdctl
+ make fcdpp
+fi
+
+if [ ! -f "/home/pi/ssdv/ssdv" ]; then
+ cd
+ echo "Installing SSDV for FUNcube mode"
+ git clone https://github.com/alanbjohnston/ssdv.git # install ssdv for FUNcube images
+ cd ssdv
+ make
+fi
+
+cd
- echo "The CubeSatSim software will start next time you reboot"
+#echo "Would you like to reboot to complete the installation (y/n)?"
+
+#read -r ANS
+
+#if [ "$ANS" = "y" ]; then
+
+# sudo reboot now
+
+#else
+
+ # echo "The CubeSatSim software will start next time you reboot"
+#fi
+
+sed -i 's/quick_exec=0/quick_exec=1/' ~/.config/libfm/libfm.conf
+
+sudo apt install -y raspberrypi-ui-mods
+
+sudo apt autoremove -y
+
+if [ "$noreboot" = "0" ] ; then
+
+ if [ $FLAG -eq 1 ]; then # Not sure if this is needed
+ echo "systemctl daemon-reload and reboot"
+ sudo systemctl daemon-reload
+ sudo reboot -h now
+# sudo cubesatsim
+ else
+ grep 'changed' /home/pi/CubeSatSim/.updated
+ if [[ $(grep 'changed' /home/pi/CubeSatSim/.updated) ]]; then
+ echo "reboot due to code changes " | wall
+ sudo reboot -h now
+# sudo cubesatsim
+ else
+ echo "nothing to do."
+ fi
+ fi
+else
+ if [ $FLAG -eq 1 ]; then
+ echo "reboot needed for changes to take effect" | wall
+ fi
fi
diff --git a/log b/log
index 2a3ce9d7..a516a3c0 100755
--- a/log
+++ b/log
@@ -2,16 +2,65 @@
echo -e "\nLog file script for CubeSatSim\n"
-if [ "$1" = "-r" ] || [ "$1" = "-t" ] ; then
- sudo journalctl -a -u transmit > /home/pi/CubeSatSim/logt.txt
- cat /home/pi/CubeSatSim/logt.txt
- echo -e "\nTransmit Log file also saved as /home/pi/CubeSatSim/logt.txt"
-elif [ "$1" = "-c" ]; then
- sudo journalctl -a -u command > /home/pi/CubeSatSim/logc.txt
- cat /home/pi/CubeSatSim/logc.txt
- echo -e "\nCommand and Control Log file also saved as /home/pi/CubeSatSim/logc.txt"
+if [ "$1" = "-h" ] ; then
+ echo "Displays systemd logs for the chose process. The choices are:"
+ echo " -d cubesatsim (also no choice gives you this)"
+ echo " -t transmit"
+ echo " -c command and control"
+ echo " -p pacsat"
+ echo "Default is the log is dumpted to the screen and written to a file."
+ echo "If an additional r is included, the log is realtime, and exits with a Control-C"
+ echo
+ exit
+fi
+
+REALTIME=0
+if [ "$2" = "r" ] ; then
+ REALTIME=1
+fi
+
+if [ "$REALTIME" = "1" ] ; then
+
+ echo "To exit, type Control-C"
+ echo
+ sleep 2
+
+ if [ "$1" = "-r" ] || [ "$1" = "-t" ] ; then
+ sudo journalctl -af -u transmit # > /home/pi/CubeSatSim/logt.txt
+ # cat /home/pi/CubeSatSim/logt.txt
+ # echo -e "\nTransmit Log file also saved as /home/pi/CubeSatSim/logt.txt"
+ elif [ "$1" = "-c" ]; then
+ sudo journalctl -af -u command # > /home/pi/CubeSatSim/logc.txt
+ cat /home/pi/CubeSatSim/logc.txt
+ # echo -e "\nCommand and Control Log file also saved as /home/pi/CubeSatSim/logc.txt"
+ elif [ "$1" = "-p" ]; then
+ sudo journalctl -af -u pacsatsim # > /home/pi/CubeSatSim/logp.txt
+ cat /home/pi/CubeSatSim/logp.txt
+ # echo -e "\nCommand and Control Log file also saved as /home/pi/CubeSatSim/logp.txt"
+ else
+ sudo journalctl -af -u cubesatsim # > /home/pi/CubeSatSim/log.txt
+ # cat /home/pi/CubeSatSim/log.txt
+ # echo -e "\nLog file also saved as /home/pi/CubeSatSim/log.txt"
+ fi
+
else
- sudo journalctl -a -u cubesatsim > /home/pi/CubeSatSim/log.txt
- cat /home/pi/CubeSatSim/log.txt
- echo -e "\nLog file also saved as /home/pi/CubeSatSim/log.txt"
+
+ if [ "$1" = "-r" ] || [ "$1" = "-t" ] ; then
+ sudo journalctl -a -u transmit > /home/pi/CubeSatSim/logt.txt
+ cat /home/pi/CubeSatSim/logt.txt
+ echo -e "\nTransmit Log file also saved as /home/pi/CubeSatSim/logt.txt"
+ elif [ "$1" = "-c" ]; then
+ sudo journalctl -a -u command > /home/pi/CubeSatSim/logc.txt
+ cat /home/pi/CubeSatSim/logc.txt
+ echo -e "\nCommand and Control Log file also saved as /home/pi/CubeSatSim/logc.txt"
+ elif [ "$1" = "-p" ]; then
+ sudo journalctl -a -u pacsatsim > /home/pi/CubeSatSim/logp.txt
+ cat /home/pi/CubeSatSim/logp.txt
+ echo -e "\nCommand and Control Log file also saved as /home/pi/CubeSatSim/logp.txt"
+ else
+ sudo journalctl -a -u cubesatsim > /home/pi/CubeSatSim/log.txt
+ cat /home/pi/CubeSatSim/log.txt
+ echo -e "\nLog file also saved as /home/pi/CubeSatSim/log.txt"
+ fi
+
fi
diff --git a/main.c b/main.c
index ff1d3654..3152e021 100644
--- a/main.c
+++ b/main.c
@@ -25,10 +25,11 @@
int main(int argc, char * argv[]) {
- printf("\n\nCubeSatSim v2.1 starting...\n\n");
+ printf("\n\nCubeSatSim v2.2 starting...\n\n");
wiringPiSetup();
-
+
+ strcpy(fail_yes, "no");
// Open configuration file with callsign and reset count
FILE * config_file = fopen("/home/pi/CubeSatSim/sim.cfg", "r");
if (config_file == NULL) {
@@ -41,11 +42,11 @@ int main(int argc, char * argv[]) {
// char * cfg_buf[100];
- fscanf(config_file, "%s %d %f %f %s %d %s %s %s %d %d",
- call, & reset_count, & lat_file, & long_file, sim_yes, & squelch, tx, rx, hab_yes, & rx_pl, & tx_pl);
+ fscanf(config_file, "%s %d %f %f %s %d %s %s %s %d %d %s %d",
+ call, &reset_count, &lat_file, &long_file, sim_yes, &squelch, tx, rx, hab_yes, &rx_pl, &tx_pl, fail_yes, &fail_time);
fclose(config_file);
- fprintf(stderr,"Config file /home/pi/CubeSatSim/sim.cfg contains %s %d %f %f %s %d %s %s %s %d %d\n",
- call, reset_count, lat_file, long_file, sim_yes, squelch, tx, rx, hab_yes, rx_pl, tx_pl);
+ fprintf(stderr,"Config file /home/pi/CubeSatSim/sim.cfg contains %s %d %f %f %s %d %s %s %s %d %d %s %d\n",
+ call, reset_count, lat_file, long_file, sim_yes, squelch, tx, rx, hab_yes, rx_pl, tx_pl, fail_yes, fail_time);
fprintf(stderr, "Transmit on %s MHz Receive on %s MHz\n", tx, rx);
@@ -79,13 +80,19 @@ int main(int argc, char * argv[]) {
if (strcmp(sim_yes, "yes") == 0) {
sim_mode = TRUE;
- fprintf(stderr, "Sim mode is turned ON by configuration\n");
+ fprintf(stderr, "Sim Mode is turned ON by configuration\n");
sim_config = TRUE;
}
if (strcmp(hab_yes, "yes") == 0) {
hab_mode = TRUE;
fprintf(stderr, "HAB mode is ON\n");
}
+ if (strcmp(fail_yes, "yes") == 0) {
+ fail_rnd_mode = TRUE;
+ fprintf(stderr, "Random fail mode is ON\n");
+ failTime = 0;
+ srand((unsigned int)time(0));
+ }
FILE * command_file = fopen("/home/pi/CubeSatSim/command_control", "r");
if (command_file == NULL) {
@@ -102,6 +109,25 @@ int main(int argc, char * argv[]) {
}
}
printf("c2cStatus: %d \n", c2cStatus);
+
+ printf("Test bus 1\n");
+ fflush(stdout);
+ i2c_bus1 = (test_i2c_bus(1) != -1) ? 1 : OFF;
+ printf("Test bus 3\n");
+ fflush(stdout);
+ i2c_bus3 = (test_i2c_bus(3) != -1) ? 3 : OFF;
+ printf("Finished testing\n");
+ fflush(stdout);
+
+ if (i2c_bus3 == OFF) {
+ printf("Sim Mode turned on automatically\n");
+ sim_mode = TRUE;
+ FILE * sim_mode_auto = popen("touch /home/pi/CubeSatSim/sim_mode_auto", "r"); // store sim_mode_auto flag
+ pclose(sim_mode_auto);
+ } else {
+ FILE * sim_mode_auto = popen("sudo rm /home/pi/CubeSatSim/sim_mode_auto", "r"); // remove sim_mode_auto flag
+ pclose(sim_mode_auto);
+ }
char resbuffer[1000];
// const char testStr[] = "cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}' | sed 's/^1000//' | grep '9000'";
@@ -129,12 +155,12 @@ int main(int argc, char * argv[]) {
else
fprintf(stderr, "Not a Pi Zero or Pi Zero 2\n");
- pi_zero_2_offset = 500;
- if (uptime_sec < 30.0) {
- FILE * transmit_stop = popen("sudo systemctl start transmit", "r");
- pclose(transmit_stop);
+ pi_zero_2_offset = 500;
+ if (uptime_sec < 30.0) {
+ FILE * transmit_stop = popen("sudo systemctl start transmit", "r");
+ pclose(transmit_stop);
fprintf(stderr, "Sleep 5 sec\n");
- sleep(5); // try sleep at start to help boot
+ sleep(5); // try sleep at start to help boot
}
}
else {
@@ -161,15 +187,6 @@ int main(int argc, char * argv[]) {
// FILE * file_deletes = popen("sudo rm /home/pi/CubeSatSim/ready /home/pi/CubeSatSim/cwready > /dev/null", "r");
// pclose(file_deletes);
-
- printf("Test bus 1\n");
- fflush(stdout);
- i2c_bus1 = (test_i2c_bus(1) != -1) ? 1 : OFF;
- printf("Test bus 3\n");
- fflush(stdout);
- i2c_bus3 = (test_i2c_bus(3) != -1) ? 3 : OFF;
- printf("Finished testing\n");
- fflush(stdout);
// sleep(2);
@@ -244,13 +261,28 @@ int main(int argc, char * argv[]) {
printf("Mode is Repeater\n");
} else if ( mode_string == 'n') {
mode = TXCOMMAND;
- printf("Mode is Transmit Command\n");
- } else {
+ printf("Mode is Transmit Command\n");
+ } else if ( mode_string == 'p') {
+ mode = PACSAT;
+ printf("Mode is Pacsat\n");
+ } else if ( mode_string == 'P') {
+ mode = PACSATGND;
+ printf("Mode is Pacsat Ground Station\n");
+ } else {
printf("Mode is BPSK\n");
}
}
}
-
+/*
+ if ( mode == PACSAT) {
+ FILE * pacsat_file = popen("sudo systemctl restart pacsatsim", "r");
+ pclose(pacsat_file);
+ }
+ else {
+ FILE * pacsat_file = popen("sudo systemctl stop pacsatsim", "r");
+ pclose(pacsat_file);
+ }
+*/
// Open telemetry file with STEM Payload Data
telem_file = fopen("/home/pi/CubeSatSim/telem.txt", "a");
if (telem_file == NULL)
@@ -272,47 +304,10 @@ int main(int argc, char * argv[]) {
/**/
fflush(stderr);
-
- if (mode == AFSK)
- {
- // Check for SPI and AX-5043 Digital Transceiver Board
- FILE * file = popen("sudo raspi-config nonint get_spi", "r");
-// printf("getc: %c \n", fgetc(file));
- if (fgetc(file) == 48) {
- printf("SPI is enabled!\n");
-
- FILE * file2 = popen("ls /dev/spidev0.* 2>&1", "r");
- printf("Result getc: %c \n", getc(file2));
-
- if (fgetc(file2) != 'l') {
- printf("SPI devices present!\n");
- // }
-
- setSpiChannel(SPI_CHANNEL);
- setSpiSpeed(SPI_SPEED);
- initializeSpi();
- ax25_init( & hax25, (uint8_t * ) dest_addr, 11, (uint8_t * ) call, 11, AX25_PREAMBLE_LEN, AX25_POSTAMBLE_LEN);
- if (init_rf()) {
- printf("AX5043 successfully initialized!\n");
- ax5043 = TRUE;
- cw_id = OFF;
-// mode = AFSK;
- // cycle = OFF;
- printf("Mode AFSK with AX5043\n");
- transmit = TRUE;
-// sleep(10); // just in case CW ID is sent
- } else
- printf("AX5043 not present!\n");
- pclose(file2);
- }
- }
- pclose(file);
- }
-
+
txLed = 2;
txLedOn = HIGH;
txLedOff = LOW;
- vB5 = TRUE;
onLed = 27;
onLedOn = HIGH;
onLedOff = LOW;
@@ -326,44 +321,54 @@ int main(int argc, char * argv[]) {
}
config_file = fopen("sim.cfg", "w");
- fprintf(config_file, "%s %d %8.4f %8.4f %s %d %s %s %s %d %d", call, reset_count, lat_file, long_file, sim_yes, squelch, tx, rx, hab_yes, rx_pl, tx_pl);
+ fprintf(config_file, "%s %d %8.4f %8.4f %s %d %s %s %s %d %d %s %d",
+ call, reset_count, lat_file, long_file, sim_yes, squelch, tx, rx, hab_yes, rx_pl, tx_pl, fail_yes, fail_time);
// fprintf(config_file, "%s %d", call, reset_count);
fclose(config_file);
config_file = fopen("sim.cfg", "r");
- if (vB4) {
- map[BAT] = BAT2;
- map[BAT2] = BAT;
- snprintf(busStr, 10, "%d %d", i2c_bus1, test_i2c_bus(0));
- } else if (vB5) {
- map[MINUS_X] = MINUS_Y;
- map[PLUS_Z] = MINUS_X;
- map[MINUS_Y] = PLUS_Z;
-
- if (access("/dev/i2c-11", W_OK | R_OK) >= 0) { // Test if I2C Bus 11 is present
+ map[MINUS_X] = MINUS_Y;
+ map[PLUS_Z] = MINUS_X;
+ map[MINUS_Y] = PLUS_Z;
+/*
+ if (access("/dev/i2c-11", W_OK | R_OK) >= 0) { // Test if I2C Bus 11 is present
printf("/dev/i2c-11 is present\n\n");
snprintf(busStr, 10, "%d %d", test_i2c_bus(1), test_i2c_bus(11));
- } else {
- snprintf(busStr, 10, "%d %d", i2c_bus1, i2c_bus3);
- }
} else {
- map[BAT2] = MINUS_Z;
- map[BAT] = BAT2;
- map[PLUS_Z] = BAT;
- map[MINUS_Z] = PLUS_Z;
- snprintf(busStr, 10, "%d %d", i2c_bus1, test_i2c_bus(0));
- voltageThreshold = 8.0;
+ snprintf(busStr, 10, "%d %d", i2c_bus1, i2c_bus3);
}
-
- // check for camera
-// char cmdbuffer1[1000];
- FILE * file4 = popen("vcgencmd get_camera", "r");
- fgets(cmdbuffer, 1000, file4);
- char camera_present[] = "supported=1 detected=1";
+*/
+ snprintf(busStr, 10, "%d %d", i2c_bus1, i2c_bus3);
+
+ FILE * os_test = popen("cat /etc/os-release", "r");
+ fgets(cmdbuffer, 1000, os_test);
+ printf("os-release: %s\n", cmdbuffer);
+ char os_present[] = "bookworm";
// printf("strstr: %s \n", strstr( & cmdbuffer1, camera_present));
- camera = (strstr( (const char *)& cmdbuffer, camera_present) != NULL) ? ON : OFF;
- printf("Camera result:%s camera: %d \n", & cmdbuffer, camera);
- pclose(file4);
+ int os_status = (strstr( (const char *)& cmdbuffer, os_present) != NULL) ? ON : OFF;
+ printf("os_status: %d\n", os_status);
+ pclose(os_test);
+
+ // check for camera
+ FILE *cam_test;
+ if (os_status == ON) { // bookworm
+ cam_test = popen("sudo rpicam-hello --list-cameras | grep 'No cameras available!'", "r");
+ fgets(cmdbuffer, 1000, cam_test);
+ char no_camera_present[] = "No cameras available!";
+ // printf("strstr: %s \n", strstr( & cmdbuffer1, camera_present));
+ camera = (strstr( (const char *)& cmdbuffer, no_camera_present) != NULL) ? OFF : ON;
+ }
+ else // bullseye
+ {
+ cam_test = popen("vcgencmd get_camera", "r");
+ fgets(cmdbuffer, 1000, cam_test);
+ char camera_present[] = "supported=1 detected=1";
+ // printf("strstr: %s \n", strstr( & cmdbuffer1, camera_present));
+ camera = (strstr( (const char *)& cmdbuffer, camera_present) != NULL) ? ON : OFF;
+ }
+
+ printf("Camera result: %s camera: %d \n", & cmdbuffer, camera);
+ pclose(cam_test);
#ifdef DEBUG_LOGGING
printf("INFO: I2C bus status 0: %d 1: %d 3: %d camera: %d\n", i2c_bus0, i2c_bus1, i2c_bus3, camera);
@@ -373,52 +378,91 @@ int main(int argc, char * argv[]) {
//file5 = popen("sudo rm /home/pi/CubeSatSim/camera_out.jpg.wav > /dev/null 2>&1", "r");
pclose(file5);
- if (!ax5043) // don't test for payload if AX5043 is present
- {
+ cmdbuffer[0] = '\0';
+ gps_status = OFF;
+ FILE *gps_read = NULL;
+ if ((mode == AFSK) || (mode == CW) || (mode == SSTV))
+ {
+ gps_read = sopen("python3 /home/pi/CubeSatSim/gps_client.py"); // python sensor polling function
+
+ if (gps_read != NULL) {
+ fgets(cmdbuffer, 1000, gps_read);
+ fprintf(stderr, "gps read: %s\n", cmdbuffer);
+ if ((cmdbuffer[0] == '-') && (cmdbuffer[1] == '1'))
+ {
+ gps_status = OFF;
+ fprintf(stderr, "Pi GPS off\n");
+ } else if ((cmdbuffer[0] == '1') || (cmdbuffer[0] == '2') || (cmdbuffer[0] == '3')) {
+ gps_status = ON;
+ fprintf(stderr, "Pi GPS on\n");
+ }
+ fclose(gps_read);
+ } else
+ fprintf(stderr, "Error checking gps");
+ }
+
payload = OFF;
- fprintf(stderr,"Opening serial\n");
- if ((uart_fd = serialOpen("/dev/ttyAMA0", 115200)) >= 0) { // was 9600
- fprintf(stderr,"Serial opened to Pico\n");
-// payload = ON;
- payload = get_payload_serial(FALSE);
- fprintf(stderr,"Get_payload_status: %d \n", payload); // not debug
-
- } else {
- fprintf(stderr, "Unable to open UART: %s\n -> Did you configure /boot/config.txt and /boot/cmdline.txt?\n", strerror(errno));
- }
- }
- if ((i2c_bus3 == OFF) || (sim_mode == TRUE)) {
+ if (gps_status == OFF)
+ {
+ fprintf(stderr,"Opening serial\n");
+ if ((uart_fd = serialOpen("/dev/ttyAMA0", 115200)) >= 0) { // was 9600
+ fprintf(stderr,"Serial opened to Pico\n");
+ // payload = ON;
+ payload = get_payload_serial(FALSE);
+ fprintf(stderr,"Get_payload_status: %d \n", payload); // not debug
+
+ if (sim_mode && payload && !sim_config) {
+ sim_mode = FALSE;
+ printf("Turning off Sim Mode since payload is present and Sim Mode not manually configured.\n");
+ FILE * sim_mode_auto = popen("sudo rm /home/pi/CubeSatSim/sim_mode_auto", "r"); // remove sim_mode_auto flag
+ pclose(sim_mode_auto);
+ }
+ } else {
+ fprintf(stderr, "Unable to open UART: %s\n -> Did you configure /boot/config.txt and /boot/cmdline.txt?\n", strerror(errno));
+ }
+ }
+ else
+ {
+ payload = FALSE;
+ printf("get_payload_status not run since gps_status is ON\n");
+ }
+
+ sensor_setup();
- sim_mode = TRUE;
-
- fprintf(stderr, "Simulated telemetry mode!\n");
+ if (sim_mode == TRUE) {
+
+ fprintf(stderr, "Sim Mode is active\n");
srand((unsigned int)time(0));
- axis[0] = rnd_float(-0.2, 0.2);
- if (axis[0] == 0)
- axis[0] = rnd_float(-0.2, 0.2);
- axis[1] = rnd_float(-0.2, 0.2);
- axis[2] = (rnd_float(-0.2, 0.2) > 0) ? 1.0 : -1.0;
+ axis[X] = rnd_float(-0.2, 0.2);
+ if (axis[X] == 0)
+ axis[X] = rnd_float(-0.2, 0.2);
+ axis[Y] = rnd_float(-0.2, 0.2);
+ float axis_z;
+ axis_z = sqrt(1 - axis[X] * axis[X] - axis[Y] * axis[Y]);
+ axis[Z] = (rnd_float(-0.2, 0.2) > 0) ? axis_z : -1.0 * axis_z;
- angle[0] = (float) atan(axis[1] / axis[2]);
- angle[1] = (float) atan(axis[2] / axis[0]);
- angle[2] = (float) atan(axis[1] / axis[0]);
+ angle[X] = (float) atan(axis[Y] / axis[Z]);
+ angle[Y] = (float) atan(axis[Z] / axis[X]);
+ angle[Z] = (float) atan(axis[Y] / axis[X]);
- volts_max[0] = rnd_float(4.5, 5.5) * (float) sin(angle[1]);
- volts_max[1] = rnd_float(4.5, 5.5) * (float) cos(angle[0]);
- volts_max[2] = rnd_float(4.5, 5.5) * (float) cos(angle[1] - angle[0]);
+ volts_max[X] = rnd_float(9.0, 12.0) * (float) sin(angle[Y]);
+ volts_max[Y] = rnd_float(9.0, 12.0) * (float) cos(angle[X]);
+ volts_max[Z] = rnd_float(9.0, 12.0) * (float) cos(angle[Y] - angle[X]);
- float amps_avg = rnd_float(150, 300);
+ float amps_avg = rnd_float(150, 750);
- amps_max[0] = (amps_avg + rnd_float(-25.0, 25.0)) * (float) sin(angle[1]);
- amps_max[1] = (amps_avg + rnd_float(-25.0, 25.0)) * (float) cos(angle[0]);
- amps_max[2] = (amps_avg + rnd_float(-25.0, 25.0)) * (float) cos(angle[1] - angle[0]);
+ amps_max[X] = (amps_avg + rnd_float(-25.0, 25.0)) * (float) sin(angle[Y]);
+ amps_max[Y] = (amps_avg + rnd_float(-25.0, 25.0)) * (float) cos(angle[X]);
+ amps_max[Z] = (amps_avg + rnd_float(-25.0, 25.0)) * (float) cos(angle[Y] - angle[X]);
- batt = rnd_float(3.8, 4.3);
+ batt = rnd_float(3.8, 4.1);
speed = rnd_float(1.0, 2.5);
eclipse = (rnd_float(-1, +4) > 0) ? 1.0 : 0.0;
+ atmosphere = (rnd_float(-1, +1) > 0) ? 0.0 : 1.0;
+
// eclipse = 1;
period = rnd_float(150, 300);
tempS = rnd_float(20, 55);
@@ -426,9 +470,10 @@ int main(int argc, char * argv[]) {
temp_min = rnd_float(10, 20);
// #ifdef DEBUG_LOGGING
- for (int i = 0; i < 3; i++)
+ for (int i = X; i <= Z; i++)
printf("axis: %f angle: %f v: %f i: %f \n", axis[i], angle[i], volts_max[i], amps_max[i]);
- printf("batt: %f speed: %f eclipse_time: %f eclipse: %f period: %f temp: %f max: %f min: %f\n", batt, speed, eclipse_time, eclipse, period, tempS, temp_max, temp_min);
+ printf("batt: %f speed: %f eclipse_time: %f eclipse: %f period: %f temp: %f max: %f min: %f atmosphere: %f\n",
+ batt, speed, eclipse_time, eclipse, period, tempS, temp_max, temp_min, atmosphere);
// #endif
time_start = (long int) millis();
@@ -436,6 +481,14 @@ int main(int argc, char * argv[]) {
eclipse_time = (long int)(millis() / 1000.0);
if (eclipse == 0.0)
eclipse_time -= period / 2; // if starting in eclipse, shorten interval
+
+ tempP = rnd_float(80, 90); // simulated payload parameters
+ altSP = rnd_float(28000, 32000);
+ changeP = rnd_float(-10, 10);
+ presP = rnd_float(1014, 1016);
+ altGP = rnd_float(20,120);
+ humiP = rnd_float(40,60);
+
}
// tx_freq_hz -= tx_channel * 50000;
@@ -467,8 +520,9 @@ int main(int argc, char * argv[]) {
printf("\n FSK Mode, %d bits per frame, %d bits per second, %d ms per frame, %d ms sample period\n",
bufLen / (samples * frameCnt), bitRate, frameTime, samplePeriod);
-
- } else if (mode == BPSK) {
+ } else if ((mode == BPSK) || (mode == PACSAT) || (mode == PACSATGND)) {
+//// } else {
+
bitRate = 1200;
rsFrames = 3;
payloads = 6;
@@ -490,8 +544,11 @@ int main(int argc, char * argv[]) {
frameTime = ((float)((float)bufLen / (samples * frameCnt * bitRate))) * 1000; // frame time in ms
- printf("\n BPSK Mode, bufLen: %d, %d bits per frame, %d bits per second, %d ms per frame %d ms sample period\n",
- bufLen, bufLen / (samples * frameCnt), bitRate, frameTime, samplePeriod);
+ if (mode == BPSK)
+ printf("\n BPSK Mode, bufLen: %d, %d bits per frame, %d bits per second, %d ms per frame %d ms sample period\n",
+ bufLen, bufLen / (samples * frameCnt), bitRate, frameTime, samplePeriod);
+ else
+ printf("\n dataLen: %d \n", dataLen);
sin_samples = S_RATE/freq_Hz;
// printf("Sin map: ");
@@ -542,14 +599,17 @@ int main(int argc, char * argv[]) {
memset(voltage, 0, sizeof(voltage));
memset(current, 0, sizeof(current));
memset(sensor, 0, sizeof(sensor));
- memset(other, 0, sizeof(other));
+ memset(other, 0, sizeof(other));
- if (((mode == FSK) || (mode == BPSK))) // && !sim_mode)
+ if ((mode == FSK) || (mode == BPSK) || (mode == PACSAT) || (mode == PACSATGND)) // && !sim_mode)
get_tlm_fox(); // fill transmit buffer with reset count 0 packets that will be ignored
- else if (((mode == FC))) // && !sim_mode)
+ else if (mode == FC) // && !sim_mode)
get_tlm_fc(); // fill transmit buffer with reset count 0 packets that will be ignored
-
- firstTime = 1;
+ else if (mode == CW)
+ get_tlm(); // generate a frame of telemetry right away
+
+ if (firstTime == 0)
+ firstTime = 1;
// if (!sim_mode) // always read sensors, even in sim mode
{
@@ -559,11 +619,13 @@ int main(int argc, char * argv[]) {
strcat(pythonConfigStr, " c");
fprintf(stderr, "pythonConfigStr: %s\n", pythonConfigStr);
+
+ FILE *file2 = sopen(pythonVenv); // activate venv
file1 = sopen(pythonConfigStr); // python sensor polling function
fgets(cmdbuffer, 1000, file1);
- fprintf(stderr, "pythonStr result: %s\n", cmdbuffer);
+ fprintf(stderr, "pythonStr INA219 read result: %s\n", cmdbuffer);
}
for (int i = 0; i < 9; i++) {
@@ -573,13 +635,13 @@ int main(int argc, char * argv[]) {
current_max[i] = -1000.0;
}
for (int i = 0; i < SENSOR_FIELDS; i++) {
- sensor_min[i] = 1000.0;
- sensor_max[i] = -1000.0;
+ sensor_min[i] = 100000.0;
+ sensor_max[i] = -100000.0;
// printf("Sensor min and max initialized!");
}
for (int i = 0; i < 3; i++) {
- other_min[i] = 1000.0;
- other_max[i] = -1000.0;
+ other_min[i] = 100000.0;
+ other_max[i] = -100000.0;
}
loopTime = millis();
@@ -588,11 +650,13 @@ int main(int argc, char * argv[]) {
fflush(stdout);
fflush(stderr);
// frames_sent++;
+// if (!sim_mode) {
+ sensor_payload[0] = '\0';
+ memset(sensor, 0, sizeof(sensor));
+// }
- sensor_payload[0] = 0;
memset(voltage, 0, sizeof(voltage));
memset(current, 0, sizeof(current));
- memset(sensor, 0, sizeof(sensor));
memset(other, 0, sizeof(other));
FILE * uptime_file = fopen("/proc/uptime", "r");
@@ -605,12 +669,40 @@ int main(int argc, char * argv[]) {
// #endif
fclose(uptime_file);
+ if (fail_rnd_mode) {
+ if ((millis() - failTime) > fail_time * 1000) {
+ failureMode = rnd_float(1.0, 10.0);
+ printf("Simulated Random Failure Change to %d\n", failureMode);
+ FILE * failure_mode_file = fopen("/home/pi/CubeSatSim/failure_mode.txt", "w");
+ fprintf(failure_mode_file, "%d", failureMode);
+ fclose(failure_mode_file);
+ failTime = loopTime;
+ } else
+ printf("No random failure change. millis: %ld failTime: %ld fail_time: %d\n", millis(), failTime, fail_time);
+ }
+// else
+// {
+// failureMode = OFF;
+ FILE * failure_mode_file = fopen("/home/pi/CubeSatSim/failure_mode.txt", "r");
+ if (failure_mode_file != NULL) {
+ char failure_string[10];
+ if ( (fgets(failure_string, 10, failure_mode_file)) != NULL) {
+ failureMode = atoi(failure_string);
+ fclose(failure_mode_file);
+ printf("Failure mode: %d\n", failureMode);
+ }
+ } else {
+ failureMode = FAIL_NONE;
+ printf("No simulated failure.\n");
+ }
+// }
+
{
int count1;
char * token;
fputc('\n', file1);
fgets(cmdbuffer, 1000, file1);
-// fprintf(stderr, "Python read Result: %s\n", cmdbuffer);
+ fprintf(stderr, "Python INA219 read Result: %s\n", cmdbuffer);
// serialPuts(uart_fd, cmdbuffer); // write INA data to Pico over serial
@@ -635,39 +727,60 @@ int main(int argc, char * argv[]) {
}
}
if (voltage[map[BAT]] == 0.0) // No BAT Board
- if (voltage[map[BAT2]] == 0.0) // No BAT2 Board
- batteryVoltage = 4.5;
- else {
- batteryVoltage = voltage[map[BAT2]]; // only BAT2 Board present
+ if (voltage[map[BAT2]] == 0.0) // No BAT2 Board
+ batteryVoltage = 4.5;
+ else {
+ batteryVoltage = voltage[map[BAT2]]; // only BAT2 Board present
+ if (sim_mode && !sim_config) { // if Voltage sensor on Battery board is present, exit simulated telemetry mode
+ sim_mode = FALSE;
+ fprintf(stderr, "Turning off Sim Mode since battery sensor 2 is present\n");
+ FILE * sim_mode_auto = popen("sudo rm /home/pi/CubeSatSim/sim_mode_auto", "r"); // remove sim_mode_auto flag
+ pclose(sim_mode_auto);
+ }
+ }
+ else {
+ batteryVoltage = voltage[map[BAT]]; // BAT Board present
if (sim_mode && !sim_config) { // if Voltage sensor on Battery board is present, exit simulated telemetry mode
sim_mode = FALSE;
- fprintf(stderr, "Turning off sim_mode since battery sensor 2 is present\n");
+ fprintf(stderr, "Turning off Sim Mode since battery sensor is present\n");
+ FILE * sim_mode_auto = popen("sudo rm /home/pi/CubeSatSim/sim_mode_auto", "r"); // remove sim_mode_auto flag
+ pclose(sim_mode_auto);
}
}
- else {
- batteryVoltage = voltage[map[BAT]]; // BAT Board present
- if (sim_mode && !sim_config) { // if Voltage sensor on Battery board is present, exit simulated telemetry mode
- sim_mode = FALSE;
- fprintf(stderr, "Turning off sim_mode since battery sensor is present\n");
- }
- }
batteryCurrent = current[map[BAT]] + current[map[BAT2]]; // Sum BAT and BAT2 currents
-
}
+
+ if (gps_status == OFF)
+ {
+ payload = get_payload_serial(FALSE); // not debug
+ printf("get_payload_status: %d \n", payload);
+ }
+ else
+ {
+ payload = FALSE;
+ printf("get_payload_status not run since gps_status is ON\n");
+ }
+
+ if (payload == FALSE) {
+ payload = pi_sensors(buffer2);
+ printf("pi_sensors status: %d \n", payload);
+ }
-// if (payload == ON) { // moved to here
- if (!ax5043) {
-// if ((payload == ON) && (mode != BPSK)) { // moved to here
-// STEMBoardFailure = 0;
- payload = get_payload_serial(FALSE);
- printf("get_payload_status: %d \n", payload); // not debug
+ if (sim_mode && payload && !sim_config) {
+ sim_mode = FALSE;
+ printf("Turning off Sim Mode since payload is present and Sim Mode not manually configured.\n");
+ FILE * sim_mode_auto = popen("sudo rm /home/pi/CubeSatSim/sim_mode_auto", "r"); // remove sim_mode_auto flag
+ pclose(sim_mode_auto);
+ }
+
fflush(stdout);
// printf("String: %s\n", buffer2);
fflush(stdout);
- strcpy(sensor_payload, buffer2);
-// printf(" Response from STEM Payload board: %s\n", sensor_payload);
+ strcpy(sensor_payload, buffer2);
+
+ printf(" Response from STEM Payload: %s\n", sensor_payload);
- telem_file = fopen("/home/pi/CubeSatSim/telem.txt", "a");
+ telem_file = fopen("/home/pi/CubeSatSim/telem.txt", "a");
// printf("Writing payload string\n");
time_t timeStamp;
time(&timeStamp); // get timestamp
@@ -676,17 +789,30 @@ int main(int argc, char * argv[]) {
char timeStampNoNl[31], bat_string[31];
snprintf(timeStampNoNl, 30, "%.24s", ctime(&timeStamp));
// printf("TimeStamp: %s\n", timeStampNoNl);
-
+/*
if (c2cStatus == DISABLED)
snprintf(bat_string, 30, "BAT %4.2f %5.1f", batteryVoltage, batteryCurrent);
else
snprintf(bat_string, 30, "BAT %4.2f %5.1f C", batteryVoltage, batteryCurrent);
-
+ */
+ snprintf(bat_string, 30, "BAT %.2f %.1f", batteryVoltage, batteryCurrent);
+ if (c2cStatus != DISABLED)
+ strcat(bat_string," C");
+ if (sim_mode || (failureMode != FAIL_NONE))
+ strcat(bat_string," S");
fprintf(telem_file, "%s %s %s\n", timeStampNoNl, bat_string, sensor_payload); // write telemetry string to telem.txt file
fclose(telem_file);
-
+
+ if (failureMode == FAIL_PAYLOAD) {
+ sensor_payload[0] = '\0'; // This will cause the payload to not be processed.
+ printf("Simulated Payload Failure.\n");
+ }
+
+//// if (!sim_mode) {
+ {
if ((sensor_payload[0] == 'O') && (sensor_payload[1] == 'K')) // only process if valid payload response
{
+// printf("Valid Payload!\n");
int count1;
char * token;
@@ -696,14 +822,66 @@ int main(int argc, char * argv[]) {
for (count1 = 0; count1 < SENSOR_FIELDS; count1++) {
if (token != NULL) {
sensor[count1] = (float) atof(token);
+ strcpy(sensor_string[count1], token);
// #ifdef DEBUG_LOGGING
// printf("sensor: %f ", sensor[count1]); // print sensor data
+// printf("Sensor String %d is %s\n",count1, sensor_string[count1]);
// #endif
token = strtok(NULL, space);
}
}
- printf("\n");
+ if (gps_status == TRUE) {
+ fprintf(stderr, "Checking Pi gps\n");
+ cmdbuffer[0] = '\0';
+ gps_read = sopen("python3 /home/pi/CubeSatSim/gps_client.py"); // python sensor polling function
+
+ if (gps_read != NULL) {
+// fputc('\n', gps_read);
+ fgets(cmdbuffer, 1000, gps_read);
+
+// const char gpsTestStr[] = "2 32.3 -54 333\n";
+// strcpy(cmdbuffer, gpsTestStr);
+
+ fprintf(stderr, "gps read: %s\n", cmdbuffer);
+ if ((cmdbuffer[0] == '2') || (cmdbuffer[0] == '3'))
+ {
+ printf("Valid gps data!\n");
+// printf("%x %x \n", cmdbuffer[strlen(cmdbuffer) - 2], cmdbuffer[strlen(cmdbuffer) - 1] );
+ if (cmdbuffer[strlen(cmdbuffer) - 1] == '\n')
+ cmdbuffer[strlen(cmdbuffer) - 1] = '\0';
+// printf("%x %x \n", cmdbuffer[strlen(cmdbuffer) - 2], cmdbuffer[strlen(cmdbuffer) - 1] );
+
+ int count1;
+ char * token;
+
+ const char space[2] = " ";
+ token = strtok(cmdbuffer, space);
+ // printf("token: %s\n", token);
+ for (count1 = GPS; count1 < (GPS + 4); count1++) {
+ if (token != NULL) {
+ sensor[count1] = (float) atof(token);
+ strcpy(sensor_string[count1], token);
+ // #ifdef DEBUG_LOGGING
+// printf("sensor: %f ", sensor[count1]); // print sensor data
+// printf("Sensor String %d is %s\n",count1, sensor_string[count1]);
+ // #endif
+ token = strtok(NULL, space);
+ }
+ }
+// printf("\n");
+ strcpy(sensor_string[GPS], "GPS");
+
+ } else {
+ fprintf(stderr, "No Pi gps available\n");
+ }
+ fclose(gps_read);
+ } else
+ fprintf(stderr, "Error checking gps");
+
+ }
+
+ printf("\n");
// if (sensor[GPS1] != 0) {
if ((sensor[GPS1] > -90.0) && (sensor[GPS1] < 90.0) && (sensor[GPS1] != 0.0)) {
if (sensor[GPS1] != latitude) {
@@ -720,10 +898,11 @@ int main(int argc, char * argv[]) {
newGpsTime = millis();
}
}
- }
- else
- ; //payload = OFF; // turn off since STEM Payload is not responding
- }
+ }
+ }
+// else
+// ; //payload = OFF; // turn off since STEM Payload is not responding
+
if ((millis() - newGpsTime) > 60000) {
longitude += rnd_float(-0.05, 0.05) / 100.0; // was .05
latitude += rnd_float(-0.05, 0.05) / 100.0;
@@ -731,8 +910,130 @@ int main(int argc, char * argv[]) {
// printf("GPS Location with Rnd: APRS %07.2f, %08.2f \n", toAprsFormat(latitude), toAprsFormat(longitude));
newGpsTime = millis();
}
-
+
+// if (sim_mode && (failureMode != FAIL_PAYLOAD) && !payload) {
+ if (sim_mode && (failureMode != FAIL_PAYLOAD)) {
+ char str_tmp[10];
+ printf("Generating simulated payload telemetry\n");
+ if (atmosphere == 0) {
+ sensor[PRES] = 0;
+ strcpy(sensor_string[PRES], "0.0");
+ altSP += changeP;
+ sensor[ALT] = altSP;
+ sprintf(str_tmp, "%5.0f", altSP);
+ strcpy(sensor_string[ALT], str_tmp);
+ printf("Alt: %s\n", sensor_string[ALT]);
+ sensor[HUMI] = 0;
+ strcpy(sensor_string[HUMI], "0.0");
+ sensor[TEMP] = tempP - 80 * (1 - eclipse) + rnd_float(-0.7, 0.7);
+ sprintf(str_tmp, "%4.1f", sensor[TEMP]);
+ strcpy(sensor_string[TEMP], str_tmp);
+ printf("Temp: %s\n", sensor_string[TEMP]);
+ } else {
+ sensor[PRES] = presP + rnd_float(-1, 1);
+ sprintf(str_tmp, "%6.1f", presP);
+ strcpy(sensor_string[PRES], str_tmp);
+ printf("Pres: %s\n", sensor_string[PRES]);
+ sensor[ALT] = altGP;
+ sprintf(str_tmp, "%5.0f", altGP);
+ strcpy(sensor_string[ALT], str_tmp);
+ sensor[HUMI] = humiP + rnd_float(-1, 1);
+ sprintf(str_tmp, "%4.1f", sensor[HUMI]);
+ strcpy(sensor_string[HUMI], str_tmp);
+ sensor[TEMP] = tempS + rnd_float(-0.7, 0.7);
+ sprintf(str_tmp, "%4.1f",sensor[TEMP]);
+ strcpy(sensor_string[TEMP], str_tmp);
+ printf("Temp: %s\n", sensor_string[TEMP]);
+ }
+ char sensor_number[20];
+ sensor[ACCEL_X] = axis[X];
+ sprintf(sensor_number, "%.2f", axis[X]);
+ strcpy(sensor_string[ACCEL_X], sensor_number);
+ sensor[ACCEL_Y] = axis[Y];
+ sprintf(sensor_number, "%.2f", axis[Y]);
+ strcpy(sensor_string[ACCEL_Y], sensor_number);
+ sensor[ACCEL_Z] = axis[Z];
+ sprintf(sensor_number, "%.2f", axis[Z]);
+ strcpy(sensor_string[ACCEL_Z], sensor_number);
+
+ float spin;
+ spin = rnd_float(-30.0, 30.0);
+ sensor[GYRO_X] = axis[X] * spin;
+ sprintf(sensor_number, "%.2f", sensor[GYRO_X]);
+ strcpy(sensor_string[GYRO_X], sensor_number);
+ sensor[GYRO_Y] = axis[Y] * spin;
+ sprintf(sensor_number, "%.2f", sensor[GYRO_Y]);
+ strcpy(sensor_string[GYRO_Y], sensor_number);
+ sensor[GYRO_Z] = axis[Z] * spin;
+ sprintf(sensor_number, "%.2f", sensor[GYRO_Z]);
+ strcpy(sensor_string[GYRO_Z], sensor_number);
+
+ // printf("sim sensor: %s\n", sensor_string[GYRO_Z]);
+ printf("sim sensor spin: %f value: %f length: %d string: %s\n", spin, sensor[GYRO_Z], strlen(sensor_string[GYRO_Z]), sensor_string[GYRO_Z]);
+ }
+
+ if (failureMode == FAIL_BME) {
+ sensor[TEMP] = 0.0;
+ strcpy(sensor_string[TEMP], "0.0");
+ sensor[PRES] = 0.0;
+ strcpy(sensor_string[PRES], "0.0");
+ sensor[HUMI] = 0.0;
+ strcpy(sensor_string[HUMI], "0.0");
+ sensor[ALT] = 0.0;
+ strcpy(sensor_string[ALT], "0.0");
+ printf("Simulated BME Failure!\n");
+ }
+
+ if (failureMode == FAIL_MPU) {
+ sensor[ACCEL_X] = 0.0;
+ strcpy(sensor_string[ACCEL_X], "0.0");
+ sensor[ACCEL_Y] = 0.0;
+ strcpy(sensor_string[ACCEL_Y], "0.0");
+ sensor[ACCEL_Z] = 0.0;
+ strcpy(sensor_string[ACCEL_Z], "0.0");
+ sensor[GYRO_X] = 0.0;
+ strcpy(sensor_string[GYRO_X], "0.0");
+ sensor[GYRO_Y] = 0.0;
+ strcpy(sensor_string[GYRO_Y], "0.0");
+ sensor[GYRO_Z] = 0.0;
+ strcpy(sensor_string[GYRO_Z], "0.0");
+ printf("Simulated MPU Failure!\n");
+ }
+
+// if ((failureMode == FAIL_BME) || (failureMode == FAIL_MPU) || (sim_mode && (failureMode != FAIL_PAYLOAD))) // recreaate sensor_payload string
+ if (failureMode != FAIL_PAYLOAD)
+ {
+ sensor_payload[0] = '\0';
+ strcpy(sensor_string[0], "OK");
+ strcpy(sensor_string[1], "BME280");
+ strcpy(sensor_string[6], "MPU6050");
+
+ for (count1 = 0; count1 < SENSOR_FIELDS; count1++) {
+ strcat(sensor_payload, sensor_string[count1]);
+ strcat(sensor_payload, " ");
+ }
+ printf("Updated Sensor String: %s\n", sensor_payload);
+ }
+// else if (failureMode != FAIL_PAYLOAD) {
+// printf("Restoring sensor_payload\n");
+// strcpy(sensor_payload, buffer2); // restore sensor_payload after strtok operation
+// }
+
+ char sensor_buffer[30];
+ int sensor_count;
+ sensor_buffer[0] = 0;
+ sensor_count = sensor_loop(sensor_buffer);
+ if (sensor_count > NEW_SENSOR_FIELDS_MAX)
+ sensor_count = NEW_SENSOR_FIELDS_MAX;
+ if ((sensor_count > 0) && (failureMode != FAIL_PAYLOAD)) {
+ char space[] = " ";
+ strcat(sensor_payload, space);
+ strcat(sensor_payload, sensor_buffer);
+ printf(" Payload after new sensor read: %s\n", sensor_payload);
+ }
+
if ((sensor_payload[0] == 'O') && (sensor_payload[1] == 'K')) {
+// printf("Valid Payload!!\n");
for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) {
if (sensor[count1] < sensor_min[count1])
sensor_min[count1] = sensor[count1];
@@ -743,6 +1044,7 @@ int main(int argc, char * argv[]) {
}
if (sim_mode) { // simulated telemetry
+ printf("Simulated telemetry mode\n");
double time = ((long int)millis() - time_start) / 1000.0;
@@ -769,15 +1071,6 @@ int main(int argc, char * argv[]) {
current[map[PLUS_Z]] = (Zi >= 0) ? Zi : 0;
current[map[MINUS_Z]] = (Zi >= 0) ? 0 : ((-1.0f) * Zi);
- voltage[map[PLUS_X]] = (Xv >= 1) ? Xv : rnd_float(0.9, 1.1);
- voltage[map[MINUS_X]] = (Xv <= -1) ? ((-1.0f) * Xv) : rnd_float(0.9, 1.1);
- voltage[map[PLUS_Y]] = (Yv >= 1) ? Yv : rnd_float(0.9, 1.1);
- voltage[map[MINUS_Y]] = (Yv <= -1) ? ((-1.0f) * Yv) : rnd_float(0.9, 1.1);
- voltage[map[PLUS_Z]] = (Zv >= 1) ? Zv : rnd_float(0.9, 1.1);
- voltage[map[MINUS_Z]] = (Zv <= -1) ? ((-1.0f) * Zv) : rnd_float(0.9, 1.1);
-
- printf("temp: %f Time: %f Eclipse: %d : %f %f | %f %f | %f %f\n",tempS, time, eclipse, voltage[map[PLUS_X]], voltage[map[MINUS_X]], voltage[map[PLUS_Y]], voltage[map[MINUS_Y]], current[map[PLUS_Z]], current[map[MINUS_Z]]);
-
tempS += (eclipse > 0) ? ((temp_max - tempS) / 50.0f) : ((temp_min - tempS) / 50.0f);
tempS += +rnd_float(-1.0, 1.0);
// IHUcpuTemp = (int)((tempS + rnd_float(-1.0, 1.0)) * 10 + 0.5);
@@ -790,27 +1083,43 @@ int main(int argc, char * argv[]) {
// float charging = eclipse * (fabs(amps_max[0] * 0.707) + fabs(amps_max[1] * 0.707) + rnd_float(-4.0, 4.0));
// current[map[BAT]] = ((current[map[BAT2]] * voltage[map[BAT2]]) / batt) - charging;
- current[map[BAT]] = rnd_float(285, 305) - charging;
+ current[map[BAT]] = rnd_float(320, 510) - charging;
- printf("charging: %f bat curr: %f bus curr: %f bat volt: %f bus volt: %f \n",charging, current[map[BAT]], current[map[BAT2]], batt, voltage[map[BAT2]]);
+ printf("charging: %f bat curr: %f bus curr: %f bat volt: %f bus volt: %f \n",charging, current[map[BAT]], current[map[BAT2]], batt, voltage[map[BAT2]]);
- batt -= (batt > 3.5) ? current[map[BAT]] / 30000 : current[map[BAT]] / 3000;
- if (batt < 3.0) {
- batt = 3.0;
+ batt -= (batt > 3.5) ? current[map[BAT]] / 300000 : current[map[BAT]] / 30000;
+ if (batt < 3.6) {
+ batt = 3.6;
SafeMode = 1;
printf("Safe Mode!\n");
} else
SafeMode= 0;
- if (batt > 4.5)
- batt = 4.5;
+ if (batt > 4.1)
+ batt = 4.1;
voltage[map[BAT]] = batt + rnd_float(-0.01, 0.01);
+
+ float Vm, Vp;
+ Vm = batt + 0.5;
+ Vp = (Xv > 0) ? Xv : rnd_float(0.0, 0.1);
+ voltage[map[PLUS_X]] = (Vp >= Vm) ? (Vm + rnd_float(-0.1, 0.1)) : Vp;
+ Vp = (Xv < 0) ? ((-1.0f) * Xv) : rnd_float(0.0, 0.1);
+ voltage[map[MINUS_X]] = (Vp >= Vm) ? (Vm + rnd_float(-0.1, 0.1)) : Vp;
+ Vp = (Yv > 0) ? Yv : rnd_float(0.0, 0.1);
+ voltage[map[PLUS_Y]] = (Vp >= Vm) ? (Vm + rnd_float(-0.1, 0.1)) : Vp;
+ Vp = (Yv < 0) ? ((-1.0f) * Yv) : rnd_float(0.0, 0.1);
+ voltage[map[MINUS_Y]] = (Vp >= Vm) ? (Vm + rnd_float(-0.1, 0.1)) : Vp;
+ Vp = (Zv > 0) ? Zv : rnd_float(0.0, 0.1);
+ voltage[map[PLUS_Z]] = (Vp >= Vm) ? (Vm + rnd_float(-0.1, 0.1)) : Vp;
+ Vp = (Zv < 0) ? ((-1.0f) * Zv) : rnd_float(0.0, 0.1);
+ voltage[map[MINUS_Z]] = (Vp >= Vm) ? (Vm + rnd_float(-0.1, 0.1)) : Vp;
+
+ printf("temp: %f Time: %f Eclipse: %d : %f %f | %f %f | %f %f\n",tempS, time, eclipse, voltage[map[PLUS_X]], voltage[map[MINUS_X]], voltage[map[PLUS_Y]], voltage[map[MINUS_Y]], current[map[PLUS_Z]], current[map[MINUS_Z]]);
// end of simulated telemetry
- }
- else {
- }
+ }
+
FILE * cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
if (cpuTempSensor) {
// double cpuTemp;
@@ -875,22 +1184,7 @@ int main(int argc, char * argv[]) {
sleep(10);
}
//#endif
-
- FILE * fp = fopen("/home/pi/CubeSatSim/telem_string.txt", "w");
- if (fp != NULL) {
-// printf("Writing telem_string.txt\n");
- if (batteryVoltage != 4.5)
- if (c2cStatus == DISABLED)
- fprintf(fp, "BAT %4.2fV %4.0fmA\n", batteryVoltage, batteryCurrent);
- else
- fprintf(fp, "BAT %4.2fV %4.0fmA C\n", batteryVoltage, batteryCurrent); // show command and control is on
- else
- fprintf(fp, "\n"); // don't show voltage and current if it isn't a sensor value
-
- fclose(fp);
- } else
- printf("Error writing to telem_string.txt\n");
-
+
/**/
// sleep(1); // Delay 1 second
ctr = 0;
@@ -919,6 +1213,75 @@ int main(int argc, char * argv[]) {
}
}
// printf("c2cStatus: %d \n", c2cStatus);
+
+ if (failureMode == FAIL_NONE)
+ printf("No Simulated Failure!\n");
+ if (failureMode == FAIL_UNPLUG) {
+ voltage[map[PLUS_Y]] = rnd_float(0.8, 0.95);
+ current[map[PLUS_Y]] = 0.0;
+ printf("+Y Solar Unplugged Failure\n");
+ }
+ if (failureMode == FAIL_SOLAR) {
+ voltage[map[PLUS_X]] = 0.0;
+ current[map[PLUS_X]] = 0.0;
+ printf("+X Solar Simulated Failure\n");
+ }
+ if (failureMode == FAIL_DEGRADE) {
+ voltage[map[MINUS_X]] = voltage[map[MINUS_X]] * 0.5;
+ current[map[MINUS_X]] = current[map[MINUS_X]] * 0.5;
+ printf("-X Solar Deg Simulated Failure\n");
+ }
+ if (failureMode == FAIL_SHORT) {
+ voltage[map[MINUS_Y]] = 0.0;
+ printf("-Y Solar SC Simulated Failure!\n");
+ }
+ if (failureMode == FAIL_I2C1) {
+ voltage[map[PLUS_X]] = 0.0;
+ current[map[PLUS_X]] = 0.0;
+ voltage[map[PLUS_Y]] = 0.0;
+ current[map[PLUS_Y]] = 0.0;
+ voltage[map[BAT]] = 0.0;
+ current[map[BAT]] = 0.0;
+ voltage[map[BAT2]] = 0.0;
+ current[map[BAT2]] = 0.0;
+ printf("I2C Bus 1 Simulated Failure!\n");
+ }
+ if (failureMode == FAIL_I2C3) {
+ voltage[map[MINUS_X]] = 0.0;
+ current[map[MINUS_X]] = 0.0;
+ voltage[map[MINUS_Y]] = 0.0;
+ current[map[MINUS_Y]] = 0.0;
+ voltage[map[MINUS_Z]] = 0.0;
+ current[map[MINUS_Z]] = 0.0;
+ voltage[map[PLUS_Z]] = 0.0;
+ current[map[PLUS_Z]] = 0.0;
+ printf("I2C Bus 3 Simulated Failure!\n");
+ }
+
+ FILE * fp = fopen("/home/pi/CubeSatSim/telem_string.txt", "w");
+ if (fp != NULL) {
+// printf("Writing telem_string.txt v: %f v2: %f batteryVoltage: %f\n", voltage[map[BAT]], voltage[map[BAT2]], batteryVoltage);
+ if (sim_mode || (failureMode != FAIL_NONE)) {
+ if (voltage[map[BAT2]] == 0)
+ fprintf(fp, "BAT %.2f %.1f ", voltage[map[BAT]], current[map[BAT]]);
+ else
+ fprintf(fp, "BAT %.2f %.1f ", voltage[map[BAT2]], current[map[BAT]] + current[map[BAT2]]);
+ }
+ else {
+ fprintf(fp, "BAT %.2fV %.0fmA", batteryVoltage, batteryCurrent);
+ }
+
+// fprintf(fp, "BAT %.2fV %.0fmA", batteryVoltage, batteryCurrent);
+
+ if (c2cStatus != DISABLED)
+ fprintf(fp," C");
+ if (sim_mode || (failureMode != FAIL_NONE))
+ fprintf(fp," S\n");
+ else
+ fprintf(fp,"\n");
+ fclose(fp);
+ } else
+ printf("Error writing to telem_string.txt\n");
if ((mode == AFSK) || (mode == CW)) {
get_tlm();
@@ -929,11 +1292,11 @@ int main(int argc, char * argv[]) {
sleep(rand_sleep);
// fprintf(stderr, "INFO: Sleeping for extra %d sec\n", rand_sleep);
- } else if ((mode == FSK) || (mode == BPSK)) {// FSK or BPSK
+ } else if ((mode == FSK) || (mode == BPSK) || (mode == PACSAT) || (mode == PACSATGND)) {// FSK or BPSK
get_tlm_fox();
} else if ((mode == FC)) {
get_tlm_fc();
- } else { // SSTV
+ } else { // SSTV or PACSATGND
// fprintf(stderr, "Sleeping\n");
sleep(30);
}
@@ -989,20 +1352,6 @@ int upper_digit(int number) {
return digit;
}
-static int init_rf() {
- int ret;
- fprintf(stderr, "Initializing AX5043\n");
-
- ret = ax5043_init( & hax5043, XTAL_FREQ_HZ, VCO_INTERNAL);
- if (ret != PQWS_SUCCESS) {
- fprintf(stderr,
- "ERROR: Failed to initialize AX5043 with error code %d\n", ret);
- // exit(EXIT_FAILURE);
- return (0);
- }
- return (1);
-}
-
void get_tlm(void) {
FILE * txResult;
@@ -1065,17 +1414,16 @@ void get_tlm(void) {
// char footer_str[] = "-11>APCSS:010101/hi hi ' >> t.txt && touch /home/pi/CubeSatSim/ready"; // transmit is done by transmit.py
char footer_str[] = " && echo 'AMSAT-11>APCSS:010101/hi hi ' >> t.txt && touch /home/pi/CubeSatSim/ready"; // transmit is done by transmit.py
char footer_str2[] = " && touch /home/pi/CubeSatSim/ready";
+ char zero[] = "0.0";
- if (ax5043) {
- strcpy(str, header_str);
- } else {
+
strcpy(str, header_str3);
// }
if (mode == AFSK) {
strcat(str, call);
strcat(str, header_str2);
}
- }
+
// printf("Str: %s \n", str);
if (mode != CW) {
// sprintf(header_str2b, "=%7.2f%c%c%c%08.2f%cShi hi ",4003.79,'N',0x5c,0x5c,07534.33,'W'); // add APRS lat and long
@@ -1088,9 +1436,6 @@ void get_tlm(void) {
else
sprintf(header_long, "%08.2f%c",toAprsFormat( longitude) * (-1.0), 'W'); // long
- if (ax5043)
- sprintf(header_str2b, "=%s%c%sShi hi ", header_lat, 0x5c, header_long); // add APRS lat and long
- else
//#ifdef HAB
if (hab_mode)
sprintf(header_str2b, "=%s%c%sOhi hi ", header_lat, 0x2f, header_long); // add APRS lat and long with Balloon HAB icon
@@ -1105,8 +1450,11 @@ void get_tlm(void) {
strcat(str, header_str4);
strcat(str, call);
if (c2cStatus != DISABLED) {
- strcat(str, header_c2c);
+ strcat(str, " C");
}
+ if (sim_mode || failureMode != FAIL_NONE) {
+ strcat(str, " S");
+ }
sprintf(tlm_str, "%s' > cw0.txt", &str);
printf("CW string to execute: %s\n", &tlm_str);
@@ -1139,15 +1487,29 @@ void get_tlm(void) {
// }
} else { // APRS
- if (c2cStatus == 0)
- sprintf(tlm_str, "BAT %4.2f %5.1f ", batteryVoltage, batteryCurrent);
- else
- sprintf(tlm_str, "BAT %4.2f %5.1f C ", batteryVoltage, batteryCurrent);
-
- strcat(str, tlm_str);
+ if (sim_mode || (failureMode != FAIL_NONE)) {
+ if (voltage[map[BAT2]] == 0)
+ snprintf(tlm_str, 30, "BAT %.2f %.1f ", voltage[map[BAT]], current[map[BAT]]);
+ else
+ snprintf(tlm_str, 30, "BAT %.2f %.1f ", voltage[map[BAT2]], current[map[BAT]] + current[map[BAT2]]);
+
+ if (c2cStatus != DISABLED)
+ strcat(tlm_str,"C ");
+
+ strcat(tlm_str,"S ");
+ }
+ else {
+ snprintf(tlm_str, 30, "BAT %.2f %.1f ", batteryVoltage, batteryCurrent);
+
+ if (c2cStatus != DISABLED)
+ strcat(tlm_str,"C ");
+ }
+// printf("tlm_str: %s\n", tlm_str);
+ strcat(str, tlm_str);
}
- strcpy(sensor_payload, buffer2);
- printf(" Response from STEM Payload board:: %s\n", sensor_payload);
+
+// strcpy(sensor_payload, buffer2);
+ printf(" sensor_payload: %s\n", sensor_payload);
// printf(" Str so far: %s\n", str);
if (mode != CW)
@@ -1171,30 +1533,7 @@ void get_tlm(void) {
sleep(5);
}
}
- else if (ax5043) {
- digitalWrite(txLed, txLedOn);
- fprintf(stderr, "INFO: Transmitting X.25 packet using AX5043\n");
- memcpy(data, str, strnlen(str, 256));
- printf("data: %s \n", data);
- int ret = ax25_tx_frame( & hax25, & hax5043, data, strnlen(str, 256));
- if (ret) {
- fprintf(stderr,
- "ERROR: Failed to transmit AX.25 frame with error code %d\n",
- ret);
- exit(EXIT_FAILURE);
- }
- ax5043_wait_for_transmit();
- digitalWrite(txLed, txLedOff);
-
- if (ret) {
- fprintf(stderr,
- "ERROR: Failed to transmit entire AX.25 frame with error code %d\n",
- ret);
- exit(EXIT_FAILURE);
- }
- sleep(4); // was 2
-
- } else { // APRS using transmit
+ else { // APRS using transmit
strcat(str, footer_str1);
// strcat(str, call);
@@ -1203,7 +1542,7 @@ void get_tlm(void) {
else
strcat(str, footer_str2);
- fprintf(stderr, "String to execute: %s\n", str);
+ fprintf(stderr, "APRS String to execute: %s\n", str);
printf("\n\nTelemetry string is %s \n\n", str);
@@ -1230,21 +1569,24 @@ void get_tlm(void) {
// generates telemetry which is decoded by AMSAT's FoxTelem: https://www.amsat.org/foxtelem-software-for-windows-mac-linux/
// for more info about how we use FoxTelem see https://www.g0kla.com/foxtelem/amsat_telemetry_designers_handbook.pdf
-void get_tlm_fox() {
+void get_tlm_fox() {
int i;
long int sync = syncWord;
+ int cam = ON;
- smaller = (int) (S_RATE / (2 * freq_Hz));
+ smaller = (int)(S_RATE / (2 * freq_Hz));
+// if (mode == PACSAT)
+// dataLen = 78;
short int b[dataLen];
short int b_max[dataLen];
short int b_min[dataLen];
-
+
memset(b, 0, sizeof(b));
memset(b_max, 0, sizeof(b_max));
memset(b_min, 0, sizeof(b_min));
-
+
short int h[headerLen];
memset(h, 0, sizeof(h));
@@ -1261,121 +1603,127 @@ void get_tlm_fox() {
int posXi = 0, negXi = 0, posYi = 0, negYi = 0, posZi = 0, negZi = 0;
int head_offset = 0;
+ STEMBoardFailure = 1;
+
short int buffer_test[bufLen];
int buffSize;
- buffSize = (int) sizeof(buffer_test);
+ buffSize = (int)sizeof(buffer_test);
+
+ if (failureMode == FAIL_PAYLOAD) {
+ payload = OFF;
+ printf("Payload Simulated Failure!\n");
+ }
+ if (failureMode == FAIL_CAMERA) {
+ cam = OFF;
+ printf("Camera Simulated Failure!\n");
+ }
+ else {
+ cam = camera;
+ }
+
if (mode == FSK)
id = 7;
else
- id = 0; // 99 in h[6]
-
- // for (int frames = 0; frames < FRAME_CNT; frames++)
+ id = 0; // 99 in h[6]
+
+ // for (int frames = 0; frames < FRAME_CNT; frames++)
for (int frames = 0; frames < frameCnt; frames++) {
-
- if (firstTime != ON) {
+ // if (firstTime != ON) {
+ if (TRUE) {
// delay for sample period
-/**/
-// while ((millis() - sampleTime) < (unsigned int)samplePeriod)
- int startSleep = millis();
- if ((millis() - sampleTime) < ((unsigned int)frameTime - 750 + pi_zero_2_offset)) // was 250 100 500 for FSK
-// sleep(2.0); // 0.5); // 25); // initial period
- sleep(1.0); // 0.5); // 25); // initial period
- while ((millis() - sampleTime) < ((unsigned int)frameTime - 750 + pi_zero_2_offset)) // was 250 100
- sleep(0.1); // 25); // 0.5); // 25);
-// sleep((unsigned int)sleepTime);
-/**/
+ /**/
+ // while ((millis() - sampleTime) < (unsigned int)samplePeriod)
+ int startSleep = millis();
+ if ((millis() - sampleTime) < ((unsigned int)frameTime - 750 + pi_zero_2_offset)) // was 250 100 500 for FSK
+ // sleep(2.0); // 0.5); // 25); // initial period
+ sleep(1.0); // 0.5); // 25); // initial period
+ while ((millis() - sampleTime) < ((unsigned int)frameTime - 750 + pi_zero_2_offset)) // was 250 100
+ sleep(0.1); // 25); // 0.5); // 25);
+ // sleep((unsigned int)sleepTime);
+ /**/
printf("Start sleep %d Sleep period: %d while period: %d\n", startSleep, millis() - startSleep, (unsigned int)frameTime - 750 + pi_zero_2_offset);
fflush(stdout);
-
- sampleTime = (unsigned int) millis();
+
+ sampleTime = (unsigned int)millis();
} else
+ {
printf("first time - no sleep\n");
+ firstTime = OFF;
+ }
- printf("++++ Loop time: %5.3f sec +++++\n", (millis() - loopTime)/1000.0);
+ printf("++++ Loop time: %5.3f sec +++++\n", (millis() - loopTime) / 1000.0);
fflush(stdout);
- loopTime = millis();
-
-// if (mode == FSK)
+ loopTime = millis();
+
+ // if (mode == FSK)
{ // just moved
for (int count1 = 0; count1 < 8; count1++) {
- if (voltage[count1] < voltage_min[count1])
- voltage_min[count1] = voltage[count1];
- if (current[count1] < current_min[count1])
- current_min[count1] = current[count1];
-
- if (voltage[count1] > voltage_max[count1])
- voltage_max[count1] = voltage[count1];
- if (current[count1] > current_max[count1])
- current_max[count1] = current[count1];
+ if (voltage[count1] < voltage_min[count1]) voltage_min[count1] = voltage[count1];
+ if (current[count1] < current_min[count1]) current_min[count1] = current[count1];
+ if (voltage[count1] > voltage_max[count1]) voltage_max[count1] = voltage[count1];
+ if (current[count1] > current_max[count1]) current_max[count1] = current[count1];
-// printf("Vmin %4.2f Vmax %4.2f Imin %4.2f Imax %4.2f \n", voltage_min[count1], voltage_max[count1], current_min[count1], current_max[count1]);
+ // printf("Vmin %4.2f Vmax %4.2f Imin %4.2f Imax %4.2f \n", voltage_min[count1], voltage_max[count1], current_min[count1], current_max[count1]);
}
- for (int count1 = 0; count1 < 3; count1++) {
- if (other[count1] < other_min[count1])
- other_min[count1] = other[count1];
- if (other[count1] > other_max[count1])
- other_max[count1] = other[count1];
+ for (int count1 = 0; count1 < 3; count1++) {
+ if (other[count1] < other_min[count1]) other_min[count1] = other[count1];
+ if (other[count1] > other_max[count1]) other_max[count1] = other[count1];
// printf("Other min %f max %f \n", other_min[count1], other_max[count1]);
}
- if (mode == FSK)
- {
- if (loop % 32 == 0) { // was 8
-// printf("Sending MIN frame \n");
- frm_type = 0x03;
- for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) {
- if (count1 < 3)
- other[count1] = other_min[count1];
- if (count1 < 8) {
- voltage[count1] = voltage_min[count1];
- current[count1] = current_min[count1];
- }
- if (sensor_min[count1] != 1000.0) // make sure values are valid
- sensor[count1] = sensor_min[count1];
- }
- }
- if ((loop + 16) % 32 == 0) { // was 8
-// printf("Sending MAX frame \n");
- frm_type = 0x02;
- for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) {
- if (count1 < 3)
- other[count1] = other_max[count1];
- if (count1 < 8) {
- voltage[count1] = voltage_max[count1];
- current[count1] = current_max[count1];
- }
- if (sensor_max[count1] != -1000.0) // make sure values are valid
- sensor[count1] = sensor_max[count1];
- }
- }
- }
- else
- frm_type = 0x02; // BPSK always send MAX MIN frame
- }
+ if (mode == FSK) {
+ if (loop % 32 == 0) { // was 8
+ // printf("Sending MIN frame \n");
+ frm_type = 0x03;
+ for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) {
+ if (count1 < 3) other[count1] = other_min[count1];
+ if (count1 < 8) {
+ voltage[count1] = voltage_min[count1];
+ current[count1] = current_min[count1];
+ }
+ if (sensor_min[count1] != 100000.0) // make sure values are valid
+ sensor[count1] = sensor_min[count1];
+ }
+ }
+ if ((loop + 16) % 32 == 0) { // was 8
+ // printf("Sending MAX frame \n");
+ frm_type = 0x02;
+ for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) {
+ if (count1 < 3) other[count1] = other_max[count1];
+ if (count1 < 8) {
+ voltage[count1] = voltage_max[count1];
+ current[count1] = current_max[count1];
+ }
+ if (sensor_max[count1] != -100000.0) // make sure values are valid
+ sensor[count1] = sensor_max[count1];
+ }
+ }
+ } else
+ frm_type = 0x02; // BPSK always send MAX MIN frame
+ }
sensor_payload[0] = 0; // clear for next payload
-
-// if (mode == FSK) { // remove this
-// }
+
+ // if (mode == FSK) { // remove this
+ // }
memset(rs_frame, 0, sizeof(rs_frame));
memset(parities, 0, sizeof(parities));
- h[0] = (short int) ((h[0] & 0xf8) | (id & 0x07)); // 3 bits
- if (uptime != 0) // if uptime is 0, leave reset count at 0
+ h[0] = (short int)((h[0] & 0xf8) | (id & 0x07)); // 3 bits
+ if (uptime != 0) // if uptime is 0, leave reset count at 0
{
- h[0] = (short int) ((h[0] & 0x07) | ((reset_count & 0x1f) << 3));
- h[1] = (short int) ((reset_count >> 5) & 0xff);
- h[2] = (short int) ((h[2] & 0xf8) | ((reset_count >> 13) & 0x07));
+ h[0] = (short int)((h[0] & 0x07) | ((reset_count & 0x1f) << 3));
+ h[1] = (short int)((reset_count >> 5) & 0xff);
+ h[2] = (short int)((h[2] & 0xf8) | ((reset_count >> 13) & 0x07));
}
- h[2] = (short int) ((h[2] & 0x0e) | ((uptime & 0x1f) << 3));
- h[3] = (short int) ((uptime >> 5) & 0xff);
- h[4] = (short int) ((uptime >> 13) & 0xff);
- h[5] = (short int) ((h[5] & 0xf0) | ((uptime >> 21) & 0x0f));
- h[5] = (short int) ((h[5] & 0x0f) | (frm_type << 4));
+ h[2] = (short int)((h[2] & 0x0e) | ((uptime & 0x1f) << 3));
+ h[3] = (short int)((uptime >> 5) & 0xff);
+ h[4] = (short int)((uptime >> 13) & 0xff);
+ h[5] = (short int)((h[5] & 0xf0) | ((uptime >> 21) & 0x0f));
+ h[5] = (short int)((h[5] & 0x0f) | (frm_type << 4));
- if (mode == BPSK)
- h[6] = 99;
+ if (mode == BPSK) h[6] = 99;
posXi = (int)(current[map[PLUS_X]] + 0.5) + 2048;
posYi = (int)(current[map[PLUS_Y]] + 0.5) + 2048;
@@ -1396,22 +1744,23 @@ void get_tlm_fox() {
BAT2Voltage = (int)(voltage[map[BAT2]] * 100);
BAT2Current = (int)(current[map[BAT2]] + 0.5) + 2048;
- if (payload == ON)
- STEMBoardFailure = 0;
+// if (payload == ON) STEMBoardFailure = 0;
+ if ((payload == ON) || (sim_mode && (failureMode != FAIL_PAYLOAD)))
+ STEMBoardFailure = 0;
// read payload sensor if available
-// encodeA(b, 0 + head_offset, batt_a_v); // replaced by XS2 and XS3 below
-// encodeB(b, 1 + head_offset, batt_b_v);
+ // encodeA(b, 0 + head_offset, batt_a_v); // replaced by XS2 and XS3 below
+ // encodeB(b, 1 + head_offset, batt_b_v);
encodeA(b, 3 + head_offset, batt_c_v);
- encodeB(b, 4 + head_offset, (int)(sensor[ACCEL_X] * 100 + 0.5) + 2048); // Xaccel
- encodeA(b, 6 + head_offset, (int)(sensor[ACCEL_Y] * 100 + 0.5) + 2048); // Yaccel
- encodeB(b, 7 + head_offset, (int)(sensor[ACCEL_Z] * 100 + 0.5) + 2048); // Zaccel
+ encodeB(b, 4 + head_offset, (int)(sensor[ACCEL_X] * 100 + 0.5) + 2048); // Xaccel
+ encodeA(b, 6 + head_offset, (int)(sensor[ACCEL_Y] * 100 + 0.5) + 2048); // Yaccel
+ encodeB(b, 7 + head_offset, (int)(sensor[ACCEL_Z] * 100 + 0.5) + 2048); // Zaccel
encodeA(b, 9 + head_offset, battCurr);
- encodeB(b, 10 + head_offset, (int)(sensor[TEMP] * 10 + 0.5)); // Temp
+ encodeB(b, 10 + head_offset, (int)(sensor[TEMP] * 10 + 0.5)); // Temp
if (mode == FSK) {
encodeA(b, 12 + head_offset, posXv);
@@ -1427,7 +1776,7 @@ void get_tlm_fox() {
encodeB(b, 25 + head_offset, negYi);
encodeA(b, 27 + head_offset, posZi);
encodeB(b, 28 + head_offset, negZi);
- } else // BPSK
+ } else // BPSK
{
encodeA(b, 12 + head_offset, posXv);
encodeB(b, 13 + head_offset, posYv);
@@ -1442,7 +1791,7 @@ void get_tlm_fox() {
encodeB(b, 25 + head_offset, negXi);
encodeA(b, 27 + head_offset, negYi);
encodeB(b, 28 + head_offset, negZi);
-
+
encodeA(b_max, 12 + head_offset, (int)(voltage_max[map[PLUS_X]] * 100));
encodeB(b_max, 13 + head_offset, (int)(voltage_max[map[PLUS_Y]] * 100));
encodeA(b_max, 15 + head_offset, (int)(voltage_max[map[PLUS_Z]] * 100));
@@ -1455,51 +1804,57 @@ void get_tlm_fox() {
encodeA(b_max, 24 + head_offset, (int)(current_max[map[PLUS_Z]] + 0.5) + 2048);
encodeB(b_max, 25 + head_offset, (int)(current_max[map[MINUS_X]] + 0.5) + 2048);
encodeA(b_max, 27 + head_offset, (int)(current_max[map[MINUS_Y]] + 0.5) + 2048);
- encodeB(b_max, 28 + head_offset, (int)(current_max[map[MINUS_Z]] + 0.5) + 2048);
+ encodeB(b_max, 28 + head_offset, (int)(current_max[map[MINUS_Z]] + 0.5) + 2048);
encodeA(b_max, 9 + head_offset, (int)(current_max[map[BAT]] + 0.5) + 2048);
encodeA(b_max, 3 + head_offset, (int)(voltage_max[map[BAT]] * 100));
encodeA(b_max, 30 + head_offset, (int)(voltage_max[map[BAT2]] * 100));
encodeB(b_max, 46 + head_offset, (int)(current_max[map[BAT2]] + 0.5) + 2048);
-
- encodeB(b_max, 37 + head_offset, (int)(other_max[RSSI] + 0.5) + 2048);
+
+ encodeB(b_max, 37 + head_offset, (int)(other_max[RSSI] + 0.5) + 2048);
encodeA(b_max, 39 + head_offset, (int)(other_max[IHU_TEMP] * 10 + 0.5));
encodeB(b_max, 31 + head_offset, ((int)(other_max[SPIN] * 10)) + 2048);
- if (sensor_min[TEMP] != 1000.0) // make sure values are valid
- {
- encodeB(b_max, 4 + head_offset, (int)(sensor_max[ACCEL_X] * 100 + 0.5) + 2048); // Xaccel
- encodeA(b_max, 6 + head_offset, (int)(sensor_max[ACCEL_Y] * 100 + 0.5) + 2048); // Yaccel
- encodeB(b_max, 7 + head_offset, (int)(sensor_max[ACCEL_Z] * 100 + 0.5) + 2048); // Zaccel
-
- encodeA(b_max, 33 + head_offset, (int)(sensor_max[PRES] + 0.5)); // Pressure
- encodeB(b_max, 34 + head_offset, (int)(sensor_max[ALT] * 10.0 + 0.5)); // Altitude
- encodeB(b_max, 40 + head_offset, (int)(sensor_max[GYRO_X] + 0.5) + 2048);
- encodeA(b_max, 42 + head_offset, (int)(sensor_max[GYRO_Y] + 0.5) + 2048);
- encodeB(b_max, 43 + head_offset, (int)(sensor_max[GYRO_Z] + 0.5) + 2048);
-
- encodeA(b_max, 48 + head_offset, (int)(sensor_max[DTEMP] * 10 + 0.5) + 2048);
-// encodeB(b_max, 49 + head_offset, (int)(sensor_max[XS1] * 10 + 0.5) + 2048);
- encodeB(b_max, 10 + head_offset, (int)(sensor_max[TEMP] * 10 + 0.5));
- encodeA(b_max, 45 + head_offset, (int)(sensor_max[HUMI] * 10 + 0.5));
-
- encodeB(b_max, 49 + head_offset, (int)(sensor_max[XS1]));
- encodeA(b_max, 0 + head_offset, (int)(sensor_max[XS2]));
- encodeB(b_max, 1 + head_offset, (int)(sensor_max[XS3]));
- }
- else
- {
- encodeB(b_max, 4 + head_offset, 2048); // 0
- encodeA(b_max, 6 + head_offset, 2048); // 0
- encodeB(b_max, 7 + head_offset, 2048); // 0
-
- encodeB(b_max, 40 + head_offset, 2048);
- encodeA(b_max, 42 + head_offset, 2048);
- encodeB(b_max, 43 + head_offset, 2048);
-
- encodeA(b_max, 48 + head_offset, 2048);
-// encodeB(b_max, 49 + head_offset, 2048);
- }
+ if (sensor_min[TEMP] != 100000.0) // make sure values are valid
+ {
+ encodeB(b_max, 4 + head_offset, (int)(sensor_max[ACCEL_X] * 100 + 0.5) + 2048); // Xaccel
+ encodeA(b_max, 6 + head_offset, (int)(sensor_max[ACCEL_Y] * 100 + 0.5) + 2048); // Yaccel
+ encodeB(b_max, 7 + head_offset, (int)(sensor_max[ACCEL_Z] * 100 + 0.5) + 2048); // Zaccel
+
+ encodeA(b_max, 33 + head_offset, (int)(sensor_max[PRES] + 0.5)); // Pressure
+ if (sensor_max[ALT] < 0) sensor_max[ALT] = 0.0;
+ encodeB(b_max, 34 + head_offset, (int)(sensor_max[ALT] / 10.0 + 0.5)); // Altitude
+ encodeB(b_max, 40 + head_offset, (int)(sensor_max[GYRO_X] + 0.5) + 2048);
+ encodeA(b_max, 42 + head_offset, (int)(sensor_max[GYRO_Y] + 0.5) + 2048);
+ encodeB(b_max, 43 + head_offset, (int)(sensor_max[GYRO_Z] + 0.5) + 2048);
+
+ // encodeB(b_max, 49 + head_offset, (int)(sensor_max[XS1] * 10 + 0.5) + 2048);
+ encodeB(b_max, 10 + head_offset, (int)(sensor_max[TEMP] * 10 + 0.5));
+ encodeA(b_max, 45 + head_offset, (int)(sensor_max[HUMI] * 10 + 0.5));
+ if (failureMode != FAIL_PAYLOAD) {
+ encodeA(b_max, 48 + head_offset, (int)(sensor_max[DTEMP] * 10 + 0.5) + 2048);
+ encodeB(b_max, 49 + head_offset, (int)(sensor_max[XS1]));
+ encodeA(b_max, 0 + head_offset, (int)(sensor_max[XS2]));
+ encodeB(b_max, 1 + head_offset, (int)(sensor_max[XS3]));
+ }
+ else {
+ encodeA(b_max, 48 + head_offset, 2048);
+ encodeB(b_max, 49 + head_offset, 0);
+ encodeA(b_max, 0 + head_offset, 0);
+ encodeB(b_max, 1 + head_offset, 0);
+ }
+ } else {
+ encodeB(b_max, 4 + head_offset, 2048); // 0
+ encodeA(b_max, 6 + head_offset, 2048); // 0
+ encodeB(b_max, 7 + head_offset, 2048); // 0
+
+ encodeB(b_max, 40 + head_offset, 2048);
+ encodeA(b_max, 42 + head_offset, 2048);
+ encodeB(b_max, 43 + head_offset, 2048);
+
+ encodeA(b_max, 48 + head_offset, 2048);
+ // encodeB(b_max, 49 + head_offset, 2048);
+ }
encodeA(b_min, 12 + head_offset, (int)(voltage_min[map[PLUS_X]] * 100));
encodeB(b_min, 13 + head_offset, (int)(voltage_min[map[PLUS_Y]] * 100));
encodeA(b_min, 15 + head_offset, (int)(voltage_min[map[PLUS_Z]] * 100));
@@ -1512,102 +1867,165 @@ void get_tlm_fox() {
encodeA(b_min, 24 + head_offset, (int)(current_min[map[PLUS_Z]] + 0.5) + 2048);
encodeB(b_min, 25 + head_offset, (int)(current_min[map[MINUS_X]] + 0.5) + 2048);
encodeA(b_min, 27 + head_offset, (int)(current_min[map[MINUS_Y]] + 0.5) + 2048);
- encodeB(b_min, 28 + head_offset, (int)(current_min[map[MINUS_Z]] + 0.5) + 2048);
-
+ encodeB(b_min, 28 + head_offset, (int)(current_min[map[MINUS_Z]] + 0.5) + 2048);
+
encodeA(b_min, 9 + head_offset, (int)(current_min[map[BAT]] + 0.5) + 2048);
encodeA(b_min, 3 + head_offset, (int)(voltage_min[map[BAT]] * 100));
encodeA(b_min, 30 + head_offset, (int)(voltage_min[map[BAT2]] * 100));
encodeB(b_min, 46 + head_offset, (int)(current_min[map[BAT2]] + 0.5) + 2048);
-
+
encodeB(b_min, 31 + head_offset, ((int)(other_min[SPIN] * 10)) + 2048);
- encodeB(b_min, 37 + head_offset, (int)(other_min[RSSI] + 0.5) + 2048);
+ encodeB(b_min, 37 + head_offset, (int)(other_min[RSSI] + 0.5) + 2048);
encodeA(b_min, 39 + head_offset, (int)(other_min[IHU_TEMP] * 10 + 0.5));
-
- if (sensor_min[TEMP] != 1000.0) // make sure values are valid
- {
- encodeB(b_min, 4 + head_offset, (int)(sensor_min[ACCEL_X] * 100 + 0.5) + 2048); // Xaccel
- encodeA(b_min, 6 + head_offset, (int)(sensor_min[ACCEL_Y] * 100 + 0.5) + 2048); // Yaccel
- encodeB(b_min, 7 + head_offset, (int)(sensor_min[ACCEL_Z] * 100 + 0.5) + 2048); // Zaccel
-
- encodeA(b_min, 33 + head_offset, (int)(sensor_min[PRES] + 0.5)); // Pressure
- encodeB(b_min, 34 + head_offset, (int)(sensor_min[ALT] * 10.0 + 0.5)); // Altitude
- encodeB(b_min, 40 + head_offset, (int)(sensor_min[GYRO_X] + 0.5) + 2048);
- encodeA(b_min, 42 + head_offset, (int)(sensor_min[GYRO_Y] + 0.5) + 2048);
- encodeB(b_min, 43 + head_offset, (int)(sensor_min[GYRO_Z] + 0.5) + 2048);
-
- encodeA(b_min, 48 + head_offset, (int)(sensor_min[DTEMP] * 10 + 0.5) + 2048);
-// encodeB(b_min, 49 + head_offset, (int)(sensor_min[XS1] * 10 + 0.5) + 2048);
- encodeB(b_min, 10 + head_offset, (int)(sensor_min[TEMP] * 10 + 0.5));
- encodeA(b_min, 45 + head_offset, (int)(sensor_min[HUMI] * 10 + 0.5));
-
- encodeB(b_min, 49 + head_offset, (int)(sensor_min[XS1]));
- encodeA(b_min, 0 + head_offset, (int)(sensor_min[XS2]));
- encodeB(b_min, 1 + head_offset, (int)(sensor_min[XS3]));
- }
- else
- {
- encodeB(b_min, 4 + head_offset, 2048); // 0
- encodeA(b_min, 6 + head_offset, 2048); // 0
- encodeB(b_min, 7 + head_offset, 2048); // 0
-
- encodeB(b_min, 40 + head_offset, 2048);
- encodeA(b_min, 42 + head_offset, 2048);
- encodeB(b_min, 43 + head_offset, 2048);
-
- encodeA(b_min, 48 + head_offset, 2048);
-// encodeB(b_min, 49 + head_offset, 2048);
- }
- }
+
+ if (sensor_min[TEMP] != 100000.0) // make sure values are valid
+ {
+ encodeB(b_min, 4 + head_offset, (int)(sensor_min[ACCEL_X] * 100 + 0.5) + 2048); // Xaccel
+ encodeA(b_min, 6 + head_offset, (int)(sensor_min[ACCEL_Y] * 100 + 0.5) + 2048); // Yaccel
+ encodeB(b_min, 7 + head_offset, (int)(sensor_min[ACCEL_Z] * 100 + 0.5) + 2048); // Zaccel
+
+ encodeA(b_min, 33 + head_offset, (int)(sensor_min[PRES] + 0.5)); // Pressure
+ if (sensor_min[ALT] < 0) sensor_min[ALT] = 0.0;
+ encodeB(b_min, 34 + head_offset, (int)(sensor_min[ALT] / 10.0 + 0.5)); // Altitude
+ encodeB(b_min, 40 + head_offset, (int)(sensor_min[GYRO_X] + 0.5) + 2048);
+ encodeA(b_min, 42 + head_offset, (int)(sensor_min[GYRO_Y] + 0.5) + 2048);
+ encodeB(b_min, 43 + head_offset, (int)(sensor_min[GYRO_Z] + 0.5) + 2048);
+
+ // encodeB(b_min, 49 + head_offset, (int)(sensor_min[XS1] * 10 + 0.5) + 2048);
+ encodeB(b_min, 10 + head_offset, (int)(sensor_min[TEMP] * 10 + 0.5));
+ encodeA(b_min, 45 + head_offset, (int)(sensor_min[HUMI] * 10 + 0.5));
+
+ if (failureMode != FAIL_PAYLOAD) {
+ encodeA(b_min, 48 + head_offset, (int)(sensor_min[DTEMP] * 10 + 0.5) + 2048);
+ encodeB(b_min, 49 + head_offset, (int)(sensor_min[XS1]));
+ encodeA(b_min, 0 + head_offset, (int)(sensor_min[XS2]));
+ encodeB(b_min, 1 + head_offset, (int)(sensor_min[XS3]));
+ }
+ else {
+ encodeA(b_min, 48 + head_offset, 2048);
+ encodeB(b_min, 49 + head_offset, 0);
+ encodeA(b_min, 0 + head_offset, 0);
+ encodeB(b_min, 1 + head_offset, 0);
+ }
+ } else {
+ encodeB(b_min, 4 + head_offset, 2048); // 0
+ encodeA(b_min, 6 + head_offset, 2048); // 0
+ encodeB(b_min, 7 + head_offset, 2048); // 0
+
+ encodeB(b_min, 40 + head_offset, 2048);
+ encodeA(b_min, 42 + head_offset, 2048);
+ encodeB(b_min, 43 + head_offset, 2048);
+
+ encodeA(b_min, 48 + head_offset, 2048);
+ // encodeB(b_min, 49 + head_offset, 2048);
+ }
+ }
+ encodeA(b, 30 + head_offset, BAT2Voltage);
+
+ encodeB(b, 31 + head_offset, ((int)(other[SPIN] * 10)) + 2048);
+
+ encodeA(b, 33 + head_offset, (int)(sensor[PRES] + 0.5)); // Pressure
+ if (sensor[ALT] < 0) sensor[ALT] = 0.0;
+ encodeB(b, 34 + head_offset, (int)(sensor[ALT] / 10.0 + 0.5)); // Altitude
+ encodeB(b_min, 49 + head_offset, (int)(sensor_min[XS1]));
+ encodeA(b_min, 0 + head_offset, (int)(sensor_min[XS2]));
+ encodeB(b_min, 1 + head_offset, (int)(sensor_min[XS3]));
+ // }
+ // else
+ // {
+ // encodeB(b_min, 4 + head_offset, 2048); // 0
+ // encodeA(b_min, 6 + head_offset, 2048); // 0
+ // encodeB(b_min, 7 + head_offset, 2048); // 0
+ //
+ // encodeB(b_min, 40 + head_offset, 2048);
+ // encodeA(b_min, 42 + head_offset, 2048);
+ // encodeB(b_min, 43 + head_offset, 2048);
+ //
+ // encodeA(b_min, 48 + head_offset, 2048);
+ // // encodeB(b_min, 49 + head_offset, 2048);
+ // }
+ //
+ // }
encodeA(b, 30 + head_offset, BAT2Voltage);
encodeB(b, 31 + head_offset, ((int)(other[SPIN] * 10)) + 2048);
- encodeA(b, 33 + head_offset, (int)(sensor[PRES] + 0.5)); // Pressure
- encodeB(b, 34 + head_offset, (int)(sensor[ALT] * 10.0 + 0.5)); // Altitude
+ encodeA(b, 33 + head_offset, (int)(sensor[PRES] + 0.5)); // Pressure
+ if (sensor[ALT] < 0) sensor[ALT] = 0.0;
+ encodeB(b, 34 + head_offset, (int)(sensor[ALT] / 10.0 + 0.5)); // Altitude
+ encodeA(b, 45 + head_offset, (int)(sensor[HUMI] * 10 + 0.5)); // in place of sensor1
+ encodeA(b, 39 + head_offset, (int)(other[TEMP] * 10 + 0.5));
encodeA(b, 36 + head_offset, Resets);
encodeB(b, 37 + head_offset, (int)(other[RSSI] + 0.5) + 2048);
- encodeA(b, 39 + head_offset, (int)(other[IHU_TEMP] * 10 + 0.5));
-
encodeB(b, 40 + head_offset, (int)(sensor[GYRO_X] + 0.5) + 2048);
encodeA(b, 42 + head_offset, (int)(sensor[GYRO_Y] + 0.5) + 2048);
encodeB(b, 43 + head_offset, (int)(sensor[GYRO_Z] + 0.5) + 2048);
- encodeA(b, 45 + head_offset, (int)(sensor[HUMI] * 10 + 0.5)); // in place of sensor1
+ if (failureMode != FAIL_PAYLOAD) {
+ encodeA(b, 48 + head_offset, (int)(sensor[DTEMP] * 10 + 0.5) + 2048);
+ encodeB(b, 49 + head_offset, (int)(sensor[XS1]));
+ encodeA(b, 0 + head_offset, (int)(sensor[XS2]));
+ encodeB(b, 1 + head_offset, (int)(sensor[XS3]));
+ }
+ else {
+ encodeA(b, 48 + head_offset, 2048);
+ encodeB(b, 49 + head_offset, 0);
+ encodeA(b, 0 + head_offset, 0);
+ encodeB(b, 1 + head_offset, 0);
+ }
encodeB(b, 46 + head_offset, BAT2Current);
- encodeA(b, 48 + head_offset, (int)(sensor[DTEMP] * 10 + 0.5) + 2048);
-// encodeB(b, 49 + head_offset, (int)(sensor[XS1] * 10 + 0.5) + 2048);
-
- encodeB(b, 49 + head_offset, (int)(sensor[XS1]));
- encodeA(b, 0 + head_offset, (int)(sensor[XS2]));
- encodeB(b, 1 + head_offset, (int)(sensor[XS3]));
-
- FILE * command_count_file = fopen("/home/pi/CubeSatSim/command_count.txt", "r");
- if (command_count_file != NULL) {
- char count_string[10];
- if ( (fgets(count_string, 10, command_count_file)) != NULL)
- groundCommandCount = atoi(count_string);
-// fclose(command_count_file);
- } else
- printf("Error opening command_count.txt!\n");
+ encodeA(b, 39 + head_offset, (int)(other[IHU_TEMP] * 10 + 0.5));
+
+ // encodeB(b, 49 + head_offset, (int)(sensor[XS1] * 10 + 0.5) + 2048);
+
+ FILE* command_count_file = fopen("/home/pi/CubeSatSim/command_count.txt", "r");
+ if (command_count_file != NULL) {
+ char count_string[10];
+ if ((fgets(count_string, 10, command_count_file)) != NULL)
+ groundCommandCount = atoi(count_string);
+ else
+ printf("command_count.txt is invalid\n");
+ // fclose(command_count_file);
+ } else
+ printf("Error opening command_count.txt!\n");
fclose(command_count_file);
-
-// printf("Command count: %d\n", groundCommandCount);
-
- int status = STEMBoardFailure + SafeMode * 2 + sim_mode * 4 + PayloadFailure1 * 8 +
- (i2c_bus0 == OFF) * 16 + (i2c_bus1 == OFF) * 32 + (i2c_bus3 == OFF) * 64 + (camera == OFF) * 128 + groundCommandCount * 256;
+
+ printf("Command count: %d\n", groundCommandCount);
+ int simulated;
+ simulated = sim_mode;
+ if (failureMode != FAIL_NONE) {
+ simulated = TRUE;
+ printf("Showing Simulated in FoxTelem\n");
+ }
+ int i2c_1, i2c_3;
+ i2c_1 = i2c_bus1;
+ i2c_3 = i2c_bus3;
+ // printf("Bus1: %d Bus2: %d \n", i2c_1, i2c_3);
+ if (failureMode == FAIL_I2C1) {
+ i2c_1 = OFF;
+ // printf("I2C Bus 1 Simulated Failure\n");
+ } else if (failureMode == FAIL_I2C3) {
+ i2c_3 = OFF;
+ // printf("I2C Bus 3 Simulated Failure\n");
+ }
+ // int status = STEMBoardFailure + SafeMode * 2 + sim_mode * 4 + PayloadFailure1 * 8 +
+ // (i2c_bus0 == OFF) * 16 + (i2c_bus1 == OFF) * 32 + (i2c_bus3 == OFF) * 64 + (camera == OFF) * 128 + groundCommandCount * 256;
+ int status = STEMBoardFailure + SafeMode * 2 + simulated * 4 + PayloadFailure1 * 8 + (i2c_bus0 == OFF) * 16 + (i2c_1 == OFF) * 32 + (i2c_3 == OFF) * 64 + (cam == OFF) * 128 + groundCommandCount * 256;
encodeA(b, 51 + head_offset, status);
encodeB(b, 52 + head_offset, rxAntennaDeployed + txAntennaDeployed * 2 + c2cStatus * 4);
- if (mode == BPSK) {
- encodeA(b_max, 51 + head_offset, status);
+ encodeA(b, 53 + head_offset, groundCommandCount);
+
+ if ((mode == BPSK) || (mode == PACSAT) || (mode == PACSATGND)) {
+ encodeA(b_max, 51 + head_offset, status);
encodeA(b_min, 51 + head_offset, status);
encodeB(b_max, 52 + head_offset, rxAntennaDeployed + txAntennaDeployed * 2 + c2cStatus * 4);
encodeB(b_min, 52 + head_offset, rxAntennaDeployed + txAntennaDeployed * 2 + c2cStatus * 4);
}
-
+
if (txAntennaDeployed == 0) {
txAntennaDeployed = 1;
printf("TX Antenna Deployed!\n");
@@ -1615,16 +2033,46 @@ void get_tlm_fox() {
if (rxAntennaDeployed == 0) {
rxAntennaDeployed = 1;
printf("RX Antenna Deployed!\n");
- }
-
+ }
+
if (mode == BPSK) { // wod field experiments
unsigned long val = 0xffff;
- encodeA(b, 64 + head_offset, 0xff & val);
- encodeA(b, 65 + head_offset, val >> 8);
- encodeA(b, 63 + head_offset, 0x00);
+ encodeA(b, 64 + head_offset, 0xff & val);
+ encodeA(b, 65 + head_offset, val >> 8);
+ encodeA(b, 63 + head_offset, 0x00);
encodeA(b, 62 + head_offset, 0x01);
encodeB(b, 74 + head_offset, 0xfff);
- }
+ }
+
+ if ((mode == PACSAT) || (mode == PACSATGND))
+ {
+ FILE *telem_binary = fopen("/home/pi/CubeSatSim/tlm.bin", "wb");
+ if (telem_binary != NULL) {
+
+ int bytes_written = 4;
+ unsigned int now = (unsigned int)time(0);
+ fwrite(&now, sizeof(now), 1, telem_binary);
+
+ int count;
+ char byte;
+ printf("b is: \n");
+ for (count = 0; count < dataLen; count++) {
+ byte = b[count];
+ fwrite(&byte, 1, 1, telem_binary);
+ printf("%02X ", byte);
+ bytes_written++;
+ }
+ printf("\n");
+ printf("Writing %d bytes to tlm.bin\n", bytes_written + 4);
+ fclose(telem_binary);
+ }
+ else
+ printf("Error opening tlm.bin\n");
+ }
+ else
+ { // extra bracket for some reason?
+ {
+
short int data10[headerLen + rsFrames * (rsFrameLen + parityLen)];
short int data8[headerLen + rsFrames * (rsFrameLen + parityLen)];
@@ -1632,7 +2080,7 @@ void get_tlm_fox() {
int ctr3 = 0;
for (i = 0; i < rsFrameLen; i++) {
for (int j = 0; j < rsFrames; j++) {
- if (!((i == (rsFrameLen - 1)) && (j == 2))) // skip last one for BPSK
+ if (!((i == (rsFrameLen - 1)) && (j == 2))) // skip last one for BPSK
{
if (ctr1 < headerLen) {
rs_frame[j][i] = h[ctr1];
@@ -1641,30 +2089,23 @@ void get_tlm_fox() {
data8[ctr1++] = rs_frame[j][i];
// printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]);
} else {
- if (mode == FSK)
- {
- rs_frame[j][i] = b[ctr3 % dataLen];
- update_rs(parities[j], b[ctr3 % dataLen]);
- } else // BPSK
- if ((int)(ctr3/dataLen) == 3)
- {
- rs_frame[j][i] = b_max[ctr3 % dataLen];
- update_rs(parities[j], b_max[ctr3 % dataLen]);
- }
- else if ((int)(ctr3/dataLen) == 4)
- {
- rs_frame[j][i] = b_min[ctr3 % dataLen];
- update_rs(parities[j], b_min[ctr3 % dataLen]);
- }
- else
- {
- rs_frame[j][i] = b[ctr3 % dataLen];
- update_rs(parities[j], b[ctr3 % dataLen]);
- }
- {
- }
-
- // printf("%d rs_frame[%d][%d] = %x %d \n",
+ if (mode == FSK) {
+ rs_frame[j][i] = b[ctr3 % dataLen];
+ update_rs(parities[j], b[ctr3 % dataLen]);
+ } else // BPSK
+ if ((int)(ctr3 / dataLen) == 3) {
+ rs_frame[j][i] = b_max[ctr3 % dataLen];
+ update_rs(parities[j], b_max[ctr3 % dataLen]);
+ } else if ((int)(ctr3 / dataLen) == 4) {
+ rs_frame[j][i] = b_min[ctr3 % dataLen];
+ update_rs(parities[j], b_min[ctr3 % dataLen]);
+ } else {
+ rs_frame[j][i] = b[ctr3 % dataLen];
+ update_rs(parities[j], b[ctr3 % dataLen]);
+ }
+ {}
+
+ // printf("%d rs_frame[%d][%d] = %x %d \n",
// ctr1, j, i, b[ctr3 % DATA_LEN], ctr3 % DATA_LEN);
data8[ctr1++] = rs_frame[j][i];
// printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]);
@@ -1674,54 +2115,54 @@ void get_tlm_fox() {
}
}
- #ifdef DEBUG_LOGGING
- // printf("\nAt end of data8 write, %d ctr1 values written\n\n", ctr1);
- /*
- printf("Parities ");
- for (int m = 0; m < parityLen; m++) {
- printf("%d ", parities[0][m]);
- }
- printf("\n");
- */
- #endif
-
+#ifdef DEBUG_LOGGING
+// printf("\nAt end of data8 write, %d ctr1 values written\n\n", ctr1);
+/*
+ printf("Parities ");
+ for (int m = 0; m < parityLen; m++) {
+ printf("%d ", parities[0][m]);
+ }
+ printf("\n");
+*/
+#endif
+
int ctr2 = 0;
memset(data10, 0, sizeof(data10));
- for (i = 0; i < dataLen * payloads + headerLen; i++) // 476 for BPSK
+ for (i = 0; i < dataLen * payloads + headerLen; i++) // 476 for BPSK
{
- data10[ctr2] = (Encode_8b10b[rd][((int) data8[ctr2])] & 0x3ff);
- nrd = (Encode_8b10b[rd][((int) data8[ctr2])] >> 10) & 1;
+ data10[ctr2] = (Encode_8b10b[rd][((int)data8[ctr2])] & 0x3ff);
+ nrd = (Encode_8b10b[rd][((int)data8[ctr2])] >> 10) & 1;
// printf ("data10[%d] = encoded data8[%d] = %x \n",
- // ctr2, ctr2, data10[ctr2]);
+ // ctr2, ctr2, data10[ctr2]);
- rd = nrd; // ^ nrd;
+ rd = nrd; // ^ nrd;
ctr2++;
}
-// {
- for (i = 0; i < parityLen; i++) {
- for (int j = 0; j < rsFrames; j++) {
- if ((uptime != 0) || (i != 0)) // don't correctly update parties if uptime is 0 so the frame will fail the FEC check and be discarded
- data10[ctr2++] = (Encode_8b10b[rd][((int) parities[j][i])] & 0x3ff);
- nrd = (Encode_8b10b[rd][((int) parities[j][i])] >> 10) & 1;
+ // {
+ for (i = 0; i < parityLen; i++) {
+ for (int j = 0; j < rsFrames; j++) {
+ if ((uptime != 0) || (i != 0)) // don't correctly update parties if uptime is 0 so the frame will fail the FEC check and be discarded
+ data10[ctr2++] = (Encode_8b10b[rd][((int)parities[j][i])] & 0x3ff);
+ nrd = (Encode_8b10b[rd][((int)parities[j][i])] >> 10) & 1;
// printf ("data10[%d] = encoded parities[%d][%d] = %x \n",
- // ctr2 - 1, j, i, data10[ctr2 - 1]);
+ // ctr2 - 1, j, i, data10[ctr2 - 1]);
- rd = nrd;
- }
+ rd = nrd;
}
- // }
- #ifdef DEBUG_LOGGING
- // printf("\nAt end of data10 write, %d ctr2 values written\n\n", ctr2);
- #endif
+ }
+ // }
+#ifdef DEBUG_LOGGING
+// printf("\nAt end of data10 write, %d ctr2 values written\n\n", ctr2);
+#endif
int data;
int val;
- //int offset = 0;
+ // int offset = 0;
- #ifdef DEBUG_LOGGING
- // printf("\nAt start of buffer loop, syncBits %d samples %d ctr %d\n", syncBits, samples, ctr);
- #endif
+#ifdef DEBUG_LOGGING
+// printf("\nAt start of buffer loop, syncBits %d samples %d ctr %d\n", syncBits, samples, ctr);
+#endif
for (i = 1; i <= syncBits * samples; i++) {
write_wave(ctr, buffer);
@@ -1739,18 +2180,17 @@ void get_tlm_fox() {
if (data == 0) {
phase *= -1;
if ((ctr - smaller) > 0) {
- for (int j = 1; j <= smaller; j++)
- buffer[ctr - j] = buffer[ctr - j] * 0.4;
+ for (int j = 1; j <= smaller; j++) buffer[ctr - j] = buffer[ctr - j] * 0.4;
}
flip_ctr = ctr;
}
}
}
}
- #ifdef DEBUG_LOGGING
- // printf("\n\nValue of ctr after header: %d Buffer Len: %d\n\n", ctr, buffSize);
- #endif
- for (i = 1; i <= (10 * (headerLen + dataLen * payloads + rsFrames * parityLen) * samples); i++) // 572
+#ifdef DEBUG_LOGGING
+// printf("\n\nValue of ctr after header: %d Buffer Len: %d\n\n", ctr, buffSize);
+#endif
+ for (i = 1; i <= (10 * (headerLen + dataLen * payloads + rsFrames * parityLen) * samples); i++) // 572
{
write_wave(ctr, buffer);
if ((i % samples) == 0) {
@@ -1767,8 +2207,7 @@ void get_tlm_fox() {
if (data == 0) {
phase *= -1;
if ((ctr - smaller) > 0) {
- for (int j = 1; j <= smaller; j++)
- buffer[ctr - j] = buffer[ctr - j] * 0.4;
+ for (int j = 1; j <= smaller; j++) buffer[ctr - j] = buffer[ctr - j] * 0.4;
}
flip_ctr = ctr;
}
@@ -1776,55 +2215,29 @@ void get_tlm_fox() {
}
}
}
- #ifdef DEBUG_LOGGING
- // printf("\nValue of ctr after looping: %d Buffer Len: %d\n", ctr, buffSize);
- // printf("\ctr/samples = %d ctr/(samples*10) = %d\n\n", ctr/samples, ctr/(samples*10));
- #endif
+#ifdef DEBUG_LOGGING
+// printf("\nValue of ctr after looping: %d Buffer Len: %d\n", ctr, buffSize);
+// printf("\ctr/samples = %d ctr/(samples*10) = %d\n\n", ctr/samples, ctr/(samples*10));
+#endif
- //int error = 0;
- // int count;
- // for (count = 0; count < dataLen; count++) {
- // printf("%02X", b[count]);
- // }
- // printf("\n");
+ // int error = 0;
+ // int count;
+ // for (count = 0; count < dataLen; count++) {
+ // printf("%02X", b[count]);
+ // }
+ // printf("\n");
// socket write
socket_send(ctr);
-/*
- if (!socket_open && transmit) {
- printf("Opening socket!\n");
- // struct sockaddr_in address;
- // int valread;
- struct sockaddr_in serv_addr;
- // char *hello = "Hello from client";
- // char buffer[1024] = {0};
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("\n Socket creation error \n");
- error = 1;
- }
-
- memset( & serv_addr, '0', sizeof(serv_addr));
-
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(PORT);
-
- // Convert IPv4 and IPv6 addresses from text to binary form
- if (inet_pton(AF_INET, "127.0.0.1", & serv_addr.sin_addr) <= 0) {
- printf("\nInvalid address/ Address not supported \n");
- error = 1;
- }
-
- if (connect(sock, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0) {
- printf("\nConnection Failed \n");
- printf("Error: %s\n", strerror(errno));
- error = 1;
-// FILE * transmit_restartf2 = popen("sudo systemctl restart transmit", "r");
-// pclose(transmit_restartf2);
-// sleep(10); // was 5 // sleep if socket connection refused
-
- // try again
- error = 0;
+ /*
+ if (!socket_open && transmit) {
+ printf("Opening socket!\n");
+ // struct sockaddr_in address;
+ // int valread;
+ struct sockaddr_in serv_addr;
+ // char *hello = "Hello from client";
+ // char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
error = 1;
@@ -1835,7 +2248,7 @@ void get_tlm_fox() {
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
- // Convert IPv4 and IPv6 addresses from text to binary form
+ // Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", & serv_addr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
error = 1;
@@ -1845,101 +2258,128 @@ void get_tlm_fox() {
printf("\nConnection Failed \n");
printf("Error: %s\n", strerror(errno));
error = 1;
-// FILE * transmit_restartf = popen("sudo systemctl restart transmit", "r");
-// pclose(transmit_restartf);
-// sleep(10); // was 5 // sleep if socket connection refused
- }
- }
- if (error == 1) {
- printf("Socket error count: %d\n", error_count);
-// ; //transmitStatus = -1;
- if (error_count++ > 5) {
- printf("Restarting transmit\n");
- FILE * transmit_restartf = popen("sudo systemctl restart transmit", "r");
- pclose(transmit_restartf);
- sleep(10); // was 5 // sleep if socket connection refused
- }
- }
- else {
- socket_open = 1;
- error_count = 0;
- }
- }
+ // FILE * transmit_restartf2 = popen("sudo systemctl restart transmit", "r");
+ // pclose(transmit_restartf2);
+ // sleep(10); // was 5 // sleep if socket connection refused
+
+ // try again
+ error = 0;
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ printf("\n Socket creation error \n");
+ error = 1;
+ }
- if (!error && transmit) {
- // digitalWrite (0, LOW);
- // printf("Sending %d buffer bytes over socket after %d ms!\n", ctr, (long unsigned int)millis() - start);
- start = millis();
- int sock_ret = send(sock, buffer, (unsigned int)(ctr * 2 + 2), 0);
-// printf("socket send 1 %d ms bytes: %d \n\n", (unsigned int)millis() - start, sock_ret);
- fflush(stdout);
-
- if (sock_ret < (ctr * 2 + 2)) {
- // printf("Not resending\n");
- sleep(0.5);
- sock_ret = send(sock, &buffer[sock_ret], (unsigned int)(ctr * 2 + 2 - sock_ret), 0);
-// printf("socket send 2 %d ms bytes: %d \n\n", millis() - start, sock_ret);
+ memset( & serv_addr, '0', sizeof(serv_addr));
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_port = htons(PORT);
+
+ // Convert IPv4 and IPv6 addresses from text to binary form
+ if (inet_pton(AF_INET, "127.0.0.1", & serv_addr.sin_addr) <= 0) {
+ printf("\nInvalid address/ Address not supported \n");
+ error = 1;
+ }
+
+ if (connect(sock, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0) {
+ printf("\nConnection Failed \n");
+ printf("Error: %s\n", strerror(errno));
+ error = 1;
+ // FILE * transmit_restartf = popen("sudo systemctl restart transmit", "r");
+ // pclose(transmit_restartf);
+ // sleep(10); // was 5 // sleep if socket connection refused
+ }
+ }
+ if (error == 1) {
+ printf("Socket error count: %d\n", error_count);
+ // ; //transmitStatus = -1;
+ if (error_count++ > 5) {
+ printf("Restarting transmit\n");
+ FILE * transmit_restartf = popen("sudo systemctl restart transmit", "r");
+ pclose(transmit_restartf);
+ sleep(10); // was 5 // sleep if socket connection refused
+ }
+ }
+ else {
+ socket_open = 1;
+ error_count = 0;
+ }
}
-*/
-
- loop_count++;
- if ((firstTime == 1) || (((loop_count % 180) == 0) && (mode == FSK)) || (((loop_count % 80) == 0) && (mode == BPSK))) // do first time and was every 180 samples
- {
- int max;
- if (mode == FSK)
- if (sim_mode)
- max = 6;
- else if (firstTime == 1)
- max = 4; // 5; // was 6
- else
- max = 3;
- else
- if (firstTime == 1)
- max = 5; // 5; // was 6
- else
- max = 4;
-
- for (int times = 0; times < max; times++)
- {
-/// start = millis(); // send frame until buffer fills
- socket_send(ctr);
-/// sock_ret = send(sock, buffer, (unsigned int)(ctr * 2 + 2), 0);
-// printf("socket send %d in %d ms bytes: %d \n\n",times + 2, (unsigned int)millis() - start, sock_ret);
-
-/// if ((millis() - start) > 500) {
-/// printf("Buffer over filled!\n");
-/// break;
-/// }
-
-/// if (sock_ret < (ctr * 2 + 2)) {
- // printf("Not resending\n");
-/// sleep(0.5);
-/// sock_ret = send(sock, &buffer[sock_ret], (unsigned int)(ctr * 2 + 2 - sock_ret), 0);
-/// printf("socket resend %d in %d ms bytes: %d \n\n",times, millis() - start, sock_ret);
-/// }
+
+ if (!error && transmit) {
+ // digitalWrite (0, LOW);
+ // printf("Sending %d buffer bytes over socket after %d ms!\n", ctr, (long unsigned int)millis() - start);
+ start = millis();
+ int sock_ret = send(sock, buffer, (unsigned int)(ctr * 2 + 2), 0);
+ // printf("socket send 1 %d ms bytes: %d \n\n", (unsigned int)millis() - start, sock_ret);
+ fflush(stdout);
+
+ if (sock_ret < (ctr * 2 + 2)) {
+ // printf("Not resending\n");
+ sleep(0.5);
+ sock_ret = send(sock, &buffer[sock_ret], (unsigned int)(ctr * 2 + 2 - sock_ret), 0);
+ // printf("socket send 2 %d ms bytes: %d \n\n", millis() - start, sock_ret);
}
- sampleTime = (unsigned int) millis(); // resetting time for sleeping
- // fflush(stdout);
-// if (firstTime == 1)
-// max -= 1;
+ */
+
+ loop_count++;
+ if ((firstTime == 1) || (((loop_count % 180) == 0) && (mode == FSK)) || (((loop_count % 80) == 0) && (mode == BPSK))) // do first time and was every 180 samples
+ {
+ int max;
+ if (mode == FSK)
+ if (sim_mode)
+ max = 6;
+ else if (firstTime == 1)
+ max = 4; // 5; // was 6
+ else
+ max = 3;
+ else if (firstTime == 1)
+ max = 5; // 5; // was 6
+ else
+ max = 4;
+
+ for (int times = 0; times < max; times++) {
+ /// start = millis(); // send frame until buffer fills
+ socket_send(ctr);
+ /// sock_ret = send(sock, buffer, (unsigned int)(ctr * 2 + 2), 0);
+ // printf("socket send %d in %d ms bytes: %d \n\n",times + 2, (unsigned int)millis() - start, sock_ret);
+
+ /// if ((millis() - start) > 500) {
+ /// printf("Buffer over filled!\n");
+ /// break;
+ /// }
+
+ /// if (sock_ret < (ctr * 2 + 2)) {
+ // printf("Not resending\n");
+ /// sleep(0.5);
+ /// sock_ret = send(sock, &buffer[sock_ret], (unsigned int)(ctr * 2 + 2 - sock_ret), 0);
+ /// printf("socket resend %d in %d ms bytes: %d \n\n",times, millis() - start, sock_ret);
+ /// }
}
+ sampleTime = (unsigned int)millis(); // resetting time for sleeping
+ // fflush(stdout);
+ // if (firstTime == 1)
+ // max -= 1;
+ }
+
+ if (socket_open == 1)
+ firstTime = 0;
+// else if (frames_sent > 0) //5)
+// firstTime = 0;
+
+ }
+ } // extra bracket for some reason?
-/// if (sock_ret == -1) {
-/// printf("Error: %s \n", strerror(errno));
-/// socket_open = 0;
- //transmitStatus = -1;
-/// }
-/// }
if (!transmit) {
fprintf(stderr, "\nNo CubeSatSim Band Pass Filter detected. No transmissions after the CW ID.\n");
fprintf(stderr, " See http://cubesatsim.org/wiki for info about building a CubeSatSim\n\n");
}
-/// if (socket_open == 1)
-/// firstTime = 0;
-// else if (frames_sent > 0) //5)
-// firstTime = 0;
-
+// if (firstTime && (mode == PACSAT))
+// {
+// firstTime = OFF;
+// fprintf(stderr, "No longer first time\n");
+// fflush(stdout);
+// }
return;
}
@@ -2278,9 +2718,8 @@ if (setting == ON) {
FILE *command = popen("touch /home/pi/CubeSatSim/battery_saver", "r");
pclose(command);
fprintf(stderr,"Turning Safe Mode ON\n");
- fprintf(stderr,"Turning Battery saver mode ON\n");
- battery_saver_mode = ON;
- if ((mode == AFSK) || (mode == SSTV) || (mode == CW)) {
+ fprintf(stderr,"Turning Battery saver mode ON\n");
+ if ((mode == AFSK) || (mode == SSTV) || (mode == CW) || (mode == PACSAT) || (mode == PACSATGND)) {
command = popen("echo 'reboot due to turning ON Safe Mode!' | wall", "r");
pclose(command);
command = popen("sudo reboot now", "r");
@@ -2297,7 +2736,7 @@ if (setting == ON) {
pclose(command);
fprintf(stderr,"Turning Battery saver mode OFF\n");
battery_saver_mode = OFF;
- if ((mode == AFSK) || (mode == SSTV) || (mode == CW)) {
+ if ((mode == AFSK) || (mode == SSTV) || (mode == CW) || (mode == PACSAT) || (mode == PACSATGND)) {
command = popen("echo 'reboot due to turning OFF Safe Mode!' | wall", "r");
pclose(command);
command = popen("sudo reboot now", "r");
@@ -2317,6 +2756,10 @@ if (setting == ON) {
void get_tlm_fc() { // FUNcube Mode telemetry generation
+ printf("++++ Loop time: %5.3f sec +++++\n", (millis() - loopTime) / 1000.0);
+ fflush(stdout);
+ loopTime = millis();
+
//# define FC_EM
//#define JY_1
#define FC_SIM
@@ -2460,7 +2903,9 @@ void get_tlm_fc() { // FUNcube Mode telemetry generation
if (command_count_file != NULL) {
char count_string[10];
if ( (fgets(count_string, 10, command_count_file)) != NULL)
- groundCommandCount = (uint16_t) atoi(count_string);
+ groundCommandCount = (uint16_t) atoi(count_string);
+ else
+ printf("command_count.txt is invalid\n");
} else
printf("Error opening command_count.txt!\n");
fclose(command_count_file);
@@ -2606,7 +3051,8 @@ void get_tlm_fc() { // FUNcube Mode telemetry generation
void socket_send(int length) {
- printf("Socket_send!\n");
+ printf("Socket_send!\n");
+ fflush(stdout);
int error = 0;
if (!socket_open && transmit) { // open socket if not open
@@ -2615,7 +3061,8 @@ void socket_send(int length) {
// int valread;
struct sockaddr_in serv_addr;
// char *hello = "Hello from client";
- // char buffer[1024] = {0};
+ // char buffer[1024] = {0};
+ // error_count = 0;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
error = 1;
@@ -2635,7 +3082,9 @@ void socket_send(int length) {
if (connect(sock, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
printf("Error: %s\n", strerror(errno));
+ fflush(stdout);
error = 1;
+ sleep(1);
// try again
error = 0;
@@ -2658,18 +3107,21 @@ void socket_send(int length) {
if (connect(sock, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
printf("Error: %s\n", strerror(errno));
+ fflush(stdout);
error = 1;
+ sleep(1);
}
}
if (error == 1) {
printf("Socket error count: %d\n", error_count);
// ; //transmitStatus = -1;
if (error_count++ > 5) {
- printf("Restarting transmit\n");
- FILE * transmit_restartf = popen("sudo systemctl restart transmit", "r");
- pclose(transmit_restartf);
- sleep(10); // was 5 // sleep if socket connection refused
- }
+ printf("Restarting transmit\n");
+ fflush(stdout);
+ FILE * transmit_restartf = popen("sudo systemctl restart transmit", "r");
+ pclose(transmit_restartf);
+ sleep(10); // was 5 // sleep if socket connection refused
+ }
}
else {
socket_open = 1;
@@ -2724,3 +3176,50 @@ void socket_send(int length) {
if (socket_open == 1)
firstTime = 0;
}
+
+int pi_sensors(char *buffer)
+{
+ char sensor_buffer[1000];
+ FILE *sensor_read;
+
+ strcpy(buffer, "OK BME280 ");
+
+ sensor_read = sopen("/home/pi/raspberry-pi-bme280/bme280"); // read BME if present
+ fgets(sensor_buffer, 1000, sensor_read);
+ fprintf(stderr, "bme result: %s\n", sensor_buffer);
+ fclose(sensor_read);
+ if (sensor_buffer[strlen(sensor_buffer) - 1] == '\n')
+ sensor_buffer[strlen(sensor_buffer) - 1] = '\0'; // remove newline at end
+ strcat(buffer, sensor_buffer);
+
+ strcat(buffer, " MPU6050 ");
+
+ sensor_read = sopen("/home/pi/MPU6050-C-CPP-Library-for-Raspberry-Pi/mpu6050"); // read MPU if present
+ fgets(sensor_buffer, 1000, sensor_read);
+ fprintf(stderr, "mpu result: %s\n", sensor_buffer);
+ fclose(sensor_read);
+ if (sensor_buffer[strlen(sensor_buffer) - 1] == '\n')
+ sensor_buffer[strlen(sensor_buffer) - 1] = '\0'; // remove newline at end
+ strcat(buffer, sensor_buffer);
+
+ fprintf(stderr, "pi_sensors string: %s\n", buffer);
+
+ strcat(buffer, " GPS 0.0 0.0 0.0 TMP 0.0"); // place holders for GPS and diode temp
+/*
+ strcat(buffer, " YPR ");
+
+ sensor_read = sopen("/home/pi/MPU6050-C-CPP-Library-for-Raspberry-Pi/ypr"); // read MPU if present
+ fgets(sensor_buffer, 1000, sensor_read);
+ fprintf(stderr, "mpu result: %s\n", sensor_buffer);
+ fclose(sensor_read);
+ if (sensor_buffer[strlen(sensor_buffer) - 1] == '\n')
+ sensor_buffer[strlen(sensor_buffer) - 1] = '\0'; // remove newline at end
+ strcat(buffer, sensor_buffer); // no need to remove newline at end
+
+ fprintf(stderr, "pi_sensors string: %s\n", buffer);
+*/
+ if (strncmp(buffer, "OK BME280 0.0 0.0 0.0 0.0 MPU6050 0.0 0.0 0.0 0.0 0.0 0.0 GPS 0.0 0.0 0.0", 57) == 0)
+ return (0);
+ else
+ return (1);
+}
diff --git a/main.h b/main.h
index 1c2e5e36..08a9ad5e 100644
--- a/main.h
+++ b/main.h
@@ -39,30 +39,35 @@
#define PRES 3
#define ALT 4
#define HUMI 5
-#define GYRO_X 7 // MPU6050 is posisition 6
+#define GYRO_X 7 // MPU6050 label is posisition 6
#define GYRO_Y 8
#define GYRO_Z 9
#define ACCEL_X 10
#define ACCEL_Y 11
#define ACCEL_Z 12
-#define GPS1 14 // GPS is position 13
-#define GPS2 15
-#define GPS3 16
-#define DTEMP 18 // TMP is position 17
+#define GPS 13 // GPS label
+#define GPS1 14 // latitude
+#define GPS2 15 // longitude
+#define GPS3 16 // altitude
+#define DTEMP 18 // TMP label is position 17
#define XS1 20 // NEW user defined token will be position 19
#define XS2 21
#define XS3 22
-#define SENSOR_FIELDS 26
+#define NEW_SENSOR_FIELDS_MAX 6
+#define SENSOR_FIELDS (26 + 6)
#define FC_EPS 1
#define FC_BOB 25
#define FC_SW 50
#define FC_PAYLOAD 55
+#define X 0
+#define Y 1
+#define Z 2
#define RSSI 0
#define IHU_TEMP 2
#define SPIN 1
-#define OFF - 1
+#define OFF -1
#define ON 1
#define CHECK 0
#define DISABLED 0
@@ -73,9 +78,6 @@ uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET;
uint8_t data[1024];
uint32_t tx_channel = 0;
-ax5043_conf_t hax5043;
-ax25_conf_t hax25;
-
int twosToInt(int val, int len);
float toAprsFormat(float input);
float rnd_float(double min, double max);
@@ -101,6 +103,7 @@ int socket_open = 0;
int sock = 0;
int loop = -1, loop_count = 0;
int firstTime = ON; // 0;
+int secondTime = ON;
long start;
int testCount = 0;
long time_start;
@@ -122,7 +125,24 @@ FILE *image_file;
#define CW 5
#define FC 6
#define REPEATER 7
+#define PACSAT 8
#define TXCOMMAND 12
+#define PACSATGND 13
+
+#define FAIL_COUNT 11
+#define FAIL_NONE -1
+#define FAIL_UNPLUG 1
+#define FAIL_SOLAR 2
+#define FAIL_DEGRADE 3
+#define FAIL_SHORT 4
+#define FAIL_I2C1 5
+#define FAIL_I2C3 6
+#define FAIL_CAMERA 7
+#define FAIL_PAYLOAD 8
+#define FAIL_BME 9
+#define FAIL_MPU 10
+#define FAIL_AUDIO 11
+int failureMode = FAIL_NONE;
int transmitStatus = -1;
@@ -148,6 +168,8 @@ long int uptime;
char call[5];
char sim_yes[10];
char hab_yes[10];
+char fail_yes[10];
+int fail_time = 60;
int squelch = 3; // default squelch
char rx[12], tx[12];
int tx_pl = 0;
@@ -158,16 +180,16 @@ float sleepTime;
unsigned int sampleTime = 0;
int frames_sent = 0;
int cw_id = ON;
-int vB4 = FALSE, vB5 = FALSE, vB3 = FALSE, ax5043 = FALSE, transmit = FALSE, onLed, onLedOn, onLedOff, txLed, txLedOn, txLedOff, payload = OFF;
+int transmit = FALSE, onLed, onLedOn, onLedOff, txLed, txLedOn, txLedOff, payload = OFF;
// float voltageThreshold = 3.6, batteryVoltage = 4.5, batteryCurrent = 0, currentThreshold = 100;
-float voltageThreshold = 3.5, batteryVoltage = 4.5, batteryCurrent = 0, currentThreshold = 100;
+float voltageThreshold = 3.50, batteryVoltage = 4.5, batteryCurrent = 0, currentThreshold = 100;
float latitude = 39.027702f, longitude = -77.078064f;
float lat_file, long_file;
double cpuTemp;
int frameTime;
long int newGpsTime;
-float axis[3], angle[3], volts_max[3], amps_max[3], batt, speed, period, tempS, temp_max, temp_min, eclipse;
+float axis[3], angle[3], volts_max[3], amps_max[3], batt, speed, period, tempS, temp_max, temp_min, eclipse, atmosphere, tempP, altSP, presP, altGP, humiP, changeP;
int i2c_bus0 = OFF, i2c_bus1 = OFF, i2c_bus3 = OFF, camera = OFF, sim_mode = FALSE, SafeMode = FALSE;
int rxAntennaDeployed = 0, txAntennaDeployed = 0, c2cStatus = 0;
int sim_config = FALSE; // sim mode not set by configuration
@@ -175,11 +197,13 @@ double eclipse_time;
float voltage[9], current[9], sensor[SENSOR_FIELDS], other[3];
char sensor_payload[500];
+char sensor_string[SENSOR_FIELDS][32];
int test_i2c_bus(int bus);
//const char pythonCmd[] = "python3 -u /home/pi/CubeSatSim/python/voltcurrent.py ";
-const char pythonCmd[] = "python3 -u /home/pi/CubeSatSim/ina219.py ";
+const char pythonVenv[] = "source /home/pi/venv/bin/activate";
+const char pythonCmd[] = "/home/pi/venv/bin/python3 -u /home/pi/CubeSatSim/ina219.py ";
char pythonStr[100], pythonConfigStr[100], busStr[10];
int map[8] = {0, 1, 2, 3, 4, 5, 6, 7};
char src_addr[5] = "";
@@ -211,8 +235,11 @@ int pi_zero_2_offset = 0;
int hab_mode = FALSE;
+int fail_rnd_mode = FALSE;
int battery_saver_mode = FALSE;
long int loopTime;
+long int failTime = 0;
+int gps_status = OFF;
int error_count = 0;
int groundCommandCount = 0;
@@ -223,6 +250,9 @@ int groundCommandCount = 0;
int m_ileaver_index; /* Byte counter for interleaver */
unsigned char m_conv_sr; /* Convolutional encoder shift register state */
+void sensor_setup(); // defined in sensor_extension.c
+int sensor_loop(char *sensor_buffer); // defined in sensor_extension.c
+int pi_sensors(char *buffer); // used to read BME and MPU sensor if connected to Pi
// from funcubeLib/common/fecConstants.h
diff --git a/motd.txt b/motd.txt
new file mode 100644
index 00000000..09ff7ac9
--- /dev/null
+++ b/motd.txt
@@ -0,0 +1,11 @@
+
+This Raspberry Pi has the CubeSatSim v2.x software installed
+and runs automatically as systemd cubesatsim.service. For more
+information see https://CubeSatSim.org. To update
+to the latest version, enter this command:
+
+CubeSatSim/update
+
+To see configuration options, enter this command:
+
+CubeSatSim/config
diff --git a/pacsatsim.sh b/pacsatsim.sh
new file mode 100755
index 00000000..24350f6b
--- /dev/null
+++ b/pacsatsim.sh
@@ -0,0 +1,322 @@
+#!/bin/bash
+
+# script to run PacsatSim
+
+loopback=0
+vox=0
+safe=0
+card=0
+pwm=0
+
+if [ "$1" = "l" ] ; then
+
+ loopback=1
+
+elif [ "$1" = "v" ] ; then
+
+ vox=1
+
+elif [ "$1" = "c" ] ; then
+
+ card=1
+
+else
+
+ pwm=1
+
+fi
+
+FILE=/home/pi/CubeSatSim/battery_saver
+if [ -f "$FILE" ]; then
+
+ safe=1
+
+fi
+
+if [[ $(arecord -l | grep "USB Audio Device") ]] ; then
+ echo "USB Sound Card detected"
+ soundcard=1
+else
+ echo "No USB Sound Card detected"
+ soundcard=0
+fi
+
+gpio -g mode 7 up
+if [[ $(gpio -g read 7 | grep 0) ]] ; then
+ echo "TXC is present"
+ txc=1
+else
+ echo "TXC not present"
+ txc=0
+fi
+
+timeout 1 rtl_test &> out.txt
+if [[ $(grep "No supported" out.txt) ]] ; then
+ echo "No RTL-SDR detected"
+ rtl=0
+else
+ echo "RTL-SDR detected."
+ rtl=1
+fi
+
+value=`cat /home/pi/CubeSatSim/sim.cfg`
+echo "$value" > /dev/null
+set -- $value
+
+callsign="$1"
+txfrequency="$7e3"
+rxfrequency="$8e3"
+
+echo -n "PacSat callsign is "
+echo $callsign
+echo -n "Transmit Frequency is "
+echo $txfrequency
+echo -n "Receive Frequency is "
+echo $rxfrequency
+echo
+
+sleep 2
+
+if [ ! -d "/home/pi/PacSat" ]; then
+
+ echo "Setting up PacSatSim default configuration"
+ echo
+
+ cd
+ sudo rm pacsat-dir.zip
+ mkdir /home/pi/PacSat
+ mkdir /home/pi/PacSat/pacsat
+ mkdir /home/pi/PacSat/pacsat/dir
+ wget https://github.com/alanbjohnston/pi_pacsat/releases/download/v0.2/pacsat-dir.zip
+ unzip pacsat-dir.zip
+ sudo rm pacsat-dir.zip
+
+ cd
+ sudo rm /home/pi/pi_pacsat/Debug/pacsat.config
+ sudo rm /home/pi/pi_pacsat/Debug/pacsat.state
+ sudo rm /home/pi/pi_pacsat/Debug/pacsat_upload_table.dat
+ sudo rm pi_pacsat.zip
+ wget https://github.com/alanbjohnston/pi_pacsat/releases/download/v0.2/pi_pacsat.zip
+ unzip pi_pacsat.zip -d /
+ sudo rm pi_pacsat.zip
+
+# mkdir /home/pi/PacSat
+# mkdir /home/pi/PacSat/pacsat
+# mkdir /home/pi/PacSat/pacsat/dir
+
+# cd /home/pi/pi_pacsat/Debug
+
+# sudo rm pacsat_last_command_time.dat
+# sudo rm pacsat_upload_table.dat
+# sudo rm pacsat.state
+
+# echo "bit_rate=9600" > pacsat.config
+# echo "bbs_callsign=AMSAT-12" >> pacsat.config
+# echo "broadcast_callsign=AMSAT-11" >> pacsat.config
+# echo "digi_callsign=AMSAT-1" >> pacsat.config
+# echo "max_frames_in_tx_buffer=5" >> pacsat.config
+
+# echo "pb_open=1" > pacsat.state
+# echo "uplink_open=1" >> pacsat.state
+# echo "pb_max_period_for_client_in_seconds=60" >> pacsat.state
+# echo "uplink_max_period_for_client_in_seconds=60" >> pacsat.state
+
+# touch /home/pi/pi_pacsat/Debug/pacsat_upload_table.dat
+
+fi
+
+value=`cat /home/pi/CubeSatSim/sim.cfg`
+echo "$value" > /dev/null
+set -- $value
+
+callsign="$1"
+frequency="$7e3"
+
+echo "Configured callsign is "
+echo $callsign
+
+oldcallsign=$(grep -oP '(?<=bbs_callsign=).*(?=-)' /home/pi/pi_pacsat/Debug/pacsat.config)
+
+echo "Callsign in pacsat.config is "
+echo $oldcallsign
+
+if [ ! "$callsign" = "$oldcallsign" ] ; then
+
+ sudo sed -i "s/bbs_callsign=$oldcallsign/bbs_callsign=$callsign/g" /home/pi/pi_pacsat/Debug/pacsat.config
+ sudo sed -i "s/broadcast_callsign=$oldcallsign/broadcast_callsign=$callsign/g" /home/pi/pi_pacsat/Debug/pacsat.config
+ sudo sed -i "s/digi_callsign=$oldcallsign/digi_callsign=$callsign/g" /home/pi/pi_pacsat/Debug/pacsat.config
+
+ echo "New pacsat.confg is"
+ echo
+
+ cat /home/pi/pi_pacsat/Debug/pacsat.config
+
+fi
+
+sudo /etc/init.d/alsa-utils stop
+sudo /etc/init.d/alsa-utils start
+
+# export LD_LIBRARY_PATH=/mnt/usb-disk/ariss/lib:/usr/local/lib/iors_common:$LD_LIBRARY_PATH
+
+export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
+
+#sudo systemctl stop cubesatsim
+
+#sudo systemctl stop transmit
+
+#sudo systemctl stop command &>/dev/null
+
+sudo modprobe snd-aloop
+
+#sudo systemctl stop openwebrx
+
+#sudo systemctl stop rtl_tcp &>/dev/null
+
+#pkill -o chromium &>/dev/null
+
+#sudo killall -9 rtl_fm &>/dev/null
+
+#sudo killall -9 direwolf &>/dev/null
+
+#udo killall -9 aplay &>/dev/null
+
+#sudo killall -9 qsstv &>/dev/null
+
+#sudo killall -9 rtl_tcp &>/dev/null
+
+#sudo killall -9 java &>/dev/null
+
+#sudo killall -9 CubicSDR &>/dev/null
+
+#sudo killall -9 zenity &>/dev/null
+
+sudo killall -9 pacsat_telem &>/dev/null
+
+sudo killall -9 pi_pacsat &>/dev/null
+
+echo
+
+
+#choice=2
+
+#fi
+
+
+# frequency=434900000
+ echo
+ echo "If your Pacsat Ground Station is transmitting packets, you will see them here"
+ echo
+
+
+#echo
+
+#echo "Note that the 'Tuned to' frequency will be different from the chosen frequency due to the way SDRs work."
+
+
+# echo -e "Auto decoding APRS Pacsat packets on $frequency Hz"
+
+# direwolf -P+ -D1 -qd -dp -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf-pacsatsim-loopback.conf -t 0 &
+
+ # /usr/bin/x-terminal-emulator --geometry=120x40 -e "/home/pi/CubeSatSim/pacsatsim-df.sh"
+
+sudo usermod -a -G gpio pi
+
+if [ "$loopback" = "1" ] ; then
+
+ echo "Using audio loopback"
+ ADEVICE="ADEVICE plughw:CARD=Loopback,DEV=0"
+ PTT="PTT GPIOD gpiochip0 17"
+
+ value=`cat /home/pi/CubeSatSim/.mode`
+ echo "$value" > /dev/null
+ set -- $value
+
+ MODE=$1
+
+ if [ ! "$MODE" = "P" ] ; then
+
+ /home/pi/CubeSatSim/config -I n
+
+ fi
+
+# sudo /home/pi/CubeSatSim/pacsatsim-d.sh &
+
+# direwolf -P+ -D1 -qd -dp -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf-pacsatsim-loopback.conf -t 0 &
+
+elif [ "$safe" = "1" ] ; then
+
+ echo "Safe mode - battery saver"
+# sudo /home/pi/CubeSatSim/pacsatsim-d.sh &
+
+ ADEVICE="ADEVICE shared_mic plughw:CARD=Loopback,DEV=0"
+ PTT="PTT GPIOD gpiochip0 17"
+
+# direwolf -P+ -D1 -qd -dp -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf-pacsatsim-pwm-loopback.conf -t 0 &
+
+# arecord -D plughw:CARD=Loopback,DEV=1 -f S16_LE -r 48000 -c 1 | csdr convert_s16_f | csdr gain_ff 4000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434900 &
+# arecord -D plughw:CARD=Loopback,DEV=1 -f S16_LE -r 48000 -c 1 | csdr convert_s16_f | csdr gain_ff 4000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f $frequency &
+
+
+elif [ "$vox" = "1" ]; then
+
+ echo "Using Soundcard Audio TX and RX (VOX, no PTT)"
+ ADEVICE="ADEVICE plughw:CARD=Device,DEV=0"
+ PTT="PTT GPIOD gpiochip0 17"
+# sudo /home/pi/CubeSatSim/pacsatsim-dj.sh &
+
+# direwolf -P+ -D1 -qd -dp -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf-pacsatsim-jp14-half.conf -t 0 &
+
+elif [ "$pwm" = "1" ] ; then
+
+ echo "FM TXC using Soundcard input (JP13), PWM output"
+ ADEVICE="ADEVICE shared_mic plughw:CARD=Headphones,DEV=0"
+ PTT="PTT GPIOD gpiochip0 -20"
+
+# direwolf -P+ -D1 -qd -dp -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf-pacsatsim-pwm.conf -t 0 &
+
+else
+
+ echo "FM TXC using Soundcard input (JP13) and output (JP14)"
+ ADEVICE="ADEVICE shared_mic plughw:CARD=Device,DEV=0"
+ PTT="PTT GPIOD gpiochip0 -20"
+# direwolf -P+ -D1 -qd -dp -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf-pacsatsim-jp14.conf -t 0 &
+
+fi
+
+DIREWOLF_CONF="/home/pi/CubeSatSim/direwolf-pacsatsim-tmp.conf"
+
+echo "$ADEVICE" > $DIREWOLF_CONF
+echo "MYCALL $callsign-1" >> $DIREWOLF_CONF
+echo "$PTT" >> $DIREWOLF_CONF
+cat /home/pi/CubeSatSim/direwolf/direwolf-pacsatsim.conf >> $DIREWOLF_CONF
+
+echo
+echo "$DIREWOLF_CONF"
+echo
+cat $DIREWOLF_CONF
+echo
+
+direwolf -P+ -D1 -qd -dp -r 48000 -c $DIREWOLF_CONF -t 0 &
+
+# arecord -D plughw:CARD=Loopback,DEV=1 -f S16_LE -r 48000 -c 1 | csdr convert_s16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434900 &
+## arecord -D plughw:CARD=Loopback,DEV=1 -f S16_LE -r 48000 -c 1 | csdr convert_s16_f | csdr gain_ff 4000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434900 &
+
+## echo "Don't close the direwolf window or the Pacsatsim will stop running."
+
+export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
+
+/home/pi/pacsat_telem/Debug/pacsat_telem -v -d /home/pi/PacSat/pacsat &
+
+sleep 5
+
+value=`aplay -l | grep "Loopback"`
+echo "$value" > /dev/null
+set -- $value
+
+#rtl_fm -M fm -f $frequency -s 48k | tee >(aplay -D hw:${2:0:1},0,0 -r 48000 -t raw -f S16_LE -c 1) | aplay -D hw:0,0 -r 48000 -t raw -f S16_LE -c 1 &
+
+cd /home/pi/pi_pacsat/Debug
+
+./pi_pacsat -c pacsat.config -d /home/pi/PacSat
+
+sleep 60
diff --git a/sensor_extension.c b/sensor_extension.c
new file mode 100644
index 00000000..5c958a5a
--- /dev/null
+++ b/sensor_extension.c
@@ -0,0 +1,34 @@
+// Use this template for adding additional sensors
+// see example ...
+
+// put your library includes here
+#include
+#include
+
+// put your globals here
+
+
+// put your setup code here
+void sensor_setup() {
+
+// printf("Starting new sensor!\n");
+
+}
+
+// put your loop code here
+// Very Important: only use print, not println!!
+int sensor_loop(char *sensor_buffer) {
+
+ int sensors = 0; // set to the number of sensor readings adding.
+ sensor_buffer[0] = 0; // make sure buffer is empty
+
+// printf("Reading new sensors!\n");
+
+// sensors = 3;
+// strcpy(sensor_buffer, "NEW 0.0 0.0 0.0");
+
+// printf("New sensor string: %s\n", sensor_buffer);
+
+ return(sensors);
+
+}
diff --git a/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_maxtelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_maxtelemetry.csv
new file mode 100644
index 00000000..f99efb04
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_maxtelemetry.csv
@@ -0,0 +1,62 @@
+61,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION
+0,MAX,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2
+1,MAX,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3
+2,MAX,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage
+3,MAX,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis
+4,MAX,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis
+5,MAX,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis
+6,MAX,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current
+7,MAX,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,BME280 STEM Payload sensor temperature
+8,MAX,posXv,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X solar panel Voltage
+9,MAX,posYv,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y solar panel Voltage
+10,MAX,posZv,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z solar panel Voltage
+11,MAX,negXv,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X solar panel Voltage
+12,MAX,negYv,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y solar panel Voltage
+13,MAX,negZv,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z solar panel Voltage
+14,MAX,posXi,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X solar panel Current
+15,MAX,posYi,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y solar panel Current
+16,MAX,posZi,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z solar panel Current
+17,MAX,negXi,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X solar panel Current
+18,MAX,negYi,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y solar panel Current
+19,MAX,negZi,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z solar panel Current
+20,MAX,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage
+21,MAX,spin,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells
+22,MAX,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,BME280 STEM Payload sensor pressure
+23,MAX,Altitude,12,m,cubesatsim_altitude|INT,NONE,6,4,3,BME280 Altitude,BME280 STEM Payload sensor altitude
+24,MAX,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count
+25,MAX,rssi,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication
+26,MAX,IHUcpuTemp,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal temperature of IHU from Pi
+27,MAX,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around X Axis
+28,MAX,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Y Axis
+29,MAX,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Z Axis
+30,MAX,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,BME280 Humidity
+31,MAX,BAT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current
+32,MAX,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature
+33,MAX,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1
+34,MAX,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status, STEM Payload STEM Payload board failure Indicator
+35,MAX,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage)
+36,MAX,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry,Simulated Telemetry Indicator
+37,MAX,PayloadStatus1,1,-,17,NONE,6,8,0,Exp 3,STEM Payload status 1 failure indicator
+38,MAX,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator
+39,MAX,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator
+40,MAX,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator
+41,MAX,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator
+42,MAX,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received
+43,MAX,RxAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status
+44,MAX,TxAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status
+45,MAX,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status
+46,MAX,ICR3VProt,12,V,43,NONE,7,2,3,3V Prot,ICR 3V Proteted
+47,MAX,ICR2dot5V,12,V,43,NONE,7,3,3,2.5V,ICR 2.5V
+48,MAX,ICR2dot5VProt,12,V,43,NONE,7,4,3,2.5V Prot,ICR 2.5V Protected
+49,MAX,rf6,12,-,0,NONE,0,0,0,None,None
+50,MAX,rf7,12,-,0,NONE,0,0,0,None,None
+51,MAX,MuxTest,12,V,43,NONE,7,5,3,Sensor Power,Sensor Power Voltage at the ICR
+52,MAX,LtVGACtl,12,V,42,NONE,1,4,3,VGA Control,Control Voltage to the Variable Gain Amplifier (VGA)
+53,MAX,pad,4,-,34,NONE,0,0,0,None,Unused
+54,MAX,IHUdiagData,32,-,18,NONE,3,2,0,Diagnostic Info,Diagnostic Data on IHU Performance
+55,MAX,pad1,1,-,0,NONE,0,0,0,NONE,Filler
+56,MAX,wodSize,8,000s,36,NONE,3,3,0,WOD Stored,Number of WOD data payloads kept for each of Science and Housekeeping. In hundreds
+57,MAX,swCmds,32,-,35,NONE,7,6,0,Diagnostic,ICR Diagnostic information
+58,MAX,hwCmdCnt,6,-,1,NONE,7,7,0,HW Command Count,Number of hardware commands since last reset
+59,MAX,swCmdCnt,6,-,1,NONE,7,8,0,SW Command Count,Number of software commands since last reset
+60,MAX,pad2,27,-,0,NONE,0,0,0,NONE,Filler byets
diff --git a/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_mintelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_mintelemetry.csv
new file mode 100644
index 00000000..7d69fce6
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_mintelemetry.csv
@@ -0,0 +1,62 @@
+61,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION
+0,MIN,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2
+1,MIN,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3
+2,MIN,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage
+3,MIN,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis
+4,MIN,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis
+5,MIN,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis
+6,MIN,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current
+7,MIN,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,BME280 STEM Payload sensor temperature
+8,MIN,posXv,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X solar panel Voltage
+9,MIN,posYv,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y solar panel Voltage
+10,MIN,posZv,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z solar panel Voltage
+11,MIN,negXv,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X solar panel Voltage
+12,MIN,negYv,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y solar panel Voltage
+13,MIN,negZv,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z solar panel Voltage
+14,MIN,posXi,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X solar panel Current
+15,MIN,posYi,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y solar panel Current
+16,MIN,posZi,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z solar panel Current
+17,MIN,negXi,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X solar panel Current
+18,MIN,negYi,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y solar panel Current
+19,MIN,negZi,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z solar panel Current
+20,MIN,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage
+21,MIN,spin,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells
+22,MIN,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,BME280 STEM Payload sensor pressure
+23,MIN,Altitude,12,m,cubesatsim_altitude|INT,NONE,6,4,3,BME280 Altitude,BME280 STEM Payload sensor altitude
+24,MIN,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count
+25,MIN,rssi,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication
+26,MIN,IHUcpuTemp,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal temperature of IHU from Pi
+27,MIN,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around X Axis
+28,MIN,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Y Axis
+29,MIN,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Z Axis
+30,MIN,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,BME280 Humidity
+31,MIN,BAT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current
+32,MIN,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature
+33,MIN,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1
+34,MIN,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status, STEM Payload STEM Payload board failure Indicator
+35,MIN,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage)
+36,MIN,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry,Simulated Telemetry Indicator
+37,MIN,PayloadStatus1,1,-,17,NONE,6,8,0,Exp 3,STEM Payload status 1 failure indicator
+38,MIN,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator
+39,MIN,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator
+40,MIN,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator
+41,MIN,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator
+42,MIN,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received
+43,MIN,RxAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status
+44,MIN,TxAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status
+45,MIN,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status
+46,MIN,ICR3VProt,12,V,43,NONE,7,2,3,3V Prot,ICR 3V Proteted
+47,MIN,ICR2dot5V,12,V,43,NONE,7,3,3,2.5V,ICR 2.5V
+48,MIN,ICR2dot5VProt,12,V,43,NONE,7,4,3,2.5V Prot,ICR 2.5V Protected
+49,MIN,rf6,12,-,0,NONE,0,0,0,None,None
+50,MIN,rf7,12,-,0,NONE,0,0,0,None,None
+51,MIN,MuxTest,12,V,43,NONE,7,5,3,Sensor Power,Sensor Power Voltage at the ICR
+52,MIN,LtVGACtl,12,V,42,NONE,1,4,3,VGA Control,Control Voltage to the Variable Gain Amplifier (VGA)
+53,MIN,pad,4,-,34,NONE,0,0,0,None,Unused
+54,MIN,IHUdiagData,32,-,18,NONE,3,2,0,Diagnostic Info,Diagnostic Data on IHU Performance
+55,MIN,pad1,1,-,0,NONE,0,0,0,NONE,Filler
+56,MIN,wodSize,8,000s,36,NONE,3,3,0,WOD Stored,Number of WOD data payloads kept for each of Science and Housekeeping. In hundreds
+57,MIN,swCmds,32,-,35,NONE,7,6,0,Diagnostic,ICR Diagnostic information
+58,MIN,hwCmdCnt,6,-,1,NONE,7,7,0,HW Command Count,Number of hardware commands since last reset
+59,MIN,swCmdCnt,6,-,1,NONE,7,8,0,SW Command Count,Number of software commands since last reset
+60,MIN,pad2,27,-,0,NONE,0,0,0,NONE,Filler
diff --git a/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_rttelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_rttelemetry.csv
new file mode 100644
index 00000000..9fdaed04
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_rttelemetry.csv
@@ -0,0 +1,63 @@
+62,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION
+0,realTime,Sensor 2,12,integer,1,Experiments,6,8,3,Sensor 2,STEM Payload Extra Sensor 2
+1,realTime,Sensor 3,12,integer,1,Experiments,6,9,3,Sensor 3,STEM Payload Extra Sensor 3
+2,realTime,BATT_V,12,V,cubesatsim_voltage|FLOAT2,Battery,4,1,3,Battery Voltage,INA219 Battery Voltage
+3,realTime,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+X Panel,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis
+4,realTime,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+Y Panel,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis
+5,realTime,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+Z Panel,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis
+6,realTime,BATT_I,12,mA,cubesatsim_current,Battery,4,2,3,Battery Current,INA219 Battery Current
+7,realTime,Temperature,12,C,cubesatsim_temperature,Experiments,6,2,3,BME280 Temp,BME280 STEM Payload sensor temperature
+8,realTime,posXv,12,V,cubesatsim_voltage|FLOAT2,+X Panel,7,1,3,Voltage,INA219 +X solar panel Voltage
+9,realTime,posYv,12,V,cubesatsim_voltage|FLOAT2,+Y Panel,8,1,3,Voltage,INA219 +Y solar panel Voltage
+10,realTime,posZv,12,V,cubesatsim_voltage|FLOAT2,+Z Panel,9,1,3,Voltage,INA219 +Z solar panel Voltage
+11,realTime,negXv,12,V,cubesatsim_voltage|FLOAT2,-X Panel,10,1,3,Voltage,INA219 -X solar panel Voltage
+12,realTime,negYv,12,V,cubesatsim_voltage|FLOAT2,-Y Panel,11,1,3,Voltage,INA219 -Y solar panel Voltage
+13,realTime,negZv,12,V,cubesatsim_voltage|FLOAT2,-Z Panel,12,1,3,Voltage,INA219 -Z solar panel Voltage
+14,realTime,posXi,12,mA,cubesatsim_current,+X Panel,7,2,3,Current,INA219 +X solar panel Current
+15,realTime,posYi,12,mA,cubesatsim_current,+Y Panel,8,2,3,Current,INA219 +Y solar panel Current
+16,realTime,posZi,12,mA,cubesatsim_current,+Z Panel,9,2,3,Current,INA219 +Z solar panel Current
+17,realTime,negXi,12,mA,cubesatsim_current,-X Panel,10,2,3,Current,INA219 -X solar panel Current
+18,realTime,negYi,12,mA,cubesatsim_current,-Y Panel,11,2,3,Current,INA219 -Y solar panel Current
+19,realTime,negZi,12,mA,cubesatsim_current,-Z Panel,12,2,3,Current,INA219 -Z solar panel Current
+20,realTime,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,Battery2,5,1,3,Battery2 Voltage,INA219 Battery2 Voltage
+21,realTime,spin,12,rpm,cubesatsim_rpm,Computer Software,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells
+22,realTime,Pressure,12,hPa,cubesatsim_pressure,Experiments,6,3,3,BME280 Pressure,BME280 STEM Payload sensor pressure
+23,realTime,Altitude,12,m,cubesatsim_altitude|INT,Experiments,6,4,3,BME280 Altitude,BME280 STEM Payload sensor altitude
+24,realTime,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count
+25,realTime,rssi,12,dBm,cubesatsim_rssi|INT,Radio,1,1,3,RSSI,Received Signal Strength Indication
+26,realTime,IHUcpuTemp,12,C,cubesatsim_temperature,Computer Hardware,2,1,3,IHU Temp (Pi),Internal temperature of IHU from Pi
+27,realTime,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+X Panel,7,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around X Axis
+28,realTime,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+Y Panel,8,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Y Axis
+29,realTime,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+Z Panel,9,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Z Axis
+30,realTime,Humidity,12,%,cubesatsim_temperature,Experiments,6,5,3,BME280 Humidity,BME280 Humidity
+31,realTime,BAT2_I,12,mA,cubesatsim_current,Battery2,5,2,3,Battery2 Current,INA219 Battery2 Current
+32,realTime,DiodeTemp,12,C,cubesatsim_rpm,Experiments,6,6,3,Diode Temp,STEM Payload Diode Temperature
+33,realTime,Sensor 1,12,integer,1,Experiments,6,7,3,Sensor 1,STEM Payload Extra Sensor 1
+34,realTime,STEMPayloadStatus,1,-,17,Experiments,6,1,0,STEM Payload Status, STEM Payload STEM Payload board failure Indicator
+35,realTime,SafeMode,1,-,STATUS_ON_OFF,Computer Software,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage)
+36,realTime,SimulatedTelemetry,1,-,STATUS_ON_OFF,Computer Software,3,4,0,Simulated Telemetry,Simulated Telemetry Indicator
+37,realTime,PayloadStatus1,1,-,17,NONE,6,8,0,Exp 3,STEM Payload status 1 failure indicator
+38,realTime,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator
+39,realTime,I2CBus1Failure,1,-,17,Computer Hardware,2,2,0,I2C Bus 1,I2C bus 1 failure indicator
+40,realTime,I2CBus3Failure,1,-,17,Computer Hardware,2,3,0,I2C Bus 3,I2C bus 3 failure indicator
+41,realTime,CameraFailure,1,-,17,Computer Hardware,2,4,0,Camera,Camera failure indicator
+42,realTime,GroundCommands,4,-,1,NONE,0,0,0,Ground Commands,Number of ground commands received
+43,realTime,RxAntenna,1,-,16,Radio,1,3,0,RX Antenna,Receive antenna status
+44,realTime,TxAntenna,1,-,16,Radio,1,2,0,TX Antenna,Transmit antenna status
+45,realTime,C2CStatus,2,-,COMMAND_STATUS,Computer Software,3,5,0,Command Control, Command & Control Status
+46,realTime,GroundCommands2,10,-,1,Computer Software,3,3,0,Ground Commands,Number of ground commands received
+47,realTime,ICR3VProt,12,V,43,NONE,7,2,3,3V Prot,ICR 3V Proteted
+48,realTime,ICR2dot5V,12,V,43,NONE,7,3,3,2.5V,ICR 2.5V
+49,realTime,ICR2dot5VProt,12,V,43,NONE,7,4,3,2.5V Prot,ICR 2.5V Protected
+50,realTime,rf6,12,-,0,NONE,0,0,0,None,None
+51,realTime,rf7,12,-,0,NONE,0,0,0,None,None
+52,realTime,MuxTest,12,V,43,NONE,7,5,3,Sensor Power,Sensor Power Voltage at the ICR
+53,realTime,LtVGACtl,12,V,42,NONE,1,4,3,VGA Control,Control Voltage to the Variable Gain Amplifier (VGA)
+54,realTime,pad,4,-,34,NONE,0,0,0,None,Unused
+55,realTime,IHUdiagData,32,-,18,NONE,3,2,0,Diagnostic Info,Diagnostic Data on IHU Performance
+56,realTime,pad1,1,-,0,NONE,0,0,0,NONE,Filler
+57,realTime,wodSize,8,000s,36,NONE,3,3,0,WOD Stored,Number of WOD data payloads kept for each of Science and Housekeeping. In hundreds
+58,realTime,swCmds,32,-,35,NONE,7,6,0,Diagnostic,ICR Diagnostic information
+59,realTime,hwCmdCnt,6,-,1,NONE,7,7,0,HW Command Count,Number of hardware commands since last reset
+60,realTime,swCmdCnt,6,-,1,NONE,7,8,0,SW Command Count,Number of software commands since last reset
+61,realTime,pad2,17,-,0,NONE,0,0,0,NONE,Filler
diff --git a/spacecraft/FoxTelem_1.13i/CubeSatSim_conversion_curves.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_conversion_curves.csv
new file mode 100644
index 00000000..38f4351b
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_conversion_curves.csv
@@ -0,0 +1,13 @@
+CurveName,a,bx,cx^2,dx^3,ex^4,fx^5,Description
+cubesatsim_voltage,0,0.01,0,0,0,0,Converts voltages read from the INA219 sensors
+cubesatsim_current,-2048,1,0,0,0,0,Converts positive and negative currents read from the INA219 sensors
+cubesatsim_temperature,0,0.1,0,0,0,0,Converts temperature of Pi
+cubesatsim_rotation,-2048,1,0,0,0,0,Converts positive and negative dps rotation
+cubesatsim_acceleration,-20.48,0.01,0,0,0,0,Converts positive and negative g acceleration
+cubesatsim_altitude,0,10,0,0,0,0,Converts altitude
+cubesatsim_pressure,0,1,0,0,0,0,Converts pressure
+cubesatsim_sensor1,0,1,0,0,0,0,Conversion of Sensor 1
+cubesatsim_sensor2,-2048,1,0,0,0,0,Conversion of Sensor 2
+cubesatsim_sensor3,-20.48,0.01,0,0,0,0,Conversion of Sensor 3
+cubesatsim_rpm,-204.8,0.1,0,0,0,0,Conversion of calculated RPM
+cubesatsim_rssi,-2048,1,0,0,0,0,Conversion of Received Signal Strength
diff --git a/spacecraft/FoxTelem_1.13i/CubeSatSim_maxtelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_maxtelemetry.csv
new file mode 100644
index 00000000..9bcc637e
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_maxtelemetry.csv
@@ -0,0 +1,48 @@
+47,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION
+0,MAX,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2
+1,MAX,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3
+2,MAX,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage
+3,MAX,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis
+4,MAX,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis
+5,MAX,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis
+6,MAX,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current
+7,MAX,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,STEM Payload Sensor BME280 Temperature
+8,MAX,PANEL_PLUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X Panel Voltage
+9,MAX,PANEL_MINUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X Panel Voltage
+10,MAX,PANEL_PLUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y Panel Voltage
+11,MAX,PANEL_MINUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y Panel Voltage
+12,MAX,PANEL_PLUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z Panel Voltage
+13,MAX,PANEL_MINUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z Panel Voltage
+14,MAX,PANEL_PLUS_X_I,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X Panel Current
+15,MAX,PANEL_MINUS_X_I,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X Panel Current
+16,MAX,PANEL_PLUS_Y_I,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y Panel Current
+17,MAX,PANEL_MINUS_Y_I,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y Panel Current
+18,MAX,PANEL_PLUS_Z_I,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z Panel Current
+19,MAX,PANEL_MINUS_Z_I,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z Panel Current
+20,MAX,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage
+21,MAX,SPIN,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells
+22,MAX,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,STEM Payload Sensor BME280 Pressure
+23,MAX,Altitude,12,m,cubesatsim_altitude|INT,NONE,6,4,3,BME280 Altitude,STEM Payload Sensor BME280 Altitude
+24,MAX,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count
+25,MAX,RSSI,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication
+26,MAX,IHUTemperature,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal Temperature of Pi IHU
+27,MAX,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around X Axis
+28,MAX,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Y Axis
+29,MAX,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Z Axis
+30,MAX,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,STEM Payload Sensor BME280 Humidity
+31,MAX,BATT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current
+32,MAX,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature
+33,MAX,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1
+34,MAX,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status,STEM Payload Board Status
+35,MAX,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage)
+36,MAX,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry, Simulated Telemetry Indicator
+37,MAX,PayloadStatus1,1,-,17,NONE,0,0,0,Exp 3,STEM Payload status 1 failure indicator
+38,MAX,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator
+39,MAX,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator
+40,MAX,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator
+41,MAX,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator
+42,MAX,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received
+43,MAX,RXAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status
+44,MAX,TXAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status
+45,MAX,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status
+46,MAX,Pad,56,-,0,NONE,0,0,0,NONE,NONE
diff --git a/spacecraft/FoxTelem_1.13i/CubeSatSim_mintelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_mintelemetry.csv
new file mode 100644
index 00000000..5d6627a9
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_mintelemetry.csv
@@ -0,0 +1,48 @@
+47,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION
+0,MIN,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2
+1,MIN,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3
+2,MIN,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage
+3,MIN,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis
+4,MIN,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis
+5,MIN,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis
+6,MIN,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current
+7,MIN,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,STEM Payload Sensor BME280 Temperature
+8,MIN,PANEL_PLUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X Panel Voltage
+9,MIN,PANEL_MINUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X Panel Voltage
+10,MIN,PANEL_PLUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y Panel Voltage
+11,MIN,PANEL_MINUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y Panel Voltage
+12,MIN,PANEL_PLUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z Panel Voltage
+13,MIN,PANEL_MINUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z Panel Voltage
+14,MIN,PANEL_PLUS_X_I,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X Panel Current
+15,MIN,PANEL_MINUS_X_I,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X Panel Current
+16,MIN,PANEL_PLUS_Y_I,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y Panel Current
+17,MIN,PANEL_MINUS_Y_I,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y Panel Current
+18,MIN,PANEL_PLUS_Z_I,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z Panel Current
+19,MIN,PANEL_MINUS_Z_I,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z Panel Current
+20,MIN,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage
+21,MIN,SPIN,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells
+22,MIN,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,STEM Payload Sensor BME280 Pressure
+23,MIN,Altitude,12,m,cubesatsim_altitude|INT,NONE,6,4,3,BME280 Altitude,STEM Payload Sensor BME280 Altitude
+24,MIN,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count
+25,MIN,RSSI,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication
+26,MIN,IHUTemperature,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal Temperature of Pi IHU
+27,MIN,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around X Axis
+28,MIN,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Y Axis
+29,MIN,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Z Axis
+30,MIN,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,STEM Payload Sensor BME280 Humidity
+31,MIN,BATT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current
+32,MIN,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature
+33,MIN,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1
+34,MIN,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status,STEM Payload Board Status
+35,MIN,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage)
+36,MIN,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry, Simulated Telemetry Indicator
+37,MIN,PayloadStatus1,1,-,17,NONE,0,0,0,Exp 3,STEM Payload status 1 failure indicator
+38,MIN,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator
+39,MIN,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator
+40,MIN,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator
+41,MIN,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator
+42,MIN,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received
+43,MIN,RXAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status
+44,MIN,TXAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status
+45,MIN,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status
+46,MIN,Pad,56,-,0,NONE,0,0,0,NONE,NONE
diff --git a/spacecraft/FoxTelem_1.13i/CubeSatSim_rttelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_rttelemetry.csv
new file mode 100644
index 00000000..967514bc
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_rttelemetry.csv
@@ -0,0 +1,49 @@
+48,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION
+0,RT,Sensor 2,12,integer,1,Experiments,6,8,3,Sensor 2,STEM Payload Extra Sensor 2
+1,RT,Sensor 3,12,integer,1,Experiments,6,9,3,Sensor 3,STEM Payload Extra Sensor 3
+2,RT,BATT_V,12,V,cubesatsim_voltage|FLOAT2,Battery,4,1,3,Battery Voltage,INA219 Battery Voltage
+3,RT,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+X Panel,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis
+4,RT,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+Y Panel,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis
+5,RT,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+Z Panel,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis
+6,RT,BATT_I,12,mA,cubesatsim_current,Battery,4,2,3,Battery Current,INA219 Battery Current
+7,RT,Temperature,12,C,cubesatsim_temperature,Experiments,6,2,3,BME280 Temp,STEM Payload Sensor BME280 Temperature
+8,RT,PANEL_PLUS_X_V,12,V,cubesatsim_voltage|FLOAT2,+X Panel,7,1,3,Voltage,INA219 +X Panel Voltage
+9,RT,PANEL_MINUS_X_V,12,V,cubesatsim_voltage|FLOAT2,-X Panel,10,1,3,Voltage,INA219 -X Panel Voltage
+10,RT,PANEL_PLUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,+Y Panel,8,1,3,Voltage,INA219 +Y Panel Voltage
+11,RT,PANEL_MINUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,-Y Panel,11,1,3,Voltage,INA219 -Y Panel Voltage
+12,RT,PANEL_PLUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,+Z Panel,9,1,3,Voltage,INA219 +Z Panel Voltage
+13,RT,PANEL_MINUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,-Z Panel,12,1,3,Voltage,INA219 -Z Panel Voltage
+14,RT,PANEL_PLUS_X_I,12,mA,cubesatsim_current,+X Panel,7,2,3,Current,INA219 +X Panel Current
+15,RT,PANEL_MINUS_X_I,12,mA,cubesatsim_current,-X Panel,10,2,3,Current,INA219 -X Panel Current
+16,RT,PANEL_PLUS_Y_I,12,mA,cubesatsim_current,+Y Panel,8,2,3,Current,INA219 +Y Panel Current
+17,RT,PANEL_MINUS_Y_I,12,mA,cubesatsim_current,-Y Panel,11,2,3,Current,INA219 -Y Panel Current
+18,RT,PANEL_PLUS_Z_I,12,mA,cubesatsim_current,+Z Panel,9,2,3,Current,INA219 +Z Panel Current
+19,RT,PANEL_MINUS_Z_I,12,mA,cubesatsim_current,-Z Panel,12,2,3,Current,INA219 -Z Panel Current
+20,RT,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,Battery2,5,1,3,Battery2 Voltage,INA219 Battery2 Voltage
+21,RT,SPIN,12,rpm,cubesatsim_rpm,Computer Software,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells
+22,RT,Pressure,12,hPa,cubesatsim_pressure,Experiments,6,3,3,BME280 Pressure,STEM Payload Sensor BME280 Pressure
+23,RT,Altitude,12,m,cubesatsim_altitude|INT,Experiments,6,4,3,BME280 Altitude,STEM Payload Sensor BME280 Altitude
+24,RT,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count
+25,RT,RSSI,12,dBm,cubesatsim_rssi|INT,Radio,1,1,3,RSSI,Received Signal Strength Indication
+26,RT,IHUTemperature,12,C,cubesatsim_temperature,Computer Hardware,2,1,3,IHU Temp (Pi),Internal Temperature of Pi IHU
+27,RT,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+X Panel,7,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around X Axis
+28,RT,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+Y Panel,8,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Y Axis
+29,RT,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+Z Panel,9,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Z Axis
+30,RT,Humidity,12,%,cubesatsim_temperature,Experiments,6,5,3,BME280 Humidity,STEM Payload Sensor BME280 Humidity
+31,RT,BATT2_I,12,mA,cubesatsim_current,Battery2,5,2,3,Battery2 Current,INA219 Battery2 Current
+32,RT,DiodeTemp,12,C,cubesatsim_rpm,Experiments,6,6,3,Diode Temp,STEM Payload Diode Temperature
+33,RT,Sensor 1,12,integer,1,Experiments,6,7,3,Sensor 1,STEM Payload Extra Sensor 1
+34,RT,STEMPayloadStatus,1,-,17,Experiments,6,1,0,STEM Payload Status,STEM Payload Board Status
+35,RT,SafeMode,1,-,STATUS_ON_OFF,Computer Software,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage)
+36,RT,SimulatedTelemetry,1,-,STATUS_ON_OFF,Computer Software,3,4,0,Simulated Telemetry, Simulated Telemetry Indicator
+37,RT,PayloadStatus1,1,-,17,NONE,0,0,0,Exp 3,STEM Payload status 1 failure indicator
+38,RT,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator
+39,RT,I2CBus1Failure,1,-,17,Computer Hardware,2,2,0,I2C Bus 1,I2C bus 1 failure indicator
+40,RT,I2CBus3Failure,1,-,17,Computer Hardware,2,3,0,I2C Bus 3,I2C bus 3 failure indicator
+41,RT,CameraFailure,1,-,17,Computer Hardware,2,4,0,Camera,Camera failure indicator
+42,RT,GroundCommands,4,-,1,NONE,0,0,0,Ground Commands,Number of ground commands received
+43,RT,RXAntenna,1,-,16,Radio,1,3,0,RX Antenna,Receive antenna status
+44,RT,TXAntenna,1,-,16,Radio,1,2,0,TX Antenna,Transmit antenna status
+45,RT,C2CStatus,2,-,COMMAND_STATUS,Computer Software,3,5,0,Command Control, Command & Control Status
+46,RT,GroundCommands2,10,-,1,Computer Software,3,3,0,Ground Commands,Number of ground commands received
+47,RT,Pad,46,-,0,NONE,0,0,0,NONE,NONE
diff --git a/spacecraft/FoxTelem_1.13i/README.md b/spacecraft/FoxTelem_1.13i/README.md
new file mode 100644
index 00000000..765fba49
--- /dev/null
+++ b/spacecraft/FoxTelem_1.13i/README.md
@@ -0,0 +1,7 @@
+These files update the spacecraft files in FoxTelem version 1.13i or later and fix a bug in the payload altitude sensor display.
+
+You can download them as a zip file: [foxtelem_spacecraft_files.zip](https://github.com/user-attachments/files/23393444/foxtelem_spacecraft_files.zip)
+
+Extract (unzip foxtelem_spacecraft_files.zip) and copy into FoxTelem spacecraft folder, replacing existing files.
+
+Next time you run FoxTelem, the CubeSatSim-FSK and CubeSatSim-BPSK spacecraft will be automatically updated.
diff --git a/spacecraft/PacSatGround_0.46m/PacSatSim.dat b/spacecraft/PacSatGround_0.46m/PacSatSim.dat
new file mode 100644
index 00000000..92ae8f93
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46m/PacSatSim.dat
@@ -0,0 +1,15 @@
+Pacsat Telemetry Decoder Properties
+#Sat Nov 26 18:12:20 EST 2016
+numberOfLookupTables=0
+measurementsFileName=measurements.csv
+model=1
+layout0.filename=PACSAT_rttelemetry.csv
+layout0.name=TLMI_LAYOUT
+passMeasurementsFileName=passmeasurements.csv
+name=PacSatSim
+description=PacSatSim
+numberOfLayouts=1
+satId=3
+catalogNumber=0
+conversionCoefficients=pacsat-coef.csv
+layoutsUseBits=True
diff --git a/spacecraft/PacSatGround_0.46m/PacSatSim.properties b/spacecraft/PacSatGround_0.46m/PacSatSim.properties
new file mode 100644
index 00000000..e4ccad24
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46m/PacSatSim.properties
@@ -0,0 +1,20 @@
+#PacSat Ground Station Properties
+#Sun Feb 17 18:25:06 EST 2019
+sequence_num=3
+name=PacSatSim
+digiCallsign=AMSAT-1
+description=PacSatSim
+broadcastCallsign=AMSAT-11
+DIR_AGE=10
+bbsCallsign=AMSAT-12
+telemLayoutFile=PacSatSim.dat
+telem_server=tlm.amsatfox.org
+web_site_url=http://CubeSatSim.org
+show_system_files_on_dir_tab=false
+show_user_files=true
+supports_file_upload=true
+norad_id=30776
+psf_header_check_sums=false
+commandsFile=pacsat.commands
+is_command_station=true
+secret_key=ScKQLp2ZMvCaCTK5jAmOmKmA0JiSyJ6Y15+Yfg\=\=
diff --git a/spacecraft/PacSatGround_0.46o/PacSatGround.zip b/spacecraft/PacSatGround_0.46o/PacSatGround.zip
new file mode 100644
index 00000000..6694f79a
Binary files /dev/null and b/spacecraft/PacSatGround_0.46o/PacSatGround.zip differ
diff --git a/spacecraft/PacSatGround_0.46o/PacSatGroundLoop.zip b/spacecraft/PacSatGround_0.46o/PacSatGroundLoop.zip
new file mode 100644
index 00000000..7efc92a7
Binary files /dev/null and b/spacecraft/PacSatGround_0.46o/PacSatGroundLoop.zip differ
diff --git a/spacecraft/PacSatGround_0.46o/PacSatSim-coef.csv b/spacecraft/PacSatGround_0.46o/PacSatSim-coef.csv
new file mode 100644
index 00000000..cb9f0537
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46o/PacSatSim-coef.csv
@@ -0,0 +1,41 @@
+0,-,NONE,0,1,0,0,0,0,None,0,4096,None
+1,-,Boolean,0,1,0,0,0,0,Boolean,0,1,A Boolean value that prints TRUE or FALSE
+2,-,Counts,0,1,0,0,0,0,Counts,0,4096,An integer count value
+3,-,Date,0,1,0,0,0,0,Date,0,4096,A Unix epoch date time integer
+4,-,TXPower,0,1,0,0,0,0,None,0,4096,None
+5,-,IHUSpeed,0,0.1,0,0,0,0,None,0,4096,None
+6,-,RSSI_1,0,-1,0,0,0,0,Counts,0,4096,Signed 8 bit
+7,-,Mode,0,0,0,0,0,0,Enum,0,4096,SAFE:CREW:TELEM:X BAND RPT:APRS:SSTV:FS
+8,-,Battery,0,0.001,0,0,0,0,None,0,4096,Battery Voltage
+9,-,IHUTemp,0,0.1,0,0,0,0,None,0,4096,None
+10,-,Mode,0,1,0,0,0,0,None,0,4096,The spacecraft Mode
+11,-,FS_BYTES_PER_BLK,0,128,0,0,0,0,Counts,0,4096,The number of bytes per block in RED FS
+12,-,FS_FILE_NUMBER,-4,1,0,0,0,0,Counts,0,4096,The number of files in the FS excluding core OS folders
+13,-,SHTC3Temp,-45,0.002670288,0,0,0,0,None,0,4096,SHTC3 Temperature sensor
+14,-,SHTC3Humidity,0,0.001525879,0,0,0,0,None,0,4096,SHTC3 Humidity sensor
+15,-,LPS22Pressure,0,0.000244141,0,0,0,0,None,0,4096,LPS22 Pressure sensor
+16,-,LPS22Temp,0,0.01,0,0,0,0,None,0,4096,LPS22 Temperature of sensor
+17,-,IMUTemp,0,0.00390625,0,0,0,0,None,0,4096,Temperature of IMU = raw/256
+18,-,Acc,0,6.10E-05,0,0,0,0,Sint16,0,4096,Accelerometer is 2g full scale
+19,-,Gyro,0,0.000976563,0,0,0,0,Sint16,0,4096,Gyro scale for 32dps
+20,-,Mag,0,0.149975574,0,0,0,0,Sint16,0,4096,Mag is 4912 full scale
+21,-,AntMode,0,0,0,0,0,0,Enum,0,4096,MANUAL:AUTO:ORBIT
+22,-,ResetReason,0,0,0,0,0,0,Enum,0,4096,NONE:SHUTDOWN:REBOOT:RADIO:TNC:TNC LISTEN:RUN TWICE:RADIO REBOOT:TNC PS REBOOT:TNC REBOOT:SOFT:THERMAL
+23,-,LogLevel,0,0,0,0,0,0,Enum,0,4096,NONE:ERROR:WARN:INFO
+24,-,O2FromVolts,86.434,-0.0354,0,0,0,0,None,0,4096,O2 Conc from raw voltage as a percentage
+25,-,SensorState,0,0,0,0,0,0,Enum,0,4096,OFF:ON:ERR
+26,-,SPARE2,0,0,0,0,0,0,Counts,0,4096,SPARE
+27,-,O2Conc,0,0.01,0,0,0,0,Sint16,0,4096,O2 concentration as percentage
+28,-,SSTVMode,0,0,0,0,0,0,Enum,0,4096,MartinM1:MartinM2:ScottieS1:ScottieS2:Robot36:PasokonP3:PasokonP5:PasokonP7:PD90:PD120:PD160:PD180:PD240:PD290:Robot8BW:Robot24BW
+29,-,DivideBy100,0,0.01,0,0,0,0,None,0,4096,Divide by 100
+30,-,DivideBy100Offset,-20.48,0.01,0,0,0,0,None,0,4096,Divide by 100 with Offset
+31,-,Offset,-2048,1,0,0,0,0,Counts,0,4096,Offset
+32,-,DivideBy10Offset,-204.8,0.1,0,0,0,0,None,0,4096,Divide by 10 with Offset
+33,-,Status,0,0,0,0,0,0,Enum,0,4096,OFF:ON
+34,-,CommandStatus,0,0,0,0,0,0,Enum,0,4096,OFF:Carrier:DTMF/APRS
+35,-,FailStatus,0,0,0,0,0,0,Enum,0,4096,OK:FAIL
+36,-,AntStatus,0,0,0,0,0,0,Enum,0,4096,STOWED:DEPLOYED
+37,-,Times10,0,10.0,0,0,0,0,Counts,0,4096,Multiply by 10
+NOTES:,,,,,,,,,,,,
+Serial,Ignore,name,a,b,c,d,e,f,format,low limit,high limit,Comment
+Echo value = a + bx + cx^2 + dx^3 + ex^4 + fx^5,Echo value = a + bx + cx^2 + dx^3 + ex^4 + fx^5,,,,,,,,,,,
diff --git a/spacecraft/PacSatGround_0.46o/PacSatSim.commands b/spacecraft/PacSatGround_0.46o/PacSatSim.commands
new file mode 100644
index 00000000..4e7a8073
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46o/PacSatSim.commands
@@ -0,0 +1,37 @@
+# This is a list of commands that can be sent to the spacecraft
+# args are 16 bit except the special code 99099099 which is replaced with the unix time, or when special code MSB32BIT is used to combine two fields
+LIST, namespaces, None, Operations, Telem, File System
+LIST, IMAGE FOLDER, sstv_queue 1, sstv_queue 2, sstv_queue 3, sstv_queue 4, sstv_queue 5, sstv_queue 6, sstv_queue 7, sstv_queue 8, sstv_queue 9
+LIST, FOLDER, bin, lib, config, PACSAT dir, upload queue, wod queue, log queue, text queue, sensor wod queue, data1, data2, data3, data4, data5, data6, data7, data8, data9
+LIST, ENABLE, false, true
+LIST, ROLL AT STARTUP, false, true
+LIST, OVERWRITE, false, true
+LIST, FSK, false, true
+LIST, REMOVE ORPHAN FILES, false, true
+LIST, STATE, stop, start
+LIST, UPLINK MODE, Off, All stations, Command Stations Only
+LIST, FILENAME, use id for file name, user file name
+LIST, SHUTDOWN, reboot, shutdown
+LIST, RESET, reboot
+LIST, RATE, 1200, 9600
+LIST, FEC, Off, On
+LIST, FULL DUPLEX, false, true
+LIST, LOG NAME, Log, WOD
+LIST, LOG LEVEL, None, Error, Warnings, Info
+# Name, Name space, cmd, arg0, arg1, arg2, arg3, argName0, argName1, argName2, argName3, confirm, use reset/uptime, description
+#
+# PACSAT
+#
+Pacsat Broadcast,3,1,0,0,0,0,State,Period(sec),Timeout(sec),NONE,false,false,Enable or disable the Pacsat Broadcast module. The directory entries and individual files will be broadcast based on commands from ground stations.
+File Uploads,3,2,0,0,0,0,Uplink Mode,Period(sec),Timeout(sec),NONE,false,false,Enable or disable File Uploads. Limit file uploads to command stations that authenticate with a secret key.
+Install File,3,3,0,0,0,0,FileId,MSB32BIT,Folder,NONE,false,false,Copy a file from the PACSAT Directory to a folder and name it with a 4 byte hex name that matches the id or the user filename.
+Execute File,3,13,0,0,0,0,FileId,MSB32BIT,Arg1,Arg2,true,false,Execute a file on the ARISS-PI. The file must already be installed in the bin folder
+Delete File,3,4,0,0,0,0,FileId,MSB32BIT,Folder,NONE,true,false,Delete a file on the ARISS-PI. Typically this leaves the original copy in the PACSAT dir. To delete the original copy specify the PACSAT Dir folder
+Delete Folder Contents,3,5,0,0,0,0,Folder,Remove Orphan Files,NONE,NONE,true,false,Remove all files from the folder. The original files will remain in the PACSAT Directory unless deleted seperately. Orphan files are files in a folder without a corresponding Pacsat Dir file. NB: Deleting the entire Pacsat Dir is a desperate measure perhaps only useful in testing!
+Default File Expiry Period,3,6,0,0,0,0,Period(days),NONE,NONE,NONE,false,false,Set the default expiry period for files without a specific expiry time. The new value will be applied to all files.
+File Expiry Period,3,7,0,0,0,0,FileId,MSB32BIT,Date,MSB32BIT,false,false,Set the expiry date for a specific file`.
+Directory Maintenence Period,3,8,0,0,0,0,Period(s),NONE,NONE,NONE,false,false,Period between checks to each node in the directory for file expiry.
+Uplink queue maintenance Period,3,9,0,0,0,0,Period(s),NONE,NONE,NONE,false,false,Period to check the entire uplink queue for expired files.
+Int File Que Check Period,3,10,0,0,0,0,Period(s),NONE,NONE,NONE,false,false,Period to check the ingestion queues for newly generated internal files.
+Max File Size,3,11,0,0,0,0,Size(kb),NONE,NONE,NONE,false,false,Maximum size for an uploaded file
+Max Upload File Age,3,12,0,0,0,0,Age(days),NONE,NONE,NONE,false,false,Partially uploaded files not modified for more than this period will be removed from the upload queue.
diff --git a/spacecraft/PacSatGround_0.46o/PacSatSim.dat b/spacecraft/PacSatGround_0.46o/PacSatSim.dat
new file mode 100644
index 00000000..7b738eb6
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46o/PacSatSim.dat
@@ -0,0 +1,18 @@
+#Pacsat Telemetry Decoder Properties
+#Fri Feb 6 18:12:20 EST 2026
+numberOfLookupTables=0
+measurementsFileName=measurements.csv
+model=1
+layoutsUseToCallsignAsType=true
+numberOfLayouts=2
+layout0.filename=PacSatSim_rttelemetry.csv
+layout0.name=TLMP1
+layout1.filename=PacSatSim_rttelemetry.csv
+layout1.name=WOD
+passMeasurementsFileName=passmeasurements.csv
+name=CubeSatSim
+description=PacSatSim
+satId=3
+catalogNumber=0
+conversionCoefficients=PacSatSim-coef.csv
+layoutsUseBits=True
diff --git a/spacecraft/PacSatGround_0.46o/PacSatSim.properties b/spacecraft/PacSatGround_0.46o/PacSatSim.properties
new file mode 100644
index 00000000..8ff5be50
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46o/PacSatSim.properties
@@ -0,0 +1,21 @@
+#PacSat Ground Station Properties
+#Fri Feb 6 18:25:06 EST 2026
+sequence_num=3
+name=PacSatSim
+digiCallsign=AMSAT-1
+description=PacSatSim
+broadcastCallsign=AMSAT-11
+DIR_AGE=10
+bbsCallsign=AMSAT-12
+telemLayoutFile=PacSatSim.dat
+telem_server=tlm.amsatfox.org
+web_site_url=http://CubeSatSim.org
+show_system_files_on_dir_tab=false
+show_user_files=true
+supports_file_upload=true
+norad_id=30776
+psf_header_check_sums=false
+is_command_station=true
+secret_key=Not-required
+commandsFile=PacSatSim.commands
+echo_to_stdout=true
diff --git a/spacecraft/PacSatGround_0.46o/PacSatSim_conversion_curves.csv b/spacecraft/PacSatGround_0.46o/PacSatSim_conversion_curves.csv
new file mode 100644
index 00000000..30f05985
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46o/PacSatSim_conversion_curves.csv
@@ -0,0 +1,13 @@
+CurveName,a,bx,cx^2,dx^3,ex^4,fx^5,Description
+cubesatsim_voltage,0,0.01,0,0,0,0,Converts voltages read from the INA219 sensors
+cubesatsim_current,-2048,1,0,0,0,0,Converts positive and negative currents read from the INA219 sensors
+cubesatsim_temperature,0,0.1,0,0,0,0,Converts temperature of Pi
+cubesatsim_rotation,-2048,1,0,0,0,0,Converts positive and negative dps rotation
+cubesatsim_acceleration,-20.48,0.01,0,0,0,0,Converts positive and negative g acceleration
+cubesatsim_altitude,0,0.1,0,0,0,0,Converts altitude
+cubesatsim_pressure,0,1,0,0,0,0,Converts pressure
+cubesatsim_sensor1,0,1,0,0,0,0,Conversion of Sensor 1
+cubesatsim_sensor2,-2048,1,0,0,0,0,Conversion of Sensor 2
+cubesatsim_sensor3,-20.48,0.01,0,0,0,0,Conversion of Sensor 3
+cubesatsim_rpm,-204.8,0.1,0,0,0,0,Conversion of calculated RPM
+cubesatsim_rssi,-2048,1,0,0,0,0,Conversion of Received Signal Strength
diff --git a/spacecraft/PacSatGround_0.46o/PacSatSim_rttelemetry.csv b/spacecraft/PacSatGround_0.46o/PacSatSim_rttelemetry.csv
new file mode 100644
index 00000000..24298614
--- /dev/null
+++ b/spacecraft/PacSatGround_0.46o/PacSatSim_rttelemetry.csv
@@ -0,0 +1,63 @@
+62,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION
+0,long,timestamp,32,Sec,0,NONE,0,0,0,timestamp,This is the unix time in seconds
+1,int,Sensor 2,12,integer,2,Experiments,6,8,3,Sensor 2,STEM Payload Extra Sensor 2
+2,int,Sensor 3,12,integer,2,Experiments,6,9,3,Sensor 3,STEM Payload Extra Sensor 3
+3,float,BATT_V,12,V,29,Battery,4,1,3,Battery Voltage,INA219 Battery Voltage
+4,float,SatelliteXAxisAcceleration,12,g,30,+X Panel,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis
+5,float,SatelliteYAxisAcceleration,12,g,30,+Y Panel,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis
+6,float,SatelliteZAxisAcceleration,12,g,30,+Z Panel,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis
+7,int,BATT_I,12,mA,31,Battery,4,2,3,Battery Current,INA219 Battery Current
+8,float,Temperature,12,C,5,Experiments,6,2,3,BME280 Temp,BME280 STEM Payload sensor temperature
+9,float,posXv,12,V,29,+X Panel,7,1,3,Voltage,INA219 +X solar panel Voltage
+10,float,posYv,12,V,29,+Y Panel,8,1,3,Voltage,INA219 +Y solar panel Voltage
+11,float,posZv,12,V,29,+Z Panel,9,1,3,Voltage,INA219 +Z solar panel Voltage
+12,float,negXv,12,V,29,-X Panel,10,1,3,Voltage,INA219 -X solar panel Voltage
+13,float,negYv,12,V,29,-Y Panel,11,1,3,Voltage,INA219 -Y solar panel Voltage
+14,float,negZv,12,V,29,-Z Panel,12,1,3,Voltage,INA219 -Z solar panel Voltage
+15,int,posXi,12,mA,31,+X Panel,7,2,3,Current,INA219 +X solar panel Current
+16,int,posYi,12,mA,31,+Y Panel,8,2,3,Current,INA219 +Y solar panel Current
+17,int,posZi,12,mA,31,+Z Panel,9,2,3,Current,INA219 +Z solar panel Current
+18,int,negXi,12,mA,31,-X Panel,10,2,3,Current,INA219 -X solar panel Current
+19,int,negYi,12,mA,31,-Y Panel,11,2,3,Current,INA219 -Y solar panel Current
+20,int,negZi,12,mA,31,-Z Panel,12,2,3,Current,INA219 -Z solar panel Current
+21,float,BATT2_V,12,V,29,Battery2,5,1,3,Battery2 Voltage,INA219 Battery2 Voltage
+22,float,spin,12,rpm,32,Computer Software,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells
+23,int,Pressure,12,hPa,2,Experiments,6,3,3,BME280 Pressure,BME280 STEM Payload sensor pressure
+24,float,Altitude,12,m,37,Experiments,6,4,3,BME280 Altitude,BME280 STEM Payload sensor altitude
+25,float,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count
+26,float,rssi,12,dBm,31,Radio,1,1,3,RSSI,Received Signal Strength Indication
+27,float,IHUcpuTemp,12,C,5,Computer Hardware,2,1,3,IHU Temp (Pi),Internal temperature of IHU from Pi
+28,float,SatelliteXAxisAngularVelocity,12,dps,31,+X Panel,7,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around X Axis
+29,float,SatelliteYAxisAngularVelocity,12,dps,31,+Y Panel,8,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Y Axis
+30,float,SatelliteZAxisAngularVelocity,12,dps,31,+Z Panel,9,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Z Axis
+31,float,Humidity,12,%,5,Experiments,6,5,3,BME280 Humidity,BME280 Humidity
+32,int,BAT2_I,12,mA,31,Battery2,5,2,3,Battery2 Current,INA219 Battery2 Current
+33,float,DiodeTemp,12,C,32,Experiments,6,6,3,Diode Temp,STEM Payload Diode Temperature
+34,int,Sensor 1,12,integer,2,Experiments,6,7,3,Sensor 1,STEM Payload Extra Sensor 1
+35,float,STEMPayloadStatus,1,-,35,Experiments,6,1,0,STEM Payload Status, STEM Payload STEM Payload board failure Indicator
+36,float,SafeMode,1,-,33,Computer Software,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage)
+37,float,SimulatedTelemetry,1,-,33,Computer Software,3,4,0,Simulated Telemetry,Simulated Telemetry Indicator
+38,float,PayloadStatus1,1,-,35,NONE,6,8,0,Exp 3,STEM Payload status 1 failure indicator
+39,float,I2CBus0Failure,1,-,35,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator
+40,float,I2CBus1Failure,1,-,35,Computer Hardware,2,2,0,I2C Bus 1,I2C bus 1 failure indicator
+41,float,I2CBus3Failure,1,-,35,Computer Hardware,2,3,0,I2C Bus 3,I2C bus 3 failure indicator
+42,float,CameraFailure,1,-,35,Computer Hardware,2,4,0,Camera,Camera failure indicator
+43,int,GroundCommands,4,-,2,Computer Software,3,3,0,Ground Commands,Number of ground commands received
+44,float,RxAntenna,1,-,36,Radio,1,3,0,RX Antenna,Receive antenna status
+45,float,TxAntenna,1,-,36,Radio,1,2,0,TX Antenna,Transmit antenna status
+46,float,C2CStatus,2,-,34,Computer Software,3,5,0,Command Control, Command & Control Status
+47,float,ICR3VProt,12,V,0,NONE,7,2,3,3V Prot,ICR 3V Proteted
+48,float,ICR2dot5V,12,V,0,NONE,7,3,3,2.5V,ICR 2.5V
+49,float,ICR2dot5VProt,12,V,0,NONE,7,4,3,2.5V Prot,ICR 2.5V Protected
+50,float,rf6,12,-,0,NONE,0,0,0,None,None
+51,float,rf7,12,-,0,NONE,0,0,0,None,None
+52,float,MuxTest,12,V,0,NONE,7,5,3,Sensor Power,Sensor Power Voltage at the ICR
+53,float,LtVGACtl,12,V,0,NONE,1,4,3,VGA Control,Control Voltage to the Variable Gain Amplifier (VGA)
+54,float,pad,4,-,34,NONE,0,0,0,None,Unused
+55,float,IHUdiagData,32,-,18,NONE,3,2,0,Diagnostic Info,Diagnostic Data on IHU Performance
+56,float,pad1,1,-,0,NONE,0,0,0,NONE,Filler
+57,float,wodSize,8,000s,36,NONE,3,3,0,WOD Stored,Number of WOD data payloads kept for each of Science and Housekeeping. In hundreds
+58,float,swCmds,32,-,35,NONE,7,6,0,Diagnostic,ICR Diagnostic information
+59,float,hwCmdCnt,6,-,1,NONE,7,7,0,HW Command Count,Number of hardware commands since last reset
+60,float,swCmdCnt,6,-,1,NONE,7,8,0,SW Command Count,Number of software commands since last reset
+61,float,pad2,27,-,0,NONE,0,0,0,NONE,Filler
diff --git a/systemd/pacsatsim.service b/systemd/pacsatsim.service
new file mode 100644
index 00000000..d5163bd6
--- /dev/null
+++ b/systemd/pacsatsim.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=PacsatSim
+
+[Service]
+TimeoutStopSec=5
+ExecStart=/home/pi/CubeSatSim/pacsatsim.sh
+WorkingDirectory=/home/pi/CubeSatSim
+StandardOutput=inherit
+StandardError=inherit
+Restart=always
+User=pi
+
+[Install]
+WantedBy=default.target
diff --git a/systemd/transmit.service b/systemd/transmit.service
index ab6dd815..0b77ff50 100644
--- a/systemd/transmit.service
+++ b/systemd/transmit.service
@@ -8,7 +8,7 @@ WorkingDirectory=/home/pi/CubeSatSim
StandardOutput=inherit
StandardError=inherit
Restart=always
-User=root
+User=pi
[Install]
WantedBy=default.target
diff --git a/telem.c b/telem.c
index 1fc534a5..e8a498e4 100644
--- a/telem.c
+++ b/telem.c
@@ -15,7 +15,7 @@ int main(int argc, char *argv[]) {
}
}
- printf("CubeSatSim v2.1 INA219 Voltage and Current Telemetry\n");
+ printf("CubeSatSim v2.2 INA219 Voltage and Current Telemetry\n");
map[MINUS_X] = MINUS_Y;
map[PLUS_Z] = MINUS_X;
map[MINUS_Y] = PLUS_Z;
@@ -30,6 +30,9 @@ int main(int argc, char *argv[]) {
strcat(pythonConfigStr, " s");
char cmdbuffer[1000];
+
+ FILE *file2 = sopen(pythonVenv); // activate venv
+
FILE *file1 = sopen(pythonConfigStr); // try new function
fgets(cmdbuffer, 1000, file1);
if (debug == ON)
diff --git a/transmit.py b/transmit.py
index 10cee57d..75f59de0 100644
--- a/transmit.py
+++ b/transmit.py
@@ -1,16 +1,91 @@
#!/usr/bin/env python
-import RPi.GPIO as GPIO
-from RPi.GPIO import output
#import subprocess
import time
from time import sleep
#import os
import sys
from os import system
+from os import path
from PIL import Image, ImageDraw, ImageFont, ImageColor
import serial
import random
+import subprocess
+
+def output(pin, value):
+ command = "gpio -g write " + str(pin) + " " + str(value)
+ system(command)
+ print(command)
+
+def input(pin):
+ # command = "gpio -g read " + str(pin)
+ query = ["gpio", "-g", "read", str(pin)] # Read GPIO pin
+ command = "gpio -g read " + str(pin)
+ try:
+ result = subprocess.run(query, capture_output=True, text=True, check=True)
+# print(f"Command run was: {query}")
+# print("Sucess!")
+# print(f"Output of the command (stdout): {result.stdout}")
+# print(f"{command}: {result.stdout}")
+ return int(result.stdout)
+ except subprocess.CalledProcessError as e:
+# print(f"Command failed with return code: {e.returncode}")
+# print(f"Command run was: {e.cmd}")
+# print(f"Output of the command (stdout): {e.stdout}")
+# print(f"Error output of the command (stderr): {e.stderr}")
+ print(f"{command}: -1")
+ return -1
+
+def setup(pin, config):
+ if config == "in" or config == "out" or config == "up" or config == "down":
+ command = "gpio -g mode " + str(pin) + " " + config
+ system(command)
+ print(command)
+ else:
+ print(f"Unknown gpio setup configuration: {config}")
+
+def blink(times):
+ powerPin = 16
+ for i in range(times):
+ system("gpio -g write " + str(powerPin) + " 0") # blink two times
+ sleep(0.1)
+ system("gpio -g write " + str(powerPin) + " 1")
+ sleep(0.1)
+
+def sim_failure_check():
+ try:
+ global card
+ global cam_fail
+ global sim_mode
+ global sim_config
+ cam_fail = False
+ file = open("/home/pi/CubeSatSim/failure_mode.txt")
+ fail_mode = int(file.read(2))
+# print("Fail_mode: ")
+# print(fail_mode)
+ if (fail_mode == 11):
+ card = "Device" # Change audio so no FM audio plays
+ print("Failure mode no FM audio")
+ sim_mode = True
+ elif (fail_mode == 7):
+ cam_fail = True
+ print("Failure mode camera fail")
+ sim_mode = True
+ card = "Headphones"
+ elif (fail_mode == -1):
+ print("No failure mode")
+ card = "Headphones"
+ if sim_config:
+ sim_mode = True
+ else:
+ print("Other failure mode")
+ card = "Headphones"
+ sim_mode = True
+ except:
+ print("No failure mode")
+ card = "Headphones"
+ if sim_config:
+ sim_mode = True
def battery_saver_check():
try:
@@ -27,9 +102,9 @@ def battery_saver_check():
def blink(times):
powerPin = 16
for i in range(times):
- GPIO.output(powerPin, 0) # blink two times
+ output(powerPin, 0) # blink
sleep(0.1)
- GPIO.output(powerPin, 1)
+ output(powerPin, 1)
sleep(0.1)
def increment_mode():
@@ -76,13 +151,11 @@ def increment_mode():
file.close()
print(".mode file written")
- GPIO.setwarnings(False)
- GPIO.output(txLed, 0)
- GPIO.output(powerPin, 0)
+ output(txLed, 0)
+ output(powerPin, 0)
print("sudo reboot -h now")
- GPIO.setwarnings(False)
- GPIO.setup(powerPin, GPIO.OUT)
- GPIO.output(powerPin, 0);
+ setup(powerPin, "out")
+ output(powerPin, 0);
# system("reboot -h now")
# release = True;
@@ -95,13 +168,23 @@ def increment_mode():
print("can't write to .mode file")
def camera_photo():
+ global cam_fail
+ global os_status
+ sim_failure_check()
system("sudo rm /home/pi/CubeSatSim/camera_out.jpg")
stored_image = False
try:
- system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") # > /dev/null 2>&1")
+ if os_status == "bookworm":
+ system("rpicam-still -o /home/pi/CubeSatSim/camera_out.jpg --width 320 --height 256") # > /dev/null 2>&1")
+ else:
+ system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256")
f = open("/home/pi/CubeSatSim/camera_out.jpg")
f.close()
print("Photo taken")
+ if (cam_fail == True):
+ system("cp /home/pi/CubeSatSim/sstv//sstv_image_2_320_x_256.jpeg /home/pi/CubeSatSim/camera_out.jpg")
+ print("Using stored image")
+ stored_image = True
except:
system("cp /home/pi/CubeSatSim/sstv//sstv_image_2_320_x_256.jpeg /home/pi/CubeSatSim/camera_out.jpg")
print("Using stored image")
@@ -123,14 +206,18 @@ def camera_photo():
img = Image.open(file)
draw = ImageDraw.Draw(img)
# draw.text((10, 10), callsign, font=font2, fill='white')
- # draw.text((120, 10), telem_string, font=font2, fill='white')
+ # draw.text((120, 10), telem_string, font=font2, fill='white')
draw.text((12, 12), callsign, font=font1, fill='black')
draw.text((10, 10), callsign, font=font1, fill='white')
- draw.text((122, 12), telem_string, font=font2, fill='black')
- draw.text((120, 10), telem_string, font=font2, fill='white')
+ draw.text((112, 12), telem_string, font=font2, fill='black') # was 122
+ draw.text((110, 10), telem_string, font=font2, fill='white') # was 120
img.save(file)
-print("CubeSatSim v2.1 transmit.py starting...")
+ return True
+ else:
+ return False
+
+print("CubeSatSim v2.2 transmit.py starting...")
pd = 21
ptt = 20
@@ -141,57 +228,45 @@ powerPin = 16
command_tx = True
-GPIO.setmode(GPIO.BCM)
-GPIO.setwarnings(False)
-GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)
-GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP)
-GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP)
-GPIO.setup(txc_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
-GPIO.setup(green, GPIO.OUT)
-GPIO.output(powerPin, 1)
+setup(13, "up")
+setup(12, "up")
+setup(27, "up")
+setup(txc_pin, "up")
+setup(green, "out")
+output(powerPin, 1)
transmit = False
txLed = 27
-txLedOn = 1
-txLedOff = 0
-if GPIO.input(12) == False:
+if input(12) == False:
print("LPF present")
transmit = True
else:
print("No LPF")
+setup(txLed, "out")
-# GPIO.setup(txLed, GPIO.OUT)
-# output(txLed, txLedOff)
-
-GPIO.setmode(GPIO.BCM) # Repeat to make LED work on Pi 4
-GPIO.setwarnings(False)
-GPIO.setup(txLed, GPIO.OUT)
-
-GPIO.setup(pd, GPIO.OUT)
+setup(pd, "out")
#output(pd, 1)
output(pd, 0)
-GPIO.setup(ptt, GPIO.OUT)
-output (ptt, 1)
+setup(ptt, "out")
+output(ptt, 1)
txc = False
-if GPIO.input(txc_pin) == False:
+if input(txc_pin) == False:
print("TXC is present")
- txc = True;
+ txc = True
else:
print("TXC not present")
-# txc = False # forcing it off
-output(txLed, txLedOn)
+# False # forcing it off
+output(txLed, 1)
sleep(1)
-output(txLed, txLedOff)
+output(txLed, 0)
battery_saver_check()
-# print(txLedOn)
+# print(1)
print(txLed)
-# GPIO.setup(27, GPIO.OUT)
-# GPIO.output(27, 0)
debug_mode = 0 # change to 1 to debug transmit
@@ -212,17 +287,17 @@ if __name__ == "__main__":
print(transmit)
- uptime_time = 45 # 45 second boot time if Pi Zero
+ uptime_time = 55 # 55 second boot time if Pi Zero
try:
f = open("/home/pi/CubeSatSim/pi_zero2", "r")
f.close()
print("Pi Zero 2 detected!")
- uptime_time = 20 # 20 second boot time if Pi Zero 2
+ uptime_time = 30 # 30 second boot time if Pi Zero 2
except:
print("Pi Zero 2 not detected")
try:
- system("cat /proc/uptime > /home/pi/CubeSatSim/uptime")
+ system("sudo cat /proc/uptime > /home/pi/CubeSatSim/uptime")
file = open("/home/pi/CubeSatSim/uptime")
up = file.read().split(" ")[0]
print(up)
@@ -260,6 +335,9 @@ if __name__ == "__main__":
print("Can't open beacon_off file, defaulting to False")
print("Command_tx: ")
print(command_tx)
+
+ if (mode != "p") or (command_tx == False):
+ system("sudo systemctl stop pacsatsim")
try:
file = open("/home/pi/CubeSatSim/command_count.txt", "r")
@@ -282,22 +360,35 @@ if __name__ == "__main__":
tx = '434.9000'
rx = '435.0000'
txr = '144.9000'
+ sim_mode = False
+ sim_config = False
+ hab_mode = False
try:
file = open("/home/pi/CubeSatSim/sim.cfg")
# callsign = file.readline().split(" ")[0]
config = file.readline().split()
callsign = config[0]
- if len(config) > 5:
- sq = config[5]
- if (mode == 'p') or (mode == 'P'):
- sq = 0 # turn off squelch for Pacsat
- print(sq)
+ if len(config) > 4:
+ if config[4] == 'y' or config[4] == 'yes':
+ sim_mode = True
+ sim_config = True
+ print("Simulated telemetry mode is configured")
+ else:
+ try:
+ if path.isfile("/home/pi/CubeSatSim/sim_mode_auto"):
+ print("Simulated telemetry mode automatically turned on!")
+ sim_mode = True
+ sim_config = True
+ except:
+ if (debug_mode == 1):
+ print("/home/pi/CubeSatSim/sim_mode_auto not found")
+ if len(config) > 5:
+ if (mode != 'p') and (mode != 'P'): # squelch off for Pacsat
+ sq = config[5]
+ print(f'squelch: {sq}')
if len(config) > 6:
txf = float(config[6])
-# print(txf)
-# print( "{:.4f}".format(txf))
-
if (mode == 'e'):
txr = (txf - 290.0) # - 0.1 # Cross Band Repeater mode transmit frequency in 2m band
tx = "{:.4f}".format(txr)
@@ -310,6 +401,10 @@ if __name__ == "__main__":
# print( "{:.4f}".format(rxf))
rx = "{:.4f}".format(rxf)
print(rx)
+ if len(config) > 8:
+ if config[8] == 'y' or config[8] == 'yes':
+ hab_mode = True
+ print("Balloon (HAB) mode is configured.")
if len(config) > 9:
rxpl = float(config[9])
# print(rxpl)
@@ -338,34 +433,66 @@ if __name__ == "__main__":
print("Can't read callsign from sim.cfg file, defaulting to AMSAT")
file.close()
+ no_command = True
try:
f = open("/home/pi/CubeSatSim/command_control", "r")
+ no_command = False
f.close()
- GPIO.setmode(GPIO.BCM)
- GPIO.setwarnings(False)
- GPIO.setup(squelch, GPIO.IN, pull_up_down=GPIO.PUD_UP) ## pull up in case pin is not connected
- if GPIO.input(squelch) == False:
- print("squelch not set correctly, no command input!")
- no_command = True
- else:
- print("command and control is activated")
- no_command = False
-# system("/home/pi/CubeSatSim/command &")
- system("sudo systemctl start command")
+# setup(squelch, "up") ## pull up in case pin is not connected
+# if input(squelch) == False:
+# print("squelch not set correctly, no command input!")
+# else:
+# if (mode != 'n') and (mode != 'x'):
+# print("command and control is activated")
+# no_command = False
+# system("sudo systemctl start command")
+# else:
+# print("Command and control not activated since Transmit Commands mode")
+# txc = True # Transmit commands only works with FM transceiver, so bypass Battery Saver if activated
except:
print("command and control not activated")
- no_command = True
-
+
print(callsign)
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4
- print(txLed)
- print(txLedOn)
- GPIO.setup(txLed, GPIO.OUT)
+ query = ["grep", "VERSION_CODENAME=bullseye", "/etc/os-release"]
+ try:
+ result = subprocess.run(query, capture_output=True, text=True, check=True)
+ print(f"Command run was: {query}")
+ os_status = result.stdout.strip()
+ print(f"Output of the command (stdout): {os_status}")
+ except subprocess.CalledProcessError as e:
+# print(f"Command failed with return code: {e.returncode}")
+ print(f"Command run was: {e.cmd}")
+ os_status = e.stdout.strip()
+ print(f"Output of the command (stdout): {e.stdout}")
+# print(f"Error output of the command (stderr): {e.stderr}")
+ if os_status != "VERSION_CODENAME=bullseye":
+ os_status = "bookworm"
+ else:
+ os_status = "bullseye"
+ print (os_status)
+
card = "Headphones" # default using pcm audio output of Pi Zero
# card = "Device" # using USB sound card for audio output
- if (mode != 'e'):
+ query = ["sudo", "systemctl", "is-active", "gpsd.socket"]
+ try:
+ result = subprocess.run(query, capture_output=True, text=True, check=True)
+ print(f"Command run was: {query}")
+ gpsd_status = result.stdout.strip()
+ print(f"Output of the command (stdout): {gpsd_status}")
+ except subprocess.CalledProcessError as e:
+# print(f"Command failed with return code: {e.returncode}")
+ print(f"Command run was: {e.cmd}")
+ gpsd_status = e.stdout.strip()
+ print(f"Output of the command (stdout): {e.stdout}")
+# print(f"Error output of the command (stderr): {e.stderr}")
+
+ if (mode != 'e'):
+
+ if (gpsd_status == "active"):
+ print("Stopping gpsd.socket")
+ system("sudo systemctl stop gpsd.socket")
print("Programming FM module!\n");
output(pd, 1)
output (ptt, 1)
@@ -384,49 +511,95 @@ if __name__ == "__main__":
except:
print("Error in serial write")
output(pd, 0)
-
- if (((mode == 'a') or (mode == 'b') or (mode == 'f') or (mode == 's') or (mode == 'j')) and (command_tx == True) and (skip == False)) or ((mode == 'e') and (command_tx == True)): # battery_saver_mode
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
- print("Transmit CW ID")
- if (no_command):
+ if (gpsd_status == "active"):
+ print("Restarting gpsd.socket")
+ system("sudo systemctl restart gpsd.socket")
+
+ sim_failure_check()
+ if (hab_mode == True) and (mode == 'a'):
+ print("Don't transmit CW ID since APRS HAB mode is active")
+ else:
+ if (((mode == 'a') or (mode == 'b') or (mode == 'f') or (mode == 's') or (mode == 'j') or (mode == 'p') or (mode == 'P')) and (command_tx == True) and (skip == False)) or ((mode == 'e') and (command_tx == True)): # battery_saver_mode
+ output(txLed, 1)
+ print("Transmit CW ID")
+ status = ""
+ if not no_command:
+ status = status + " C"
+ if sim_mode:
+ status = status + " S"
if (debug_mode == 1):
- system("echo 'hi hi de " + callsign + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3")
+ system("echo 'hi hi de " + callsign + status + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3")
else:
- system("echo 'hi hi de " + callsign + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
+ system("echo 'hi hi de " + callsign + status + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
+ output(txLed, 0)
+
+ sleep(1)
else:
- if (debug_mode == 1):
- system("echo 'hi hi de " + callsign + " C" + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3")
- else:
- system("echo 'hi hi de " + callsign + " C" + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
-
-
- output(txLed, txLedOff)
-
- sleep(1)
- else:
- print("Don't transmit CW ID since command_tx is False or APRS mode or change of mode")
-
- if (transmit):
+ print("Don't transmit CW ID since command_tx is False or APRS mode or change of mode")
+
+ if (transmit):
# print 'Length: ', len(sys.argv)
# if (len(sys.argv)) > 1:
# print("There are arguments!")
- if (mode == 'a') or (mode == 'x') or (mode == 'n'):
+ if (mode == 'a') or (mode == 'x') or (mode == 'n') or (mode == 'p') or (mode == 'P'):
# command_control_check()
output(pd, 1)
output(ptt, 1)
if (mode == 'a'):
print("AFSK")
+ elif (mode == 'p') or (mode == 'P'):
+ if (mode == 'P'):
+ print("Pacsat Ground Station")
+ else:
+ print("Pacsat")
+ if (command_tx == True):
+ system("sudo systemctl restart pacsatsim")
+ print("Starting PacSatSim")
+ output(txLed, 0)
+ print("0")
+ rpitx = "arecord -D plughw:CARD=Loopback,DEV=1 -f S16_LE -r 48000 -c 1 | csdr convert_s16_f | csdr gain_ff 4000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1 &"
+ stop_rpitx = "sudo killall -9 rpitx && sudo killall -9 arecord && sudo rpitx -m RF -f 434.9e3 > /dev/null 2>&1"
+ if not txc:
+ print("txc is:")
+ print(txc)
+ system(stop_rpitx)
+ system(rpitx)
+ print("Safe Mode!!")
+ while (True):
+ if (txc):
+ sleep(0.1)
+ while (input(ptt) != 0):
+ sleep(0.2)
+ output(txLed, 1)
+# print("1")
+ while (input(ptt) != 1):
+ sleep(0.2)
+ output(txLed, 0)
+# print("0")
+ else:
+# sleep(0.1)
+ while (input(17) == 0):
+ sleep(0.05)
+## system(rpitx)
+ output(txLed, 1)
+# print("1")
+ while (input(17) == 1):
+ sleep(0.05)
+## system(stop_rpitx)
+ output(txLed, 0)
+# print("0")
+
+# sleep(10)
+
else:
- GPIO.output(powerPin, 0)
print("Transmit APRS Commands")
+ system("sudo systemctl stop command")
# while True:
# sleep(0.1)
- if (mode != 'n'):
- system("touch /home/pi/CubeSatSim/ready")
+# if (mode != 'n'):
+# system("touch /home/pi/CubeSatSim/ready")
while True:
try:
@@ -437,20 +610,19 @@ if __name__ == "__main__":
system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1")
system("cat /home/pi/CubeSatSim/t.txt")
if (command_tx == True):
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
+ output(txLed, 1)
# output(pd, 1)
# output (ptt, 0)
# sleep(.1)
#
# battery_saver_check()
if (txc):
+ sim_failure_check()
# output(pd, 1)
sleep(0.1) # add delay before transmit
output (ptt, 0)
sleep(0.3) # add even more time at start
- system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/telem.wav")
+ system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/telem.wav")
sleep(0.2) # add more time at end
output (ptt, 1)
# output(pd, 0)
@@ -464,7 +636,7 @@ if __name__ == "__main__":
sleep(0.1)
# output (ptt, 1)
# output(pd, 0)
- output(txLed, txLedOff)
+ output(txLed, 0)
system("sudo rm /home/pi/CubeSatSim/ready")
f.close()
@@ -472,11 +644,12 @@ if __name__ == "__main__":
print("Ready for next packet!")
sleep(0.5)
+
except:
# command_control_check()
sleep(1)
elif (mode == 'm'):
- system("touch /home/pi/CubeSatSim/cwready")
+# system("touch /home/pi/CubeSatSim/cwready")
print("CW")
while True:
# command_control_check()
@@ -493,11 +666,10 @@ if __name__ == "__main__":
system(command)
## chan = chan + 1
if (command_tx == True):
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
+ output(txLed, 1)
if (txc):
+ sim_failure_check()
# output (pd, 1)
sleep(0.3)
output (ptt, 0)
@@ -509,8 +681,8 @@ if __name__ == "__main__":
if (debug_mode == 1):
system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3")
else:
- system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
- output(txLed, txLedOff)
+ system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
+ output(txLed, 0)
# command_control_check()
sleep(2)
@@ -529,7 +701,10 @@ if __name__ == "__main__":
# from pysstv.sstv import SSTV
# camera = PiCamera()
print("Testing for camera")
- system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256")
+ if os_status == "bookworm":
+ system("rpicam-still -o /home/pi/CubeSatSim/camera_out.jpg --width 320 --height 256") # > /dev/null 2>&1")
+ else:
+ system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256")
f = open("/home/pi/CubeSatSim/camera_out.jpg")
f.close()
print("Camera present")
@@ -541,7 +716,7 @@ if __name__ == "__main__":
camera_present = 0
# while 1:
- output(txLed, txLedOff)
+ output(txLed, 0)
# output (ptt, 1)
# output(pd, 0)
if (camera_present == 1):
@@ -553,12 +728,11 @@ if __name__ == "__main__":
if (command_tx == True):
print ("Sending SSTV image")
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
+ output(txLed, 1)
# battery_saver_check()
if (txc):
+ sim_failure_check()
# output(pd, 1)
output (ptt, 0)
system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav")
@@ -570,42 +744,14 @@ if __name__ == "__main__":
else:
system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
- output(txLed, txLedOff)
+ output(txLed, 0)
# sleep(1)
except:
print("image 2 did not load - copy from CubeSatSim/sstv directory")
while 1:
# command_control_check()
- camera_photo()
-## system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") # > /dev/null 2>&1")
-## print("Photo taken")
-##
-## file='/home/pi/CubeSatSim/camera_out.jpg'
-## font1 = ImageFont.truetype('DejaVuSerif.ttf', 20)
-## font2 = ImageFont.truetype('DejaVuSerif-Bold.ttf', 16)
-##
-## try:
-## filep = open("/home/pi/CubeSatSim/telem_string.txt")
-## telem_string = filep.readline()
-## except:
-## telem_string = ""
-## if (debug_mode == 1):
-## print("Can't read telem_string.txt")
-## print(telem_string)
-##
-## img = Image.open(file)
-## draw = ImageDraw.Draw(img)
-# draw.text((10, 10), callsign, font=font2, fill='white')
-# draw.text((120, 10), telem_string, font=font2, fill='white')
-## draw.text((12, 12), callsign, font=font1, fill='black')
-## draw.text((10, 10), callsign, font=font1, fill='white')
-## draw.text((122, 12), telem_string, font=font2, fill='black')
-## draw.text((120, 10), telem_string, font=font2, fill='white')
-## img.save(file)
-
-# command_control_check()
-
+ camera_photo()
system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/camera_out.jpg")
system("sudo rm /home/pi/CubeSatSim/camera_out.jpg > /dev/null 2>&1")
@@ -613,12 +759,12 @@ if __name__ == "__main__":
if (command_tx == True):
print ("Sending SSTV image")
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
+ output(txLed, 1)
# battery_saver_check()
if (txc):
+# print(card)
+ sim_failure_check()
# output(pd, 1)
output (ptt, 0)
system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/camera_out.jpg.wav")
@@ -630,7 +776,7 @@ if __name__ == "__main__":
else:
system("cat /home/pi/CubeSatSim/camera_out.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
- output(txLed, txLedOff)
+ output(txLed, 0)
# output (ptt, 1)
# output(pd, 0)
@@ -649,13 +795,12 @@ if __name__ == "__main__":
if (command_tx == True):
print ("Sending SSTV image")
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
+ output(txLed, 1)
# battery_saver_check()
if (txc):
+ sim_failure_check()
# output(pd, 1)
output (ptt, 0)
system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav")
@@ -667,7 +812,7 @@ if __name__ == "__main__":
else:
system("cat /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
- output(txLed, txLedOff)
+ output(txLed, 0)
# output (ptt, 1)
# output(pd, 0)
sleep(1)
@@ -686,12 +831,11 @@ if __name__ == "__main__":
if (command_tx == True):
print ("Sending SSTV image")
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
+ output(txLed, 1)
# battery_saver_check()
if (txc):
+ sim_failure_check()
# output(pd, 1)
output (ptt, 0)
system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav")
@@ -703,7 +847,7 @@ if __name__ == "__main__":
else:
system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1")
- output(txLed, txLedOff)
+ output(txLed, 0)
# output (ptt, 1)
# output(pd, 0)
sleep(10)
@@ -716,13 +860,12 @@ if __name__ == "__main__":
if (command_tx == True):
# command_control_check()
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
+ output(txLed, 1)
# battery_saver_check()
if (txc):
+ sim_failure_check()
# output(pd, 1)
output (ptt, 0)
system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv.wav")
@@ -731,7 +874,7 @@ if __name__ == "__main__":
else:
sleep(60)
- output(txLed, txLedOff)
+ output(txLed, 0)
# output (ptt, 1)
# output(pd, 0)
sleep(10)
@@ -745,9 +888,6 @@ if __name__ == "__main__":
print("turn on FM rx")
output(pd, 1)
output(ptt, 1)
-
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4
- GPIO.setup(txLed, GPIO.OUT)
if (command_tx == True):
# system("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | sudo /home/pi/rpitx/sendiq -i /dev/stdin -s 96000 -f 434.9e6 -t float &")
@@ -757,20 +897,16 @@ if __name__ == "__main__":
print("Initial image_id: " + str(image_id) + "\n")
while 1:
# print ("LED on")
- output(txLed, txLedOff)
+ output(txLed, 0)
sleep(0.4)
# if (command_tx == False):
-# output(txLed, txLedOn)
+# output(txLed, 1)
# sleep(0.03)
-# output(txLed, txLedOff)
+# output(txLed, 0)
# command_control_check()
if (command_tx == True):
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
-# print(txLed)
-# print(txLedOn)
+ output(txLed, 1)
if (mode == 'b'):
sleep(4.2)
@@ -806,11 +942,7 @@ if __name__ == "__main__":
print("turn on FM rx")
output(pd, 1)
output(ptt, 1)
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4
- GPIO.setup(txLed, GPIO.OUT)
-# GPIO.setup(powerPin, GPIO.OUT)
- GPIO.setup(squelch, GPIO.IN, pull_up_down=GPIO.PUD_UP) ## pull up in case pin is not connected
-# GPIO.output(powerPin, 1) # was 0
+ setup(squelch, "up") ## pull up in case pin is not connected
# txf = float(tx) - 288.9
# print("Transmit frequency: ",txf)
if (command_tx != True):
@@ -818,18 +950,16 @@ if __name__ == "__main__":
print("Ready to detect carrier")
while True:
- if (GPIO.input(squelch) == False) and (command_tx == True):
+ if (input(squelch) == False) and (command_tx == True):
print("Carrier detected, starting repeater")
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
- system("sudo nc -l 8011 | csdr convert_i16_f | csdr gain_ff 16000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1 &")
+ output(txLed, 1)
+ system("sudo nc -l 8011 | csdr convert_i16_f | csdr gain_ff 4000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1 &")
sleep(0.5)
system("sudo arecord -D shared_mic -r48000 -fS16_LE -c1 | nc localhost 8011 &")
- while (GPIO.input(squelch) == False):
+ while (input(squelch) == False):
sleep(1)
print("No carrier detected, stopping repeater")
- output(txLed, txLedOff)
+ output(txLed, 0)
system("sudo rpitx -i null > /dev/null 2>&1")
system("sudo killall -9 arecord > /dev/null 2>&1")
system("sudo killall -9 nc > /dev/null 2>&1")
@@ -845,26 +975,19 @@ if __name__ == "__main__":
output(pd, 1)
output(ptt, 1)
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4
- GPIO.setup(txLed, GPIO.OUT)
-
if (command_tx == True):
system("sudo nc -l 8080 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 &")
print("Turning LED on/off and listening for carrier")
while 1:
- output(txLed, txLedOff)
+ output(txLed, 0)
sleep(0.4)
# if (command_tx == False):
-# output(txLed, txLedOn)
+# output(txLed, 1)
# sleep(0.03)
-# output(txLed, txLedOff)
+# output(txLed, 0)
# command_control_check()
if (command_tx == True):
- GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4
- GPIO.setup(txLed, GPIO.OUT)
- output(txLed, txLedOn)
-# print(txLed)
-# print(txLedOn)
+ output(txLed, 1)
sleep(4.2)
else:
print("No Low Pass Filter so no telemetry transmit. See http://cubesatsim.org/wiki for instructions on how to build the LPF.")
diff --git a/update b/update
deleted file mode 100755
index c2e2ffbe..00000000
--- a/update
+++ /dev/null
@@ -1,452 +0,0 @@
-#!/bin/bash
-
-echo -e "\nupdate script for CubeSatSim v2.1\n"
-
-FLAG=0
-checkout=0
-
-if [ -z "$1" ] ; then
- checkout=0
-else
- checkout=1
- branch="$1"
- echo -n "changing to branch "
- echo $branch
- FLAG=1
-fi
-
-if [ "$1" = "n" ] ; then
- noreboot=1
-else
- noreboot=0
-fi
-
-# echo "No reboot"
-# echo $noreboot
-
-sudo rm /home/pi/CubeSatSim/morse.wav /home/pi/CubeSatSim/id.txt /home/pi/CubeSatSim/cw.txt > /dev/null 2>&1
-
-if [ "$1" = "u" ]; then
-
-# sudo apt-get update && sudo apt-get dist-upgrade -y
- sudo apt-get update -y
-
- sudo apt-get install -y git libasound2-dev i2c-tools build-essential libgd-dev libmagic-dev python3-pip minicom
-
-fi
-
-# sudo apt-get install -y python3-smbus libusb-1.0
-
-sudo sed -i 's/update.sh/update /g' /etc/motd
-
-sudo sed -i 's/installed and/installed\nand/g' /etc/motd
-
-sudo sed -i 's/more information/more\ninformation/g' /etc/motd
-
-sudo sed -i 's/update to/update\nto/g' /etc/motd
-
-sudo sed -i 's/console=tty1 r/console=tty1 maxcpus=1 r/g' /boot/cmdline.txt # single core if Pi Zero 2
-
-sudo sed -i 's/maxcpus=2/maxcpus=1/g' /boot/cmdline.txt # single core if Pi Zero 2
-
-cd /home/pi/CubeSatSim
-
-git pull --no-rebase > .updated
-
-if [ $checkout -eq 1 ]; then
- git checkout $branch
- git pull --no-rebase > .updated
-fi
-
-make debug
-
-FILE=/home/pi/CubeSatSim/command_tx
-if [ -f "$FILE" ]; then
- echo "$FILE exists."
-else
- echo "creating $FILE"
- echo "True\n" > /home/pi/CubeSatSim/command_tx
-fi
-
-FILE=/home/pi/CubeSatSim/command_count.txt
-if [ -f "$FILE" ]; then
- echo "$FILE exists."
-else
- echo "creating $FILE"
- echo "0\n" > /home/pi/CubeSatSim/command_count.txt
-fi
-
-if [[ $(diff systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service) ]]; then
- echo "changed cubesatsim.service."
- sudo cp /home/pi/CubeSatSim/systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service
- FLAG=1
-else
- echo "no changes to cubesatsim.service."
-fi
-
-FILE=/etc/systemd/system/rpitx.service
-if [ -f "$FILE" ]; then
- sudo systemctl disable rpitx
- sudo rm /etc/systemd/system/rpitx.service
-fi
-
-FILE=/etc/systemd/system/transmit.service
-if [ -f "$FILE" ]; then
- if [[ $(diff systemd/transmit.service /etc/systemd/system/transmit.service) ]]; then
- echo "changed transmit.service."
- sudo cp /home/pi/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service
- FLAG=1
- else
- echo "no change to transmit.service."
- fi
-else
- echo "creating transmit.service."
- sudo cp /home/pi/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service
- FLAG=1
-fi
-
-FILE=/etc/systemd/system/command.service
-if [ -f "$FILE" ]; then
- if [[ $(diff systemd/command.service /etc/systemd/system/command.service) ]]; then
- echo "changed command.service."
- sudo cp /home/pi/CubeSatSim/systemd/command.service /etc/systemd/system/command.service
- FLAG=1
- else
- echo "no change to command.service."
- fi
-else
- echo "creating command.service."
- sudo cp /home/pi/CubeSatSim/systemd/command.service /etc/systemd/system/command.service
- sudo systemctl enable command
- FLAG=1
-fi
-
-FILE=/etc/asound.conf
-if [ -f "$FILE" ]; then
- if [[ $(diff /home/pi/CubeSatSim/asound.conf /etc/asound.conf) ]]; then
- echo "changed /etc/asound.conf."
- sudo cp /home/pi/CubeSatSim/asound.conf /etc/asound.conf
- FLAG=1
- else
- echo "no change to /etc/asound.conf."
- fi
-else
- echo "creating /etc/asound.conf."
- sudo cp /home/pi/CubeSatSim/asound.conf /etc/asound.conf
- FLAG=1
-fi
-
-FILE=/home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg
-if [ ! -f "$FILE" ]; then
- echo "Copying SSTV image 1."
- cp /home/pi/CubeSatSim/sstv/sstv_image_1_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg
-fi
-
-FILE=/home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg
-if [ ! -f "$FILE" ]; then
- echo "Copying SSTV image 2."
- cp /home/pi/CubeSatSim/sstv/sstv_image_2_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg
-fi
-
-grep 'update' /home/pi/CubeSatSim/.updated
-if [[ $(grep 'update' /home/pi/CubeSatSim/.updated) ]]; then
- echo "update script updated, running again"
- /home/pi/CubeSatSim/update
-fi
-
-if [ ! -d "/home/pi/PiSSTVpp" ]; then
-
-# sudo apt-get update && sudo apt-get dist-upgrade -y
- sudo apt-get update -y
-
- sudo apt-get install -y python-picamera python3-picamera build-essential libgd-dev libmagic-dev
-
-
- cd
-
- git clone https://github.com/alanbjohnston/PiSSTVpp.git
-
- cd PiSSTVpp
-
- make pisstvpp
-
- cd
-
-
- sudo raspi-config nonint do_camera 0
-
-
- FILE=/home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg
- if [ ! -f "$FILE" ]; then
- echo "Copying SSTV image 1."
- cp /home/pi/CubeSatSim/sstv/sstv_image_1_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg
- fi
-
- FILE=/home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg
- if [ ! -f "$FILE" ]; then
- echo "Copying SSTV image 2."
- cp /home/pi/CubeSatSim/sstv/sstv_image_2_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg
- fi
-
-# echo "You need to reboot to complete this update. Reboot now (y/n)?"
-
-# read -r ANS
-
-# if [ "$ANS" = "y" ]; then
-
-# sudo reboot now
-
-# else
-
-# echo "The CubeSatSim software may not work correctly until you reboot."
-
-# fi
-
-fi
-
-if [ ! -d "/home/pi/rpitx" ]; then
-
- cd
- git clone https://github.com/alanbjohnston/rpitx.git
- cd rpitx
- ./install.sh
- cd
-else
-
- if [[ $(grep 'SYNCWITHPWM' /home/pi/rpitx/src/librpitx/src/fskburst.h) ]]; then
- echo "rpitx library already updated"
- else
- echo "updating rpitx"
- cd /home/pi/rpitx
- git pull
- ./update.sh
- cd
- fi
-fi
-
-if [ ! -d "/home/pi/WiringPi" ]; then
-
- cd
-
- git clone https://github.com/PinkFreud/WiringPi
- cd WiringPi
- ./build debian
-
- sudo dpkg -i debian-template/wiringpi-2.61-1.deb
-
- cd
-
- cd CubeSatSim
- make debug
-
- FLAG=1
-
- cd
-
-fi
-
-if [ ! -d "/home/pi/ssdv" ]; then
-
- echo "Installing SSDV for FUNcube mode"
- cd
- git clone https://github.com/alanbjohnston/ssdv.git # install ssdv for FUNcube images
- cd ssdv
- make
- cd
- FLAG=1
-fi
-
-if [ ! -d "/home/pi/fctelem" ]; then
- echo "Installing fctelem binary v0.2 for FUNcube mode"
- cd
- mkdir /home/pi/fctelem
- mkdir /home/pi/fctelem/public_html
- cd fctelem
- wget https://github.com/alanbjohnston/go/releases/download/v0.2/fctelem.zip
- unzip fctelem.zip
- FLAG=1
-elif [ ! -f "/home/pi/fctelem/v0.2" ]; then
- echo "Updating fctelem binary to version v0.2 for FUNcube mode"
- cd
- cd /home/pi/fctelem
- sudo mv fctelem fctelem.bk
- sudo mv fcdecode.conf fcdecode.conf.bk
- sudo mv fctelem.zip fctelem.zip.1
- wget https://github.com/alanbjohnston/go/releases/download/v0.2/fctelem.zip
- unzip fctelem.zip
- FLAG=1
-fi
-
-if [ ! -f "/home/pi/fcdctl/fcdctl" ]; then
- echo "Installing fcdctl to set FUNcubeDongle Pro gain"
- sudo rm /var/lib/dpkg/info/python3-pip.list
- sudo apt install python3-pip --reinstall
- sudo apt-get install -y python3-smbus libusb-1.0 -y
- cd
- git clone https://github.com/csete/fcdctl.git
- cd fcdctl
- make fcdpp
-fi
-
-cd /home/pi/pi-power-button
-
- git checkout master
-
- git pull --no-rebase > .updated_p
-
- grep 'changed' /home/pi/pi-power-button/.updated_p
- if [[ $(grep 'changed' /home/pi/pi-power-button/.updated_p) ]]; then
-
- echo "updating pi-power-button."
-
-# git checkout master
-
- script/install
-
- FLAG=1
-
- else
- echo "nothing to do for pi-power-button."
- fi
-
-cd /home/pi/ssdv
-
- git checkout master
-
- git pull --no-rebase > .updated_p
-
- grep 'changed' /home/pi/ssdv/.updated_p
- if [[ $(grep 'changed' /home/pi/ssdv/.updated_p) ]]; then
-
- echo "updating ssdv."
-
-# git checkout master
-
- script/install
-
- FLAG=1
-
- else
- echo "nothing to do for ssdv."
- fi
-
-
- if [[ $(grep 'dtparam=audio=on' /boot/config.txt) ]]; then
- echo "dtparam=audio=on already in /boot/config.txt"
- else
- echo "adding dtparam=audio=on to /boot/config.txt"
- sudo sh -c 'echo "\ndtparam=audio=on" >> /boot/config.txt'
- FLAG=1
- fi
-
- if [[ $(grep 'dtoverlay=audremap,enable_jack=on' /boot/config.txt) ]]; then
- echo "dtoverlay=audremap,enable_jack=on already in /boot/config.txt"
- else
- echo "adding dtoverlay=audremap,enable_jack=on to /boot/config.txt"
- sudo sh -c 'echo "\ndtoverlay=audremap,enable_jack=on" >> /boot/config.txt'
- FLAG=1
- fi
-
- if [[ $(grep 'dtoverlay=pwm,pin=18,func=2' /boot/config.txt) ]]; then
- echo "dtoverlay=pwm,pin=18,func=2 already in /boot/config.txt"
- else
- echo "adding dtoverlay=pwm,pin=18,func=2 to /boot/config.txt"
- sudo sh -c 'echo "\ndtoverlay=pwm,pin=18,func=2" >> /boot/config.txt'
- FLAG=1
-
- cd /home/pi/pi-power-button
- git pull --no-rebase
- git checkout reboot-mode-change
- script/install
-
-# sudo apt-get update && sudo apt-get dist-upgrade -y
- sudo apt-get update -y
- sudo apt-get install -y libjpeg-dev zlib1g-dev libfreetype6-dev liblcms1-dev libopenjp2-7 libtiff5 python3-pil
- sudo pip3 install -y adafruit-blinka RPI.GPIO adafruit-extended-bus adafruit-circuitpython-ina219 pillow
-
- fi
-
- if [[ $(grep 'disable_splash=1' /boot/config.txt) ]]; then
- echo "disable_splash=1 already in /boot/config.txt"
- else
- echo "adding to /boot/config.txt"
- sudo sh -c 'echo "\ndisable_splash=1" >> /boot/config.txt'
- FLAG=1
- fi
-
- if [[ $(grep 'boot_delay=0' /boot/config.txt) ]]; then
- echo "boot_delay=0 already in /boot/config.txt"
- else
- echo "adding to /boot/config.txt"
- sudo sh -c 'echo "\nboot_delay=0" >> /boot/config.txt'
- FLAG=1
- fi
-
- if ! grep -q force_turbo=1 /boot/config.txt ; then
- sudo sh -c 'echo "force_turbo=1" >> /boot/config.txt'
- FLAG=1
- fi
-
-#if [ ! -f "/home/pi/CubeSatSim/telem_string.txt" ]; then
-
-# sudo apt-get update && sudo apt-get dist-upgrade -y
-
-# sudo apt-get install -y libjpeg-dev zlib1g-dev libfreetype6-dev liblcms1-dev libopenjp2-7 libtiff5 -y
-
-# sudo pip3 install pillow
-
-#fi
-
-changed=0
-value=`cat /home/pi/CubeSatSim/sim.cfg`
-# echo "$value"
-echo "$value" > /dev/null
-set -- $value
-
-if [ -z "$1" ] ; then n1="AMSAT" ; changed=1 ; else n1=$1 ; fi # callsign
-if [ -z "$2" ] ; then n2="0" ; changed=1 ; else n2=$2 ; fi # reset count
-if [ -z "$3" ] ; then n3="0" ; changed=1 ; else n3=$3 ; fi # lat
-if [ -z "$4" ] ; then n4="0" ; changed=1 ; else n4=$4 ; fi # lon
-if [ -z "$5" ] ; then n5="no" ; changed=1 ; else n5=$5 ; fi # sim mode
-if [ -z "$6" ] ; then n6="3" ; changed=1 ; else n6=$6 ; fi # squelch
-if [ -z "$7" ] ; then n7="434.9000" ; changed=1 ; else n7=$7 ; fi # transmit frequency
-if [ -z "$8" ] ; then n8="435.0000" ; changed=1 ; else n8=$8 ; fi # receive frequency
-if [ -z "$9" ] ; then n9="no" ; changed=1 ; else n9=$9 ; fi # hab mode
-if [ -z "${10}" ] ; then m1="0" ; changed=1 ; else m1=${10} ; fi # rx pl code
-if [ -z "${11}" ] ; then m2="0" ; changed=1 ; else m2=${11} ; fi # tx pl code
-
-if [ $changed -eq 1 ]; then
- echo -e "Current sim.cfg configuration file:"
- echo
- echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
- echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n"
- echo
- echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $m1 $m2
- echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $m1 $m2 > /home/pi/CubeSatSim/sim.cfg
- echo
-fi
-
-if [ "$noreboot" = "0" ] ; then
-
- if [ $FLAG -eq 1 ]; then
- echo "systemctl daemon-reload and reboot"
- sudo systemctl daemon-reload
- sudo reboot -h now
-# sudo cubesatsim
- else
- grep 'changed' /home/pi/CubeSatSim/.updated
- if [[ $(grep 'changed' /home/pi/CubeSatSim/.updated) ]]; then
- echo "reboot due to code changes " | wall
- sudo reboot -h now
-# sudo cubesatsim
- else
- echo "nothing to do."
- fi
- fi
-else
- if [ $FLAG -eq 1 ]; then
- echo "reboot needed for changes to take effect" | wall
- fi
-fi
-
-echo "CubeSatSim update complete."
diff --git a/update b/update
new file mode 120000
index 00000000..f7ffc47a
--- /dev/null
+++ b/update
@@ -0,0 +1 @@
+install
\ No newline at end of file