Model Rocket Launch Control

Good evening all, I am getting back into coding after a few years hiatus so hang with me while I figure out the inevitable issues I'm sure to find.

I'm working on building a launch system for model rockets, using arduino. Goals:

Send short character strings via serial (from PC through USB, to an Arduino, transmit using HC-12 modules, and use the end Arduino to actuate relays (I know the code hasn't been set up to controls different pins yet)

I haven't begun to program in the HC-12 modules yet, as I can't get the simple serial commands to work yet, here's the code, any help is appreciated.

I can see where the command is transmitted to the board, but the built in LED doesn't flash or turn on. (I have tested the blink sketch and it works)

void setup(){


 

Serial.begin(9600);

 

while (!Serial);

 

Serial.println("Use 'LE' to load capacitor bank for ejection charge, use 'FR' to launch rocket engine, use 'CP' to clear launchpad electrical ");

 

}

 

void loop() {

 

if (Serial.available()){

 

char state = (char) Serial.read();

 

if (state == 'LE'){

 

digitalWrite(13, HIGH);
Serial.println("Command completed! Deployment bank charging...");
}

 

if (state == 'CP'){

 

digitalWrite(13, LOW);

 

Serial.println("Command completed launchpad ready to reload, ***CLEAR***");

 

}

 

if (state == 'FR'){

  digitalWrite(13, HIGH);  

  delay(1000);                      

  digitalWrite(13, LOW);   

  delay(1000);    

Serial.println("Command completed Rocket Fired - launchpad hot ***must clear");

 

}

}


 

}

Michibacy:
I can't get the simple serial commands to work yet, here's the code, any help is appreciated.

Have no idea what this means.

ieee488:
Have no idea what this means.

Sorry my terminology might be off. I'm able to type in the different "states" into serial monitor, and can verify they're being transmitted (according to the LEDs on the board) but nothing happens after that (pin 13/LED doesn't blink and no responses in the serial monitor)

Check out How to use this forum, in particular about posting code.

char state = (char) Serial.read();
if (state == 'LE'){

Two errors I can see here. One, c-strings can't be compared with ==, you have to use strcmp() - see the format here. Also usage examples at C++ reference on the web.

Second, state is one character and you're comparing it to 'LE' which is two characters. Maybe you want state to be an array.

holdingpattern:
Is the plan to do some validation on the codes coming in (eg maybe an FR has to follow a CP or whatever) before sending those out again to the other Arduino?

Are the commands typed into the Arduino monitor (or similar)? If so, I'd be inclined to have an app on the PC (maybe processing?) doing that.

Had a fresh cup of English Breakfast and a fresh pair of eyes this morning....redid the code and it's working perfect, now my question is this, how do I implement the code for HC-12 Modules, to transmit the serial commands? I'm typing commands into Serial Monitor (any better suggestions? I'm up for experimenting) How do I go about adding in validation? (probably a good idea considering I'm launching 1km in the air and would hate to forget to enable the ejection system).

Here's the new code I came up with:

const unsigned int BAUD_RATE = 9600;

char command;

void setup() {
  while (!Serial);
  pinMode(13, OUTPUT);
  Serial.begin(BAUD_RATE);
  Serial.println("Welcome to Launch Command... ");
  delay(1000);
  Serial.println("Initilizaing Setup... ");
  delay(1000);
  Serial.println("Transmit Module OPEN");
  delay(500);
  Serial.println("Handshake UP");
  delay(500);
  Serial.println("Handshake DOWN");
  delay(1000);
  Serial.println("Use 'L' to load capacitor bank for ejection charge, use 'F' to launch rocket engine, use 'C' to clear launchpad electrical ");
  delay(500);
  Serial.println("Waiting for command...");
  delay(1000);
}

void loop() {

  if (Serial.available() > 0) {
    command = Serial.read();
    if (command == 'L' ) {

      Serial.println("Loading Ejection Charge Circuit...3");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...2");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...1");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...");
      Serial.println("500mAh Ejection Charge Circuit CLOSED");
      delay(250);
      digitalWrite(13, HIGH);
      delay(15000);
      digitalWrite(13, LOW);
      delay(500);
      Serial.println("500mAh Ejection Charge Circuit OPEN");
      delay(500);
      Serial.println("Ejection Charge Circuit Loaded***ROCKET ARMED*** Ready to Fire");
      delay(500);
      Serial.println("Waiting for command...");
      delay(1000);
    }

    if (command == 'C' ) {
      Serial.println("Launch Pad Circuits OPEN ***ALL CLEAR***");
      digitalWrite(13, LOW);
      digitalWrite(13, LOW);
      delay(500);
      Serial.println("Waiting for command...");
      delay(1000);
    }
    if (command == 'F' ) {
      delay(750);
      Serial.println("ROCKET FIRING!!!");
      Serial.println("2A Launch Circuit CLOSED/Umblical Disconnect OPEN");
      digitalWrite(13, HIGH);
      delay(2000);
      digitalWrite(13, LOW);
      digitalWrite(13, LOW);
      Serial.println("2A Launch Circuit OPEN/Umblical Disconnect OPEN");
      delay(500);
      Serial.println("Launchpad ****CLEAR*** Ejection charge circuit ****CLEAR***");
      delay(500);

      Serial.println("Waiting for command... READY to Reload");
      delay(1000);
    }
    if (command == 'H' ) {

      Serial.println("Use 'L' to load capacitor bank for ejection charge, use 'F' to launch rocket engine, use 'C' to clear launchpad electrical ");;


    }
  }

}

holdingpattern:
The hc-12 is a serial device is it not? Perhaps make a software serial port for it (unless your Arduino has another hardware serial, like Mega for example) and write those codes back out again on that port, after doing whatever validation you need.

Yes, it is a serial device. I'm still rather new to programming, how would I go about making a software serial port? (I'm using Arduino Nano)

holdingpattern:
See here and examples.

As far as I know (which is not far :wink: ) it's programmed just like Serial, just with your choice of name, so hc12.begin() or mySerial.begin() etc

Ok Thanks! I've just gotta' wait for the HC12's to show up and go from there!

holdingpattern:
You could connect the two Arduinos' soft serial ports by wires, I reckon.

I'm working with some experimental nozzle designs as well as fuel compositions thus my need for wireless control. I surely don't need the 1km that is advertised by the manufacturer for the HC12 but it'd definitely beat running a wire to the launch box :slight_smile:

I've found a simple code Here, any idea how to parse those transmit codes into my code?

search term: serial transfer

Thanks, the coding is making my head spin slightly. I might just need to experiment once I receive the modules and can mess around with both modules and boards at the same time. Do you for see any issues using my exiting code and the SerialTransfer?

Wonderful, thank you!

Will I be able to configure (AT Commands) the HC-12 modules through this set up?

holdingpattern:
I'm seeing an interesting weekend mini-project for me here, not that I have the slightest interest in rocketry. (Although my daughter's an engineer in radio astronomy.... I didn't even understand the topic of her Masters proposal, let alone any of the stuff inside.)

Have a launch "console" on the PC, written in Processing. Only certain buttons are enabled to start. Hit one of them to do something, it sends command to local Arduino on USB. Local Arduino might do further validation (maybe that a hardware switch is set) then forwards the command to the Remote Arduino over wired software serial. Remote Arduino does some further validation (maybe a switch at that end needs checking too), does whatever the command told it do, eg set a relay (if the validation worked) then sends a message back to the other Arduino and ultimately to the PC to say the command was carried out or not. Depending on that message, another button is enabled at the console for the next step or the original button is re-enabled for another go.

I'm lucky: I won't be ham-strung by it needing to be real, I can just make it up, but would be a good proof-of-concept of an end to end process.

The transmitting is definitely working. The only problem (I'm sure it's minor) is that the commands are only working on the control side of things. IE the LED turns on and off (after the appropriate time) on the control board, but it doesn't do anything but respond on the launch board, back over serial.

EDIT: Just need to change some code, thank you for all your help! I am able to get the two boards to communicate now!

I think I'd just make a launch control using an RC tx/rx setup, with two servos or similar that must move from separate controls on the tx to complete the launch circuit. Simple standoff launch control.

Hi,
Have you googled;

arduino HC12

There are many examples and explanatory YouTube videos about those devices.

Can I suggest when you get the HC12's, and for the moment discard your existing code and write fresh code JUST to get the HC12's communicating.

Tom... :slight_smile:

holdingpattern:
I don’t clearly understand what that means, sorry.

Are you saying that a command “X” from PC to the control Arduino arrives and turns on an led there, and “X” is successfully transmitted from the control Arduino to the launch Arduino, but no led turns on at the launch Arduino?

How do you know that “X” is received correctly at the launch end?

Got that issue figured out, just needed to modify some code for my purpose. The problem I’m running into now. I’m trying to program a simple exchange of commands to confirm connection between the modules. I’ve attached the modified code, any change you might take a look?

I Send “T” on the control, Launch pad receives the “T” and is then programmed to transmit a “M” connection back over to the control. The “M” command is then programmed to serial print “Packets received”. I can confirm the Launch pad is receiving the “T”, but get no sign of the return “M” back on control.

Control Code

// forum 668348, control end
// 4 mar 2020
// code from https://forum.arduino.cc/index.php?topic=668348.0 #5
//     with software serial added to send the command from serial out again to launch site
//     (seen lines marked //new)

const unsigned int BAUD_RATE = 9600;

char command;

#include <SoftwareSerial.h> //new
SoftwareSerial hc12(10, 12); // RX, TX //new

void setup()
{
  while (!Serial);
  hc12.begin(9600); //new
  pinMode(13, OUTPUT);
  Serial.begin(BAUD_RATE);
  Serial.println("    *** this version sends the L, C or F out again on software serial ***");
  Serial.println("Welcome to Launch Command... ");
  delay(1000);
  Serial.println("Initilizaing Setup... ");
  delay(1000);
  Serial.println("Transmit Module OPEN");
  delay(1000);
  Serial.println("Use 'L' to load capacitor bank for ejection charge, use 'F' to launch rocket engine, use 'C' to clear launchpad electrical ");
  delay(500);
  Serial.println("Waiting for command...");
  delay(1000);
}//setup

void loop()
{

  if (Serial.available() > 0) {
    
    command = Serial.read();
    if (command == 'L' ) {

      Serial.println("Loading Ejection Charge Circuit...3");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...2");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...1");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...");
      Serial.println("500mAh Ejection Charge Circuit CLOSED");
      Serial.println("500mAh Ejection Charge Circuit OPEN");
      hc12.println('L'); //new
      Serial.print("           **** sent "); //new
      Serial.print(command); //new
      Serial.println(" on software serial ****");//new
      delay(16000);
      Serial.println("500mAh Ejection Charge Circuit OPEN");
      Serial.println("Ejection Charge Circuit Loaded***ROCKET ARMED*** Ready to Fire");
      delay(500);
      Serial.println("Waiting for command...");
      delay(1000);
    }//L

    if (command == 'C' ) {
      Serial.println("Launch Pad Circuits OPEN ***ALL CLEAR***");
      digitalWrite(13, LOW);
      digitalWrite(13, LOW);
      delay(500);
      hc12.println(command); //new
      Serial.print("           **** sent "); //new
      Serial.print(command); //new
      Serial.println(" on software serial ****");//new
      Serial.println("Waiting for command...");
      delay(1000);
    }//C

    if (command == 'F' ) {
      delay(750);
      Serial.println("ROCKET FIRING!!!");
      Serial.println("2A Launch Circuit CLOSED/Umblical Disconnect OPEN");
      hc12.println('F');
      delay(2000);
      Serial.println("2A Launch Circuit OPEN/Umblical Disconnect OPEN");
      Serial.println("Launchpad ****CLEAR*** Ejection charge circuit ****CLEAR***");
      Serial.println("Waiting for command... READY to Reload");
      delay(1000);
    }//F
   
    if (command == 'H' ) {
      Serial.println("Use 'L' to load capacitor bank for ejection charge, use 'F' to launch rocket engine, use 'C' to clear launchpad electrical ");;
    }//H

        if (command == 'T' ) {
      delay(750);
      hc12.println('T');
      delay(500);
      Serial.println("Hand Shake up");
      delay(1000);
    }//T
    
    if (command == 'M' ) {
      Serial.println("Packets Received");
      Serial.println("Handshake Down");
    }//m
    
    
  }

}//loop

Launch Pad Code

// forum 668348, launch site
// 4 mar 2020

// proof of concept....
// listens to software serial for an L, C or F
// turns on one led for each
// a while after an F, all leds go off

const byte ledL = 2;
const byte ledC = 3;
const byte ledF = 4;
char command;
#include <SoftwareSerial.h> //new
SoftwareSerial hc12(10, 12); // RX, TX //new

void setup()
{
  Serial.begin(9600);
  hc12.begin(9600);
  pinMode(ledL, OUTPUT);
  pinMode(ledC, OUTPUT);
  pinMode(ledF, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.println("setup() starting...");
  Serial.println("listening for commands on serial");
}

void loop()
{
  if (hc12.available() > 0)
  {
    command = hc12.read();
    if (command == 'L' )
    {
      Serial.print("Load Received");
      digitalWrite(13, HIGH);
      delay(15000);
      digitalWrite(13, LOW);
    }
    
    if (command == 'C' )
    {
      Serial.print("Clear Circuits Received");
      digitalWrite(13, LOW);
    }
    
    if (command == 'F' )
    {
      Serial.print("Fire Command Received");
      digitalWrite(13, HIGH);
      delay(2000);
      digitalWrite(13, LOW);
      digitalWrite(13, LOW);
      digitalWrite(13, LOW);
      Serial.println(".... done");
    }

    if (command == 'T' ) {
      Serial.println("Hand Shake Initiated");
      delay(500);
      hc12.println('M');
    }//M
  }

}//loop

Thanks for the help holdingpattern, you've been a tremendous help! It's working great, now just to program which pins go to which relays. Much appreciated!

I've got the HC12's all soldered to their jumpers and communicating (about 75 yard apart in a steel sided warehouse).

Test Call is working fantastically.

Just need to work on the pin coding for the relays. And thank you for the tips on the relays!

One last question, a feature that I didn’t think about until now that’d be good to have. A battery voltage check command for the launch pad. I’ve used the :

int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0/1023.0);
    hc12.println(voltage);

one the launch pad to check voltage of the 12 volt battery I’ll have tied to the circuit. I’m using pin A0 as input, and reducing the voltage from 12 volts to a maximum of 5 volts using 3 5.1k ohm resistors to voltage divide (tapping into the line after resistor 3, at 15 volts max would give me 5 volts)

How do I go about reading the string (if I have my terminology correct) (example 11.80) on the sending arduino? I’ve attached both codes as they are so far:

Control Arduino:

// forum 668348, control end
// 4 mar 2020
// code from https://forum.arduino.cc/index.php?topic=668348.0 #5
//     with software serial added to send the command from serial out again to launch site
//     (seen lines marked //new)

const unsigned int BAUD_RATE = 9600;

char command;

#include <SoftwareSerial.h> //new
SoftwareSerial hc12(10, 12); // RX, TX //new

void setup()
{
  while (!Serial);
  hc12.begin(9600); //new
  pinMode(13, OUTPUT);
  Serial.begin(BAUD_RATE);
  Serial.println("Welcome to Launch Command... ");
  delay(1000);
  Serial.println("Initilizaing Setup... ");
  delay(1000);
  Serial.println("Transmit Module OPEN");
  delay(1000);
  Serial.println("INSTRUCTIONS: 'L' to load capacitor bank for ejection charge, 'A' to arm rocket engine,  'F' to launch rocket engine, 'C' to clear launchpad electrical, 'T' to test wireless connection");
  delay(500);
  Serial.println("Waiting for command...");
  delay(1000);
}//setup

void loop()
{
  if (Serial.available() > 0)
  {
    command = Serial.read();
    if (command == 'L' ) {

      Serial.println("Loading Ejection Charge Circuit...3");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...2");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...1");
      delay(500);
      Serial.println("Loading Ejection Charge Circuit...");
      Serial.println("500mAh Ejection Charge Circuit CLOSED");
      hc12.println('L'); //new
      delay(16000);
      Serial.println("500mAh Ejection Charge Circuit OPEN");
      Serial.println("Ejection Charge Circuit Loaded***ROCKET EJECTION ARMED***");
      delay(500);
      Serial.println("Waiting for command...");
      delay(1000);
    }//L

    if (command == 'C' ) {
      Serial.println("Launch Pad Circuits OPEN ***ALL CLEAR***");
      hc12.println('C'); //new
      Serial.println("Waiting for command...");
      delay(1000);
    }//C

    if (command == 'F' ) {
      delay(750);
      Serial.println("ROCKET FIRING!!!");
      Serial.println("2A Launch Circuit CLOSED/Umblical Disconnect OPEN");
      hc12.println('F');
      delay(2000);
      Serial.println("2A Launch Circuit OPEN/Umblical Disconnect OPEN");
      Serial.println("Launchpad ****CLEAR*** Ejection charge circuit ****CLEAR***");
      Serial.println("Waiting for command... READY to Reload");
      delay(1000);
    }//F

    if (command == 'H' ) {
      Serial.println("INSTRUCTIONS: 'L' to load capacitor bank for ejection charge, 'A' to arm rocket engine,  'F' to launch rocket engine, 'C' to clear launchpad electrical, 'T' to test wireless connection");;
    }//H

    if (command == 'T' ) {
      delay(750);
      Serial.println("Hand Shake Up");
      hc12.println('T');
      
    }//T

    if (command == 'A' ) {
      delay(750);
      hc12.println('A');
      delay(500);
      Serial.println("***ROCKET ARMED***");
      Serial.println("Waiting for command... READY to FIRE");
    }//A

     if (command == 'B' ) {
        Serial.println("...checking battery status...");
        hc12.println('B');
      }


  }

    if (hc12.available() > 0) 
    {
       command = hc12.read();
      if (command == 'z' ){ 
        Serial.println("***Packet Received***1/5"); 
      }
      if (command == 'x' ) {
        Serial.println("***Packet Received***2/5");
      }
      if (command == 'c' ) {
        Serial.println("***Packet Received***3/5");
      }
      if (command == 'v' ) {
        Serial.println("***Packet Received***4/5"); 
      }
      if (command == 'b' ) {
        Serial.println("***Packet Received***5/5");
        Serial.println("Handshake Down");
        }

      }
      
    
    
  }//loop

