Servo timer

Hi guys first post. I always wanted an arduino and this summer I finally got one. Boy is it fun! The real reason I got it is because I have a ton of other hobbies that would be made more enjoyable through automation. I am into rubber powered model airplanes and since they have no remote control, if they get caught up in a thermal they could fly away. So what I want to build is a programmable timer that will move a servo back and forth 3 times after a set time. The servo will be connected to something that make the airplane come down like a parachute or something. Ive seen where others have done this using an attiny13 or attiny85. What I was thinking is to have one pin for the signal to the servo, 2 buttons, 3 leds, and a 3.7volt lithium polymer battery to power it. The switches can go on 1 pin if I put differing value resistors on each switch. The leds display the time the timer will run untill the servo moves. One led displays the hundreds digit another the tens, and another the ones. I guess they would have to blink to indicate the number for each place value. Now the switches, one will be labeled stop/dt, this will start the timer when released and also go into program mode when held down at the same time as the start button. The hundreds digit light will turn solid, telling the operator the hundreds digit can be programmed by hitting the stop/dt button once for 1 and so on for the rest of the digits. When done programming hit the start button to save the time then push stop/dt to to arm it the release to start the timer. Hows does that sound? Im basicly reverse engineering and simplifying this http://www.eft-inc.com/models/docs/smoothie_man.pdf. Since Im into rubber power I do not need a motor controller. So what do you think? Im very over my head with this project and every bit of help I can get will be greatly appreciated!

You might go back to the free flight days before electronics to keep your setup simple. I think I remember something like a thin rubberband attached to a rudder or similar that when released would send the plane into a spiral to return to earth. I think the timed trip mechanism was s smoldering string that burned thru a cotton release thread allowed the rudder to be pulled to one side by the rubberband. Also in the single tube RC radio days, the functions now performed by servos were performed by rubberband powered gizmos I think called escapements.

Given all that electronic hardware and servos and so on implied by this approach, have you considered simply adding remote control? You don't have to use it until it comes time to recover your aircraft, but perhaps you'll find you want to. Alternatively, if you're dead set against that, instead of using a timer implement a "dead man's handle" in the form of a radio transmitter/receiver pair in which the receiver initiates the recovery sequence when it loses the signal from the transmitter. So it'll recover as soon as it gets out of range, or when you decide to turn the transmitter off.

I really thought about about using a remote controlled servo to bring it down but the battery+receiver+servo would be way too heavy. The thing with fuse or smoldering string works however they have been known to fail. Not to mention you could run out of string.

Not to mention you could run out of string.

too bad you don't have a walmart where you live. :frowning:

Swri9217:
the battery+receiver+servo would be way too heavy

Well, I thought weight might be an issue, but then you were talking about a servo, presumably controlled by an Arduino and presumably all battery powered - that's not going to be any lighter than an RC system. You can get pretty light micro RC systems these days and I thought it might be worth exploring the option. What is your weight budget for this thing?

Maybe just use a piece of "muscle wire" to act on a mechanism that releases the cord that then puts the rudder into the spiral position.

My weight budget is 10 grams Id say. I figure a gram or two for the battery, 2 grams for the circuit board, and 2 grams for the servo. Thats 5 grams and I think those weights are ok because Ive seen timers that light and lighter. After some thinking, I've drastically simplified this thing. Instead of 3 buttons I will use a 10k trim pot to set the time and a button to stop and start the timer. My friend wants me to add an led for low voltage warning as it will be powered by a 1 cell lipo battery and they cant be discharged below 3 volts. In model airplane competitions the flight time increases from 2 minutes to 6 minutes in 30 second increments. I have 180 degrees of travel to work with so every 30 degrees equals a minute delay. 60 degrees= 2minutes. Simple.

I have the servo bussiness figured out but now I need to convert the varying voltage coming from the pot to a varying time delay. I dont know how to do that. I did finnd a variable rate led blink sketch on the internet but it didnt help much. Could it just need calibrating or is there a proportional millisecond delay code I dont know about?

