Hold Servo Position Until Next Serial Instruction

I am new to C and Arduino. I'm sure this is a very basic oversight on my part, but so far my GoogleFoo has not yielded the solution I am looking for.

So a brief rundown of my simple project. I'm receiving serial data and using an array to determine the microsecond value to write to the servo. That function is working correctly. However, I need the servo to stay in that position until I receive a new serial value.

I would appreciate any advice you can provide.

Here is my code:

#include <Servo.h>
Servo servo1;
long num;
const int SpeedMap[211] PROGMEM = {2300, 2297, 2295, 2292, 2289, 2286, 2284, 2281, 2278, 2275, 2273, 2270, 2267, 2264, 2262, 2259, 2256, 2253, 2251, 2248, 2245, 2242, 2240, 2237, 2234, 2231, 2229, 2226, 2223, 2220, 2218, 2215, 2212, 2209, 2207, 2204, 2201, 2198, 2196, 2193, 2190, 2185, 2179, 2174, 2168, 2163, 2157, 2152, 2146, 2141, 2135, 2128, 2120, 2113, 2105, 2098, 2090, 2083, 2075, 2068, 2060, 2052, 2043, 2035, 2026, 2018, 2009, 2001, 1992, 1984, 1975, 1967, 1959, 1951, 1943, 1935, 1927, 1919, 1911, 1903, 1895, 1887, 1878, 1870, 1861, 1853, 1844, 1836, 1827, 1819, 1810, 1800, 1790, 1781, 1771, 1761, 1751, 1741, 1732, 1722, 1712, 1702, 1692, 1681, 1671, 1661, 1651, 1641, 1630, 1620, 1610, 1600, 1589, 1579, 1568, 1558, 1547, 1537, 1526, 1516, 1505, 1495, 1484, 1474, 1463, 1453, 1442, 1432, 1421, 1411, 1400, 1390, 1379, 1369, 1358, 1348, 1337, 1327, 1316, 1306, 1295, 1285, 1275, 1265, 1255, 1245, 1235, 1225, 1215, 1205, 1195, 1185, 1175, 1165, 1155, 1145, 1135, 1125, 1115, 1105, 1095, 1085, 1075, 1065, 1055, 1045, 1035, 1025, 1015, 1005, 995, 985, 975, 965, 955, 945, 935, 925, 915, 905, 895, 885, 875, 865, 855, 845, 835, 825, 815, 805, 795, 785, 774, 764, 753, 743, 732, 722, 711, 701, 690, 680, 670, 660, 650, 640, 630, 620, 610, 600, 590}; 

void setup()
{
servo1.attach(5, 590, 2300);
Serial.begin(9600);
Serial.print("Enter Airspeed = ");
}

void loop(){
  int servMs;
  int airspd;
  while (Serial.available()>0) {
  airspd =Serial.parseInt();
  servMs=pgm_read_word(&SpeedMap[airspd]);
  Serial.print(airspd);
  Serial.println(" Knots");
  Serial.print("Enter Airspeed = ");
  }
  servo1.writeMicroseconds(servMs);
  delay(15);
}

I need the servo to stay in that position until I receive a new serial value.

Once in position the servo will not move unless you detach it and apply an external load to its output or write a new value to it.

That was my expectation. Unfortunately, that is not how it is acting right now. With the code exactly as above, the servo is returning to the minimum value (590 mS) immediately after the delay time in the last instruction.

I bet you have your line-endings set to CR-LF in the serial monitor. Remember that Serial.parseInt() will parse up to the first character that isn't part of an integer. That would be the CR. So what does it return when it gets the LF?

I have the serial monitor set to "No Line Ending". I did try all the other settings though, with the same result.

I have been taking this project in stages, so before I added the array I was just sending over microsecond data and everything was working fine, the servo would hold position. When I added the array that is when it quite holding. I just can't figure out what I did wrong.

I changed my code to println airsp, in stead of the text I was using before.

When I enter 200 his is the return:

Enter Airspeed = 200200
Enter Airspeed = 00

Hi!

according to me create interrupt on every 50ms duration.

In this interrupt update servo position with Int lastReceivedValue.

In main program when received currentValue then update this value in lastReceivedValue.

Now you are free in main program , interrupt always update your servo positions.

i hope it helps.

I'll give that a try. Thank you

In actual implementation I will be receiving a 76 character serial string and I need to read 3 of those characters to proving the data input. I haven't added that code yet though. I will also need to add some code to make the position return to zero if I loose the serial connection. One step at a time though.

BharatSun:
according to me create interrupt on every 50ms duration.

How could that be necessary?

The Servo library already does that for you.

@WingsonWheels, have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example.

Note how the variable newData is set to true when a message is received. Use that to indicate the need to update the servo position.

...R
PS. There is a simple user-input example in Planning and Implementing a Program

Can it be that you reinitialise servMs at the top of loop()?

With the code exactly as above, the servo is returning to the minimum value (590 mS)

don't confuse milliseconds (ms) with microseconds (us) (strictly speaking, that should be a mu, not a 'u')

move "int servMs" out of loop(). giving it an initial value of 1500 microseconds would be good.

wg0z:
move "int servMs" out of loop(). giving it an initial value of 1500 microseconds would be good.

Or make it static int inside loop() to prevent its value being set to an indeterminate value when declared each time through loop()