Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 28, 2010, 07:00:28 am
Yes, the micros function has a resolution of 4usec, but the timer itself clicks 16 times each usec, so actually has a 1/16 usec resolution.  To get my 1usec, I'm using the prescaler set at 8, so my timer clicks twice each usec and gives me what I need.  The problem came in when i was verifying it using the micros function, and noticed that it was skipping turned out to be hardware and NOT the micros function.  Everything is fine now.

The application is a very high precision stepper motor controller that has real-time, on-the-fly variable acceleration.  I've not seen a controller that can do this.  An error of 2 or 3 usec can make a big difference surprisingly, but it looks like Arduino is up to the task.
2  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 11, 2010, 03:36:53 am
Wow.  Thanks for the references!  I still have a lot to discover about the Arduino!
3  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 10, 2010, 08:56:02 pm
I absolutely concur with the constants comment.  As it stands there is no way to enter constant tables.  With a tweek of the compiler, and no hardware changes, one could enter lookup tables into flash memory, that is currently not used, and that might speed up processing a lot.  I can think of many applications that would be impossible without this feature.

Is there a (practical) way to extend SRAM?  Or is there something that can be added to provide more RAM without going through the serial port?
4  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 09, 2010, 08:26:00 pm
So now I think I understand now (thanks to PaulS post) how the memory is managed with the Arduino.  Maybe this is described somewhere else, but in summary here is what I learned by fiddlin around:

There are 3 address spaces.  The SRAM (8k) starting from top of memory has:

Declared constants (from all your code)
1st stack frame:  Return ptr
                             Local arrays
                             Local variables
Next frame:         Return ptr
                             Local arrays
                             Local variables
                            <free mem>
Global variables

In a different address space you have your code which might be up to128 or 256k.

And then in a third address space you have EEPROM (4k) which you can
read/write for persistent data.

For designing applications, this means:
1.  Be very frugal with SRAM.  This means keep arrays as small as possible, keep globals to a minimum, send your generated data somewhere else--don't use SRAM to keep it for you.  The EEPROM should be used only for what you really want to persist, because you don't have much space, and it is a little awkward (and slower) to access.
2.  You can be reckless with the size of your code.  It would be hard to consume 128k, much less 256 with code.

How much memory is left in SRAM?  I don't know if libray functions exist, but this little snippet I did yesterday works for me:

int availableMemory(){
   int loBound = (int)&lastDeclaredGlobalVariable;
   int hiBound = (int)&hiBound;
   return hiBound - loBound;

Globals are stored working up from the bottom of memory.  Use whatever variable (outside of any function) which was last declared for the function above.  The stack is working down from the top of memory.  So the last declared local variable is the top of the available space--in this case it would be hiBound itself.  The difference between these two addresses tells you how much you have at the time of the availableMemory() call.

What happens when the stack meets the lower bound?  Your program freezes, and Arduino blinks one of the lights.

I hope this helps somebody.  Arduino is all new to me, so if I said something wrong here please post a correction!
5  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 08, 2010, 05:06:06 am
Getting no output means you are getting no errors.  (If you scroll to the end of my code you will see sample output that I get.)  No output is what we want.  I'm getting suspicious that it is my hardware misbehaving--and not the micros code.  I just ran a loop on an array where I ask to output A and then B and then A - B.  I get what I expect for A and B, but then garbage for A-B (or A+B).  And then 20 elements later, I get good stuff again.  It can't be memory, because it is computing the result.  Hmmm....

Thanks for your input.  Don't spend anymore time on this problem (micros) until I can verify my hardware.  I'm a very experienced C++ programmer, but kinda new to Arduino...still learning what to expect.  I'm very impressed with what it can do.

Here's a really stupid question:  How do you tell which Arduino Mega you have by looking at it?  Also how much programming space (code, variables, stack) do I have?  The compiler says I have that how much I really have to work with, or is it something less?  My code right now is about 11k according to the compiler.
6  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 08, 2010, 12:43:48 am
Global or local variables makes no difference.  It is a serious problem with the function.  As you can see, my code is utterly simple.  I was hoping it might be a conflict with the Serial output, but that is not it.  I tried basically the same thing but storing the data in an array, and then outputting as a batch...but I get the same data.  The problem is in micros().  It should be quite easy to diagnose, because it it very consistent.
7  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 07, 2010, 11:30:43 pm
Well, I've gotten into this deeper than I wanted to.  The Timer1 and Timer3 code do not support a a one time timer (such as interrupt me in 1,234,567 usec), I needed just this--accurate to within 1 usec--which the Arduino supports quite nicely..  However, in verifying my code, i was using micros(), and discovered a problem with it.  This program below does nothing but read micros, but occasionally subsequent reads are lower than previous reads:


void setup(){
   unsigned long x, xLast=0, y = 0;
   int count = 0;
      x = micros();
      if (x < y){//This should never happen (except overflows)
         Serial.print(" ");
         Serial.print(" ");
         Serial.print(x - xLast);//Time between last error and this one
         Serial.print(" ");
         Serial.println(y - x);//Always the same difference
         xLast = x;
         if (count > 100) break;//So no runaway
      y = x;

void loop(){

4100 5116 4100 1016

16388 17404 12288 1016

30724 31740 14336 1016

43012 44028 12288 1016

56324 57340 13312 1016

70660 71676 14336 1016

83972 84988 13312 1016

96260 97276 12288 1016

111620 112636 15360 1016

128004 129020 16384 1016

145412 146428 17408 1016

159748 160764 14336 1016

175108 176124 15360 1016

188420 189436 13312 1016

201728 202748 13308 1020

I looked at the micros() code very briefly, and noticed that it turns interrupts off while reading the overflow counter.  Would this turn the SIGNAL interrupt off, so that if there was an overflow while executing the micros code, wouldn't the overflow  be missed?  If so, maybe the code could check the overflow flag after it restores the interrupts.  I didn't study the micros() code very thoroughly, but clearly there is an important problem here.

The micros() function is one function that should behave reliably, because a lot of other code may be depending on it.
8  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Confusion with micros() on: November 07, 2010, 12:10:52 pm
Thank you westfw.  Your explanation makes sense.  I discovered the Almel spec sheet which has a thorough explanation of how the timers work, and now it is starting to come together.  I didn't know how micros() worked, until your post.
9  Forum 2005-2010 (read only) / Bugs & Suggestions / Confusion with micros() on: November 06, 2010, 01:31:18 pm
Using Arduino mega & Linux, this code:

void setup() {
  unsigned long x;
  x = micros();
  x = micros();
  x = micros();
  x = micros();
  x = micros();
  x = micros();

void loop() {

Gives me this output on the monitor:






Removing noInterrupts() yields a sequential output.  Keeping the noInterrupts(),
but changing baud rate to 57600 gives a sequential output.  Can somebody
explain what's happening?
10  Forum 2005-2010 (read only) / Portugues / Um americano que queria comprar coisas em Brasil on: November 08, 2010, 04:44:07 pm
Sou um americano, estou em CA agora.  Eu preciso voltar para minha casa em Floripa logo.  Minha pergunta e:  como a gente pode comprar coisas electronicas em Brasil?  Aqui tudo e facil, barato, e rapido.  Ali eu sempre tenho problemas.  Tem  websites onde a gente pode comprar barato?  Por examplo aqui um Arduino Mega custa $50, para entregar mais ou menos $60 (um ou dois dias).  Quanto custa em Brasil, e onde voces compraram?  E seguro?  Quanto tempo para entregar?

E outra coisas electronicas, como motores, sensores, etc.  Tem boas sites?

Pages: [1]