Go Down

Topic: for loop (Read 3600 times)previous topic - next topic

valenti

Sep 14, 2010, 03:22 pm
Hi.
Im working on reading .txt line sent from PC to arduino, so arduino can read xyz values.
it is working quite good but i have one biiigggg problem :/

Code: [Select]
`ypos=9;xpos=2;endx=(ypos-xpos-1);for (int g=0;g<6;g++){xva[g]=stevilka[xpos+g+1];}xval=atof(xva);`

in this code now it works, but instead in for loop of g<6 i would like to make g<endx, but it doesnt work. I also try to make it g<(ypos-xpos-1); but with no luck. And also if i make g<endx the endx somehow is not 6 if i try.
so main question is how can i set in for loop the g<integer, because it somehow doesnt work for me. I use 0018.

ypos, xpos, endx are integers.
if you need i can post whole code

Groove

#1
Sep 14, 2010, 03:39 pm
Quote
it doesnt work

This probably means something very specific to you, but you haven't shared it with us.

whistler

#2
Sep 14, 2010, 05:05 pm
Quote
the endx somehow is not 6

A wild GUESS: You've written right off the end of at least one array and trashed at least one of your scalar vars.

PaulS

#3
Sep 14, 2010, 05:08 pm
You are also not properly NULL terminating the xva array. atof expects the character array it receives to be properly NULL terminated.

valenti

#4
Sep 14, 2010, 08:37 pmLast Edit: Sep 14, 2010, 08:38 pm by valenti Reason: 1
ooh yea made that correction PaulS. But the problem in short way..

Code: [Select]
`ypos=9;xpos=2;endx=(ypos-xpos-1);for (int g=0;g<endx;g++){xva[g]=stevilka[xpos+g+1];xva[g+1]=0;}xval=atof(xva);if(endx==6){digitalWrite(13,HIGH);}`
and the light doesnt get HIGH... so the endx is not 6, but if i remove endx from for loop, the light get HIGH... so i assume that for loop somehow change the value of endx...
unfortunately i cant use serialmonitor since i have serial input from PC, so cant check the value of endx

PaulS

#5
Sep 14, 2010, 09:03 pm
Quote
so i assume that for loop somehow change the value of endx...

It's looking like whistler is correct. You are overwriting memory somewhere.

We need to see all of your code.

Eight

#6
Sep 14, 2010, 09:06 pmLast Edit: Sep 14, 2010, 09:23 pm by Eight Reason: 1
Any time you're programming, you need to have some way of being able to debug what you're doing.

I'll bet Whistler is correct on this one.

If you made the effort to give yourself a way of outputing messages back to yourself from the code, you'd probably have realised by now that you're exceeding the upper-limit of xva[].

And if the next variable declared in memory was endx, then you've just killed it. The Arduino compiler won't warn you if, for example, you've declared an array of six bytes but then set the value of a seventh.

There's a good chance that your loop is not terminating at all (since after you've killed endx with a zero, g will never be less than endx).
[/edit]

valenti

#7
Sep 14, 2010, 11:04 pm
ok so the first part is the processing code to send lines of .txt

Code: [Select]
`import processing.serial.*;String lines[];Serial myport;int test1=1,test2=1,n=1,receive;void setup() {  println(Serial.list());  lines=loadStrings("1234.txt");  myport = new Serial (this, Serial.list()[0], 9600);}void draw(){    if(test1==1){  println(lines[n]);  delay(3000);  test1=0;    }    if(test2==1){  myport.write(lines[n]);    test2=0;  }}`

second part is the arduino code:

Code: [Select]
`char gva[9], xva[9], yva[9], zva[9], stevilka[50];float gval, xval, yval, zval;int gpos=99, xpos=99, ypos=99, zpos=99, i=0, endx;void setup() {Serial.begin(9600);} void loop(){  //RECEIVE  while(Serial.available()){    stevilka[i] = Serial.read();      //positions (G X Y Z)    if(stevilka[i]=='G'){    gpos = i;    }    if(stevilka[i]=='X'){    xpos = i;    }    if(stevilka[i]=='Y'){    ypos = i;    }    if(stevilka[i]=='Z'){    zpos = i;    }        i++;    }    stevilka[i]=0;  //EXAMPLE OF DECLARING A VALUE OF X IN A LINE  endx=(ypos-xpos-1);for (int g=0;g<endx;g++){xva[g]=stevilka[xpos+g+1];xva[g+1]=0;}xval=atof(xva);if(endx==6){digitalWrite(13,HIGH);}}`

im sending a test line to arduino: G1X4.0435Y1.0487Z2.5430

Eight

#8
Sep 14, 2010, 11:16 pmLast Edit: Sep 14, 2010, 11:17 pm by Eight Reason: 1
Well bugger me!

You might have a different issue entirely. Or you might have an extra one.

The problem with waiting while data is available on the serial port is that it's possible for it to finish before Processing has finished sending all the data. A slight gap in the transmission when Serial.available() is called would terminate the loop. If that happened then your variables wouldn't be set properly so endx wouldn't be 6.

Easiest thing to do from here would be to sit in the loop reading from the serial port until you're sure you have all the data you need.

Cool problem though.

Eight

#9
Sep 14, 2010, 11:20 pmLast Edit: Sep 14, 2010, 11:20 pm by Eight Reason: 1
As a side note: why don't you stop using Processing for a bit and test by manually sending strings via the Serial monitor?

Then you can put in a load of Serial.prints to better figure out what's going on exactly.

When it works from the serial monitor, it'll probably work from Processing.

valenti

#10
Sep 14, 2010, 11:30 pm
huh i allready wrote that code for some other project(with delay, but have to use millis instead) but for now sending data with processing without reading delay works fine, and never terminate string too early... so lets assume that this isnt a problem, but i will fix it.
damn, i forgot about sending data through serial monitor... tnx for tip

valenti

#11
Sep 15, 2010, 10:23 am
am... ok when i wake up I review the code, but that was not a problem.. since i never set i=0; so if the serial was not available it skip one loop of while sentence, but the "i" remains the same, so the string just continue to write from position it stoped...

PaulS

#12
Sep 15, 2010, 12:40 pmLast Edit: Sep 15, 2010, 12:49 pm by PaulS Reason: 1
Serial data transmission is SLOW. Loop is fast.

You are probably reading something like "G1X" on the pass through loop. Since you haven't got a way of knowing when a packet is complete, you compute endx assuming that you have received a complete packet. Since X was received, xpos = 2 but ypos is still 99. 99 - 2 is 97. 97 - 1 is 96, which is stored in endx.

Then, you loop 96 times writing data in xva, which is sized to hold 9 values. Oops, you just overwrote something.

You need to revise the Processing code to add at least an end of packet marker, like a !. Then, keep reading serial data until that marker is received.

Don't do any processing of the serial data until that marker is received.

By the way, since 99 is a perfectly valid array index, it does not make a good "not yet assigned" value. -1 would be a better choice. 99 might seem OK now, but future changes (or copying and pasting the code elsewhere, for another purpose) will cause grief if 99 is ever a valid value. -1 will never be a valid index.