N4 Flight Software N4
Flight software used for the N4 flight computers
Loading...
Searching...
No Matches
main.cpp File Reference

This contains the main driver code for the flight computer. More...

#include <Arduino.h>
#include <Wire.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <TinyGPSPlus.h>
#include <SFE_BMP180.h>
#include <FS.h>
#include <SD.h>
#include <SPIFFS.h>
#include "defs.h"
#include "mpu.h"
#include "SerialFlash.h"
#include "logger.h"
#include "data_types.h"
#include "custom_time.h"
#include "states.h"
#include "system_logger.h"
#include "system_log_levels.h"
#include "wifi-config.h"

Macros

#define BAUDRATE   115200
 
#define NAK_INTERVAL   4000
 
#define SOH   0x01
 
#define EOT   0x04
 
#define ACK   0x06
 
#define NAK   0x15
 
#define CAN   0x18
 
#define MAX_CMD_LENGTH   10
 
#define MAX_CSV_LENGTH   256
 
#define FORMAT_SPIFFS_IF_FAILED   1
 
#define TRANSMIT_TELEMETRY_BIT   ((EventBits_t) 0x01 << 0)
 
#define CHECK_FLIGHT_STATE_BIT   ((EventBits_t) 0x01 << 1)
 
#define LOG_TO_MEMORY_BIT   ((EventBits_t) 0x01 << 2)
 
#define TRANSMIT_XBEE_BIT   ((EventBits_t) 0x01 << 3)
 
#define DEBUG_TO_TERM_BIT   ((EventBits_t) 0x01 << 4)
 
#define ALTITUDE   1525.0
 

Enumerations

enum  TEST_STATE { HANDSHAKE = 0 , RECEIVE_TEST_DATA , CONFIRM_TEST_DATA }
 This enum holds the states during flight computer test mode. More...
 

Functions

void drogueChuteDeploy ()
 fires the pyro-charge to deploy the drogue chute Turn on the drogue chute ejection circuit by running the GPIO HIGH for a preset No. of seconds.
Default no. of seconds to remain HIGH is 5
 
void mainChuteDeploy ()
 fires the pyro-charge to deploy the main chute Turn on the main chute ejection circuit by running the GPIO HIGH for a preset No. of seconds.
Default no. of seconds to remain HIGH is 5
 
void listDir (fs::FS &fs, const char *dirname, uint8_t levels)
 
void initGPIO ()
 Inititialize the GPIOs.
 
void InitSPIFFS ()
 
void initSD ()
 
void SwitchLEDs (uint8_t red_state, uint8_t green_state)
 Switch the LEDS states.
 
void InitXMODEM ()
 Initiate XMODEM protocol by sending a NAK command every 4 seconds until the transmitter returns an ACK signal.
 
void SerialEvent ()
 
void ParseSerial (char *)
 
void checkRunTestToggle ()
 Sample the RUN/TEST toggle pins to check whether the fligh tcomputer is in test mode or run mode. If in TEST mode, define the TEST flag If in RUN mode, define the RUN flag TEST_MODE Pin and RUN_MODE pin are both pulled HIGH. When you set the jumper, you pull that pin to LOW.
 
void readFile (fs::FS &fs, const char *path)
 
void writeFile (fs::FS &fs, const char *path, const char *message)
 
void appendFile (fs::FS &fs, const char *path, const char *message)
 
void deleteFile (fs::FS &fs, const char *path)
 
void readTestDataFile ()
 
void buzz ()
 Buzz the buzzer for a given buzz_interval This function is non-blocking.
 
void blink_200ms (uint8_t led_pin)
 implements non-blocking blink
 
void ParseSerialBuffer (char *buffer)
 
void ParseSerialNumeric (int value)
 Parse the received serial command if it is a digit We are only interested in numeric values being sent by the transmitter to us, the receiver.
 
void handshakeSerialEvent ()
 Receive serial message during handshake.
 
void receiveTestDataSerialEvent ()
 Receive serial message during RECEIVE_TEST_DATA state Data received in this state is the actual test data. It is saved into the test flash memory.
 
void BMPInit ()
 Initialize BMP180 barometric sensor.
 
void GPSInit ()
 Initialize the GPS connected on Serial2.
 
void readAccelerationTask (void *pvParameter)
 Read acceleration data from the accelerometer.
 
void readAltimeterTask (void *pvParameters)
 Read ar pressure data from the barometric sensor onboard.
 
void readGPSTask (void *pvParameters)
 Read the GPS location data and altitude and append to telemetry packet for transmission.
 
void clearTelemetryQueueTask (void *pvParameters)
 dequeue data from telemetry queue after all the tasks have consumed the data
 
