diff --git a/.gitignore b/.gitignore index 220663f21..c904aa40b 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,23 @@ telem.wav cw.txt cwready logr.txt +command_control +command_control_direwolf +command_count.txt +command_tx +cw0.txt +cw1.txt +cw2.txt +cw3.txt +cw4.txt +cw5.txt +cw6.txt +logc.txt +telem.txt +telem_string.txt +test +transmit_dtmf +uptime +beacon_off +battery_saver + diff --git a/README.md b/README.md index cd6e0db4d..8423ed4bd 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,5 @@ # CubeSatSim -There is beta release for the new CubeSatSim hardware and software in the beta branch. - -### The beta hardware files are here: -https://CubeSatSim.org/hardware-beta - -### The beta wiki instructions are here: -https://github.com/alanbjohnston/CubeSatSim/wiki/v1.3.2-0.-Home. - -### The beta Bill of Materials (BOM) is here: -https://CubeSatSim.org/bom-beta. - -### Information about the latest beta software release is here: -https://github.com/alanbjohnston/CubeSatSim/releases - The CubeSat Simulator https://github.com/alanbjohnston/CubeSatSim/wiki is a low cost satellite emulator that runs on solar panels and batteries, transmits UHF radio telemetry, has a 3D printed frame, and can be extended by additional sensors and modules. This project is sponsored by the not-for-profit [Radio Amateur Satellite Corporation, AMSAT®](https://amsat.org). There are several hardware versions and software branches to go with them - see below for information. @@ -36,7 +22,7 @@ The other option is to start with a Raspberry Pi OS (Rasbian) image (Bullseye or ## Disk Image Option Steps -See the Wiki Software Install page for details: https://github.com/alanbjohnston/CubeSatSim/wiki/2.-Software-Install. +See the Wiki Software Install page for details: [https://github.com/alanbjohnston/CubeSatSim/wiki/V1.3.2-2.-Software-Install](https://github.com/alanbjohnston/CubeSatSim/wiki/V1.3.2-2.-Software-Install#disk-image-option-steps). ## Installation Script Option Steps @@ -52,15 +38,15 @@ To get the software follow these steps: `cd CubeSatSim` -`git checkout master` +`git checkout beta` -You are now ready to install the software using this script in the CubeSatSim directory: +`# You are now ready to install the software using this script in the CubeSatSim directory:` `./install` The installation script will run for quite a while. You will get prompted for your amateur radio callsign in all capitals, if you have one. If you don't you can put some other word which will be transmitted as a CW ID. You will also be prompted for your latitude and longitude for APRS packets. The script will prompt you if you want to modify /boot/config.txt file. Type a `y` and the script will complete. You will need to reboot. -See the Wiki for more details about the CubeSatSim https://github.com/alanbjohnston/CubeSatSim/wiki +See the Wiki for more details about the CubeSatSim [https://github.com/alanbjohnston/CubeSatSim/wiki](https://github.com/alanbjohnston/CubeSatSim/wiki/v1.3.2-0.-Home) Older Versions diff --git a/command b/command new file mode 100755 index 000000000..1349f45a7 --- /dev/null +++ b/command @@ -0,0 +1,132 @@ +#!/bin/bash + +echo -e "\nCommand and Control script for CubeSatSim v2.0\n" + + FILE=/home/pi/CubeSatSim/command_control + if [ -f "$FILE" ]; then + echo "Radio command and control is ON" +# echo "Turning Command and control to OFF" +# sudo rm /home/pi/CubeSatSim/command_control +# echo "rebooting" +# sudo systemctl stop rpitx +# sudo reboot now +# fi + + else + echo "Radio command and control is OFF" + + while true + do + sleep 60 + done + +# exit 1 + fi + +if [ "$1" = "d" ]; then + + echo "debug mode" + + debug=1 + +else + + debug=0 + +fi + +echo "Waiting 20 seconds for USB" + +sleep 20 + +FILE=/home/pi/CubeSatSim/command_control_direwolf +if [[ $(arecord -l | grep "USB Audio Device") ]] && [ -f "$FILE" ]; then + + echo "Starting Direwolf DTMF and APRS Command and Control" + + if [ "$debug" = "1" ]; then + + echo "debug mode" + + direwolf -c /home/pi/CubeSatSim/direwolf-cc.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py d + + else + + direwolf -c /home/pi/CubeSatSim/direwolf-cc.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py + + fi +else + + if [ -f "$FILE" ]; then + + echo "Direwolf mode set but no USB soundcard detected!" + +# echo "Trying RTL-FM" + + timeout 1 rtl_test &> out.txt + if [[ $(grep "No supported" out.txt) ]] ; then + + echo "No RTL-SDR detected. Command and control is OFF" +# sleep 60 + exit + + else + + echo "RTL-SDR detected." + echo "Command and control is OFF" +# sudo modprobe snd-aloop + +# value=`aplay -l | grep "Loopback"` +# echo "$value" > /dev/null +# set -- $value + +# card=${2:0:1} + +# value=`cat /home/pi/CubeSatSim/sim.cfg` +# echo "$value" > /dev/null +# set -- $value + +# freq=$8 + +# echo "Current value of rx is" +# echo $freq + +# rtl_fm -M fm -f ${freq}M -s 48k | aplay -D plughw:${card},0,0 -r 48000 -t raw -f S16_LE -c 1 & + +# if [ "$debug" = "1" ]; then + +# echo "debug mode" + +# direwolf -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py d + +# else + +# direwolf -r 48000 -c /home/pi/CubeSatSim/direwolf/direwolf.conf -t 0l | python3 /home/pi/CubeSatSim/dtmf_aprs_cc.py + +# fi + + sleep 5 + fi + rm out.txt + else + + echo "Starting Carrier (squelch) Command and Control" + + fi + + if [ "$1" = "d" ]; then + + echo "debug mode" + + python3 /home/pi/CubeSatSim/squelch_cc.py d + + else + + python3 /home/pi/CubeSatSim/squelch_cc.py + + fi +fi + +sudo killall -9 direwolf &>/dev/null +sudo killall -9 rtl_fm &>/dev/null + diff --git a/config b/config index 7f0dec97b..51c9035e8 100755 --- a/config +++ b/config @@ -1,32 +1,266 @@ #!/bin/bash -echo "CubeSatSim v1.2 configuration tool" +function transmit_command_aprs { -if [ "$2" = "-n" ]; then - norestart=1 + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + + echo "Stopping command and control" + sudo systemctl stop command + + echo "Transmit DTMF start" + gpio write 28 0 # ptt + gpio write 2 1 # tx LED + timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-aprs.conf -t 0l + gpio write 2 0 # tx LED + gpio write 28 1 #ptt + echo "Transmit stop" + + echo "Resuming command and control" + sudo systemctl start command + + else + + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=a" + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + echo $STRING > /home/pi/CubeSatSim/t.txt + echo + echo -n "Sending APRS packet to change mode to APRS " + echo $STRING + sudo touch /home/pi/CubeSatSim/ready + sleep 3 + + fi + + exit +} + +function transmit_command_fsk { + + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + + echo "Stopping command and control" + sudo systemctl stop command + + echo "Transmit DTMF start" + gpio write 28 0 # ptt + gpio write 2 1 # tx LED + timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-fsk.conf -t 0l + gpio write 2 0 # tx LED + gpio write 28 1 #ptt + echo "Transmit stop" + + echo "Resuming command and control" + sudo systemctl start command + + else + + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=f" + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + echo $STRING > /home/pi/CubeSatSim/t.txt + echo + echo -n "Sending APRS packet to change mode to FSK" + echo $STRING + sudo touch /home/pi/CubeSatSim/ready + sleep 3 + + fi + + exit +} + +function transmit_command_bpsk { + + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + + echo "Stopping command and control" + sudo systemctl stop command + + echo "Transmit DTMF start" + gpio write 28 0 # ptt + gpio write 2 1 # tx LED + timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-bpsk.conf -t 0l + gpio write 2 0 # tx LED + gpio write 28 1 #ptt + echo "Transmit stop" + + echo "Resuming command and control" + sudo systemctl start command + + else + + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=b" + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + echo $STRING > /home/pi/CubeSatSim/t.txt + echo + echo -n "Sending APRS packet to change mode to BPSK" + echo $STRING + sudo touch /home/pi/CubeSatSim/ready + sleep 3 + + fi + + exit +} + +function transmit_command_sstv { + + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + + echo "Stopping command and control" + sudo systemctl stop command + + echo "Transmit DTMF start" + gpio write 28 0 # ptt + gpio write 2 1 # tx LED + timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-sstv.conf -t 0l + gpio write 2 0 # tx LED + gpio write 28 1 #ptt + echo "Transmit stop" + + echo "Resuming command and control" + sudo systemctl start command + + else + + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=s" + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + echo $STRING > /home/pi/CubeSatSim/t.txt + echo + echo -n "Sending APRS packet to change mode to SSTV" + echo $STRING + sudo touch /home/pi/CubeSatSim/ready + sleep 3 + + fi + + exit +} + +function transmit_command_cw { + + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + + echo "Stopping command and control" + sudo systemctl stop command + + echo "Transmit DTMF start" + gpio write 28 0 # ptt + gpio write 2 1 # tx LED + timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-cw.conf -t 0l + gpio write 2 0 # tx LED + gpio write 28 1 #ptt + echo "Transmit stop" + + echo "Resuming command and control" + sudo systemctl start command + + else + + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=m" + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + echo $STRING > /home/pi/CubeSatSim/t.txt + echo + echo -n "Sending APRS packet to change mode to CW" + echo $STRING + sudo touch /home/pi/CubeSatSim/ready + sleep 3 + + fi + + exit +} + +function transmit_command_beacon { + + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + + echo "Stopping command and control" + sudo systemctl stop command + + echo "Transmit DTMF start" + gpio write 28 0 # ptt + gpio write 2 1 # tx LED + timeout 3 direwolf -c /home/pi/CubeSatSim/direwolf/direwolf-transmit-dtmf-beacon.conf -t 0l + gpio write 2 0 # tx LED + gpio write 28 1 #ptt + echo "Transmit stop" + + echo "Resuming command and control" + sudo systemctl start command + + else + + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=o" + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + echo $STRING > /home/pi/CubeSatSim/t.txt + echo + echo -n "Sending APRS packet to toggle Beacon" + echo $STRING + sudo touch /home/pi/CubeSatSim/ready + sleep 3 + + fi + + exit +} + +echo "CubeSatSim v2.0 configuration tool" +echo +# echo $1 +# echo $2 +# echo + +sudo modprobe snd-aloop + +# if [ "$2" = "n" ] ; then +if [ -z "$2" ] ; then + noreboot=0 else - norestart=0 + noreboot=1 + echo "Reboot disabled" fi +# echo "No reboot" +# echo $noreboot + +reboot=0 +restart=0 + if [ "$1" = "" ]; then value=`cat /home/pi/CubeSatSim/.mode` echo "$value" > /dev/null set -- $value if [ "$1" = "a" ]; then - echo "APRS mode is set" + echo "Mode is APRS" elif [ "$1" = "m" ]; then - echo "CW mode is set" + echo "Mode is CW" elif [ "$1" = "f" ]; then - echo "FSK mode is set" + echo "Mode is FSK" elif [ "$1" = "b" ]; then - echo "BPSK mode is set" + echo "Mode is BPSK" elif [ "$1" = "s" ]; then - echo "SSTV mode is set" + echo "Mode is SSTV" + elif [ "$1" = "e" ]; then + echo "Mode is Repeater" + elif [ "$1" = "n" ]; then + echo -n "Mode is Transmit Commands with " + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + echo -n "DTMF" + else + echo -n "APRS" + fi else echo fi - + echo value=`cat /home/pi/CubeSatSim/sim.cfg` echo "$value" > /dev/null set -- $value @@ -38,67 +272,198 @@ if [ "$1" = "" ]; then # sim="no" echo "Simulated Telemetry is OFF" fi - + echo + + if [ "$9" = "yes" ] || [ "$9" = "y" ]; then + echo "Balloon mode is ON" + else + echo "Balloon mode is OFF" + fi + + echo + echo -n "Current command count is: " + cat /home/pi/CubeSatSim/command_count.txt + echo +# echo +# echo "Current beacon transmit mode is:" +# cat /home/pi/CubeSatSim/command_tx +# echo + + echo -n "Squelch level is: " + echo $6 + echo + + FILE=/home/pi/CubeSatSim/command_control + if [ -f "$FILE" ]; then + + if [[ $(arecord -l | grep card) ]]; then + FILE=/home/pi/CubeSatSim/command_control_direwolf + if [ -f "$FILE" ]; then + echo "Radio DTMF/APRS command and control is ON" + else + echo "Radio carrier command and control is ON" + fi + else + echo "Radio carrier command and control is ON" + fi + else + echo "Radio command and control is OFF" + fi + + echo + + echo -n "RX PL code is: " + echo -n ${10} +# echo + echo -n " TX PL code is: " + echo ${11} + echo + + FILE=/home/pi/CubeSatSim/battery_saver + if [ -f "$FILE" ]; then + echo "Safe Mode! Battery saver mode is ON" + else + echo "Battery saver mode is OFF" + fi + + echo + FILE=/home/pi/CubeSatSim/beacon_off + if [ -f "$FILE" ]; then + echo "Transmit beacon telemetry is OFF" + else + echo "Transmit beacon telemetry is ON" + fi + echo echo -e "Current sim.cfg configuration file:" # echo - echo $1 $2 $3 $4 $5 + echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} echo + echo "To change, include an OPTION" + echo "To see options, type config -h" # echo -# echo "To change, include an OPTION" -# echo - set -- "-h" -fi +# set -- "-h" +# fi + + +elif [ "$1" = "-i" ]; then + + restart=1 -if [ "$1" = "-i" ]; then - echo "Restarting CubeSatSim" - sudo systemctl restart cubesatsim - exit elif [ "$1" = "-a" ]; then - echo "changing CubeSatSim to AFSK mode" - sudo echo "a" > /home/pi/CubeSatSim/.mode - sudo systemctl restart cubesatsim - exit + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" == "n" ]; then + + transmit_command_aprs + + else + + echo "changing CubeSatSim to AFSK mode" + sudo echo "a" > /home/pi/CubeSatSim/.mode + if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] ; then + FILE=/home/pi/CubeSatSim/battery_saver + if [ -f "$FILE" ]; then + restart=1 + else + reboot=1 + fi + else + restart=1 + fi + fi + elif [ "$1" = "-m" ]; then - echo "changing CubeSatSim to CW mode" - sudo echo "m" > /home/pi/CubeSatSim/.mode - sudo systemctl restart cubesatsim - exit + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" == "n" ]; then + + transmit_command_cw + + else + + echo "changing CubeSatSim to CW mode" + sudo echo "m" > /home/pi/CubeSatSim/.mode + if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] ; then + FILE=/home/pi/CubeSatSim/battery_saver + if [ -f "$FILE" ]; then + restart=1 + else + reboot=1 + fi + else + restart=1 + fi + fi + elif [ "$1" = "-f" ]; then - echo "changing CubeSatSim to FSK mode" - sudo echo "f" > /home/pi/CubeSatSim/.mode - sudo systemctl restart cubesatsim - exit + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" == "n" ]; then + + transmit_command_fsk + + else + + echo "changing CubeSatSim to FSK mode" + sudo echo "f" > /home/pi/CubeSatSim/.mode + restart=1 + fi + elif [ "$1" = "-b" ]; then - echo "changing CubeSatSim to BPSK mode" - sudo echo "b" > /home/pi/CubeSatSim/.mode - sudo systemctl restart cubesatsim - exit + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" == "n" ]; then + + transmit_command_bpsk + + else + + echo "changing CubeSatSim to BPSK mode" + sudo echo "b" > /home/pi/CubeSatSim/.mode + restart=1 + fi + elif [ "$1" = "-s" ]; then - echo "changing CubeSatSim to SSTV mode" - sudo echo "s" > /home/pi/CubeSatSim/.mode - sudo systemctl restart cubesatsim - exit -elif [ "$1" = "-h" ]; then - echo "config OPTION" - echo - echo "Changes CubeSatSim mode, resets, or modifies configuration file" - echo - echo " -h This help info" - echo " -a Change to AFSK/APRS mode" - echo " -m Change to CW mode" - echo " -f Change to FSK/DUV mode" - echo " -b Change to BPSK mode" - echo " -s Change to SSTV mode" - echo " -i Restarts CubeSatsim software" - echo " -c Change the CALLSIGN in the configuration file sim.cfg" - echo " -t Change the Simulated Telemetry setting in sim.cfg" - echo " -r Change the Resets Count in the configuration file sim.cfg" - echo " -l Change the Latitude and Longitude in the configuration file sim.cfg" - echo - exit + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" == "n" ]; then + + transmit_command_sstv + + else + + echo "changing CubeSatSim to SSTV mode" + sudo echo "s" > /home/pi/CubeSatSim/.mode + if [ "$1" == "f" ] || [ "$1" == "b" ] || [ "$1" == "e" ] ; then + + FILE=/home/pi/CubeSatSim/battery_saver + if [ -f "$FILE" ]; then + restart=1 + else + reboot=1 + fi + else + restart=1 + fi + fi elif [ "$1" = "-t" ]; then @@ -119,7 +484,7 @@ elif [ "$1" = "-t" ]; then echo -# echo $1 $2 $3 $4 +# $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} echo "Do you want Simulated Telemetry ON (y/n) " read sim @@ -133,16 +498,18 @@ elif [ "$1" = "-t" ]; then echo "Simulated Telemetry is OFF" fi +# echo + echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n" +# echo + echo $1 $2 $3 $4 $sim $6 $7 $8 $9 ${10} + echo $1 $2 $3 $4 $sim $6 $7 $8 $9 ${10} > /home/pi/CubeSatSim/sim.cfg echo - echo -e "\nCubeSatSim configuraation sim.cfg file updated to: \n" - echo - echo $1 $2 $3 $4 $sim - echo $1 $2 $3 $4 $sim > /home/pi/CubeSatSim/sim.cfg - echo - echo "Restarting CubeSatSim with new configuraation file" - echo +## echo "Rebooting CubeSatSim with new configuration file" +## echo - sudo systemctl restart cubesatsim + reboot=1 +## sudo reboot now +# sudo restart cubesatsim elif [ "$1" = "-c" ]; then @@ -162,7 +529,7 @@ elif [ "$1" = "-c" ]; then echo $1 echo -# echo $1 $2 $3 $4 $5 +# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} echo "Enter callsign in all capitals: " read callsign @@ -174,19 +541,21 @@ elif [ "$1" = "-c" ]; then norestart=1 else - echo -e "\nCubeSatSim configuraation sim.cfg file updated to: \n" + echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n" - echo $callsign $2 $3 $4 $5 - echo $callsign $2 $3 $4 $5 > /home/pi/CubeSatSim/sim.cfg + echo $callsign $2 $3 $4 $5 $6 $7 $8 $9 ${10} + echo $callsign $2 $3 $4 $5 $6 $7 $8 $9 ${10} > /home/pi/CubeSatSim/sim.cfg fi if [ "$norestart" = "1" ]; then echo else echo - echo "Restarting CubeSatSim with new configuraation file" - echo - sudo systemctl restart cubesatsim +## echo "Rebooting CubeSatSim with new configuration file" +## echo + reboot=1 +## sudo reboot now +# sudo systemctl restart cubesatsim fi elif [ "$1" = "-r" ]; then @@ -208,7 +577,7 @@ elif [ "$1" = "-r" ]; then echo $2 echo -# echo $1 $2 $3 $4 $5 +# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} echo -e "Enter Reset Count (integer): " @@ -226,19 +595,21 @@ elif [ "$1" = "-r" ]; then norestart=1 else - echo -e "\nCubeSatSim configuraation sim.cfg file updated to: \n" + echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n" - echo $1 $resets $3 $4 $5 - echo $1 $resets $3 $4 $5 > /home/pi/CubeSatSim/sim.cfg + echo $1 $resets $3 $4 $5 $6 $7 $8 $9 ${10} + echo $1 $resets $3 $4 $5 $6 $7 $8 $9 ${10} > /home/pi/CubeSatSim/sim.cfg fi if [ "$norestart" = "1" ]; then echo else - echo - echo "Restarting CubeSatSim with new configuraation file" - echo - sudo systemctl restart cubesatsim +## echo +## echo "Rebooting CubeSatSim with new configuration file" +## echo + reboot=1 +## sudo reboot now +# sudo systemctl restart cubesatsim fi elif [ "$1" = "-l" ]; then @@ -261,7 +632,7 @@ elif [ "$1" = "-l" ]; then echo $3 echo -# echo $1 $2 $3 $4 $5 +# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} echo -e "Enter latitude (decimal degrees, positive is north): " @@ -302,18 +673,811 @@ elif [ "$1" = "-l" ]; then echo "Keeping value of" $long fi - echo -e "\nCubeSatSim configuraation sim.cfg file updated to: \n" - echo $1 $2 $lat $long $5 - echo $1 $2 $lat $long $5 > /home/pi/CubeSatSim/sim.cfg + 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 if [ "$norestart" = "1" ]; then echo else +## echo +## echo "Rebooting CubeSatSim with new configuration file" +## echo + reboot=1 +## sudo reboot now +# sudo systemctl restart cubesatsim + fi + +elif [ "$1" = "-S" ]; then + + echo + echo "Scan both I2C buses on the Raspberry Pi" + echo + + echo "I2C Bus 1" + echo + i2cdetect -y 1 + echo + echo "I2C Bus 1" + echo + i2cdetect -y 3 + echo + +elif [ "$1" = "-C" ]; then + + echo + echo "Clear logs" + echo + + sudo systemctl stop cubesatsim + sudo systemctl stop transmit + sudo systemctl stop command + + sudo mv -f /home/pi/CubeSatSim/telem.txt /home/pi/CubeSatSim/telem.txt.bk + + sudo journalctl --rotate + sudo journalctl --vacuum-time=1s + + reboot=1 +## sudo systemctl reboot now + +## echo "rebooting" + +elif [ "$1" = "-T" ]; then + + echo + echo "Change command and control state" + echo + + FILE=/home/pi/CubeSatSim/command_control + if [ -f "$FILE" ]; then + echo "Radio command and control is ON" echo - echo "Restarting CubeSatSim with new configuraation file" + echo "Do you want to turn command and control to OFF (y/n) " + read reset echo - sudo systemctl restart cubesatsim + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Command and control set to OFF" + sudo rm /home/pi/CubeSatSim/command_control > /dev/null 2>&1 +# reboot=1 + echo "restarting command and control" + sudo systemctl restart command +## sudo reboot now + fi + + else + echo "Radio command and control is OFF" + echo + echo "Do you want to set command and control to ON (y/n) " + read reset + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Command and control set to ON" + sudo touch /home/pi/CubeSatSim/command_control + echo "restarting command and control" +# reboot=1 + sudo systemctl restart command +## sudo reboot now + fi + fi -fi -# sudo systemctl restart cubesatsim +elif [ "$1" = "-d" ]; then + + echo + echo "Change command and control Direwolf state" + echo + if [[ $(arecord -l | grep card) ]]; then + : + else + echo "Note: No USB Sound Card is plugged in!" + echo "Direwolf will not run unless one is plugged in." + fi + + FILE=/home/pi/CubeSatSim/command_control_direwolf + if [ -f "$FILE" ]; then + echo "Radio command and control with Direwolf for DTMF and APRS is ON" + echo + echo "Do you want to turn Direwolf OFF and do Carrier command and control (y/n) " + read reset + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Command and control Direwolf set to OFF" + sudo rm /home/pi/CubeSatSim/command_control_direwolf > /dev/null 2>&1 +# reboot=1 +## echo "rebooting" + sudo systemctl restart command +## sudo reboot now + fi + + else + echo "Radio command and control with Direwolf for DTMF and APRS is OFF so carrier command and control is enabled" + echo + echo "Do you want to set command and control with Direwolf for DTMF and APRS to ON (y/n) " + read reset + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Command and control Direwolf set to ON" + sudo touch /home/pi/CubeSatSim/command_control_direwolf +## echo "rebooting" +# reboot=1 + sudo systemctl restart command + if [[ $(arecord -l | grep card) ]]; then + restart=1 +### echo "restarting cubesatsim software" +### sudo systemctl restart cubesatsim + fi +## sudo reboot now + fi + + fi + + FILE=/home/pi/CubeSatSim/command_control + if [ -f "$FILE" ]; then + echo + + else + echo "Radio command and control is OFF" + echo + echo "Do you want to set command and control to ON (y/n) " + read reset + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Command and control set to ON" + sudo touch /home/pi/CubeSatSim/command_control + echo "restarting command and control" +# reboot=1 + sudo systemctl restart command +## sudo reboot now + fi + + fi + +elif [ "$1" = "-D" ]; then + + echo + echo "Change Transmit Commands state" + echo + + FILE=/home/pi/CubeSatSim/transmit_dtmf + if [ -f "$FILE" ]; then + echo "Transmit Commands in DTMF is set" + echo + echo "Do you want to Transmit Commands in APRS (y/n) " + read reset + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Transmit Commands in APRS" + sudo rm /home/pi/CubeSatSim/transmit_dtmf > /dev/null 2>&1 + fi + + else + echo "Transmit Commands in APRS is set" + echo + echo "Do you want to Transmit Commands in DTMF (y/n) " + read reset + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Transmit Commands in DTMF" + touch /home/pi/CubeSatSim/transmit_dtmf + fi + fi + +elif [ "$1" = "-R" ]; then + + echo + echo "Reset the Commands Count in the file command_count.txt" + echo + + echo "Current commands count is:" + cat /home/pi/CubeSatSim/commands_count.txt + echo + + echo "Do you want to reset the commands count to zero (y/n) " + read reset + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + sudo rm /home/pi/CubeSatSim/command_count.txt > /dev/null 2>&1 + echo "Commands count reset to 0" + echo "0\n" > /home/pi/CubeSatSim/command_count.txt + else + echo "Commands count not reset" + fi + +elif [ "$1" = "-B" ]; then + + echo + echo "Manually setting Safe Mode (battery saver mode)" + echo + + FILE=/home/pi/CubeSatSim/battery_saver + if [ -f "$FILE" ]; then + echo "Safe Mode! Battery saver mode is ON." + mode=1 + else + echo "Safe Mode is OFF." + echo "Battery saver mode is OFF." + mode=0 + fi + + echo + + echo "Do you want Safe Mode (battery saver mode) ON (y/n) " + read saver + echo + +## reboot=0 + + if [ "$saver" = "y" ] || [ "$saver" = "yes" ] ; then + if [ "$mode" = "0" ] ; then + echo "Safe Mode will be turned on! Battery saver will be turned ON" + sudo touch /home/pi/CubeSatSim/battery_saver + reboot=1 + fi + else + + if [ "$mode" = "1" ] ; then + echo "Safe Mode will be turned OFF. Battery saver mode will be turned OFF" + sudo rm /home/pi/CubeSatSim/battery_saver > /dev/null 2>&1 + reboot=1 + fi + fi + + if [ "$reboot" = "1" ] ; then + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" = "a" ] || [ "$1" = "s" ] || [ "$1" = "m" ] ; then + reboot=1 +## echo "rebooting" +## sudo reboot now + else + restart=1 +## echo "restarting" +## sudo systemctl restart cubesatsim + fi + fi + +elif [ "$1" = "-q" ]; then + + echo + echo "Editing the Squelch setting in" + echo "the configuration file for CubeSatSim" + echo + + value=`cat /home/pi/CubeSatSim/sim.cfg` + echo "$value" > /dev/null + set -- $value + + echo + echo "Current value of squelch is" + echo $6 + echo + +# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} + + echo -e "Enter squelch (integer 1 - 8): " + + read sq + + if [ -z $sq ] ; then + + sq="$6" + echo "Keeping value of" $lat + fi + + if ! [[ $sq =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] ; then + + echo "Error: not a number!" + sq="$6" + echo "Keeping value of" $sq + fi + +# 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 + echo "Restarting CubeSatSim with new configuration file" +## echo + +# reboot=1 +## sudo reboot now + sudo systemctl restart transmit + +elif [ "$1" = "-Q" ]; then + +# echo + echo "Reading current Squelch for 10 seconds" + echo "Squelch is active low (0 means squelch broken)" + echo + + timeout 10 bash -c -- 'while true; do (gpio read 22 && sleep 1); done' + +elif [ "$1" = "-P" ]; then + + echo + echo "Editing the PL (Private Line) CTCSS/CDCSS setting in" + echo "the configuration file for CubeSatSim" + echo + + value=`cat /home/pi/CubeSatSim/sim.cfg` + echo "$value" > /dev/null + set -- $value + + echo + echo "Current value of RX PL is" + echo ${10} + echo "Current value of TX PL is" + echo ${11} + echo + +# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} + + echo -e "Enter RX PL value integer 0: None, 01-38: CTCSS (analog, 39-121:CDCSS (digital)" + + read rxpl + + if [ -z $rxpl ] ; then + + rxpl="${10}" + echo "Keeping value of" $rxpl + else + restart=1 + fi + + if ! [[ $rxpl =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] ; then + + echo "Error: not a number!" + rxpl="${10}" + echo "Keeping value of" $rxpl + else + restart=1 + fi + + echo -e "Enter TX PL value integer 0: None, 01-38: CTCSS (analog, 39-121:CDCSS (digital)" + + read txpl + + if [ -z $txpl ] ; then + + txpl="${11}" + echo "Keeping value of" $txpl + fi + + if ! [[ $txpl =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] ; then + + echo "Error: not a number!" + txpl="${11}" + echo "Keeping value of" $txpl + fi + +# 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 +## echo "Rebooting CubeSatSim with new configuration file" +## echo + + reboot=1 +## sudo reboot now +# sudo systemctl restart cubesatsim + +elif [ "$1" = "-F" ]; then + + echo + echo "Editing the tx and rx frequency in the" + echo "configuration file for CubeSatSim" + echo + echo "Return keeps current value." +# echo -e "Current sim.cfg configuration file:" +# echo + + value=`cat /home/pi/CubeSatSim/sim.cfg` + echo "$value" > /dev/null + set -- $value + + echo "Current value of tx is" + echo $7 + echo + echo "Current value of rx is" + echo $8 + echo + +# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} + + echo "Enter tx frequency as 4XX.XXXX: " + read tx + + if [ -z $tx ] ; then + + tx="$7" + echo "Keeping value of" $tx + fi + + echo "Enter rx frequency as 4XX.XXXX: " + read rx + + if [ -z $rx ] ; then + + rx="$8" + echo "Keeping value of" $rx + fi +# else + + 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 +# else + echo + echo "Restarting CubeSatSim with new configuration file" +## echo +# reboot=1 +## sudo reboot now + sudo systemctl restart transmit +# fi + +elif [ "$1" = "-o" ]; then + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" == "n" ]; then + + transmit_command_beacon + + else + echo + echo "Change telemetry beacon transmit state" + echo + + FILE=/home/pi/CubeSatSim/beacon_off + if [ -f "$FILE" ]; then + echo "Transmit beacon telemetry is off" +# echo +# echo "Do you want to turn beacon telemetry ON (y/n) " +# read reset + + reset="y" + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Turn beacon telemetry ON" + sudo rm /home/pi/CubeSatSim/beacon_off > /dev/null 2>&1 + sudo systemctl restart transmit + # restart=1 + fi + + else + echo "Transmit beacon telemetry is on" +# echo +# echo "Do you want to turn beacon telemetry OFF (y/n) " +# read reset + reset="y" + echo + + if [ "$reset" = "y" ] || [ "$reset" = "yes" ] ; then + echo "Turn beacon telemetry OFF" + touch /home/pi/CubeSatSim/beacon_off + sudo systemctl restart transmit + # restart=1 + fi + fi + fi + +elif [ "$1" = "-H" ]; then + +# echo + echo "Editing the Balloon mode setting in" + echo "the configuration file for CubeSatSim" + echo + + value=`cat /home/pi/CubeSatSim/sim.cfg` + echo "$value" > /dev/null + set -- $value + + if [ "$9" = "yes" ] || [ "$9" = "y" ]; then + echo "Balloon mode is ON" + else + echo "Balloon mode is OFF" + fi + + echo + +# echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} + + echo "Do you want Balloon mode ON (y/n) " + read hab + echo + + if [ "$hab" = "y" ] || [ "$hab" = "yes" ] ; then + hab="yes" + echo "Balloon mode is ON" + else + hab="no" + echo "Balloon mode is OFF" + fi + +# 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 +## echo "Rebooting CubeSatSim with new configuration file" +## echo + + reboot=1 +## sudo reboot now +# sudo systemctl restart cubesatsim + +elif [ "$1" = "-p" ]; then + + echo "Real-time output from the serial port from the Pico:" + echo +# sleep 2 + timeout 2 cat /dev/serial0 > /dev/null + + timeout 3 cat /dev/serial0 + +elif [ "$1" = "-v" ]; then + + echo "Real-time output from the INA219 voltage and current sensors:" + echo + /home/pi/CubeSatSim/telem + +elif [ "$1" = "-e" ]; then + + echo "changing CubeSatSim to Repeater mode" + sudo echo "e" > /home/pi/CubeSatSim/.mode + + restart=1 + +elif [ "$1" = "-n" ]; then + + echo "changing CubeSatSim to Transmit Commands mode" + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" = "n" ]; then + echo "Turning Transmit Command and Control mode OFF" + echo "Switching to BPSK mode" + sudo echo "b" > /home/pi/CubeSatSim/.mode + reboot=1 + else + echo "Turning Transmit Command and Control mode ON" + sudo echo "n" > /home/pi/CubeSatSim/.mode + restart=1 + fi + +elif [ "$1" = "-A" ]; then + + echo "Transmit APRS control packets to control another CubeSatSim" + echo + + value=`cat /home/pi/CubeSatSim/.mode` + echo "$value" > /dev/null + set -- $value + + if [ "$1" != "n" ]; then + + sudo systemctl stop cubesatsim + sudo systemctl stop transmit + # sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + + sudo python3 -u /home/pi/CubeSatSim/transmit.py x > /dev/null 2>&1 & # Force APRS mode + fi + + sim="y" + + while [ "$sim" = "y" ] + do + + echo "Enter the mode number to change: 1=APRS, 2=FSK, 3=BPSK, 4=SSTV, 5=CW" + read MODE + + case $MODE in + + 1) + echo "Mode 1 is APRS" + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=a" + ;; + 2) + echo "Mode 2 is FSK" + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=f" + ;; + 3) + echo "Mode 3 is BPSK" + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=b" + ;; + 4) + echo "Mode 4 is SSTV" + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=s" + ;; + 5) + echo "Mode 5 is CW" + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=m" + ;; + *) + echo "Unknown mode" + STRING="AMSAT-11>APCSS:=3901.40N\07704.39WShi hi MODE=?" + ;; + esac + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 + echo $STRING > /home/pi/CubeSatSim/t.txt + echo + echo -n "Sending APRS packet " + echo $STRING + sudo touch /home/pi/CubeSatSim/ready + sleep 5 + sudo touch /home/pi/CubeSatSim/ready + + echo + echo "Do you want to send another APRS command packet (y/n) " + read sim + echo + done + sudo rm /home/pi/CubeSatSim/t.txt > /dev/null 2>&1 +# sudo systemctl restart cubesatsim + + if [ "$1" != "n" ]; then + + reboot=1 + fi + +elif [ "$1" = "-L" ]; then + + echo + echo "Setting microphone level for command and control" + echo + + echo -e "Enter microphone level in percentage (integer 0 - 100): " + + read mic + + if ! [ -z $mic ] && [[ $mic =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] ; then + echo "Updating mic level" + value=`arecord -l | grep "card"` && echo "$value" > /dev/null && set -- $value && amixer -c ${2:0:1} set Mic $mic% + else + echo "Not updating mic level" + fi + +elif [ "$1" = "-g" ]; then + + echo "Are you sure you want to reset the CubeSatSim configuration back to the default settings?" + echo + + read rset + echo + + if [ "$rset" = "y" ] || [ "$rset" = "yes" ] ; then + + echo "Resetting" + + echo "AMSAT 0 0 0 no 3 434.9 435 no 0 0" > /home/pi/CubeSatSim/sim.cfg + + sudo echo "b" > /home/pi/CubeSatSim/.mode + + sudo rm /home/pi/CubeSatSim/battery_saver > /dev/null 2>&1 + + sudo rm /home/pi/CubeSatSim/command_control > /dev/null 2>&1 + + sudo rm /home/pi/CubeSatSim/command_control_direwolf > /dev/null 2>&1 + + sudo rm /home/pi/CubeSatSim/beacon_off > /dev/null 2>&1 + + sudo echo "0" > /home/pi/CubeSatSim/command_count.txt + + sudo systemctl stop cubesatsim + sudo systemctl stop transmit + sudo systemctl stop command + + sudo mv -f /home/pi/CubeSatSim/telem.txt /home/pi/CubeSatSim/telem.txt.bk + + sudo journalctl --rotate + sudo journalctl --vacuum-time=1s + + reboot=1 + else + + echo "Not resetting" + + fi + +elif [ "$1" = "-h" ]; then + + echo "config OPTION" + echo + echo "Changes CubeSatSim mode, resets, or modifies configuration file" + echo + echo " -h This help info" + echo " -a Change to AFSK/APRS mode" + echo " -m Change to CW mode" + echo " -f Change to FSK/DUV mode" + echo " -b Change to BPSK mode" + echo " -s Change to SSTV mode" + echo " -n Change to Transmit Commands mode" + echo " -e Change to Repeater mode" + echo " -i Restart CubeSatsim software" + echo " -c Change the CALLSIGN in the configuration file sim.cfg" + echo " -t Change the Simulated Telemetry setting in sim.cfg" + echo " -r Change the Resets Count in the configuration file sim.cfg" + echo " -l Change the Latitude and Longitude in the configuration file sim.cfg" + echo " -S Scan both I2C buses on the Raspberry Pi" + echo " -C Clear logs" + echo " -T Change command and control state" + echo " -d Change command and control Direwolf state" + echo " -R Change the Commands Count in the file command_count.txt" + echo " -B Change Safe Mode (battery saver mode) manually" + echo " -q Change the Squelch setting for command receiver" + echo " -F Change the RX and TX frequency" + echo " -H Change the Balloon (HAB) mode" + echo " -p Display payload sensor data" + echo " -v Display voltage and current data" + echo " -P Change the PL (Private Line) CTCSS/CDCSS codes for RX and TX" + echo " -A Transmit APRS control packets to control another CubeSatSim" + echo " -D Change Transmit Commands state APRS or DTMF" + echo " -o Change telemetry beacon transmit state" + echo " -L Change microphone level for command and control" + echo " -g Reset configuration back to default settings" + + echo + exit + +else +# echo + echo "Unknown option. Try config -h for a list of supported options." + echo + +fi + +# sudo systemctl restart cubesatsim + +# echo "Checking for reboot or restart" + +# echo $noreboot + +#reboot=0 +#restart=1 + +if [ "$reboot" = "1" ] ; then + if [ "$noreboot" = "0" ] ; then + echo 'Reboot due to config change!' | wall + echo "Rebooting" + sudo systemctl stop transmit + sudo reboot now + else + echo "Reboot needed for changes to take effect" + fi +fi + +if [ "$restart" = "1" ] ; then + if [ "$reboot" = "0" ] ; then + echo "Restarting" +# sudo systemctl stop transmit + sudo systemctl restart cubesatsim + sudo systemctl restart transmit + else + echo "Restart needed for changes to take effect" + fi +fi diff --git a/direwolf-cc.conf b/direwolf-cc.conf new file mode 100644 index 000000000..8419355f2 --- /dev/null +++ b/direwolf-cc.conf @@ -0,0 +1,2 @@ +ADEVICE hw:CARD=Device,DEV=0 default +DTMF diff --git a/direwolf/direwolf-transmit-dtmf-aprs.conf b/direwolf/direwolf-transmit-dtmf-aprs.conf new file mode 100644 index 000000000..786102cd2 --- /dev/null +++ b/direwolf/direwolf-transmit-dtmf-aprs.conf @@ -0,0 +1,5 @@ +ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0 +MYCALL AMSAT +CHANNEL 0 +MODEM 1200 +CBEACON dest="DTMF-3" info="1 #" delay=0 diff --git a/direwolf/direwolf-transmit-dtmf-beacon.conf b/direwolf/direwolf-transmit-dtmf-beacon.conf new file mode 100644 index 000000000..6c022dea0 --- /dev/null +++ b/direwolf/direwolf-transmit-dtmf-beacon.conf @@ -0,0 +1,5 @@ +ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0 +MYCALL AMSAT +CHANNEL 0 +MODEM 1200 +CBEACON dest="DTMF-3" info="10 #" delay=0 diff --git a/direwolf/direwolf-transmit-dtmf-bpsk.conf b/direwolf/direwolf-transmit-dtmf-bpsk.conf new file mode 100644 index 000000000..a0ae9b54a --- /dev/null +++ b/direwolf/direwolf-transmit-dtmf-bpsk.conf @@ -0,0 +1,5 @@ +ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0 +MYCALL AMSAT +CHANNEL 0 +MODEM 1200 +CBEACON dest="DTMF-3" info="3 #" delay=0 diff --git a/direwolf/direwolf-transmit-dtmf-cw.conf b/direwolf/direwolf-transmit-dtmf-cw.conf new file mode 100644 index 000000000..8629754f1 --- /dev/null +++ b/direwolf/direwolf-transmit-dtmf-cw.conf @@ -0,0 +1,5 @@ +ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0 +MYCALL AMSAT +CHANNEL 0 +MODEM 1200 +CBEACON dest="DTMF-3" info="5 #" delay=0 diff --git a/direwolf/direwolf-transmit-dtmf-fsk.conf b/direwolf/direwolf-transmit-dtmf-fsk.conf new file mode 100644 index 000000000..f197e5837 --- /dev/null +++ b/direwolf/direwolf-transmit-dtmf-fsk.conf @@ -0,0 +1,5 @@ +ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0 +MYCALL AMSAT +CHANNEL 0 +MODEM 1200 +CBEACON dest="DTMF-3" info="2 #" delay=0 diff --git a/direwolf/direwolf-transmit-dtmf-sstv.conf b/direwolf/direwolf-transmit-dtmf-sstv.conf new file mode 100644 index 000000000..c58cb77fc --- /dev/null +++ b/direwolf/direwolf-transmit-dtmf-sstv.conf @@ -0,0 +1,5 @@ +ADEVICE hw:CARD=Loopback,DEV=0 hw:CARD=Headphones,DEV=0 +MYCALL AMSAT +CHANNEL 0 +MODEM 1200 +CBEACON dest="DTMF-3" info="4 #" delay=0 diff --git a/direwolf/direwolf.conf b/direwolf/direwolf.conf new file mode 100644 index 000000000..701d80b4c --- /dev/null +++ b/direwolf/direwolf.conf @@ -0,0 +1 @@ +ADEVICE plughw:CARD=Loopback,DEV=1 plughw:CARD=Loopback,DEV=0 diff --git a/dtmf_aprs_cc.py b/dtmf_aprs_cc.py new file mode 100644 index 000000000..befe58c73 --- /dev/null +++ b/dtmf_aprs_cc.py @@ -0,0 +1,200 @@ +import sys +from os import system +import RPi.GPIO as GPIO +from RPi.GPIO import output +from time import sleep +import logging +logging.basicConfig(format='%(message)s') +# logging.warning('CC-Warning!') + +if __name__ == "__main__": + powerPin = 16 + txLed = 27 + change_mode = False + debug_mode = False + counter = 1 + if (len(sys.argv)) > 1: +# print("There are arguments!") + if ('d' == sys.argv[1]): + debug_mode = True + + for line in sys.stdin: +# if (debug_mode): + print(line, end =" ") + logging.warning(line) + +# if '^c' == line.rstrip(): +# break + + if ((line.find("MODE=a")) > 0): + system("echo '\nAPRS Mode!!\n'") + mode = 'a' + change_mode = True + counter = (counter + 1) % 2 + if ((line.find("DTMF>APDW15:t1#")) > 0): + system("echo '\nAPRS Mode!!\n'") + mode = 'a' + change_mode = True + if ((line.find("MODE=f")) > 0): + system("echo '\nFSK Mode!!\n'") + mode = 'f' + change_mode = True + counter = (counter + 1) % 2 + if ((line.find("DTMF>APDW15:t2#")) > 0): + system("echo '\nFSK Mode!!\n'") + mode = 'f' + change_mode = True + if ((line.find("MODE=b")) > 0): + system("echo '\nBPSK Mode!!\n'") + mode = 'b' + change_mode = True + counter = (counter + 1) % 2 + if ((line.find("DTMF>APDW15:t3#")) > 0): + system("echo '\nBPSK Mode!!\n'") + mode = 'b' + change_mode = True + if ((line.find("MODE=s")) > 0): + system("echo '\nSSTV Mode!!\n'") + mode = 's' + change_mode = True + counter = (counter + 1) % 2 + if ((line.find("DTMF>APDW15:t4#")) > 0): + system("echo '\nSSTV Mode!!\n'") + mode = 's' + change_mode = True + if ((line.find("MODE=m")) > 0): + system("echo '\nCW Mode!!\n'") + mode = 'm' + change_mode = True + counter = (counter + 1) % 2 + if ((line.find("DTMF>APDW15:t5#")) > 0): + system("echo '\nCW Mode!!\n'") + mode = 'm' + change_mode = True + if ((line.find("MODE=n")) > 0): + system("echo '\nTransmit Commands Mode!!\n'") + mode = 'n' + change_mode = True + counter = (counter + 1) % 2 + if ((line.find("DTMF>APDW15:t11#")) > 0): + system("echo '\nTransmit Commands Mode!!\n'") + mode = 'n' + change_mode = True +# Currently, C2C does not support Repeater mode e + if ((line.find("MODE=o")) > 0): + system("echo '\nBeacon Mode toggle!!\n'") + mode = 'o' + change_mode = True + counter = (counter + 1) % 2 + if ((line.find("DTMF>APDW15:t10#")) > 0): + system("echo '\nBeacon Mode toggle!!\n'") + mode = 'o' + change_mode = True + + if (debug_mode == False) and (change_mode == True) and (counter == 1): # skip every other APRS command since Direwolf prints them twice + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(powerPin, GPIO.OUT) + GPIO.setup(txLed, GPIO.OUT) + + if (mode == 'f'): + GPIO.output(powerPin, 0) # blink two times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + elif (mode == 'b'): + GPIO.output(powerPin, 0) # blink three times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + elif (mode == 's'): + GPIO.output(powerPin, 0) # blink four times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + elif (mode == 'm'): + GPIO.output(powerPin, 0) # blink five times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1); + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + elif (mode == 'a'): + mode = 'a' + GPIO.output(powerPin, 0) # blink one time + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + try: + file = open("/home/pi/CubeSatSim/command_count.txt", "r") + string = file.read() + file.close() + command_count = int(string) + command_count += 1 + filec = open("/home/pi/CubeSatSim/command_count.txt", "w") + command_count_string = str(command_count) + print(command_count_string) + string = filec.write(command_count_string) + filec.close() + except: + print("Can't write command_count file!") + print("Command_count: ") + print(command_count) + + GPIO.output(txLed, 0) + GPIO.output(powerPin, 0) + system("sudo systemctl stop rpitx") +# system("sudo systemctl stop cubesatsim") + + print("\n/home/pi/CubeSatSim/config -" + mode) + system("/home/pi/CubeSatSim/config -" + mode) + + + change_mode = False + + print("Waiting 5 seconds to allow unplug and plug of soundcard") + sleep(5) + print("Done") + diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1.mnb b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1.mnb new file mode 100644 index 000000000..71762841c --- /dev/null +++ b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1.mnb @@ -0,0 +1,16 @@ +D1 66.29 64.52 0 1N5817 D-2.5 +D2 72.01 10.49 0 1N5817 D-2.5 +D3 66.45 10.62 180 1N4148 D-2.5 +D4 71.58 64.49 0 1N5817 D-2.5 +D8 59.41 6.91 270 DNI/5V1 Zener 1W ZDIO-2.5 +D9 19.71 45.92 0 DNI/1N5817 D-2.5 +D10 77.50 10.46 0 1N5817 D-2.5 +JP1 72.09 8.41 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP2 24.74 59.61 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP3 19.63 58.93 270 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP4 71.53 62.46 0 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP5 74.93 68.28 270 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP6 26.14 37.01 180 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP7 15.95 61.98 90 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP8 37.80 36.96 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +X1 73.61 73.10 270 SC1464-ND PG203J diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1.mnt b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1.mnt new file mode 100644 index 000000000..13698afc5 --- /dev/null +++ b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1.mnt @@ -0,0 +1,37 @@ +C1 19.33 75.46 270 18pF C0603 +C2 19.28 71.32 270 16pF C0603 +C3 16.38 10.11 180 18pF C0603 +C4 20.68 10.16 180 16pF C0603 +C7 55.60 56.62 0 DNI/47uF C0603 +C8 58.42 47.83 270 DNI/100nF C0603 +C10 66.83 3.91 270 DNI/100nF C0603 +D5 66.01 67.21 180 DNI/B5817WS SOD-323F +D6 72.16 8.69 180 DNI/B5817WS SOD-323F +D7 66.47 8.84 0 DNI/4148WS SOD-323F +D11 77.44 8.74 180 DNI/B5817WS SOD-323F +E1 7.06 75.34 180 ANT-916-CHP-T XDCR_ANT-916-CHP-T +E2 19.05 3.94 0 ANT-916-CHP-T XDCR_ANT-916-CHP-T +J1 32.55 66.61 0 CONN_20X2 2X20 +J8 37.19 71.83 0 Sparkfun USB-C Breakout 1X06_NO_SILK +J9 37.36 73.97 180 DNI/USB4105-GF-A or GT-USB-7010B USB-C-16P-2LAYER-PADS +L1 17.25 73.38 90 13nH L0603 +L2 18.49 12.17 180 13nH L0603 +R2 56.11 62.23 0 DNI/1k R0603 +R4 60.50 62.23 180 DNI/1k R0603 +R5 30.48 76.28 180 DNI/5.1k R0603 +R6 44.20 76.30 0 DNI/5.1k R0603 +R10 65.68 71.81 0 DNI/1k R0603 +R11 25.17 71.88 0 DNI/100 R0603 +R12 48.56 72.24 0 DNI/220 R0603 +R16 20.07 60.05 0 DNI/68 R0805 +R17 24.61 60.05 270 DNI/180 R0603 +R18 32.94 60.20 180 DNI/68 R0805 +R21 55.42 51.26 0 DNI/100 R0603 +R22 56.59 44.55 0 DNI/220 R0603 +R25 64.24 40.89 90 DNI/4.7k R0603 +R26 74.70 40.61 90 DNI/4.7k R0603 +R28 61.98 8.81 0 DNI/10k R0603 +R31 3.86 44.37 0 DNI/1k R0603 +R32 3.40 60.55 180 DNI/100 R0603 +U1 54.43 24.61 270 Raspberry Pi Pico PICO-PKG-NO_DEBUG +U6 39.24 51.22 270 SRFRS0W5 SR_FRS_0W5 diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bnames.pdf b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bnames.pdf new file mode 100644 index 000000000..493f2e583 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bnames.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bom.csv.txt b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bom.csv.txt new file mode 100644 index 000000000..11c1485d9 --- /dev/null +++ b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bom.csv.txt @@ -0,0 +1,54 @@ +"Qty";"Value";"Device";"Package";"Parts";"Description";""; +"2";"100";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R8, R30";"Resistor";""; +"1";"100";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"R19";"Resistor";""; +"2";"100nF";"CAPPTH";"CAP-PTH-SMALL";"C6, C9";"Capacitor";""; +"1";"10K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R27";"Resistor";""; +"2";"13nH";"SMD-FERRITE-CHIP-120-OHM-500MA(0603)";"L0603";"L1, L2";"303030001";""; +"2";"16pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"C2, C4";"302010097";""; +"1";"180";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R14";"Resistor";""; +"2";"18pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"C1, C3";"302010097";""; +"2";"1K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R1, R3";"Resistor";""; +"1";"1N4148";"DIODE-D-2.5";"D-2.5";"D3";"DIODE";""; +"4";"1N5817";"DIODE-D-2.5";"D-2.5";"D1, D2, D4, D10";"DIODE";""; +"2";"1k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R7, R29";"Resistor";""; +"1";"220";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R9";"Resistor";""; +"1";"220";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"R20";"Resistor";""; +"2";"4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R23, R24";"Resistor";""; +"1";"47uF";"CAPPTH";"CAP-PTH-SMALL";"C5";"Capacitor";""; +"2";"68";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R13, R15";"Resistor";""; +"2";"ANT-916-CHP-T";"ANT-916-CHP-T";"XDCR_ANT-916-CHP-T";"E1, E2";"868MHz ISM, LoRa, Sensor Networks, SigFox Chip RF Antenna 863MHz ~ 873MHz 0.5dBi Solder Surface Mount Check prices";""; +"1";"BME280";"M04NO_SILK_ALL_ROUND";"1X04_NO_SILK_ALL_ROUND";"J5";"Header 4";""; +"2";"Blue 5mm";"LED3MM";"LED3MM";"LED2, LED4";"LED";""; +"1";"CONN_20X2";"CONN_20X2";"2X20";"J1";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"3";"DNI/100";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"R11, R21, R32";"301010206";""; +"2";"DNI/100nF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"C8, C10";"302010097";""; +"1";"DNI/10k";"R-EU_R0603";"R0603";"R28";"RESISTOR, European symbol";""; +"1";"DNI/180";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"R17";"301010206";""; +"1";"DNI/1N5817";"DIODE-D-2.5";"D-2.5";"D9";"DIODE";""; +"2";"DNI/1k";"R-EU_R0603";"R0603";"R2, R4";"RESISTOR, European symbol";""; +"2";"DNI/1k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"R10, R31";"301010206";""; +"1";"DNI/1x4 pin header";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"J12";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"2";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"R12, R22";"301010206";""; +"2";"DNI/4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"R33, R34";"Resistor";""; +"2";"DNI/4.7k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"R25, R26";"301010206";""; +"1";"DNI/4148WS";"DIODESOD-323F";"SOD-323F";"D7";"Diode";""; +"1";"DNI/47uF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"C7";"302010097";""; +"2";"DNI/5.1k";"R-EU_R0603";"R0603";"R5, R6";"RESISTOR, European symbol";""; +"1";"DNI/5V1 Zener 1W";"ZENER-DIODEZD-2.5";"ZDIO-2.5";"D8";"Z-Diode";""; +"2";"DNI/68";"R-US_R0805";"R0805";"R16, R18";"RESISTOR, American symbol";""; +"3";"DNI/B5817WS";"DIODESOD-323F";"SOD-323F";"D5, D6, D11";"Diode";""; +"1";"DNI/Sparkfun QWIIC Breakout";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"J10";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"1";"DNI/Test Point for MIC_IN";"CONN_01PTH_NO_SILK_YES_STOP";"1X01_NO_SILK";"J11";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"1";"DNI/USB4105-GF-A or GT-USB-7010B";"USB_C_2-LAYER_PADS";"USB-C-16P-2LAYER-PADS";"J9";"USB Type C 16Pin Connector";""; +"2";"Green 5mm";"LED3MM";"LED3MM";"LED1, LED3";"LED";""; +"3";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"JP3, JP4, JP6";"Normally closed trace jumper";""; +"5";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"JP1, JP2, JP5, JP7, JP8";"Normally open jumper";""; +"1";"MPU6050";"M08NO_SILK_FEMALE_PTH";"1X08_NO_SILK@1";"J4";"Header 8";""; +"2";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"J6, J7";"Standard 2-pin 0.1" header. Use with";""; +"1";"RA-SPST";"RA-SPST";"RA-SPST";"S1";"";""; +"1";"Raspberry Pi Pico";"RASPBERRY_PICO-NO_DEBUG";"PICO-PKG-NO_DEBUG";"U1";"";""; +"1";"Red 5mm";"LED3MM";"LED3MM";"LED5";"LED";""; +"1";"SC1464-ND";"PG203J";"PG203J";"X1";"MIC/HEADPHONE JACK";""; +"2";"SMA-VERT";"SMA-VERT";"SMA-VERT";"X2, X3";"";""; +"1";"SRFRS0W5";"SR_FRS_0W5";"SR_FRS_0W5";"U6";"";""; +"1";"Sparkfun USB-C Breakout";"CONN_06NO_SILK_FEMALE_PTH";"1X06_NO_SILK";"J8";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bottom.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bottom.png new file mode 100644 index 000000000..74b6f58d6 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_bottom.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_gerbers.zip b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_gerbers.zip new file mode 100644 index 000000000..dca7e79e7 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_gerbers.zip differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_pcb.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_pcb.png new file mode 100644 index 000000000..d05ed4960 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_pcb.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_pour.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_pour.png new file mode 100644 index 000000000..06cc698c8 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_pour.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_schematic.pdf b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_schematic.pdf new file mode 100644 index 000000000..bc1fa3c73 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_schematic.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_tnames.pdf b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_tnames.pdf new file mode 100644 index 000000000..afd460463 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_tnames.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_top.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_top.png new file mode 100644 index 000000000..261839d71 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.1_top.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3._bottom.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3._bottom.png new file mode 100644 index 000000000..2204c7ed2 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3._bottom.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3.mnb b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3.mnb new file mode 100644 index 000000000..d707b0c83 --- /dev/null +++ b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3.mnb @@ -0,0 +1,14 @@ +D1 63.80 60.53 0 1N5817 D-2.5 +D2 72.01 10.49 0 1N5817 D-2.5 +D3 66.45 10.62 180 1N4148 D-2.5 +D8 59.31 7.52 270 DNI/5V1 Zener 1W ZDIO-2.5 +D9 19.71 45.92 0 DNI/1N5817 D-2.5 +D10 77.50 10.46 0 1N5817 D-2.5 +JP1 72.16 8.66 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP2 24.74 59.61 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP3 19.63 58.93 270 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP5 75.08 56.49 270 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP6 26.31 37.01 180 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP7 15.95 61.98 90 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP8 37.92 40.67 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +X1 71.86 61.21 270 SC1464-ND PG203J diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3.mnt b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3.mnt new file mode 100644 index 000000000..d536d87fc --- /dev/null +++ b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3.mnt @@ -0,0 +1,37 @@ +C1 18.75 76.02 270 18pF C0603 +C2 18.69 71.88 270 16pF C0603 +C3 16.38 10.11 180 18pF C0603 +C4 20.68 10.16 180 16pF C0603 +C7 55.60 56.62 0 DNI/47uF C0603 +C8 59.00 47.55 270 DNI/100nF C0603 +C10 66.83 3.91 270 DNI/100nF C0603 +D5 63.83 62.51 180 DNI/B5817WS SOD-323F +D6 72.16 8.69 180 DNI/B5817WS SOD-323F +D7 66.47 8.84 0 DNI/4148WS SOD-323F +E1 7.06 75.34 180 ANT-916-CHP-T XDCR_ANT-916-CHP-T +E2 19.05 3.94 0 ANT-916-CHP-T XDCR_ANT-916-CHP-T +J1 32.55 66.61 0 CONN_20X2 2X20 +J3 8.71 38.41 0 SJ1-2503A CONN_SJ1-2503A +J8 36.17 72.01 0 Sparkfun USB-C Breakout 1X06_NO_SILK +J9 36.35 74.15 180 DNI/USB4105-GF-A or GT-USB-7010B USB-C-16P-2LAYER-PADS +L1 16.76 73.94 90 13nH L0603 +L2 18.49 12.17 180 13nH L0603 +R2 54.00 62.26 0 DNI/1k R0603 +R4 58.39 62.26 180 DNI/1k R0603 +R5 29.46 76.45 180 DNI/5.1k R0603 +R6 43.18 76.48 0 DNI/5.1k R0603 +R10 64.26 72.06 0 DNI/1k R0603 +R11 24.16 72.06 0 DNI/100 R0603 +R12 47.55 72.42 0 DNI/220 R0603 +R16 20.07 60.05 0 DNI/68 R0805 +R17 24.71 60.15 270 DNI/180 R0603 +R18 32.94 60.20 180 DNI/68 R0805 +R21 55.42 51.26 0 DNI/100 R0603 +R22 59.33 44.63 0 DNI/220 R0603 +R25 67.59 40.77 90 DNI/4.7k R0603 +R26 76.53 40.79 90 DNI/4.7k R0603 +R28 61.98 8.81 0 DNI/10k R0603 +R31 3.86 44.37 0 DNI/1k R0603 +R32 3.40 60.55 180 DNI/100 R0603 +U1 54.36 27.48 270 Raspberry Pi Pico PICO-PKG-NO_DEBUG +U6 39.24 51.22 270 SR105U SR_FRS_0W5 diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_gerbers.zip b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_gerbers.zip new file mode 100644 index 000000000..9828f0aca Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_gerbers.zip differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_pcb.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_pcb.png new file mode 100644 index 000000000..0aadd9470 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_pcb.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_pour.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_pour.png new file mode 100644 index 000000000..8dcc59962 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_pour.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_schematic.pdf b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_schematic.pdf new file mode 100644 index 000000000..8f92a4ca1 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_schematic.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_top.png b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_top.png new file mode 100644 index 000000000..9b76469dd Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-STEM-b1.3.2.3_top.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.1b_bottom.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.1b_bottom.png new file mode 100644 index 000000000..012b63dd5 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.1b_bottom.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.1b_top.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.1b_top.png new file mode 100644 index 000000000..a68568d96 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.1b_top.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_bottom.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_bottom.png new file mode 100644 index 000000000..dfeb330e6 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_bottom.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_gerbers.zip b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_gerbers.zip new file mode 100644 index 000000000..4b48013a9 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_gerbers.zip differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_pcb.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_pcb.png new file mode 100644 index 000000000..42c58a446 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_pcb.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_pour.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_pour.png new file mode 100644 index 000000000..35769b63a Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_pour.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_schematic.pdf b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_schematic.pdf new file mode 100644 index 000000000..06e3cc6b3 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_schematic.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_top.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_top.png new file mode 100644 index 000000000..3433fa7d7 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2.2_top.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bnames.pdf b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bnames.pdf new file mode 100644 index 000000000..6bb434266 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bnames.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bom.csv.txt b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bom.csv.txt new file mode 100644 index 000000000..31a2e012e --- /dev/null +++ b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bom.csv.txt @@ -0,0 +1,16 @@ +"Part";"Value";"Device";"Package";"Description";"COPYRIGHT";"DESCRIPTION";"DIGI-KEY_PART_NUMBER";"DIGI-KEY_PART_NUMBER_1";"DIGI-KEY_PART_NUMBER_2";"DIGI-KEY_PART_NUMBER_3";"DIGI-KEY_PART_NUMBER_4";"MANUFACTURER_PART_NUMBER";"MF";"MFR_NAME";"MP";"PACKAGE";"PURCHASE-URL";"REFDES";"TYPE"; +"BT2";"AA battery holder BH3AA-PC";"BH3AA-PC";"BAT_BH3AA-PC";"Holder Batt 3-Aa Cells Pc Mount";"";" Battery Holder (Open) AA 3 Cell PC Pin ";"BH3AA-PC-ND";"";"";"";"";"";"MPD";"";"BH3AAPC";"None";"https://pricing.snapeda.com/search/part/BH3AAPC/?ref=eda";"";""; +"C1";"DNI/0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"F1";"PTC";"PTCPTH";"PTC";"Resettable Fuse PTC";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP1";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP2";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP3";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP4";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP5";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP6";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP7";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"JP8";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"R1";"DNI/R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"U1";"INA219 purple board";"INA219";"INA219";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";""; +"U2";"INA219AIDR";"INA219AIDR";"D0008A_N";"";"Copyright (C) 2022 Ultra Librarian. All rights reserved.";"";"";"296-23978-1-ND";"296-23978-2-ND";"296-23978-6-ND";"2156-INA219AIDR-ND";"INA219AIDR";"";"Texas Instruments";"";"";"";"RefDes";"TYPE"; diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bottom.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bottom.png new file mode 100644 index 000000000..17c913ea0 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_bottom.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_gerbers.zip b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_gerbers.zip new file mode 100644 index 000000000..539adccb0 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_gerbers.zip differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_pcb.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_pcb.png new file mode 100644 index 000000000..85fb997d5 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_pcb.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_pour.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_pour.png new file mode 100644 index 000000000..ee11aa9ba Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_pour.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_schematic.pdf b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_schematic.pdf new file mode 100644 index 000000000..8b5e4d29a Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_schematic.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_tnames.pdf b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_tnames.pdf new file mode 100644 index 000000000..7bbc04886 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_tnames.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_top.png b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_top.png new file mode 100644 index 000000000..d2cea4b15 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-battery-b1.3.2b_top.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_bottom.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_bottom.png new file mode 100644 index 000000000..6705d6367 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_bottom.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_gerbers.zip b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_gerbers.zip new file mode 100644 index 000000000..4588fe1e0 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_gerbers.zip differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_pcb.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_pcb.png new file mode 100644 index 000000000..970c44e34 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_pcb.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_pour.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_pour.png new file mode 100644 index 000000000..a05e58e9c Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_pour.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_schematic.pdf b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_schematic.pdf new file mode 100644 index 000000000..721fb95a9 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_schematic.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_top.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_top.png new file mode 100644 index 000000000..94d79206d Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2.1_top.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._bottom.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._bottom.png new file mode 100644 index 000000000..dd161800c Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._bottom.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._pcb.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._pcb.png new file mode 100644 index 000000000..31e547863 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._pcb.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._pour.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._pour.png new file mode 100644 index 000000000..36aa645f5 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._pour.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._top.png b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._top.png new file mode 100644 index 000000000..90f293394 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2._top.png differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_bnames.pdf b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_bnames.pdf new file mode 100644 index 000000000..2161269a6 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_bnames.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_bom.csv.txt b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_bom.csv.txt new file mode 100644 index 000000000..98f15be60 --- /dev/null +++ b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_bom.csv.txt @@ -0,0 +1,18 @@ +"Qty";"Value";"Device";"Package";"Parts";"Description";""; +"2";"";"CONN_01PTH_NO_SILK_YES_STOP";"1X01_NO_SILK";"JP16, JP19";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"6";"0.1µF";"CAP_CERAMIC0603";"0603";"C2, C3, C4, C5, C6, C7";"Ceramic Capacitors";""; +"6";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"D7, D8, D9, D10, D11, D12";"Schottky diode";""; +"6";"1N5817";"DIODE-D-2.5";"D-2.5";"D1, D2, D3, D4, D5, D6";"DIODE";""; +"2";"4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"R3, R4";"Resistor";""; +"1";"CONN_20X2";"CONN_20X2";"2X20";"J1";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"2";"DNI-4.7k";"R-US_R0603";"R0603";"R11, R12";"RESISTOR, American symbol";""; +"2";"DNI-4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"R7, R8";"Resistor";""; +"1";"DNI/Sparkfun QWIIC Breakout";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"J5";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"1";"Female socket 1x4";"CONN_06NO_SILK_NO_POP";"1X06_NO_SILK";"J4";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"6";"INA219 purple board";"INA219";"INA219";"U3, U4, U5, U6, U7, U8";"";""; +"6";"INA219AIDR";"INA219AIDR";"D0008A_N";"U2, U10, U11, U12, U13, U14";"";""; +"1";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"JP18";"Normally open jumper";""; +"1";"Micro JST";"CONN_021X02_NO_SILK";"1X02_NO_SILK";"JP8";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"14";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"JP1, JP2, JP3, JP4, JP5, JP6, JP7, JP10, JP11, JP12, JP13, JP14, JP15, JP17";"Standard 2-pin 0.1" header. Use with";""; +"6";"R100";"R-US_R0805";"R0805";"R1, R2, R5, R6, R9, R10";"RESISTOR, American symbol";""; +"1";"VDD-EN";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"JP9";"Normally closed trace jumper";""; diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_gerbers.zip b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_gerbers.zip new file mode 100644 index 000000000..6acd612ae Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_gerbers.zip differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_schematic.pdf b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_schematic.pdf new file mode 100644 index 000000000..749176d72 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_schematic.pdf differ diff --git a/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_tnames.pdf b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_tnames.pdf new file mode 100644 index 000000000..e9fae5fb6 Binary files /dev/null and b/hardware/beta-v1.3.2/cubesatsim-solar-b1.3.2_tnames.pdf differ diff --git a/hardware/beta-v1.3.2/readme.md b/hardware/beta-v1.3.2/readme.md new file mode 100644 index 000000000..16c85c0c9 --- /dev/null +++ b/hardware/beta-v1.3.2/readme.md @@ -0,0 +1,35 @@ + + +Here is information about the Beta version of the CubeSatSim V2 Boards, version beta v1.3.2 + +There are 3 boards: STEM Payload, Solar (was Main in v1), and Battery + +Here's what the files are: + +*_gerbers.zip -- All gerber files used to fabricate PCBs along with .TXT drill file + +*_schematic.pdf -- Schematic + +*_pcb.png -- View of board + +*_pour.png -- View of board with fill + +*_top.png -- Top view of PCB generated by gerbers + +*_bottom.png -- Bottom view of PCB generated by gerbers + +*_tNames.pdf -- Top outline of components + +*_bNames.pdf -- Bottom outline of components + +*.mnt -- top SMD component placement data + +*.mnb -- bottom SMD component placement data + +*_bom.csv.txt -- Bill of Materials in CSV format + +I use PCBWay to fabricate PCBs https://pcbway.com + +Here is a very draft bill of materials: https://docs.google.com/spreadsheets/d/1Ta5UaJcinGozcheROrkfwXdGSDUZrXvQ1_nbIBdIIOY/edit?usp=sharing + +Draft wiki instructions: https://github.com/alanbjohnston/CubeSatSim/wiki/v1.3.2-0.-Home diff --git a/hardware/frame/v1.3.2/cubesatsim_frame_side.v1.3.2.stl b/hardware/frame/v1.3.2/cubesatsim_frame_side.v1.3.2.stl new file mode 100644 index 000000000..96d694348 Binary files /dev/null and b/hardware/frame/v1.3.2/cubesatsim_frame_side.v1.3.2.stl differ diff --git a/hardware/frame/v1.3.2/cubesatsim_frame_side_camera.v1.3.2.stl b/hardware/frame/v1.3.2/cubesatsim_frame_side_camera.v1.3.2.stl new file mode 100644 index 000000000..ff97bc1cf Binary files /dev/null and b/hardware/frame/v1.3.2/cubesatsim_frame_side_camera.v1.3.2.stl differ diff --git a/hardware/frame/v1.3.2/cubesatsim_frame_top_bottom.v1.3.2.stl b/hardware/frame/v1.3.2/cubesatsim_frame_top_bottom.v1.3.2.stl new file mode 100644 index 000000000..88e4a6143 Binary files /dev/null and b/hardware/frame/v1.3.2/cubesatsim_frame_top_bottom.v1.3.2.stl differ diff --git a/hardware/frame/v1.3.2/readme.md b/hardware/frame/v1.3.2/readme.md new file mode 100644 index 000000000..a09f30a7b --- /dev/null +++ b/hardware/frame/v1.3.2/readme.md @@ -0,0 +1,9 @@ +These are the STL files for printing the frame. + +You will need to print two of the top/bottom, and one of each side + +The source is availale at: + +https://cad.onshape.com/documents/ba47819ff100597297d1d967/w/f19409ec7cd5459afb429cb9/e/a0e0cc37dee6fb879c4bcc2b +https://cad.onshape.com/documents/5374160b1b209f298471bf23/w/77e97d7333356f1dcfe6c902/e/6c75800e116cf1f6a984aaa4 +https://cad.onshape.com/documents/1e544928f336f4755d6edfbe/w/b9582e1314647916bddf672c/e/41923e90fc3648cd04399c0e diff --git a/hardware/frame/v2.0/cubesatsim_frame_side.v2.0.stl b/hardware/frame/v2.0/cubesatsim_frame_side.v2.0.stl new file mode 100644 index 000000000..175042696 Binary files /dev/null and b/hardware/frame/v2.0/cubesatsim_frame_side.v2.0.stl differ diff --git a/hardware/frame/v2.0/cubesatsim_frame_side_camera.v2.0.stl b/hardware/frame/v2.0/cubesatsim_frame_side_camera.v2.0.stl new file mode 100644 index 000000000..3e6cf0a76 Binary files /dev/null and b/hardware/frame/v2.0/cubesatsim_frame_side_camera.v2.0.stl differ diff --git a/hardware/frame/v2.0/cubesatsim_frame_top_bottom.v2.0.stl b/hardware/frame/v2.0/cubesatsim_frame_top_bottom.v2.0.stl new file mode 100644 index 000000000..88e4a6143 Binary files /dev/null and b/hardware/frame/v2.0/cubesatsim_frame_top_bottom.v2.0.stl differ diff --git a/hardware/frame/v2.0/readme.md b/hardware/frame/v2.0/readme.md new file mode 100644 index 000000000..ccb58d268 --- /dev/null +++ b/hardware/frame/v2.0/readme.md @@ -0,0 +1,11 @@ +These are the STL files for printing the frame. + +![CubeSatSim Frame v2.0](https://github.com/user-attachments/assets/bbcedd26-cc1b-488d-86fa-b6e12f46bd6a) + +You will need to print two of the top/bottom, and one of each side + +The source is availale at: + +https://cad.onshape.com/documents/ba47819ff100597297d1d967/w/f19409ec7cd5459afb429cb9/e/a0e0cc37dee6fb879c4bcc2b +https://cad.onshape.com/documents/1515e31c7fa5f6258ef39ae7/w/36f6069826ee0c0263f8d85e/e/2b7801717a8e1af3df455057 +https://cad.onshape.com/documents/188300bd4469521b14597507/w/546e1730182c1520c46b050d/e/ceef7084a00eb9b26c486bb6 diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1.mnb b/hardware/v2.0/cubesatsim-battery-v2.0.1.mnb new file mode 100644 index 000000000..48b4e2ca1 --- /dev/null +++ b/hardware/v2.0/cubesatsim-battery-v2.0.1.mnb @@ -0,0 +1,3 @@ +JP4 12.92 79.27 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP5 66.93 74.27 90 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP6 17.51 69.85 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1.mnt b/hardware/v2.0/cubesatsim-battery-v2.0.1.mnt new file mode 100644 index 000000000..5646f1682 --- /dev/null +++ b/hardware/v2.0/cubesatsim-battery-v2.0.1.mnt @@ -0,0 +1,11 @@ +BT1 44.48 57.58 0 1024 BAT_1024 +BT2 41.27 29.90 0 1012 BAT_1012 +C1 4.88 58.78 0 DNI/0.1µF 0603 +J1 32.68 74.23 0 CONN_20X2 2X20 +JP9 3.38 54.25 0 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP10 6.71 50.72 0 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP11 6.85 54.23 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP12 3.31 50.70 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +R1 17.45 69.49 0 DNI/R100 R0805 +U1 12.19 67.41 180 INA219 purple board INA219 +U2 4.55 62.79 0 INA219AIDR D0008A_N diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_bom.csv.txt b/hardware/v2.0/cubesatsim-battery-v2.0.1_bom.csv.txt new file mode 100644 index 000000000..d7850b630 --- /dev/null +++ b/hardware/v2.0/cubesatsim-battery-v2.0.1_bom.csv.txt @@ -0,0 +1,23 @@ +"Part";"Value";"Device";"Package";"Description";""; +"BT1";"1024";"1024";"BAT_1024";"Check availability";""; +"BT2";"1012";"1012";"BAT_1012";"Check availability";""; +"C1";"DNI/0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";""; +"F1";"PTC";"PTCPTH";"PTC";"Resettable Fuse PTC";""; +"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP1";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP2";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP3";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP4";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP5";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";""; +"JP6";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP7";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP8";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP9";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";""; +"JP10";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";""; +"JP11";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP12";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP13";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP14";"";"CONN_01";"1X01";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"R1";"DNI/R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"U1";"INA219 purple board";"INA219";"INA219";"";""; +"U2";"INA219AIDR";"INA219AIDR";"D0008A_N";"";""; diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_bottom.png b/hardware/v2.0/cubesatsim-battery-v2.0.1_bottom.png new file mode 100644 index 000000000..41f92256d Binary files /dev/null and b/hardware/v2.0/cubesatsim-battery-v2.0.1_bottom.png differ diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_centroid.zip b/hardware/v2.0/cubesatsim-battery-v2.0.1_centroid.zip new file mode 100644 index 000000000..d72238760 Binary files /dev/null and b/hardware/v2.0/cubesatsim-battery-v2.0.1_centroid.zip differ diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_gerbers.zip b/hardware/v2.0/cubesatsim-battery-v2.0.1_gerbers.zip new file mode 100644 index 000000000..273179833 Binary files /dev/null and b/hardware/v2.0/cubesatsim-battery-v2.0.1_gerbers.zip differ diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_pcb.png b/hardware/v2.0/cubesatsim-battery-v2.0.1_pcb.png new file mode 100644 index 000000000..1d2f98ad0 Binary files /dev/null and b/hardware/v2.0/cubesatsim-battery-v2.0.1_pcb.png differ diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_pour.png b/hardware/v2.0/cubesatsim-battery-v2.0.1_pour.png new file mode 100644 index 000000000..ab4c33853 Binary files /dev/null and b/hardware/v2.0/cubesatsim-battery-v2.0.1_pour.png differ diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_schematic.pdf b/hardware/v2.0/cubesatsim-battery-v2.0.1_schematic.pdf new file mode 100644 index 000000000..681a87c72 Binary files /dev/null and b/hardware/v2.0/cubesatsim-battery-v2.0.1_schematic.pdf differ diff --git a/hardware/v2.0/cubesatsim-battery-v2.0.1_top.png b/hardware/v2.0/cubesatsim-battery-v2.0.1_top.png new file mode 100644 index 000000000..fa61c7085 Binary files /dev/null and b/hardware/v2.0/cubesatsim-battery-v2.0.1_top.png differ diff --git a/hardware/v2.0/cubesatsim-main-v2.0.mnb b/hardware/v2.0/cubesatsim-main-v2.0.mnb new file mode 100644 index 000000000..8d335ba68 --- /dev/null +++ b/hardware/v2.0/cubesatsim-main-v2.0.mnb @@ -0,0 +1,18 @@ +D1 63.55 60.58 0 1N5817 D-2.5 +D2 72.01 10.49 0 1N5817 D-2.5 +D3 66.45 10.62 180 1N4148 D-2.5 +D4 63.65 54.61 0 1N5817 D-2.5 +D8 59.31 7.52 270 DNI/5V1 Zener 1W ZDIO-2.5 +D9 19.71 45.92 0 DNI/1N5817 D-2.5 +D10 77.50 10.46 0 1N5817 D-2.5 +JP1 72.17 8.66 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP2 24.73 59.61 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP3 19.63 58.93 270 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP4 51.94 53.34 180 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP5 75.08 56.49 270 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP6 26.31 37.01 180 JUMPER-SMT_2_NC_TRACE_SILK SMT-JUMPER_2_NC_TRACE_SILK +JP7 15.95 61.99 90 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP8 37.93 40.67 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP9 45.17 51.10 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +JP10 63.64 56.54 0 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +X1 71.86 61.21 270 SC1464-ND PG203J diff --git a/hardware/v2.0/cubesatsim-main-v2.0.mnt b/hardware/v2.0/cubesatsim-main-v2.0.mnt new file mode 100644 index 000000000..a364bdebd --- /dev/null +++ b/hardware/v2.0/cubesatsim-main-v2.0.mnt @@ -0,0 +1,39 @@ +C1 18.75 76.02 270 18pF C0603 +C2 18.69 71.88 270 16pF C0603 +C3 16.38 10.11 180 18pF C0603 +C4 20.68 10.16 180 16pF C0603 +C7 55.60 56.62 0 DNI/47uF C0603 +C8 59.00 47.55 270 DNI/100nF C0603 +C10 66.83 3.91 270 DNI/100nF C0603 +D5 63.53 62.56 180 DNI/B5817WS SOD-323F +D6 72.16 8.69 180 DNI/B5817WS SOD-323F +D7 66.47 8.84 0 DNI/4148WS SOD-323F +D11 63.65 56.59 180 DNI/B5817WS SOD-323F +E1 6.80 76.35 180 ANT-916-CHP-T XDCR_ANT-916-CHP-T +E2 19.18 3.81 0 ANT-916-CHP-T XDCR_ANT-916-CHP-T +J1 32.55 66.61 0 CONN_20X2 2X20 +J8 36.17 72.01 0 Sparkfun USB-C Breakout 1X06_NO_SILK +J9 36.35 74.15 180 DNI/USB4105-GF-A or GT-USB-7010B USB-C-16P-2LAYER-PADS +J13 8.92 31.68 0 SJ1-2503A CONN_SJ1-2503A +J14 15.95 31.76 0 SJ1-2503A CONN_SJ1-2503A +L1 16.76 73.94 90 13nH L0603 +L2 18.49 12.17 180 13nH L0603 +R2 54.00 62.26 0 DNI/1k R0603 +R4 58.39 62.26 180 DNI/1k R0603 +R5 29.46 76.45 180 DNI/5.1k R0603 +R6 43.18 76.48 0 DNI/5.1k R0603 +R10 64.26 72.06 0 DNI/1k R0603 +R11 24.16 72.06 0 DNI/100 R0603 +R12 47.55 72.42 0 DNI/220 R0603 +R16 20.07 60.05 0 DNI/68 R0805 +R17 24.71 60.15 270 DNI/180 R0603 +R18 32.94 60.20 180 DNI/68 R0805 +R21 55.42 51.26 0 DNI/100 R0603 +R22 59.33 44.63 0 DNI/220 R0603 +R25 67.59 40.77 90 DNI/4.7k R0603 +R26 76.53 40.79 90 DNI/4.7k R0603 +R28 61.98 8.81 0 DNI/10k R0603 +R31 3.86 44.37 0 DNI/220 R0603 +R32 3.40 60.55 180 DNI/1k R0603 +U1 54.36 27.48 270 Raspberry Pi Pico PICO-PKG-NO_DEBUG +U6 39.24 51.22 270 SR105U SR_FRS_0W5 diff --git a/hardware/v2.0/cubesatsim-main-v2.0_bom.csv.txt b/hardware/v2.0/cubesatsim-main-v2.0_bom.csv.txt new file mode 100644 index 000000000..55ff16da5 --- /dev/null +++ b/hardware/v2.0/cubesatsim-main-v2.0_bom.csv.txt @@ -0,0 +1,93 @@ +"Part";"Value";"Device";"Package";"Description";""; +"C1";"18pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";""; +"C2";"16pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";""; +"C3";"18pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";""; +"C4";"16pF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";""; +"C5";"47uF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";""; +"C6";"100nF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";""; +"C7";"DNI/47uF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";""; +"C8";"DNI/100nF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";""; +"C9";"100nF";"CAPPTH";"CAP-PTH-SMALL";"Capacitor";""; +"C10";"DNI/100nF";"CERAMIC-10PF-50V-5%-NPO(0603)";"C0603";"302010097";""; +"D1";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D2";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D3";"1N4148";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D4";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D5";"DNI/B5817WS";"DIODESOD-323F";"SOD-323F";"Diode";""; +"D6";"DNI/B5817WS";"DIODESOD-323F";"SOD-323F";"Diode";""; +"D7";"DNI/4148WS";"DIODESOD-323F";"SOD-323F";"Diode";""; +"D8";"DNI/5V1 Zener 1W";"ZENER-DIODEZD-2.5";"ZDIO-2.5";"Z-Diode";""; +"D9";"DNI/1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D10";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D11";"DNI/B5817WS";"DIODESOD-323F";"SOD-323F";"Diode";""; +"E1";"ANT-916-CHP-T";"ANT-916-CHP-T";"XDCR_ANT-916-CHP-T";"868MHz ISM, LoRa, Sensor Networks, SigFox Chip RF Antenna 863MHz ~ 873MHz 0.5dBi Solder Surface Mount Check prices";""; +"E2";"ANT-916-CHP-T";"ANT-916-CHP-T";"XDCR_ANT-916-CHP-T";"868MHz ISM, LoRa, Sensor Networks, SigFox Chip RF Antenna 863MHz ~ 873MHz 0.5dBi Solder Surface Mount Check prices";""; +"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"J4";"MPU6050";"M08NO_SILK_FEMALE_PTH";"1X08_NO_SILK@1";"Header 8";""; +"J5";"BME280";"M04NO_SILK_ALL_ROUND";"1X04_NO_SILK_ALL_ROUND";"Header 4";""; +"J6";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"J7";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"J8";"Sparkfun USB-C Breakout";"CONN_06NO_SILK_FEMALE_PTH";"1X06_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"J9";"DNI/USB4105-GF-A or GT-USB-7010B";"USB_C_2-LAYER_PADS";"USB-C-16P-2LAYER-PADS";"USB Type C 16Pin Connector";""; +"J10";"DNI/Sparkfun QWIIC Breakout";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"J12";"DNI/1x4 pin header";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"J13";"SJ1-2503A";"SJ1-2503A";"CONN_SJ1-2503A";"";""; +"J14";"SJ1-2503A";"SJ1-2503A";"CONN_SJ1-2503A";"";""; +"J15";"";"CONN_06NO_SILK_NO_POP";"1X06_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP1";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP2";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP3";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";""; +"JP4";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";""; +"JP5";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP6";"JUMPER-SMT_2_NC_TRACE_SILK";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";""; +"JP7";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP8";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP9";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP10";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"L1";"13nH";"SMD-FERRITE-CHIP-120-OHM-500MA(0603)";"L0603";"303030001";""; +"L2";"13nH";"SMD-FERRITE-CHIP-120-OHM-500MA(0603)";"L0603";"303030001";""; +"LED1";"Yellow 5mm";"LED3MM";"LED3MM";"LED";""; +"LED2";"White 5mm";"LED3MM";"LED3MM";"LED";""; +"LED3";"Green 5mm";"LED3MM";"LED3MM";"LED";""; +"LED4";"Blue 5mm";"LED3MM";"LED3MM";"LED";""; +"LED5";"Red 5mm";"LED3MM";"LED3MM";"LED";""; +"R1";"1K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R2";"DNI/1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";""; +"R3";"1K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R4";"DNI/1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";""; +"R5";"DNI/5.1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";""; +"R6";"DNI/5.1k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";""; +"R7";"1k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R8";"100";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R9";"220";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R10";"DNI/1k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R11";"DNI/100";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R12";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R13";"68";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R14";"180";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R15";"68";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R16";"DNI/68";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R17";"DNI/180";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R18";"DNI/68";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R19";"100";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";""; +"R20";"220";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";""; +"R21";"DNI/100";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R22";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R23";"4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R24";"4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R25";"DNI/4.7k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R26";"DNI/4.7k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R27";"10K";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R28";"DNI/10k";"R-EU_R0603";"R0603";"RESISTOR, European symbol";""; +"R29";"220";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R30";"1k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R31";"DNI/220";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R32";"DNI/1k";"SMD-RES-1.2K-1%-1/10W(0603)";"R0603";"301010206";""; +"R33";"DNI/4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"R34";"DNI/4.7k";"RESISTORPTH-1/4W-VERT";"AXIAL-0.1";"Resistor";""; +"S1";"RA-SPST";"RA-SPST";"RA-SPST";"";""; +"U1";"Raspberry Pi Pico";"RASPBERRY_PICO-NO_DEBUG";"PICO-PKG-NO_DEBUG";"";""; +"U6";"SR105U";"SR_FRS_0W5";"SR_FRS_0W5";"";""; +"X1";"SC1464-ND";"PG203J";"PG203J";"MIC/HEADPHONE JACK";""; +"X2";"SMA-VERT";"SMA-VERT";"SMA-VERT";"";""; +"X3";"SMA-VERT";"SMA-VERT";"SMA-VERT";"";""; diff --git a/hardware/v2.0/cubesatsim-main-v2.0_bottom.png b/hardware/v2.0/cubesatsim-main-v2.0_bottom.png new file mode 100644 index 000000000..e298f5819 Binary files /dev/null and b/hardware/v2.0/cubesatsim-main-v2.0_bottom.png differ diff --git a/hardware/v2.0/cubesatsim-main-v2.0_gerbers.zip b/hardware/v2.0/cubesatsim-main-v2.0_gerbers.zip new file mode 100644 index 000000000..eed74445a Binary files /dev/null and b/hardware/v2.0/cubesatsim-main-v2.0_gerbers.zip differ diff --git a/hardware/v2.0/cubesatsim-main-v2.0_pcb.png b/hardware/v2.0/cubesatsim-main-v2.0_pcb.png new file mode 100644 index 000000000..29633023f Binary files /dev/null and b/hardware/v2.0/cubesatsim-main-v2.0_pcb.png differ diff --git a/hardware/v2.0/cubesatsim-main-v2.0_pour.png b/hardware/v2.0/cubesatsim-main-v2.0_pour.png new file mode 100644 index 000000000..96f242199 Binary files /dev/null and b/hardware/v2.0/cubesatsim-main-v2.0_pour.png differ diff --git a/hardware/v2.0/cubesatsim-main-v2.0_schematic.pdf b/hardware/v2.0/cubesatsim-main-v2.0_schematic.pdf new file mode 100644 index 000000000..d266622bf Binary files /dev/null and b/hardware/v2.0/cubesatsim-main-v2.0_schematic.pdf differ diff --git a/hardware/v2.0/cubesatsim-main-v2.0_top.png b/hardware/v2.0/cubesatsim-main-v2.0_top.png new file mode 100644 index 000000000..40cb176e4 Binary files /dev/null and b/hardware/v2.0/cubesatsim-main-v2.0_top.png differ diff --git a/hardware/v2.0/cubesatsim-solar-v2.0.mnb b/hardware/v2.0/cubesatsim-solar-v2.0.mnb new file mode 100644 index 000000000..3ac6ed082 --- /dev/null +++ b/hardware/v2.0/cubesatsim-solar-v2.0.mnb @@ -0,0 +1,12 @@ +D1 37.58 48.87 180 1N5817 D-2.5 +D2 37.66 42.52 180 1N5817 D-2.5 +D3 37.50 35.95 180 1N5817 D-2.5 +D4 42.94 48.94 0 1N5817 D-2.5 +D5 42.94 42.42 0 1N5817 D-2.5 +D6 42.79 36.07 0 1N5817 D-2.5 +JP9 1.35 57.85 270 VDD-EN SMT-JUMPER_2_NC_TRACE_SILK +JP18 24.75 62.60 180 JUMPER-SMT_2_NO_SILK SMT-JUMPER_2_NO_SILK +U5 71.44 19.89 90 INA219 purple board INA219 +U6 8.59 48.95 270 INA219 purple board INA219 +U7 8.46 20.29 270 INA219 purple board INA219 +U8 71.36 48.21 90 INA219 purple board INA219 diff --git a/hardware/v2.0/cubesatsim-solar-v2.0.mnt b/hardware/v2.0/cubesatsim-solar-v2.0.mnt new file mode 100644 index 000000000..54cb3f584 --- /dev/null +++ b/hardware/v2.0/cubesatsim-solar-v2.0.mnt @@ -0,0 +1,29 @@ +C2 17.54 37.77 0 0.1µF 0603 +C3 17.41 21.59 0 0.1µF 0603 +C4 17.56 11.14 0 0.1µF 0603 +C5 17.53 50.09 0 0.1µF 0603 +C6 61.82 19.28 180 0.1µF 0603 +C7 62.06 38.65 180 0.1µF 0603 +D7 42.95 38.00 0 1A/23V/620mV SOD-323 +D8 43.08 44.40 0 1A/23V/620mV SOD-323 +D9 43.43 50.75 0 1A/23V/620mV SOD-323 +D10 37.72 50.67 180 1A/23V/620mV SOD-323 +D11 37.62 37.92 180 1A/23V/620mV SOD-323 +D12 37.90 44.40 180 1A/23V/620mV SOD-323 +J1 32.55 66.61 0 CONN_20X2 2X20 +R1 11.58 43.79 270 R100 R0805 +R2 11.68 15.01 270 R100 R0805 +R5 24.84 14.99 90 R100 R0805 +R6 24.87 43.84 270 R100 R0805 +R9 68.07 25.10 90 R100 R0805 +R10 68.19 53.47 90 R100 R0805 +R11 42.91 62.08 0 DNI-4.7k R0603 +R12 36.87 62.08 0 DNI-4.7k R0603 +U2 17.53 44.60 0 INA219AIDR D0008A_N +U3 48.65 48.20 90 INA219 purple board INA219 +U4 30.84 48.90 270 INA219 purple board INA219 +U10 17.45 26.75 0 INA219AIDR D0008A_N +U11 17.68 16.66 0 INA219AIDR D0008A_N +U12 17.50 55.36 0 INA219AIDR D0008A_N +U13 61.72 24.82 0 INA219AIDR D0008A_N +U14 61.58 44.20 0 INA219AIDR D0008A_N diff --git a/hardware/v2.0/cubesatsim-solar-v2.0_bom.csv.txt b/hardware/v2.0/cubesatsim-solar-v2.0_bom.csv.txt new file mode 100644 index 000000000..c761de98a --- /dev/null +++ b/hardware/v2.0/cubesatsim-solar-v2.0_bom.csv.txt @@ -0,0 +1,64 @@ +"Part";"Value";"Device";"Package";"Description";""; +"C2";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";""; +"C3";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";""; +"C4";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";""; +"C5";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";""; +"C6";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";""; +"C7";"0.1µF";"CAP_CERAMIC0603";"0603";"Ceramic Capacitors";""; +"D1";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D2";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D3";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D4";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D5";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D6";"1N5817";"DIODE-D-2.5";"D-2.5";"DIODE";""; +"D7";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";""; +"D8";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";""; +"D9";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";""; +"D10";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";""; +"D11";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";""; +"D12";"1A/23V/620mV";"DIODE-SCHOTTKY-BAT20J";"SOD-323";"Schottky diode";""; +"J1";"CONN_20X2";"CONN_20X2";"2X20";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"J5";"DNI/Sparkfun QWIIC Breakout";"CONN_041X04_NO_SILK";"1X04_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP1";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP2";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP3";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP4";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP5";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP6";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP7";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP8";"Micro JST";"CONN_021X02_NO_SILK";"1X02_NO_SILK";"Multi connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP9";"VDD-EN";"JUMPER-SMT_2_NC_TRACE_SILK";"SMT-JUMPER_2_NC_TRACE_SILK";"Normally closed trace jumper";""; +"JP10";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP11";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP12";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP13";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP14";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP15";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP16";"";"CONN_01PTH_NO_SILK_YES_STOP";"1X01_NO_SILK";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"JP17";"Micro JST";"M02JST-PTH-VERT";"JST-2-PTH-VERT";"Standard 2-pin 0.1" header. Use with";""; +"JP18";"JUMPER-SMT_2_NO_SILK";"JUMPER-SMT_2_NO_SILK";"SMT-JUMPER_2_NO_SILK";"Normally open jumper";""; +"JP19";"";"CONN_01PTH_NO_SILK_YES_STOP";"1X01_NO_SILK";"Single connection point. Often used as Generic Header-pin footprint for 0.1 inch spaced/style header connections";""; +"R1";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R2";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R3";"4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";""; +"R4";"4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";""; +"R5";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R6";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R7";"DNI-4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";""; +"R8";"DNI-4.7k";"RESISTORPTH-1/4W-VERT-KIT";"AXIAL-0.1EZ";"Resistor";""; +"R9";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R10";"R100";"R-US_R0805";"R0805";"RESISTOR, American symbol";""; +"R11";"DNI-4.7k";"R-US_R0603";"R0603";"RESISTOR, American symbol";""; +"R12";"DNI-4.7k";"R-US_R0603";"R0603";"RESISTOR, American symbol";""; +"U2";"INA219AIDR";"INA219AIDR";"D0008A_N";"";""; +"U3";"INA219 purple board";"INA219";"INA219";"";""; +"U4";"INA219 purple board";"INA219";"INA219";"";""; +"U5";"INA219 purple board";"INA219";"INA219";"";""; +"U6";"INA219 purple board";"INA219";"INA219";"";""; +"U7";"INA219 purple board";"INA219";"INA219";"";""; +"U8";"INA219 purple board";"INA219";"INA219";"";""; +"U10";"INA219AIDR";"INA219AIDR";"D0008A_N";"";""; +"U11";"INA219AIDR";"INA219AIDR";"D0008A_N";"";""; +"U12";"INA219AIDR";"INA219AIDR";"D0008A_N";"";""; +"U13";"INA219AIDR";"INA219AIDR";"D0008A_N";"";""; +"U14";"INA219AIDR";"INA219AIDR";"D0008A_N";"";""; diff --git a/hardware/v2.0/cubesatsim-solar-v2.0_bottom.png b/hardware/v2.0/cubesatsim-solar-v2.0_bottom.png new file mode 100644 index 000000000..d227199f6 Binary files /dev/null and b/hardware/v2.0/cubesatsim-solar-v2.0_bottom.png differ diff --git a/hardware/v2.0/cubesatsim-solar-v2.0_gerbers.zip b/hardware/v2.0/cubesatsim-solar-v2.0_gerbers.zip new file mode 100644 index 000000000..5c910832c Binary files /dev/null and b/hardware/v2.0/cubesatsim-solar-v2.0_gerbers.zip differ diff --git a/hardware/v2.0/cubesatsim-solar-v2.0_schematic.pdf b/hardware/v2.0/cubesatsim-solar-v2.0_schematic.pdf new file mode 100644 index 000000000..283f53565 Binary files /dev/null and b/hardware/v2.0/cubesatsim-solar-v2.0_schematic.pdf differ diff --git a/hardware/v2.0/cubesatsim-solar-v2.0_top.png b/hardware/v2.0/cubesatsim-solar-v2.0_top.png new file mode 100644 index 000000000..f5afb2ddc Binary files /dev/null and b/hardware/v2.0/cubesatsim-solar-v2.0_top.png differ diff --git a/hardware/v2.0/readme.md b/hardware/v2.0/readme.md new file mode 100644 index 000000000..74dc6a559 --- /dev/null +++ b/hardware/v2.0/readme.md @@ -0,0 +1,31 @@ +cubesatsim-battery-v2 0 1_top cubesatsim-main-v2 0_top cubesatsim-solar-v2 0_top + +Here is information about the CubeSatSim PCBs, version v2.0 + +There are 3 boards: Main, Solar, and Battery + +Here's what the files are: + +*_gerbers.zip -- All gerber files used to fabricate PCBs along with .TXT drill file + +*_schematic.pdf -- Schematic + +*_pcb.png -- View of board + +*_pour.png -- View of board with fill + +*_top.png -- Top view of PCB generated by gerbers + +*_bottom.png -- Bottom view of PCB generated by gerbers + +*.mnt -- top SMD component placement data + +*.mnb -- bottom SMD component placement data + +*_bom.csv.txt -- Bill of Materials in CSV format + +I use PCBWay to fabricate PCBs https://pcbway.com + +Here is a very draft bill of materials: https://CubeSatSim.org/bom-v2 + +Wiki instructions: https://github.com/alanbjohnston/CubeSatSim/wiki/ diff --git a/ina219.py b/ina219.py index 5da9eeecd..6f1b44bd6 100644 --- a/ina219.py +++ b/ina219.py @@ -7,6 +7,12 @@ from adafruit_extended_bus import ExtendedI2C as I2C from adafruit_ina219 import INA219 from adafruit_ina219 import ADCResolution, BusVoltageRange +import signal + +# Don't turn these signal into exceptions, just die. +# https://stackoverflow.com/questions/26692284/how-to-prevent-brokenpipeerror-when-doing-a-flush-in-python +signal.signal(signal.SIGINT, signal.SIG_DFL) +signal.signal(signal.SIGPIPE, signal.SIG_DFL) if __name__ == "__main__": # print 'Length: ', len(sys.argv) @@ -346,8 +352,11 @@ print("Python Error Recovered!") if not single: - inp = input() -# print(inp) + try: + inp = input() +# print(inp) + except: + print("Python error getting input!") else: break diff --git a/install b/install index c47cb7d37..2991d2b8d 100755 --- a/install +++ b/install @@ -1,6 +1,6 @@ #!/bin/bash -echo -e "\ninstallation script for CubeSatSim v1.2\n" +echo -e "\ninstallation script for CubeSatSim v2.0\n" FILE=/home/pi/CubeSatSim/sim.cfg if [ -f "$FILE" ]; then @@ -10,6 +10,22 @@ else echo "AMSAT 1 0.0 0.0" > /home/pi/CubeSatSim/sim.cfg fi +FILE=/home/pi/CubeSatSim/command_tx +if [ -f "$FILE" ]; then + echo "$FILE exists." +else + echo "creating $FILE" + echo "True\n" > /home/pi/CubeSatSim/command_tx +fi + +FILE=/home/pi/CubeSatSim/command_count.txt +if [ -f "$FILE" ]; then + echo "$FILE exists." +else + echo "creating $FILE" + echo "0\n" > /home/pi/CubeSatSim/command_count.txt +fi + cd CubeSatSim/config -c -n @@ -18,30 +34,37 @@ CubeSatSim/config -l -n sudo apt-get update && sudo apt-get dist-upgrade -y +sudo apt-get remove pulseaudio -y + # removed wiringpi and python-picamera python3-picamera sudo apt-get install -y git libasound2-dev i2c-tools build-essential libgd-dev libmagic-dev minicom cd /tmp -wget https://project-downloads.drogon.net/wiringpi-latest.deb +# wget https://project-downloads.drogon.net/wiringpi-latest.deb + +# sudo dpkg -i wiringpi-latest.deb + +cd -sudo dpkg -i wiringpi-latest.deb +git clone https://github.com/alanbjohnston/WiringPi +cd WiringPi +./build debian +sudo dpkg -i debian-template/wiringpi-2.61-1.deb cd #changed to python3-smbus -sudo apt install -y python3-pip python3-smbus +sudo apt install -y python3-pip python3-smbus libjpeg-dev zlib1g-dev libfreetype6-dev libopenjp2-7 libtiff5 python3-pil python3-serial sudo pip3 install --upgrade setuptools sudo pip3 install adafruit-blinka RPI.GPIO adafruit-extended-bus adafruit-circuitpython-ina219 - - cd ~/CubeSatSim -git pull +git pull --no-rebase make debug @@ -50,7 +73,7 @@ if [ -f "$FILE" ]; then echo "$FILE exists." else echo "creating $FILE" - echo "ARG1=f" > .mode + echo "b" > .mode fi cd @@ -72,7 +95,7 @@ git clone https://github.com/alanbjohnston/pi-power-button.git cd pi-power-button -git checkout v1.2 +git checkout master ./script/install @@ -91,7 +114,6 @@ cp /home/pi/CubeSatSim/sstv/sstv_image_1_320_x_256.jpg /home/pi/CubeSatSim/sstv_ echo "Copying SSTV image 2" cp /home/pi/CubeSatSim/sstv/sstv_image_2_320_x_256.jpg /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg - cd git clone https://github.com/alanbjohnston/rpitx.git @@ -101,15 +123,21 @@ cd rpitx ./install.sh +cd + cd sudo cp ~/CubeSatSim/systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service sudo systemctl enable cubesatsim -sudo cp ~/CubeSatSim/systemd/rpitx.service /etc/systemd/system/rpitx.service +sudo cp ~/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service + +# sudo systemctl enable transmit + +sudo cp ~/CubeSatSim/systemd/command.service /etc/systemd/system/command.service -sudo systemctl enable rpitx +sudo systemctl enable command sudo cp /boot/config.txt /boot/config.txt.0 @@ -125,8 +153,13 @@ sudo raspi-config nonint do_legacy 0 #if [ "$1" = "u" ]; then #fi - sudo sed -i 's/console=serial0,115200 //g' /boot/cmdline.txt +## sudo sed -i 's/console=serial0,115200 //g' /boot/cmdline.txt + + sudo sed -i 's/console=serial0,115200 //g' /boot/cmdline.txt + + sudo sed -i 's/console=tty1 r/console=tty1 maxcpus=1 r/g' /boot/cmdline.txt # single core if Pi Zero 2 + sudo sed -i 's/#dtparam=i2c_arm=on/dtparam=i2c_arm=on/g' /boot/config.txt if [[ $(grep 'dtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24' /boot/config.txt) ]]; then @@ -164,6 +197,73 @@ sudo raspi-config nonint do_legacy 0 sudo sed -i 's/ rootwait/ rootwait modules-load=dwc2,g_ether/g' /boot/cmdline.txt fi + if [[ $(grep 'dtparam=audio=on' /boot/config.txt) ]]; then + echo "dtparam=audio=on already in /boot/config.txt" + else + echo "adding dtparam=audio=on to /boot/config.txt" + sudo sh -c 'echo "\ndtparam=audio=on" >> /boot/config.txt' + fi + + if [[ $(grep 'dtoverlay=audremap,enable_jack=on' /boot/config.txt) ]]; then + echo "dtoverlay=audremap,enable_jack=on already in /boot/config.txt" + else + echo "adding dtoverlay=audremap,enable_jack=on to /boot/config.txt" + sudo sh -c 'echo "\ndtoverlay=audremap,enable_jack=on" >> /boot/config.txt' + fi + + if [[ $(grep 'dtoverlay=pwm,pin=18,func=2' /boot/config.txt) ]]; then + echo "dtoverlay=pwm,pin=18,func=2 already in /boot/config.txt" + else + echo "adding to /boot/config.txt" + sudo sh -c 'echo "\ndtoverlay=pwm,pin=18,func=2" >> /boot/config.txt' + fi + + if [[ $(grep 'disable_splash=1 ' /boot/config.txt) ]]; then + echo "disable_splash=1 already in /boot/config.txt" + else + echo "adding to /boot/config.txt" + sudo sh -c 'echo "\ndisable_splash=1" >> /boot/config.txt' + fi + + if [[ $(grep 'boot_delay=0' /boot/config.txt) ]]; then + echo "boot_delay=0 already in /boot/config.txt" + else + echo "adding to /boot/config.txt" + sudo sh -c 'echo "\nboot_delay=0" >> /boot/config.txt' + fi + + if ! grep -q force_turbo=1 /boot/config.txt ; then sudo sh -c 'echo "force_turbo=1" >> /boot/config.txt'; fi + +sudo sh -c 'echo "\n" >> /boot/config.txt' + +changed=0 +value=`cat /home/pi/CubeSatSim/sim.cfg` +echo "$value" > /dev/null +set -- $value + +if [ -z "$1" ] ; then n1="AMSAT" ; changed=1 ; else n1=$1 ; fi # callsign +if [ -z "$2" ] ; then n2="0" ; changed=1 ; else n2=$2 ; fi # reset count +if [ -z "$3" ] ; then n3="0" ; changed=1 ; else n3=$3 ; fi # lat +if [ -z "$4" ] ; then n4="0" ; changed=1 ; else n4=$4 ; fi # lon +if [ -z "$5" ] ; then n5="no" ; changed=1 ; else n5=$5 ; fi # sim mode +if [ -z "$6" ] ; then n6="3" ; changed=1 ; else n6=$6 ; fi # squelch +if [ -z "$7" ] ; then n7="434.9000" ; changed=1 ; else n7=$7 ; fi # transmit frequency +if [ -z "$8" ] ; then n8="435.0000" ; changed=1 ; else n8=$8 ; fi # receive frequency +if [ -z "$9" ] ; then n9="no" ; changed=1 ; else n9=$9 ; fi # hab mode +if [ -z "$10" ] ; then n10="0" ; changed=1 ; else n10=$10 ; fi # rx pl code +if [ -z "$11" ] ; then n11="0" ; changed=1 ; else n11=$11 ; fi # tx pl code + +if [ $changed -eq 1 ]; then + echo -e "Current sim.cfg configuration file:" + echo + echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 + echo -e "\nCubeSatSim configuraation sim.cfg file updated to: \n" + echo + echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $10 $11 + echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $10 $11 > /home/pi/CubeSatSim/sim.cfg + echo +fi + echo "Would you like to reboot to complete the installation (y/n)?" read -r ANS diff --git a/log b/log index 9518703d4..2a3ce9d73 100755 --- a/log +++ b/log @@ -2,10 +2,14 @@ echo -e "\nLog file script for CubeSatSim\n" -if [ "$1" = "-r" ]; then - sudo journalctl -a -u rpitx > /home/pi/CubeSatSim/logr.txt - cat /home/pi/CubeSatSim/logr.txt - echo -e "\nLog file also saved as /home/pi/CubeSatSim/logr.txt" +if [ "$1" = "-r" ] || [ "$1" = "-t" ] ; then + sudo journalctl -a -u transmit > /home/pi/CubeSatSim/logt.txt + cat /home/pi/CubeSatSim/logt.txt + echo -e "\nTransmit Log file also saved as /home/pi/CubeSatSim/logt.txt" +elif [ "$1" = "-c" ]; then + sudo journalctl -a -u command > /home/pi/CubeSatSim/logc.txt + cat /home/pi/CubeSatSim/logc.txt + echo -e "\nCommand and Control Log file also saved as /home/pi/CubeSatSim/logc.txt" else sudo journalctl -a -u cubesatsim > /home/pi/CubeSatSim/log.txt cat /home/pi/CubeSatSim/log.txt diff --git a/main.c b/main.c index 46c35239f..9ceb0827f 100644 --- a/main.c +++ b/main.c @@ -18,35 +18,144 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - - + #include "main.h" +//#define HAB // uncomment to change APRS icon from Satellite to Balloon and only BAT telemetry + int main(int argc, char * argv[]) { + + printf("\n\nCubeSatSim v2.0 starting...\n\n"); + + wiringPiSetup(); + + // Open configuration file with callsign and reset count + FILE * config_file = fopen("/home/pi/CubeSatSim/sim.cfg", "r"); + if (config_file == NULL) { + printf("Creating config file."); + config_file = fopen("/home/pi/CubeSatSim/sim.cfg", "w"); + fprintf(config_file, "%s %d", " ", 100); + fclose(config_file); + config_file = fopen("/home/pi/CubeSatSim/sim.cfg", "r"); + } + +// 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); + 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, "Transmit on %s MHz Receive on %s MHz\n", tx, rx); + + FILE * uptime_file = fopen("/proc/uptime", "r"); + fscanf(uptime_file, "%f", & uptime_sec); + printf("Uptime sec: %f \n", uptime_sec); + fclose(uptime_file); +// program_radio(); // do in transmit instead + if (uptime_sec < 30.0) { + reset_count = (reset_count + 1) % 0xffff; // only increment uptime if just rebooted + fprintf(stderr,"INFO: Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime_sec); + } + + if ((fabs(lat_file) > 0) && (fabs(lat_file) < 90.0) && (fabs(long_file) > 0) && (fabs(long_file) < 180.0)) { + fprintf(stderr, "Valid latitude and longitude in config file\n"); +// convert to APRS DDMM.MM format +// latitude = toAprsFormat(lat_file); +// longitude = toAprsFormat(long_file); + latitude = lat_file; + longitude = long_file; + fprintf(stderr, "Lat/Long %f %f\n", latitude, longitude); + fprintf(stderr, "Lat/Long in APRS DDMM.MM format: %07.2f/%08.2f\n", toAprsFormat(latitude), toAprsFormat(longitude)); + newGpsTime = millis(); + + } else { // set default +// latitude = toAprsFormat(latitude); +// longitude = toAprsFormat(longitude); + newGpsTime = millis(); + } + + if (strcmp(sim_yes, "yes") == 0) { + sim_mode = TRUE; + 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"); + } + + FILE * command_file = fopen("/home/pi/CubeSatSim/command_control", "r"); + if (command_file == NULL) { + fprintf(stderr,"Command and control is OFF\n"); + c2cStatus = DISABLED; + } else { + command_file = fopen("/home/pi/CubeSatSim/command_control_direwolf", "r"); + if (command_file == NULL) { + fprintf(stderr,"Command and control Carrier (squelch) is ON\n"); + c2cStatus = CARRIER; + } else { + fprintf(stderr,"Command and control DTMF or APRS is ON\n"); + c2cStatus = DTMF_APRS; + } + } + printf("c2cStatus: %d \n", c2cStatus); + char resbuffer[1000]; - const char testStr[] = "cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}' | sed 's/^1000//' | grep '902120'"; +// const char testStr[] = "cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}' | sed 's/^1000//' | grep '9000'"; + const char testStr[] = "cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}' | sed 's/^1000//'"; + const char test2Str[] = "cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}' | sed 's/^1000//' | grep '902120'"; FILE *file_test = sopen(testStr); // see if Pi Zero 2 fgets(resbuffer, 1000, file_test); -// fprintf(stderr, "test result: %s\n", resbuffer); + fprintf(stderr, "Pi Zero test result: %s\n", resbuffer); fclose(file_test); -// fprintf(stderr, " %x ", resbuffer[0]); -// fprintf(stderr, " %x ", resbuffer[1]); - if (resbuffer[1] != 0) +// fprintf(stderr, "hex: %x %x %x %x \n", resbuffer[0], resbuffer[1], resbuffer[2], resbuffer[3]); + if ((resbuffer[0] != '9') || (resbuffer[1] != '0') || (resbuffer[2] != '0') || (resbuffer[3] != '0')) { - sleep(5); // try sleep at start to help boot - voltageThreshold = 3.7; - printf("Pi Zero 2 detected"); + // voltageThreshold = 3.7; +// if ((resbuffer[0] != '9') || (resbuffer[1] != '0') || (resbuffer[2] != '2') || (resbuffer[3] != '1')) + FILE *file2_test = sopen(test2Str); // see if Pi Zero 2 + fgets(resbuffer, 1000, file2_test); + fprintf(stderr, "Pi Zero 2 test result: %s\n", resbuffer); + fclose(file2_test); + if (strlen(resbuffer) > 5) + fprintf(stderr, "Pi Zero 2 detected\n"); + 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); + fprintf(stderr, "Sleep 5 sec\n"); + sleep(5); // try sleep at start to help boot + } + } + else { + fprintf(stderr,"Pi Zero detected\n"); + if ((c2cStatus == DISABLED) || (c2cStatus == CARRIER)) { + 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 10 sec\n"); + sleep(10); + } } - printf("\n\nCubeSatSim v1.2 starting...\n\n"); - - FILE * rpitx_stop = popen("sudo systemctl stop rpitx", "r"); - pclose(rpitx_stop); +// FILE * transmit_stop = popen("sudo systemctl stop transmit", "r"); +// FILE * transmit_stop = popen("sudo systemctl restart transmit", "r"); + + +// FILE * cc_start = popen("/home/pi/CubeSatSim/command &", "r"); +// pclose(cc_start); - FILE * file_deletes = popen("sudo rm /home/pi/CubeSatSim/ready /home/pi/CubeSatSim/cwready > /dev/null", "r"); - pclose(file_deletes); +// 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); @@ -58,26 +167,31 @@ int main(int argc, char * argv[]) { fflush(stdout); // sleep(2); + +//#ifdef HAB + if (hab_mode) + fprintf(stderr, "HAB mode enabled - in APRS balloon icon and no battery saver or low voltage shutdown\n"); +//#endif - FILE * rpitx_restart = popen("sudo systemctl restart rpitx", "r"); - pclose(rpitx_restart); +// FILE * transmit_restart = popen("sudo systemctl restart transmit", "r"); +// pclose(transmit_restart); - mode = FSK; + mode = BPSK; frameCnt = 1; if (argc > 1) { // strcpy(src_addr, argv[1]); if ( * argv[1] == 'b') { mode = BPSK; - printf("Mode BPSK\n"); + printf("Mode is BPSK\n"); } else if ( * argv[1] == 'a') { mode = AFSK; - printf("Mode AFSK\n"); + printf("Mode is AFSK\n"); } else if ( * argv[1] == 'm') { mode = CW; - printf("Mode CW\n"); + printf("Mode is CW\n"); } else { - printf("Mode FSK\n"); + printf("Mode is BPSK\n"); } if (argc > 2) { @@ -102,9 +216,9 @@ int main(int argc, char * argv[]) { fclose(mode_file); printf("Mode file /home/pi/CubeSatSim/.mode contains %c\n", mode_string); - if ( mode_string == 'b') { - mode = BPSK; - printf("Mode is BPSK\n"); + if ( mode_string == 'f') { + mode = FSK; + printf("Mode is FSK\n"); } else if ( mode_string == 'a') { mode = AFSK; printf("Mode is AFSK\n"); @@ -114,45 +228,40 @@ int main(int argc, char * argv[]) { } else if ( mode_string == 'm') { mode = CW; printf("Mode is CW\n"); + } else if ( mode_string == 'e') { + mode = REPEATER; + printf("Mode is Repeater\n"); + } else if ( mode_string == 'n') { + mode = TXCOMMAND; + printf("Mode is Transmit Command\n"); } else { - printf("Mode is FSK\n"); + printf("Mode is BPSK\n"); } } } - // Open configuration file with callsign and reset count - FILE * config_file = fopen("/home/pi/CubeSatSim/sim.cfg", "r"); - if (config_file == NULL) { - printf("Creating config file."); - config_file = fopen("/home/pi/CubeSatSim/sim.cfg", "w"); - fprintf(config_file, "%s %d", " ", 100); - fclose(config_file); - config_file = fopen("/home/pi/CubeSatSim/sim.cfg", "r"); - } - -// char * cfg_buf[100]; - - fscanf(config_file, "%s %d %f %f %s", call, & reset_count, & lat_file, & long_file, sim_yes); - fclose(config_file); - printf("Config file /home/pi/CubeSatSim/sim.cfg contains %s %d %f %f %s\n", call, reset_count, lat_file, long_file, sim_yes); - reset_count = (reset_count + 1) % 0xffff; - - if ((fabs(lat_file) > 0) && (fabs(lat_file) < 90.0) && (fabs(long_file) > 0) && (fabs(long_file) < 180.0)) { - printf("Valid latitude and longitude in config file\n"); -// convert to APRS DDMM.MM format - latitude = toAprsFormat(lat_file); - longitude = toAprsFormat(long_file); - printf("Lat/Long in APRS DDMM.MM format: %f/%f\n", latitude, longitude); - } else { // set default - latitude = toAprsFormat(latitude); - longitude = toAprsFormat(longitude); - } + // Open telemetry file with STEM Payload Data + telem_file = fopen("/home/pi/CubeSatSim/telem.txt", "a"); + if (telem_file == NULL) + printf("Error opening telem file\n"); + fclose(telem_file); + printf("Opened telem file\n"); - if (strcmp(sim_yes, "yes") == 0) - sim_mode = TRUE; - wiringPiSetup(); + battery_saver_mode = battery_saver_check(); +/**/ + if (battery_saver_mode == ON) { + SafeMode = 1; + fprintf(stderr, "Safe Mode! Battery_saver_mode is ON\n\n"); + } + else { + fprintf(stderr, "\nBattery_saver_mode is OFF\n\n"); + SafeMode = 0; + } +/**/ + fflush(stderr); + if (mode == AFSK) { // Check for SPI and AX-5043 Digital Transceiver Board @@ -189,92 +298,31 @@ int main(int argc, char * argv[]) { pclose(file); } - txLed = 0; // defaults for vB3 board without TFB - txLedOn = LOW; - txLedOff = HIGH; - if (!ax5043) { - pinMode(2, INPUT); - pullUpDnControl(2, PUD_UP); - - if (digitalRead(2) != HIGH) { - printf("vB3 with TFB Present\n"); - vB3 = TRUE; - txLed = 3; - txLedOn = LOW; - txLedOff = HIGH; - onLed = 0; - onLedOn = LOW; - onLedOff = HIGH; - transmit = TRUE; - } else { - pinMode(3, INPUT); - pullUpDnControl(3, PUD_UP); - - if (digitalRead(3) != HIGH) { - printf("vB4 Present with UHF BPF\n"); - txLed = 2; - txLedOn = HIGH; - txLedOff = LOW; - vB4 = TRUE; - onLed = 0; - onLedOn = HIGH; - onLedOff = LOW; - transmit = TRUE; - } else { - pinMode(26, INPUT); - pullUpDnControl(26, PUD_UP); - - if (digitalRead(26) != HIGH) { - printf("v1 Present with UHF BPF\n"); - txLed = 2; - txLedOn = HIGH; - txLedOff = LOW; - vB5 = TRUE; - onLed = 27; - onLedOn = HIGH; - onLedOff = LOW; - transmit = TRUE; - } - else { - pinMode(23, INPUT); - pullUpDnControl(23, PUD_UP); - - if (digitalRead(23) != HIGH) { - printf("v1 Present with VHF BPF\n"); - txLed = 2; - txLedOn = HIGH; - txLedOff = LOW; - vB5 = TRUE; - onLed = 27; - onLedOn = HIGH; - onLedOff = LOW; - printf("VHF BPF not yet supported so no transmit\n"); - transmit = FALSE; - } - } - } - } + txLed = 2; + txLedOn = HIGH; + txLedOff = LOW; + vB5 = TRUE; + onLed = 27; + onLedOn = HIGH; + onLedOff = LOW; + + pinMode(26, INPUT); + pullUpDnControl(26, PUD_UP); + + if (digitalRead(26) != HIGH) { + printf("v1 Present with UHF BPF\n"); + transmit = TRUE; } - pinMode(txLed, OUTPUT); - digitalWrite(txLed, txLedOff); - #ifdef DEBUG_LOGGING - printf("Tx LED Off\n"); - #endif - pinMode(onLed, OUTPUT); - digitalWrite(onLed, onLedOn); - #ifdef DEBUG_LOGGING - printf("Power LED On\n"); - #endif config_file = fopen("sim.cfg", "w"); - fprintf(config_file, "%s %d %8.4f %8.4f %s", call, reset_count, lat_file, long_file, sim_yes); + 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", call, reset_count); fclose(config_file); config_file = fopen("sim.cfg", "r"); if (vB4) { - map[BAT] = BUS; - map[BUS] = BAT; + 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; @@ -288,8 +336,8 @@ int main(int argc, char * argv[]) { snprintf(busStr, 10, "%d %d", i2c_bus1, i2c_bus3); } } else { - map[BUS] = MINUS_Z; - map[BAT] = BUS; + 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)); @@ -303,7 +351,7 @@ int main(int argc, char * argv[]) { char camera_present[] = "supported=1 detected=1"; // printf("strstr: %s \n", strstr( & cmdbuffer1, camera_present)); camera = (strstr( (const char *)& cmdbuffer, camera_present) != NULL) ? ON : OFF; - // printf("Camera result:%s camera: %d \n", & cmdbuffer1, camera); + printf("Camera result:%s camera: %d \n", & cmdbuffer, camera); pclose(file4); #ifdef DEBUG_LOGGING @@ -311,55 +359,19 @@ int main(int argc, char * argv[]) { #endif FILE * file5 = popen("sudo rm /home/pi/CubeSatSim/camera_out.jpg > /dev/null 2>&1", "r"); - file5 = popen("sudo rm /home/pi/CubeSatSim/camera_out.jpg.wav > /dev/null 2>&1", "r"); + //file5 = popen("sudo rm /home/pi/CubeSatSim/camera_out.jpg.wav > /dev/null 2>&1", "r"); pclose(file5); - // try connecting to STEM Payload board using UART - // /boot/config.txt and /boot/cmdline.txt must be set correctly for this to work - - if (!ax5043 && !vB3 && !(mode == CW) && !(mode == SSTV)) // don't test for payload if AX5043 is present or CW or SSTV modes + if (!ax5043) // don't test for payload if AX5043 is present { payload = OFF; - + fprintf(stderr,"Opening serial\n"); if ((uart_fd = serialOpen("/dev/ttyAMA0", 115200)) >= 0) { // was 9600 - char c; - int charss = (char) serialDataAvail(uart_fd); - if (charss != 0) - printf("Clearing buffer of %d chars \n", charss); - while ((charss--> 0)) - c = (char) serialGetchar(uart_fd); // clear buffer - - unsigned int waitTime; - int i; - for (i = 0; i < 2; i++) { - if (payload != ON) { - serialPutchar(uart_fd, 'R'); - printf("Querying payload with R to reset\n"); - waitTime = millis() + 500; - while ((millis() < waitTime) && (payload != ON)) { - if (serialDataAvail(uart_fd)) { - printf("%c", c = (char) serialGetchar(uart_fd)); - fflush(stdout); - if (c == 'O') { - printf("%c", c = (char) serialGetchar(uart_fd)); - fflush(stdout); - if (c == 'K') - payload = ON; - } - } - printf("\n"); - // sleep(0.75); - } - } - } - if (payload == ON) { - printf("\nSTEM Payload is present!\n"); - sleep(2); // delay to give payload time to get ready - } - else { - printf("\nSTEM Payload not present!\n -> Is STEM Payload programed and Serial1 set to 115200 baud?\n"); - - } + 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)); } @@ -369,7 +381,7 @@ int main(int argc, char * argv[]) { sim_mode = TRUE; - printf("Simulated telemetry mode!\n"); + fprintf(stderr, "Simulated telemetry mode!\n"); srand((unsigned int)time(0)); @@ -414,11 +426,11 @@ int main(int argc, char * argv[]) { eclipse_time -= period / 2; // if starting in eclipse, shorten interval } - tx_freq_hz -= tx_channel * 50000; + // tx_freq_hz -= tx_channel * 50000; if (transmit == FALSE) { - fprintf(stderr, "\nNo CubeSatSim Band Pass Filter detected. No transmissions after the CW ID.\n"); + fprintf(stderr, "\nNo CubeSatSim Low 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"); } @@ -486,7 +498,7 @@ int main(int argc, char * argv[]) { get_tlm_fox(); // fill transmit buffer with reset count 0 packets that will be ignored firstTime = 1; - if (!sim_mode) +// if (!sim_mode) // always read sensors, even in sim mode { strcpy(pythonStr, pythonCmd); strcat(pythonStr, busStr); @@ -507,7 +519,7 @@ int main(int argc, char * argv[]) { voltage_max[i] = -1000.0; current_max[i] = -1000.0; } - for (int i = 0; i < 17; i++) { + for (int i = 0; i < SENSOR_FIELDS; i++) { sensor_min[i] = 1000.0; sensor_max[i] = -1000.0; // printf("Sensor min and max initialized!"); @@ -516,8 +528,7 @@ int main(int argc, char * argv[]) { other_min[i] = 1000.0; other_max[i] = -1000.0; } - - long int loopTime; + loopTime = millis(); while (loop-- != 0) { @@ -537,14 +548,139 @@ int main(int argc, char * argv[]) { uptime = (int) (uptime_sec + 0.5); // printf("Uptime sec: %f \n", uptime_sec); // #ifdef DEBUG_LOGGING - printf("INFO: Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); +// printf("INFO: Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); // #endif fclose(uptime_file); + + { + int count1; + char * token; + fputc('\n', file1); + fgets(cmdbuffer, 1000, file1); +// fprintf(stderr, "Python read Result: %s\n", cmdbuffer); + +// serialPuts(uart_fd, cmdbuffer); // write INA data to Pico over serial + + const char space[2] = " "; + token = strtok(cmdbuffer, space); + + for (count1 = 0; count1 < 8; count1++) { + if (token != NULL) { + voltage[count1] = (float) atof(token); + #ifdef DEBUG_LOGGING +// printf("voltage: %f ", voltage[count1]); + #endif + token = strtok(NULL, space); + if (token != NULL) { + current[count1] = (float) atof(token); + if ((current[count1] < 0) && (current[count1] > -0.5)) + current[count1] *= (-1.0f); + #ifdef DEBUG_LOGGING +// printf("current: %f\n", current[count1]); + #endif + token = strtok(NULL, space); + } + } + if (voltage[map[BAT]] == 0.0) + batteryVoltage = 4.5; + else { + batteryVoltage = voltage[map[BAT]]; + 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]]; + + } + +// 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 + fflush(stdout); +// printf("String: %s\n", buffer2); + fflush(stdout); + strcpy(sensor_payload, buffer2); +// printf(" Response from STEM Payload board: %s\n", sensor_payload); + + telem_file = fopen("/home/pi/CubeSatSim/telem.txt", "a"); +// printf("Writing payload string\n"); + time_t timeStamp; + time(&timeStamp); // get timestamp +// printf("Timestamp: %s\n", ctime(&timeStamp)); + + 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); + + fprintf(telem_file, "%s %s %s\n", timeStampNoNl, bat_string, sensor_payload); // write telemetry string to telem.txt file + fclose(telem_file); + + if ((sensor_payload[0] == 'O') && (sensor_payload[1] == 'K')) // only process if valid payload response + { + int count1; + char * token; + + const char space[2] = " "; + token = strtok(sensor_payload, space); +// printf("token: %s\n", token); + for (count1 = 0; count1 < SENSOR_FIELDS; count1++) { + if (token != NULL) { + sensor[count1] = (float) atof(token); +// #ifdef DEBUG_LOGGING +// printf("sensor: %f ", sensor[count1]); // print sensor data +// #endif + token = strtok(NULL, space); + } + } + + printf("\n"); +// if (sensor[GPS1] != 0) { + if ((sensor[GPS1] > -90.0) && (sensor[GPS1] < 90.0) && (sensor[GPS1] != 0.0)) { + if (sensor[GPS1] != latitude) { + latitude = sensor[GPS1]; + printf("Latitude updated to %f \n", latitude); + newGpsTime = millis(); + } + } +// if (sensor[GPS2] != 0) { + if ((sensor[GPS2] > -180.0) && (sensor[GPS2] < 180.0) && (sensor[GPS2] != 0.0)) { + if (sensor[GPS2] != longitude) { + longitude = sensor[GPS2]; + printf("Longitude updated to %f \n", longitude); + newGpsTime = millis(); + } + } + } + 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; +// printf("GPS Location with Rnd: %f, %f \n", latitude, longitude); +// printf("GPS Location with Rnd: APRS %07.2f, %08.2f \n", toAprsFormat(latitude), toAprsFormat(longitude)); + newGpsTime = millis(); + } - printf("++++ Loop time: %5.3f sec +++++\n", (millis() - loopTime)/1000.0); - fflush(stdout); - loopTime = millis(); - + if ((sensor_payload[0] == 'O') && (sensor_payload[1] == 'K')) { + for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) { + if (sensor[count1] < sensor_min[count1]) + sensor_min[count1] = sensor[count1]; + if (sensor[count1] > sensor_max[count1]) + sensor_max[count1] = sensor[count1]; + // printf("Smin %f Smax %f \n", sensor_min[count1], sensor_max[count1]); + } + } + if (sim_mode) { // simulated telemetry double time = ((long int)millis() - time_start) / 1000.0; @@ -586,15 +722,15 @@ int main(int argc, char * argv[]) { // IHUcpuTemp = (int)((tempS + rnd_float(-1.0, 1.0)) * 10 + 0.5); other[IHU_TEMP] = tempS; - voltage[map[BUS]] = rnd_float(5.0, 5.005); - current[map[BUS]] = rnd_float(158, 171); + voltage[map[BAT2]] = 0.0; // rnd_float(5.0, 5.005); + current[map[BAT2]] = 0.0; // rnd_float(158, 171); // float charging = current[map[PLUS_X]] + current[map[MINUS_X]] + current[map[PLUS_Y]] + current[map[MINUS_Y]] + current[map[PLUS_Z]] + current[map[MINUS_Z]]; 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[BUS]] * voltage[map[BUS]]) / batt) - charging; + current[map[BAT]] = ((current[map[BAT2]] * voltage[map[BAT2]]) / batt) - charging; - // printf("charging: %f bat curr: %f bus curr: %f bat volt: %f bus volt: %f \n",charging, current[map[BAT]], current[map[BUS]], batt, voltage[map[BUS]]); + // 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) { @@ -612,43 +748,7 @@ int main(int argc, char * argv[]) { // end of simulated telemetry } else { - int count1; - char * token; - fputc('\n', file1); - fgets(cmdbuffer, 1000, file1); - fprintf(stderr, "Python read Result: %s\n", cmdbuffer); - - const char space[2] = " "; - token = strtok(cmdbuffer, space); - - for (count1 = 0; count1 < 8; count1++) { - if (token != NULL) { - voltage[count1] = (float) atof(token); - #ifdef DEBUG_LOGGING -// printf("voltage: %f ", voltage[count1]); - #endif - token = strtok(NULL, space); - if (token != NULL) { - current[count1] = (float) atof(token); - if ((current[count1] < 0) && (current[count1] > -0.5)) - current[count1] *= (-1.0f); - #ifdef DEBUG_LOGGING -// printf("current: %f\n", current[count1]); - #endif - token = strtok(NULL, space); - } - } } - - batteryVoltage = voltage[map[BAT]]; - batteryCurrent = current[map[BAT]]; - - if (batteryVoltage < 3.6) { - SafeMode = 1; - printf("Safe Mode!\n"); - } else - SafeMode = 0; - FILE * cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); if (cpuTempSensor) { // double cpuTemp; @@ -664,90 +764,41 @@ int main(int argc, char * argv[]) { // IHUcpuTemp = (int)((cpuTemp * 10.0) + 0.5); } fclose(cpuTempSensor); - } - if (payload == ON) { // -55 - STEMBoardFailure = 0; - - - char c; - unsigned int waitTime; - int i, end, trys = 0; - sensor_payload[0] = 0; - sensor_payload[1] = 0; - while (((sensor_payload[0] != 'O') || (sensor_payload[1] != 'K')) && (trys++ < 10)) { - i = 0; - serialPutchar(uart_fd, '?'); - sleep(0.05); // added delay after ? - printf("%d Querying payload with ?\n", trys); - waitTime = millis() + 500; - end = FALSE; - // int retry = FALSE; - while ((millis() < waitTime) && !end) { - int chars = (char) serialDataAvail(uart_fd); - while ((chars > 0) && !end) { -// printf("Chars: %d\ ", chars); - chars--; - c = (char) serialGetchar(uart_fd); - // printf ("%c", c); - // fflush(stdout); - if (c != '\n') { - sensor_payload[i++] = c; - } else { - end = TRUE; - } - } - } - - sensor_payload[i++] = ' '; - // sensor_payload[i++] = '\n'; - sensor_payload[i] = '\0'; - printf(" Response from STEM Payload board: %s\n", sensor_payload); - sleep(0.1); // added sleep between loops - } - if ((sensor_payload[0] == 'O') && (sensor_payload[1] == 'K')) // only process if valid payload response - { - int count1; - char * token; - - const char space[2] = " "; - token = strtok(sensor_payload, space); - for (count1 = 0; count1 < 17; count1++) { - if (token != NULL) { - sensor[count1] = (float) atof(token); - #ifdef DEBUG_LOGGING - // printf("sensor: %f ", sensor[count1]); - #endif - token = strtok(NULL, space); - } - } - printf("\n"); - } - else - payload = OFF; // turn off since STEM Payload is not responding - } - if ((sensor_payload[0] == 'O') && (sensor_payload[1] == 'K')) { - for (int count1 = 0; count1 < 17; count1++) { - if (sensor[count1] < sensor_min[count1]) - sensor_min[count1] = sensor[count1]; - if (sensor[count1] > sensor_max[count1]) - sensor_max[count1] = sensor[count1]; - // printf("Smin %f Smax %f \n", sensor_min[count1], sensor_max[count1]); - } - } -// } + } #ifdef DEBUG_LOGGING - fprintf(stderr, "INFO: Battery voltage: %5.2f V Threshold %5.2f V Current: %6.1f mA Threshold: %6.1f mA\n", batteryVoltage, voltageThreshold, batteryCurrent, currentThreshold); +// fprintf(stderr, "INFO: Battery voltage: %5.2f V Threshold %5.2f V Current: %6.1f mA Threshold: %6.1f mA\n", batteryVoltage, voltageThreshold, batteryCurrent, currentThreshold); #endif -// if ((batteryVoltage > 1.0) && (batteryVoltage < batteryThreshold)) // no battery INA219 will give 0V, no battery plugged into INA219 will read < 1V - -/**/ - if ((batteryCurrent > currentThreshold) && (batteryVoltage < voltageThreshold) && !sim_mode) // currentThreshold ensures that this won't happen when running on DC power. + + if ((batteryCurrent > currentThreshold) && (batteryVoltage < (voltageThreshold + 0.15)) && !sim_mode && !hab_mode) + { + fprintf(stderr,"Battery voltage low\n"); + if (battery_saver_mode == OFF) { + fprintf(stderr,"Switch to battery saver\n"); + battery_saver(ON); + fprintf(stderr, "Safe Mode!\n"); + SafeMode = 1; + + } + } else if ((battery_saver_mode == ON) && (batteryCurrent < 0) && !sim_mode && !hab_mode) + { + fprintf(stderr,"Battery is being charged - switch battery saver off\n"); + if (battery_saver_mode == ON) { + battery_saver(OFF); + fprintf(stderr, "Safe Mode off!\n"); + SafeMode = 0; + } + } + if ((batteryCurrent > currentThreshold) && (batteryVoltage < voltageThreshold) && !sim_mode && !hab_mode) // currentThreshold ensures that this won't happen when running on DC power. { fprintf(stderr, "Battery voltage too low: %f V - shutting down!\n", batteryVoltage); digitalWrite(txLed, txLedOff); digitalWrite(onLed, onLedOff); - + + FILE * file6; + file6 = popen("echo 'shutdown due to low battery voltage!' | wall", "r"); + pclose(file6); + sleep(1); digitalWrite(onLed, onLedOn); sleep(1); @@ -757,13 +808,27 @@ int main(int argc, char * argv[]) { sleep(1); digitalWrite(onLed, onLedOff); - FILE * file6 = popen("/home/pi/CubeSatSim/log > shutdown_log.txt", "r"); - pclose(file6); - sleep(40); file6 = popen("sudo shutdown -h now > /dev/null 2>&1", "r"); pclose(file6); 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; @@ -771,13 +836,42 @@ int main(int argc, char * argv[]) { // fprintf(stderr, "INFO: Getting TLM Data\n"); #endif + FILE * command_file = fopen("/home/pi/CubeSatSim/command_control", "r"); + if (command_file == NULL) { + if (c2cStatus != DISABLED) { + fprintf(stderr,"Command and control is OFF\n"); + c2cStatus = DISABLED; + } + } else { + command_file = fopen("/home/pi/CubeSatSim/command_control_direwolf", "r"); + if (command_file == NULL) { + if (c2cStatus != CARRIER) { + fprintf(stderr,"Command and control Carrier (squelch) is ON\n"); + c2cStatus = CARRIER; + } + } else { + if (c2cStatus != DTMF_APRS) { + fprintf(stderr,"Command and control DTMF or APRS is ON\n"); + c2cStatus = DTMF_APRS; + } + } + } + // printf("c2cStatus: %d \n", c2cStatus); + if ((mode == AFSK) || (mode == CW)) { get_tlm(); + sleep(25); +// fprintf(stderr, "INFO: Sleeping for 25 sec\n"); + + int rand_sleep = (int)rnd_float(0.0, 5.0); + sleep(rand_sleep); +// fprintf(stderr, "INFO: Sleeping for extra %d sec\n", rand_sleep); + } else if ((mode == FSK) || (mode == BPSK)) {// FSK or BPSK get_tlm_fox(); } else { // SSTV - fprintf(stderr, "Sleeping\n"); - sleep(50); +// fprintf(stderr, "Sleeping\n"); + sleep(30); } #ifdef DEBUG_LOGGING @@ -790,17 +884,17 @@ int main(int argc, char * argv[]) { #ifdef DEBUG_LOGGING // printf("Tx LED On 1\n"); #endif - printf("Sleeping to allow BPSK transmission to finish.\n"); +// printf("Sleeping to allow BPSK transmission to finish.\n"); sleep((unsigned int)(loop_count * 5)); - printf("Done sleeping\n"); + // printf("Done sleeping\n"); // digitalWrite(txLed, txLedOff); #ifdef DEBUG_LOGGING // printf("Tx LED Off\n"); #endif } else if (mode == FSK) { - printf("Sleeping to allow FSK transmission to finish.\n"); +// printf("Sleeping to allow FSK transmission to finish.\n"); sleep((unsigned int)loop_count); - printf("Done sleeping\n"); +// printf("Done sleeping\n"); } return 0; @@ -857,7 +951,7 @@ void get_tlm(void) { int tlm[7][5]; memset(tlm, 0, sizeof tlm); - tlm[1][A] = (int)(voltage[map[BUS]] / 15.0 + 0.5) % 100; // Current of 5V supply to Pi + tlm[1][A] = (int)(voltage[map[BAT2]] / 15.0 + 0.5) % 100; // Current of 5V supply to Pi tlm[1][B] = (int)(99.5 - current[map[PLUS_X]] / 10.0) % 100; // +X current [4] tlm[1][C] = (int)(99.5 - current[map[MINUS_X]] / 10.0) % 100; // X- current [10] tlm[1][D] = (int)(99.5 - current[map[PLUS_Y]] / 10.0) % 100; // +Y current [7] @@ -873,7 +967,7 @@ void get_tlm(void) { else tlm[3][A] = (int)((voltage[map[BAT]] * 10.0) + 44.5) % 100; // 0 - 4.5 V for new 3 cell battery - tlm[3][B] = (int)(voltage[map[BUS]] * 10.0) % 100; // 5V supply to Pi + tlm[3][B] = (int)(voltage[map[BAT2]] * 10.0) % 100; // 5V supply to Pi tlm[4][A] = (int)((95.8 - other[IHU_TEMP]) / 1.48 + 0.5) % 100; // was [B] but didn't display in online TLM spreadsheet @@ -900,10 +994,13 @@ void get_tlm(void) { char header_str2b[30]; // for APRS coordinates char header_lat[10]; char header_long[10]; - char header_str4[] = "hi hi "; - char footer_str1[] = "\' > t.txt && echo \'"; - char footer_str[] = "-11>APCSS:010101/hi hi ' >> t.txt && touch /home/pi/CubeSatSim/ready"; // transmit is done by rpitx.py - + char header_str4[] = "hi hi de "; +// char footer_str1[] = "\' > t.txt && echo \'"; + char footer_str1[] = "\' > t.txt"; +// 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"; + if (ax5043) { strcpy(str, header_str); } else { @@ -918,102 +1015,90 @@ void get_tlm(void) { 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 if (latitude > 0) - sprintf(header_lat, "%7.2f%c", latitude, 'N'); // lat + sprintf(header_lat, "%07.2f%c", toAprsFormat(latitude), 'N'); // lat else - sprintf(header_lat, "%7.2f%c", latitude * (-1.0), 'S'); // lat + sprintf(header_lat, "%07.2f%c", toAprsFormat(latitude) * (-1.0), 'S'); // lat if (longitude > 0) - sprintf(header_long, "%08.2f%c", longitude , 'E'); // long + sprintf(header_long, "%08.2f%c", toAprsFormat(longitude) , 'E'); // long else - sprintf(header_long, "%08.2f%c", longitude * (-1.0), 'W'); // long + 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 - sprintf(header_str2b, "=%s%c%c%sShi hi ", header_lat, 0x5c, 0x5c, header_long); // add APRS lat and long -// printf("\n\nString is %s \n\n", header_str2b); +//#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 +//#else + else + sprintf(header_str2b, "=%s%c%c%sShi hi ", header_lat, 0x5c, 0x5c, header_long); // add APRS lat and long with Satellite icon +//#endif + + printf("\n\nString is %s \n\n", header_str2b); strcat(str, header_str2b); - } else { + } else { // CW mode strcat(str, header_str4); + strcat(str, call); + + sprintf(tlm_str, "%s' > cw0.txt", &str); + printf("CW string to execute: %s\n", &tlm_str); + FILE * cw_file = popen(tlm_str, "r"); + pclose(cw_file); + } // } printf("Str: %s \n", str); - + if (mode == CW) { int channel; for (channel = 1; channel < 7; channel++) { - sprintf(tlm_str, "%d%d%d %d%d%d %d%d%d %d%d%d ", + sprintf(tlm_str, "echo -n ' %d%d%d %d%d%d %d%d%d %d%d%d ' > cw%1d.txt", channel, upper_digit(tlm[channel][1]), lower_digit(tlm[channel][1]), channel, upper_digit(tlm[channel][2]), lower_digit(tlm[channel][2]), channel, upper_digit(tlm[channel][3]), lower_digit(tlm[channel][3]), - channel, upper_digit(tlm[channel][4]), lower_digit(tlm[channel][4])); - // printf("%s",tlm_str); - strcat(str, tlm_str); - } + channel, upper_digit(tlm[channel][4]), lower_digit(tlm[channel][4]), channel); - // read payload sensor if available + strcat(str, tlm_str); + + printf("CW string to execute: %s\n", &tlm_str); + + FILE * cw_file = popen(tlm_str, "r"); + pclose(cw_file); - char sensor_payload[500]; - - if (payload == ON) { - char c; - unsigned int waitTime; - int i, end, trys = 0; - sensor_payload[0] = 0; - sensor_payload[1] = 0; - while (((sensor_payload[0] != 'O') || (sensor_payload[1] != 'K')) && (trys++ < 10)) { - i = 0; - serialPutchar(uart_fd, '?'); - sleep(0.05); // added delay after ? - printf("%d Querying payload with ?\n", trys); - waitTime = millis() + 500; - end = FALSE; - // int retry = FALSE; - while ((millis() < waitTime) && !end) { - int chars = (char) serialDataAvail(uart_fd); - while ((chars > 0) && !end) { -// printf("Chars: %d\ ", chars); - chars--; - c = (char) serialGetchar(uart_fd); - // printf ("%c", c); - // fflush(stdout); - if (c != '\n') { - sensor_payload[i++] = c; - } else { - end = TRUE; - } - } - } - - sensor_payload[i++] = ' '; - // sensor_payload[i++] = '\n'; - sensor_payload[i] = '\0'; - printf(" Response from STEM Payload board: %s\n", sensor_payload); - sleep(0.1); // added sleep between loops - } + } + if (c2cStatus != DISABLED) { + FILE *file_append = sopen("echo 'C' >> cw6.txt"); + fclose(file_append); + } + } else { // APRS - if (mode != CW) + if (c2cStatus == 0) + sprintf(tlm_str, "BAT %4.2f %5.1f ", voltage[map[BAT]] , current[map[BAT]] ); + else + sprintf(tlm_str, "BAT %4.2f %5.1f C ", voltage[map[BAT]] , current[map[BAT]] ); + + strcat(str, tlm_str); + } + strcpy(sensor_payload, buffer2); + printf(" Response from STEM Payload board:: %s\n", sensor_payload); +// printf(" Str so far: %s\n", str); + + if (mode != CW) strcat(str, sensor_payload); // append to telemetry string for transmission - } if (mode == CW) { - char cw_str2[1000]; - char cw_header2[] = "echo '"; - char cw_footer2[] = "' > id.txt && gen_packets -M 20 id.txt -o morse.wav -r 48000 > /dev/null 2>&1 && cat morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.897e3"; - char cw_footer3[] = "' > cw.txt && touch /home/pi/CubeSatSim/cwready"; // transmit is done by rpitx.py - -// printf("Str str: %s \n", str); -// fflush(stdout); - strcat(str, cw_footer3); -// printf("Str: %s \n", str); -// fflush(stdout); - printf("CW string to execute: %s\n", str); - fflush(stdout); - - FILE * cw_file = popen(str, "r"); +// char cw_str2[1000]; +// char cw_header2[] = "echo '"; +// char cw_footer2[] = "' > id.txt && gen_packets -M 20 id.txt -o morse.wav -r 48000 > /dev/null 2>&1 && cat morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/transmit/transmit -i- -m RF -f 434.897e3"; + char cw_footer3[] = "' > cw.txt && touch /home/pi/CubeSatSim/cwready"; // transmit is done by transmit.py + char cwready[] = "touch /home/pi/CubeSatSim/cwready"; // cw frame is complete. transmit is done by transmit.py + + FILE * cw_file = popen(cwready, "r"); pclose(cw_file); - while ((cw_file = fopen("/home/pi/CubeSatSim/cwready", "r")) != NULL) { // wait for rpitx to be done + while ((cw_file = fopen("/home/pi/CubeSatSim/cwready", "r")) != NULL) { // wait for transmit to be done fclose(cw_file); -// printf("Sleeping while waiting for rpitx \n"); +// printf("Sleeping while waiting for transmit \n"); // fflush(stdout); sleep(5); } @@ -1041,12 +1126,16 @@ void get_tlm(void) { } sleep(4); // was 2 - } else { // APRS using rpitx + } else { // APRS using transmit strcat(str, footer_str1); - strcat(str, call); - strcat(str, footer_str); -// fprintf(stderr, "String to execute: %s\n", str); +// strcat(str, call); + if (battery_saver_mode == ON) + strcat(str, footer_str); // add extra packet for transmit transmission + else + strcat(str, footer_str2); + + fprintf(stderr, "String to execute: %s\n", str); printf("\n\nTelemetry string is %s \n\n", str); @@ -1070,8 +1159,10 @@ void get_tlm(void) { return; } -void get_tlm_fox() { +// 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() { int i; long int sync = syncWord; @@ -1094,9 +1185,9 @@ void get_tlm_fox() { short int rs_frame[rsFrames][223]; unsigned char parities[rsFrames][parityLen], inputByte; - int id, frm_type = 0x01, NormalModeFailure = 0, groundCommandCount = 0; + int id, frm_type = 0x01, NormalModeFailure = 0; int PayloadFailure1 = 0, PayloadFailure2 = 0; - int PSUVoltage = 0, PSUCurrent = 0, Resets = 0, Rssi = 2048; + int BAT2Voltage = 0, BAT2Current = 0, Resets = 0, Rssi = 2048; int batt_a_v = 0, batt_b_v = 0, batt_c_v = 0, battCurr = 0; int posXv = 0, negXv = 0, posYv = 0, negYv = 0, posZv = 0, negZv = 0; int posXi = 0, negXi = 0, posYi = 0, negYi = 0, posZi = 0, negZi = 0; @@ -1120,18 +1211,23 @@ void get_tlm_fox() { /**/ // while ((millis() - sampleTime) < (unsigned int)samplePeriod) int startSleep = millis(); - if ((millis() - sampleTime) < ((unsigned int)frameTime - 250)) // was 250 100 500 for FSK - sleep(2.0); // 0.5); // 25); // initial period - while ((millis() - sampleTime) < ((unsigned int)frameTime - 250)) // was 250 100 + 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("Sleep period: %d\n", millis() - startSleep); + 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(); } else printf("first time - no sleep\n"); + + printf("++++ Loop time: %5.3f sec +++++\n", (millis() - loopTime)/1000.0); + fflush(stdout); + loopTime = millis(); // if (mode == FSK) { // just moved @@ -1159,9 +1255,9 @@ void get_tlm_fox() { if (mode == FSK) { if (loop % 32 == 0) { // was 8 - printf("Sending MIN frame \n"); +// printf("Sending MIN frame \n"); frm_type = 0x03; - for (int count1 = 0; count1 < 17; count1++) { + for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) { if (count1 < 3) other[count1] = other_min[count1]; if (count1 < 8) { @@ -1173,9 +1269,9 @@ void get_tlm_fox() { } } if ((loop + 16) % 32 == 0) { // was 8 - printf("Sending MAX frame \n"); +// printf("Sending MAX frame \n"); frm_type = 0x02; - for (int count1 = 0; count1 < 17; count1++) { + for (int count1 = 0; count1 < SENSOR_FIELDS; count1++) { if (count1 < 3) other[count1] = other_max[count1]; if (count1 < 8) { @@ -1229,16 +1325,16 @@ void get_tlm_fox() { batt_c_v = (int)(voltage[map[BAT]] * 100); battCurr = (int)(current[map[BAT]] + 0.5) + 2048; - PSUVoltage = (int)(voltage[map[BUS]] * 100); - PSUCurrent = (int)(current[map[BUS]] + 0.5) + 2048; + BAT2Voltage = (int)(voltage[map[BAT2]] * 100); + BAT2Current = (int)(current[map[BAT2]] + 0.5) + 2048; if (payload == ON) STEMBoardFailure = 0; // read payload sensor if available - encodeA(b, 0 + head_offset, batt_a_v); - 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 @@ -1295,14 +1391,14 @@ void get_tlm_fox() { 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[BUS]] * 100)); - encodeB(b_max, 46 + head_offset, (int)(current_max[map[BUS]] + 0.5) + 2048); + 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); 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[0] != 1000.0) // make sure values are valid + + 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 @@ -1314,10 +1410,14 @@ void get_tlm_fox() { 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[XS1] * 10 + 0.5) + 2048); - encodeB(b_max, 49 + head_offset, (int)(sensor_max[XS2] * 10 + 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[XS1])); + encodeA(b_max, 0 + head_offset, (int)(sensor[XS2])); + encodeB(b_max, 1 + head_offset, (int)(sensor[XS3])); } else { @@ -1330,7 +1430,7 @@ void get_tlm_fox() { encodeB(b_max, 43 + head_offset, 2048); encodeA(b_max, 48 + head_offset, 2048); - encodeB(b_max, 49 + 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)); @@ -1348,14 +1448,14 @@ void get_tlm_fox() { 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[BUS]] * 100)); - encodeB(b_min, 46 + head_offset, (int)(current_min[map[BUS]] + 0.5) + 2048); + 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); encodeA(b_min, 39 + head_offset, (int)(other_min[IHU_TEMP] * 10 + 0.5)); - if (sensor_min[0] != 1000.0) // make sure values are valid + 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 @@ -1367,10 +1467,14 @@ void get_tlm_fox() { 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[XS1] * 10 + 0.5) + 2048); - encodeB(b_min, 49 + head_offset, (int)(sensor_min[XS2] * 10 + 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[XS1])); + encodeA(b_min, 0 + head_offset, (int)(sensor[XS2])); + encodeB(b_min, 1 + head_offset, (int)(sensor[XS3])); } else { @@ -1383,10 +1487,10 @@ void get_tlm_fox() { encodeB(b_min, 43 + head_offset, 2048); encodeA(b_min, 48 + head_offset, 2048); - encodeB(b_min, 49 + head_offset, 2048); +// encodeB(b_min, 49 + head_offset, 2048); } } - encodeA(b, 30 + head_offset, PSUVoltage); + encodeA(b, 30 + head_offset, BAT2Voltage); encodeB(b, 31 + head_offset, ((int)(other[SPIN] * 10)) + 2048); @@ -1404,20 +1508,46 @@ void get_tlm_fox() { encodeA(b, 45 + head_offset, (int)(sensor[HUMI] * 10 + 0.5)); // in place of sensor1 - encodeB(b, 46 + head_offset, PSUCurrent); - encodeA(b, 48 + head_offset, (int)(sensor[XS1] * 10 + 0.5) + 2048); - encodeB(b, 49 + head_offset, (int)(sensor[XS2] * 10 + 0.5) + 2048); - + 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"); + 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; encodeA(b, 51 + head_offset, status); - encodeB(b, 52 + head_offset, rxAntennaDeployed + txAntennaDeployed * 2); - + encodeB(b, 52 + head_offset, rxAntennaDeployed + txAntennaDeployed * 2 + c2cStatus * 4); + 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"); } + if (rxAntennaDeployed == 0) { + rxAntennaDeployed = 1; + printf("RX Antenna Deployed!\n"); + } if (mode == BPSK) { // wod field experiments unsigned long val = 0xffff; @@ -1617,9 +1747,11 @@ void get_tlm_fox() { if (connect(sock, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); - printf("Error: %s \n", strerror(errno)); + printf("Error: %s\n", strerror(errno)); error = 1; - sleep(2.0); // sleep if socket connection refused +// 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; @@ -1641,15 +1773,27 @@ void get_tlm_fox() { if (connect(sock, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); - printf("Error: %s \n", strerror(errno)); + printf("Error: %s\n", strerror(errno)); error = 1; - // sleep(1.0); // sleep if socket connection refused +// FILE * transmit_restartf = popen("sudo systemctl restart transmit", "r"); +// pclose(transmit_restartf); +// sleep(10); // was 5 // sleep if socket connection refused } } - if (error == 1) - ; //rpitxStatus = -1; - else + 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; + } } if (!error && transmit) { @@ -1657,14 +1801,14 @@ void get_tlm_fox() { // 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); +// 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); +// printf("socket send 2 %d ms bytes: %d \n\n", millis() - start, sock_ret); } loop_count++; @@ -1688,7 +1832,7 @@ void get_tlm_fox() { { start = millis(); // send frame until buffer fills 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); +// 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"); @@ -1711,7 +1855,7 @@ void get_tlm_fox() { if (sock_ret == -1) { printf("Error: %s \n", strerror(errno)); socket_open = 0; - //rpitxStatus = -1; + //transmitStatus = -1; } } if (!transmit) { @@ -1873,3 +2017,224 @@ float toAprsFormat(float input) { float output = dd * 100 + mm1 + (float)mm2 * 0.01; return(output); } + +int get_payload_serial(int debug_camera) { + + index1 = 0; + flag_count = 0; + start_flag_detected = FALSE; + start_flag_complete = FALSE; + end_flag_detected = FALSE; + jpeg_start = 0; + + serialFlush (uart_fd); // flush serial buffer so latest payload is read + +// #ifdef GET_IMAGE_DEBUG + if (debug_camera) + printf("Received from Payload:\n"); + // #endif + finished = FALSE; + + unsigned long time_start = millis(); + while ((!finished) && ((millis() - time_start) < CAMERA_TIMEOUT)) { + + if (serialDataAvail(uart_fd)) { + char octet = (char) serialGetchar(uart_fd); + printf("%c", octet); + fflush(stdout); + + if (start_flag_complete) { +// printf("Start flag complete detected\n"); + buffer2[index1++] = octet; + if (octet == end_flag[flag_count]) { // looking for end flag +// if (end_flag_detected) { + flag_count++; +#ifdef GET_IMAGE_DEBUG +// if (debug_camera) + printf("Found part of end flag!\n"); +#endif + if (flag_count >= strlen(end_flag)) { // complete image + index1 -= strlen(end_flag); + buffer2[index1++] = 0; + printf(" Payload length: %d \n",index1); + +// write_jpg(); + finished = TRUE; + index1 = 0; + start_flag_complete = FALSE; + start_flag_detected = FALSE; // get ready for next image + end_flag_detected = FALSE; + flag_count = 0; +// delay(6000); + } + } else { + if (flag_count > 1) + printf("Resetting. Not end flag.\n"); + flag_count = 0; + + } + /// buffer2[index1++] = octet; + +//#ifdef GET_IMAGE_DEBUG + if (debug_camera) { + char hexValue[5]; + if (octet != 0x66) { + sprintf(hexValue, "%02X", octet); +// printf(hexValue); + } else { +// Serial.println("\n********************************************* Got a 66!"); + printf("66"); + } +// Serial.write(octet); + } +//#endif + if (index1 > 1000) { + index1 = 0; + printf("Resetting index!\n"); + } +// } + } else if (octet == start_flag[flag_count]) { // looking for start flag + start_flag_detected = TRUE; + flag_count++; +#ifdef GET_IMAGE_DEBUG + printf("Found part of start flag! \n"); +#endif + if (flag_count >= strlen(start_flag)) { + flag_count = 0; + start_flag_complete = TRUE; +#ifdef GET_IMAGE_DEBUG + printf("Found all of start flag!\n"); +#endif + } + } else { // not the flag, keep looking + start_flag_detected = FALSE; + flag_count = 0; +#ifdef GET_IMAGE_DEBUG + printf("Resetting. Not start flag.\n"); +#endif + } + } +// Serial.println("writing to Serial2"); + } + if (debug_camera) + printf("\nComplete\n"); + fflush(stdout); + return(finished); +} + +void program_radio() { +// if (sr_frs_present) { + printf("Programming FM module!\n"); + + pinMode(28, OUTPUT); + pinMode(29, OUTPUT); + digitalWrite(29, HIGH); // enable SR_FRS + digitalWrite(28, HIGH); // stop transmit + +if ((uart_fd = serialOpen("/dev/ttyAMA0", 9600)) >= 0) { // was 9600 + printf("serial opened 9600\n"); + for (int i = 0; i < 5; i++) { + sleep(1); // delay(500); +//#ifdef APRS_VHF +// char vhf_string[] = "AT+DMOSETGROUP=0,144.3900,144.3900,0,3,0,0\r\n"; +// serialPrintf(uart_fd, vhf_string); +// mySerial.println("AT+DMOSETGROUP=0,144.3900,144.3900,0,3,0,0\r"); // can change to 144.39 for standard APRS +// mySerial.println("AT+DMOSETGROUP=0,145.0000,145.0000,0,3,0,0\r"); // can change to 145 for testing ASPRS +//#else + char uhf_string[] = "AT+DMOSETGROUP=0,435.0000,434.9000,0,3,0,0\r\n"; + char uhf_string1a[] = "AT+DMOSETGROUP=0,"; // changed frequency to verify + char comma[] = ","; + char uhf_string1b[] = ",0,"; // changed frequency to verify + char uhf_string1[] = "AT+DMOSETGROUP=0,435.0000,434.9000,0,"; // changed frequency to verify + char uhf_string2[] = ",0,0\r\n"; + char sq_string[2]; + sq_string[0] = '0' + squelch; + sq_string[1] = 0; + +// serialPrintf(uart_fd, uhf_string); +/**/ + serialPrintf(uart_fd, uhf_string1a); + serialPrintf(uart_fd, rx); + serialPrintf(uart_fd, comma); + serialPrintf(uart_fd, tx); + serialPrintf(uart_fd, uhf_string1b); + serialPrintf(uart_fd, sq_string); + serialPrintf(uart_fd, uhf_string2); +/**/ + +// mySerial.println("AT+DMOSETGROUP=0,435.1000,434.9900,0,3,0,0\r"); // squelch set to 3 +//#endif + sleep(1); + char mic_string[] = "AT+DMOSETMIC=8,0\r\n"; + serialPrintf(uart_fd, mic_string); +// mySerial.println("AT+DMOSETMIC=8,0\r"); // was 8 + + } + } +//#ifdef APRS_VHF +// printf("Programming FM tx 144.39, rx on 144.39 MHz\n"); +//#else + printf("Programming FM tx 434.9, rx on 435.0 MHz\n"); +//#endif +// digitalWrite(PTT_PIN, LOW); // transmit carrier for 0.5 sec +// sleep(0.5); +// digitalWrite(PTT_PIN, HIGH); + digitalWrite(29, LOW); // disable SR_FRS + pinMode(28, INPUT); + pinMode(29, INPUT); + + serialClose(uart_fd); +} + +int battery_saver_check() { + FILE *file = fopen("/home/pi/CubeSatSim/battery_saver", "r"); + if (file == NULL) { +// fprintf(stderr,"Battery saver mode is OFF!\n"); + return(OFF); + } + fclose(file); +// fprintf(stderr, "Safe Mode!\n"); +// fprintf(stderr,"Battery saver mode is ON!\n"); + return(ON); +} + +void battery_saver(int setting) { +if (setting == ON) { + if (battery_saver_check() == OFF) { + FILE *command = popen("touch /home/pi/CubeSatSim/battery_saver", "r"); + pclose(command); + fprintf(stderr,"Turning Safe Mode ON\n"); + fprintf(stderr,"Turning Battery saver mode ON\n"); + if ((mode == AFSK) || (mode == SSTV) || (mode == CW)) { + command = popen("echo 'reboot due to turning ON Safe Mode!' | wall", "r"); + pclose(command); + command = popen("sudo reboot now", "r"); + pclose(command); + sleep(60); + return; + } +// } else +// fprintf(stderr, "Nothing to do for battery_saver\n"); + } + } else if (setting == OFF) { + if (battery_saver_check() == ON) { + FILE *command = popen("rm /home/pi/CubeSatSim/battery_saver", "r"); + pclose(command); + fprintf(stderr,"Turning Battery saver mode OFF\n"); + if ((mode == AFSK) || (mode == SSTV) || (mode == CW)) { + command = popen("echo 'reboot due to turning OFF Safe Mode!' | wall", "r"); + pclose(command); + command = popen("sudo reboot now", "r"); + pclose(command); + sleep(60); + return; + } +// } else +// fprintf(stderr, "Nothing to do for battery_saver\n"); + } + } else { + fprintf(stderr,"battery_saver function error"); + return; + } + return; +} diff --git a/main.h b/main.h index f26913ec9..6708d1af1 100644 --- a/main.h +++ b/main.h @@ -29,24 +29,29 @@ #define PLUS_X 0 #define PLUS_Y 1 #define BAT 2 -#define BUS 3 +#define BAT2 3 #define MINUS_X 4 #define MINUS_Y 5 #define PLUS_Z 6 #define MINUS_Z 7 -#define TEMP 2 +#define TEMP 2 // OK and BME280 is positions 0 and 1 #define PRES 3 #define ALT 4 #define HUMI 5 -#define GYRO_X 7 +#define GYRO_X 7 // MPU6050 is posisition 6 #define GYRO_Y 8 #define GYRO_Z 9 #define ACCEL_X 10 #define ACCEL_Y 11 #define ACCEL_Z 12 -#define XS1 14 -#define XS2 15 -#define XS3 16 +#define GPS1 14 // GPS is position 13 +#define GPS2 15 +#define GPS3 16 +#define DTEMP 18 // TMP 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 RSSI 0 #define IHU_TEMP 2 @@ -54,6 +59,10 @@ #define OFF - 1 #define ON 1 +#define CHECK 0 +#define DISABLED 0 +#define CARRIER 1 +#define DTMF_APRS 2 uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET; uint8_t data[1024]; @@ -77,6 +86,7 @@ void update_rs(unsigned char parity[32], unsigned char c); void write_little_endian(unsigned int word, int num_bytes, FILE *wav_file); static int init_rf(); extern int Encode_8b10b[][256]; +void program_radio(); int socket_open = 0; int sock = 0; @@ -89,6 +99,7 @@ char cmdbuffer[1000]; FILE * file1; short int buffer[2336400]; // max size for 10 frames count of BPSK FILE *sopen(const char *program); +FILE *telem_file; #define S_RATE (48000) // (44100) @@ -97,8 +108,10 @@ FILE *sopen(const char *program); #define BPSK 3 #define SSTV 4 #define CW 5 +#define REPEATER 11 +#define TXCOMMAND 12 -int rpitxStatus = -1; +int transmitStatus = -1; float amplitude; // = ; // 20000; // 32767/(10%amp+5%amp+100%amp) float freq_Hz = 3000; // 1200 @@ -121,6 +134,11 @@ float uptime_sec = 0; long int uptime; char call[5]; char sim_yes[10]; +char hab_yes[10]; +int squelch = 3; // default squelch +char rx[12], tx[12]; +int tx_pl = 0; +int rx_pl = 0; int bitRate, mode, bufLen, rsFrames, payloads, rsFrameLen, dataLen, headerLen, syncBits, syncWord, parityLen, samples, frameCnt, samplePeriod; float sleepTime; @@ -128,17 +146,21 @@ 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; +// float voltageThreshold = 3.6, batteryVoltage = 4.5, batteryCurrent = 0, currentThreshold = 100; float voltageThreshold = 3.5, 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; -int i2c_bus0 = OFF, i2c_bus1 = OFF, i2c_bus3 = OFF, camera = OFF, sim_mode = FALSE, SafeMode = FALSE, rxAntennaDeployed = 0, txAntennaDeployed = 0; +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 double eclipse_time; -float voltage[9], current[9], sensor[17], other[3]; +float voltage[9], current[9], sensor[SENSOR_FIELDS], other[3]; char sensor_payload[500]; int test_i2c_bus(int bus); @@ -149,5 +171,35 @@ char pythonStr[100], pythonConfigStr[100], busStr[10]; int map[8] = {0, 1, 2, 3, 4, 5, 6, 7}; char src_addr[5] = ""; char dest_addr[5] = "APCSS"; -float voltage_min[9], current_min[9], voltage_max[9], current_max[9], sensor_max[17], sensor_min[17], other_max[3], other_min[3]; +float voltage_min[9], current_min[9], voltage_max[9], current_max[9], sensor_max[SENSOR_FIELDS], sensor_min[SENSOR_FIELDS], other_max[3], other_min[3]; +int get_payload_serial(int debug_camera); +int finished = FALSE; + +//char buffer2[100001]; +char buffer2[2000]; +int index1 = 0; +//char start_flag[] = "3d99de816e5ad7742b61a37c39141783"; +char start_flag[] = "_START_FLAG_"; + +//char end_flag[] = "f681a5c52351befe0e3524eb1a40f14b7803317a"; +char end_flag[] = "_END_FLAG_"; + +int flag_count = 0; +int start_flag_detected = FALSE; +int start_flag_complete = FALSE; +int end_flag_detected = FALSE; +int jpeg_start = 0; +#define CAMERA_TIMEOUT 2000 // 1500 // 2000 // 10000 // 20000 // Payload timeout in milli seconds + +void battery_saver(int setting); +int battery_saver_check(); +int pi_zero_2_offset = 0; + + +int hab_mode = FALSE; +int battery_saver_mode = FALSE; +long int loopTime; + +int error_count = 0; +int groundCommandCount = 0; diff --git a/rpitx.py b/rpitx.py deleted file mode 100644 index 08f929a10..000000000 --- a/rpitx.py +++ /dev/null @@ -1,283 +0,0 @@ -#!/usr/bin/env python - -import RPi.GPIO as GPIO -from RPi.GPIO import output -#import subprocess -#import time -from time import sleep -#import os -import sys -from os import system - -print("CubeSatSim v1.1 rpitx.py starting...") - -GPIO.setmode(GPIO.BCM) -GPIO.setwarnings(False) -GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP) -GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP) -GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP) - -transmit = False -if GPIO.input(12) == False: - print("Version is v1 with UHF BPF") - transmit = True - txLed = 27 - txLedOn = 1 - txLedOff = 0 -elif GPIO.input(27) == False: - print("Version is TFB") - transmit = True - txLed = 22 - txLedOn = 0 - txLedOff = 1 -elif GPIO.input(13) == False: - print("Version is v1 with VHF BPF") - print("VHF transmit not implemented yet") -# transmit = True - txLed = 27 - txLedOn = 1 - txLedOff = 0 -else: - print("No BPF") - txLed = 27 - txLedOn = 1 - txLedOff = 0 - -# GPIO.setup(txLed, GPIO.OUT) -# output(txLed, txLedOff) - -GPIO.setmode(GPIO.BCM) # Repeat to make LED work on Pi 4 -GPIO.setwarnings(False) -GPIO.setup(txLed, GPIO.OUT) - -output(txLed, txLedOn) -sleep(1) -output(txLed, txLedOff) - -# print(txLedOn) -print(txLed) -# GPIO.setup(27, GPIO.OUT) -# GPIO.output(27, 0) - -debug_mode = 0 - -if __name__ == "__main__": - - if (len(sys.argv)) > 1: -# print("There are arguments!") - if (('d' == sys.argv[1]) or ('-d' in sys.argv[1])): - debug_mode = 1 - - print(transmit) - - try: - file = open("/home/pi/CubeSatSim/.mode") - mode = file.read(1) - except: - mode = "f" - if (debug_mode == 1): - print("Can't open .mode file, defaulting to FSK") - print("Mode is: ") - print(mode) - - try: - file = open("/home/pi/CubeSatSim/sim.cfg") - callsign = file.readline().split(" ")[0] - except: - callsign = "AMSAT" - if (debug_mode == 1): - print("Can't read callsign from sim.cfg file, defaulting to AMSAT") - print(callsign) - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 - GPIO.setup(txLed, GPIO.OUT) - - sleep(1) - output(txLed, txLedOn) - 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 434.9e3") - 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 434.9e3 > /dev/null 2>&1") - - sleep(4); # was 8 - output(txLed, txLedOff) - - sleep(1) - - - if (transmit): - -# print 'Length: ', len(sys.argv) - -# if (len(sys.argv)) > 1: -# print("There are arguments!") - if (mode == 'a'): - print("AFSK") - sleep(5) - try: - file = open("/home/pi/CubeSatSim/t.txt") - file.close() - except: - system("echo '" + callsign + "-11>APCSS:hi hi 100 199 199 199 298 299 299 278 380 350 300 300 439 400 400 400 500 500 500 500 600 600 600 650' > /home/pi/CubeSatSim/t.txt && echo 'AMSAT>APCSS:010101/hi hi ' >> /home/pi/CubeSatSim/t.txt") - for x in range(5): - output(txLed, txLedOn) - if (debug_mode == 1): - system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/telem.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3") - else: - system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/telem.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3 > /dev/null 2>&1") - sleep(0.2) - output(txLed, txLedOff) - sleep(3.8) - while True: - try: - f = open("/home/pi/CubeSatSim/ready") - output(txLed, txLedOn) - if (debug_mode == 1): - system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/telem.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3") - else: - system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/telem.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3 > /dev/null 2>&1") - output(txLed, txLedOff) - f.close() - system("sudo rm /home/pi/CubeSatSim/ready") - sleep(0.5) - except: - sleep(0.5) - elif (mode == 'm'): - print("CW") -# sleep(4) - try: - file = open("/home/pi/CubeSatSim/cw.txt") - file.close() - except: - system("echo 'hi hi 100 199 199 199 298 299 299 278 380 350 300 300 439 400 400 400 500 500 500 500 600 600 600 650' > /home/pi/CubeSatSim/cw.txt") - output(txLed, txLedOn) - if (debug_mode == 1): - system("gen_packets -M 20 -o /home/pi/CubeSatSim/morse.wav /home/pi/CubeSatSim/cw.txt -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 434.9e3") - else: - system("gen_packets -M 20 -o /home/pi/CubeSatSim/morse.wav /home/pi/CubeSatSim/cw.txt -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 434.9e3 > /dev/null 2>&1") - output(txLed, txLedOff) - - while True: - try: - f = open("/home/pi/CubeSatSim/cwready") - output(txLed, txLedOn) - if (debug_mode == 1): - system("gen_packets -M 20 -o /home/pi/CubeSatSim/morse.wav /home/pi/CubeSatSim/cw.txt -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 434.9e3") - else: - system("gen_packets -M 20 -o /home/pi/CubeSatSim/morse.wav /home/pi/CubeSatSim/cw.txt -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 434.9e3 > /dev/null 2>&1") - output(txLed, txLedOff) - f.close() - system("sudo rm /home/pi/CubeSatSim/cwready") - sleep(1) - except: - sleep(1) - elif (mode == 's'): - print("SSTV") - try: -# from picamera import PiCamera -# from pysstv.sstv import SSTV -# camera = PiCamera() - print("Testing for camera") - system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") - f = open("/home/pi/CubeSatSim/camera_out.jpg") - print("Camera present") - camera_present = 1 -# camera.close() - except: - print("No camera available") - print(" -> if camera plugged in, is software enabled?") - camera_present = 0 - -# while 1: - output(txLed, txLedOff) - if (camera_present == 1): - try: - file = open("/home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") - print("First SSTV stored image detected") - system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") - print ("Sending SSTV image") - output(txLed, txLedOn) - if (debug_mode == 1): - system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3") - else: - system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3 > /dev/null 2>&1") - output(txLed, txLedOff) - # sleep(1) - except: - print("image 2 did not load - copy from CubeSatSim/sstv directory") - while 1: - system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") # > /dev/null 2>&1") - print("Photo taken") - 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") - print ("Sending SSTV image") - output(txLed, txLedOn) - if (debug_mode == 1): - system("cat /home/pi/CubeSatSim/camera_out.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3") - else: - system("cat /home/pi/CubeSatSim/camera_out.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3 > /dev/null 2>&1") - output(txLed, txLedOff) - system("sudo rm /home/pi/CubeSatSim/camera_out.jpg.wav > /dev/null 2>&1") - sleep(1) - else: - try: - file = open("/home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg") - print("First SSTV stored image detected") - system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg") - print ("Sending SSTV image") - output(txLed, txLedOn) - if (debug_mode == 1): - system("cat /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3") - else: - system("cat /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3 > /dev/null 2>&1") - output(txLed, txLedOff) - sleep(1) - except: - print("image 1 did not load - copy from CubeSatSim/sstv directory") - try: - file = open("/home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") - print("Second SSTV stored image detected") - system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") - while 1: - print ("Sending SSTV image") - output(txLed, txLedOn) - if (debug_mode == 1): - system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3") - else: - system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3 > /dev/null 2>&1") - output(txLed, txLedOff) - sleep(5) - except: - print("image 2 did not load - copy from CubeSatSim/sstv directory") - system("(while true; do (sleep 5 && cat /home/pi/CubeSatSim/wav/sstv.wav); done) | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 434.9e3 &") - while 1: - output(txLed, txLedOn) - sleep(60) - output(txLed, txLedOff) - sleep(1) - - elif (mode == 'b'): - print("BPSK") - system("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | sudo /home/pi/rpitx/sendiq -i /dev/stdin -s 96000 -f 434.9e6 -t float &") - print("Turning LED on/off") - while 1: - output(txLed, txLedOff) - sleep(0.5) - output(txLed, txLedOn) - sleep(4.0) - else: - print("FSK") - system("sudo nc -l 8080 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3 &") - print("Turning LED on/off") - while 1: - output(txLed, txLedOff) - sleep(0.5) - output(txLed, txLedOn) - sleep(4.0) -# else: -# print("FSK") -# system("sudo nc -l 8080 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3") - - else: - print("No Band Pass Filter so no telemetry transmit. See http://cubesatsim.org/wiki for instructions on how to build the BPF.") - while 1: - sleep(5) diff --git a/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_maxtelemetry.csv b/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_maxtelemetry.csv new file mode 100644 index 000000000..5e4214929 --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_maxtelemetry.csv @@ -0,0 +1,62 @@ +61,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION +0,MAX,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2 +1,MAX,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3 +2,MAX,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage +3,MAX,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis +4,MAX,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis +5,MAX,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis +6,MAX,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current +7,MAX,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,BME280 STEM Payload sensor temperature +8,MAX,posXv,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X solar panel Voltage +9,MAX,posYv,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y solar panel Voltage +10,MAX,posZv,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z solar panel Voltage +11,MAX,negXv,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X solar panel Voltage +12,MAX,negYv,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y solar panel Voltage +13,MAX,negZv,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z solar panel Voltage +14,MAX,posXi,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X solar panel Current +15,MAX,posYi,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y solar panel Current +16,MAX,posZi,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z solar panel Current +17,MAX,negXi,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X solar panel Current +18,MAX,negYi,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y solar panel Current +19,MAX,negZi,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z solar panel Current +20,MAX,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage +21,MAX,spin,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells +22,MAX,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,BME280 STEM Payload sensor pressure +23,MAX,Altitude,12,m,cubesatsim_altitude,NONE,6,4,3,BME280 Altitude,BME280 STEM Payload sensor altitude +24,MAX,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count +25,MAX,rssi,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication +26,MAX,IHUcpuTemp,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal temperature of IHU from Pi +27,MAX,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around X Axis +28,MAX,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Y Axis +29,MAX,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Z Axis +30,MAX,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,BME280 Humidity +31,MAX,BAT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current +32,MAX,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature +33,MAX,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1 +34,MAX,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status, STEM Payload STEM Payload board failure Indicator +35,MAX,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage) +36,MAX,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry,Simulated Telemetry Indicator +37,MAX,PayloadStatus1,1,-,17,NONE,6,8,0,Exp 3,STEM Payload status 1 failure indicator +38,MAX,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator +39,MAX,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator +40,MAX,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator +41,MAX,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator +42,MAX,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received +43,MAX,RxAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status +44,MAX,TxAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status +45,MAX,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status +46,MAX,ICR3VProt,12,V,43,NONE,7,2,3,3V Prot,ICR 3V Proteted +47,MAX,ICR2dot5V,12,V,43,NONE,7,3,3,2.5V,ICR 2.5V +48,MAX,ICR2dot5VProt,12,V,43,NONE,7,4,3,2.5V Prot,ICR 2.5V Protected +49,MAX,rf6,12,-,0,NONE,0,0,0,None,None +50,MAX,rf7,12,-,0,NONE,0,0,0,None,None +51,MAX,MuxTest,12,V,43,NONE,7,5,3,Sensor Power,Sensor Power Voltage at the ICR +52,MAX,LtVGACtl,12,V,42,NONE,1,4,3,VGA Control,Control Voltage to the Variable Gain Amplifier (VGA) +53,MAX,pad,4,-,34,NONE,0,0,0,None,Unused +54,MAX,IHUdiagData,32,-,18,NONE,3,2,0,Diagnostic Info,Diagnostic Data on IHU Performance +55,MAX,pad1,1,-,0,NONE,0,0,0,NONE,Filler +56,MAX,wodSize,8,000s,36,NONE,3,3,0,WOD Stored,Number of WOD data payloads kept for each of Science and Housekeeping. In hundreds +57,MAX,swCmds,32,-,35,NONE,7,6,0,Diagnostic,ICR Diagnostic information +58,MAX,hwCmdCnt,6,-,1,NONE,7,7,0,HW Command Count,Number of hardware commands since last reset +59,MAX,swCmdCnt,6,-,1,NONE,7,8,0,SW Command Count,Number of software commands since last reset +60,MAX,pad2,27,-,0,NONE,0,0,0,NONE,Filler diff --git a/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_mintelemetry.csv b/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_mintelemetry.csv new file mode 100644 index 000000000..97dcaa4b5 --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_mintelemetry.csv @@ -0,0 +1,62 @@ +61,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION +0,MIN,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2 +1,MIN,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3 +2,MIN,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage +3,MIN,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis +4,MIN,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis +5,MIN,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis +6,MIN,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current +7,MIN,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,BME280 STEM Payload sensor temperature +8,MIN,posXv,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X solar panel Voltage +9,MIN,posYv,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y solar panel Voltage +10,MIN,posZv,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z solar panel Voltage +11,MIN,negXv,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X solar panel Voltage +12,MIN,negYv,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y solar panel Voltage +13,MIN,negZv,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z solar panel Voltage +14,MIN,posXi,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X solar panel Current +15,MIN,posYi,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y solar panel Current +16,MIN,posZi,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z solar panel Current +17,MIN,negXi,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X solar panel Current +18,MIN,negYi,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y solar panel Current +19,MIN,negZi,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z solar panel Current +20,MIN,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage +21,MIN,spin,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells +22,MIN,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,BME280 STEM Payload sensor pressure +23,MIN,Altitude,12,m,cubesatsim_altitude,NONE,6,4,3,BME280 Altitude,BME280 STEM Payload sensor altitude +24,MIN,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count +25,MIN,rssi,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication +26,MIN,IHUcpuTemp,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal temperature of IHU from Pi +27,MIN,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around X Axis +28,MIN,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Y Axis +29,MIN,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Z Axis +30,MIN,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,BME280 Humidity +31,MIN,BAT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current +32,MIN,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature +33,MIN,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1 +34,MIN,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status, STEM Payload STEM Payload board failure Indicator +35,MIN,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage) +36,MIN,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry,Simulated Telemetry Indicator +37,MIN,PayloadStatus1,1,-,17,NONE,6,8,0,Exp 3,STEM Payload status 1 failure indicator +38,MIN,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator +39,MIN,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator +40,MIN,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator +41,MIN,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator +42,MIN,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received +43,MIN,RxAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status +44,MIN,TxAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status +45,MIN,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status +46,MIN,ICR3VProt,12,V,43,NONE,7,2,3,3V Prot,ICR 3V Proteted +47,MIN,ICR2dot5V,12,V,43,NONE,7,3,3,2.5V,ICR 2.5V +48,MIN,ICR2dot5VProt,12,V,43,NONE,7,4,3,2.5V Prot,ICR 2.5V Protected +49,MIN,rf6,12,-,0,NONE,0,0,0,None,None +50,MIN,rf7,12,-,0,NONE,0,0,0,None,None +51,MIN,MuxTest,12,V,43,NONE,7,5,3,Sensor Power,Sensor Power Voltage at the ICR +52,MIN,LtVGACtl,12,V,42,NONE,1,4,3,VGA Control,Control Voltage to the Variable Gain Amplifier (VGA) +53,MIN,pad,4,-,34,NONE,0,0,0,None,Unused +54,MIN,IHUdiagData,32,-,18,NONE,3,2,0,Diagnostic Info,Diagnostic Data on IHU Performance +55,MIN,pad1,1,-,0,NONE,0,0,0,NONE,Filler +56,MIN,wodSize,8,000s,36,NONE,3,3,0,WOD Stored,Number of WOD data payloads kept for each of Science and Housekeeping. In hundreds +57,MIN,swCmds,32,-,35,NONE,7,6,0,Diagnostic,ICR Diagnostic information +58,MIN,hwCmdCnt,6,-,1,NONE,7,7,0,HW Command Count,Number of hardware commands since last reset +59,MIN,swCmdCnt,6,-,1,NONE,7,8,0,SW Command Count,Number of software commands since last reset +60,MIN,pad2,27,-,0,NONE,0,0,0,NONE,Filler diff --git a/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_rttelemetry.csv b/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_rttelemetry.csv new file mode 100644 index 000000000..17ef4ab64 --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/CubeSatSim_PSK_rttelemetry.csv @@ -0,0 +1,62 @@ +61,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION +0,realTime,Sensor 2,12,integer,1,Experiments,6,8,3,Sensor 2,STEM Payload Extra Sensor 2 +1,realTime,Sensor 3,12,integer,1,Experiments,6,9,3,Sensor 3,STEM Payload Extra Sensor 3 +2,realTime,BATT_V,12,V,cubesatsim_voltage|FLOAT2,Battery,4,1,3,Battery Voltage,INA219 Battery Voltage +3,realTime,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+X Panel,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis +4,realTime,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+Y Panel,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis +5,realTime,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,+Z Panel,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis +6,realTime,BATT_I,12,mA,cubesatsim_current,Battery,4,2,3,Battery Current,INA219 Battery Current +7,realTime,Temperature,12,C,cubesatsim_temperature,Experiments,6,2,3,BME280 Temp,BME280 STEM Payload sensor temperature +8,realTime,posXv,12,V,cubesatsim_voltage|FLOAT2,+X Panel,7,1,3,Voltage,INA219 +X solar panel Voltage +9,realTime,posYv,12,V,cubesatsim_voltage|FLOAT2,+Y Panel,8,1,3,Voltage,INA219 +Y solar panel Voltage +10,realTime,posZv,12,V,cubesatsim_voltage|FLOAT2,+Z Panel,9,1,3,Voltage,INA219 +Z solar panel Voltage +11,realTime,negXv,12,V,cubesatsim_voltage|FLOAT2,-X Panel,10,1,3,Voltage,INA219 -X solar panel Voltage +12,realTime,negYv,12,V,cubesatsim_voltage|FLOAT2,-Y Panel,11,1,3,Voltage,INA219 -Y solar panel Voltage +13,realTime,negZv,12,V,cubesatsim_voltage|FLOAT2,-Z Panel,12,1,3,Voltage,INA219 -Z solar panel Voltage +14,realTime,posXi,12,mA,cubesatsim_current,+X Panel,7,2,3,Current,INA219 +X solar panel Current +15,realTime,posYi,12,mA,cubesatsim_current,+Y Panel,8,2,3,Current,INA219 +Y solar panel Current +16,realTime,posZi,12,mA,cubesatsim_current,+Z Panel,9,2,3,Current,INA219 +Z solar panel Current +17,realTime,negXi,12,mA,cubesatsim_current,-X Panel,10,2,3,Current,INA219 -X solar panel Current +18,realTime,negYi,12,mA,cubesatsim_current,-Y Panel,11,2,3,Current,INA219 -Y solar panel Current +19,realTime,negZi,12,mA,cubesatsim_current,-Z Panel,12,2,3,Current,INA219 -Z solar panel Current +20,realTime,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,Battery2,5,1,3,Battery2 Voltage,INA219 Battery2 Voltage +21,realTime,spin,12,rpm,cubesatsim_rpm,Computer Software,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells +22,realTime,Pressure,12,hPa,cubesatsim_pressure,Experiments,6,3,3,BME280 Pressure,BME280 STEM Payload sensor pressure +23,realTime,Altitude,12,m,cubesatsim_altitude,Experiments,6,4,3,BME280 Altitude,BME280 STEM Payload sensor altitude +24,realTime,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count +25,realTime,rssi,12,dBm,cubesatsim_rssi|INT,Radio,1,1,3,RSSI,Received Signal Strength Indication +26,realTime,IHUcpuTemp,12,C,cubesatsim_temperature,Computer Hardware,2,1,3,IHU Temp (Pi),Internal temperature of IHU from Pi +27,realTime,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+X Panel,7,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around X Axis +28,realTime,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+Y Panel,8,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Y Axis +29,realTime,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,+Z Panel,9,3,3,Rotation,STEM Payload Board MPU6050 Angular veolcity around Z Axis +30,realTime,Humidity,12,%,cubesatsim_temperature,Experiments,6,5,3,BME280 Humidity,BME280 Humidity +31,realTime,BAT2_I,12,mA,cubesatsim_current,Battery2,5,2,3,Battery2 Current,INA219 Battery2 Current +32,realTime,DiodeTemp,12,C,cubesatsim_rpm,Experiments,6,6,3,Diode Temp,STEM Payload Diode Temperature +33,realTime,Sensor 1,12,integer,1,Experiments,6,7,3,Sensor 1,STEM Payload Extra Sensor 1 +34,realTime,STEMPayloadStatus,1,-,17,Experiments,6,1,0,STEM Payload Status, STEM Payload STEM Payload board failure Indicator +35,realTime,SafeMode,1,-,STATUS_ON_OFF,Computer Software,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage) +36,realTime,SimulatedTelemetry,1,-,STATUS_ON_OFF,Computer Software,3,4,0,Simulated Telemetry,Simulated Telemetry Indicator +37,realTime,PayloadStatus1,1,-,17,NONE,6,8,0,Exp 3,STEM Payload status 1 failure indicator +38,realTime,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator +39,realTime,I2CBus1Failure,1,-,17,Computer Hardware,2,2,0,I2C Bus 1,I2C bus 1 failure indicator +40,realTime,I2CBus3Failure,1,-,17,Computer Hardware,2,3,0,I2C Bus 3,I2C bus 3 failure indicator +41,realTime,CameraFailure,1,-,17,Computer Hardware,2,4,0,Camera,Camera failure indicator +42,realTime,GroundCommands,4,-,1,Computer Software,3,3,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 diff --git a/spacecraft/FoxTelem_1.13e/CubeSatSim_maxtelemetry.csv b/spacecraft/FoxTelem_1.13e/CubeSatSim_maxtelemetry.csv new file mode 100644 index 000000000..c442b89de --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/CubeSatSim_maxtelemetry.csv @@ -0,0 +1,48 @@ +47,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION +0,MAX,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2 +1,MAX,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3 +2,MAX,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage +3,MAX,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis +4,MAX,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis +5,MAX,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis +6,MAX,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current +7,MAX,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,STEM Payload Sensor BME280 Temperature +8,MAX,PANEL_PLUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X Panel Voltage +9,MAX,PANEL_MINUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X Panel Voltage +10,MAX,PANEL_PLUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y Panel Voltage +11,MAX,PANEL_MINUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y Panel Voltage +12,MAX,PANEL_PLUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z Panel Voltage +13,MAX,PANEL_MINUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z Panel Voltage +14,MAX,PANEL_PLUS_X_I,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X Panel Current +15,MAX,PANEL_MINUS_X_I,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X Panel Current +16,MAX,PANEL_PLUS_Y_I,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y Panel Current +17,MAX,PANEL_MINUS_Y_I,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y Panel Current +18,MAX,PANEL_PLUS_Z_I,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z Panel Current +19,MAX,PANEL_MINUS_Z_I,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z Panel Current +20,MAX,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage +21,MAX,SPIN,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells +22,MAX,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,STEM Payload Sensor BME280 Pressure +23,MAX,Altitude,12,m,cubesatsim_altitude,NONE,6,4,3,BME280 Altitude,STEM Payload Sensor BME280 Altitude +24,MAX,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count +25,MAX,RSSI,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication +26,MAX,IHUTemperature,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal Temperature of Pi IHU +27,MAX,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around X Axis +28,MAX,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Y Axis +29,MAX,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Z Axis +30,MAX,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,STEM Payload Sensor BME280 Humidity +31,MAX,BATT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current +32,MAX,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature +33,MAX,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1 +34,MAX,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status,STEM Payload Board Status +35,MAX,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage) +36,MAX,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry, Simulated Telemetry Indicator +37,MAX,PayloadStatus1,1,-,17,NONE,0,0,0,Exp 3,STEM Payload status 1 failure indicator +38,MAX,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator +39,MAX,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator +40,MAX,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator +41,MAX,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator +42,MAX,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received +43,MAX,RXAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status +44,MAX,TXAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status +45,MAX,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status +46,MAX,Pad,56,-,0,NONE,0,0,0,NONE,NONE diff --git a/spacecraft/FoxTelem_1.13e/CubeSatSim_mintelemetry.csv b/spacecraft/FoxTelem_1.13e/CubeSatSim_mintelemetry.csv new file mode 100644 index 000000000..eefa1e486 --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/CubeSatSim_mintelemetry.csv @@ -0,0 +1,48 @@ +47,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHORT_NAME,DESCRIPTION +0,MIN,Sensor 2,12,integer,1,NONE,6,8,3,Sensor 2,STEM Payload Extra Sensor 2 +1,MIN,Sensor 3,12,integer,1,NONE,6,9,3,Sensor 3,STEM Payload Extra Sensor 3 +2,MIN,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,INA219 Battery Voltage +3,MIN,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around X Axis +4,MIN,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Y Axis +5,MIN,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,STEM Payload Board MPU6050 Acceleration around Z Axis +6,MIN,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,INA219 Battery Current +7,MIN,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,BME280 Temp,STEM Payload Sensor BME280 Temperature +8,MIN,PANEL_PLUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,INA219 +X Panel Voltage +9,MIN,PANEL_MINUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,INA219 -X Panel Voltage +10,MIN,PANEL_PLUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,INA219 +Y Panel Voltage +11,MIN,PANEL_MINUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,INA219 -Y Panel Voltage +12,MIN,PANEL_PLUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,INA219 +Z Panel Voltage +13,MIN,PANEL_MINUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,INA219 -Z Panel Voltage +14,MIN,PANEL_PLUS_X_I,12,mA,cubesatsim_current,NONE,7,2,3,Current,INA219 +X Panel Current +15,MIN,PANEL_MINUS_X_I,12,mA,cubesatsim_current,NONE,10,2,3,Current,INA219 -X Panel Current +16,MIN,PANEL_PLUS_Y_I,12,mA,cubesatsim_current,NONE,8,2,3,Current,INA219 +Y Panel Current +17,MIN,PANEL_MINUS_Y_I,12,mA,cubesatsim_current,NONE,11,2,3,Current,INA219 -Y Panel Current +18,MIN,PANEL_PLUS_Z_I,12,mA,cubesatsim_current,NONE,9,2,3,Current,INA219 +Z Panel Current +19,MIN,PANEL_MINUS_Z_I,12,mA,cubesatsim_current,NONE,12,2,3,Current,INA219 -Z Panel Current +20,MIN,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery 2 Voltage,INA219 Battery 2 Voltage +21,MIN,SPIN,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells +22,MIN,Pressure,12,hPa,cubesatsim_pressure,NONE,6,3,3,BME280 Pressure,STEM Payload Sensor BME280 Pressure +23,MIN,Altitude,12,m,cubesatsim_altitude,NONE,6,4,3,BME280 Altitude,STEM Payload Sensor BME280 Altitude +24,MIN,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count +25,MIN,RSSI,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication +26,MIN,IHUTemperature,12,C,cubesatsim_temperature,NONE,2,1,3,IHU Temp (Pi),Internal Temperature of Pi IHU +27,MIN,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around X Axis +28,MIN,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Y Axis +29,MIN,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,STEM Payload Board MPU6050 Angular Veolcity around Z Axis +30,MIN,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,BME280 Humidity,STEM Payload Sensor BME280 Humidity +31,MIN,BATT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery 2 Current,INA219 Battery 2 Current +32,MIN,DiodeTemp,12,C,cubesatsim_rpm,NONE,6,6,3,Diode Temp,STEM Payload Diode Temperature +33,MIN,Sensor 1,12,integer,1,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1 +34,MIN,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status,STEM Payload Board Status +35,MIN,SafeMode,1,-,STATUS_ON_OFF,NONE,3,2,0,Safe Mode, Safe Mode (Low Battery Voltage) +36,MIN,SimulatedTelemetry,1,-,STATUS_ON_OFF,NONE,3,4,0,Simulated Telemetry, Simulated Telemetry Indicator +37,MIN,PayloadStatus1,1,-,17,NONE,0,0,0,Exp 3,STEM Payload status 1 failure indicator +38,MIN,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator +39,MIN,I2CBus1Failure,1,-,17,NONE,2,2,0,I2C Bus 1,I2C bus 1 failure indicator +40,MIN,I2CBus3Failure,1,-,17,NONE,2,3,0,I2C Bus 3,I2C bus 3 failure indicator +41,MIN,CameraFailure,1,-,17,NONE,2,4,0,Camera,Camera failure indicator +42,MIN,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received +43,MIN,RXAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status +44,MIN,TXAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status +45,MIN,C2CStatus,2,-,COMMAND_STATUS,NONE,3,5,0,Command Control, Command & Control Status +46,MIN,Pad,56,-,0,NONE,0,0,0,NONE,NONE diff --git a/spacecraft/FoxTelem_1.13e/CubeSatSim_rttelemetry.csv b/spacecraft/FoxTelem_1.13e/CubeSatSim_rttelemetry.csv index 10175581f..e69de29bb 100644 --- a/spacecraft/FoxTelem_1.13e/CubeSatSim_rttelemetry.csv +++ b/spacecraft/FoxTelem_1.13e/CubeSatSim_rttelemetry.csv @@ -1,47 +0,0 @@ -46,TYPE,FIELD,BITS,UNIT,CONVERSION,MODULE,MODULE_NUM,MODULE_LINE,LINE_TYPE,SHOMIN_NAME,DESCRIPTION -0,MIN,SENSOR2,12,V,cubesatsim_voltage|FLOAT2,NONE,0,0,3,Sensor2,STEM Payload Extra Sensor2 -1,MIN,SENSOR3,12,V,cubesatsim_voltage|FLOAT2,NONE,0,0,3,Sensor3,STEM Payload Extra Sensor3 -2,MIN,BATT_V,12,V,cubesatsim_voltage|FLOAT2,NONE,4,1,3,Battery Voltage,Battery Voltage -3,MIN,SatelliteXAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,7,4,3,Acceleration,Acceleration around X Axis -4,MIN,SatelliteYAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,8,4,3,Acceleration,Acceleration around Y Axis -5,MIN,SatelliteZAxisAcceleration,12,g,cubesatsim_acceleration|FLOAT2,NONE,9,4,3,Acceleration,Acceleration around Z Axis -6,MIN,BATT_I,12,mA,cubesatsim_current,NONE,4,2,3,Battery Current,Battery current -7,MIN,Temperature,12,C,cubesatsim_temperature,NONE,6,2,3,Temperature,STEM Payload Sensor Temperature -8,MIN,PANEL_PLUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,7,1,3,Voltage,+X Panel -9,MIN,PANEL_MINUS_X_V,12,V,cubesatsim_voltage|FLOAT2,NONE,10,1,3,Voltage,-X Panel -10,MIN,PANEL_PLUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,8,1,3,Voltage,+Y Panel -11,MIN,PANEL_MINUS_Y_V,12,V,cubesatsim_voltage|FLOAT2,NONE,11,1,3,Voltage,-Y Panel -12,MIN,PANEL_PLUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,9,1,3,Voltage,+Z Panel -13,MIN,PANEL_MINUS_Z_V,12,V,cubesatsim_voltage|FLOAT2,NONE,12,1,3,Voltage,-Z Panel -14,MIN,PANEL_PLUS_X_I,12,mA,cubesatsim_current,NONE,7,2,3,Current,+X Panel -15,MIN,PANEL_MINUS_X_I,12,mA,cubesatsim_current,NONE,10,2,3,Current,-X Panel -16,MIN,PANEL_PLUS_Y_I,12,mA,cubesatsim_current,NONE,8,2,3,Current,+Y Panel -17,MIN,PANEL_MINUS_Y_I,12,mA,cubesatsim_current,NONE,11,2,3,Current,-Y Panel -18,MIN,PANEL_PLUS_Z_I,12,mA,cubesatsim_current,NONE,9,2,3,Current,+Z Panel -19,MIN,PANEL_MINUS_Z_I,12,mA,cubesatsim_current,NONE,12,2,3,Current,-Z Panel -20,MIN,BATT2_V,12,V,cubesatsim_voltage|FLOAT2,NONE,5,1,3,Battery2 Voltage,Battery2 Voltage -21,MIN,SPIN,12,rpm,cubesatsim_rpm,NONE,3,1,3,Spacecraft Spin,Calculated spin rate using solar cells -22,MIN,Pressure,12,bar,cubesatsim_pressure,NONE,6,3,3,Pressure,STEM Payload Sensor Pressure -23,MIN,Altitude,12,m,cubesatsim_altitude,NONE,6,4,3,Altitude,STEM Payload Sensor Altitude -24,MIN,Resets,12,-,12,NONE,3,2,3,Reset Count, Software Reset Count -25,MIN,RSSI,12,dBm,cubesatsim_rssi|INT,NONE,1,1,3,RSSI,Received Signal Strength Indication -26,MIN,IHUTemperature,12,C,cubesatsim_temperature,NONE,2,1,3,Temperature,Internal Temperature of IHU -27,MIN,SatelliteXAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,7,3,3,Rotation,Angular Veolcity around X Axis -28,MIN,SatelliteYAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,8,3,3,Rotation,Angular Veolcity around Y Axis -29,MIN,SatelliteZAxisAngularVelocity,12,dps,cubesatsim_rotation|INT,NONE,9,3,3,Rotation,Angular Veolcity around Z Axis -30,MIN,Humidity,12,%,cubesatsim_temperature,NONE,6,5,3,Humidity,STEM Payload Sensor Humidity -31,MIN,BATT2_I,12,mA,cubesatsim_current,NONE,5,2,3,Battery2 Current,Power Supply DC Current -32,MIN,DIODE_T,12,signed raw,cubesatsim_rpm,NONE,6,6,3,Diode Temperature,Diode Temperature -33,MIN,Sensor1,12,signed scaled,cubesatsim_rpm,NONE,6,7,3,Sensor 1,STEM Payload Extra Sensor 1 -34,MIN,STEMPayloadStatus,1,-,17,NONE,6,1,0,STEM Payload Status,STEM Payload Board Status -35,MIN,Nominal Mode,1,-,17,NONE,3,2,0,Nominal Mode, Nominal Mode (Not Safe Mode) -36,MIN,PayloadStatus1,1,-,17,NONE,6,7,0,Exp 2,STEM Payload status 1 failure indicator -37,MIN,PayloadStatus2,1,-,17,NONE,6,8,0,Exp 3,STEM Payload status 2 failure indicator -38,MIN,I2CBus0Failure,1,-,17,NONE,2,2,0,I2C Bus 0,I2C bus 0 failure indicator -39,MIN,I2CBus1Failure,1,-,17,NONE,2,3,0,I2C Bus 1,I2C bus 1 failure indicator -40,MIN,I2CBus3Failure,1,-,17,NONE,2,4,0,I2C Bus 3,I2C bus 3 failure indicator -41,MIN,CameraFailure,1,-,17,NONE,2,5,0,Camera,Camera failure indicator -42,MIN,GroundCommands,4,-,1,NONE,3,3,0,Ground Commands,Number of ground commands received -43,MIN,RXAntenna,1,-,16,NONE,1,3,0,RX Antenna,Receive antenna status -44,MIN,TXAntenna,1,-,16,NONE,1,2,0,TX Antenna,Transmit antenna status -45,MIN,Pad,58,-,0,NONE,0,0,0,NONE,NONE diff --git a/spacecraft/FoxTelem_1.13e/CubeSat_Simulator_DUV.MASTER b/spacecraft/FoxTelem_1.13e/CubeSat_Simulator_DUV.MASTER new file mode 100644 index 000000000..05812fc69 --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/CubeSat_Simulator_DUV.MASTER @@ -0,0 +1,59 @@ +#Fox 1 Telemetry Decoder Properties +#Sat Apr 11 13:20:20 EST 2020 +#File named .dat should be in the logfiles directory and is loaded by FoxTelem +#File named .MASTER should not be edited and is a backup copy in the installation directory +foxId=7 +displayName=CubeSatSim-FSK +name=CubeSatSim +model=0 +IHU_SN=7 +catalogNumber=0 +description=CubeSatSim, the AMSAT CubeSat Simulator, is a functional satellite model that generates real telemetry from solar panels, batteries, and temperature sensors. Use this for DUV FSK telemetry. For more information see http://cubesatsim.org +BATTERY_CURRENT_ZERO=-1.839 +EXP1=0 +EXP2=0 +EXP3=0 +EXP4=0 +numberOfLayouts=4 +layout0.filename=FOX1A_debug.csv +layout0.name=DEBUG +layout1.filename=CubeSatSim_maxtelemetry.csv +layout1.name=maxtelemetry +layout2.filename=CubeSatSim_rttelemetry.csv +layout2.name=rttelemetry +layout3.filename=CubeSatSim_mintelemetry.csv +layout3.name=mintelemetry +#layout4.filename=FOX1A_radtelemetry.csv +#layout4.name=radtelemetry +#layout5.filename=FOX1A_radtelemetry2.csv +#layout5.name=radtelemetry2 +#layout5.parentLayout=radtelemetry +lookupTable0.filename=FOX1A_rssiFM.tab +numberOfLookupTables=3 +lookupTable0=RSSI +lookupTable1.filename=FOX1A_ihuVBattSN7.tab +lookupTable1=IHU_VBATT +lookupTable2.filename=FOX1A_ihutempSN7.tab +lookupTable2=IHU_TEMP +numberOfStringLookupTables=2 +stringLookupTable0.filename=status_on_off.tab +stringLookupTable0=STATUS_ON_OFF +stringLookupTable1=COMMAND_STATUS +stringLookupTable1.filename=command_status.tab +telemetryDownlinkFreqkHz=434900 +maxFreqBoundkHz=434950 +minFreqBoundkHz=434850 +measurementsFileName=measurements.csv +memsRestValueX=2087 +memsRestValueY=2101 +memsRestValueZ=2045 +passMeasurementsFileName=passmeasurements.csv +numberOfSources=1 +source0.name=amsat.cubesat_simulator.ihu.duv +source0.formatName=FSK 200bps (Fox1) +#source1.name=amsat.cubesat_simulator.ihu.highspeed +track=false +useIHUVBatt=true +user_format=FSK 200bps (Fox1) +useConversionCoeffs=true +conversionCurvesFileName=CubeSatSim_conversion_curves.csv diff --git a/spacecraft/FoxTelem_1.13e/CubeSat_Simulator_PSK.MASTER b/spacecraft/FoxTelem_1.13e/CubeSat_Simulator_PSK.MASTER new file mode 100644 index 000000000..56c22e88d --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/CubeSat_Simulator_PSK.MASTER @@ -0,0 +1,77 @@ +#Fox 1 Telemetry Decoder Properties +#Thu Apr 11 13:23:23 EST 2020 +user_mode=4 +foxId=99 +IHU_SN=7 +catalogNumber=0 +model=0 +mpptResistanceError=6.58 +mpptSensorOffThreshold=1600 +name=CubeSatSim +displayName=CubeSatSim-BPSK +BATTERY_CURRENT_ZERO=-1.834 +hasImprovedCommandReceiver=true +EXP1=0 +EXP2=0 +EXP3=0 +EXP4=0 +description=CubeSatSim, the AMSAT CubeSat Simulator, is a functional satellite model that generates real telemetry from solar panels, batteries, and temperature sensors. Use this for BPSK telemetry. For more information see http://cubesatsim.org +numberOfFrameLayouts=5 +frameLayout0.filename=FOX1E_Type0_ALL_WOD.frame +frameLayout0.name=All WOD +frameLayout1.filename=CubeSatSim_PSK_Type1_HEALTH.frame +frameLayout1.name=Health +frameLayout2.filename=CubeSatSim_PSK_Type2_MINMAX.frame +frameLayout2.name=MinMax +frameLayout3.filename=FOX1E_Type3_REALTIME_BEACON.frame +frameLayout3.name=Realtime Beacon +frameLayout4.filename=FOX1E_Type4_WOD_BEACON.frame +frameLayout4.name=WOD Beacon +numberOfLayouts=9 +layout0.filename=FOX1A_debug.csv +layout0.name=DEBUG +layout1.filename=CubeSatSim_PSK_maxtelemetry.csv +layout1.name=maxtelemetry +layout2.filename=CubeSatSim_PSK_rttelemetry.csv +layout2.name=rttelemetry +layout3.filename=CubeSatSim_PSK_mintelemetry.csv +layout3.name=mintelemetry +layout4.filename=FOX1E_radtelemetry.csv +layout4.name=radtelemetry +layout5.filename=FOX1E_radtelemetry2.csv +layout5.name=radtelemetry2 +layout5.parentLayout=radtelemetry +layout6.filename=CubeSatSim_PSK_wodtelemetry.csv +layout6.name=wodtelemetry +layout7.filename=FOX1E_wodradtelemetry.csv +layout7.name=wodradtelemetry +layout8.filename=FOX1E_wodradtelemetry2.csv +layout8.name=wodradtelemetry2 +layout8.parentLayout=wodradtelemetry +numberOfLookupTables=3 +lookupTable0.filename=FOX1A_rssiFM.tab +lookupTable0=RSSI +lookupTable1.filename=FOX1E_ihuVBattSNx.tab +lookupTable1=IHU_VBATT +lookupTable2.filename=FOX1A_ihutempSN7.tab +lookupTable2=IHU_TEMP +numberOfStringLookupTables=2 +stringLookupTable0.filename=status_on_off.tab +stringLookupTable0=STATUS_ON_OFF +stringLookupTable1=COMMAND_STATUS +stringLookupTable1.filename=command_status.tab +maxFreqBoundkHz=434950 +measurementsFileName=measurements.csv +memsRestValueX=2129 +memsRestValueY=2131 +memsRestValueZ=2103 +minFreqBoundkHz=434850 +passMeasurementsFileName=passmeasurements.csv +telemetryDownlinkFreqkHz=434900 +track=true +useIHUVBatt=false +numberOfSources=1 +source0.name=amsat.cubesat_simulator.ihu.bpsk +user_format=0 +useConversionCoeffs=true +conversionCurvesFileName=CubeSatSim_conversion_curves.csv diff --git a/spacecraft/FoxTelem_1.13e/README.md b/spacecraft/FoxTelem_1.13e/README.md new file mode 100644 index 000000000..a7ff0428b --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/README.md @@ -0,0 +1,3 @@ +These files are for FoxTelem version 1.13e in the spacecraft directory. + +You can download this version of FoxTelem here: https://www.g0kla.com/foxtelem/downloads/test/ diff --git a/spacecraft/FoxTelem_1.13e/command_status.tab b/spacecraft/FoxTelem_1.13e/command_status.tab new file mode 100644 index 000000000..73d91a95a --- /dev/null +++ b/spacecraft/FoxTelem_1.13e/command_status.tab @@ -0,0 +1,3 @@ +0,OFF +1,Carrier +2,DTMF/APRS diff --git a/squelch_cc.py b/squelch_cc.py new file mode 100644 index 000000000..9faa6ca85 --- /dev/null +++ b/squelch_cc.py @@ -0,0 +1,196 @@ +import RPi.GPIO as GPIO +from RPi.GPIO import output +from time import sleep +from os import system +import sys + +def command_control_check(): + +# global command_control +# global no_command + global debug_mode + command_count = 0 + global squelch + global txLed + +# output(pd, 1) +# output(ptt, 1) +# sleep(1) +# if (no_command == False and GPIO.input(squelch) == False): + if GPIO.input(squelch) == False: + print("carrier received!") + # command_tx = not command_tx +# print(command_tx) + + try: + file = open("/home/pi/CubeSatSim/command_count.txt", "r") + string = file.read() + file.close() + command_count = int(string) + command_count += 1 + filec = open("/home/pi/CubeSatSim/command_count.txt", "w") + command_count_string = str(command_count) + print(command_count_string) + string = filec.write(command_count_string) + filec.close() + except: + print("Can't write command_count file!") + print("Command_count: ") + print(command_count) + + increment_mode() + +# if (command_tx == True): +# print("Turning on transmit") +# system("echo > command_tx True") +# output(txLed, txLedOn) +# sleep(0.5) +# output(txLed, txLedff) +# else: +# print("Turning off transmit") +# system("echo > command_tx False") +## else: +## print("No carrier received!") +# output(pd, 0) +# sleep(1) + +def increment_mode(): + global debug_mode + + print("increment mode") + powerPin = 16 + try: + file = open("/home/pi/CubeSatSim/.mode") + mode = file.read(1) + except: +# mode = "f" +# if (debug_mode == 1): + print("Can't open .mode file") # , defaulting to FSK") + file.close() + print("Mode is: ") + print(mode) + if (mode == 'a'): + mode = 'f' + GPIO.output(powerPin, 0) # blink two times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + elif (mode == 'f'): + mode = 'b' + GPIO.output(powerPin, 0) # blink three times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + elif (mode == 'b'): + mode = 's' + GPIO.output(powerPin, 0) # blink four times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + elif (mode == 's'): + mode = 'm' + GPIO.output(powerPin, 0) # blink five times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1); + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + else: + mode = 'a' + GPIO.output(powerPin, 0) # blink one time + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(1) + + try: + print("/home/pi/CubeSatSim/config -" + mode) + if (debug_mode == False): + GPIO.setwarnings(False) + GPIO.output(txLed, 0) + GPIO.output(powerPin, 0) + system("sudo systemctl stop rpitx") + system("sudo systemctl stop cubesatsim") + + system("/home/pi/CubeSatSim/config -" + mode) + print("Changing mode now") + + +# file = open("/home/pi/CubeSatSim/.mode", "w") +# count_string = str(command_count) +# file.write(mode) +# file.close() +# print(".mode file written") +# print("sudo reboot -h now") +# GPIO.setwarnings(False) +# GPIO.setup(powerPin, GPIO.OUT) +# GPIO.output(powerPin, 0); +# system("reboot -h now") +# release = True; +# system("/home/pi/CubeSatSim/config -" + mode) +# system("reboot -h now") + print(" ") +# sleep(10); + except: + print("can't change mode") + +print("Squelch Command and Control active") +debug_mode = False +if (len(sys.argv)) > 1: +# print("There are arguments!") + if ('d' == sys.argv[1]): + debug_mode = True + print("Debug mode - mode changes not made") + +GPIO.setmode(GPIO.BCM) +GPIO.setwarnings(False) +squelch = 6 +powerPin = 16 +txLed = 27 +GPIO.setup(squelch, GPIO.IN, pull_up_down=GPIO.PUD_UP) ## pull up in case pin is not connected +GPIO.setup(powerPin, GPIO.OUT) +GPIO.setup(txLed, GPIO.OUT) + +while True: + command_control_check() + sleep(0.5) diff --git a/stempayload/Payload_BME280_MPU6050_AIO/Payload_BME280_MPU6050_AIO.ino b/stempayload/Payload_BME280_MPU6050_AIO/Payload_BME280_MPU6050_AIO.ino new file mode 100644 index 000000000..a1022069e --- /dev/null +++ b/stempayload/Payload_BME280_MPU6050_AIO/Payload_BME280_MPU6050_AIO.ino @@ -0,0 +1,683 @@ +// code for Pico or Pro Micro or STM32 on the CubeSat Simulator STEM Payload board +// works wih CubeSatSim software v1.3.2 or later +// extra sensors can be added in payload_extension.cpp file + +#include +#include +#include +#include +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) +#include +#endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Arduino Mbed OS RP2040 Boards is used in Arduino IDE +#include +TinyGPSPlus gps; +UART Serial2(8, 9, 0, 0); + +#elif !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards in Arduino IDE +#include +TinyGPSPlus gps; +bool check_for_wifi(); +bool wifi = false; +int led_builtin_pin; +float tlm[20]; + +#else // if Sparkfun Pro Micro or STM32 +#include +#endif + +#define SEALEVELPRESSURE_HPA (1013.25) + +Adafruit_BME280 bme; +MPU6050 mpu6050(Wire); + +long timer = 0; +int bmePresent; +int RXLED = 17; // The RX LED has a defined Arduino pin +int greenLED = 9; +int blueLED = 8; +int Sensor1 = 0; +float Sensor2 = 0; +float temp; +int calibration = 0; + +void ee_prom_word_write(int addr, int val); +short ee_prom_word_read(int addr); +int first_time = true; +int first_read = true; + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) +float T2 = 24; // Temperature data point 1 +float R2 = 169; // Reading data point 1 +float T1 = 6; // Temperature data point 2 +float R1 = 181; // Reading data point 2 +#endif +#if defined __AVR_ATmega32U4__ +float T2 = 26.3; // Temperature data point 1 +float R2 = 167; // Reading data point 1 +float T1 = 2; // Temperature data point 2 +float R1 = 179; // Reading data point 2 +#endif +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) +float T2 = 25; // Temperature data point 1 +float R2 = 671; // Reading data point 1 +float T1 = 15.5; // Temperature data point 2 +float R1 = 695; // Reading data point 2 +#endif + +int sensorValue; +float Temp; +float rest; + +char sensor_end_flag[] = "_END_FLAG_"; +char sensor_start_flag[] = "_START_FLAG_"; +bool show_gps = true; // set to false to not see all messages +float flon = 0.0, flat = 0.0, flalt = 0.0; +void get_gps(); + +extern void payload_setup(); // sensor extension setup function defined in payload_extension.cpp +extern void payload_loop(); // sensor extension read function defined in payload_extension.cpp + +extern void aio_setup(); // Adafruit IO setup code defined in adafruitio_00_publish.cpp +extern void aio_loop(float telem[]); // Adafruit IO loop code defined in adafruitio_00_publish.cpp + +void setup() { + + Serial.begin(115200); // Serial Monitor for testing + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + Serial1.setRX(1); + delay(100); + Serial1.setTX(0); + delay(100); +#endif + + Serial1.begin(115200); // for communication with Pi Zero + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards in Arduino IDE + EEPROM.begin(512); +#endif + + delay(2000); + +#if defined (ARDUINO_ARCH_MBED_RP2040) && (ARDUINO_ARCH_RP2040) + Serial.println("Pico with Mbed"); +#elif !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + Serial.println("Pico with RP2040"); +#elif defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + Serial.println("STM32"); +#elif defined __AVR_ATmega32U4__ + Serial.println("Pro Micro"); +#else + Serial.println("Unknown board"); +#endif + + Serial.println("Starting!"); + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + Serial.println("Starting Serial2 for optional GPS on JP12"); +// Serial2.begin(9600); // serial from - some modules need 115200 + Serial2.begin(9600); // serial from GPS or other serial sensor. Some GPS need 115200 + + // set all Pico GPIO connected pins to input + for (int i = 10; i < 22; i++) { + pinMode(i, INPUT); + } + pinMode(26, INPUT); + pinMode(27, INPUT); + pinMode(28, INPUT); + pinMode(15, INPUT_PULLUP); // squelch +#endif + + blink_setup(); + + blink(500); + delay(250); + blink(500); + delay(250); + led_set(greenLED, HIGH); + delay(250); + led_set(greenLED, LOW); + led_set(blueLED, HIGH); + delay(250); + led_set(blueLED, LOW); + + if (bme.begin(0x76)) { + bmePresent = 1; + } else { + Serial.println("Could not find a valid BME280 sensor, check wiring!"); + bmePresent = 0; + } + + mpu6050.begin(); + + if (eeprom_word_read(0) == 0xA07) + { + Serial.println("Reading gyro offsets from EEPROM\n"); + + float xOffset = ((float)eeprom_word_read(1)) / 100.0; + float yOffset = ((float)eeprom_word_read(2)) / 100.0; + float zOffset = ((float)eeprom_word_read(3)) / 100.0; + + Serial.println(xOffset, DEC); + Serial.println(yOffset, DEC); + Serial.println(zOffset, DEC); + + mpu6050.setGyroOffsets(xOffset, yOffset, zOffset); + + Serial.println("\nTemperature calibration data from EEPROM\n"); + + T1 = ((float)eeprom_word_read(4)) / 10.0; + R1 = ((float)eeprom_word_read(5)); + T2 = ((float)eeprom_word_read(6)) / 10.0; + R2 = ((float)eeprom_word_read(7)); + + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + Serial.println(" "); + + } + else + { + Serial.println("Calculating gyro offsets\n"); + mpu6050.calcGyroOffsets(true); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + Serial.println("Storing gyro offsets in EEPROM\n"); + + eeprom_word_write(0, 0xA07); + eeprom_word_write(1, (int)(mpu6050.getGyroXoffset() * 100.0) + 0.5); + eeprom_word_write(2, (int)(mpu6050.getGyroYoffset() * 100.0) + 0.5); + eeprom_word_write(3, (int)(mpu6050.getGyroZoffset() * 100.0) + 0.5); + + Serial.println(eeprom_word_read(0), HEX); + Serial.println(((float)eeprom_word_read(1)) / 100.0, DEC); + Serial.println(((float)eeprom_word_read(2)) / 100.0, DEC); + Serial.println(((float)eeprom_word_read(3)) / 100.0, DEC); + + Serial.println("\nStoring temperature calibration data in EEPROM\n"); + + eeprom_word_write(4, (int)(T1 * 10.0) + 0.5); + eeprom_word_write(5, (int) R1); + eeprom_word_write(6, (int)(T2 * 10.0) + 0.5); + eeprom_word_write(7, (int) R2); + + T1 = ((float)eeprom_word_read(4)) / 10.0; + R1 = ((float)eeprom_word_read(5)); + T2 = ((float)eeprom_word_read(6)) / 10.0; + R2 = ((float)eeprom_word_read(7)); + + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + Serial.println(" "); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif +#endif + } + payload_setup(); // sensor extension setup function defined in payload_extension.cpp + aio_setup(); // Adafruit IO setup code defined in adafruitio_00_publish.cpp + + for (int i = 0; i++; i < 20) + tlm[i] = 0.0; +// tlm[0] = 23.1; // uncomment for non-zero test values if no BME or MPU sensor is attached. +// tlm[1] = 1000.2; +// tlm[2] = 122; +// tlm[3] = 56.8; +} + +void loop() { + + blink(50); + + if (Serial1.available() > 0) { + Serial.print("Received serial data!!!\n"); + delay(10); + while (Serial1.available() > 0) { + char result = Serial1.read(); + Serial.print(result); + } + Serial.println(" "); + } + { +// if (result == '?') + { + if (bmePresent) { + + tlm[0] = bme.readTemperature(); + tlm[1] = bme.readPressure() / 100.0F; + tlm[2] = bme.readAltitude(SEALEVELPRESSURE_HPA); + tlm[3] = bme.readHumidity(); + + Serial1.print(sensor_start_flag); + Serial1.print("OK BME280 "); + Serial1.print(tlm[0]); + Serial1.print(" "); + Serial1.print(tlm[1]); + Serial1.print(" "); + Serial1.print(tlm[2]); + Serial1.print(" "); + Serial1.print(tlm[3]); + + Serial.print("OK BME280 "); + Serial.print(tlm[0]); + Serial.print(" "); + Serial.print(tlm[1]); + Serial.print(" "); + Serial.print(tlm[2]); + Serial.print(" "); + Serial.print(tlm[3]); + } else + { + Serial1.print(sensor_start_flag); + Serial1.print("OK BME280 0.0 0.0 0.0 0.0"); + + Serial.print("OK BME280 0.0 0.0 0.0 0.0"); + } + mpu6050.update(); + + tlm[4] = mpu6050.getGyroX(); + tlm[5] = mpu6050.getGyroY(); + tlm[6] = mpu6050.getGyroZ(); + tlm[7] = mpu6050.getAccX(); + tlm[8] = mpu6050.getAccY(); + tlm[9] = mpu6050.getAccZ(); + + Serial1.print(" MPU6050 "); + Serial1.print(tlm[4]); + Serial1.print(" "); + Serial1.print(tlm[5]); + Serial1.print(" "); + Serial1.print(tlm[6]); + + Serial1.print(" "); + Serial1.print(tlm[7]); + Serial1.print(" "); + Serial1.print(tlm[8]); + Serial1.print(" "); + Serial1.print(tlm[9]); + + Serial.print(" MPU6050 "); + Serial.print(tlm[4]); + Serial.print(" "); + Serial.print(tlm[5]); + Serial.print(" "); + Serial.print(tlm[6]); + + Serial.print(" "); + Serial.print(tlm[7]); + Serial.print(" "); + Serial.print(tlm[8]); + Serial.print(" "); + Serial.print(tlm[9]); + + sensorValue = read_analog(); + +// Serial.println(sensorValue); + Temp = T1 + (sensorValue - R1) *((T2 - T1)/(R2 - R1)); + +// Serial1.print(" GPS 0 0 0 TMP "); + + Serial1.print(" GPS "); + Serial1.print(flat,4); + Serial1.print(" "); + Serial1.print(flon,4); + Serial1.print(" "); + Serial1.print(flalt,2); + + Serial1.print(" TMP "); + Serial1.print(Temp); + +// Serial1.print(" "); +// Serial1.println(Sensor2); + + Serial.print(" GPS "); + Serial.print(flat,4); + Serial.print(" "); + Serial.print(flon,4); + Serial.print(" "); + Serial.print(flalt,2); + +// Serial.print(" GPS 0 0 0 TMP "); + Serial.print(" TMP "); + Serial.print(Temp); +// Serial.print(" "); +// Serial.println(Sensor2); + + float rotation = sqrt(tlm[4]*tlm[4] + tlm[5]*tlm[5] + tlm[6]*tlm[6]); + float acceleration = sqrt(tlm[7]*tlm[7] + tlm[8]*tlm[8] + tlm[9]*tlm[9]); +// Serial.print(rotation); +// Serial.print(" "); +// Serial.println(acceleration); + + if (first_read == true) { + first_read = false; + rest = acceleration; + } + + if (acceleration > 1.2 * rest) + led_set(greenLED, HIGH); + else + led_set(greenLED, LOW); + + if (rotation > 5) + led_set(blueLED, HIGH); + else + led_set(blueLED, LOW); + } + + payload_loop(); // sensor extension read function defined in payload_extension.cpp + aio_loop(tlm); // Adafruit IO loop code defined in adafruitio_00_publish.cpp + +// Serial1.println(" "); + Serial1.println(sensor_end_flag); + Serial.println(" "); + + } + + if (Serial.available() > 0) { + blink(50); + char result = Serial.read(); +// Serial.println(result); +// Serial.println("OK"); +// Serial.println(counter++); +//#if !defined (ARDUINO_ARCH_RP2040) + if (result == 'R' || result == 'r') { +// Serial1.println("OK"); +// delay(100); + Serial.println("Resetting\n"); + first_read = true; + setup(); + } + else if (result == 'D' || result == 'd') { + Serial.println("\nCurrent temperature calibration data\n"); + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + + Serial.println("\nCurrent raw temperature reading\n"); + Serial.println(sensorValue, DEC); + Serial.println(" "); + } + else if (result == 'C' || result == 'c') { + Serial.println("\nClearing stored gyro offsets in EEPROM\n"); + eeprom_word_write(0, 0x00); +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif + first_time = true; + setup(); + } + else if (result == 'S' || result == 's') { + Serial.print("\nStoring temperature calibration data point "); // in EEPROM\n"); + Serial.print(calibration + 1); + Serial.print(" in EEPROM\n"); + + Serial.println(temp); + Serial.println(sensorValue); + Serial.println(" "); + + eeprom_word_write(calibration * 2 + 4 , (int)(temp * 10.0) + 0.5); + eeprom_word_write(calibration * 2 + 5, sensorValue); + + if (calibration == 0) { + T1 = temp; + R1 = sensorValue; + calibration = 1; + } else { + T2 = temp; + R2 = sensorValue; + calibration = 0; + } + +// calibration = (calibration + 1) % 2; +// Serial.println(calibration + 1); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif + + } +//#endif + } + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + Serial.print("Squelch: "); + Serial.println(digitalRead(15)); + + get_gps(); +#else + delay(1000); // not needed due to gps 1 second polling delay + +#endif +} + +void eeprom_word_write(int addr, int val) +{ +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + EEPROM.write(addr * 2, lowByte(val)); + EEPROM.write(addr * 2 + 1, highByte(val)); +#endif +} + +short eeprom_word_read(int addr) +{ + int result = 0; +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + result = ((EEPROM.read(addr * 2 + 1) << 8) | EEPROM.read(addr * 2)); +#endif + return result; +} + +void blink_setup() +{ +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + // initialize digital pin PB1 as an output. + pinMode(PC13, OUTPUT); + pinMode(PB9, OUTPUT); + pinMode(PB8, OUTPUT); +#endif + +#if defined __AVR_ATmega32U4__ + pinMode(RXLED, OUTPUT); // Set RX LED as an output + // TX LED is set as an output behind the scenes + pinMode(greenLED, OUTPUT); + pinMode(blueLED,OUTPUT); +#endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + pinMode(LED_BUILTIN, OUTPUT); + pinMode(18, OUTPUT); // blue LED on STEM Payload Board v1.3.2 + pinMode(19, OUTPUT); // green LED on STEM Payload Board v1.3.2 +#endif + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (check_for_wifi()) { + wifi = true; + led_builtin_pin = LED_BUILTIN; // use default GPIO for Pico W + pinMode(LED_BUILTIN, OUTPUT); +// configure_wifi(); + } else { + led_builtin_pin = 25; // manually set GPIO 25 for Pico board +// pinMode(25, OUTPUT); + pinMode(led_builtin_pin, OUTPUT); + } + pinMode(18, OUTPUT); + pinMode(19, OUTPUT); +#endif +} + +void blink(int length) +{ +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + digitalWrite(PC13, LOW); // turn the LED on (HIGH is the voltage level) +#endif + +#if defined __AVR_ATmega32U4__ + digitalWrite(RXLED, LOW); // set the RX LED ON + TXLED0; //TX LED is not tied to a normally controlled pin so a macro is needed, turn LED OFF +#endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON +#endif + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (wifi) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, HIGH); // set the built-in LED ON +#endif + +delay(length); + +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + digitalWrite(PC13, HIGH); // turn the LED off by making the voltage LOW +#endif + +#if defined __AVR_ATmega32U4__ + digitalWrite(RXLED, HIGH); // set the RX LED OFF + TXLED0; //TX LED macro to turn LED ON +#endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED OFF +#endif + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (wifi) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, LOW); // set the built-in LED ON +#endif +} + +void led_set(int ledPin, bool state) +{ +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + if (ledPin == greenLED) + digitalWrite(PB9, state); + else if (ledPin == blueLED) + digitalWrite(PB8, state); +#endif + +#if defined __AVR_ATmega32U4__ + digitalWrite(ledPin, state); +#endif + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + if (ledPin == greenLED) + digitalWrite(19, state); + else if (ledPin == blueLED) + digitalWrite(18, state); +#endif +} + +int read_analog() +{ + int sensorValue; + #if defined __AVR_ATmega32U4__ + sensorValue = analogRead(A3); +#endif + +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + sensorValue = analogRead(PA7); +#endif +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + sensorValue = analogRead(28); +#endif + return(sensorValue); +} + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) +bool check_for_wifi() { + + pinMode(29, INPUT); + const float conversion_factor = 3.3f / (1 << 12); + uint16_t result = analogRead(29); +// Serial.printf("ADC3 value: 0x%03x, voltage: %f V\n", result, result * conversion_factor); + + if (result < 0x10) { + Serial.println("\nPico W detected!\n"); + return(true); + } + else { + Serial.println("\nPico detected!\n"); + return(false); + } +} +#endif + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) +void get_gps() { +// Serial.println("Getting GPS data"); + bool newData = false; + unsigned long start = millis(); + +// for (unsigned long start = millis(); millis() - start < 1000;) // 5000;) + while ((millis() - start) < 1000) // 5000;) + { + while (Serial2.available()) + { + char c = Serial2.read(); + if (show_gps) + Serial.write(c); // uncomment this line if you want to see the GPS data flowing + if (gps.encode(c)) // Did a new valid sentence come in? + newData = true; + } + } + if (newData) { + Serial.print("GPS read new data in ms: "); + Serial.println(millis() - start); + +// float flon = 0.0, flat = 0.0, flalt = 0.0; +// unsigned long age; +// starting = millis(); +// gps.f_get_position(&flat, &flon, &age); + + Serial.print(F("Location: ")); + if (gps.location.isValid()) + { + Serial.print(gps.location.lat(), 6); + Serial.print(F(",")); + Serial.print(gps.location.lng(), 6); + + flat = gps.location.lat(); + flon = gps.location.lng(); + flalt = gps.altitude.meters(); + } + else + { + Serial.print(F("INVALID")); + } + Serial.print("\r\n"); + + } else +// Serial.printf("GPS read no new data: %d\n", millis() - start); + ; +} +#endif diff --git a/stempayload/Payload_BME280_MPU6050_AIO/adafruitio_00_publish_modified.cpp b/stempayload/Payload_BME280_MPU6050_AIO/adafruitio_00_publish_modified.cpp new file mode 100644 index 000000000..27deb5faa --- /dev/null +++ b/stempayload/Payload_BME280_MPU6050_AIO/adafruitio_00_publish_modified.cpp @@ -0,0 +1,142 @@ +// Mods to this file by Alan B Johnston KU2Y +// +// changed setup to aio_setup and loop to aio_loop +// +// You must put your account and WiFi info and rename config file as config.h +// +// Adafruit IO Publish Example +// +// Adafruit invests time and resources providing this open source code. +// Please support Adafruit and open source hardware by purchasing +// products from Adafruit! +// +// Written by Todd Treece for Adafruit Industries +// Copyright (c) 2016 Adafruit Industries +// Licensed under the MIT license. +// +// All text above must be included in any redistribution. + +/************************** Configuration ***********************************/ + +// edit the config.h tab and enter your Adafruit IO credentials +// and any additional configuration needed for WiFi, cellular, +// or ethernet clients. +#include "config.h" + +/************************ Example Starts Here *******************************/ + +// this int will hold the current count for our sketch +// int count = 0; +bool aio_connected = false; +unsigned long time_stamp; + +// should match the number of feeds define below so throttling delay is set correctly +#define FEEDS 7 + +// set up the 'counter' feed +//AdafruitIO_Feed *counter = io.feed("counter"); +AdafruitIO_Feed *temperature = io.feed("temperature"); +AdafruitIO_Feed *pressure = io.feed("pressure"); +AdafruitIO_Feed *altitude = io.feed("altitude"); +AdafruitIO_Feed *humidity = io.feed("humidity"); +AdafruitIO_Feed *accel_x = io.feed("Acceleration - X Axis"); +AdafruitIO_Feed *accel_y = io.feed("Acceleration - Y Axis"); +AdafruitIO_Feed *accel_z = io.feed("Acceleration - Z Axis"); +// AdafruitIO_Feed *gyro_x = io.feed("Rotation X Axis"); +// AdafruitIO_Feed *gyro_y = io.feed("Rotation Y Axis"); +// AdafruitIO_Feed *gyro_z = io.feed("Rotation Z Axis"); + +void aio_setup() { +/* + // start the serial connection + Serial.begin(115200); + + // wait for serial monitor to open + while(! Serial); +*/ + Serial.print("\nConnecting to Adafruit IO"); + + // connect to io.adafruit.com + io.connect(); + +/* // wait for a connection + while(io.status() < AIO_CONNECTED) { + Serial.print("."); + delay(500); + } + + // we are connected + Serial.println(); + Serial.println(io.statusText()); +*/ + time_stamp = millis(); +} + +void aio_loop(float tlm[]) { + + if (!aio_connected) { + if (io.status() < AIO_CONNECTED) { + Serial.println("\nConnecting to Adafruit IO..."); + } else { + Serial.print("\nSuccessfully connected to Adafruit IO! Status: "); +// Serial.println(); + Serial.println(io.statusText()); + aio_connected = true; + } + } else { + // io.run(); is required for all sketches. + // it should always be present at the top of your loop + // function. it keeps the client connected to + // io.adafruit.com, and processes any incoming data. + io.run(); + + if ((millis() - time_stamp) < ((2000 * (FEEDS+1)) + 1000)) { // 8000) { // Only send if 8 seconds have passed + Serial.print("\nWaiting to send Adafruit IO\n"); + } + else { + time_stamp = millis(); + // save count to the 'counter' feed on Adafruit IO + Serial.print("\nSending to Adafruit IO -> "); + // Serial.println(count); + // counter->save(count); + Serial.print(tlm[0]); + temperature->save(tlm[0]); + Serial.print(" "); + Serial.print(tlm[1]); + pressure->save(tlm[1]); + Serial.print(" "); + Serial.print(tlm[2]); + altitude->save(tlm[2]); + Serial.print(" "); + Serial.print(tlm[3]); + humidity->save(tlm[3]); + Serial.print(" "); +// Serial.print(tlm[4]); +// gyro_x->save(tlm[4]); +// Serial.print(" "); +// Serial.print(tlm[5]); +// gyro_y->save(tlm[5]); +// Serial.print(" "); +// Serial.print(tlm[6]); +// gyro_z->save(tlm[6]); + Serial.print(tlm[7]); + accel_x->save(tlm[7]); + Serial.print(" "); + Serial.print(tlm[8]); + accel_y->save(tlm[8]); + Serial.print(" "); + Serial.print(tlm[9]); + accel_z->save(tlm[9]); + + Serial.println(" "); + + // increment the count by 1 +// count++; + + // Adafruit IO is rate limited for publishing, so a delay is required in + // between feed->save events. In this example, we will wait three seconds + // (1000 milliseconds == 1 second) during each loop. + // delay(10000); // 1000 + } + } +} diff --git a/stempayload/Payload_BME280_MPU6050_AIO/edit_this_config_and_rename.h b/stempayload/Payload_BME280_MPU6050_AIO/edit_this_config_and_rename.h new file mode 100644 index 000000000..b6c47fa31 --- /dev/null +++ b/stempayload/Payload_BME280_MPU6050_AIO/edit_this_config_and_rename.h @@ -0,0 +1,74 @@ +// Edit this config file with your IO Username, Key, WiFi SSID and Password, then save as config.h + +/************************ Adafruit IO Config *******************************/ + +// visit io.adafruit.com if you need to create an account, +// or if you need your Adafruit IO key. +#define IO_USERNAME "your_username" +#define IO_KEY "your_key" + +/******************************* WIFI **************************************/ + +// the AdafruitIO_WiFi client will work with the following boards: +// - HUZZAH ESP8266 Breakout -> https://www.adafruit.com/products/2471 +// - Feather HUZZAH ESP8266 -> https://www.adafruit.com/products/2821 +// - Feather HUZZAH ESP32 -> https://www.adafruit.com/product/3405 +// - Feather M0 WiFi -> https://www.adafruit.com/products/3010 +// - Feather WICED -> https://www.adafruit.com/products/3056 +// - Adafruit PyPortal -> https://www.adafruit.com/product/4116 +// - Adafruit Metro M4 Express AirLift Lite -> +// https://www.adafruit.com/product/4000 +// - Adafruit AirLift Breakout -> https://www.adafruit.com/product/4201 +// - Adafruit AirLift Shield -> https://www.adafruit.com/product/4285 +// - Adafruit AirLift FeatherWing -> https://www.adafruit.com/product/4264 + +#define WIFI_SSID "your_ssid" +#define WIFI_PASS "your_pass" + +// uncomment the following line if you are using airlift +// #define USE_AIRLIFT + +// uncomment the following line if you are using winc1500 +// #define USE_WINC1500 + +// uncomment the following line if you are using mrk1010 or nano 33 iot +//#define ARDUINO_SAMD_MKR1010 + +// comment out the following lines if you are using fona or ethernet +#include "AdafruitIO_WiFi.h" + +#if defined(USE_AIRLIFT) || defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || \ + defined(ADAFRUIT_PYPORTAL) +// Configure the pins used for the ESP32 connection +#if !defined(SPIWIFI_SS) // if the wifi definition isnt in the board variant +// Don't change the names of these #define's! they match the variant ones +#define SPIWIFI SPI +#define SPIWIFI_SS 10 // Chip select pin +#define NINA_ACK 9 // a.k.a BUSY or READY pin +#define NINA_RESETN 6 // Reset pin +#define NINA_GPIO0 -1 // Not connected +#endif +AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS, SPIWIFI_SS, + NINA_ACK, NINA_RESETN, NINA_GPIO0, &SPIWIFI); +#else +AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS); +#endif +/******************************* FONA **************************************/ + +// the AdafruitIO_FONA client will work with the following boards: +// - Feather 32u4 FONA -> https://www.adafruit.com/product/3027 + +// uncomment the following two lines for 32u4 FONA, +// and comment out the AdafruitIO_WiFi client in the WIFI section +// #include "AdafruitIO_FONA.h" +// AdafruitIO_FONA io(IO_USERNAME, IO_KEY); + +/**************************** ETHERNET ************************************/ + +// the AdafruitIO_Ethernet client will work with the following boards: +// - Ethernet FeatherWing -> https://www.adafruit.com/products/3201 + +// uncomment the following two lines for ethernet, +// and comment out the AdafruitIO_WiFi client in the WIFI section +// #include "AdafruitIO_Ethernet.h" +// AdafruitIO_Ethernet io(IO_USERNAME, IO_KEY); diff --git a/stempayload/Payload_BME280_MPU6050_AIO/payload_extension.cpp b/stempayload/Payload_BME280_MPU6050_AIO/payload_extension.cpp new file mode 100644 index 000000000..5b8dd2ec8 --- /dev/null +++ b/stempayload/Payload_BME280_MPU6050_AIO/payload_extension.cpp @@ -0,0 +1,25 @@ +// Use this template for adding additional sensors +// see Payload_BME280_MPU6050_XS_Extended for an example + +// put your library includes here +#include "Arduino.h" + +// put your globals here + +// put your setup code here +void payload_setup() { + +// Serial.println("Starting new sensor!"); + +} + +// put your loop code here +// Very Important: only use print, not println!! +void payload_loop() { + +/* + Serial1.print(" NEW 0.0"); // send sensor data over serial to Pi Zero + Serial.print(" NEW 0.0"); // send sensor data over serial monitor for testing +*/ + +} diff --git a/stempayload/Payload_BME280_MPU6050_XS/Payload_BME280_MPU6050_XS.ino b/stempayload/Payload_BME280_MPU6050_XS/Payload_BME280_MPU6050_XS.ino index f0111f9ea..748989b70 100644 --- a/stempayload/Payload_BME280_MPU6050_XS/Payload_BME280_MPU6050_XS.ino +++ b/stempayload/Payload_BME280_MPU6050_XS/Payload_BME280_MPU6050_XS.ino @@ -1,16 +1,36 @@ -// code for Pro Micro or STM32 on the CubeSat Simulator STEM Payload board -// answers "OK" on the serial port Serial1 when queried by the Pi +// code for Pico or Pro Micro or STM32 on the CubeSat Simulator STEM Payload board +// works wih CubeSatSim software v1.3.2 or later +// extra sensors can be added in payload_extension.cpp file #include #include #include #include +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) #include +#endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Arduino Mbed OS RP2040 Boards is used in Arduino IDE +#include +TinyGPSPlus gps; +UART Serial2(8, 9, 0, 0); + +#elif !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards in Arduino IDE +#include +TinyGPSPlus gps; +bool check_for_wifi(); +bool wifi = false; +int led_builtin_pin; + +#else // if Sparkfun Pro Micro or STM32 +#include +#endif + #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; MPU6050 mpu6050(Wire); - + long timer = 0; int bmePresent; int RXLED = 17; // The RX LED has a defined Arduino pin @@ -18,11 +38,20 @@ int greenLED = 9; int blueLED = 8; int Sensor1 = 0; float Sensor2 = 0; -void eeprom_word_write(int addr, int val); -short eeprom_word_read(int addr); +float temp; +int calibration = 0; + +void ee_prom_word_write(int addr, int val); +short ee_prom_word_read(int addr); int first_time = true; int first_read = true; +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) +float T2 = 24; // Temperature data point 1 +float R2 = 169; // Reading data point 1 +float T1 = 6; // Temperature data point 2 +float R1 = 181; // Reading data point 2 +#endif #if defined __AVR_ATmega32U4__ float T2 = 26.3; // Temperature data point 1 float R2 = 167; // Reading data point 1 @@ -39,15 +68,63 @@ float R1 = 695; // Reading data point 2 int sensorValue; float Temp; float rest; - + +char sensor_end_flag[] = "_END_FLAG_"; +char sensor_start_flag[] = "_START_FLAG_"; +bool show_gps = true; // set to false to not see all messages +float flon = 0.0, flat = 0.0, flalt = 0.0; +void get_gps(); + +extern void payload_setup(); // sensor extension setup function defined in payload_extension.cpp +extern void payload_loop(); // sensor extension read function defined in payload_extension.cpp + void setup() { + + Serial.begin(115200); // Serial Monitor for testing - Serial.begin(9600); // Serial Monitor for testing - - Serial1.begin(115200); // Pi UART faster speed -// Serial1.begin(9600); // Pi UART faster speed - +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + Serial1.setRX(1); + delay(100); + Serial1.setTX(0); + delay(100); +#endif + + Serial1.begin(115200); // for communication with Pi Zero + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards in Arduino IDE + EEPROM.begin(512); +#endif + + delay(2000); + +#if defined (ARDUINO_ARCH_MBED_RP2040) && (ARDUINO_ARCH_RP2040) + Serial.println("Pico with Mbed"); +#elif !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + Serial.println("Pico with RP2040"); +#elif defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + Serial.println("STM32"); +#elif defined __AVR_ATmega32U4__ + Serial.println("Pro Micro"); +#else + Serial.println("Unknown board"); +#endif + Serial.println("Starting!"); + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + Serial.println("Starting Serial2 for optional GPS on JP12"); +// Serial2.begin(9600); // serial from - some modules need 115200 + Serial2.begin(9600); // serial from GPS or other serial sensor. Some GPS need 115200 + + // set all Pico GPIO connected pins to input + for (int i = 10; i < 22; i++) { + pinMode(i, INPUT); + } + pinMode(26, INPUT); + pinMode(27, INPUT); + pinMode(28, INPUT); + pinMode(15, INPUT_PULLUP); // squelch +#endif blink_setup(); @@ -70,7 +147,7 @@ void setup() { } mpu6050.begin(); - + if (eeprom_word_read(0) == 0xA07) { Serial.println("Reading gyro offsets from EEPROM\n"); @@ -84,37 +161,89 @@ void setup() { Serial.println(zOffset, DEC); mpu6050.setGyroOffsets(xOffset, yOffset, zOffset); + + Serial.println("\nTemperature calibration data from EEPROM\n"); + + T1 = ((float)eeprom_word_read(4)) / 10.0; + R1 = ((float)eeprom_word_read(5)); + T2 = ((float)eeprom_word_read(6)) / 10.0; + R2 = ((float)eeprom_word_read(7)); + + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + Serial.println(" "); + } else { - Serial.println("Calculating gyro offsets and storing in EEPROM\n"); - + Serial.println("Calculating gyro offsets\n"); mpu6050.calcGyroOffsets(true); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + Serial.println("Storing gyro offsets in EEPROM\n"); eeprom_word_write(0, 0xA07); eeprom_word_write(1, (int)(mpu6050.getGyroXoffset() * 100.0) + 0.5); eeprom_word_write(2, (int)(mpu6050.getGyroYoffset() * 100.0) + 0.5); - eeprom_word_write(3, (int)(mpu6050.getGyroZoffset() * 100.0) + 0.5); + eeprom_word_write(3, (int)(mpu6050.getGyroZoffset() * 100.0) + 0.5); Serial.println(eeprom_word_read(0), HEX); Serial.println(((float)eeprom_word_read(1)) / 100.0, DEC); Serial.println(((float)eeprom_word_read(2)) / 100.0, DEC); Serial.println(((float)eeprom_word_read(3)) / 100.0, DEC); + + Serial.println("\nStoring temperature calibration data in EEPROM\n"); + + eeprom_word_write(4, (int)(T1 * 10.0) + 0.5); + eeprom_word_write(5, (int) R1); + eeprom_word_write(6, (int)(T2 * 10.0) + 0.5); + eeprom_word_write(7, (int) R2); + + T1 = ((float)eeprom_word_read(4)) / 10.0; + R1 = ((float)eeprom_word_read(5)); + T2 = ((float)eeprom_word_read(6)) / 10.0; + R2 = ((float)eeprom_word_read(7)); + + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + Serial.println(" "); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif +#endif } -/**/ + payload_setup(); // sensor extension setup function defined in payload_extension.cpp } void loop() { - + + blink(50); + if (Serial1.available() > 0) { - blink(50); - char result = Serial1.read(); -// Serial1.println(result); -// Serial1.println("OK"); - + Serial.print("Received serial data!!!\n"); + delay(10); + while (Serial1.available() > 0) { + char result = Serial1.read(); + Serial.print(result); + } + Serial.println(" "); + } + { // if (result == '?') { if (bmePresent) { + Serial1.print(sensor_start_flag); Serial1.print("OK BME280 "); Serial1.print(bme.readTemperature()); Serial1.print(" "); @@ -123,9 +252,22 @@ void loop() { Serial1.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); Serial1.print(" "); Serial1.print(bme.readHumidity()); + + Serial.print("OK BME280 "); + temp = bme.readTemperature(); + Serial.print(temp); + Serial.print(" "); + Serial.print(bme.readPressure() / 100.0F); + Serial.print(" "); + Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); + Serial.print(" "); + Serial.print(bme.readHumidity()); } else { + Serial1.print(sensor_start_flag); Serial1.print("OK BME280 0.0 0.0 0.0 0.0"); + + Serial.print("OK BME280 0.0 0.0 0.0 0.0"); } mpu6050.update(); @@ -136,22 +278,59 @@ void loop() { Serial1.print(" "); Serial1.print(mpu6050.getGyroZ()); - Serial1.print(" "); - Serial1.print(mpu6050.getAccX()); - Serial1.print(" "); - Serial1.print(mpu6050.getAccY()); - Serial1.print(" "); - Serial1.print(mpu6050.getAccZ()); + Serial1.print(" "); + Serial1.print(mpu6050.getAccX()); + Serial1.print(" "); + Serial1.print(mpu6050.getAccY()); + Serial1.print(" "); + Serial1.print(mpu6050.getAccZ()); + + Serial.print(" MPU6050 "); + Serial.print(mpu6050.getGyroX()); + Serial.print(" "); + Serial.print(mpu6050.getGyroY()); + Serial.print(" "); + Serial.print(mpu6050.getGyroZ()); - sensorValue = read_analog(); + Serial.print(" "); + Serial.print(mpu6050.getAccX()); + Serial.print(" "); + Serial.print(mpu6050.getAccY()); + Serial.print(" "); + Serial.print(mpu6050.getAccZ()); + + sensorValue = read_analog(); // Serial.println(sensorValue); Temp = T1 + (sensorValue - R1) *((T2 - T1)/(R2 - R1)); - Serial1.print(" XS "); - Serial1.print(Temp); +// Serial1.print(" GPS 0 0 0 TMP "); + + Serial1.print(" GPS "); + Serial1.print(flat,4); + Serial1.print(" "); + Serial1.print(flon,4); Serial1.print(" "); - Serial1.println(Sensor2); + Serial1.print(flalt,2); + + Serial1.print(" TMP "); + Serial1.print(Temp); + +// Serial1.print(" "); +// Serial1.println(Sensor2); + + Serial.print(" GPS "); + Serial.print(flat,4); + Serial.print(" "); + Serial.print(flon,4); + Serial.print(" "); + Serial.print(flalt,2); + +// Serial.print(" GPS 0 0 0 TMP "); + Serial.print(" TMP "); + Serial.print(Temp); +// Serial.print(" "); +// Serial.println(Sensor2); float rotation = sqrt(mpu6050.getGyroX()*mpu6050.getGyroX() + mpu6050.getGyroY()*mpu6050.getGyroY() + mpu6050.getGyroZ()*mpu6050.getGyroZ()); float acceleration = sqrt(mpu6050.getAccX()*mpu6050.getAccX() + mpu6050.getAccY()*mpu6050.getAccY() + mpu6050.getAccZ()*mpu6050.getAccZ()); @@ -174,7 +353,13 @@ void loop() { else led_set(blueLED, LOW); } - + + payload_loop(); // sensor extension read function defined in payload_extension.cpp + +// Serial1.println(" "); + Serial1.println(sensor_end_flag); + Serial.println(" "); + } if (Serial.available() > 0) { @@ -183,98 +368,104 @@ void loop() { // Serial.println(result); // Serial.println("OK"); // Serial.println(counter++); - - if (result == 'R') { - Serial1.println("OK"); - delay(100); +//#if !defined (ARDUINO_ARCH_RP2040) + if (result == 'R' || result == 'r') { +// Serial1.println("OK"); +// delay(100); + Serial.println("Resetting\n"); first_read = true; setup(); } - else if (result == 'C') { - Serial.println("Clearing stored gyro offsets in EEPROM\n"); + else if (result == 'D' || result == 'd') { + Serial.println("\nCurrent temperature calibration data\n"); + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + + Serial.println("\nCurrent raw temperature reading\n"); + Serial.println(sensorValue, DEC); + Serial.println(" "); + } + else if (result == 'C' || result == 'c') { + Serial.println("\nClearing stored gyro offsets in EEPROM\n"); eeprom_word_write(0, 0x00); +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif first_time = true; setup(); - } - - if ((result == '?') || first_time == true) - { - first_time = false; - if (bmePresent) { - Serial.print("OK BME280 "); - Serial.print(bme.readTemperature()); - Serial.print(" "); - Serial.print(bme.readPressure() / 100.0F); - Serial.print(" "); - Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); - Serial.print(" "); - Serial.print(bme.readHumidity()); - } else - { - Serial.print("OK BME280 0.0 0.0 0.0 0.0"); - } - mpu6050.update(); - - Serial.print(" MPU6050 "); - Serial.print(mpu6050.getGyroX()); - Serial.print(" "); - Serial.print(mpu6050.getGyroY()); - Serial.print(" "); - Serial.print(mpu6050.getGyroZ()); - - Serial.print(" "); - Serial.print(mpu6050.getAccX()); - Serial.print(" "); - Serial.print(mpu6050.getAccY()); - Serial.print(" "); - Serial.print(mpu6050.getAccZ()); - - sensorValue = read_analog(); - - Temp = T1 + (sensorValue - R1) *((T2 - T1)/(R2 - R1)); - - Serial.print(" XS "); - Serial.print(Temp); - Serial.print(" "); - Serial.print(Sensor2); - Serial.print(" ("); - Serial.print(sensorValue); - Serial.println(")"); - - float rotation = sqrt(mpu6050.getGyroX()*mpu6050.getGyroX() + mpu6050.getGyroY()*mpu6050.getGyroY() + mpu6050.getGyroZ()*mpu6050.getGyroZ()); - float acceleration = sqrt(mpu6050.getAccX()*mpu6050.getAccX() + mpu6050.getAccY()*mpu6050.getAccY() + mpu6050.getAccZ()*mpu6050.getAccZ()); -// Serial.print(rotation); -// Serial.print(" "); -// Serial.println(acceleration); - - if (first_read == true) { - first_read = false; - rest = acceleration; } - - if (acceleration > 1.2 * rest) - led_set(greenLED, HIGH); - else - led_set(greenLED, LOW); - - if (rotation > 5) - led_set(blueLED, HIGH); - else - led_set(blueLED, LOW); + else if (result == 'S' || result == 's') { + Serial.print("\nStoring temperature calibration data point "); // in EEPROM\n"); + Serial.print(calibration + 1); + Serial.print(" in EEPROM\n"); + + Serial.println(temp); + Serial.println(sensorValue); + Serial.println(" "); + + eeprom_word_write(calibration * 2 + 4 , (int)(temp * 10.0) + 0.5); + eeprom_word_write(calibration * 2 + 5, sensorValue); + + if (calibration == 0) { + T1 = temp; + R1 = sensorValue; + calibration = 1; + } else { + T2 = temp; + R2 = sensorValue; + calibration = 0; + } + +// calibration = (calibration + 1) % 2; +// Serial.println(calibration + 1); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); } +#endif + + } +//#endif } - delay(100); + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + Serial.print("Squelch: "); + Serial.println(digitalRead(15)); + + get_gps(); +#else + delay(1000); // not needed due to gps 1 second polling delay + +#endif } void eeprom_word_write(int addr, int val) { +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE EEPROM.write(addr * 2, lowByte(val)); EEPROM.write(addr * 2 + 1, highByte(val)); +#endif } short eeprom_word_read(int addr) { - return ((EEPROM.read(addr * 2 + 1) << 8) | EEPROM.read(addr * 2)); + int result = 0; +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + result = ((EEPROM.read(addr * 2 + 1) << 8) | EEPROM.read(addr * 2)); +#endif + return result; } void blink_setup() @@ -292,6 +483,27 @@ void blink_setup() pinMode(greenLED, OUTPUT); pinMode(blueLED,OUTPUT); #endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + pinMode(LED_BUILTIN, OUTPUT); + pinMode(18, OUTPUT); // blue LED on STEM Payload Board v1.3.2 + pinMode(19, OUTPUT); // green LED on STEM Payload Board v1.3.2 +#endif + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (check_for_wifi()) { + wifi = true; + led_builtin_pin = LED_BUILTIN; // use default GPIO for Pico W + pinMode(LED_BUILTIN, OUTPUT); +// configure_wifi(); + } else { + led_builtin_pin = 25; // manually set GPIO 25 for Pico board +// pinMode(25, OUTPUT); + pinMode(led_builtin_pin, OUTPUT); + } + pinMode(18, OUTPUT); + pinMode(19, OUTPUT); +#endif } void blink(int length) @@ -304,8 +516,19 @@ void blink(int length) digitalWrite(RXLED, LOW); // set the RX LED ON TXLED0; //TX LED is not tied to a normally controlled pin so a macro is needed, turn LED OFF #endif - - delay(length); // wait for a lenth of time + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON +#endif + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (wifi) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, HIGH); // set the built-in LED ON +#endif + +delay(length); #if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) digitalWrite(PC13, HIGH); // turn the LED off by making the voltage LOW @@ -315,6 +538,17 @@ void blink(int length) digitalWrite(RXLED, HIGH); // set the RX LED OFF TXLED0; //TX LED macro to turn LED ON #endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED OFF +#endif + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (wifi) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, LOW); // set the built-in LED ON +#endif } void led_set(int ledPin, bool state) @@ -329,6 +563,13 @@ void led_set(int ledPin, bool state) #if defined __AVR_ATmega32U4__ digitalWrite(ledPin, state); #endif + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + if (ledPin == greenLED) + digitalWrite(19, state); + else if (ledPin == blueLED) + digitalWrite(18, state); +#endif } int read_analog() @@ -337,8 +578,81 @@ int read_analog() #if defined __AVR_ATmega32U4__ sensorValue = analogRead(A3); #endif + #if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) sensorValue = analogRead(PA7); +#endif +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + sensorValue = analogRead(28); #endif return(sensorValue); } + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) +bool check_for_wifi() { + + pinMode(29, INPUT); + const float conversion_factor = 3.3f / (1 << 12); + uint16_t result = analogRead(29); +// Serial.printf("ADC3 value: 0x%03x, voltage: %f V\n", result, result * conversion_factor); + + if (result < 0x10) { + Serial.println("\nPico W detected!\n"); + return(true); + } + else { + Serial.println("\nPico detected!\n"); + return(false); + } +} +#endif + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) +void get_gps() { +// Serial.println("Getting GPS data"); + bool newData = false; + unsigned long start = millis(); + +// for (unsigned long start = millis(); millis() - start < 1000;) // 5000;) + while ((millis() - start) < 1000) // 5000;) + { + while (Serial2.available()) + { + char c = Serial2.read(); + if (show_gps) + Serial.write(c); // uncomment this line if you want to see the GPS data flowing + if (gps.encode(c)) // Did a new valid sentence come in? + newData = true; + } + } + if (newData) { + Serial.print("GPS read new data in ms: "); + Serial.println(millis() - start); + +// float flon = 0.0, flat = 0.0, flalt = 0.0; +// unsigned long age; +// starting = millis(); +// gps.f_get_position(&flat, &flon, &age); + + Serial.print(F("Location: ")); + if (gps.location.isValid()) + { + Serial.print(gps.location.lat(), 6); + Serial.print(F(",")); + Serial.print(gps.location.lng(), 6); + + flat = gps.location.lat(); + flon = gps.location.lng(); + flalt = gps.altitude.meters(); + } + else + { + Serial.print(F("INVALID")); + } + Serial.print("\r\n"); + + } else +// Serial.printf("GPS read no new data: %d\n", millis() - start); + ; +} +#endif diff --git a/stempayload/Payload_BME280_MPU6050_XS/payload_extension.cpp b/stempayload/Payload_BME280_MPU6050_XS/payload_extension.cpp new file mode 100644 index 000000000..5b8dd2ec8 --- /dev/null +++ b/stempayload/Payload_BME280_MPU6050_XS/payload_extension.cpp @@ -0,0 +1,25 @@ +// Use this template for adding additional sensors +// see Payload_BME280_MPU6050_XS_Extended for an example + +// put your library includes here +#include "Arduino.h" + +// put your globals here + +// put your setup code here +void payload_setup() { + +// Serial.println("Starting new sensor!"); + +} + +// put your loop code here +// Very Important: only use print, not println!! +void payload_loop() { + +/* + Serial1.print(" NEW 0.0"); // send sensor data over serial to Pi Zero + Serial.print(" NEW 0.0"); // send sensor data over serial monitor for testing +*/ + +} diff --git a/stempayload/Payload_BME280_MPU6050_XS_Extended/Payload_BME280_MPU6050_XS_Extended.ino b/stempayload/Payload_BME280_MPU6050_XS_Extended/Payload_BME280_MPU6050_XS_Extended.ino index f7b391b44..748989b70 100644 --- a/stempayload/Payload_BME280_MPU6050_XS_Extended/Payload_BME280_MPU6050_XS_Extended.ino +++ b/stempayload/Payload_BME280_MPU6050_XS_Extended/Payload_BME280_MPU6050_XS_Extended.ino @@ -1,49 +1,133 @@ +// code for Pico or Pro Micro or STM32 on the CubeSat Simulator STEM Payload board +// works wih CubeSatSim software v1.3.2 or later +// extra sensors can be added in payload_extension.cpp file + #include #include #include #include +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) #include -#include "Adafruit_SI1145.h" -#include +#endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Arduino Mbed OS RP2040 Boards is used in Arduino IDE +#include +TinyGPSPlus gps; +UART Serial2(8, 9, 0, 0); + +#elif !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards in Arduino IDE +#include +TinyGPSPlus gps; +bool check_for_wifi(); +bool wifi = false; +int led_builtin_pin; + +#else // if Sparkfun Pro Micro or STM32 +#include +#endif #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; MPU6050 mpu6050(Wire); -Adafruit_SI1145 uv = Adafruit_SI1145(); -Adafruit_LIS3MDL lis3mdl; long timer = 0; int bmePresent; -int uvPresent; -int magPresent; int RXLED = 17; // The RX LED has a defined Arduino pin int greenLED = 9; int blueLED = 8; -void eeprom_word_write(int addr, int val); -short eeprom_word_read(int addr); +int Sensor1 = 0; +float Sensor2 = 0; +float temp; +int calibration = 0; + +void ee_prom_word_write(int addr, int val); +short ee_prom_word_read(int addr); int first_time = true; int first_read = true; + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) +float T2 = 24; // Temperature data point 1 +float R2 = 169; // Reading data point 1 +float T1 = 6; // Temperature data point 2 +float R1 = 181; // Reading data point 2 +#endif +#if defined __AVR_ATmega32U4__ float T2 = 26.3; // Temperature data point 1 float R2 = 167; // Reading data point 1 float T1 = 2; // Temperature data point 2 float R1 = 179; // Reading data point 2 +#endif +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) +float T2 = 25; // Temperature data point 1 +float R2 = 671; // Reading data point 1 +float T1 = 15.5; // Temperature data point 2 +float R1 = 695; // Reading data point 2 +#endif + int sensorValue; float Temp; float rest; -float magRaw = 0; -float magRawAbs = 0; - -void setup() { - Serial.begin(9600); // Serial Monitor for testing +char sensor_end_flag[] = "_END_FLAG_"; +char sensor_start_flag[] = "_START_FLAG_"; +bool show_gps = true; // set to false to not see all messages +float flon = 0.0, flat = 0.0, flalt = 0.0; +void get_gps(); - Serial1.begin(115200); // Pi UART faster speed +extern void payload_setup(); // sensor extension setup function defined in payload_extension.cpp +extern void payload_loop(); // sensor extension read function defined in payload_extension.cpp +void setup() { + + Serial.begin(115200); // Serial Monitor for testing + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + Serial1.setRX(1); + delay(100); + Serial1.setTX(0); + delay(100); +#endif + + Serial1.begin(115200); // for communication with Pi Zero + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards in Arduino IDE + EEPROM.begin(512); +#endif + + delay(2000); + +#if defined (ARDUINO_ARCH_MBED_RP2040) && (ARDUINO_ARCH_RP2040) + Serial.println("Pico with Mbed"); +#elif !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + Serial.println("Pico with RP2040"); +#elif defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + Serial.println("STM32"); +#elif defined __AVR_ATmega32U4__ + Serial.println("Pro Micro"); +#else + Serial.println("Unknown board"); +#endif + Serial.println("Starting!"); - blink_setup(); +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + Serial.println("Starting Serial2 for optional GPS on JP12"); +// Serial2.begin(9600); // serial from - some modules need 115200 + Serial2.begin(9600); // serial from GPS or other serial sensor. Some GPS need 115200 + // set all Pico GPIO connected pins to input + for (int i = 10; i < 22; i++) { + pinMode(i, INPUT); + } + pinMode(26, INPUT); + pinMode(27, INPUT); + pinMode(28, INPUT); + pinMode(15, INPUT_PULLUP); // squelch +#endif + + blink_setup(); + blink(500); delay(250); blink(500); @@ -58,84 +142,120 @@ void setup() { if (bme.begin(0x76)) { bmePresent = 1; } else { - Serial.println("BME280 sensor fault"); + Serial.println("Could not find a valid BME280 sensor, check wiring!"); bmePresent = 0; } - - if (! uv.begin()) { - Serial.println("Si1145 sensor fault"); - uvPresent = 0; - } else { - uvPresent = 1; - } - - if (! lis3mdl.begin_I2C()) { - Serial.println("LIS3MDL sensor fault"); - magPresent = 0; - } else { - magPresent = 1; - } - + mpu6050.begin(); - + if (eeprom_word_read(0) == 0xA07) { Serial.println("Reading gyro offsets from EEPROM\n"); - + float xOffset = ((float)eeprom_word_read(1)) / 100.0; float yOffset = ((float)eeprom_word_read(2)) / 100.0; float zOffset = ((float)eeprom_word_read(3)) / 100.0; - + Serial.println(xOffset, DEC); Serial.println(yOffset, DEC); Serial.println(zOffset, DEC); - + mpu6050.setGyroOffsets(xOffset, yOffset, zOffset); + + Serial.println("\nTemperature calibration data from EEPROM\n"); + + T1 = ((float)eeprom_word_read(4)) / 10.0; + R1 = ((float)eeprom_word_read(5)); + T2 = ((float)eeprom_word_read(6)) / 10.0; + R2 = ((float)eeprom_word_read(7)); + + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + Serial.println(" "); + } else { - Serial.println("Calculating gyro offsets and storing in EEPROM\n"); - + Serial.println("Calculating gyro offsets\n"); mpu6050.calcGyroOffsets(true); - + +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + Serial.println("Storing gyro offsets in EEPROM\n"); + eeprom_word_write(0, 0xA07); eeprom_word_write(1, (int)(mpu6050.getGyroXoffset() * 100.0) + 0.5); eeprom_word_write(2, (int)(mpu6050.getGyroYoffset() * 100.0) + 0.5); - eeprom_word_write(3, (int)(mpu6050.getGyroZoffset() * 100.0) + 0.5); - + eeprom_word_write(3, (int)(mpu6050.getGyroZoffset() * 100.0) + 0.5); + Serial.println(eeprom_word_read(0), HEX); Serial.println(((float)eeprom_word_read(1)) / 100.0, DEC); Serial.println(((float)eeprom_word_read(2)) / 100.0, DEC); Serial.println(((float)eeprom_word_read(3)) / 100.0, DEC); + + Serial.println("\nStoring temperature calibration data in EEPROM\n"); + + eeprom_word_write(4, (int)(T1 * 10.0) + 0.5); + eeprom_word_write(5, (int) R1); + eeprom_word_write(6, (int)(T2 * 10.0) + 0.5); + eeprom_word_write(7, (int) R2); + + T1 = ((float)eeprom_word_read(4)) / 10.0; + R1 = ((float)eeprom_word_read(5)); + T2 = ((float)eeprom_word_read(6)) / 10.0; + R2 = ((float)eeprom_word_read(7)); + + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + Serial.println(" "); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif +#endif } - pinMode(greenLED, OUTPUT); - pinMode(blueLED, OUTPUT); + payload_setup(); // sensor extension setup function defined in payload_extension.cpp } - + void loop() { - if ((Serial.available() > 0) || first_time == true) { - blink(50); - char result = Serial.read(); - - if (result == 'R') { - Serial.println("OK"); - delay(100); - first_time = true; - setup(); - } - else if (result == 'C') { - Serial.println("Clearing stored gyro offsets in EEPROM\n"); - eeprom_word_write(0, 0x00); - first_time = true; - setup(); + blink(50); + + if (Serial1.available() > 0) { + Serial.print("Received serial data!!!\n"); + delay(10); + while (Serial1.available() > 0) { + char result = Serial1.read(); + Serial.print(result); } - if ((result == '?') || first_time == true) + Serial.println(" "); + } + { +// if (result == '?') { - first_time = false; if (bmePresent) { + Serial1.print(sensor_start_flag); + Serial1.print("OK BME280 "); + Serial1.print(bme.readTemperature()); + Serial1.print(" "); + Serial1.print(bme.readPressure() / 100.0F); + Serial1.print(" "); + Serial1.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); + Serial1.print(" "); + Serial1.print(bme.readHumidity()); + Serial.print("OK BME280 "); - Serial.print(bme.readTemperature()); + temp = bme.readTemperature(); + Serial.print(temp); Serial.print(" "); Serial.print(bme.readPressure() / 100.0F); Serial.print(" "); @@ -144,9 +264,26 @@ void loop() { Serial.print(bme.readHumidity()); } else { + Serial1.print(sensor_start_flag); + Serial1.print("OK BME280 0.0 0.0 0.0 0.0"); + Serial.print("OK BME280 0.0 0.0 0.0 0.0"); } mpu6050.update(); + + Serial1.print(" MPU6050 "); + Serial1.print(mpu6050.getGyroX()); + Serial1.print(" "); + Serial1.print(mpu6050.getGyroY()); + Serial1.print(" "); + Serial1.print(mpu6050.getGyroZ()); + + Serial1.print(" "); + Serial1.print(mpu6050.getAccX()); + Serial1.print(" "); + Serial1.print(mpu6050.getAccY()); + Serial1.print(" "); + Serial1.print(mpu6050.getAccZ()); Serial.print(" MPU6050 "); Serial.print(mpu6050.getGyroX()); @@ -154,206 +291,368 @@ void loop() { Serial.print(mpu6050.getGyroY()); Serial.print(" "); Serial.print(mpu6050.getGyroZ()); - + Serial.print(" "); - Serial.print(mpu6050.getAccX()); + Serial.print(mpu6050.getAccX()); Serial.print(" "); - Serial.print(mpu6050.getAccY()); + Serial.print(mpu6050.getAccY()); Serial.print(" "); - Serial.print(mpu6050.getAccZ()); - - sensorValue = analogRead(A3); - Temp = T1 + (sensorValue - R1) * ((T2 - T1) / (R2 - R1)); - - Serial.print(" XS "); - Serial.print(Temp); - Serial.print(" "); - if (uvPresent) { - Serial.print(uv.readVisible()); - Serial.print(" "); - Serial.print(uv.readIR()); - Serial.print(" "); - } else - { - Serial.print("0.0 0.0 "); - } - if (magPresent) { - lis3mdl.read(); - magRaw = (((lis3mdl.x + lis3mdl.y + lis3mdl.z) / 3)); - magAbs = abs(magRaw); - Serial.println(magAbs); - } else - { - Serial.println("0.0"); - } - - float rotation = sqrt(mpu6050.getGyroX() * mpu6050.getGyroX() + mpu6050.getGyroY() * mpu6050.getGyroY() + mpu6050.getGyroZ() * mpu6050.getGyroZ()); - float acceleration = sqrt(mpu6050.getAccX() * mpu6050.getAccX() + mpu6050.getAccY() * mpu6050.getAccY() + mpu6050.getAccZ() * mpu6050.getAccZ()); - - if (acceleration > 1.2) + Serial.print(mpu6050.getAccZ()); + + sensorValue = read_analog(); + +// Serial.println(sensorValue); + Temp = T1 + (sensorValue - R1) *((T2 - T1)/(R2 - R1)); + +// Serial1.print(" GPS 0 0 0 TMP "); + + Serial1.print(" GPS "); + Serial1.print(flat,4); + Serial1.print(" "); + Serial1.print(flon,4); + Serial1.print(" "); + Serial1.print(flalt,2); + + Serial1.print(" TMP "); + Serial1.print(Temp); + +// Serial1.print(" "); +// Serial1.println(Sensor2); + + Serial.print(" GPS "); + Serial.print(flat,4); + Serial.print(" "); + Serial.print(flon,4); + Serial.print(" "); + Serial.print(flalt,2); + +// Serial.print(" GPS 0 0 0 TMP "); + Serial.print(" TMP "); + Serial.print(Temp); +// Serial.print(" "); +// Serial.println(Sensor2); + + float rotation = sqrt(mpu6050.getGyroX()*mpu6050.getGyroX() + mpu6050.getGyroY()*mpu6050.getGyroY() + mpu6050.getGyroZ()*mpu6050.getGyroZ()); + float acceleration = sqrt(mpu6050.getAccX()*mpu6050.getAccX() + mpu6050.getAccY()*mpu6050.getAccY() + mpu6050.getAccZ()*mpu6050.getAccZ()); +// Serial.print(rotation); +// Serial.print(" "); +// Serial.println(acceleration); + + if (first_read == true) { + first_read = false; + rest = acceleration; + } + + if (acceleration > 1.2 * rest) led_set(greenLED, HIGH); - else + else led_set(greenLED, LOW); - - if (rotation > 5) + + if (rotation > 5) led_set(blueLED, HIGH); - else + else led_set(blueLED, LOW); } - } - if (Serial1.available() > 0) { + payload_loop(); // sensor extension read function defined in payload_extension.cpp - blink(50); - char result = Serial1.read(); +// Serial1.println(" "); + Serial1.println(sensor_end_flag); + Serial.println(" "); + + } - if (result == 'R') { - Serial1.println("OK"); - delay(100); + if (Serial.available() > 0) { + blink(50); + char result = Serial.read(); +// Serial.println(result); +// Serial.println("OK"); +// Serial.println(counter++); +//#if !defined (ARDUINO_ARCH_RP2040) + if (result == 'R' || result == 'r') { +// Serial1.println("OK"); +// delay(100); + Serial.println("Resetting\n"); first_read = true; setup(); } - - if (result == '?') - { - if (bmePresent) { - Serial1.print("OK BME280 "); - Serial1.print(bme.readTemperature()); - Serial1.print(" "); - Serial1.print(bme.readPressure() / 100.0F); - Serial1.print(" "); - Serial1.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); - Serial1.print(" "); - Serial1.print(bme.readHumidity()); - } else - { - Serial1.print("OK BME280 0.0 0.0 0.0 0.0"); - } - mpu6050.update(); - - Serial1.print(" MPU6050 "); - Serial1.print(mpu6050.getGyroX()); - Serial1.print(" "); - Serial1.print(mpu6050.getGyroY()); - Serial1.print(" "); - Serial1.print(mpu6050.getGyroZ()); - - Serial1.print(" "); - Serial1.print(mpu6050.getAccX()); - Serial1.print(" "); - Serial1.print(mpu6050.getAccY()); - Serial1.print(" "); - Serial1.print(mpu6050.getAccZ()); - - sensorValue = analogRead(A3); - Temp = T1 + (sensorValue - R1) * ((T2 - T1) / (R2 - R1)); - - Serial1.print(" XS "); - Serial1.print(Temp); - Serial1.print(" "); - if (uvPresent) { - Serial1.print(uv.readVisible()); - Serial1.print(" "); - Serial1.print(uv.readIR()); - Serial1.print(" "); - } else - { - Serial1.print("0.0 0.0 "); - } - if (magPresent) { - lis3mdl.read(); - magRaw = (((lis3mdl.x + lis3mdl.y + lis3mdl.z) / 3)); - magAbs = abs(magRaw); - Serial1.println(magAbs); - } else - { - Serial1.println("0.0"); - } - - - float rotation = sqrt(mpu6050.getGyroX() * mpu6050.getGyroX() + mpu6050.getGyroY() * mpu6050.getGyroY() + mpu6050.getGyroZ() * mpu6050.getGyroZ()); - float acceleration = sqrt(mpu6050.getAccX() * mpu6050.getAccX() + mpu6050.getAccY() * mpu6050.getAccY() + mpu6050.getAccZ() * mpu6050.getAccZ()); - - if (first_read == true) { - first_read = false; - rest = acceleration; - } - - if (acceleration > 1.2 * rest) - led_set(greenLED, HIGH); - else - led_set(greenLED, LOW); - - if (rotation > 5) - led_set(blueLED, HIGH); - else - led_set(blueLED, LOW); - } + else if (result == 'D' || result == 'd') { + Serial.println("\nCurrent temperature calibration data\n"); + Serial.println(T1, DEC); + Serial.println(R1, DEC); + Serial.println(" "); + Serial.println(T2, DEC); + Serial.println(R2, DEC); + + Serial.println("\nCurrent raw temperature reading\n"); + Serial.println(sensorValue, DEC); + Serial.println(" "); } + else if (result == 'C' || result == 'c') { + Serial.println("\nClearing stored gyro offsets in EEPROM\n"); + eeprom_word_write(0, 0x00); +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif + first_time = true; + setup(); + } + else if (result == 'S' || result == 's') { + Serial.print("\nStoring temperature calibration data point "); // in EEPROM\n"); + Serial.print(calibration + 1); + Serial.print(" in EEPROM\n"); + + Serial.println(temp); + Serial.println(sensorValue); + Serial.println(" "); + + eeprom_word_write(calibration * 2 + 4 , (int)(temp * 10.0) + 0.5); + eeprom_word_write(calibration * 2 + 5, sensorValue); + + if (calibration == 0) { + T1 = temp; + R1 = sensorValue; + calibration = 1; + } else { + T2 = temp; + R2 = sensorValue; + calibration = 0; + } + +// calibration = (calibration + 1) % 2; +// Serial.println(calibration + 1); + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + + if (EEPROM.commit()) { + Serial.println("EEPROM successfully committed\n"); + } else { + Serial.println("ERROR! EEPROM commit failed\n"); + } +#endif + + } +//#endif + } + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + Serial.print("Squelch: "); + Serial.println(digitalRead(15)); + + get_gps(); +#else + delay(1000); // not needed due to gps 1 second polling delay +#endif } - + void eeprom_word_write(int addr, int val) { +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE EEPROM.write(addr * 2, lowByte(val)); EEPROM.write(addr * 2 + 1, highByte(val)); +#endif } - + short eeprom_word_read(int addr) { - return ((EEPROM.read(addr * 2 + 1) << 8) | EEPROM.read(addr * 2)); + int result = 0; +#if !defined(ARDUINO_ARCH_MBED_RP2040) // && defined(ARDUINO_ARCH_RP2040) // if Raspberry Pi RP2040 Boards is used in Arduino IDE + result = ((EEPROM.read(addr * 2 + 1) << 8) | EEPROM.read(addr * 2)); +#endif + return result; } - -void blink_setup() + +void blink_setup() { -#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) // initialize digital pin PB1 as an output. pinMode(PC13, OUTPUT); pinMode(PB9, OUTPUT); pinMode(PB8, OUTPUT); #endif - + #if defined __AVR_ATmega32U4__ pinMode(RXLED, OUTPUT); // Set RX LED as an output // TX LED is set as an output behind the scenes pinMode(greenLED, OUTPUT); - pinMode(blueLED, OUTPUT); + pinMode(blueLED,OUTPUT); #endif -} +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + pinMode(LED_BUILTIN, OUTPUT); + pinMode(18, OUTPUT); // blue LED on STEM Payload Board v1.3.2 + pinMode(19, OUTPUT); // green LED on STEM Payload Board v1.3.2 +#endif + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (check_for_wifi()) { + wifi = true; + led_builtin_pin = LED_BUILTIN; // use default GPIO for Pico W + pinMode(LED_BUILTIN, OUTPUT); +// configure_wifi(); + } else { + led_builtin_pin = 25; // manually set GPIO 25 for Pico board +// pinMode(25, OUTPUT); + pinMode(led_builtin_pin, OUTPUT); + } + pinMode(18, OUTPUT); + pinMode(19, OUTPUT); +#endif +} + void blink(int length) { #if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) digitalWrite(PC13, LOW); // turn the LED on (HIGH is the voltage level) #endif - + #if defined __AVR_ATmega32U4__ digitalWrite(RXLED, LOW); // set the RX LED ON TXLED0; //TX LED is not tied to a normally controlled pin so a macro is needed, turn LED OFF -#endif +#endif - delay(length); // wait for a lenth of time +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON +#endif +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (wifi) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, HIGH); // set the built-in LED ON +#endif + +delay(length); + #if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) digitalWrite(PC13, HIGH); // turn the LED off by making the voltage LOW #endif - + #if defined __AVR_ATmega32U4__ digitalWrite(RXLED, HIGH); // set the RX LED OFF TXLED0; //TX LED macro to turn LED ON -#endif -} +#endif + +#if defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED OFF +#endif +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) + if (wifi) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, LOW); // set the built-in LED ON +#endif +} + void led_set(int ledPin, bool state) { #if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) if (ledPin == greenLED) digitalWrite(PB9, state); else if (ledPin == blueLED) - digitalWrite(PB8, state); + digitalWrite(PB8, state); #endif - + #if defined __AVR_ATmega32U4__ - digitalWrite(ledPin, state); + digitalWrite(ledPin, state); +#endif + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + if (ledPin == greenLED) + digitalWrite(19, state); + else if (ledPin == blueLED) + digitalWrite(18, state); +#endif +} + +int read_analog() +{ + int sensorValue; + #if defined __AVR_ATmega32U4__ + sensorValue = analogRead(A3); +#endif + +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + sensorValue = analogRead(PA7); +#endif +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) + sensorValue = analogRead(28); +#endif + return(sensorValue); +} + +#if !defined(ARDUINO_ARCH_MBED_RP2040) && defined(ARDUINO_ARCH_RP2040) +bool check_for_wifi() { + + pinMode(29, INPUT); + const float conversion_factor = 3.3f / (1 << 12); + uint16_t result = analogRead(29); +// Serial.printf("ADC3 value: 0x%03x, voltage: %f V\n", result, result * conversion_factor); + + if (result < 0x10) { + Serial.println("\nPico W detected!\n"); + return(true); + } + else { + Serial.println("\nPico detected!\n"); + return(false); + } +} #endif + +#if defined (ARDUINO_ARCH_MBED_RP2040) || (ARDUINO_ARCH_RP2040) +void get_gps() { +// Serial.println("Getting GPS data"); + bool newData = false; + unsigned long start = millis(); + +// for (unsigned long start = millis(); millis() - start < 1000;) // 5000;) + while ((millis() - start) < 1000) // 5000;) + { + while (Serial2.available()) + { + char c = Serial2.read(); + if (show_gps) + Serial.write(c); // uncomment this line if you want to see the GPS data flowing + if (gps.encode(c)) // Did a new valid sentence come in? + newData = true; + } + } + if (newData) { + Serial.print("GPS read new data in ms: "); + Serial.println(millis() - start); + +// float flon = 0.0, flat = 0.0, flalt = 0.0; +// unsigned long age; +// starting = millis(); +// gps.f_get_position(&flat, &flon, &age); + + Serial.print(F("Location: ")); + if (gps.location.isValid()) + { + Serial.print(gps.location.lat(), 6); + Serial.print(F(",")); + Serial.print(gps.location.lng(), 6); + + flat = gps.location.lat(); + flon = gps.location.lng(); + flalt = gps.altitude.meters(); + } + else + { + Serial.print(F("INVALID")); + } + Serial.print("\r\n"); + + } else +// Serial.printf("GPS read no new data: %d\n", millis() - start); + ; } +#endif diff --git a/stempayload/Payload_BME280_MPU6050_XS_Extended/payload_extension.cpp b/stempayload/Payload_BME280_MPU6050_XS_Extended/payload_extension.cpp new file mode 100644 index 000000000..b88dd680f --- /dev/null +++ b/stempayload/Payload_BME280_MPU6050_XS_Extended/payload_extension.cpp @@ -0,0 +1,71 @@ +// Use this template for adding additional sensors + +// put your library includes here +#include "Adafruit_SI1145.h" +#include + +// put your globals here +Adafruit_SI1145 uv = Adafruit_SI1145(); +Adafruit_LIS3MDL lis3mdl; + +int uvPresent; +int magPresent; + +float magRaw = 0; +float magRawAbs = 0; + +// put your setup code here +void payload_setup() { + + Serial.println("Starting Si1145 sensor!"); + + if (! uv.begin()) { + Serial.println("Si1145 sensor fault"); + uvPresent = 0; + } else { + uvPresent = 1; + } + + Serial.println("Starting LIS3MDL sensor!"); + + if (! lis3mdl.begin_I2C()) { + Serial.println("LIS3MDL sensor fault"); + magPresent = 0; + } else { + magPresent = 1; + } +} + +// put your loop code here +// Very Important: only use print, not println!! +void payload_loop() { + + if (uvPresent) { + Serial1.print(" SI "); // chose a 2-3 letter hint for your sensor + Serial1.print(uv.readVisible()); // Serial1 sends the sensor data to the Pi Zero for transmission + Serial1.print(" "); + Serial1.print(uv.readIR()); + + Serial.print(" SI "); + Serial.print(uv.readVisible()); // Serial sends the sensor data to the Serial Monitor for debugging + Serial.print(" "); + Serial.print(uv.readIR()); + } else { + Serial1.print(" SI 0.0 0.0"); + Serial.print(" SI 0.0 0.0"); + } + if (magPresent) { + lis3mdl.read(); + magRaw = (((lis3mdl.x + lis3mdl.y + lis3mdl.z) / 3)); + magRawAbs = abs(magRaw); + + Serial1.print(" LI "); + Serial1.print(magRawAbs); + + Serial1.print(" LI "); + Serial.print(magRawAbs); + } else { + Serial1.print(" LI 0.0"); + Serial.print(" LI 0.0"); + } +} diff --git a/stempayload/payload_pico/payload_pico.h b/stempayload/payload_pico/payload_pico.h new file mode 100644 index 000000000..2b3dba7cf --- /dev/null +++ b/stempayload/payload_pico/payload_pico.h @@ -0,0 +1,485 @@ +//#include +#include +#include +//#include +#include +//#include "afsk/status.h" +//#include "afsk/ax5043.h" +//#include "afsk/ax25.h" +//#include "ax5043/spi/ax5043spi.h" +//#include +//#include +//#include +#include +#include +//#include "TelemEncoding.h" +//#include +//#include +//#include +#include +//#include +//#include +#include "DumbTXSWS.h" +#include +//#include +#include +#include +#include +#include +//#include +#include +#include "pico/stdlib.h" // stdlib +#include "hardware/irq.h" // interrupts +#include "hardware/pwm.h" // pwm +#include "hardware/sync.h" // wait for interrupt +//#include "RPi_Pico_TimerInterrupt.h" +//#include +#include "hardware/gpio.h" +#include "hardware/adc.h" +#include + +// Pico GPIO pin assignments +#define PI_TX 0 // Serial to Pi transmit data +#define PI_RX 1 // Serial to Pi receive data +#define SDA 2 // I2C 1 Data +#define SCL 3 // I2C 1 Clock +#define SDA2 4 // I2C 2 Data +#define SCL2 5 // I2C 2 Clock +#define BPSK_CONTROL_A 6 // was 16 // control for Phase A to switch +#define BPSK_CONTROL_B 7 // was 15 // control for Phase A to switch + +#ifdef PICO_0V1 +#define BPF_PIN 8 // BPF is installed for v0.1 Pico +#define PI_3V3_PIN 9 // 3.3V supply used to detect Pi Zero for v0.1 Pico +#define TX2 12 // Serial2 to ESP32-CAM transmit data +#define RX2 13 // Serial2 to ESP32-CAM receive data +#else +#define TX2 8 // Serial2 to ESP32-CAM transmit data +#define RX2 9 // Serial2 to ESP32-CAM receive data +#define BPF_PIN 12 // BPF is installed +#define PI_3V3_PIN 13 // 3.3V supply used to detect Pi Zero +#endif + + +#define MAIN_PB_PIN 10 // Main board PB pushbutton pin +#define TXC_PIN 11 // Transceiver Board is present + +#define BPSK_PWM_A_PIN 14 // was 6 // PWM Output Phase A to switch +#define BPSK_PWM_B_PIN 15 // was 7 // PWM Output Phase B to switch +#define SWTX_PIN 16 // was 14 SR_FRS_05W Transmit Pico software serial port +#define PTT_PIN 17 // SR_FRS_05W PTT Push to Talk - transmit +#define STEM_LED_GREEN 18 // STEM board LED1 Green +#define STEM_LED_BLUE 19 // STEM board LED2 Blue +#define MAIN_LED_GREEN 20 // Main board LED1 +#define MAIN_LED_BLUE 21 // Main board LED1 +#define PD_PIN 22 // SR_FRS_05W PD pin - enable +#define AUDIO_OUT_PIN 26 // 26 // SR_FRS_05W audio out pin +#define AUDIO_IN_PIN 27 // SR_FRS_05W audio in pin +#define TEMPERATURE_PIN 28 // Diode temperature analog pin + +#define PORT 8080 +#define FREQUENCY_OFFSET 0 +#define TRUE 1 +#define FALSE 0 + +#define A_ 1 +#define B_ 2 +#define C_ 3 +#define D_ 4 +#define PLUS_X 0 +#define PLUS_Y 1 +#define BAT 2 +#define BUS 3 +#define MINUS_X 5 // 4 +#define MINUS_Y 6 // 5 +#define PLUS_Z 4 // 6 +#define MINUS_Z 7 +#define TEMP 2 +#define PRES 3 +#define ALT 4 +#define HUMI 5 +#define GYRO_X 7 +#define GYRO_Y 8 +#define GYRO_Z 9 +#define ACCEL_X 10 +#define ACCEL_Y 11 +#define ACCEL_Z 12 +#define XS1 14 +#define XS2 15 +#define XS3 16 + +#define RSSI_ 0 +#define IHU_TEMP 2 +#define SPIN 1 + +#define OFF - 1 +#define ON 1 + +#define PROMPT_CALLSIGN 1 +#define PROMPT_SIM 2 +#define PROMPT_LAT 3 +#define PROMPT_RESET 4 +#define PROMPT_QUERY 5 +#define PROMPT_HELP 6 +#define PROMPT_RESTART 7 +#define PROMPT_DEBUG 8 +#define PROMPT_VOLTAGE 9 +#define PROMPT_PAYLOAD 10 +#define PROMPT_TEMP 11 +#define PROMPT_FORMAT 12 +#define PROMPT_REBOOT 13 +#define PROMPT_I2CSCAN 14 +#define PROMPT_WIFI 15 +#define PROMPT_CAMERA 16 + +#define PAYLOAD_QUERY 1 +#define PAYLOAD_RESET 2 +#define PAYLOAD_CLEAR 3 + +volatile int prompt = false; +volatile int prompting = false; + +char serial_string[128]; + +float get_cpu_temp(); + +//#define WAV_DATA_LENGTH (50000 * 8) + +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; + +float xOffset; +float yOffset; +float zOffset; + +int twosToInt(int val, int len); +float toAprsFormat(float input); +float rnd_float(double min, double max); +void get_tlm(); +void get_tlm_fox(); +int encodeA(short int * b, int index, int val); +int encodeB(short int * b, int index, int val); +void config_x25(); +void trans_x25(); +int upper_digit(int number); +int lower_digit(int number); +void update_rs(unsigned char parity[32], unsigned char c); +void write_little_endian(unsigned int word, int num_bytes, FILE *wav_file); +static int init_rf(); +void test_radio(); +void config_radio(); +void send_aprs_packet(); +void read_ina219(); +void read_sensors(); +void get_tlm_ao7(); +void print_string(char *string); +void start_payload(); +void led_set(int ledPin, bool state); +void blink(int length); +void blink_setup(); +short eeprom_word_read(int addr); +void eeprom_word_write(int addr, int val); +void read_payload(); +void start_ina219(); +void pwm_interrupt_handler(); +void start_pwm(); +void transmit_on(); +void transmit_off(); +void config_telem(); +void config_simulated_telem(); +void generate_simulated_telem(); +void process_pushbutton(); +void blinkTimes(int blinks); +void blink_pin(int pin, int duration); +void config_gpio(); +void start_isr(); +void read_reset_count(); +void start_button_isr(); +void payload_OK_only(); +void client_print_string(char *string); +bool check_for_wifi(); +void check_for_browser(); +void configure_wifi(); +void transmit_cw(int freq, float duration); +void transmit_char(char character); +void transmit_string(char *string); +void transmit_callsign(char *callsign); +void parse_payload(); +void load_files(); +void show_dir(); +void serial_input(); +void get_serial_string(); +void get_serial_char(); +void get_serial_clear_buffer(); +void set_lat_lon(); +void program_radio(); +bool read_config_file(); +void write_config_file(); +void read_mode(); +void write_mode(); +void start_clockgen(); +bool TimerHandler1(struct repeating_timer *t); +void load_sstv_image_1_as_cam_dot_jpg(); +void load_sstv_image_2_as_cam_dot_jpg(); +void get_input(); +void transmit_led(bool status); +void reset_min_max(); + +#ifndef STASSID +#define STASSID "Pico" +#define STAPSK "picoPassword" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; +int port = 7373; +volatile bool wifi = false; + +extern int Encode_8b10b[][256]; + +//int socket_open = 0; +//int sock = 0; +int loop_count = 0; +int firstTime = ON; // 0; +long start; +int testCount = 0; +long time_start; +//char cmdbuffer[1000]; +//FILE * file1;// +#define BUFFER_SIZE 5841 //970 // (970 * 2) // * 2) +//short int buffer[BUFFER_SIZE]; // 50000]; //BUFFER_SIZE]; // ctr is an int // 100000]; // 50000]; // 25000]; // 10240]; // was 2336400]; // max size for 10 frames count of BPSK +byte buffer[BUFFER_SIZE]; // 50000]; //BUFFER_SIZE]; // ctr is an int // 100000]; // 50000]; // 25000]; // 10240]; // was 2336400]; // max size for 10 frames count of BPSK +//short int buffer[(WAV_DATA_LENGTH/8)]; +//FILE *sopen(const char *program); +char tlm_str[1000]; +char payload_str[100]; + +#define S_RATE (200) // (8000) //(48000) // (44100) + +#define AFSK 1 +#define FSK 2 +#define BPSK 3 +#define SSTV 4 +#define CW 5 + +int rpitxStatus = -1; + +float amplitude; // = ; // 20000; // 32767/(10%amp+5%amp+100%amp) +float freq_Hz = 3000; // 1200 +short int sin_samples; +short int sin_map[16]; +int STEMBoardFailure = 1; + +int smaller; +int flip_ctr = 0; +int phase = 1; +int ctr = 0; +int rd = 0; +int nrd; +void write_to_buffer(int i, int symbol, int val); +void write_wave(int i, byte * buffer); +void sleep(float time); +int uart_fd; + +int reset_count = 0; +float uptime_sec = 1000; +long int uptime = 1000; +//char call[5]; +char sim_yes[10]; + +int mode = BPSK; // SSTV; +volatile int new_mode; +int bitRate, bufLen, rsFrames, payloads, rsFrameLen, dataLen, headerLen, syncBits, syncWord, parityLen, samples, frameCnt, samplePeriod; +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; +float voltageThreshold = 3.5, batteryVoltage = 4.5, batteryCurrent = 0, currentThreshold = 100; +float latitude = 39.027702f, longitude = -77.078064f; +float lat_file, long_file; +double cpuTemp; +int frameTime; + +bool debug_camera = false; + +float axis[3], angle[3], volts_max[3], amps_max[3], batt, rotation_speed, period, tempS, temp_max, temp_min, eclipse; +int i2c_bus0 = OFF, i2c_bus1 = OFF, i2c_bus3 = OFF, camera = OFF, sim_mode = FALSE, SafeMode = FALSE, rxAntennaDeployed = 0, txAntennaDeployed = 0; +double eclipse_time; +bool i2c_1, i2c2, i2c3,i2c4, i2c5, i2c6, i2c7, i2c8; + +float voltage[9], current[9], sensor[17], other[3]; +char sensor_payload[500]; + +int test_i2c_bus(int bus); + +//const char pythonCmd[] = "python3 -u /home/pi/CubeSatSim/python/voltcurrent.py "; +//const char pythonCmd[] = "python3 -u /home/pi/CubeSatSim/ina219.py "; +//char pythonStr[100], pythonConfigStr[100], busStr[10]; +int mapping[8] = {0, 1, 2, 3, 4, 5, 6, 7}; +char src_addr[5] = ""; +char dest_addr[6] = "APCSS"; +float voltage_min[9], current_min[9], voltage_max[9], current_max[9], sensor_max[17], sensor_min[17], other_max[3], other_min[3]; + +// Payload OK + +#define SEALEVELPRESSURE_HPA (1013.25) + +Adafruit_BME280 bme; +MPU6050 mpu6050(Wire); + +long timer = 0; +int bmePresent, mpuPresent; +int RXLED = 17; // The RX LED has a defined Arduino pin +int greenLED = 19; +int blueLED = 18; +float Sensor1 = 0.0; +float Sensor2 = 0.0; +float Sensor3 = 0.0; +bool newData = false; +void eeprom_word_write(int addr, int val); +short eeprom_word_read(int addr); +int first_time = true; +int first_time_sstv = true; +int first_read = true; +float T2 = 27; // Temperature data point 1 +float R2 = 170; // Reading data point 1 +float T1 = 7; // Temperature data point 2 +float R1 = 184; // Reading data point 2 +int sensorValue; +float Temp; +float rest; + +unsigned int wav_position = 0; +/* +int pwm_counter = 0; +int pwm_counter_max = 420; +int pwm_amplitude = 50; //50 //100; +int pwm_value; +int tx_bit = 1; +*/ +volatile unsigned long delay_time; +bool polarity = true; +pwm_config config; +int bpsk_pin_slice_A; +int bpsk_pin_slice_B; +int bpsk_pin_slice; +int sample_rate; +int buffer_size; +long micro_timer; +long micro_timer2; +int ready = FALSE; +bool cw_stop = false; +int payload_command = false; +bool debug_mode = false; +bool voltage_read = false; +bool ina219_started = false; +bool camera_detected = false; +bool rotate_flag = true; + +int led_builtin_pin; + +#define PRESSED 0 +#define HELD 0 +#define RELEASED 1 +int pb_state = RELEASED; +int mode_count = 0; +unsigned long pb_press_start; +const char sstv1_filename[] = "/sstv_image_1_320_x_240.jpg"; +const char sstv2_filename[] = "/sstv_image_2_320_x_240.jpg"; + +//bool TimerHandler0(struct repeating_timer *t); +//RPI_PICO_Timer ITimer0(0); +//RPI_PICO_Timer ITimer1(1); + +bool timer0_on = false; +volatile int timer_counter; +bool filter_present = false; // BPF installation state for transmitter +bool sr_frs_present = false; // SR_FRS FM transmitter module state + +char callsign[20]; +int morse_timing = 60; // ms for a dit +int morse_freq = 1800; // Hz +//int morse_table[44][6] = { // 0-9, A-Z only by (ASCII - 48) +byte morse_table[44][6] = { // 0-9, A-Z only by (ASCII - 48) + { 3, 3, 3, 3, 3, 0 }, // 0 + { 1, 3, 3, 3, 3, 0 }, // 1 + { 1, 1, 3, 3, 3, 0 }, // 2 + { 1, 1, 1, 3, 3, 0 }, // 3 + { 1, 1, 1, 1, 3, 0 }, // 4 + { 1, 1, 1, 1, 1, 0 }, // 5 + { 3, 1, 1, 1, 1, 0 }, // 6 + { 3, 3, 1, 1, 1, 0 }, // 7 + { 3, 3, 3, 1, 1, 0 }, // 8 + { 3, 3, 3, 3, 1, 0 }, // 9 + { 0, 0, 0, 0, 0, 0 }, // - + { 0, 0, 0, 0, 0, 0 }, // - + { 0, 0, 0, 0, 0, 0 }, // - + { 0, 0, 0, 0, 0, 0 }, // - + { 0, 0, 0, 0, 0, 0 }, // - + { 0, 0, 0, 0, 0, 0 }, // - + { 0, 0, 0, 0, 0, 0 }, // - + { 1, 3, 0, 0, 0, 0 }, // A + { 3, 1, 1, 1, 0, 0 }, // B + { 3, 1, 3, 1, 0, 0 }, // C + { 3, 1, 1, 0, 0, 0 }, // D + { 1, 0, 0, 0, 0, 0 }, // E + { 1, 1, 3, 1, 0, 0 }, // F + { 3, 3, 1, 0, 0, 0 }, // G + { 1, 1, 1, 1, 0, 0 }, // H + { 1, 1, 0, 0, 0, 0 }, // I + { 1, 3, 3, 3, 0, 0 }, // J + { 3, 1, 3, 0, 0, 0 }, // K + { 1, 3, 1, 1, 0, 0 }, // L + { 3, 3, 0, 0, 0, 0 }, // M + { 3, 1, 0, 0, 0, 0 }, // N + { 3, 3, 3, 0, 0, 0 }, // O + { 1, 3, 3, 1, 0, 0 }, // P + { 3, 3, 1, 3, 0, 0 }, // Q + { 1, 3, 1, 0, 0, 0 }, // R + { 1, 1, 1, 0, 0, 0 }, // S + { 3, 0, 0, 0, 0, 0 }, // T + { 1, 1, 3, 0, 0, 0 }, // U + { 1, 1, 1, 3, 0, 0 }, // V + { 1, 3, 3, 0, 0, 0 }, // W + { 3, 1, 1, 3, 0, 0 }, // X + { 3, 1, 3, 3, 0, 0 }, // Y + { 3, 3, 1, 1, 0, 0 } // Z +}; + + +/* + * TelemEncoding.h + * + * Created on: Feb 3, 2014 + * Author: fox + */ + +#ifndef TELEMENCODING_H_ +#define TELEMENCODING_H_ + +/* +void update_rs( + unsigned char parity[32], // 32-byte encoder state; zero before each frame + unsigned char c // Current data byte to update +); +*/ + +#define CHARACTER_BITS 10 +#define CHARACTERS_PER_LONGWORD 3 +#define CHARACTER_MASK ((1<. + */ + +// This code is an Arduino sketch for the Raspberry Pi Pico +// based on the Raspberry Pi Code + +//#define PICO_0V1 // define for Pico v0.1 hardware + +#include "payload_pico.h" +#include "DumbTXSWS.h" +#include +//#include +#include +#include +//#include +#include +//#include +#include +#include "pico/stdlib.h" // stdlib +//#include "hardware/irq.h" // interrupts +//#include "hardware/pwm.h" // pwm +//#include "hardware/sync.h" // wait for interrupt +//#include "RPi_Pico_ISR_Timer.h" +//#include "RPi_Pico_TimerInterrupt.h" +#include +#include "hardware/gpio.h" +#include "hardware/adc.h" +//#include "SSTV-Arduino-Scottie1-Library.h" +#include "LittleFS.h" +//#include +//#include "picosstvpp.h" +#include "pico/bootrom.h" +#include "hardware/watchdog.h" +#include +#include + +// jpg files to be stored in flash storage on Pico (FS 512kB setting) +//#include "sstv1.h" +//#include "sstv2.h" + +//Adafruit_INA219 ina219_1_0x40; +//Adafruit_INA219 ina219_1_0x41(0x41); +//Adafruit_INA219 ina219_1_0x44(0x44); +//Adafruit_INA219 ina219_1_0x45(0x45); +//Adafruit_INA219 ina219_2_0x40(0x40); +//Adafruit_INA219 ina219_2_0x41(0x41); +//Adafruit_INA219 ina219_2_0x44(0x44); +//Adafruit_INA219 ina219_2_0x45(0x45); + +//Adafruit_SI5351 clockgen = Adafruit_SI5351(); +TinyGPSPlus gps; + +unsigned long micros3; +bool show_gps = true; // set to false to not see all GPS messages +volatile int skip = 0; + +//WiFiServer server(port); +//WiFiClient client; +WiFiClient net; +MQTTClient client; + +#define PICO_W // define if Pico W board. Otherwise, compilation fail for Pico or runtime fail if compile as Pico W + +//#define APRS_VHF + +byte green_led_counter = 0; +//char call[] = "AMSAT"; // put your callsign here + +//extern bool get_camera_image(bool debug); +//extern bool start_camera(); + +float rand_float(float lower, float upper) { + + return (float)(random(lower*100, upper*100)/100.0); +} + +void setup() { + + set_sys_clock_khz(133000, true); + + Serial.begin(115200); + + delay(10000); + + LittleFS.begin(); +// LittleFS.format(); // only format if files of size 0 keep showing up +//#ifdef APRS_VHF +// mode = AFSK; // force to APRS +//#else +// read_mode(); +//#endif + +// new_mode = mode; + +// pinMode(LED_BUILTIN, OUTPUT); +// blinkTimes(1); + +/// sleep(5.0); + +// otherwise, run CubeSatSim Pico code + + Serial.println("CubeSatSim Pico Payload v0.4 starting...\n"); + +/**/ + if (check_for_wifi()) { + wifi = true; + led_builtin_pin = LED_BUILTIN; // use default GPIO for Pico W + pinMode(LED_BUILTIN, OUTPUT); +// configure_wifi(); + } else { + led_builtin_pin = 25; // manually set GPIO 25 for Pico board +// pinMode(25, OUTPUT); + pinMode(led_builtin_pin, OUTPUT); + } +/**/ + + config_gpio(); + + Serial.print("Pi Zero present, so running Payload OK code."); + sr_frs_present = true; +// program_radio(); + start_payload(); + + pinMode(15, INPUT_PULLUP); + pinMode(22, OUTPUT); + digitalWrite(22, 1); + pinMode(17, OUTPUT); + digitalWrite(17, 1); + + prompt = false; + prompting = false; + +} + +void loop() { + + payload_OK_only(); + sleep(1.0); + Serial.print("Squelch: "); + Serial.println(digitalRead(15)); +// Serial.println(" "); + prompt_for_input(); +} + +void config_gpio() { + + pinMode(0, INPUT); + pinMode(1, INPUT); + + // set all Pico GPIO connected pins to input + for (int i = 6; i < 22; i++) { + pinMode(i, INPUT); + } + pinMode(26, INPUT); + pinMode(27, INPUT); + pinMode(28, INPUT); +} + +void program_radio() { + if (sr_frs_present) { + Serial.println("Programming SR_FRS!"); + + pinMode(PD_PIN, OUTPUT); + pinMode(PTT_PIN, OUTPUT); + digitalWrite(PD_PIN, HIGH); // enable SR_FRS + digitalWrite(PTT_PIN, HIGH); // stop transmit + + DumbTXSWS mySerial(SWTX_PIN); // TX pin + mySerial.begin(9600); + + for (int i = 0; i < 5; i++) { + sleep(0.5); // delay(500); +#ifdef APRS_VHF + mySerial.println("AT+DMOSETGROUP=0,144.3900,144.3900,0,3,0,0\r"); // can change to 144.39 for standard APRS +// mySerial.println("AT+DMOSETGROUP=0,145.0000,145.0000,0,3,0,0\r"); // can change to 145 for testing ASPRS +#else + mySerial.println("AT+DMOSETGROUP=0,435.1000,434.9900,0,3,0,0\r"); // squelch set to 3 +#endif + sleep(0.5); + mySerial.println("AT+DMOSETMIC=8,0\r"); // was 8 + + } + } +#ifdef APRS_VHF + Serial.println("Programming FM tx 144.39, rx on 144.39 MHz"); +#else + Serial.println("Programming FM tx 434.9, rx on 435.0 MHz"); +#endif +// digitalWrite(PTT_PIN, LOW); // transmit carrier for 0.5 sec +// sleep(0.5); +// digitalWrite(PTT_PIN, HIGH); + digitalWrite(PD_PIN, LOW); // disable SR_FRS + pinMode(PD_PIN, INPUT); + pinMode(PTT_PIN, INPUT); +} + +bool read_config_file() { + char buff[255]; + // Open configuration file with callsign and reset count + Serial.println("Reading config file"); + File config_file = LittleFS.open("/payload.cfg", "r"); +// FILE * config_file = fopen("/payload.cfg", "r"); + if (!config_file) { + return(false); + } + +// char * cfg_buf[100]; + config_file.read((uint8_t *)buff, 255); +// sscanf(buff, "%d", &cnt); + sscanf(buff, "%f %f %f", xOffset, yOffset, zOffset); + config_file.close(); +// if (debug_mode) + Serial.printf("Config file /payload.cfg contains %f %f %f\n", xOffset, yOffset, zOffset); + + config_file.close(); + +// write_config_file(); + + return(true); +} + +void write_config_file() { + Serial.println("Writing /payload.cfg file"); + char buff[255]; + File config_file = LittleFS.open("/payload.cfg", "w+"); + + sprintf(buff, "%f %f %f", xOffset, yOffset, zOffset); + Serial.println("Writing string "); +// if (debug_mode) + print_string(buff); + config_file.write(buff, strlen(buff)); + + config_file.close(); +// Serial.println("Write complete"); + +} + +void read_sensors() +{ + +} + +void print_string(char *string) +{ + int count = 0; + while ((count < 250) && (string[count] != 0)) + { + Serial.print(string[count++]); + } + Serial.println(" "); +} + +void start_payload() { + +//#ifdef APRS_VHF +// Serial2.setRX(9); +// Serial2.setRX(9); +// Serial2.setRX(1); + delay(100); +// Serial2.setTX(8); +// Serial2.setTX(8); +// Serial2.setRX(0); + +/* + delay(100); + Serial1.setRX(1); + delay(100); + Serial1.setTX(0); + delay(10); +*/ +/* + Serial1.begin(115200); // serial to Pi + + Serial.println("Starting Serial1 for payload"); + + Serial2.begin(115200); // serial from GPS + + Serial.println("Starting Serial2 for GPS"); +*/ +//#else + Serial1.setRX(1); + delay(100); + Serial1.setTX(0); + delay(100); + Serial1.begin(115200); // Pi UART faster speed + + Serial2.begin(9600); // serial from GPS - some GPS modules need 115200 + + Serial.println("Starting Serial2 for GPS"); +//#endif + + Serial.println("Starting payload!"); + + blink_setup(); +/* + blink(500); + sleep(0.25); // delay(250); + blink(500); + sleep(0.25); // delay(250); + led_set(greenLED, HIGH); + sleep(0.25); // delay(250); + led_set(greenLED, LOW); + led_set(blueLED, HIGH); + sleep(0.25); // delay(250); + led_set(blueLED, LOW); +*/ + + if (bme.begin()) { + bmePresent = 1; + } else { + Serial.println("Could not find a valid BME280 sensor, check wiring!"); + bmePresent = 0; + } + + Wire.begin(); + Wire.beginTransmission(0x68); + if (Wire.endTransmission() != 0) { + Serial.println("Could not find a valid MPU6050 sensor, check wiring!"); + mpuPresent = 0; + } + else { + mpuPresent = 1; + mpu6050.begin(); + + +// if ((read_config_file()) && (payload_command != PAYLOAD_RESET)) + if (false) + { + Serial.println("Reading gyro offsets from config file\n"); + mpu6050.setGyroOffsets(xOffset, yOffset, zOffset); + + } + + else + { + payload_command = false; + + Serial.println("Calculating gyro offsets and storing in EEPROM\n"); + + mpu6050.calcGyroOffsets(true); +/* + eeprom_word_write(0, 0xA07); + eeprom_word_write(1, (int)(mpu6050.getGyroXoffset() * 100.0) + 0.5); + eeprom_word_write(2, (int)(mpu6050.getGyroYoffset() * 100.0) + 0.5); + eeprom_word_write(3, (int)(mpu6050.getGyroZoffset() * 100.0) + 0.5); +*/ +// flag = 0xA07; + xOffset = mpu6050.getGyroXoffset(); + yOffset = mpu6050.getGyroYoffset(); + zOffset = mpu6050.getGyroZoffset(); + + write_config_file(); + } + } + + if (!(payload = bmePresent || mpuPresent)) + Serial.println("No payload sensors detected"); + + pinMode(greenLED, OUTPUT); + pinMode(blueLED, OUTPUT); + +} + +void payload_OK_only() +{ + payload_str[0] = '\0'; // clear the payload string + + if ((Serial.available() > 0)|| first_time == true) // commented back in + { + blink(50); + char result = Serial.read(); + char header[] = "OK BME280 "; + char str[100]; + + strcpy(payload_str, header); +// print_string(str); + if (bmePresent) +// sprintf(str, "%4.2f %6.2f %6.2f %5.2f ", + sprintf(str, "%.1f %.2f %.1f %.2f ", + bme.readTemperature(), bme.readPressure() / 100.0, bme.readAltitude(SEALEVELPRESSURE_HPA), bme.readHumidity()); + else + sprintf(str, "OK BME280 0.0 0.0 0.0 0.0 "); + strcat(payload_str, str); + + if (mpuPresent) { +// print_string(payload_str); + mpu6050.update(); + +// sprintf(str, " MPU6050 %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f ", + sprintf(str, " MPU6050 %.1f %.1f %.1f %.1f %.1f %.1f ", + mpu6050.getGyroX(), mpu6050.getGyroY(), mpu6050.getGyroZ(), mpu6050.getAccX(), mpu6050.getAccY(), mpu6050.getAccZ()); + + strcat(payload_str, str); +// print_string(payload_str); + } + if (result == 'R') { + Serial.println("OK"); + delay(100); +// first_time = true; + start_payload(); +// setup(); + } + else if (result == 'g') { + show_gps = !show_gps; + } + else if (result == 'C') { + Serial.println("Clearing stored gyro offsets in EEPROM\n"); + EEPROM.put(0, (float)0.0); +// first_time = true; + start_payload(); +// setup(); + } + if ((result == '?') || first_time == true) // commented back in + if (true) + { + +// first_time = false; + if (bmePresent) { + Serial.print("OK BME280 "); + Serial.print(bme.readTemperature()); + Serial.print(" "); + Serial.print(bme.readPressure() / 100.0F); + Serial.print(" "); + Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); + Serial.print(" "); + Serial.print(bme.readHumidity()); + } else + { + Serial.print("OK BME280 0.0 0.0 0.0 0.0"); + } + if (mpuPresent) { + mpu6050.update(); + + Serial.print(" MPU6050 "); + Serial.print(mpu6050.getGyroX()); + Serial.print(" "); + Serial.print(mpu6050.getGyroY()); + Serial.print(" "); + Serial.print(mpu6050.getGyroZ()); + + Serial.print(" "); + Serial.print(mpu6050.getAccX()); + Serial.print(" "); + Serial.print(mpu6050.getAccY()); + Serial.print(" "); + Serial.print(mpu6050.getAccZ()); + } else + { + Serial.print(" MPU6050 0.0 0.0 0.0 0.0 0.0 0.0"); + } + + sensorValue = analogRead(TEMPERATURE_PIN); + //Serial.println(sensorValue); + Temp = T1 + (sensorValue - R1) *((T2 - T1)/(R2 - R1)); + + + Serial.print(" GPS "); + Serial.print(Sensor1,4); + Serial.print(" "); + Serial.print(Sensor2,4); + Serial.print(" "); + Serial.print(Sensor3,2); + Serial.print(" AN "); + Serial.println(sensorValue); // ,0); + + if (mpuPresent) { + float rotation = sqrt(mpu6050.getGyroX()*mpu6050.getGyroX() + mpu6050.getGyroY()*mpu6050.getGyroY() + mpu6050.getGyroZ()*mpu6050.getGyroZ()); + float acceleration = sqrt(mpu6050.getAccX()*mpu6050.getAccX() + mpu6050.getAccY()*mpu6050.getAccY() + mpu6050.getAccZ()*mpu6050.getAccZ()); +// Serial.print(rotation); +// Serial.print(" "); +// Serial.println(acceleration); + + if (acceleration > 1.2) + led_set(greenLED, HIGH); + else + led_set(greenLED, LOW); + + if (rotation > 5) + led_set(blueLED, HIGH); + else + led_set(blueLED, LOW); + } + } + } + +// Serial2.print("b"); + delay(250); + +// if (Serial2.available() > 0) { + if (true) { +/* + while (Serial2.available() > 0) // read GPS + Serial.write(Serial2.read()); +*/ +// For one second we parse GPS data and report some key values + newData = false; + + unsigned long starting = millis(); + for (unsigned long start = millis(); millis() - start < 1000;) // 5000;) + { + while (Serial2.available()) + { + char c = Serial2.read(); + if (show_gps) + Serial.write(c); // uncomment this line if you want to see the GPS data flowing + if (gps.encode(c)) // Did a new valid sentence come in? + newData = true; + } + } + if (newData) + { + Serial.printf("GPS read new data in ms: %d\n", millis() - start); + float flon = 0.0, flat = 0.0, flalt = 0.0; + unsigned long age; + starting = millis(); +// gps.f_get_position(&flat, &flon, &age); + + Serial.print(F("Location: ")); + if (gps.location.isValid()) + { + Serial.print(gps.location.lat(), 6); + Serial.print(F(",")); + Serial.print(gps.location.lng(), 6); + + flat = gps.location.lat(); + flon = gps.location.lng(); + flalt = gps.altitude.meters(); + } + else + { + Serial.print(F("INVALID")); + } + Serial.print("\r\n"); + + Sensor1 = flat; + Sensor2 = flon; + Sensor3 = flalt; // (float) gps.altitude.meters(); +// Serial.printf("New GPS data: %f %f %f ms: %d\n", Sensor1, Sensor2, Sensor3, millis() - start); + } else +// Serial.printf("GPS read no new data: %d\n", millis() - start); + ; + + blink(50); +/* + if (Serial1.available()) { + char result = Serial1.read(); +// Serial1.println(result); +// Serial.println(result); // don't print read result + + if (result == 'R') { + Serial1.println("OK"); + delay(100); + first_read = true; + start_payload(); +// setup(); + } + } +*/ +// if (result == '?') + if (true) // always send payload data over serial + { + if (bmePresent) { +// Serial1.print("START_FLAGOK BME280 "); + Serial1.print(sensor_start_flag); + Serial1.print("OK BME280 "); + Serial1.print(bme.readTemperature()); + Serial1.print(" "); + Serial1.print(bme.readPressure() / 100.0F); + Serial1.print(" "); + Serial1.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); + Serial1.print(" "); + Serial1.print(bme.readHumidity()); + } else + { +// Serial1.print("START_FLAGOK BME280 0.0 0.0 0.0 0.0"); + Serial1.print(sensor_start_flag); + Serial1.print("OK BME280 0.0 0.0 0.0 0.0"); + } + if (mpuPresent) { + mpu6050.update(); + + Serial1.print(" MPU6050 "); + Serial1.print(mpu6050.getGyroX()); + Serial1.print(" "); + Serial1.print(mpu6050.getGyroY()); + Serial1.print(" "); + Serial1.print(mpu6050.getGyroZ()); + + Serial1.print(" "); + Serial1.print(mpu6050.getAccX()); + Serial1.print(" "); + Serial1.print(mpu6050.getAccY()); + Serial1.print(" "); + Serial1.print(mpu6050.getAccZ()); + + } else + { + Serial1.print(" MPU6050 0.0 0.0 0.0 0.0 0.0 0.0"); + } + + sensorValue = analogRead(TEMPERATURE_PIN); + //Serial.println(sensorValue); + Temp = T1 + (sensorValue - R1) *((T2 - T1)/(R2 - R1)); + + Serial1.print(" GPS "); + Serial1.print(Sensor1,4); + Serial1.print(" "); + Serial1.print(Sensor2,4); + Serial1.print(" "); + Serial1.print(Sensor3,2); + Serial1.print(" AN "); + Serial1.print(sensorValue); //,0); +// Serial1.println("END_FLAG"); + Serial1.println(sensor_end_flag); + + blink(50); + delay(50); + blink(50); + + if (mpuPresent) { + float rotation = sqrt(mpu6050.getGyroX()*mpu6050.getGyroX() + mpu6050.getGyroY()*mpu6050.getGyroY() + mpu6050.getGyroZ()*mpu6050.getGyroZ()); + float acceleration = sqrt(mpu6050.getAccX()*mpu6050.getAccX() + mpu6050.getAccY()*mpu6050.getAccY() + mpu6050.getAccZ()*mpu6050.getAccZ()); +// Serial.print(rotation); +// Serial.print(" "); +// Serial.println(acceleration); + + if (first_read == true) { + first_read = false; + rest = acceleration; + } + + if (acceleration > 1.2 * rest) + led_set(greenLED, HIGH); + else + led_set(greenLED, LOW); + + if (rotation > 5) + led_set(blueLED, HIGH); + else + led_set(blueLED, LOW); + } + } + } + + delay(100); +} + +/**/ +/* +void eeprom_word_write(int addr, int val) +{ + EEPROM.write(addr * 2, lowByte(val)); + EEPROM.write(addr * 2 + 1, highByte(val)); +} + +short eeprom_word_read(int addr) +{ + return ((EEPROM.read(addr * 2 + 1) << 8) | EEPROM.read(addr * 2)); +} +*/ + +void blink_setup() +{ +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + // initialize digital pin PB1 as an output. + pinMode(PC13, OUTPUT); + pinMode(PB9, OUTPUT); + pinMode(PB8, OUTPUT); +#endif + +#if defined __AVR_ATmega32U4__ || ARDUINO_ARCH_RP2040 + pinMode(RXLED, OUTPUT); // Set RX LED as an output + // TX LED is set as an output behind the scenes + pinMode(greenLED, OUTPUT); + pinMode(blueLED,OUTPUT); +#endif +} + +void blink(int length) +{ + if (wifi) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, HIGH); // set the built-in LED ON + + sleep(length/1000.0); // delay(length); // wait for a lenth of time + + if (wifi) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED OFF + else + digitalWrite(led_builtin_pin, LOW); // set the built-in LED OFF +} + +void led_set(int ledPin, bool state) +{ +#if defined(ARDUINO_ARCH_STM32F0) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32L4) + if (ledPin == greenLED) + digitalWrite(PB9, state); + else if (ledPin == blueLED) + digitalWrite(PB8, state); +#endif + +#if defined __AVR_ATmega32U4__ || ARDUINO_ARCH_RP2040 + digitalWrite(ledPin, state); +#endif +} + + +void sleep(float timer) { // sleeps for intervals more than 0.01 milli seconds + + unsigned long time_us = (unsigned long)(timer * 1000000.0); + unsigned long startSleep = micros(); + while ((micros() - startSleep) < time_us) { +// busy_wait_us(100); + delayMicroseconds(100); + } +} + +void blinkTimes(int blinks) { + for (int i = 0; i < blinks; i++) { + digitalWrite(MAIN_LED_GREEN, LOW); + + if (wifi) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED OFF + else + digitalWrite(led_builtin_pin, LOW); // set the built-in LED OFF + + sleep(0.1); + digitalWrite(MAIN_LED_GREEN, HIGH); + + if (wifi) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, HIGH); // set the built-in LED ON + + sleep(0.1); + } +} + +void blinkFastTimes(int blinks) { + for (int i = 0; i < blinks; i++) { + digitalWrite(MAIN_LED_GREEN, LOW); + + if (wifi) + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED OFF + else + digitalWrite(led_builtin_pin, LOW); // set the built-in LED OFF + + sleep(0.05); + digitalWrite(MAIN_LED_GREEN, HIGH); + + if (wifi) + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON + else + digitalWrite(led_builtin_pin, HIGH); // set the built-in LED ON + + sleep(0.05); + } +} + +void blink_pin(int pin, int duration) { + + digitalWrite(pin, HIGH); + sleep((float)duration / 1000.00); + digitalWrite(pin, LOW); + +} + + +bool check_for_wifi() { + +#ifndef PICO_W + + Serial.println("WiFi disabled in software"); + return(false); // skip check if not Pico W board or compilation will fail + +#endif + +// stdio_init_all(); + +// adc_init(); +// adc_gpio_init(29); + pinMode(29, INPUT); +// adc_select_input(3); + const float conversion_factor = 3.3f / (1 << 12); +// uint16_t result = adc_read(); + uint16_t result = analogRead(29); +// Serial.printf("ADC3 value: 0x%03x, voltage: %f V\n", result, result * conversion_factor); + +// if (result < 0x100) { + if (result < 0x10) { + Serial.println("\nPico W detected!\n"); + return(true); + } + else { + Serial.println("\nPico detected!\n"); + return(false); + } +} + +void show_dir() { + LittleFS.begin(); + Dir dir = LittleFS.openDir("/"); +// or Dir dir = LittleFS.openDir("/data"); + Serial.println("FS directory:"); + while (dir.next()) { + Serial.print(dir.fileName()); + if(dir.fileSize()) { + File f = dir.openFile("r"); + Serial.print(" "); + Serial.println(f.size()); + } + } + Serial.println(">"); +} + +void serial_input() { + + if (prompt == false) { // only query if not in the middle of prompting + + if (Serial.available() > 0) { // check for user input on serial port + +// blink(50); + char result = Serial.read(); + + if ((result != '\n') && (result != '\r')) { + + Serial.println(result); + + switch(result) { + case 'h': + case 'H': + // Serial.println("Help"); + prompt = PROMPT_HELP; + break; + + case 'a': + case 'A': + Serial.println("Change to AFSK/APRS mode"); + new_mode = AFSK; + break; + + case 'm': + case 'M': + Serial.println("Change to CW mode"); + new_mode = CW; + break; + + case 'F': + Serial.println("Formatting flash memory"); + prompt = PROMPT_FORMAT; + break; + case 'f': + Serial.println("Change to FSK mode"); + new_mode = FSK; + break; + + case 'b': + case 'B': + Serial.println("Change to BPSK mode"); + new_mode = BPSK; + break; + + case 's': + Serial.println("Change to SSTV mode"); + new_mode = SSTV; + break; + + case 'S': + Serial.println("I2C scan"); + prompt = PROMPT_I2CSCAN; + break; + + case 'i': + case 'I': + Serial.println("Restart CubeSatsim software"); + prompt = PROMPT_RESTART; + break; + + case 'c': + Serial.println("Change the CALLSIGN"); + prompt = PROMPT_CALLSIGN; + break; + + case 'C': + Serial.println("Debug camera"); + debug_camera = true; + prompt = PROMPT_CAMERA; + break; + + case 't': + case 'T': + Serial.println("Change the Simulated Telemetry"); + prompt = PROMPT_SIM; + break; + + case 'p': + case 'P': + Serial.println("Reset payload EEPROM settings"); + prompt = PROMPT_PAYLOAD; + break; + + case 'r': + case 'R': + Serial.println("Change the Resets Count"); + prompt = PROMPT_RESET; + break; + + case 'o': + case 'O': + Serial.println("Read diode temperature"); + prompt = PROMPT_TEMP; + break; + + case 'l': + case 'L': + Serial.println("Change the Latitude and Longitude"); + prompt = PROMPT_LAT; + break; + + case 'v': + case 'V': + Serial.println("Read INA219 voltage and current"); + prompt = PROMPT_VOLTAGE; + break; + + case '?': + Serial.println("Query payload sensors"); + prompt = PROMPT_QUERY; + break; + + case 'd': + Serial.println("Change debug mode"); + prompt = PROMPT_DEBUG; + break; + + case 'w': + Serial.println(wifi); + Serial.println("Connect to WiFi"); + prompt = PROMPT_WIFI; + break; + + default: + Serial.println("Not a command\n"); + + break; + } + } + } + } +} + +void prompt_for_input() { + float float_result; + + if (!prompting) { + prompting = true; + + while (Serial.available() > 0) // clear any characters in serial input buffer + Serial.read(); + + switch(prompt) { + + case PROMPT_HELP: + Serial.println("\nChange settings by typing the letter:"); + Serial.println("h Help info"); + Serial.println("F Format flash memory"); + Serial.println("S I2C scan"); + Serial.println("i Restart"); + Serial.println("p Reset payload and stored EEPROM values"); + Serial.println("? Query sensors"); + Serial.println("o Read diode temperature"); + Serial.println("d Change debug mode"); + Serial.println("w Connect to WiFi\n"); + +// Serial.printf("Software version v0.39 \nConfig file /payload.cfg contains %s %d %f %f %s\n\n", callsign, reset_count, lat_file, long_file, sim_yes); +/* + switch(mode) { + + case(AFSK): + Serial.println("AFSK mode"); + break; + + case(FSK): + Serial.println("FSK mode"); + break; + + case(BPSK): + Serial.println("BPSK mode"); + break; + + case(SSTV): + Serial.println("SSTV mode"); + break; + + case(CW): + Serial.println("CW mode"); + break; + } +*/ + break; + + case PROMPT_REBOOT: + Serial.println("Rebooting..."); + Serial.flush(); + watchdog_reboot (0, SRAM_END, 500); // restart Pico + sleep(20.0); + break; + + case PROMPT_FORMAT: + LittleFS.format(); +// Serial.println("Reboot or power cycle to restart the CubeSatSim"); + // while (1) ; // infinite loop + Serial.println("Rebooting..."); + Serial.flush(); + watchdog_reboot (0, SRAM_END, 500); // restart Pico + sleep(20.0); + break; + + case PROMPT_PAYLOAD: + Serial.println("Resetting the Payload"); + payload_command = PAYLOAD_RESET; + start_payload(); + break; + + case PROMPT_WIFI: + Serial.println(wifi); + if (wifi) { + char ssid[30], pass[30]; + Serial.println("Enter the credentials for your WiFi network"); + + Serial.print("Enter WiFi SSID: "); + get_serial_string(); + + print_string(serial_string); + + if (strlen(serial_string) > 0) { + strcpy(ssid, serial_string); + Serial.print("Enter WiFi password: "); + get_serial_string(); + if (strlen(serial_string) > 0) { + strcpy(pass, serial_string); + Serial.println("Connecting to Wifi"); +// Serial.printf("%s%s\n",ssid, pass); + + WiFi.begin(ssid, pass); + + unsigned int elapsed_timer = (unsigned int) millis(); + while ((WiFi.status() != WL_CONNECTED) && ((millis() - elapsed_timer) < 10000)) { + Serial.print("."); + delay(500); + } + if (((millis() - elapsed_timer) > 10000)) + Serial.println("Failed to connect!"); + else + Serial.println("Connected to WiFi!"); + } else + Serial.println("No password entered."); + } else + Serial.println("No SSID entered."); + } else + Serial.println("WiFi not available"); + + break; + + case PROMPT_I2CSCAN: + Serial.print("I2C scan"); + +// -------------------------------------- +// i2c_scanner +// +// Version 1 +// This program (or code that looks like it) +// can be found in many places. +// For example on the Arduino.cc forum. +// The original author is not know. +// Version 2, Juni 2012, Using Arduino 1.0.1 +// Adapted to be as simple as possible by Arduino.cc user Krodal +// Version 3, Feb 26 2013 +// V3 by louarnold +// Version 4, March 3, 2013, Using Arduino 1.0.3 +// by Arduino.cc user Krodal. +// Changes by louarnold removed. +// Scanning addresses changed from 0...127 to 1...119, +// according to the i2c scanner by Nick Gammon +// https://www.gammon.com.au/forum/?id=10896 +// Version 5, March 28, 2013 +// As version 4, but address scans now to 127. +// A sensor seems to use address 120. +// Version 6, November 27, 2015. +// Added waiting for the Leonardo serial communication. +// +// +// This sketch tests the standard 7-bit addresses +// Devices with higher bit address might not be seen properly. +// + + +{ + byte error, address; + int nDevices; + + Serial.println("Scanning I2C Bus 1"); + + nDevices = 0; + for(address = 1; address < 127; address++ ) + { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + Wire.beginTransmission(address); + error = Wire.endTransmission(); + + if (error == 0) + { + Serial.print("I2C device found at bus 1 address 0x"); + if (address<16) + Serial.print("0"); + Serial.print(address,HEX); + Serial.println(" !"); + + nDevices++; + } + else if (error==4) + { + Serial.print("Unknown error at bus 1 address 0x"); + if (address<16) + Serial.print("0"); + Serial.println(address,HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found on bus 1\n"); + else + Serial.println("done\n"); + + delay(5000); // wait 5 seconds for next scan + + Serial.println("Scanning I2C Bus 2"); + + nDevices = 0; + for(address = 1; address < 127; address++ ) + { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + + Wire1.beginTransmission(address); + error = Wire1.endTransmission(); + + if (error == 0) + { + Serial.print("I2C device found at bus 2 address 0x"); + if (address<16) + Serial.print("0"); + Serial.print(address,HEX); + Serial.println(" !"); + + nDevices++; + } + else if (error==4) + { + Serial.print("Unknown error at bus 2 address 0x"); + if (address<16) + Serial.print("0"); + Serial.println(address,HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found on bus 2\n"); + else + Serial.println("done\n"); + +} + Serial.println("complete"); + break; + + + +/* + + case PROMPT_SIM: + if (sim_mode == TRUE) + Serial.println("Simulted Telemetry mode is currently on"); + else + Serial.println("Simulted Telemetry mode is currently off"); + Serial.println("Do you want Simulated Telemetry on (y/n)"); + get_serial_char(); + if ((serial_string[0] == 'y') || (serial_string[0] == 'Y')) { + Serial.println("Setting Simulated telemetry to on"); + reset_min_max(); + config_simulated_telem(); + write_config_file(); + } else if ((serial_string[0] == 'n') || (serial_string[0] == 'N')) { + Serial.println("Setting Simulated telemetry to off"); + reset_min_max(); + sim_mode = false; + if (!ina219_started) + start_ina219(); + write_config_file(); + } else + Serial.println("No change to Simulated Telemetry mode"); + break; + + case PROMPT_LAT: + + Serial.println("Changing the latitude and longitude - only used for APRS telemetry"); + Serial.println("Hitting return keeps the current value."); + + Serial.print("Current value of latitude is "); + Serial.println(latitude); + Serial.println("Enter latitude (decimal degrees, positive is north): "); + get_serial_string(); + float_result = atof(serial_string); + if (float_result != 0.0) { + Serial.print("Latitude updated to "); + Serial.println(float_result); + latitude = float_result; + } else + Serial.println("Latitude not updated"); + + get_serial_clear_buffer(); + Serial.print("Current value of longitude is "); + Serial.println(longitude); + Serial.println("Enter longitude (decimal degrees, positive is east): "); + get_serial_string(); + float_result = atof(serial_string); + if (float_result != 0.0) { + Serial.print("Longitude updated to "); + Serial.println(float_result); + longitude = float_result; + } else + Serial.println("Longitude not updated"); + + write_config_file(); + if (mode == AFSK) + set_lat_lon(); + + break; + + case PROMPT_QUERY: + Serial.println("Querying payload sensors"); + payload_command = PAYLOAD_QUERY; + break; + + case PROMPT_CAMERA: + show_dir(); + get_camera_image(debug_camera); + show_dir(); + break; + + case PROMPT_TEMP: + sensorValue = analogRead(TEMPERATURE_PIN); + Serial.print("Raw diode voltage: "); + Serial.println(sensorValue); + Temp = T1 + (sensorValue - R1) *((T2 - T1)/(R2 - R1)); + Serial.print("Calculated temperature: "); + Serial.print(Temp); + Serial.println(" C"); + break; + + case PROMPT_VOLTAGE: + Serial.println("Querying INA219 voltage and current sensors"); + if (!ina219_started) + start_ina219(); + voltage_read = true; + read_ina219(); + break; + + + case PROMPT_RESET: + Serial.println("Reset count is now 0"); + reset_count = 0; + write_config_file(); + break; + + case PROMPT_RESTART: + prompt = false; +// Serial.println("Restart not yet implemented"); + start_payload(); +// start_ina219(); + if ((mode != CW) || (!filter_present)) + transmit_callsign(callsign); + sleep(0.5); + config_telem(); + config_radio(); + sampleTime = (unsigned int) millis(); + break; + + case PROMPT_DEBUG: + Serial.print("Changing Debug Mode to "); + debug_mode = !debug_mode; + if (debug_mode) + Serial.println("on"); + else + Serial.println("off"); + break; +*/ + + } + prompt = false; + prompting = false; + } +// else +// Serial.println("Already prompting!"); +} + +void get_serial_string() { + int input = 0; + int i = 0; + unsigned int elapsed_time = (unsigned int) millis(); + while ((input != '\n') && (input!= '\r') && (i < 128) && ((millis() - elapsed_time) < 20000)) { + if (Serial.available() > 0) { + input = Serial.read(); + if ((input != '\n') && (input!= '\r')) { + serial_string[i++] = input; + Serial.write(input); + } + } + sleep(0.1); + } + serial_string[i] = 0; + Serial.println(" "); +} + +void get_serial_char() { + unsigned int elapsed_time = (unsigned int) millis(); + while (((millis() - elapsed_time) < 20000) && (Serial.available() < 1)) { } + if (Serial.available() > 0) { + serial_string[0] = Serial.read(); // get character + Serial.write(serial_string[0]); + serial_string[1] = 0; + Serial.println(" "); + } else + { + serial_string[0] = 0; // timeout - no character + } +} + +void get_serial_clear_buffer() { +// Serial.println("Emptying serial input buffer"); + while (Serial.available() > 0) + Serial.read(); + +} + + +void read_config() { + LittleFS.begin(); + Serial.println("Reading config file"); + char buff[32]; + File mode_file = LittleFS.open("/config.txt", "r"); +// if (!mode_file) { +// write_mode(mode); +// } else { + // if (mode_file.read((uint8_t *)buff, 31)) { +// Serial.println("Reading mode from .mode file"); + sscanf(buff, "%d", &mode); + mode_file.close(); +// Serial.print("Mode is "); +// Serial.print(mode); + +// } + //} +} + +void write_config(int save_mode) { + + char buff[32]; + Serial.println("Writing config file"); + File mode_file = LittleFS.open("/config.txt", "w+"); + + sprintf(buff, "%d", save_mode); + if (debug_mode) { + Serial.println("Writing string"); + print_string(buff); + } + + if (mode_file.write(buff, strlen(buff)) != strlen(buff)) { +// Serial.println(mode_file.write(buff, strlen(buff))); + Serial.println("*** config file write error! ***\n\n"); + blinkFastTimes(3); + } + + mode_file.close(); +// Serial.println("Write complete"); +} + + +void get_input() { +// if (mode != SSTV) +// Serial.print("+"); +// if ((mode == CW) || (mode == SSTV)) + serial_input(); + +// check for button press +// if (digitalRead(MAIN_PB_PIN) == PRESSED) // pushbutton is pressed +// process_pushbutton(); + if (BOOTSEL) // boot selector button is pressed on Pico +// process_bootsel(); + Serial.println("boot selector button pressed!"); + + if (prompt) { +// Serial.println("Need to prompt for input!"); + prompt_for_input(); + prompt = false; + } +/* + // check to see if the mode has changed + if (mode != new_mode) { + Serial.println("Changing mode"); + cw_stop = false; // enable CW or won't hear CW ID +/// if (mode == SSTV) { +/// ITimer1.detachInterrupt(); +/// start_button_isr(); // restart button isr +/// } + int old_mode = mode; + bool config_done = false; +// mode = new_mode; // change modes if button pressed + write_mode(new_mode); + + Serial.println("Rebooting..."); + Serial.flush(); + watchdog_reboot (0, SRAM_END, 500); //10); // restart Pico + + sleep(20.0); + */ +/* + if (new_mode != CW) + transmit_callsign(callsign); + sleep(0.5); + + if (!config_done) + config_telem(); // run this here for all other modes + + config_radio(); + if ((mode == FSK) || (mode == BPSK)) { + digitalWrite(LED_BUILTIN, HIGH); + digitalWrite(MAIN_LED_BLUE, HIGH); + } + + sampleTime = (unsigned int) millis(); +*/ +// } + +} diff --git a/systemd/rpitx.service b/systemd/command.service similarity index 67% rename from systemd/rpitx.service rename to systemd/command.service index 2f2feac2c..9354154fa 100644 --- a/systemd/rpitx.service +++ b/systemd/command.service @@ -1,9 +1,9 @@ [Unit] -Description=CubeSatSim rpitx service +Description=Command service [Service] TimeoutStopSec=5 -ExecStart=python3 -u /home/pi/CubeSatSim/rpitx.py +ExecStart=/home/pi/CubeSatSim/command WorkingDirectory=/home/pi/CubeSatSim StandardOutput=inherit StandardError=inherit diff --git a/systemd/cubesatsim.service b/systemd/cubesatsim.service index 11966c22b..1101dc9e4 100644 --- a/systemd/cubesatsim.service +++ b/systemd/cubesatsim.service @@ -10,7 +10,7 @@ StandardError=inherit Restart=always User=root CPUAccounting=true -CPUQuota=5% +CPUQuota=7% [Install] WantedBy=default.target diff --git a/systemd/transmit.service b/systemd/transmit.service new file mode 100644 index 000000000..ab6dd815d --- /dev/null +++ b/systemd/transmit.service @@ -0,0 +1,14 @@ +[Unit] +Description=CubeSatSim transmit service + +[Service] +TimeoutStopSec=5 +ExecStart=python3 -u /home/pi/CubeSatSim/transmit.py +WorkingDirectory=/home/pi/CubeSatSim +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root + +[Install] +WantedBy=default.target diff --git a/telem.c b/telem.c index a32746db1..7afceef28 100644 --- a/telem.c +++ b/telem.c @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { } } - printf("CubeSatSim v1.2 INA219 Voltage and Current Telemetry\n"); + printf("CubeSatSim v2.0 INA219 Voltage and Current Telemetry\n"); map[MINUS_X] = MINUS_Y; map[PLUS_Z] = MINUS_X; map[MINUS_Y] = PLUS_Z; @@ -72,14 +72,14 @@ int main(int argc, char *argv[]) { } printf("\n"); - printf("+X | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_X]], current[map[PLUS_X]]); - printf("+Y | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_Y]], current[map[PLUS_Y]]); - printf("+Z | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_Z]], current[map[PLUS_Z]]); - printf("-X | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_X]], current[map[MINUS_X]]); - printf("-Y | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_Y]], current[map[MINUS_Y]]); - printf("-Z | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_Z]], current[map[MINUS_Z]]); - printf("Bat | % 4.2f V % 5.0f mA \n", voltage[map[BAT]], current[map[BAT]]); - printf("Bus | % 4.2f V % 5.0f mA \n\n", voltage[map[BUS]], current[map[BUS]]); + printf("+X | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_X]], current[map[PLUS_X]]); + printf("+Y | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_Y]], current[map[PLUS_Y]]); + printf("+Z | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_Z]], current[map[PLUS_Z]]); + printf("-X | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_X]], current[map[MINUS_X]]); + printf("-Y | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_Y]], current[map[MINUS_Y]]); + printf("-Z | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_Z]], current[map[MINUS_Z]]); + printf("Bat | % 4.2f V % 5.0f mA \n", voltage[map[BAT]], current[map[BAT]]); + printf("Bat2 | % 4.2f V % 5.0f mA \n\n", voltage[map[BAT2]], current[map[BAT2]]); fclose(file1); return 0; diff --git a/transmit.py b/transmit.py new file mode 100644 index 000000000..51392f7da --- /dev/null +++ b/transmit.py @@ -0,0 +1,835 @@ +#!/usr/bin/env python + +import RPi.GPIO as GPIO +from RPi.GPIO import output +#import subprocess +#import time +from time import sleep +#import os +import sys +from os import system +from PIL import Image, ImageDraw, ImageFont, ImageColor +import serial + +def battery_saver_check(): + try: + global txc + f = open("/home/pi/CubeSatSim/battery_saver", "r") + f.close() + txc = False + print("Safe Mode!") + print("battery saver activated") + except: + print("battery saver not activated") +# txc = True + +def increment_mode(): + print("increment mode") + powerPin = 16 + try: + file = open("/home/pi/CubeSatSim/.mode") + mode = file.read(1) + except: +# mode = "f" + if (debug_mode == 1): + print("Can't open .mode file") # , defaulting to FSK") + file.close() + print("Mode is: ") + print(mode) + if (mode == 'a'): + mode = 'f' + GPIO.output(powerPin, 0) # blink two times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(2.5) + + elif (mode == 'f'): + mode = 'b' + GPIO.output(powerPin, 0) # blink three times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(2.5) + + elif (mode == 'b'): + mode = 's' + GPIO.output(powerPin, 0) # blink four times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(2.5) + + elif (mode == 's'): + mode = 'm' + GPIO.output(powerPin, 0) # blink five times + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1); + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(0.1) + GPIO.output(powerPin, 0) + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(2.5) + else: + mode = 'a' + GPIO.output(powerPin, 0) # blink one time + sleep(0.1) + GPIO.output(powerPin, 1) + sleep(2.5) + + try: + file = open("/home/pi/CubeSatSim/.mode", "w") + count_string = str(command_count) + file.write(mode) + file.close() + print(".mode file written") + + GPIO.setwarnings(False) + GPIO.output(txLed, 0) + GPIO.output(powerPin, 0) + print("sudo reboot -h now") + GPIO.setwarnings(False) + GPIO.setup(powerPin, GPIO.OUT) + GPIO.output(powerPin, 0); +# system("reboot -h now") +# release = True; + + print("Changing mode now") +# system("/home/pi/CubeSatSim/config -" + mode) + system("reboot -h now") + + sleep(10); + except: + print("can't write to .mode file") + + +print("CubeSatSim v2.0 transmit.py starting...") + +pd = 21 +ptt = 20 +txc_pin = 7 +squelch = 6 +green = 16 +powerPin = 16 + +command_tx = True + +GPIO.setmode(GPIO.BCM) +GPIO.setwarnings(False) +GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP) +GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP) +GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP) +GPIO.setup(txc_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) +GPIO.setup(green, GPIO.OUT) +GPIO.output(powerPin, 1) + +transmit = False +txLed = 27 +txLedOn = 1 +txLedOff = 0 +if GPIO.input(12) == False: + print("Version is v1 with UHF LPF") + transmit = True +else: + print("No LPF") + + +# GPIO.setup(txLed, GPIO.OUT) +# output(txLed, txLedOff) + +GPIO.setmode(GPIO.BCM) # Repeat to make LED work on Pi 4 +GPIO.setwarnings(False) +GPIO.setup(txLed, GPIO.OUT) + +GPIO.setup(pd, GPIO.OUT) +#output(pd, 1) +output(pd, 0) +GPIO.setup(ptt, GPIO.OUT) +output (ptt, 1) + +txc = False +if GPIO.input(txc_pin) == False: + print("TXC is present") + txc = True; +else: + print("TXC not present") + +# txc = False # forcing it off +output(txLed, txLedOn) +sleep(1) +output(txLed, txLedOff) + +battery_saver_check() + +# print(txLedOn) +print(txLed) +# GPIO.setup(27, GPIO.OUT) +# GPIO.output(27, 0) + +debug_mode = 0 #no debugging transmit + +skip = False + +if __name__ == "__main__": + mode = "y" + if (len(sys.argv)) > 1: +# print("There are arguments!") + if (('d' == sys.argv[1]) or ('-d' in sys.argv[1])): + debug_mode = 1 + elif (('x' == sys.argv[1]) or ('-x' in sys.argv[1])): + mode = "x" + print("Forcing APRS mode") + elif (('s' == sys.argv[1]) or ('-s' in sys.argv[1])): + skip = True + print("Skipping delay and CW ID") + + print(transmit) + + + try: + system("cat /proc/uptime > /home/pi/CubeSatSim/uptime") + file = open("/home/pi/CubeSatSim/uptime") + up = file.read().split(" ")[0] + print(up) + uptime = float(up) + print(uptime) + if (uptime < 45): + print("Uptime < 45 seconds") + else: + print("Uptime > 45 seconds") + skip = True + file.close() + except: + print("Can't open /proc/uptime") + + if ( mode == "y"): + try: + file = open("/home/pi/CubeSatSim/.mode") + mode = file.read(1) + except: + mode = "f" + if (debug_mode == 1): + print("Can't open .mode file, defaulting to FSK") + print("Mode is: ") + print(mode) + + try: + file = open("/home/pi/CubeSatSim/beacon_off") + file.close() + command_tx = False + except: + command_tx = True + if (debug_mode == 1): + print("Can't open beacon_off file, defaulting to False") + print("Command_tx: ") + print(command_tx) + + try: + file = open("/home/pi/CubeSatSim/command_count.txt", "r") + string = file.read() + command_count = int(string) + except: + command_count = 0 + if (debug_mode == 1): + print("Can't open command_count file, setting to 0") + file = open("/home/pi/CubeSatSim/command_count.txt", "w") + count_string = str(command_count) + file.write(count_string) + file.close() + print("Command_count: ") + print(command_count) + + tx_value = '0' + rx_value = '0' + sq = '0' + tx = '434.9000' + rx = '435.0000' + + try: + file = open("/home/pi/CubeSatSim/sim.cfg") +# callsign = file.readline().split(" ")[0] + config = file.readline().split() + callsign = config[0] + if len(config) > 5: + sq = config[5] + print(sq) + if len(config) > 6: + txf = float(config[6]) +# print(txf) +# print( "{:.4f}".format(txf)) + tx = "{:.4f}".format(txf) + print(tx) + if len(config) > 7: + rxf = float(config[7]) +# print(rxf) +# print( "{:.4f}".format(rxf)) + rx = "{:.4f}".format(rxf) + print(rx) + if len(config) > 9: + rxpl = float(config[9]) + # print(rxpl) + # print( "{:.0f}".format(rxpl)) + rxpl_value = "{:.0f}".format(rxpl) + print(rxpl_value) + if len(config) > 10: + txpl = float(config[10]) +# print(txpl) +# print( "{:.0f}".format(txpl)) + txpl_value = "{:.0f}".format(txpl) + print(txpl_value) + print(config) + print +# print(callsign) + print(sq) + if sq == '8': + print("squelch set to 8, no command input!") + no_command = True + else: + no_command = False + print(no_command) + except: + callsign = "AMSAT" + if (debug_mode == 1): + print("Can't read callsign from sim.cfg file, defaulting to AMSAT") + file.close() + + try: + f = open("/home/pi/CubeSatSim/command_control", "r") + f.close() + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(squelch, GPIO.IN, pull_up_down=GPIO.PUD_UP) ## pull up in case pin is not connected + if GPIO.input(squelch) == False: + print("squelch not set correctly, no command input!") + no_command = True + else: + print("command and control is activated") + no_command = False +# system("/home/pi/CubeSatSim/command &") + system("sudo systemctl start command") + except: + print("command and control not activated") + no_command = True + + print(callsign) + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 + print(txLed) + print(txLedOn) + GPIO.setup(txLed, GPIO.OUT) + + card = "Headphones" # default using pcm audio output of Pi Zero +# card = "Device" # using USB sound card for audio output + + print("Programming FM module!\n"); + output(pd, 1) + output (ptt, 1) + try: + ser = serial.Serial("/dev/ttyAMA0", 9600) + print(ser.portstr) +# uhf_string = "AT+DMOSETGROUP=0," + rx +"," + tx + ",0,3,0,0\r\n" + uhf_string = "AT+DMOSETGROUP=0," + rx + "," + tx + "," + rxpl_value + "," + sq + "," + txpl_value + ",0\r\n" + print(uhf_string) + for i in range(6): +# ser.write(b"AT+DMOSETGROUP=0,435.0000,434.9000,0,3,0,0\r\n") + ser.write(uhf_string.encode()) + sleep(0.1) + ser.close() + ser = serial.Serial("/dev/ttyAMA0", 115200) # reset back to 115200 for cubesatsim code for payload sensor data + except: + print("Error in serial write") + output(pd, 0) + +# if (mode != 'x') and (skip == False): +# sleep(10) # delay so cubesatsim code catches up + + 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") + +# command_control_check() + +# if (mode != ) and (command_tx == True): +# if (command_tx == True): + if ((mode == 'a') or (mode == 'b') or (mode == 'f') or (mode == 's')) and (command_tx == True) and (skip == False): +# 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) +# if (txc): +# output(pd, 1) +# output (ptt, 0) +# sleep(0.1) +# system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/morse.wav") +# sleep(0.1) +# output (ptt, 1) +# output(pd, 0) +# else: + if (True): + 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 434.9e3") + 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") + 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 434.9e3 > /dev/null 2>&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 > /dev/null 2>&1") + + output(txLed, txLedOff) + + sleep(1) + else: + print("Don't transmit CW ID since command_tx is False or APRS mode") + + if (transmit): + +# print 'Length: ', len(sys.argv) + +# if (len(sys.argv)) > 1: +# print("There are arguments!") + if (mode == 'a') or (mode == 'x') or (mode == 'n'): +# command_control_check() + output(pd, 1) + output(ptt, 1) + if (mode == 'a'): + print("AFSK") + else: + GPIO.output(powerPin, 0) + print("Transmit APRS Commands") +# while True: +# sleep(0.1) + if (mode != 'n'): + system("touch /home/pi/CubeSatSim/ready") + + while True: + try: + f = open("/home/pi/CubeSatSim/ready") + f.close() + if (debug_mode == 1): + print("Packet ready!") + system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1") + system("cat /home/pi/CubeSatSim/t.txt") + if (command_tx == True): + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) +# output(pd, 1) +# output (ptt, 0) +# sleep(.1) +# +# battery_saver_check() + if (txc): +# output(pd, 1) + sleep(0.1) # add delay before transmit + output (ptt, 0) + sleep(0.3) # add even more time at start + system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/telem.wav") + sleep(0.2) # add more time at end + output (ptt, 1) +# output(pd, 0) + else: + system("echo 'AMSAT-11>APCSS:010101/hi hi ' >> t.txt") + if (debug_mode == 1): + system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/telem.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("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/telem.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") + + sleep(0.1) +# output (ptt, 1) +# output(pd, 0) + output(txLed, txLedOff) + system("sudo rm /home/pi/CubeSatSim/ready") + f.close() + + if (debug_mode == 1): + print("Ready for next packet!") + + sleep(0.5) + except: +# command_control_check() + sleep(1) + elif (mode == 'm'): + system("touch /home/pi/CubeSatSim/cwready") + print("CW") + while True: +# command_control_check() + output (pd, 1) + output (ptt, 1) + try: + f = open("/home/pi/CubeSatSim/cwready") + f.close() + system("sudo rm /home/pi/CubeSatSim/cwready") +## ch = 1 + for chan in range(7): + command = "gen_packets -M 20 -o /home/pi/CubeSatSim/morse.wav /home/pi/CubeSatSim/cw" + str(chan) + ".txt -r 48000 > /dev/null 2>&1" + print(command) + system(command) +## chan = chan + 1 + if (command_tx == True): + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) + + if (txc): +# output (pd, 1) + sleep(0.3) + output (ptt, 0) + system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/morse.wav") + sleep(0.1) + output (ptt, 1) +# output (pd, 0) + else: + if (debug_mode == 1): + system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3") + else: + system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + output(txLed, txLedOff) + +# command_control_check() + sleep(2) + f.close() + sleep(10) + except: +# command_control_check() + sleep(1) + elif (mode == 's'): + print("SSTV") +# command_control_check() + output (ptt, 1) + output(pd, 1) + try: +# from picamera import PiCamera +# from pysstv.sstv import SSTV +# camera = PiCamera() + print("Testing for camera") + system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") + f = open("/home/pi/CubeSatSim/camera_out.jpg") + f.close() + print("Camera present") + camera_present = 1 +# camera.close() + except: + print("No camera available") + print(" -> if camera plugged in, is software enabled?") + camera_present = 0 + +# while 1: + output(txLed, txLedOff) +# output (ptt, 1) +# output(pd, 0) + if (camera_present == 1): + try: + file = open("/home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") + print("First SSTV stored image detected") + system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") +# command_control_check() + + if (command_tx == True): + print ("Sending SSTV image") + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) +# battery_saver_check() + + if (txc): +# 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") + output (ptt, 1) +# output(pd, 0) + else: + if (debug_mode == 1): + system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3") + else: + system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + + output(txLed, txLedOff) + + # sleep(1) + except: + print("image 2 did not load - copy from CubeSatSim/sstv directory") + while 1: +# command_control_check() + + 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() + + 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") + +# command_control_check() + + if (command_tx == True): + print ("Sending SSTV image") + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) +# battery_saver_check() + + if (txc): +# output(pd, 1) + output (ptt, 0) + system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/camera_out.jpg.wav") + output(ptt, 1) +# output (pd, 0) + else: + if (debug_mode == 1): + system("cat /home/pi/CubeSatSim/camera_out.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3") + else: + system("cat /home/pi/CubeSatSim/camera_out.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + + output(txLed, txLedOff) +# output (ptt, 1) + +# output(pd, 0) + system("sudo rm /home/pi/CubeSatSim/camera_out.jpg.wav > /dev/null 2>&1") + sleep(10) + else: + try: + # command_control_check() + + file = open("/home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg") + print("First SSTV stored image detected") + system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg") + +# command_control_check() + + if (command_tx == True): + + print ("Sending SSTV image") + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) + +# battery_saver_check() + + if (txc): +# 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") + output(ptt, 1) +# output (pd, 0) + else: + if (debug_mode == 1): + system("cat /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3") + else: + system("cat /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + + output(txLed, txLedOff) +# output (ptt, 1) +# output(pd, 0) + sleep(1) + except: + print("image 1 did not load - copy from CubeSatSim/sstv directory") + try: +# command_control_check() + + file = open("/home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") + print("Second SSTV stored image detected") + system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg") + + while 1: + +# command_control_check() + + if (command_tx == True): + print ("Sending SSTV image") + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) +# battery_saver_check() + + if (txc): +# 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") + output(ptt, 1) +# output (pd, 0) + else: + if (debug_mode == 1): + system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3") + else: + system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + + output(txLed, txLedOff) +# output (ptt, 1) +# output(pd, 0) + sleep(10) + except: + print("image 2 did not load - copy from CubeSatSim/sstv directory") + if (txc == False): + if (command_tx == True): + system("(while true; do (sleep 10 && cat /home/pi/CubeSatSim/wav/sstv.wav); done) | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 &") + while 1: + if (command_tx == True): +# command_control_check() + + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) + +# battery_saver_check() + + if (txc): +# output(pd, 1) + output (ptt, 0) + system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv.wav") + output(ptt, 1) +# output (pd, 0) + else: + sleep(60) + + output(txLed, txLedOff) +# output (ptt, 1) +# output(pd, 0) + sleep(10) + + elif (mode == 'b'): +# command_control_check() + print("BPSK") + print("turn on FM rx") + output(pd, 1) + output(ptt, 1) + + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 + GPIO.setup(txLed, GPIO.OUT) + + if (command_tx == True): +# system("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | sudo /home/pi/rpitx/sendiq -i /dev/stdin -s 96000 -f 434.9e6 -t float &") + system("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | sudo /home/pi/rpitx/sendiq -i /dev/stdin -s 96000 -f " + tx + "e6 -t float &") + print("Turning LED on/off and listening for carrier") + while 1: + output(txLed, txLedOff) + sleep(0.4) +# if (command_tx == False): +# output(txLed, txLedOn) +# sleep(0.03) +# output(txLed, txLedOff) +# command_control_check() + + if (command_tx == True): + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) +# print(txLed) +# print(txLedOn) + sleep(4.2) + elif (mode == 'e'): # code based on https://zr6aic.blogspot.com/2016/11/creating-2m-fm-repeater-with-raspberry.html + print("Repeater") + print("Stopping command and control") + system("sudo systemctl stop command") + print("turn on FM rx") + output(pd, 1) + output(ptt, 1) + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 + GPIO.setup(txLed, GPIO.OUT) + GPIO.setup(powerPin, GPIO.OUT) + GPIO.setup(squelch, GPIO.IN, pull_up_down=GPIO.PUD_UP) ## pull up in case pin is not connected + GPIO.output(powerPin, 0) + while True: + sleep(0.5) + if (GPIO.input(squelch) == False): + print("Carrier detected, starting repeater") + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) +# system("arecord -D plughw:CARD=Device,DEV=0 | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 &") +## system("arecord -D plughw:CARD=Device,DEV=0 -f S16_LE -r 48000 -c 1 | csdr convert_s16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 &") + system("sudo nc -l 8011 | csdr convert_i16_f | csdr gain_ff 16000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 &") + sleep(1) + system("sudo arecord -D plughw:1 -r48000 -fS16_LE -c1 | nc localhost 8011 &") + GPIO.output(powerPin, 1) + sleep(0.5) + GPIO.output(powerPin, 0) + while (GPIO.input(squelch) == False): + sleep(1) + print("No carrier detected, stopping repeater") + output(txLed, txLedOff) + system("sudo killall -9 arecord") + system("sudo killall -9 nc") + system("sudo killall -9 rpitx") + + else: + print("FSK") + print("turn on FM rx") + output(pd, 1) + output(ptt, 1) + + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 + GPIO.setup(txLed, GPIO.OUT) + + if (command_tx == True): + system("sudo nc -l 8080 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 &") + print("Turning LED on/off and listening for carrier") + while 1: + output(txLed, txLedOff) + sleep(0.4) +# if (command_tx == False): +# output(txLed, txLedOn) +# sleep(0.03) +# output(txLed, txLedOff) +# command_control_check() + if (command_tx == True): + GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 + GPIO.setup(txLed, GPIO.OUT) + output(txLed, txLedOn) +# print(txLed) +# print(txLedOn) + sleep(4.2) + else: + print("No Low Pass Filter so no telemetry transmit. See http://cubesatsim.org/wiki for instructions on how to build the LPF.") + while 1: + sleep(5) diff --git a/update b/update index 53aa19cd1..b2dccbe2e 100755 --- a/update +++ b/update @@ -1,14 +1,25 @@ #!/bin/bash -echo -e "\nupdate script for CubeSatSim v1.2\n" +echo -e "\nupdate script for CubeSatSim v2.0\n" + +if [ "$1" = "n" ] ; then +# if [ -z "$2" ] ; then + noreboot=1 +else + noreboot=0 +fi + +# echo "No reboot" +# echo $noreboot sudo rm /home/pi/CubeSatSim/morse.wav /home/pi/CubeSatSim/id.txt /home/pi/CubeSatSim/cw.txt > /dev/null 2>&1 if [ "$1" = "u" ]; then - sudo apt-get update && sudo apt-get dist-upgrade -y +# sudo apt-get update && sudo apt-get dist-upgrade -y + sudo apt-get update -y - sudo apt-get install -y wiringpi 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 fi @@ -22,12 +33,30 @@ sudo sed -i 's/more information/more\ninformation/g' /etc/motd sudo sed -i 's/update to/update\nto/g' /etc/motd +sudo sed -i 's/console=tty1 r/console=tty1 maxcpus=1 r/g' /boot/cmdline.txt # single core if Pi Zero 2 + cd /home/pi/CubeSatSim -git pull > .updated +git pull --no-rebase > .updated make debug +FILE=/home/pi/CubeSatSim/command_tx +if [ -f "$FILE" ]; then + echo "$FILE exists." +else + echo "creating $FILE" + echo "True\n" > /home/pi/CubeSatSim/command_tx +fi + +FILE=/home/pi/CubeSatSim/command_count.txt +if [ -f "$FILE" ]; then + echo "$FILE exists." +else + echo "creating $FILE" + echo "0\n" > /home/pi/CubeSatSim/command_count.txt +fi + FLAG=0 if [[ $(diff systemd/cubesatsim.service /etc/systemd/system/cubesatsim.service) ]]; then @@ -38,12 +67,41 @@ else echo "no changes to cubesatsim.service." fi -if [[ $(diff systemd/rpitx.service /etc/systemd/system/rpitx.service) ]]; then - echo "changed rpitx.service." - sudo cp /home/pi/CubeSatSim/systemd/rpitx.service /etc/systemd/system/rpitx.service +FILE=/etc/systemd/system/rpitx.service +if [ -f "$FILE" ]; then + sudo systemctl disable rpitx + sudo rm /etc/systemd/system/rpitx.service +fi + +FILE=/etc/systemd/system/transmit.service +if [ -f "$FILE" ]; then + if [[ $(diff systemd/transmit.service /etc/systemd/system/transmit.service) ]]; then + echo "changed transmit.service." + sudo cp /home/pi/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service + FLAG=1 + else + echo "no change to transmit.service." + fi +else + echo "creating transmit.service." + sudo cp /home/pi/CubeSatSim/systemd/transmit.service /etc/systemd/system/transmit.service FLAG=1 +fi + +FILE=/etc/systemd/system/command.service +if [ -f "$FILE" ]; then + if [[ $(diff systemd/command.service /etc/systemd/system/command.service) ]]; then + echo "changed command.service." + sudo cp /home/pi/CubeSatSim/systemd/command.service /etc/systemd/system/command.service + FLAG=1 + else + echo "no change to command.service." + fi else - echo "no changes to rpitx.service." + echo "creating command.service." + sudo cp /home/pi/CubeSatSim/systemd/command.service /etc/systemd/system/command.service + sudo systemctl enable command + FLAG=1 fi FILE=/home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg @@ -64,23 +122,10 @@ if [[ $(grep 'update' /home/pi/CubeSatSim/.updated) ]]; then /home/pi/CubeSatSim/update fi -if [ $FLAG -eq 1 ]; then - echo "systemctl daemon-reload and restart" - sudo systemctl daemon-reload - sudo systemctl restart cubesatsim -else - grep 'changed' /home/pi/CubeSatSim/.updated - if [[ $(grep 'changed' /home/pi/CubeSatSim/.updated) ]]; then - echo "systemctl restart cubesatsim" - sudo systemctl restart cubesatsim - else - echo "nothing to do." - fi -fi - if [ ! -d "/home/pi/PiSSTVpp" ]; then - sudo apt-get update && sudo apt-get dist-upgrade -y +# sudo apt-get update && sudo apt-get dist-upgrade -y + sudo apt-get update -y sudo apt-get install -y python-picamera python3-picamera build-essential libgd-dev libmagic-dev @@ -127,9 +172,66 @@ if [ ! -d "/home/pi/PiSSTVpp" ]; then fi +if [ ! -d "/home/pi/rpitx" ]; then + + cd + git clone https://github.com/alanbjohnston/rpitx.git + cd rpitx + ./install.sh + cd +else + + if [[ $(grep 'SYNCWITHPWM' /home/pi/rpitx/src/librpitx/src/fskburst.h) ]]; then + echo "rpitx library already updated" + else + echo "updating rpitx" + cd /home/pi/rpitx + git pull + ./update.sh + cd + fi +fi + +if [ ! -d "/home/pi/WiringPi" ]; then + + cd + + git clone https://github.com/PinkFreud/WiringPi + cd WiringPi + ./build debian + + sudo dpkg -i debian-template/wiringpi-2.61-1.deb + + cd + + cd CubeSatSim + make debug + + FLAG=1 + + cd + +fi + cd /home/pi/pi-power-button -git pull > .updated_p +git checkout reboot-mode-change-beta > .updated_b + + grep 'error' /home/pi/pi-power-button/.updated_b + if [[ $(grep 'error' /home/pi/pi-power-button/.updated_b) ]]; then + + echo "pi-power-button switching to beta branch" + + git pull + + git checkout reboot-mode-change-beta + + script/install + + FLAG=1 + fi + + 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 @@ -137,23 +239,143 @@ git pull > .updated_p echo "updating pi-power-button." script/install + + FLAG=1 - echo "You need to reboot to complete this update. Reboot now (y/n)?" +# echo "You need to reboot to complete this update. Reboot now (y/n)?" - read -r ANS +# read -r ANS - if [ "$ANS" = "y" ]; then + # if [ "$ANS" = "y" ]; then - sudo reboot now + # sudo reboot now - else + # else - echo "The CubeSatSim software may not work correctly until you reboot." + # echo "The CubeSatSim software may not work correctly until you reboot." - fi + # fi else echo "nothing to do for pi-power-button." fi - - echo "CubeSatSim update complete." + + if [[ $(grep 'dtparam=audio=on' /boot/config.txt) ]]; then + echo "dtparam=audio=on already in /boot/config.txt" + else + echo "adding dtparam=audio=on to /boot/config.txt" + sudo sh -c 'echo "\ndtparam=audio=on" >> /boot/config.txt' + FLAG=1 + fi + + if [[ $(grep 'dtoverlay=audremap,enable_jack=on' /boot/config.txt) ]]; then + echo "dtoverlay=audremap,enable_jack=on already in /boot/config.txt" + else + echo "adding dtoverlay=audremap,enable_jack=on to /boot/config.txt" + sudo sh -c 'echo "\ndtoverlay=audremap,enable_jack=on" >> /boot/config.txt' + FLAG=1 + fi + + if [[ $(grep 'dtoverlay=pwm,pin=18,func=2' /boot/config.txt) ]]; then + echo "dtoverlay=pwm,pin=18,func=2 already in /boot/config.txt" + else + echo "adding dtoverlay=pwm,pin=18,func=2 to /boot/config.txt" + sudo sh -c 'echo "\ndtoverlay=pwm,pin=18,func=2" >> /boot/config.txt' + FLAG=1 + + cd /home/pi/pi-power-button + git pull --no-rebase + git checkout reboot-mode-change + script/install + +# sudo apt-get update && sudo apt-get dist-upgrade -y + sudo apt-get update -y + sudo apt-get install -y libjpeg-dev zlib1g-dev libfreetype6-dev liblcms1-dev libopenjp2-7 libtiff5 python3-pil + sudo pip3 install adafruit-blinka RPI.GPIO adafruit-extended-bus adafruit-circuitpython-ina219 pillow + + fi + + if [[ $(grep 'disable_splash=1' /boot/config.txt) ]]; then + echo "disable_splash=1 already in /boot/config.txt" + else + echo "adding to /boot/config.txt" + sudo sh -c 'echo "\ndisable_splash=1" >> /boot/config.txt' + FLAG=1 + fi + + if [[ $(grep 'boot_delay=0' /boot/config.txt) ]]; then + echo "boot_delay=0 already in /boot/config.txt" + else + echo "adding to /boot/config.txt" + sudo sh -c 'echo "\nboot_delay=0" >> /boot/config.txt' + FLAG=1 + fi + + if ! grep -q force_turbo=1 /boot/config.txt ; then + sudo sh -c 'echo "force_turbo=1" >> /boot/config.txt' + FLAG=1 + fi + +#if [ ! -f "/home/pi/CubeSatSim/telem_string.txt" ]; then + +# sudo apt-get update && sudo apt-get dist-upgrade -y + +# sudo apt-get install -y libjpeg-dev zlib1g-dev libfreetype6-dev liblcms1-dev libopenjp2-7 libtiff5 -y + +# sudo pip3 install pillow + +#fi + +changed=0 +value=`cat /home/pi/CubeSatSim/sim.cfg` +# echo "$value" +echo "$value" > /dev/null +set -- $value + +if [ -z "$1" ] ; then n1="AMSAT" ; changed=1 ; else n1=$1 ; fi # callsign +if [ -z "$2" ] ; then n2="0" ; changed=1 ; else n2=$2 ; fi # reset count +if [ -z "$3" ] ; then n3="0" ; changed=1 ; else n3=$3 ; fi # lat +if [ -z "$4" ] ; then n4="0" ; changed=1 ; else n4=$4 ; fi # lon +if [ -z "$5" ] ; then n5="no" ; changed=1 ; else n5=$5 ; fi # sim mode +if [ -z "$6" ] ; then n6="3" ; changed=1 ; else n6=$6 ; fi # squelch +if [ -z "$7" ] ; then n7="434.9000" ; changed=1 ; else n7=$7 ; fi # transmit frequency +if [ -z "$8" ] ; then n8="435.0000" ; changed=1 ; else n8=$8 ; fi # receive frequency +if [ -z "$9" ] ; then n9="no" ; changed=1 ; else n9=$9 ; fi # hab mode +if [ -z "${10}" ] ; then m1="0" ; changed=1 ; else m1=${10} ; fi # rx pl code +if [ -z "${11}" ] ; then m2="0" ; changed=1 ; else m2=${11} ; fi # tx pl code + +if [ $changed -eq 1 ]; then + echo -e "Current sim.cfg configuration file:" + echo + echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} + echo -e "\nCubeSatSim configuration sim.cfg file updated to: \n" + echo + echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $m1 $m2 + echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $m1 $m2 > /home/pi/CubeSatSim/sim.cfg + echo +fi + +if [ "$noreboot" = "0" ] ; then + + if [ $FLAG -eq 1 ]; then + echo "systemctl daemon-reload and reboot" + sudo systemctl daemon-reload + sudo reboot -h now +# sudo cubesatsim + else + grep 'changed' /home/pi/CubeSatSim/.updated + if [[ $(grep 'changed' /home/pi/CubeSatSim/.updated) ]]; then + echo "reboot due to code changes " | wall + sudo reboot -h now +# sudo cubesatsim + else + echo "nothing to do." + fi + fi +else + if [ $FLAG -eq 1 ]; then + echo "reboot needed for changes to take effect" + fi +fi + +echo "CubeSatSim update complete."