diff --git a/README.md b/README.md index 6b5b2f6e..7d4b2b08 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The CubeSat Simulator https://github.com/alanbjohnston/CubeSatSim/wiki is a low There are several hardware versions and software branches to go with them - see below for information. -See the Wiki Software Install page for more details: https://github.com/alanbjohnston/CubeSatSim/wiki/Software-Install. To build and run the software on a Raspberry Pi 3B, 3B+, or Pi Zero W (doesn't work on Pi 4 since rpitx doesn't work on it yet): +See the Wiki Software Install page for more details: https://github.com/alanbjohnston/CubeSatSim/wiki/Software-Install. To build and run the software on a Raspberry Pi 3B, 3B+, Pi Zero or Pi Zero W (doesn't work on Pi 4 since rpitx doesn't work on it yet): Requires: - Raspbian Stretch or Buster, full desktop or Lite - wiringpi @@ -14,9 +14,15 @@ Requires: - Direwolf - rpitx -See the Wiki Software Install page for more details: https://github.com/alanbjohnston/CubeSatSim/wiki/Software-Install. To build and run the software on a Raspberry Pi 3B, 3B+, or Pi Zero W (Does NOT work on a Pi 4 since rpitx does not work on it yet): +See the Wiki Software Install page for more details: https://github.com/alanbjohnston/CubeSatSim/wiki/Software-Install. Runs on a Raspberry Pi 3B, 3B+, or Pi Zero W (Does NOT work on a Pi 4 since rpitx does not work on it yet). The Pi Zero W or Pi Zero are recommended since they are draw the least power and will result in the best performance under battery power. -`sudo apt-get install -y wiringpi git libasound2-dev i2c-tools` +These instructions assume a Pi Zero W with WiFi connectivity. If you have a Pi Zero, follow these instructions to get connectivity: https://desertbot.io/blog/headless-pi-zero-ssh-access-over-usb-windows + +To begin the software install, after logging in type: + +`sudo apt update -y && sudo apt dist-upgrade -y` + +`sudo apt install -y wiringpi git libasound2-dev i2c-tools` Run raspi-config and enable the I2C bus by selecting Option 5 Interfacing Options and then Option 5 I2C and selecting Y to enable the ARM I2C bus: @@ -80,6 +86,8 @@ Create a sim.cfg configuration file with your amateur radio callsign (in all cap `echo "callsign" >> sim.cfg` +`echo >> .mode` + Compile the code: `make rebuild` @@ -125,6 +133,10 @@ To make the demo.sh script run automatically on boot: `sudo systemctl enable cubesatsim` +`sudo cp ~/CubeSatSim/systemd/rpitx.service /etc/systemd/system/rpitx.service` + +`sudo systemctl enable rpitx` + Now reboot for all the changes to take effect: `sudo reboot now` diff --git a/afsk/main.c b/afsk/main.c index 5b4634a5..2bb8ba99 100644 --- a/afsk/main.c +++ b/afsk/main.c @@ -122,7 +122,7 @@ char call[5]; int bitRate, mode, bufLen, rsFrames, payloads, rsFrameLen, dataLen, headerLen, syncBits, syncWord, parityLen, samples, frameCnt, samplePeriod; float sleepTime; -int sampleTime = 0; +int sampleTime = 0, frames_sent = 0; int cw_id = ON; int vB4 = FALSE, vB5 = FALSE, ax5043 = FALSE, transmit = FALSE, onLed, onLedOn, onLedOff, txLed, txLedOn, txLedOff, payload = OFF; float batteryThreshold = 0; @@ -399,8 +399,14 @@ int main(int argc, char *argv[]) { } 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("Tx LED On\n"); + #endif // if ((cycle == ON) && !ax5043) // don't cycle modes if using AX5043 // mode = (reset_count) % 3; // alternate between the three modes @@ -495,7 +501,7 @@ else //uint8_t data[1024]; tx_freq_hz -= tx_channel * 50000; - +/* if (transmit == FALSE) { @@ -504,7 +510,7 @@ else } // Send ID in CW (Morse Code) - +cw_id = OFF; if (cw_id == ON) // Don't send CW if using AX5043 or in mode cycling or set by 3rd argument { char cw_str[200]; @@ -518,7 +524,10 @@ if (cw_id == ON) // Don't send CW if using AX5043 or in mode cycling or set by 3 strcat(cw_str, cw_footer); //printf("Before 1st strcpy\n"); digitalWrite (txLed, txLedOn); -printf("Before cmd\n"); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif +//printf("Before cmd\n"); //printf("CW String: %s\n", cw_str); // FILE* f; system(cw_str); @@ -528,13 +537,16 @@ printf("After command\n"); // sleep(7); //printf("Before Write\n"); digitalWrite (txLed, txLedOn); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif //printf("After Write\n"); } //printf("Done CW!\n"); - +*/ while (loop-- != 0) { - + frames_sent++; float batteryVoltage = read_sensor_data(sensor[BAT]).voltage; #ifdef DEBUG_LOGGING fprintf(stderr,"INFO: Battery voltage: %f V Battery Threshold %f V\n", batteryVoltage, batteryThreshold); @@ -610,10 +622,16 @@ while (loop-- != 0) if (mode == BPSK) { digitalWrite (txLed, txLedOn); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif printf("Sleeping to allow BPSK transmission to finish.\n"); sleep(loop_count * 5); printf("Done sleeping\n"); digitalWrite (txLed, txLedOff); + #ifdef DEBUG_LOGGING + printf("Tx LED Off\n"); + #endif } else if (mode == FSK) { @@ -621,6 +639,7 @@ while (loop-- != 0) sleep(loop_count); printf("Done sleeping\n"); } +/* // int transmit = popen("timeout 1 sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.897e3","r"); int txResult = popen("sudo killall -9 rpitx > /dev/null 2>&1", "r"); pclose(txResult); @@ -631,7 +650,10 @@ while (loop-- != 0) if(cw_id == ON) // only turn off Power LED if CW ID is enabled (i.e. not demo.sh mode cycling) digitalWrite (onLed, onLedOff); - + #ifdef DEBUG_LOGGING + printf("Tx LED Off\n"); + #endif +*/ return 0; } @@ -681,6 +703,9 @@ int get_tlm(void) { for (int j = 0; j < frameCnt; j++) { digitalWrite (txLed, txLedOn); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif int tlm[7][5]; memset(tlm, 0, sizeof tlm); @@ -801,17 +826,23 @@ for (int j = 0; j < frameCnt; j++) strcat(cw_str2, cw_footer2); //printf("Before 1st strcpy\n"); digitalWrite (txLed, txLedOn); -printf("Before cmd\n"); -printf("CW telem String: %s\n", cw_str2); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif +//printf("Before cmd\n"); +//printf("CW telem String: %s\n", cw_str2); // FILE* f; if (mode == CW) system(cw_str2); // printf("File %d \n", f); // printf("close: %d \n", pclose(f)); // execute command and wait for termination before continuing -printf("After command\n"); +//printf("After command\n"); // sleep(7); //printf("Before Write\n"); digitalWrite (txLed, txLedOn); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif //printf("After Write\n"); //} //printf("Done CW!\n"); @@ -819,7 +850,10 @@ printf("After command\n"); if (ax5043) { digitalWrite (txLed, txLedOn); - fprintf(stderr,"INFO: Transmitting X.25 packet\n"); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif + fprintf(stderr,"INFO: Transmitting X.25 packet using AX5043\n"); memcpy(data, str, strnlen(str, 256)); int ret = ax25_tx_frame(&hax25, &hax5043, data, strnlen(str, 256)); if (ret) { @@ -830,6 +864,9 @@ printf("After command\n"); } ax5043_wait_for_transmit(); digitalWrite (txLed, txLedOff); + #ifdef DEBUG_LOGGING + printf("Tx LED Off\n"); + #endif if (ret) { fprintf(stderr, @@ -856,17 +893,26 @@ printf("After command\n"); fprintf(stderr, " See http://cubesatsim.org/wiki for info about building a CubeSatSim\n\n"); } digitalWrite (txLed, txLedOff); + #ifdef DEBUG_LOGGING + printf("Tx LED Off\n"); + #endif sleep(3); digitalWrite (txLed, txLedOn); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif } //digitalWrite (txLed, txLedOff); } -printf("End of get_tlm and rpitx =========================================================\n"); +//printf("End of get_tlm and rpitx =========================================================\n"); digitalWrite (txLed, txLedOff); + #ifdef DEBUG_LOGGING + printf("Tx LED Off\n"); + #endif return; } @@ -942,11 +988,17 @@ if (firstTime != ON) { // delay for sample period digitalWrite (txLed, txLedOn); + #ifdef DEBUG_LOGGING + printf("Tx LED On\n"); + #endif while ((millis() - sampleTime) < samplePeriod) sleep(sleepTime); digitalWrite (txLed, txLedOff); + #ifdef DEBUG_LOGGING + printf("Tx LED Off\n"); + #endif printf("Sample period: %d\n",millis() - sampleTime); sampleTime = millis(); @@ -1261,7 +1313,7 @@ if (firstTime != ON) // printf("\n"); // rpitx - +/* char cmdbuffer[1000]; FILE* txResult; if ((rpitxStatus != mode)) // || ((loop % 1000) == 0)) @@ -1287,7 +1339,7 @@ if (firstTime != ON) // printf("3\n"); sleep(1); // digitalWrite (txLed, txLedOff); - + if (transmit) { if (mode == FSK) { @@ -1310,6 +1362,7 @@ if (firstTime != ON) sleep(2); // printf("Results of transmit command: %s\n", cmdbuffer); } +*/ // socket write @@ -1379,7 +1432,11 @@ if (firstTime != ON) fprintf(stderr, " See http://cubesatsim.org/wiki for info about building a CubeSatSim\n\n"); } // digitalWrite (0, HIGH); - firstTime = 0; + + if (mode == FSK) + firstTime = 0; + else if (frames_sent > 0) //5) + firstTime = 0; return 0; } diff --git a/demo.sh b/demo.sh index 6a3222ee..7a29a981 100755 --- a/demo.sh +++ b/demo.sh @@ -2,35 +2,15 @@ echo -e "\nDemo of CubeSatSim at 434.9 MHz\n" -#exit +sudo systemctl restart rpitx -y=$(last reboot | grep ^reboot | wc -l) -echo $y - -#if (( $y % 2 == 0 )) -#then - echo -e "\n Continuous Mode\n\n" -# /home/pi/CubeSatSim/radioafsk f - - if [ "$1" = "a" ]; then - echo "Mode is continuous AFSK" - sleep 1 - sudo killall -9 sendiq - sudo killall -9 sendiq - sleep 1 - /home/pi/CubeSatSim/radioafsk afsk - elif [ "$1" = "b" ]; then - echo "Mode is continuous BPSK" - sleep 1 - sudo killall -9 sendiq - sudo killall -9 sendiq - sleep 1 - /home/pi/CubeSatSim/radioafsk bpsk - else - echo "Mode is continuous FSK" - sleep 1 - sudo killall -9 sendiq - sudo killall -9 sendiq - sleep 1 - /home/pi/CubeSatSim/radioafsk fsk - fi +if [ "$1" = "a" ]; then + echo "Mode is continuous AFSK" + /home/pi/CubeSatSim/radioafsk afsk +elif [ "$1" = "b" ]; then + echo "Mode is continuous BPSK" + /home/pi/CubeSatSim/radioafsk bpsk +else + echo "Mode is continuous FSK" + /home/pi/CubeSatSim/radioafsk fsk +fi diff --git a/rpitx.py b/rpitx.py new file mode 100644 index 00000000..bbfecbc4 --- /dev/null +++ b/rpitx.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +import RPi.GPIO as GPIO +import subprocess +import time +import os +import sys + +GPIO.setmode(GPIO.BCM) +GPIO.setwarnings(False) +GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP) +GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP) +transmit = False +if GPIO.input(12) == False: + transmit = True +if GPIO.input(27) == False: + transmit = True + +print(transmit) + +file = open("/home/pi/CubeSatSim/sim.cfg") +callsign = file.readline().split(" ")[0] +print(callsign) + +os.system("echo 'de " + callsign + "' > 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.9e3") + +time.sleep(2) + +if __name__ == "__main__": + print 'Length: ', len(sys.argv) + + if (len(sys.argv)) > 1: +# print("There are arguments!") + if (('a' == sys.argv[1]) or ('afsk' in sys.argv[1])): + print("AFSK") + while True: + time.sleep(5) + elif (('b' == sys.argv[1]) or ('bpsk' in sys.argv[1])): + print("BPSK") + os.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") + else: + print("FSK") + os.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("FSK") + os.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") diff --git a/rpitx.sh b/rpitx.sh new file mode 100755 index 00000000..e2cb4245 --- /dev/null +++ b/rpitx.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +echo -e "\nrpitx for CubeSatSim at 434.9 MHz using python\n" + +python /home/pi/CubeSatSim/rpitx.py $1 diff --git a/systemd/rpitx.service b/systemd/rpitx.service new file mode 100644 index 00000000..c58b7bd1 --- /dev/null +++ b/systemd/rpitx.service @@ -0,0 +1,15 @@ +[Unit] +Description=CubeSatSim rpitx service + +[Service] +TimeoutStopSec=5 +EnvironmentFile=/home/pi/CubeSatSim/.mode +ExecStart=/home/pi/CubeSatSim/rpitx.sh $ARG1 +WorkingDirectory=/home/pi/CubeSatSim +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root + +[Install] +WantedBy=default.target