void checkFlightState (void *pvParameters)
 Check and update the current state of flight - refer to states.h.
 
void flightStateCallback (void *pvParameters)
 performs flight actions based on the current flight state If the flight state neccessisates an operation, we perform it here For example if the flight state is apogee, we perform MAIN_CHUTE ejection
 
void debugToTerminalTask (void *pvParameters)
 debug flight/test data to terminal, this task is called if the DEBUG_TO_TERMINAL is set to 1 (see defs.h)
 
void logToMemory (void *pvParameter)
 log the data to the external flash memory
 
void MQTT_TransmitTelemetry (void *pvParameters)
 send flight data to ground
 
void MQTT_Reconnect ()
 Try reconnecting to MQTT if connection is lost.
 
void MQTTInit (const char *broker_IP, int broker_port)
 Initialize MQTT.
 
void setup ()
 Setup - perform initialization of all hardware subsystems, create queues, create queue handles initialize system check table.
 
void loop ()
 Main loop.
 

Variables

uint8_t operation_mode = 0
 
uint8_t current_state = FLIGHT_STATE::PRE_FLIGHT_GROUND
 
TinyGPSPlus gps
 
SystemLogger system_logger
 
const char * system_log_file = "/sys_log.log"
 
LOG_LEVEL level = INFO
 
const char * rocket_ID = "rocket-1"
 
uint8_t RUN_MODE = 0
 
uint8_t TEST_MODE = 0
 
uint8_t SOH_recvd_flag = 0
 
unsigned long last_NAK_time = 0
 
unsigned long current_NAK_time = 0
 
char SOH_CHR [6] = "SOH"
 
char serial_buffer [MAX_CMD_LENGTH]
 
int16_t serial_index = 0
 
char test_data_buffer [MAX_CSV_LENGTH]
 
int16_t test_data_serial_index = 0
 
uint8_t recv_data_led = 2
 
uint8_t red_led = 15
 
uint8_t green_led = 4
 
uint8_t buzzer = 33
 
uint8_t SET_TEST_MODE_PIN = 14
 
uint8_t SET_RUN_MODE_PIN = 13
 
uint8_t SD_CS_PIN = 26
 
uint8_t current_test_state = TEST_STATE::HANDSHAKE
 
const char * test_data_file = "/data.csv"
 
unsigned long last_buzz = 0
 
unsigned long current_buzz = 0
 
unsigned long buzz_interval = 200
 
uint8_t buzzer_state = LOW
 
unsigned long last_blink = 0
 
unsigned long current_blink = 0
 
unsigned long blink_interval = 200
 
uint8_t led_state = LOW
 
int value = 0
 Parse the received serial command if it is a string.
 
WIFIConfig wifi_config
 
uint8_t drogue_pyro = 25
 
uint8_t main_pyro = 12
 
uint8_t flash_cs_pin = 5
 
uint8_t remote_switch = 27
 
uint8_t flash_led_pin = 32
 
char filename [] = "flight.bin"
 
uint32_t FILE_SIZE_512K = 524288L
 
uint32_t FILE_SIZE_1M = 1048576L
 
uint32_t FILE_SIZE_4M = 4194304L
 
SerialFlashFile file
 
unsigned long long previous_log_time = 0
 
unsigned long long current_log_time = 0
 
uint16_t log_sample_interval = 10
 
DataLogger data_logger (flash_cs_pin, flash_led_pin, filename, file, FILE_SIZE_4M)
 
long long current_time = 0
 
long long previous_time = 0
 
EventGroupHandle_t tasksDataReceiveEventGroup
 
accel_type_t acc_data
 
gyro_type_t gyro_data
 
gps_type_t gps_data
 
altimeter_type_t altimeter_data
 
telemetry_type_t telemetry_packet
 
MPU6050 imu (0x68, 16, 1000)
 
SFE_BMP180 altimeter
 
char status
 
double T
 
double P
 
double p0
 
double a
 
QueueHandle_t telemetry_data_qHandle
 
QueueHandle_t accel_data_qHandle
 
QueueHandle_t altimeter_data_qHandle
 
QueueHandle_t gps_data_qHandle
 

Detailed Description

This contains the main driver code for the flight computer.

Author
Edwin Mwiti
Version
0.1
Date
July 15 2024

0x5765206D6179206D616B65206F757220706C616E73202C 0x62757420476F642068617320746865206C61737420776F7264

Macro Definition Documentation

◆ ACK

#define ACK   0x06

positive acknowledgement

◆ CAN

#define CAN   0x18

cancel

◆ EOT

#define EOT   0x04

end of transmission

◆ MAX_CMD_LENGTH

