Programming issues with a model rocket ejection timer

I am trying to make up a small timer that will be used as a time delay for a model rocket. It will fire an electrical ejection charge. I may use it in the Adafruit "Trinket".

To detect liftoff, either a very small thin wire will be burned by the rocket engine exhaust, or a pull-pin will let go (well proven methods for starting timers). The wire will therefore act like a switch that is "HIGH" to keep the timer from starting, then when it goes LOW the timer will start.

Due to the desire to be able to have feedback to know the status , a piezo beeper will be be sequenced to beep certain ways depending on whether it is waiting for liftoff, has started the delay time, and a long beep when it fires (I know about the current limitations of the pin outputs, I'll be using a transistor to fire the charge)

The outline for the program is like this:

Launch sensor pin (high waiting for launch, low when launched)

Status LED and status Piezo beeper

"Fire" LED that lights when the time delay has reached the programmed time to fire.

Begin loop.

delay of 100, for 1/10 second increments

If Sensor pin high, do nothing, loop back to start to check again 1/10 second later

If sensor pin low, then start the timing count:
Time = Time +1 (adds 1/10 second increments)
Counter1 = Counter1 + 1 (adds 1/10 second increments)

If Counter1 = 10, Counter1 = 0 (resets the counter so it only is used for tenths of a second.

If sensor pin high again, reset Time to zero (opportunity to reset the time count)

If counter1 = 2, Beep the piezo beeper and light LED 12 (on for 1/10 second)
(there would later be other beep timing depending on status, using the 1/10 second increments form couture)

And finally the most important:

If Time = EjectDelayTime, then light LED 10 (and sound peizo beeper) for 1 second

End of loop

I put together the programming but it is not behaving correctly at all. LED 10 (ejection)is flashing, every second, on about 90% of the time (the Piezo beeper on pin 9 is also beeping with it), when LED 10 it ought not to light at all until launch has been detected and the time has run to the delay time.

LED 12 is on continuously, when it and the peizo beeper out to be on only 1/10 second per second.

I added serial commands to debug it.

What I should see in the serial command is Buttonstate for the launch sensor (0 or 1), the Time count, and the Counter1 count.

When I run it, only the Buttonstate is working right, 1 when high, 0 when low.

Time reads 50, which is my test delay time (50 tenths of a second). Bt that ought not to be possible, it should take 5 seconds to reach 50, but it produces this number every 1/10 seconds

Counter reads zero.

I suspect part of the problem may be that the curly brackets for nesting the If commands may be out of whack.

Can soon please help me figure out what is going wrong?

FWIW - this is for a serious project. See my rocket website for some of the stuff I've done.

http://georgesrockets.com/GRP/GRP-home.htm

  • George Gassaway

// For a model rocket ejection delay timer

int led10 = 10; // Power to this LED will also be used by a transistor to fire the ejection

int led12 = 12; // visual Staus

int beeper1 = 9; // audio status

int EjectDelayTime = 50; // Time of the delay in tenths of a second. THis value will be changed as needed for the desired model and conditions

int Time = 0; // time loop counter, in 1/10 second

int counter1 = 0; // a counter only for tenths of a second, is reset to zero when it reaches 10

const int buttonPin = 6; // Pin location for the breakwire that starts the timer. Named Pushbutton from existing code I used in this

int buttonState = 0; // when the pushbutton is high, the timer does not start. Pushbutton low timer starts

void setup() {

pinMode(led10, OUTPUT);
pinMode(led12, OUTPUT);
pinMode(beeper1, OUTPUT);
pinMode(buttonPin, INPUT);

// initialize serial communication at 9600 bits per second:
Serial.begin(9600);

}

void loop()

{
delay(100); // wait for a 1/10 second (100 milliseconds)

buttonState = digitalRead(buttonPin);
{
digitalRead(buttonPin);
}

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(led12, HIGH);
digitalWrite(beeper1, HIGH);
Time = 0; // resets time count back to zero, can stop a time count back to zero. But count will resume if the pin goes low again
}
else { // this begins the count, in 1/10 second increments
// turn LED off:
digitalWrite(led12, LOW);
Time = Time + 1;
counter1 = counter1 +1;
}
{
if (counter1 = 10);
counter1 = 0; // reset counter1 to zero
}

{
// the following If/Else is to make the beeper beep for 1/10 second, every second
if (counter1 = 2) {
digitalWrite(led12, HIGH);
digitalWrite(beeper1, HIGH);
}
else {
digitalWrite(led12, LOW);
digitalWrite(beeper1, LOW);
}
}

// Fires ejection for 1 second
{
if (Time = EjectDelayTime ) {
digitalWrite(led10, HIGH); // Fires ejection for 1 second
digitalWrite(beeper1, HIGH);
delay (1000);
digitalWrite(led10, LOW); // stops firing, transistor goes low
digitalWrite(beeper1, LOW);

}

{
if (counter1 = 10);
counter1 = 0; // reset counter1 to zero
}

}

Serial.print(buttonState);
Serial.print(" Time ");
Serial.print(Time);
Serial.print(" Counter= ");
Serial.println(counter1);

} // last line

if (counter1 = 10);
You need to change = to== in all your if lines.

Check the if function!

Hi George

Thought about using one on these, even sample code

What is the point of the buzzer, after take of you won't hear it surely.


Rob

Thanks all, for your comments.

LarryD, thanks for the tip on changing the IF operator from = to ==.

That has made the timer functional. It counts the time increments properly and when it hits the programmed delay, it fires LED 10 as it is supposed to, so it would fire the ejection once a transistor is added.

Plus if I make the launch detect pin go high again before the delay time is reached, it does reset to zero as it should.

The counter1 for the tenths of a second, to make the piezo beeper beep, is still not working but I'll spend more time tonight on the code and try to figure it out.

Graynomad - The beeper is partly for testing purposes, to confirm when it has gone from "ready for flight" mode to sensing launch and count-down for ejection.

But it is also a very important safety feature. For one, to know it's working right, rather then being dead, wrong mode, or having somehow triggered early before final arming, as that would mean the rocket would crash without popping the chute. The other is to know that it has sensed liftoff and is counting to fire… which would be a BAD thing to hear while preparing the rocket for launch (not as bad as NOT knowing it was about to fire!). But at least then either it might be possible to re-short the break wire or pull-plug to reset. Or if it's not practical to do that, then simply get away from it if it is on the launcher, or drop on the ground so when it fires there will not be anyone next to it. There have been various accidents thru the years with electronics either not going off because they were dead or in the wrong mode, or firing early on the ground. So I want to have the safeguards for that, and peace of mind that it is "happy and still ready to go".

Years ago (1998), a friend of mine made a "flight computer" for my space shuttle model. It used two Basic Stamps. The computer did not steer the model, I did that by R/C. But the computer carried out a sequence of events, partly based on timing, and partly based on what it sensed had occurred, then it chose the proper thing to do for a given set of circumstances in the programming (Main things it did were to command a servo to separate the SRB's at the right moment, and to fire an ejection charge inside the ET to pop the chutes. The computer was in the ET nose). It had error codes that it would beep out if it detected something was wrong, which were very useful for testing the prototype, and for the actual final model. But if everything was OK, it would put out a simple quick beep to let me know it was fine and ready to fly. It always worked, I had ground tested the heck out of it and my friend had done a fantastic job of programming it.

Peter 1929 - As for a pressure sensor, indeed there are altimeters used for rockets. There can be a few issues, for now I want to work out a delay timer. I did not mention that the delay timer could also be used for 2-staged rockets, to ignite the second stage engine at just the right time (with an engine that cannot be ignited by a booster engine, such as Composite engines). Also, a timer can be smaller and lighter than an altimeter. This won't need any other module to be added to it, so it can be very light and very small. Indeed I will likely either use a "Trinket", or possibly my own ATtiny85, with the bare minimum components to make it work. It's intended for small models to be used in major contests, where the small size and light weight will be critical. BTW - I know serial won't work with the Trinket, or many ATtiny's, but only need the serial commands for the debugging process.

  • George Gassaway

Is the piezo an actual beeper (with built-in BEEP circuitry), or just a speak-like element that you need to drive with a tone?

 {
    if (counter1 == 10);
    counter1 = 0;         // reset counter1 to zero
  }

This code segment doesn't need the braces {} around it, but they shouldn't hurt anything either.

But the first semi-colon will hurt, counter1 will be set to 0 regardless of it's current value. Now that you've highlighted that I see it a few times in the code.


Rob

westfw, it is an actual piezo beeper, it beeps when powered directly. But, good question regardless.

For all, here is a video I made to show it to some other rocket fliers, after changing the "=" in the IF statements to "==", (from LarryD's message, which solved many of the problems).

Graynomad, YOU FOUND IT! Indeed that was the problem. I had finally realized the problem was there, by finding that counter1 counted correctly if I removed that IF command set. But I did not realize why it was doing that. Getting rid of the semi-colon fixed it.

Thanks very much!

Also, UKHeliBob, thanks as well. If Graynomad had not found it, your message would have shown me the error.

I had written a pretty long message on the problem and that I had narrowed it down to there, but did not understand why it had the problem. And when I posted it, there was Graynomad's message he'd posted a few minutes before, with the answer.

Now I can go on to wrap up the rest of the programming. When it's done I'll post the final code and another youtube video with the beeper doing its thing. Actually, right now the beeper is already doing a 1/10 second beep every second, I need to tweak the code to do that as the "ready" beep, and add the 1-3-5-7-9 rapid beeps for the timer start warning beeps. And it's doing a full one second beep at the end of the count when the Ejection fires.

  • George Gassaway
   if (counter1 == 10); {  
    counter1 = 0;           
  }

What's that semi-colon doing there in the if line ?

I completed the code for the Rocket Delay timer.

Video here:

The beeper has three different types of beeping depending on mode. Mode 1 is ready for launch, a quick 1/10 sec beep that is it fine. Mode 2 is that it has started timing, very fast beeps that would war us if it started early by accident. Also useful for ground testing. Mode 3 is after ejection, a different beep to indicate it is still running but not in the first two modes. When it is firing the ejection, it also does a constant beep. And when its not working (not on, dead battery, etc), it does not beep at all, of course.

Code below.

Thanks again to those who commented.

  • George Gassaway

// An Arduino based Model Rocket Timer for Ejection Delay and Staging Delay
// By George Gassaway NAR 18723 January 27, 2014

int led10 = 10; // Power to this LED will also be used by a transistor to fire the ejection

int led12 = 12; // visual Staus - useful for prototyping, not needed for timer if it has a beeper.

int beeper1 = 9; // audio status by Piezo beeper

int EjectDelayTime = 50; // Time of the delay in tenths of a second. THis value will be changed as needed for the desired model and conditions

int Time = 0; // time loop counter, in 1/10 second increments

int counter1 = 0; // a counter only for tenths of a second, is reset to zero when it reaches 10

const int buttonPin = 6; // Pin location for the breakwire or pull-plug that starts the timer. Named Pushbutton from old code I used in this

int buttonState = 0; // when the pushbutton (breakwire) is high, the timer does not start. Pushbutton low, the timer starts

int Mode = 1; // Prelaunch = 1, Counting delay = 2, after Ejection = 3 Determines the Beeper sequence.

void setup() {

pinMode(led10, OUTPUT);
pinMode(led12, OUTPUT);
pinMode(beeper1, OUTPUT);
pinMode(buttonPin, INPUT);

// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}

void loop()

{
delay(100); // wait for a 1/10 second (100 milliseconds)

buttonState = digitalRead(buttonPin);
{
digitalRead(buttonPin);
}

// check if the break wire is connected, if it is connected, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(led12, HIGH);
Time = 0;
Mode = 1; // resets time count back to zero, can stop a time count back to zero. But count will resume if the pin goes low again
}
else { // Launch detected by breakwire, this begins Timing Delay count, in 1/10 second increments
// turn LED off:
digitalWrite(led12, LOW);
Time = Time + 1;
}

counter1 = counter1 +1;
if (counter1 == 10) { // Resets counter1 to zero so the counter values are always tenths of a second from 0 to 9
counter1 = 0;
}

if (Time >> 0 && Mode < 3) {
Mode = 2; // Launch detected, this sets the mode to 2 to enable the rapid warning beeps
}

if (counter1 == 1 && Mode == 1 // short beep for everything nortml, Mode 1
|| counter1 == 1 && Mode == 2 // rapid beep for timer has started count, Mode 2
|| counter1 == 3 && Mode == 2
|| counter1 == 5 && Mode == 2
|| counter1 == 7 && Mode == 2
|| counter1 == 9 && Mode == 2
|| counter1 == 1 && Mode == 3 // Long beep with short interrupt, Mode 3 after Ejectin fired
|| counter1 == 2 && Mode == 3
|| counter1 == 3 && Mode == 3
|| counter1 == 4 && Mode == 3
|| counter1 == 6 && Mode == 3
|| counter1 == 6 && Mode == 3
|| counter1 == 7 && Mode == 3
|| counter1 == 8 && Mode == 3) {
digitalWrite(led12, HIGH);
digitalWrite(beeper1, HIGH); // beeps in 1/10 increments called out above, depending on Mode and counter1 number
}
else {
digitalWrite(led12, LOW);
digitalWrite(beeper1, LOW);
}

// Fires ejection for 2 seconds

if (Time == EjectDelayTime ) {
digitalWrite(led10, HIGH); // Fires ejection for 2 seconds. The signal needs to go to a transistor
digitalWrite(beeper1, HIGH);
Serial.println("FIRED EJECTION!");
delay (2000);
digitalWrite(led10, LOW); // stops firing, transistor goes low
digitalWrite(beeper1, LOW);
Mode = 3; // Post- Ejection mode, with a different beep tone
}

// the following serial lines are for debugging or seeing how it works.
Serial.print(buttonState);
Serial.print(" Time ");
Serial.print(Time);
Serial.print(" ");
Serial.print(counter1);
Serial.print(" Mode = ");
Serial.println(Mode);

} // last line

Sounds good. I love flashing LEDs and beeping beepers, simple stuff but quite satisfying and in this case useful as well.


Rob

I would like to bump this post if I could. How do you set up the wiring for a pull pin start? Do you run a wire from Pin 6 to Ground or from Pin 6 to 5V? I'm confused on this one.