Launch Pad Arduino

// forum 668348, launch site
// 4 mar 2020

// proof of concept....
// listens to software serial for an L, C or F
// turns on one led for each
// a while after an F, all leds go off

char command;
#include <SoftwareSerial.h> //new
SoftwareSerial hc12(10, 12); // RX, TX //new

void setup()
{
  Serial.begin(9600);
  hc12.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.println("setup() starting...");
  Serial.println("listening for commands on serial");
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(A0, INPUT);
  digitalWrite(3,HIGH);
  digitalWrite(7,HIGH);
  digitalWrite(8,HIGH);
  Serial.println("Launch Relay OPEN");

  
  
  
}

void loop()
{
  if (hc12.available() > 0)
 command = hc12.read();

  if (command == 'L' )
  {
    Serial.print("Load Received");
    digitalWrite(13, HIGH);
    delay(15000);
    digitalWrite(13, LOW);
  }

  if (command == 'C' )
  {
    digitalWrite(7,HIGH);
    digitalWrite(8,HIGH);
    Serial.print("Clear Circuits Received");
  }

  if (command == 'F' )
  {
    Serial.print("Fire Command Received");
    digitalWrite(8, LOW);
    delay(2000);
    digitalWrite(8,HIGH);
    digitalWrite(7, HIGH);
    Serial.println(".... done");
  }

  if (command == 'T' ) {
    Serial.println("Hand Shake Initiated");
    hc12.println('z');
    delay(500);
    hc12.println('x');
    delay(500);
    hc12.println('c');
    delay(500);
    hc12.println('v');
    delay(500);
    hc12.println('b');
    delay(500);
    }

  if (command == 'A' ) {
     digitalWrite(7,LOW);
    Serial.println("***Rocket Armed***");
  }//A

  if (command == 'B') {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0/1023.0);
    hc12.println(voltage);
  }
  
  
}//loop