#define MAX_CMD_LENGTH   10

Maximum length of the XMODEM command string that can be received

◆ MAX_CSV_LENGTH

#define MAX_CSV_LENGTH   256

Maximum length of the csv string that can be received

◆ NAK

#define NAK   0x15

negative acknowledgement

◆ NAK_INTERVAL

#define NAK_INTERVAL   4000

Interval in which to send the NAK command to the transmitter

◆ SOH

#define SOH   0x01

start of header

◆ TRANSMIT_TELEMETRY_BIT

#define TRANSMIT_TELEMETRY_BIT   ((EventBits_t) 0x01 << 0)

Task synchronization variables

Enumeration Type Documentation

◆ TEST_STATE

enum TEST_STATE

This enum holds the states during flight computer test mode.


Enumerator
HANDSHAKE 

state to establish initial communication with transmitter

RECEIVE_TEST_DATA 

sets the flight computer to receive test data over serial

Function Documentation

◆ blink_200ms()

void blink_200ms ( uint8_t led_pin)

implements non-blocking blink


◆ BMPInit()

void BMPInit ( )

Initialize BMP180 barometric sensor.


Returns
TODO: 1 if init OK, 0 otherwise

◆ buzz()

void buzz ( )

Buzz the buzzer for a given buzz_interval This function is non-blocking.


◆ checkFlightState()

void checkFlightState ( void * pvParameters)

Check and update the current state of flight - refer to states.h.


Parameters
pvParameters- A value that is passed as the parameter to the created task. If pvParameters is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.
Returns
Updates the telemetry data flight state value

◆ checkRunTestToggle()

void checkRunTestToggle ( )

Sample the RUN/TEST toggle pins to check whether the fligh tcomputer is in test mode or run mode. If in TEST mode, define the TEST flag If in RUN mode, define the RUN flag TEST_MODE Pin and RUN_MODE pin are both pulled HIGH. When you set the jumper, you pull that pin to LOW.


◆ clearTelemetryQueueTask()

void clearTelemetryQueueTask ( void * pvParameters)

dequeue data from telemetry queue after all the tasks have consumed the data


Parameters
pvParameters- A value that is passed as the parameter to the created task. If pvParameters is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.
Returns
none

◆ debugToTerminalTask()

void debugToTerminalTask ( void * pvParameters)

debug flight/test data to terminal, this task is called if the DEBUG_TO_TERMINAL is set to 1 (see defs.h)


Parameters
pvParameter- A value that is passed as the parameter to the created task. If pvParameter is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.

◆ drogueChuteDeploy()

void drogueChuteDeploy ( )

fires the pyro-charge to deploy the drogue chute Turn on the drogue chute ejection circuit by running the GPIO HIGH for a preset No. of seconds.
Default no. of seconds to remain HIGH is 5


◆ flightStateCallback()

void flightStateCallback ( void * pvParameters)

performs flight actions based on the current flight state If the flight state neccessisates an operation, we perform it here For example if the flight state is apogee, we perform MAIN_CHUTE ejection


Parameters
pvParameter- A value that is passed as the parameter to the created task. If pvParameter is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.

◆ GPSInit()

void GPSInit ( )

Initialize the GPS connected on Serial2.


Returns
1 if init OK, 0 otherwise

◆ handshakeSerialEvent()

void handshakeSerialEvent ( )

Receive serial message during handshake.


◆ initGPIO()

void initGPIO ( )

Inititialize the GPIOs.


◆ InitXMODEM()

void InitXMODEM ( )

Initiate XMODEM protocol by sending a NAK command every 4 seconds until the transmitter returns an ACK signal.

XMODEM serial function definition


Parameters
none

◆ listDir()

void listDir ( fs::FS & fs,
const char * dirname,
uint8_t levels )

XMODEM serial function prototypes

◆ logToMemory()

void logToMemory ( void * pvParameter)

log the data to the external flash memory


Parameters
pvParameter- A value that is passed as the paramater to the created task. If pvParameter is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.

◆ loop()

void loop ( )

Main loop.


◆ mainChuteDeploy()

void mainChuteDeploy ( )

fires the pyro-charge to deploy the main chute Turn on the main chute ejection circuit by running the GPIO HIGH for a preset No. of seconds.
Default no. of seconds to remain HIGH is 5


◆ MQTT_TransmitTelemetry()

void MQTT_TransmitTelemetry ( void * pvParameters)

send flight data to ground


Parameters
pvParameter- A value that is passed as the paramater to the created task. If pvParameter is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.

◆ MQTTInit()

void MQTTInit ( const char * broker_IP,
int broker_port )

Initialize MQTT.


