Show Posts
Pages: 1 [2] 3 4 ... 8
16  Forum 2005-2010 (read only) / Syntax & Programs / delays and interrupts? on: June 04, 2008, 09:08:01 am
i'm working on a relatively complicated program and i'm pushing up against the edge of what i understand.  i'm working on an experimental arduino firmware for RepRap to control the speed of the extruder motor as an RPM (it basically needs to go a constant speed by sensing the actual rotational speed and compensating for any friction, etc.)  here's the setup:

electronics:
* a dc motor, controlled via PWM
* a rotary encoder, read via quadrature encoding using pins 2/3 and an onchange interrupt
* various stepper drivers, etc.

software:
* interrupt driven quadrature reading which sets a 'position error variable' for extruder motor.  forward is positive.
* timer1 interrupt to decrement the 'position error variable' at regular intervals (this is how we get the constant speed)
* timer2 interrupt to measure the 'position error variable' at a regular interval and apply a PID algorithm to control the speed

anyway, it works great... when its just controlling the extruder speed (and nothing else is happening).  however, as soon as i tell the printer to move the extruder head, it freaks out, and occasionally the firmware resets.  after reading through the arduino library source last night, i think it may be a problem with the delayMicroseconds() function in the stepper movement function.

the way the stepper movement works is that it calculates a delay between steps, as well as the number of steps to take, then takes that number of steps with the appropriate delay between them.  generally this delay is between 600 and 3000 usecs.  the function uses the delayMicroseconds() function to wait.  from reading through the function, it appears that it disables interrupts during the delay function.

so, i need a workaround.  i need delays with microsecond precision, but i need them to be able to be interrupted.  the interrupts should be pretty quick, so i'm not super worried about the speed.

can i do something like this: (and how much extra time would it use?)

for (i=0; i<delay_microseconds; i++)
  delayMicroseconds(1);

or, should i write my own delayMicrosInterruptible() that doesnt disable the interrupts?

the code in question is all located here: http://svn.reprap.org/trunk/reprap/firmware/Arduino/GCode_Interpreter_Experimental/
17  Forum 2005-2010 (read only) / Syntax & Programs / Re: bizarre restart bug: calling arduino ninjas. on: February 26, 2008, 05:55:03 pm
just wanted to say that this was fixed!

the problem was that i was accidentally enabling an interrupt for which there was no corresponding handler function.  the result:  the interrupt got called, jumped to the function at address 0 (beginning of program) and started over.

note to self:  i will not enable interrupts i do not fully understand!
18  Forum 2005-2010 (read only) / Syntax & Programs / bizarre restart bug: calling arduino ninjas. on: February 17, 2008, 08:46:25 pm
Hey all,

So, I've been working on some code for the Arduino for a little over a month now.   The last 2 weeks have been spent fighting a real bastard of a bug.  I have years of experience programming, so I'm not a n00b, but this is also my first major microcontroller project.  I've read tons of stuff on the arduino, atmega168's, etc.  I'm basically at wits end and am hoping that some genius from the forums can help.

first, the program i'm writing is the Arduino firmware for a RepRap machine.  i'm trying to squeeze into a program a 3-axis stepper controller, some temp sensing, and some other random stuff.  The arduino is the brains and it controls an array of boards that do the actual work.  The RepRap project has a host program written in java that sends and receives commands over a serial connection.  I'm essentially just implementing that protocol on an Arduino.  Easy, right?

The approach I took was to write libraries, and use these to handle the code.  There is a copy of the most recent code, located here: http://www.osotite.com/dump/reprap-arduino-firmware-2008-02-17.zip

Okay, so lets get down to the problem.  Basically what is happening is that there are a few certain circumstances that trigger the program to reset.  I have debug code in the setup() function that prints out 'begin'.  I'll run the host software for a bit until the bug is triggered, at which point the setup() function seems to get run AGAIN!  The 'begin' string will be printed out, and program execution will continue as normal (well, except everything is reset!)

Like I said, I've spent weeks on this bug, so I've narrowed it down to a couple of very specific cases.  The simplest on is that i'll trigger a 'homereset' on the Y axis, then do a 'seek' to any point.  that will cause it to take a few steps, then reset.  the bizarre thing is that this only happens to the Y axis!!  both the x and z axes can home then seek no problem.  also, when the y axis is not at home, it can seek around no problem.

I've tried nearly everything I can think of to try and track down this bug.

I dont think its a brown-out reset, because the arduino doesnt  hit the bootloader... it goes straight to the beginning.  Not only that, but I have a random movement tester that works 100% fine with the boards... no resets. (also, the bug happens with the stepper boards unconnected!)

