diff --git a/cubesatsim/cubesatsim.h b/cubesatsim/cubesatsim.h index a33b48fe..f3b69de1 100644 --- a/cubesatsim/cubesatsim.h +++ b/cubesatsim/cubesatsim.h @@ -73,7 +73,7 @@ #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 // SR_FRS_05W audio out pin +#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 @@ -126,6 +126,8 @@ #define PROMPT_VOLTAGE 9 #define PROMPT_PAYLOAD 10 #define PROMPT_TEMP 11 +#define PROMPT_FORMAT 12 +#define PROMPT_REBOOT 13 #define PAYLOAD_QUERY 1 #define PAYLOAD_RESET 2 @@ -209,7 +211,9 @@ 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(); #ifndef STASSID #define STASSID "Pico" diff --git a/cubesatsim/cubesatsim.ino b/cubesatsim/cubesatsim.ino index bc6d086f..b00019ea 100644 --- a/cubesatsim/cubesatsim.ino +++ b/cubesatsim/cubesatsim.ino @@ -39,13 +39,16 @@ //#include #include "hardware/gpio.h" #include "hardware/adc.h" -#include "SSTV-Arduino-Scottie1-Library.h" +//#include "SSTV-Arduino-Scottie1-Library.h" #include "LittleFS.h" #include +#include "picosstvpp.h" +#include "pico/bootrom.h" +#include "hardware/watchdog.h" // jpg files to be stored in flash storage on Pico (FS 512kB setting) #include "sstv1.h" -//#include "sstv2.h" +#include "sstv2.h" Adafruit_INA219 ina219_1_0x40; Adafruit_INA219 ina219_1_0x41(0x41); @@ -75,20 +78,27 @@ void setup() { set_sys_clock_khz(133000, true); - Serial.begin(115200); + Serial.begin(115200); + + delay(5000); + + LittleFS.begin(); +// LittleFS.format(); // only format if files of size 0 keep showing up - read_mode(); + read_mode(); + + // mode = BPSK; // force to BPSK new_mode = mode; pinMode(LED_BUILTIN, OUTPUT); - blinkTimes(1); +// blinkTimes(1); - sleep(5.0); +/// sleep(5.0); // otherwise, run CubeSatSim Pico code - Serial.println("CubeSatSim Pico v0.30 starting...\n"); + Serial.println("CubeSatSim Pico v0.33 starting...\n"); config_gpio(); @@ -103,7 +113,7 @@ void setup() { // detect Pi Zero using 3.3V // if Pi is present, run Payload OK software - load_files(); +/// load_files(); /* pinMode(PI_3V3_PIN, INPUT); Serial.print("Pi 3.3V: "); @@ -120,6 +130,8 @@ void setup() { // pinMode(PI_3V3_PIN, OUTPUT); // digitalWrite(PI_3V3_PIN, HIGH); + +// Serial.println("CubeSatSim Pico v0.33 starting...\n"); start_payload(); // above code not working, so forcing it @@ -143,10 +155,10 @@ void setup() { configure_wifi(); } */ - start_button_isr(); +/// start_button_isr(); - setup_sstv(); - +// setup_sstv(); + picosstvpp_begin(26); camera_detected = start_camera(); // start_pwm(); @@ -157,10 +169,13 @@ void setup() { // strcpy(callsign, call); if (mode != CW) transmit_callsign(callsign); - sleep(5.0); +// sleep(5.0); + sleep(1.0); /**/ config_telem(); + +// start_button_isr(); // try before start_isr start_isr(); @@ -208,39 +223,51 @@ void loop() { } } else if (mode == SSTV) - { +{ // first_time_sstv = false; char image_file[128]; if (first_time_sstv) { // if (false) { // turn this off for now - strcpy(image_file, sstv1_filename); +// strcpy(image_file, sstv1_filename); + Serial.println("Using stored image file"); + load_sstv_image_1_as_cam_dot_jpg(); first_time_sstv = false; } else { if (camera_detected = get_camera_image()) { Serial.println("Getting image file"); // Serial.println("Got image file"); - char camera_file[] = "/cam.jpg"; - strcpy(image_file, camera_file); - } else - strcpy(image_file, sstv1_filename); // 2nd stored image - } +// char camera_file[] = "/cam.jpg"; +// strcpy(image_file, camera_file); + } else { +// strcpy(image_file, sstv1_filename); // 2nd stored image + Serial.println("Using stored image file"); + load_sstv_image_2_as_cam_dot_jpg(); + } + } +/* if (debug_mode) { Serial.print("\nSending SSTV image "); print_string(image_file); } +*/ // send_sstv("/cam.raw"); // send_sstv(image_file); // LittleFS.remove("/cam.bin"); - show_dir(); - char output_file2[] = "/cam2.bin"; - jpeg_decode(image_file, output_file2, true); // debug_mode); - show_dir(); - char telem_display[] = " BATT: STATUS: TEMP: "; + show_dir(); + char input_file[] = "/cam.jpg"; +// char output_file2[] = "/cam2.bin"; char output_file[] = "/cam.bin"; +// jpeg_decode(image_file, output_file, true); // debug_mode); + jpeg_decode(input_file, output_file, true); // debug_mode); + show_dir(); +// char telem_display[] = " BATT: STATUS: TEMP: "; + digitalWrite(PTT_PIN, HIGH); // shouldn't need this but - rotate_image(output_file2, output_file, telem_display); - show_dir(); +// rotate_image(output_file2, output_file, telem_display); +// show_dir(); + + picosstvpp(); if (debug_mode) Serial.println("Start transmit!!!"); @@ -249,20 +276,27 @@ void loop() { digitalWrite(LED_BUILTIN, HIGH); digitalWrite(MAIN_LED_BLUE, HIGH); - scottie1_transmit_file(output_file, debug_mode); - +// scottie1_transmit_file(output_file, debug_mode); + +// ITimer1.stopTimer(); // turn off pushbutton timer +/// ITimer1.disableTimer(); // turn off pushbutton timer + play_pwm_file(26); +// ITimer1.restartTimer(); // turn back on pushbutton timer +/// ITimer1.enableTimer(); // turn back on pushbutton timer if (debug_mode) Serial.println("Stop transmit!"); digitalWrite(PTT_PIN, HIGH); // stop transmit // if (!wifi) - digitalWrite(LED_BUILTIN, HIGH); + digitalWrite(LED_BUILTIN, LOW); digitalWrite(MAIN_LED_BLUE, LOW); if (debug_mode) Serial.println("\nImage sent!"); + } else Serial.println("Unknown mode!"); + // while ((millis() - sampleTime) < ((unsigned int)samplePeriod)) // - 250)) // was 250 100 while ((millis() - sampleTime) < ((unsigned int)frameTime)) // - 250)) // was 250 100 @@ -285,24 +319,60 @@ void loop() { digitalWrite(MAIN_LED_BLUE, HIGH); } + + 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(); + + 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"); - mode = new_mode; // change modes if button pressed - write_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(); +/* +// if ((mode == BPSK) || ((new_mode == FSK) && (old_mode == CW))) { + if (mode == BPSK) { + config_telem(); // run this before cw only for BPSK mode + config_done = true; + } +*/ + Serial.println("Rebooting..."); + watchdog_reboot (0, SRAM_END, 10); // restart Pico + + sleep(20.0); + if (new_mode != CW) transmit_callsign(callsign); - sleep(0.5); - config_telem(); + sleep(0.5); + + if (!config_done) + config_telem(); // run this here for all other modes + config_radio(); - sampleTime = (unsigned int) millis(); - } + if ((mode == FSK) || (mode == BPSK)) { + digitalWrite(LED_BUILTIN, HIGH); + digitalWrite(MAIN_LED_BLUE, HIGH); + } - if (prompt) { -// Serial.println("Need to prompt for input!"); - prompt_for_input(); - prompt = false; - } + sampleTime = (unsigned int) millis(); + } // Calculate loop time if (debug_mode) { @@ -508,7 +578,7 @@ void transmit_on() { clockgen.enableOutputs(true); Serial.println("Enable clock outputs!"); } else { - Serial.println("Enable clock outputs!"); + Serial.println("Enable clock outputs"); } } else if (mode == CW) { @@ -524,6 +594,7 @@ void transmit_off() { if (debug_mode) Serial.println("Transmit off!"); digitalWrite(MAIN_LED_BLUE, LOW); + digitalWrite(LED_BUILTIN, LOW); if ((mode == BPSK) || (mode == FSK)) { digitalWrite(BPSK_CONTROL_A, LOW); digitalWrite(BPSK_CONTROL_B, LOW); @@ -543,7 +614,7 @@ void transmit_off() { clockgen.enableOutputs(false); Serial.println("Disable clock outputs!"); } else { - Serial.println("Disable clock outputs!"); + Serial.println("Disable clock outputs"); } } @@ -655,8 +726,9 @@ void config_telem() { frameTime = 5000; bufLen = 1000; } else if (mode == SSTV) { +// ITimer1.stopTimer(); // turn off pushbutton timer Serial.println("\nConfiguring for SSTV"); - set_sstv_pin(AUDIO_OUT_PIN); +// set_sstv_pin(AUDIO_OUT_PIN); samplePeriod = 5000; frameTime = 5000; bufLen = 1000; @@ -2429,7 +2501,7 @@ void start_payload() { Serial.println("Starting payload!"); blink_setup(); - +/* blink(500); sleep(0.25); // delay(250); blink(500); @@ -2440,7 +2512,8 @@ void start_payload() { led_set(blueLED, HIGH); sleep(0.25); // delay(250); led_set(blueLED, LOW); - +*/ + if (bme.begin()) { bmePresent = 1; } else { @@ -2536,7 +2609,7 @@ void read_payload() // if ((Serial.available() > 0)|| first_time == true) { - blink(50); +// blink(50); char result = Serial.read(); char header[] = "OK BME280 "; char str[100]; @@ -2675,7 +2748,7 @@ void read_payload() if (Serial1.available() > 0) { - blink(50); +// blink(50); char result = Serial1.read(); // Serial1.println(result); @@ -2974,33 +3047,11 @@ void blink_setup() 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_RP2040 - digitalWrite(25, LOW); // set the built-in LED ON -#endif + digitalWrite(LED_BUILTIN, HIGH); // set the built-in LED ON sleep(length/1000.0); // delay(length); // wait for a lenth of time -#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_RP2040 - digitalWrite(25, HIGH); // set the built-in LED off -#endif + digitalWrite(LED_BUILTIN, LOW); // set the built-in LED off } void led_set(int ledPin, bool state) @@ -3294,6 +3345,7 @@ void process_pushbutton() { if (pb_value == RELEASED) { Serial.println("PB: Reboot!"); release = TRUE; + prompt = PROMPT_REBOOT; } blinkTimes(1); @@ -3368,12 +3420,14 @@ void process_pushbutton() { digitalWrite(MAIN_LED_GREEN, LOW); sleep(0.5); digitalWrite(MAIN_LED_GREEN, HIGH); - sleep(0.5); - + sleep(0.5); + } if (new_mode != mode) transmit_off(); sleep(2.0); + + digitalWrite(LED_BUILTIN, LOW); // make sure built-in LED is off } void process_bootsel() { @@ -3391,6 +3445,7 @@ void process_bootsel() { if (!BOOTSEL) { Serial.println("BOOTSEL: Reboot!"); release = TRUE; + prompt = PROMPT_REBOOT; } blinkTimes(1); @@ -3466,11 +3521,12 @@ void process_bootsel() { sleep(0.5); digitalWrite(MAIN_LED_GREEN, HIGH); sleep(0.5); - - } + } if (new_mode != mode) transmit_off(); // sleep(2.0); + + digitalWrite(LED_BUILTIN, LOW); // make sure built-in LED is off } void blinkTimes(int blinks) { @@ -3505,6 +3561,7 @@ void config_gpio() { // set LEDs and blink once // if (!wifi) + Serial.println("Blinking pins"); pinMode(LED_BUILTIN, OUTPUT); // Set LED pin to output pinMode(MAIN_LED_GREEN, OUTPUT); // Set Main Green LED pin to output blink_pin(MAIN_LED_GREEN, 150); @@ -3659,7 +3716,7 @@ void start_button_isr() { Serial.println("Starting pushbutton ISR"); - if (ITimer1.attachInterruptInterval(10000, TimerHandler1)) + if (ITimer1.attachInterruptInterval(10000, TimerHandler1)) { if (debug_mode) Serial.print(F("Starting ITimer1 OK, micros() = ")); @@ -3849,7 +3906,7 @@ void transmit_callsign(char *callsign) { program_radio(); } */ - transmit_off(); +/// transmit_off(); transmit_string(id); // transmit_on(); } @@ -3859,7 +3916,8 @@ void transmit_string(char *string) { if (debug_mode) Serial.println("Transmit on"); digitalWrite(PD_PIN, HIGH); // Enable SR_FRS - digitalWrite(MAIN_LED_BLUE, HIGH); + digitalWrite(MAIN_LED_BLUE, HIGH); + digitalWrite(LED_BUILTIN, HIGH); digitalWrite(PTT_PIN, LOW); while ((string[j] != '\0') && (j < 256) && !cw_stop) { @@ -3871,19 +3929,23 @@ void transmit_string(char *string) { // Serial.println("space between words"); sleep((6.0 * (float)morse_timing)/1000.0); j++; - + if (Serial.available() || BOOTSEL || !digitalRead(10)) // check for button press of serial input + cw_stop = true; +/* if (prompt) { // Serial.println("Need to prompt for input!"); prompt_for_input(); prompt = false; - } + } +*/ } } cw_stop = false; if (debug_mode) Serial.println("Transmit off"); - digitalWrite(MAIN_LED_BLUE, LOW); + digitalWrite(MAIN_LED_BLUE, LOW); + digitalWrite(LED_BUILTIN, LOW); digitalWrite(PTT_PIN, HIGH); digitalWrite(PD_PIN, LOW); // disable SR_FRS } @@ -3951,19 +4013,44 @@ void show_dir() { Serial.println(">"); } +void load_sstv_image_1_as_cam_dot_jpg() { + LittleFS.begin(); + File f; + Serial.println("Loading image sstv_image_1_320_x_240.jpg into FS"); + f = LittleFS.open("cam.jpg", "w+"); + if (f.write(sstv_image_1_320_x_240, sizeof(sstv_image_1_320_x_240)) < sizeof(sstv_image_1_320_x_240)) { + Serial.println("Loading image failed. Is Flash Size (FS) set to 1MB?"); + delay(2000); + } + f.close(); +} + +void load_sstv_image_2_as_cam_dot_jpg() { + LittleFS.begin(); + File f; + Serial.println("Loading image sstv_image_2_320_x_240.jpg into FS"); + f = LittleFS.open("cam.jpg", "w+"); + if (f.write(sstv_image_2_320_x_240, sizeof(sstv_image_2_320_x_240)) < sizeof(sstv_image_2_320_x_240)) { + Serial.println("Loading image failed. Is Flash Size (FS) set to 1MB?"); + delay(2000); + } + f.close(); +} + void load_files() { LittleFS.begin(); File f; f = LittleFS.open("sstv_image_1_320_x_240.jpg", "r"); - if (f) { +// if (f) { + if (false) { Serial.println("Image sstv_image_1_320_x_240.jpg already in FS"); f.close(); } else { Serial.println("Loading image sstv_image_1_320_x_240.jpg into FS"); f = LittleFS.open("sstv_image_1_320_x_240.jpg", "w+"); if (f.write(sstv_image_1_320_x_240, sizeof(sstv_image_1_320_x_240)) < sizeof(sstv_image_1_320_x_240)) { - Serial.println("Loading image failed. Is Flash Size (FS) set to 512kB?"); + Serial.println("Loading image failed. Is Flash Size (FS) set to 1MB?"); delay(2000); } f.close(); @@ -3977,7 +4064,7 @@ void load_files() { Serial.println("Loading image sstv_image_2_320_x_240.jpg into FS"); f = LittleFS.open("sstv_image_2_320_x_240.jpg", "w+"); if (f.write(sstv_image_2_320_x_240, sizeof(sstv_image_2_320_x_240)) < sizeof(sstv_image_2_320_x_240)) { - Serial.println("Loading image failed. Is Flash Size (FS) set to 512kB?"); + Serial.println("Loading image failed. Is Flash Size (FS) set to 1MB?"); delay(2000); } f.close(); @@ -4033,8 +4120,11 @@ void serial_input() { new_mode = CW; break; - case 'f': case 'F': + Serial.println("Formatting flash memory"); + prompt = PROMPT_FORMAT; + break; + case 'f': Serial.println("Change to FSK mode"); new_mode = FSK; break; @@ -4260,6 +4350,21 @@ void prompt_for_input() { read_ina219(); break; + case PROMPT_REBOOT: + Serial.println("Rebooting..."); + watchdog_reboot (0, SRAM_END, 10); // 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..."); + watchdog_reboot (0, SRAM_END, 10); // restart Pico + sleep(20.0); + break; + case PROMPT_PAYLOAD: Serial.println("Resetting the Payload"); payload_command = PAYLOAD_RESET; diff --git a/cubesatsim/sstv2.h b/cubesatsim/sstv2.h index 912c833a..d8e6cb32 100644 --- a/cubesatsim/sstv2.h +++ b/cubesatsim/sstv2.h @@ -24,6 +24,7 @@ #include const uint8_t sstv_image_2_320_x_240[] PROGMEM = { +//const uint8_t sstv_image_1_320_x_240[] PROGMEM = { 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x8F, 0x00, 0x8F, 0x00, 0x00, 0xFF, 0xE2, 0x10, 0x08, 0x49, 0x43, 0x43, 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0F, 0xF8, 0x61, 0x70, 0x70, 0x6C, 0x02, 0x10,