diff --git a/.gitignore b/.gitignore index f2cff743..04810931 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,5 @@ pi_zero2 image_file.bin logt.txt telem.txt.bk +failure_mode.txt +sim_mode_auto 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/asound.conf b/asound.conf index 783b59f7..cf3cc9a0 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,7 +15,7 @@ pcm.softvol { slave.pcm "shared_speaker" control { name "Master" - card 2 + card "Device" } } @@ -23,7 +23,7 @@ pcm.shared_speaker { type dmix ipc_key 1024 slave { - pcm "hw:2,0" + pcm "hw:CARD=Device,DEV=0" rate 48000 period_time 0 period_size 1024 @@ -36,7 +36,7 @@ pcm.shared_mic { type dsnoop ipc_key 2048 slave { - pcm "hw:2,0" + pcm "hw:CARD=Device,DEV=0" # channels 1 rate 48000 period_time 0 diff --git a/config b/config index 7073de90..1b7311e2 100755 --- a/config +++ b/config @@ -107,7 +107,8 @@ function check_restart { fi } -echo "CubeSatSim v2.1 configuration tool" +echo +echo "CubeSatSim v2.2 configuration tool" echo # echo $1 # echo $2 @@ -115,12 +116,17 @@ echo sudo modprobe snd-aloop - if [ "$2" = "n" ] ; then -#if [ -z "$2" ] ; then # need to swap else if change - noreboot=1 - echo "Reboot disabled" -else +# if [ "$2" = "n" ] ; then +if [ -z "$2" ] ; then noreboot=0 +else + if [ "$2" = "n" ] ; then + echo "Reboot disabled" + noreboot=1 + else + fail=$2 + fi + fi # echo "No reboot" @@ -165,13 +171,83 @@ 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} @@ -185,7 +261,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 @@ -196,7 +272,7 @@ if [ "$1" = "" ]; then echo -n "Squelch level is: " echo $6 - echo +# echo FILE=/home/pi/CubeSatSim/command_control if [ -f "$FILE" ]; then @@ -215,14 +291,14 @@ if [ "$1" = "" ]; then 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 @@ -231,7 +307,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" @@ -243,7 +319,7 @@ if [ "$1" = "" ]; then 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" @@ -357,14 +433,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 @@ -376,13 +452,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 @@ -409,7 +486,7 @@ elif [ "$1" = "-c" ]; then echo $1 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 @@ -423,8 +500,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 @@ -457,7 +534,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): " @@ -477,8 +554,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 @@ -512,7 +589,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): " @@ -554,8 +631,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 @@ -865,7 +942,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): " @@ -887,8 +964,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 @@ -910,7 +987,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` @@ -924,7 +1001,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)" @@ -967,8 +1044,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 @@ -998,7 +1075,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 @@ -1017,23 +1094,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 -# reboot=1 -## sudo reboot now +# 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 # fi elif [ "$1" = "-o" ]; then @@ -1105,7 +1183,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 @@ -1122,8 +1200,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 @@ -1344,6 +1422,321 @@ elif [ "$1" = "-j" ]; then restart=1 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 + 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 "Unless you configure gpsd otherwise, the is connected to serial0 on the Pi." + echo "To monitor your gps device, use the command gpsmon" + 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" = "-h" ]; then echo "config OPTION" @@ -1382,7 +1775,10 @@ elif [ "$1" = "-h" ]; then 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 exit 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/install b/install index 42362044..e8478a1b 100755 --- a/install +++ b/install @@ -1,6 +1,17 @@ #!/bin/bash -echo -e "\ninstallation script for CubeSatSim v2.1\n" +echo -e "\ninstallation script for CubeSatSim v2.2\n" + + if [[ $(grep '11.' /etc/debian_version) ]]; then + echo "Installing on Debian 11 (Bullseye)" + else + echo "The OS is not Debian 11 (Bullseye)!" + echo "Installation is not likely to work." + echo "It is recommended you start with" + echo "Bullseye as your OS." + echo + sleep 10 + fi if [[ $(grep 'bullseye' /etc/os-release) ]]; then echo "Bullseye detected, installation continuing." @@ -50,7 +61,7 @@ else echo "0\n" > /home/pi/CubeSatSim/command_count.txt fi -cd +touch /home/pi/CubeSatSim/command_control_direwolf CubeSatSim/config -c -n @@ -60,8 +71,25 @@ sudo apt-get update && sudo apt-get dist-upgrade -y sudo apt-get remove pulseaudio -y +sudo apt-get install -y gcc g++ make cmake libasound2-dev libudev-dev libavahi-client-dev libgpiod-dev + +cd + +git clone https://github.com/alanbjohnston/direwolf.git + +cd direwolf + +make -j + +sudo make install + +make install-rpi + # removed wiringpi and python-picamera python3-picamera -sudo apt-get install -y git libasound2-dev i2c-tools build-essential libgd-dev libmagic-dev minicom +sudo apt-get install -y git libasound2-dev i2c-tools build-essential libgd-dev libmagic-dev minicom gpsd gpsd-clients libgps-dev python3-gps + +sudo systemctl disable gpsd +sudo systemctl disable gpsd.socket cd /tmp @@ -100,19 +128,6 @@ else echo "b" > .mode fi -cd - -git clone https://github.com/alanbjohnston/direwolf.git - -cd direwolf - -make -j - -sudo make install - -make install-rpi - - cd git clone https://github.com/alanbjohnston/pi-power-button.git @@ -136,7 +151,7 @@ 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 -o fctelem.zip +unzip -u fctelem.zip cd echo "Installing fcdctl to set FUNcubeDongle Pro gain" @@ -285,6 +300,8 @@ sudo raspi-config nonint do_legacy 0 sudo sh -c 'echo "\n" >> /boot/config.txt' +sudo sed -i 's/DEVICES=""/DEVICES="\/dev\/serial0"/g' /etc/default/gpsd + changed=0 value=`cat /home/pi/CubeSatSim/sim.cfg` echo "$value" > /dev/null @@ -313,6 +330,22 @@ if [ $changed -eq 1 ]; then echo fi +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 + +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 + echo "Would you like to reboot to complete the installation (y/n)?" read -r ANS diff --git a/main.c b/main.c index fdfa7384..9376e0e9 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,17 @@ 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"); + } FILE * command_file = fopen("/home/pi/CubeSatSim/command_control", "r"); if (command_file == NULL) { @@ -102,6 +107,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 +153,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 +185,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); @@ -272,47 +287,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,34 +304,23 @@ 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; + 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 + 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]; @@ -373,52 +340,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(); + + if (sim_mode == TRUE) { - sim_mode = TRUE; - - fprintf(stderr, "Simulated telemetry mode!\n"); + 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 +432,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 +443,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; @@ -542,14 +557,24 @@ 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))) // && !sim_mode) + if (mode == FSK) { // && !sim_mode) + get_tlm_fox(); +// get_tlm_fox(); + } + if (mode == BPSK) { // && !sim_mode) get_tlm_fox(); // fill transmit buffer with reset count 0 packets that will be ignored - else if (((mode == FC))) // && !sim_mode) +// get_tlm_fox(); + } + 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 { @@ -573,13 +598,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 +613,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,6 +632,35 @@ int main(int argc, char * argv[]) { // #endif fclose(uptime_file); + if (fail_rnd_mode) { +// if (loop % 10 == 0) { + if ((loopTime - failTime) > fail_time * 1000) { +// failureMode = (int) rnd_float(1, FAIL_COUNT); + failureMode = (int) rnd_float(1, 10); + printf("Simulated Random Failure Change\n"); + 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 +// { +// 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; @@ -635,39 +691,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 +753,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 +786,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 +862,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 +874,129 @@ 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) // recreaate sensor_payload string + { + 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]; @@ -769,15 +1033,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 +1045,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]]); - 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 +1146,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 +1175,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(); @@ -989,20 +1314,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 +1376,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 +1398,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 +1412,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 +1449,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 +1495,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 +1504,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 +1531,22 @@ 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)); 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 +1563,125 @@ 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"); + printf("first or second time - no sleep\n"); - 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 +1702,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 +1734,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 +1749,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 +1762,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 +1825,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, 53 + head_offset, groundCommandCount); + + if (mode == BPSK) { 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 +1991,16 @@ 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); - } + encodeB(b, 74 + head_offset, 0xfff); + } short int data10[headerLen + rsFrames * (rsFrameLen + parityLen)]; short int data8[headerLen + rsFrames * (rsFrameLen + parityLen)]; @@ -1632,7 +2008,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 +2017,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 +2043,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 +2108,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 +2135,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 +2143,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 +2176,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,100 +2186,124 @@ 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 (sock_ret == -1) { -/// printf("Error: %s \n", strerror(errno)); -/// socket_open = 0; - //transmitStatus = -1; -/// } -/// } + /// 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 (socket_open == 1) + /// firstTime = 0; + // else if (frames_sent > 0) //5) + // firstTime = 0; return; } @@ -2460,7 +2825,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 +2973,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 +2983,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 +3004,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 +3029,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 +3098,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..64a1c747 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; @@ -124,6 +127,21 @@ FILE *image_file; #define REPEATER 7 #define TXCOMMAND 12 +#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; float amplitude; // = ; // 20000; // 32767/(10%amp+5%amp+100%amp) @@ -148,6 +166,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 +178,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.55, 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,6 +195,7 @@ 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); @@ -211,8 +232,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 +247,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/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_rttelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_rttelemetry.csv index 2d34abc9..9fdaed04 100644 --- a/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_rttelemetry.csv +++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_PSK_rttelemetry.csv @@ -1,4 +1,4 @@ -61,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION +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 @@ -41,22 +41,23 @@ 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,Computer Software,3,3,0,Ground Commands,Number of ground commands received +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,ICR3VProt,12,V,43,NONE,7,2,3,3V Prot,ICR 3V Proteted -47,realTime,ICR2dot5V,12,V,43,NONE,7,3,3,2.5V,ICR 2.5V -48,realTime,ICR2dot5VProt,12,V,43,NONE,7,4,3,2.5V Prot,ICR 2.5V Protected -49,realTime,rf6,12,-,0,NONE,0,0,0,None,None -50,realTime,rf7,12,-,0,NONE,0,0,0,None,None -51,realTime,MuxTest,12,V,43,NONE,7,5,3,Sensor Power,Sensor Power Voltage at the ICR -52,realTime,LtVGACtl,12,V,42,NONE,1,4,3,VGA Control,Control Voltage to the Variable Gain Amplifier (VGA) -53,realTime,pad,4,-,34,NONE,0,0,0,None,Unused -54,realTime,IHUdiagData,32,-,18,NONE,3,2,0,Diagnostic Info,Diagnostic Data on IHU Performance -55,realTime,pad1,1,-,0,NONE,0,0,0,NONE,Filler -56,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 -57,realTime,swCmds,32,-,35,NONE,7,6,0,Diagnostic,ICR Diagnostic information -58,realTime,hwCmdCnt,6,-,1,NONE,7,7,0,HW Command Count,Number of hardware commands since last reset -59,realTime,swCmdCnt,6,-,1,NONE,7,8,0,SW Command Count,Number of software commands since last reset -60,realTime,pad2,27,-,0,NONE,0,0,0,NONE,Filler +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_rttelemetry.csv b/spacecraft/FoxTelem_1.13i/CubeSatSim_rttelemetry.csv index 556e73d3..967514bc 100644 --- a/spacecraft/FoxTelem_1.13i/CubeSatSim_rttelemetry.csv +++ b/spacecraft/FoxTelem_1.13i/CubeSatSim_rttelemetry.csv @@ -1,4 +1,4 @@ -47,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION +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 @@ -41,8 +41,9 @@ 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,Computer Software,3,3,0,Ground Commands,Number of ground commands received +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,Pad,56,-,0,NONE,0,0,0,NONE,NONE +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 index d085dedc..765fba49 100644 --- a/spacecraft/FoxTelem_1.13i/README.md +++ b/spacecraft/FoxTelem_1.13i/README.md @@ -1,7 +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/23217474/foxtelem_spacecraft_files.zip) +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) and copy into FoxTelem spacecraft folder, replacing existing files. +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/telem.c b/telem.c index 1fc534a5..ce4f14c3 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; diff --git a/transmit.py b/transmit.py index b9cbdbfe..a2a8a8c5 100644 --- a/transmit.py +++ b/transmit.py @@ -11,6 +11,42 @@ from os import system from PIL import Image, ImageDraw, ImageFont, ImageColor import serial import random +import subprocess + +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: @@ -95,6 +131,8 @@ def increment_mode(): print("can't write to .mode file") def camera_photo(): + global cam_fail + sim_failure_check() system("sudo rm /home/pi/CubeSatSim/camera_out.jpg") stored_image = False try: @@ -102,6 +140,10 @@ def camera_photo(): 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") @@ -126,11 +168,11 @@ def camera_photo(): # 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...") +print("CubeSatSim v2.2 transmit.py starting...") pd = 21 ptt = 20 @@ -212,12 +254,12 @@ 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") @@ -282,12 +324,42 @@ 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) > 4: + if config[4] == 'y' or config[4] == 'yes': + sim_mode = True + sim_config = True + print("Simulated telemetry mode is configured") + else: +# query = ["timeout", "2", "i2cdetect", "-y", "3"] # Test if Solar board is present +# 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}") +# 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}") + + try: + file = open("/home/pi/CubeSatSim/sim_mode_auto") + print("Simulated telemetry mode automatically turned on!") + sim_mode = True + sim_config = True + file.close() + except: + if (debug_mode == 1): + print("/home/pi/CubeSatSim/sim_mode_auto not found") if len(config) > 5: sq = config[5] if (mode == 'p') or (mode == 'P'): @@ -295,9 +367,6 @@ if __name__ == "__main__": print(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 +379,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) @@ -368,7 +441,24 @@ if __name__ == "__main__": 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) @@ -387,32 +477,36 @@ 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')) 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") + 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, txLedOff) + + 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: @@ -429,8 +523,8 @@ if __name__ == "__main__": 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: @@ -450,6 +544,7 @@ if __name__ == "__main__": # # battery_saver_check() if (txc): + sim_failure_check() # output(pd, 1) sleep(0.1) # add delay before transmit output (ptt, 0) @@ -476,11 +571,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() @@ -502,6 +598,7 @@ if __name__ == "__main__": output(txLed, txLedOn) if (txc): + sim_failure_check() # output (pd, 1) sleep(0.3) output (ptt, 0) @@ -563,6 +660,7 @@ if __name__ == "__main__": # 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") @@ -581,35 +679,7 @@ if __name__ == "__main__": 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") @@ -623,6 +693,8 @@ if __name__ == "__main__": # 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") @@ -660,6 +732,7 @@ if __name__ == "__main__": # 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") @@ -696,6 +769,7 @@ if __name__ == "__main__": # 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") @@ -727,6 +801,7 @@ if __name__ == "__main__": # 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") diff --git a/update b/update index 368a0ed6..442153bf 100755 --- a/update +++ b/update @@ -1,6 +1,6 @@ #!/bin/bash -echo -e "\nupdate script for CubeSatSim v2.1\n" +echo -e "\nupdate script for CubeSatSim v2.2\n" FLAG=0 checkout=0 @@ -26,14 +26,16 @@ fi 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 +#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 + sudo apt-get install -y git libasound2-dev i2c-tools build-essential libgd-dev libmagic-dev python3-pip minicom gpsd gpsd-clients libgps-dev python3-gps -fi +#fi + +sudo apt-get install -y gpsd gpsd-clients libgps-dev python3-gps # sudo apt-get install -y python3-smbus libusb-1.0 @@ -49,6 +51,11 @@ sudo sed -i 's/console=tty1 r/console=tty1 maxcpus=1 r/g' /boot/cmdline.txt # si sudo sed -i 's/maxcpus=2/maxcpus=1/g' /boot/cmdline.txt # single core if Pi Zero 2 +sudo sed -i 's/DEVICES=""/DEVICES="\/dev\/serial0"/g' /etc/default/gpsd + +sudo systemctl disable gpsd > /dev/null 2>&1 +sudo systemctl disable gpsd.socket > /dev/null 2>&1 + cd /home/pi/CubeSatSim git pull --no-rebase > .updated @@ -56,6 +63,9 @@ git pull --no-rebase > .updated if [ $checkout -eq 1 ]; then git checkout $branch git pull --no-rebase > .updated + FLAG=1 + echo "Running update script again" + /home/pi/CubeSatSim/update fi make debug @@ -236,7 +246,7 @@ if [ ! -d "/home/pi/fctelem" ]; then mkdir /home/pi/fctelem/public_html cd fctelem wget https://github.com/alanbjohnston/go/releases/download/v0.2/fctelem.zip - unzip 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" @@ -246,15 +256,61 @@ elif [ ! -f "/home/pi/fctelem/v0.2" ]; then 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 + unzip -u fctelem.zip FLAG=1 fi +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 + +cd /home/pi/MPU6050-C-CPP-Library-for-Raspberry-Pi +git checkout master +git pull --no-rebase > .updated_p + +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 + +cd /home/pi/raspberry-pi-bme280 +git checkout payload +git pull --no-rebase > .updated_p + +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 -y + sudo apt-get install -y python3-smbus libusb-1.0 cd git clone https://github.com/csete/fcdctl.git cd fcdctl @@ -263,24 +319,22 @@ 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 + git checkout master + +# 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 + # else + # echo "nothing to do for pi-power-button." + # fi cd /home/pi/ssdv