i dont think its a timer issue because this happens when i run it at 1 RPM, and the stepper interrupt runs just fine at high speeds (300+ RPM)

The only thing I can think of right now is 1) a bug in my software, possibly because i'm doing something wrong the microcontroller doesnt like.

would someone please look over my code, both the libraries and the sketch called 'Single_Arduino_SNAP'?  i'm really in a bind here because not only does my firmware not drive my boards, but it also doesnt work for anyone else out there who is trying to run a RepRap machine off an Arduino.

if you find the bug, i promise i'll send you something very special that i printed with my machine.
19  Forum 2005-2010 (read only) / Syntax & Programs / Arduino Memory Limit on: January 28, 2008, 04:33:09 pm
What happens when you go over the Arduino memory limit?  I'm trying to debug a problem where a value in my program sometimes goes back to 0.  Are there errors in the compilation stage, or does everything just go weird?

Thanks,
Zach
20  Forum 2005-2010 (read only) / Syntax & Programs / Re: Serial read integer? on: October 08, 2007, 06:17:32 pm
I think those functions would be nice, but its rather verbose.  Even if they are there, I'm sure that many people, including myself are just going to write our own readInt() functions. you could always create those functions, and then use them in the background of the Serial.readInt() function.

what other data types are 2 bytes that are commonly used?

at the very least, it would make sense for the Serial.print() to mirror the capability of Serial.print() in what data types it can handle.

aside from that, does my code look right?
21  Forum 2005-2010 (read only) / Syntax & Programs / Serial read integer? on: October 08, 2007, 04:52:48 pm
Hey,

I need to read in an integer for a program.  I think I figured out the code to do it, but I don't have an arduino handy to test it on.  Let me know what you think of this function:

Code:
int function readInt()
{
      int tmp;

      //read in an integer.
      tmp = Serial.read();
      tmp = tmp << 8;
      tmp |= Serial.read();
      
      return tmp;
}

Also, it seems like something like this should be a part of the Serial library.  Any thoughts on that?  It might also be nice to have a readLong() function as well.

~Hoeken
22  Forum 2005-2010 (read only) / Syntax & Programs / Re: driving steppers with timers. on: November 15, 2007, 01:11:11 pm
okay, so i forged ahead and decided to give it a go.  i'm using pretty much all of the digital pins for stepping, so i felt it was okay to use one of the timers dedicated to PWM for it.  i went with TIMER2 for no particularly good reason.  the biggest thing i'm confused about is how to set it up to work correctly.  here's what i came up with:

Code:
     //output mode = compare output, non pwm clear OC2A on match
      TCCR2A |= (1<<COM2A1);
      TCCR2A &= ~(1<<COM2A0);

      //waveform generation = mode 2 = CTC
      TCCR2B &= ~(1<<WGM22);
      TCCR2A |= (1<<WGM21);
      TCCR2A &= ~(1<<WGM20);
      
      //set our prescaler to 8. one tick == 0.5 microseconds.
      TCCR2B &= ~(1<<CS22);
      TCCR2B |= (1<<CS21);
      TCCR2B &= ~(1<<CS20);

      //set the max counter here.  interrupt every 50 microseconds. (0.5 micros * 100) = 50 micros
      OCR2A = 99;

what i want is for this to count from 0-99 (100 ticks) with each tick happening every 0.5 microseconds.  the stepper handler gets called every 50 microseconds.  then i can use this interrupt handler to generate stepping signals:

Code:
SIGNAL(SIG_OUTPUT_COMPARE2A)
{
//handle our stepping here.
}

does this look good?  i havent been able to test it yet.  hopefully i'll be able to get to the lab on friday to test it.

thanks in advance guys!
23  Forum 2005-2010 (read only) / Syntax & Programs / driving steppers with timers. on: November 14, 2007, 10:14:31 am
hello all,

i've been working on stepper driver code for a while and now i think its time to take it to the next level and generate the stepping signals based on timer interrupts.  i'll lay out my initial thoughts and then my questions and hopefully someone can give me some pointers.

1. my standard usage case is going to be driving my 200-step motors in half-step mode (ie... 400 steps / revolution)  Generally I think the speeds will be from 0-200 RPM, but the ability for higher speeds would be nice as well.

2. Working from that, I've determined the range of delays I would need to get the desired speeds with this formula:

delay = 60 seconds / (RPM * steps)

so, here's some of the data i've come up with:

1500 RPM
(60 seconds) / (1500 * 400) = 100 microseconds

1000 RPM
(60 seconds) / (1000 * 400) = 150 microseconds

750 RPM
(60 seconds) / (750 * 400) = 200 microseconds

