Show Posts
Pages: [1] 2
1  Forum 2005-2010 (read only) / Bugs & Suggestions / Ethernetsends a String as one char at the time on: December 28, 2010, 09:10:42 am
I must do

 String str = "Hello World";
 int n = str.length()+1;
 char st[n];
 str.toCharArray(st,n);
 client.print(st);

instead of

 client.print(str)

to send s String in on one TCP/IP packet.

The problem is in Print.cpp:

void Print::print(const String &s)
{
 for (int i = 0; i < s.length(); i++) {
   write(s);
 }
}

and then every write(char)  is send in Client.cpp
as in one TCP/IP packet.  That sinks the transfrer
rate a lot.

It might be idea to do a write(const String &) in Print and
then implement print(const String &) by calling that.

And then in Client one must override write(const String &)
by writing all chars to same packet.

One problem to implement that is that

void String::toCharArray(char *buf, unsigned int bufsize)

and

void String::getBytes(unsigned char *buf, unsigned int bufsize)

are not const methods as they should be.

 :-[
2  Forum 2005-2010 (read only) / Bugs & Suggestions / Need a new = operator for String on: December 28, 2010, 01:47:51 pm
It would minimize one extra object if there would be also operator

const String & String::operator=( const char *st)
{
  int len = strlen(st);
  if ( len > _length )
  {
    free(_buffer);
    getBuffer( len );
  }

  if ( _buffer != NULL ) {
    _length = len;
    strcpy( _buffer, st );
  }
  return *this;
}

Otherwise in

String s;
...
s = "dummy";

first is called constructor String(const char *) to make a string to substitute to s and then is called operator=(const String&) to substitute that string to s.  So the text "dummy" created
and copied twice.

 smiley-wink
3  Forum 2005-2010 (read only) / Bugs & Suggestions / Problem with modulo (%) and reset on: December 28, 2010, 09:29:35 am
I change this to more correct forum from HW
(was http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293529218)

Problem with modulo (%) and reset
Today at 10:40:18 | | Modify | Remove
I have a problem that after a small piece of code the Arduoino (UNO)
does no reset.  It resets only by uploading a new sketch or by power off.

In the code below I separated the problem to % operation.  My idea
was to give exact 1 second signal compared to last reset.  I can go
around the problem by other ways, but I'm worried about why this peace of code has a problem.  Because I got the same problem in longer code but occasionally (when interrupt happens during %).

My guess is that if reset or interrupt happens during % then the board is somehow  in unknown state and does not reset.

The problem can be repeated by code below and pressing the reset button repeatedly until led in line 13 remains blinking.  Then the Arduino is possible to reset only by new sketch or power on.


#include <Wire.h>
#include <string.h>

#undef int
#include <stdio.h>

const int dummyPort = 7;


void setup() {
 Serial.begin(115200);
 Serial.println("Start Arduino");
 pinMode(dummyPort, OUTPUT);
 
}


unsigned long n1000 = 0;
boolean dOn = false;


void loop() {

 n1000 = micros() % 1000000;
 if ( !dOn && n1000 >= 500000 ) {
   digitalWrite(dummyPort, 1);
   dOn = true;
 }

 if ( dOn && n1000 < 500000 ) {
   digitalWrite(dummyPort, 0);
   dOn = false;
 }


}


-------------------------
Replies to few questions:


This code is not doing the reset.  The problem is that if YOU do reset
somehow during this code, the Aruino hangs and you can not do another
reset.  Why should you do the reset?  When you start serial from PC
it sinks the DTR and resets Arduino. So the problem is that when you have code like my example, you have good change to hang the Arduino
when you connect it thru USB from PC.  And to simulate that it is much faster to just press the reset button and see what happends.

The micros (not millis) is just OK for me, because millis is not accurate enough in my purpose.    

And the worst thing is that the same problem comes when some interrupt happens.  And that is the main point, but I think Reset is more familiar for most people.


-----------------------


I have 3 Arduino Uno module and all behaves the same way.
And the reset comes also from USB-serial line by DTR low and
it has exactly same effect.  So do external reset.

The difference in reset by reset button, external reset,
serial start reset and uplod is that when upload is done, the
rset signal stays 5 V, goes to 0 V and the over 7 V and then back to
5 V.  All others just pull reset signal to 0 V and returns it 5 V.

The reset is one of my worries.  The biggest is that WHY Arduino
hangs when Reset or Interrupt is done during %-operation???

4  Forum 2005-2010 (read only) / Bugs & Suggestions / There should be more const methods in String on: December 28, 2010, 05:19:25 am
F.ex

void String::toCharArray(char *buf, unsigned int bufsize)

and

void String::getBytes(unsigned char *buf, unsigned int bufsize)

are not const methods as they should be.

And because they are not const methods like

void String::toCharArray(char *buf, unsigned int bufsize) const

on can not call toCharArray from method like

  write(const String &str) {
          int n = s.length()+1;
          char sc[n];
          s.toCharArray(sc,n);
          write(sc);
  }

 smiley-sad



5  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: January 02, 2011, 07:06:55 am
I can get this one to hang:
Code:
ldiv_t n1000;
unsigned long m = 0;

void setup() {
}

void loop() {
  n1000 = ldiv(m++,1000000L);  // This hangs Arduino while pressing reset
}

You code may not hang because if nothing is changing, the compiler may optimize something away.  The same was also problem for "my minimal code with modulo" when nothing was changing.
6  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: January 02, 2011, 06:52:34 am
Quote
When I press the reset when the LED is on the strange behavior appears.
When I press the reset when the LED is off it acts normal.

I think I get the behavior in both cases.  You can changes the 500000L
to something longer to get more time in each case. F.ex to  2500000L.
Then you must also change the  n1000 %= 5000000L; to get 5 sec round trip.

But I do not see reason why it behaves differently in different state.
7  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: January 02, 2011, 06:17:54 am
Minimal code that hangs Arduino:

Code:
unsigned long n1000 = 0;
unsigned long m = 0;

void setup() {
}

void loop() {
  n1000 = m++;
  n1000 %= 1000000L;  // This hangs Arduino while pressing reset
}
8  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: January 02, 2011, 06:10:58 am
Quote
Adding shortest delay seems to make it more stable
Yes it helps, because then you minimize the change to hit reset during modulo (%).  But still it is possible to hang if you are patient enough pressing the reset button.  So this is not a way to replace this, one only hides the real problem.

Quote
... what does micros() do low level as that is also a constant factor in the code?
it gives the microseconds from the last restart.  And notice that if one uncomments  the two lines:
Code:

  n1000 = micros();
  while ( n1000 > 1000000L) n1000 -= 1000000L; // This works

and comments the modulo line
Code:
// n1000 = micros() % 1000000L;  // This hangs Arduino while pressing reset

then the code works just perfect and does the same thing.  So the % is the only one (what I can see) that has effect.  And as in earlier posts also division (/) has the same (not working) effect.
9  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: January 02, 2011, 04:36:28 am
Sorry.  Of course >= is evaluated before &&.  I just
get confused when retrolefty suggested parenthesis and
I just thought the original code was ok without (as it was)
and did not notice the false suggest.

So
Code:
!dOn && ( n1000 >= 500000L ) == !dOn && n1000 >= 500000L
as it was in the original code.

Here is the code as whole with all the mods requested:
Code:
const int dummyPort = 7;

void setup() {
  Serial.begin(115200);
  Serial.println("Start Arduino");
  pinMode(dummyPort, OUTPUT);  
}

unsigned long n1000 = 0;
boolean dOn = false;

void loop() {

  //n1000 = micros();
  //while ( n1000 > 1000000L) n1000 -= 1000000L; // This works
  
  n1000 = micros() % 1000000L;  // This hangs Arduino while pressing reset
  if ( !dOn && ( n1000 >= 500000L ) ) {
    digitalWrite(dummyPort, 1);
    dOn = true;
  }  
  
  if ( dOn && ( n1000 < 500000L ) ) {
    digitalWrite(dummyPort, 0);
    dOn = false;
  }

}

And the real problem still exist on that code:  Reseting while in modulo hangs the Arduino  smiley-sad
10  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: December 31, 2010, 09:25:04 am
Quote
I'm sorry to have wasted the board's bandwidth on something that couldn't help.

You did not waste the band.  You was the only one who really tried the code and showed to me that the problem can be repeated elsewhere than in my environment.  So lot of thanks and Happy New Year  smiley-grin
11  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: December 31, 2010, 05:03:46 am
Thanks to try my code.

Quote
...Linux...
No, I'm using Windows 7 64 bit.  But this is not the bootloader problem, because the code works if it happens to reset correctly.

Quote
I added a delay of 1 millisecond in the loop.  Here's the code:

I tried that also and forget to tell.  I thought that it helped, but if you are passioned enough to press the reset button, then the problem comes anyway.

And why?  Because the 1 ms loop takes the most of the time from the main loop, so the certainty to press the reset while in division goes minimal.  

That it the thing it took me so long to  find that division is the problem.  Originally I had so much larger main loop and the problem game very seldom, I even ignored it at the beginning.

And my real concern is that if everybody that has division in his code has the same problem.  Normally people do not press the the reset button all the time, but I think also interrupt in the same case hangs the Arduino.  And that is the main concern.
12  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: December 30, 2010, 05:16:26 pm
Quote
Why is stdio.h included?

It was just from the bigger program I tried to split to smallest one  where the error still exists and I forgot include there.  If I remove all includes, it still works same way wrong.

Quote
Software isn't my strong suit, but shouldn't it be:
 if ( (!dOn && n1000) >= 500 ) {

Does not matter, because && has stronger precedence than >=.
In case of clarity this would of course be better.

Still none of the above is the problem.  The problem is that something weird is with division.
13  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: December 30, 2010, 07:38:20 am
Actually changing
Code:
n1000 = micros() % 1000000;
 
to
Code:
 n1000 = micros();
  while ( n1000 > 1000000L) n1000 -= 1000000L;

(where is no sense after few minutes of course)
makes the code work.  So even more proofs against
modulo % or division  / ???

  
14  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: December 30, 2010, 07:08:40 am
Now I have a code:

Code:
#include <Wire.h>
#include <string.h>

#include <stdio.h>

const int dummyPort = 7;


void setup() {
  Serial.begin(115200);
  Serial.println("Start Arduino");
  pinMode(dummyPort, OUTPUT);
  
}


unsigned long n1000 = 0;
int dOn = 0;


void loop() {

  unsigned long t1 = millis();
  unsigned long t2 = t1 / 1000;
  n1000 = t1 - (t2 * 1000);

  
  // n1000 = micros() % 1000000;
  if ( !dOn && n1000 >= 500 ) {
    digitalWrite(dummyPort, 1);
    dOn = 1;
  }  
  
  if ( dOn && n1000 < 500 ) {
    digitalWrite(dummyPort, 0);
    dOn = 0;
  }

}



And that woks exactly same way in all 3 Arduino Uno-modules.
Pressing Rest button or starting Terminal hangs the Arduino.
Upulod or Power on resets and led in 7 starts to blink once
a second.

Instead the code:

Code:
#include <Wire.h>
#include <string.h>

#include <stdio.h>

const int dummyPort = 7;


void setup() {
  Serial.begin(115200);
  Serial.println("Start Arduino");
  pinMode(dummyPort, OUTPUT);
  
}


unsigned long n1000 = 0;
boolean dOn = true;
unsigned long ms = 0;
unsigned long msHigh = 0;
unsigned long msgoal = 500000L;
unsigned long msgoalHigh = 0;

void loop() {

  ms = n1000;
  n1000 = micros();
  if ( n1000 < ms ) msHigh++;
  if ( n1000 >= msgoal && msHigh >= msgoalHigh) {
    digitalWrite(dummyPort, dOn);
    dOn = !dOn;
    unsigned long newms = msgoal + 500000L;
    if ( newms < msgoal ) msgoalHigh++;
    msgoal = newms;
  }  
}


works perfect in this form and also by lot of other stuff in
loop or in interrupts.  So what else I could suspect than
division (or modulo)?
15  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Problem with modulo (%) and reset on: December 29, 2010, 06:46:01 pm
.. +7vdc is just a transent pulse ...

Anyway, after reset button or normal reset from PC it does not reset
correctly like it does when power on or upload program.  And the signal from osciloscope is different between those two cases.

Still the buggest problem is that WHY Arduiono goes on that kind of state.   No I'm not bold enough to use %-operator in my code...

And for Mike:  for some reason it works same way (= correct when reset happens to work) if there is 500000 or 500000L. You are right that it should have L, but seems to be ok without also.  Still this is not the biggest point of the problem.
Pages: [1] 2