◆ ParseSerialNumeric()

void ParseSerialNumeric ( int value)

Parse the received serial command if it is a digit We are only interested in numeric values being sent by the transmitter to us, the receiver.


◆ readAccelerationTask()

void readAccelerationTask ( void * pvParameter)

Read acceleration data from the accelerometer.


Parameters
pvParameters- A value that is passed as the paramater to the created task. If pvParameters is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.
Returns
Updates accelerometer data struct on the telemetry queue

◆ readAltimeterTask()

void readAltimeterTask ( void * pvParameters)

Read ar pressure data from the barometric sensor onboard.


Parameters
pvParameters- A value that is passed as the parameter to the created task. If pvParameters is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.
Returns
Sends altimeter data to altimeter queue

◆ readGPSTask()

void readGPSTask ( void * pvParameters)

Read the GPS location data and altitude and append to telemetry packet for transmission.


Parameters
pvParameters- A value that is passed as the paramater to the created task. If pvParameters is set to the address of a variable then the variable must still exist when the created task executes - so it is not valid to pass the address of a stack variable.

◆ receiveTestDataSerialEvent()

void receiveTestDataSerialEvent ( )

Receive serial message during RECEIVE_TEST_DATA state Data received in this state is the actual test data. It is saved into the test flash memory.


◆ setup()

void setup ( )

Setup - perform initialization of all hardware subsystems, create queues, create queue handles initialize system check table.


◆ SwitchLEDs()

void SwitchLEDs ( uint8_t red_state,
uint8_t green_state )

Switch the LEDS states.


Variable Documentation

◆ acc_data

accel_type_t acc_data

///////////////////////// DATA TYPES /////////////////////////

◆ current_log_time

unsigned long long current_log_time = 0

What is the processor time right now?

◆ current_state

uint8_t current_state = FLIGHT_STATE::PRE_FLIGHT_GROUND

The starting state - we start at PRE_FLIGHT_GROUND state

◆ current_test_state

uint8_t current_test_state = TEST_STATE::HANDSHAKE

Define current state the flight computer is in

◆ file

SerialFlashFile file

object representing file object for flash memory

◆ FILE_SIZE_1M

uint32_t FILE_SIZE_1M = 1048576L

1MB

◆ FILE_SIZE_4M

uint32_t FILE_SIZE_4M = 4194304L

4MB

◆ FILE_SIZE_512K

uint32_t FILE_SIZE_512K = 524288L

512KB

◆ filename

char filename[] = "flight.bin"

data log filename - Filename must be less than 20 chars, including the file extension

◆ flash_cs_pin

uint8_t flash_cs_pin = 5

External flash memory chip select pin

◆ flash_led_pin

uint8_t flash_led_pin = 32

LED pin connected to indicate flash memory formatting

◆ green_led

uint8_t green_led = 4

Green LED pin

◆ imu

MPU6050 imu(0x68, 16, 1000) ( 0x68 ,
16 ,
1000  )

///////////////////////// END OF DATA VARIABLES ///////////////////////// create an MPU6050 object 0x68 is the address of the MPU set gyro to max deg to 1000 deg/sec set accel fs reading to 16g

◆ log_sample_interval

uint16_t log_sample_interval = 10

After how long should we sample and log data to flash memory?

◆ operation_mode

uint8_t operation_mode = 0

Tells whether software is in safe or flight mode - FLIGHT_MODE=1, SAFE_MODE=0

◆ previous_log_time

unsigned long long previous_log_time = 0

The last time we logged data to memory

◆ recv_data_led

uint8_t recv_data_led = 2

External flash memory chip select pin

◆ red_led

uint8_t red_led = 15

Red LED pin

◆ rocket_ID

const char* rocket_ID = "rocket-1"

Unique ID of the rocket. Change to the needed rocket name before uploading

◆ SD_CS_PIN

uint8_t SD_CS_PIN = 26

Chip select pin for SD card

◆ SET_RUN_MODE_PIN

uint8_t SET_RUN_MODE_PIN = 13

Pin to set the flight computer to RUN mode

◆ SET_TEST_MODE_PIN

uint8_t SET_TEST_MODE_PIN = 14

Pin to set the flight computer to TEST mode

◆ SOH_recvd_flag

uint8_t SOH_recvd_flag = 0

Transmitter acknowledged?

◆ telemetry_data_qHandle

QueueHandle_t telemetry_data_qHandle

///////////////////////// END OF PERIPHERALS INIT /////////////////////////

◆ value

int value = 0

Parse the received serial command if it is a string.


◆ wifi_config

WIFIConfig wifi_config

MQTT helper instances, if using MQTT to transmit telemetry