500 RPM
(60 seconds) / (500 * 400) = 300 microseconds

400 RPM
(60 seconds) / (400 * 400) = 375 microseconds

300 RPM
60 seconds / (300 * 400) = 500 microseconds

200 RPM
(60 seconds) / (200 * 400) = 750 microseconds

132 RPM
(60 seconds) / (132 * 400) = 1136.36 microseconds

100 RPM
60 seconds / (100 * 400) in microseconds

43 RPM
(60 seconds) / (43 * 400) = 3488.37 microseconds

1 RPM
(60 seconds) / (1 * 400) = 150000 microseconds

okay, so judging from that i should be able to decide how often i need to interrupt to generate accurate signals.  obviously the higher the better, but that also means less time for the rest of the code.

i'm thinking every somewhere from 50-100 microseconds would be a decent speed.  i'm not sure on the maths, but i came up with this formula to give me the number of instructions i can do per interrupt:

(1/16 000 000) second = 0.0625 microseconds (time per instruction)
50 / 0.0625 = 800 instructions
75 / 0.0625 = 1200 instructions
100 / 0.0625 = 1600 instructions

now in the interrupt i dont have to do much, so i think i should be able to do those speeds.  here's what i need to do (for 3 or 4) stepper motors)

1. check an int step counter to see if its > 1  (ie how many steps do we have left)
2. do a modulus on the long counter with the int delay variable to see if its time to step again.
3. do 2 digital writes to send a pulse
4. decrement the int step counter

now that i've done a brain dump of what i've been thinking about... here are my questions:

1. what timers do i have available?  it would be nice to still have the PWM available, but i could probably live without them since i'm turning the arduino into a 3+ axis stepper controller.

2. what speed do i set it to, and how do i set it up?  i need to be able to do really slow speeds as well as fast, so i'm guessing i'll need to make some sort of counter that is a long to hold the number of ticks.

sorry about the novel, but hopefully someone reads through it and is able to help me.
24  Forum 2005-2010 (read only) / Syntax & Programs / Re: defining classes within a sketch? on: November 19, 2007, 01:11:53 pm
hey roy,

i'm not entirely sure if you can create classes in a sketch...  in C++ you need both a header file and a content file that contains the actual code.

a header contains somethign like this:

class entity {
  public:
  void Set(int foo);
  int Get(void);
  int internal;
}

then in your content file you have the actual code.

its actually really easy to create a library file... and then your code is re-usable too!!  i highly suggest doing it.
25  Forum 2005-2010 (read only) / Syntax & Programs / Re: another function problem on: November 15, 2007, 01:47:16 pm
that looks good to me, but there is probably some minor syntax error causing it to break.  if you post your full code i can help you track it down.
26  Forum 2005-2010 (read only) / Syntax & Programs / Re: Real-time control from Java on: November 13, 2007, 05:47:08 pm
you may want to take a look at this: http://www.arduino.cc/playground/Interfacing/Processing

processing is a sweet, easy to use platform/framework based on java.  there is also a way of using a library in java where you call arduino.digitalRead(pin) directly in java and the library communicates with the arduino, and the arduino does it.

i've never used it personally, but it looks like what you're looking for.
27  Forum 2005-2010 (read only) / Syntax & Programs / Re: OOP support on: November 13, 2007, 05:49:29 pm
hey idover,

the arduino does support OOP!  i've created a few libraries for it here:  http://svn.reprap.org/trunk/users/hoeken/arduino/library/

there is also a tutorial on creating your own libraries here: http://www.arduino.cc/en/Hacking/LibraryTutorial

its a bit tricky, but i'm really enjoying OOP on the arduino =)
28  Forum 2005-2010 (read only) / Syntax & Programs / Re: Running out of memory? on: November 13, 2007, 05:43:49 pm
hmm... i havent run into any problems yet, but i could definitely see the potential for it, especially since i'm trying a full-on object oriented approach as well as doing something rather complicated (3 axis controller w/ limit switches + serial comms)
29  Forum 2005-2010 (read only) / Syntax & Programs / Running out of memory? on: November 09, 2007, 03:25:19 pm
What happens when you try to use more memory than the Arduino has?  Does the compiler error?  Does your code just do weird things, etc?

Also, how much does it have?  i've read 1k in various places, is that right?
30  Forum 2005-2010 (read only) / Syntax & Programs / Re: Serial in another class on: November 09, 2007, 03:29:59 pm
yay!  i figured it out.  simply do this in your .h file:

#include "HardwareSerial.h"

(well, that lets it compile.  i'm assuming that it will also run correctly as well.  havent tested yet.)
Pages: 1 [2] 3 4 ... 8