The delay is easy. If you're using an Arduino, just wire up your pot as a voltage divider and do an analogue read of the voltage. Scale that reading up to give you the number of milliseconds you want to delay for, and call delay(). If you really want to choose from one of a set of discrete values (rather than have completely proportional control over the delay) you might want to replace the pot with a switch (link wire, jumper connector ...) to select from the discrete values. Otherwise your timing accuracy will depend on you adjusting the pot perfectly.

If you have 4x spare input pins then something like this Error Page will be concise and very small/light. Just get a version with a knob or knurled stem so it's easy to adjust by hand.

The delay time isn't critical. It doesn't have to be exactly 2 minutes it can be a little over or under. The benefit with electronic timer is they're consistent and work everytime, something fuses and other timers are not. How do I scale the reading? I thought about using a rotary switch but I will be using an attiny85 so Im kindof limited on my pins.

I'd use an analog input.

If you want control in discrete steps, you could plug in a resistor (and use a different value for different durations). If you want proportional control over the time, just use a potentiometer.

Ok so what I did was play around with the value the arduino is reading from the pot by multiplying it by a number: delay((sensorValue)*25); that gives me a delay of 25 seconds when the pot is turned all the way up. I then put in 35 to get 35 seconds and its been on for 3 minutes and counting now. This isnt how you scale it so there must be something between 25 and 35 thats throwing its count off.

Reading a pot using analogue you should get values between 0 and 1023 as that is the resolution of analogue read. Just use the map() function http://arduino.cc/en/Reference/Map to convert it to the scale you need. This could be second (120 to 360) for 2 mins to 6 mins or any other linear scale.

Heres my code. As Im just working on getting the delay sorted out Im using and adjustable blink sketch. The period the led is low is adjustable. I put the analogread in the setup because I want it to only happen after resetting the timer. Im pretty sure Im not doing this right because I replaced 255 with 180 for 3 minutes and nothing changed. It still stayed off for same period of time the 255 gave me. Im so close to getting this working! I think this is my last hurdle for the code with this project.

int sensorPin = A5; // select the input pin for the potentiometer
int ledPin = 13; // select the pin for the LED
int sensorValue = 0; // variable to store the value coming from the sensor

void setup() {
// declare the ledPin as an OUTPUT:
pinMode(ledPin, OUTPUT);
sensorValue = analogRead(sensorPin);
int val = analogRead(5);
val = map(val, 0, 1023, 0, 180);
}

void loop() {
// read the value from the sensor:
; // turn the ledPin on
digitalWrite(ledPin, HIGH);
// stop the program for milliseconds:
delay(3000);
// turn the ledPin off:
digitalWrite(ledPin, LOW);
// stop the program for for milliseconds:
delay(sensorValue);
}

I still cant get the output of the pot to scale. The delay still stays the same like 3 seconds now matter what numbers I plug in.

Use Serial.print to tell you what sensorValue is after you read it. Also, post your code again if you changed it.

Im pretty sure Im not doing this right because I replaced 255 with 180 for 3 minutes and nothing changed.

delay() uses milliseconds so delay(1000) would equal 1 second. You would not likely notice the difference in delay between 180 and 255. If you want to delay for 3 minutes then you do delay(180000). Also be aware you need to use long and not int as 180000 is to big for int variable type.

    int val = analogRead(5);
    val = map(val, 0, 1023, 0, 180);

These two lines do nothing useful as val is not used in rest of program.

    delay(sensorValue);

As sensorValue is a direct reading of the analogue port it's value could be between 0 and 1023 so the maximum time the LED would be off is just over one second, the minimum time (and some percentage above that) you would probably not notice the off time at all due to persistence of vision.

Heres my updated code. I think its very close to working I just need to figure out this map function. Right now the led is staying high because I dont know what to put in for the second delay. Im sure Im missing something very simple here.

int sensorPin = A3;    // select the input pin for the potentiometer
int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor
int Val = analogRead(sensorPin);
int outVal = map(Val, 0, 1023, 0, 30);
void setup() {
  // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);  
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);    
  // turn the ledPin on
  digitalWrite(ledPin, HIGH);  
  // stop the program for <sensorValue> milliseconds:
  delay(1000);          
  // turn the ledPin off:        
  digitalWrite(ledPin, LOW);   
  // stop the program for for <sensorValue> milliseconds:
  delay(Val);                  
}