CobraV2/sender_module/sender_module.ino
2024-06-03 20:57:13 +02:00

237 lines
4.9 KiB
C++

#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Adafruit_INA219.h>
#include "DEV_Config.h"
#include "L76X.h"
#include "Waveshare_10Dof-D.h"
// Define pin numbers for modules
const int NRF_CE_PIN = 9;
const int NRF_CS_PIN = 8;
const byte address[6] = "00001";
const int GPS_TX_PIN = 0;
const int GPS_RX_PIN = 1;
//const String INA219_SDA_PIN = "A4";
//const String INA219_SCL_PIN = "A5";
const int BUZZER_PIN = 7;
const int READY_STAGE_PIN = 5;
const int LAUNCH_STAGE_PIN = 6;
// Create objects for modules
RF24 radio(NRF_CE_PIN, NRF_CS_PIN);
GNRMC GPS1;
//Adafruit_INA219 ina219;
File dataFile;
// Flight stages
enum FlightStage {
READY,
ARM,
ASCENT,
DESCENT,
LANDED
};
FlightStage current_stage = READY;
void setup() {
// Initialize Serial
Serial.begin(115200);
Serial.println("# Welcome to CobraV2 operating system for rocket");
delay(1000);
// Buzzer pin
pinMode(BUZZER_PIN, OUTPUT);
pinMode(READY_STAGE_PIN, INPUT);
// Start with preflight stage
current_stage = READY;
delay(1000);
}
void loop() {
switch (current_stage) {
case READY:
ready_stage();
break;
case ARM:
arm_stag();
break;
case ASCENT:
ascent_stage();
break;
case DESCENT:
descent_stage();
break;
case LANDED:
landed_stage();
break;
}
}
void ready_stage() {
Serial.println("# READY stage");
int counter = 0;
while (true) {
int state = digitalRead(READY_STAGE_PIN);
if (state == HIGH) {
counter = 0;
} else {
counter += 1;
delay(300)
}
if (counter == 10) {
Serial.println("# Pin disconnected");
break;
}
}
current_stage = READY;
}
void arm_stage() {
// System check
// Block parachute ejection
// Wait for launch pin removed
// Start sending data
Serial.println("# READY stage");
// Radio
if (!radio.begin()) {
Serial.println("# Fail nRF24L01 init");
} else {
radio.openWritingPipe(address);
radio.stopListening(); // Set module as transmitter
const char msg[] = "# Radio connection activated";
radio.write(&msg, sizeof(msg));
Serial.println("# Success nRF24L01 init");
}
// GPS
DEV_Set_Baudrate(9600);
DEV_Delay_ms(500);
// IMU
IMU_EN_SENSOR_TYPE enMotionSensorType, enPressureType;
imuInit(&enMotionSensorType, &enPressureType);
if (IMU_EN_SENSOR_TYPE_ICM20948 == enMotionSensorType) {
Serial.println("# Success ICM-20948 init");
Serial.println(IMU_EN_SENSOR_TYPE_ICM20948);
} else {
Serial.println("# Fail ICM-20948 init");
}
if (IMU_EN_SENSOR_TYPE_BMP280 == enPressureType) {
Serial.println("# Success BMP280 init");
} else {
Serial.println("# Fail BMP280 init");
Serial.println(enPressureType);
}
// INA219
// if (!ina219.begin()) {
// Serial.println("# Fail INA219 sensor init");
// } else {
// Serial.println("# Success INA219 sensor init");
// }
// SD card
if (!SD.begin(4)) {
Serial.println("# Fail SD module init");
} else {
Serial.println("# Success SD module init");
}
if (SD.exists("data.txt")) {
Serial.println("# File exists");
} else {
Serial.println("# File does not exist");
}
dataFile = SD.open("data.txt", FILE_WRITE);
if (dataFile) {
Serial.println("# File opened");
dataFile.println("# CobraV2 flight data");
} else {
Serial.println("# Error opening file");
}
// Buzzer
tone(BUZZER_PIN, 1000);
delay(1000);
noTone(BUZZER_PIN);
// Check battery level
// float batteryLevel = getBatteryLevel();
// Serial.print("# Battery level: ");
// Serial.print(batteryLevel);
// Serial.println("%");
// Check for launch pin
int counter = 0;
while (true) {
int state = digitalRead(LAUNCH_STAGE_PIN);
if (state == HIGH) {
counter = 0;
} else {
counter += 1;
delay(300)
}
if (counter == 10) {
Serial.println("# Pin disconnected");
break;
}
}
current_stage = ASCENT;
}
void ascent_stage() {
// Launch
// Start sending and saving data on SD card
// Check for apogee
// Eject parachute
}
void descent_stage() {
// Detect apogee with accelerometer
// Eject parachute
// GPS and height check
}
void landed_stage() {
// Check for zero velocity
// Shut down unneeded systems
// Buzz on
// Send GPS location
// Battery check
// Turn off gyro and accelerometer
}
float getBatteryLevel() {
// Read bus voltage from INA219
float busVoltage = ina219.getBusVoltage_V();
// Assuming fully charged battery voltage is 4.2V and empty is 3.0V
float maxVoltage = 4.2;
float minVoltage = 3.0;
// Map the bus voltage to a battery level percentage
float batteryLevel = map(busVoltage, minVoltage, maxVoltage, 0, 100);
// Constrain the battery level to be within 0 and 100
batteryLevel = constrain(batteryLevel, 0, 100);
return batteryLevel;
}