Ethanol Chamber Pressure Control (C/C++)

An embedded C/C++ feedback system to control chamber pressures before a hotfire.

Summary

  • Developed a real-time closed-loop control system in C/C++ to maintain chamber pressures in case of leaks.
  • Utilized shared memory techniques on the Raspberry Pi to facilitated real-time reception and processing of data from pressure sensors.
  • Implemented an emergency safety interrupt using the "csignal" library, improving crisis management of algorithm.
  • Tested algorithm during a hotfire in October 2023, demonstrating its ability to pressurize and maintain Ethonal/Liquid Oxygen chambers.
  • Skills:

    SFU Rocketry - Liquid Rocket Engine

    The hotfire testing of a Liquid Rocket Engine is its physical activation to measure how powerful the engine is and how each individual system functions. During hotfire testing, the engine is required to have the proper amount of Ethanol, Liquid Oxygen, and Nitrogen in its chambers before firing. Each compound is pressurized within its own chamber before being mixed together at the right time to fire. However, due to unavoidable leakage or delays in actuation, the chamber may be under or over the target pressure (400 PSI) required to fire the engine properly.

    To tackle this problem, alongside the software team, I developed a solution which involves a closed-loop control system in C/C++ to actively read chamber pressures and react accordingly to the measurements. Utilizing shared memory management, a Raspberry Pi 4, and pressure sensors, the algorithm continuously checks the pressure in the Ethanol chamber, and if it is within a specified threshold, it controls the solenoid valves (SOVs) responsible for injecting or venting ethanol within the chamber. Moreover, a safety method using the "csignal" library was put into place to implement an emergency stop.

    Future Plans

    Due to the code's multi-functional ability, it can be implemented on any pressurized tank with potential leaks. For example, the code has been implemented for the Liquid Oxygen tank in a similar manner. However, each code is required to run separately for each tank, which is counterintuitive. To fix this issue, I plan to develop a multi-threaded algorithm that is capable of running each script concurrently with only one press of a button.

    Code Snippet

    
    while (true) { // Run this code until you wish to stop process with Ctrl + C
    
        currPress = shared_mem->PT_states[PT1]; // Check current pressure of chamber through sensors
    
        if (!pressurized) { // When chamber is not pressurized....
            if (currPress >= targetPress) { // Check to see if chamber is pressurized
                if (shared_mem->currentStates[ethValve] == 1) { // Check current state of ethanol chamber's valve and see if open (=1)
                    cout << "Pressure stabilized. ";
                    latch(SOV1, 0); // Close Ethanol valve
                    // ethanolValveOpen = false;
                }
                if (shared_mem->currentStates[ethVent] == 1) { // Check current state of ethanol chamber's vent and see if open (=1)
                    cout << "Pressure stabilized. ";
                    latch(SOV3, 0); // Close vent
                    // ventOpen = false;
                }
                pressurized = true; // Continue with feedback check in the next if statement
                printCount = true;
            }
        } else {
            if (currPress < targetPress - threshold) { // Check if pressure is lower than target pressure
                cout << "Pressure too low... Releasing Ethanol. ";
                if (shared_mem->currentStates[ethValve] == 0) {
                    latch(SOV1, 1); // Open Ethanol valves to pressurize
                    // ethanolValveOpen = true;
                }
                if (shared_mem->currentStates[ethVent] == 1) {
                    cout << "Pressure stabilized. ";
                    latch(SOV3, 0); // Close vent
                    // ventOpen = false;
                }
                pressurized = false;
                printCount = false;
    
            } else if (currPress > targetPress + threshold) {
                cout << "Pressure too high... Opening vents to decrease pressure. ";
                if (shared_mem->currentStates[ethValve] == 1) {
                    cout << "Pressure stabilized. ";
                    latch(SOV1, 0); // Close Ethanol valve
                    // ethanolValveOpen = false;
                }
                if (shared_mem->currentStates[ethVent] == 0) {
                    latch(SOV3, 1); // Vent opening to release pressure
                    // ventOpen = true;
                }
            } else {
                cout << "Pressure stabilized. ";
                if (shared_mem->currentStates[ethValve] == 1) {
                    latch(SOV1, 0); // Close Ethanol valve
                    // ethanolValveOpen = false;
                }
                if (shared_mem->currentStates[ethVent] == 1) {
                    latch(SOV3, 0); // Close vent
                    // ventOpen = false;
                }
                pressurized = true;
            }
        }
        
        if(!printCount){cout << "Current pressure: " << currPress << endl;}	// Print out the current pressure
        usleep(25000);
    }