serial output

hi everybody,

i´m building a small application on my arduino duemilanove which sends out some coordinates to my laptop over a serial connection, which picks this coordinates up and draws a shape whit this coordinates in a little c# app.
right now i just attached two buttons to my arduino and if i press button 1 (groen) it sends out a fixed coordinate and the same goes for a button 2 (geel).
later i will build in a mode which varies these coorinates but for the proof of concept i use these fixed coordinates.

ok so far the expanation, now the problem

when i press the button it starts sending out these numbers to my serialport but it keeps repeating this.
What i want is that it only sends these numbers once and when it has send this number it wont send it for a second time (at least not for at least 5000ms or so.)
i.ve tried (i was desperate) to put a simple delay on there but even then it sends it twice or three times (besides the fact this approach is crappy)
i´m almost sure it´s be possible to write a serial.stopsending or so though i haven´t got a clue how.
anybody got an idea?

the script i´ve got so far is;

int ledPin = 13;
int groenPin = 2;
int geelPin = 3;
int x;
int y;
//int counter = 0;
//int counted = 0;

void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(geelPin, INPUT);
pinMode(groenPin, INPUT);
}

void serieelprint()
{
Serial.println(x);
Serial.println(y);
delay(5000);
}

void loop()
{
if ((digitalRead(groenPin)) == LOW)
{
digitalWrite(ledPin, HIGH);
x = 20;
y = 40;
serieelprint();
}

if ((digitalRead(geelPin)) == LOW)
{
digitalWrite(ledPin, HIGH);
x = 100;
y = 90;
serieelprint();
}

else
{
digitalWrite(ledPin, LOW);
}

}

Your code looks ok. Perhaps add a few more print statements so you can see what is happening.

Serial.println(“groenpin start”)
serieelprint();
Serial.println(“groenpin fin”)

And the same for the geelPin

at first thanx for your quick reply,

that is indeed a good idea, i´m going to use it for sure, in my c# app i can use the start and end mesages for stopping to read the serial input.

but basically (now mostly out of curiossity (do i spell that correct?)) it doenst answer the question, is there a way of having the script send the serial data only once? and i´m still quit curious if it´s possible (i hardly can imagine it is not possible)

I was suggesting those print statments so you could see why it was sending more than once. add the print statments to your code, run it, then copy the serial output from the monitor and past it here.
try it by pressing the button for less than 5 seconds, you should see only one set of print statments. Try as second run where you hold the button for over 5 secodns but but less then ten. You should see two sets of print statments

i´ve tried it, and so far that works

(serial screen<5 sec)

start

100

90

eind

(serialscreen < 10 sec)

start

100

90

eind

start

100

90

eind

i did add the start and end line to void serieelprint in stead within the if statement so that makes the void serieelprint

void serieelprint()
{
Serial.println("start");
Serial.println(x);
Serial.println(y);
Serial.println("eind");
delay(5000);
}

though the problem is i wanna get rid of the delay function,
this is a part of a robot script en the buttonspressed represents an obstacle hit at that point i wanna let the computer know where that has happend so it can draw a map.
the problem with the delay function is that therotically the robot could hit a second location within the delaytime (in this case 5000ms)
if that would happen i would like to still receive that information about that hit and because of the delay it wont send this info.

if i cant get it to work i could look for a decent compromised delaytime but its not the approach i prefer.

though right now i´m working on my c# script so it knows that when it reads "eind" it shouldnt read its serialdata untill it has a different value than before,
i´m not that good yet at c# so if you have any tips on this subject as well they would be much appreciated.

If I undertand correctly you want to send the coords only every 5 seconds, so you need some sort of timer:

#define TIMEOUT 5000
int lastSent = 0 ;

void serieelprint()
 { 
    // only send response if its been for than 5000 milliseconds since 
    // we last sent one ( if not do nothing )
    if(millis() - lastSent > TIMEOUT)
    {
      Serial.println(x);
      Serial.println(y);

      // update last sent timer
      lastSent = millis();
    }
 }

initialise lastSent to -5000 if you want to send one on bootup.

Also might have to think about what happens when millis overflows...

Was that the kinda thing you where after?

hey,

i´m not tring to do that, though i have been thinking about this approach as well.
so maybe i might after all (if the other one is not going to work)

the thing i´m trying to achief is that only when the coordinate has changed it sends out to serial
but most of all i want it to send each coordinate only one time, so if the button is pressed for a longer time it doesnt keep sending the same coordinate over and over again.

you will probably want an additional condition based on a threshhold of the coordinates that where last reported to the pc, something like

if( abs(previousCoords - currCoords ) > threshold)
{
// send serial data
// update previousCoords with ones just sent
}

play with the threshold until you get the right value. I do something similar with getting tilt data back from a wiimote, I have it set quite high ( about 5% of total range ). This will depend on the resolution you want out...

If you get it right and your 'thing' can't change coords too quickly, you won't have to worry about the button being pressed for too long - the data will only be sent when theres meaningful changes in coordinates.

Am I on the right tracks?

hmm this sounds interstig indeed, a bit abstract but i´ll look into it,
though unfotunately tomorrow, thanx for your help so far,

unforutnately for today i gotta go do other stuff

something a bit less abstract

#define THRESHOLD 10 // just a guess - depends on your application

int oldX = 0;
int oldY = 0;

void serieelprint()
{
  // only report new position if its sufficiently "far away" from old position
  if((abs(oldX - x) > THRESHOLD ) ||
     (abs(oldX - x) > THRESHOLD ) )
  {
    Serial.println(x);
    Serial.println(y);
    oldX = x;
    oldY = y;
  }
}

The rest of your code could remain the same.

This is far from prefect code - ideally it would test the distance the point (x,y) is from (oldX,oldY) but you get the idea...

at first thanks,

indeed a lot less abstract
i´ll copy paste it right away and will let you know how it works.

tnx

I think there was a cut and paste problem :wink:

it should be:

  if((abs(oldX - x) > THRESHOLD ) ||
     (abs(oldY - y) > THRESHOLD ) )

i´ve tried it and it does exactly what i wanted,

thanx a lot

i was looking for the answer to this problem in such a wrong ¨place¨

well at least thanx again

hi everybody,

this abs(oldx-x) doesnt solve the problem after all,
allthough in the arduino serial monitor everything seems to be going well it isn,t.

the arduino doesn´t send one clean string on every buttonpress, it sends for example 1,5 times the string, so a few characters extra come along over the line.

in my c# script i´m reading the position of certain characters within the string with a IndexOf method and with this info i create a substring containing the info of coordinate X seperated from coordinate Y

the problem is that if the string send out by the arduino isnt a clean string it doesn´t read the characters in the right place and my app gets stuck (even after guarding it within one million if statements which should stop the script from working if the string isnt "clean"),

basically my question is, how can i stop the arduino with sending stuff after it has send one clean string.

cant i create a serial.close function or so which closes the port as soon as one string has been sent?
or a counter which counts the numer of times a whole tring has been sent?
i have no idea how i would solve this?

anybody ideas?

i saw tthe article on the serialend function but for as far as i understood that its mainly usable if u use pin 1 for a serialconnection.

the debugwindow of my c# app shows what kind of strings are passed throuhg, RxString is the name of the string it is all about,

rxstring = x99y80z

rxstring = x20
rxstring = y40z

rxstring = x
rxstring = 99y80z

rxstring = x20y4
rxstring = 0z

rxstring = x99y80z
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

and this is the error which keeps occurring because of the flaws in the striing