Show Posts
Pages: 1 2 [3] 4 5 ... 7
31  Forum 2005-2010 (read only) / Syntax & Programs / Re: PID Library motor control example? on: January 11, 2010, 12:34:58 am
I think this clamping code:

Quote
Code:
if(integralPart < antiWindUpLimit) then
integralPart = -antiWindUpLimit;

should read:

Code:
if(integralPart < -antiWindUpLimit) then
integralPart = -antiWindUpLimit;
32  Forum 2005-2010 (read only) / Syntax & Programs / Re: Data parsing question on: August 15, 2010, 07:32:46 pm
Quote
Bad boy, zoomkat. The break command will get out of the while loop just as well, without the need for spaghetti code.

Indeed, however in this case it's functionally identical, in fact GCC will generate exactly the same output in this type of construct (jump to the next instruction outside a loop), and it may be argued that "break" is more opaque than "goto" in this case. No spaghetti code in sight, IMHO.
33  Forum 2005-2010 (read only) / Syntax & Programs / Re: which features of C++ are supported on: August 02, 2010, 10:16:20 pm
Quote
The most conspicuous unsupported features are "new" and "delete".

Someone else may have a different opinion, but I believe the specific answer is that there is no default implementation of new and delete, however they are operators and may be overloaded on a per-class basis. Hence you can implement your own allocator for your classes. The main issue is that you will need to manage your own heap and the details of ensuring that it doesn't extend down into the stack are likely quite complex.

Also, there is no STL support, and apropos built-in types, short and int are 16 bits, long is 32 bits and float and double are identical (32-bit floating-point).

Quote
The "Morse morse(13);" example creates an instance of the class, and calls the constructor for the class, but does so in statically allocated memory.

Sort of. The calculation of the amount of space each object requires is done at compile time, the space is allocated on the stack at runtime.

For instance, if a function foo() defines an object of type Morse:

Code:
void foo() {
 Morse morse(13);

 <do something>

 return;
}

and another function bar() calls foo():

Code:
void bar() {
 int someInt;

 foo();

 return;
}

and the loop() calls both:

Code:
void loop() {
  int anInt;

  foo();
  bar();
}

During the first call to foo() (directly from loop()), the Morse object is created on the stack at a particular memory location, and destroyed when the function call returns. During the second call to foo() (via bar()), the Morse object will be in a different location in memory as there is a stack frame for the bar() function active (with the someInt variable in it).



 
34  Forum 2005-2010 (read only) / Syntax & Programs / Re: Finding an angle from a Joystick (x and y value) on: June 29, 2010, 08:40:03 pm
Quote
Hi, I am currently developing a robot with the Wii nunchuck and I am trying to find a way to deduce the angle in degree that forms my x and y value with the center of the joystick. I though of a way using the atan() method but It will only work for angle bigger than 45 degree

That's exactly what atan2(x, y) is for.
35  Forum 2005-2010 (read only) / Syntax & Programs / Re: Classes on: June 10, 2010, 07:20:18 pm
Quote
A class isn't a function

Correct, also: A class isn't an object, it's a type. This means you need an object to operate on:
Code:
class Test
{
  public:
    void Blink(int led)
    {
      digitalWrite(led,HIGH);
      delay(500);
      digitalWrite(led,LOW);
      delay(500);
    }
};

void setup()
{
  pinMode(PORTB,OUTPUT);
}

void loop()
{
  Test tester; // instantiate an object of type Test (a class)

  tester.Blink(13); // call the class method on the object
}
  
36  Forum 2005-2010 (read only) / Syntax & Programs / Re: Effect of 'goto' on stack? on: June 09, 2010, 07:59:07 pm
Quote
There is *always* a better way of doing things in C.

There are some specific use-cases where the judicious application of goto results in faster, more readable (and hence more maintainable) and less error-prone code.

Device-driver code that sequentially allocates resources before performing actions, where failure to allocate a resource requires the de-allocation in the reverse order is one example. Using nested "if" statements in this case pushes the main code path deep into the nesting, obfuscating the code's function.

Goto has a place in the language, but it's definitely an advanced technique that should be considered only with strong justification.
37  Forum 2005-2010 (read only) / Syntax & Programs / Re: Auto-fish-feeder...how to keep track of time? on: December 08, 2009, 05:17:39 am
Quote
I suppose you could do something like this

Not really necessary.

Code:
unsigned long time;
unsigned long feedfishtime = 0;

void loop() {

    time = millis();

    if ((time - feedfishtime) > 86400000) {
        feedFish();
        feedfishtime = time;
    }
}

The magic of unsigned two-complement arithmetic will ensure that even when millis() rolls over and time < feedfishtime the result of the subtraction will trigger the feeding at the correct time.
38  Forum 2005-2010 (read only) / Syntax & Programs / Re: NEW on-off cycle question!!! on: May 20, 2010, 06:33:26 am
Quote
Bzzzt!

I didn't say it was tested  smiley-wink
39  Forum 2005-2010 (read only) / Syntax & Programs / Re: NEW on-off cycle question!!! on: May 19, 2010, 09:12:30 pm
How about this:

Code:
#define _5MIN 300000
int pin = 12;
long randOn = 0;
long remaining;

void setup()
{
 pinMode(pin, OUTPUT);
}

void loop()
{

 remaining = _5MIN;

 while (remaining >= 0)
 {
  randOn= random(0,10);
  if (randOn > 5)
  {
   digitalWrite(pin, HIGH);
   delay(100);
   digitalWrite(pin, LOW);
   delay(100);
   remaining -= 200;
  }
  else
  {
   digitalWrite(pin, HIGH);
   delay(400);
   digitalWrite(pin, LOW);
   delay(100);
   remaining -= 500;
  }
 }

 delay(_5MIN * 2 + remaining); // 10 minutes minus whatever we exceeded the 5 minutes by.
}

We keep track of the 5 minutes active time with the "remaining" variable, which is decremented each time we spend some time doing something. When the 5 minutes is up, "remaining" will be < 0, in which case we reduce the 10 minute delay by the amount we went over, resulting in a total of 15 minutes spent in the full loop{}.
40  Forum 2005-2010 (read only) / Syntax & Programs / Re: Sizeof one strings in an 2D array on: April 28, 2010, 01:36:53 am
Quote
The terminating character for a C character string is '\0'

a.k.a "ASCII NUL"

so "NULL" is incorrect, but "NUL" is okay.
41  Forum 2005-2010 (read only) / Syntax & Programs / Re: Maybe a simple C++ Question [crosspost] on: January 27, 2010, 06:11:42 pm
Your problem here is that pointers to object member functions are not the same as pointers to ordinary (anonymous) functions. They look the same but they have an implicit this pointer in the signature, so that the runtime can figure out which actual objects function instance to call. The callback member function needs to be static (ie. one for the whole class, not one per object) to use the simple method.

Have a look at http://www.newty.de/fpt/callback.html.

Try this:

Code:
class B : public A
{
 private:
   static void _privateSubmitter();
  
 public:
   B( char* Authorization );

};

It compiles for me.
42  Forum 2005-2010 (read only) / Syntax & Programs / Re: Maybe a simple C++ Question [crosspost] on: January 26, 2010, 11:43:42 pm
Quote
Now what if the parameters for 'a' had nothing to do with the parameters for b?

You need another class to initialise the parameters for A:

Code:
class A {
public:
      A(int param) { }
};

class InitA {
public:
      InitA(int &param) { param = complexLogicThatCalculates_As_arg }
};

class B {
public:
      B(int param) : InitA(_As_arg), a(_As_arg)
                { whatever initialisation B needs }
private:
      int _As_arg;
      A a;
};

void setup() {
      B b(3);
}

void loop() {}

Quote
what if there is an array of As?

No, C++ currently does not support member array initialisation. The following works for primitive types but not user-defined classes. You could probably do it with std::vector but the Arduino compiler library doesn't support the STL AFAIK.

Code:
class A {
public:
      A(int param) {}
};

class InitA {
public:
      InitA(int (&param)[10]) {
            param[0] = ...;
            param[1] = ...;
            param[2] = ...;
            ...
      }
};

class B {
public:
      B(int param) : InitA(arrOfint) {}
private:
      int arrOfint[10];
};

void setup() {
      B b(3);
}

void loop() {}

or maybe even like this:

Code:
class A {
public:
      A(int param) {}
};

class InitA {
public:
      InitA(int (&param)[10]) {
            param[0] = ...; // Calculate c-tor parameter here
            param[1] = ...;
            param[2] = ...;
            ...
      }
};

class B {
public:
      B(int param) : InitA(arrOfint),
            arrOfA[0](arrOfint[0]),
            arrOfA[1](arrOfint[1]),
            arrOfA[2](arrOfint[2]),
            arrOfA[3](arrOfint[3]),
            arrOfA[4](arrOfint[4]),
            arrOfA[5](arrOfint[5]),
            arrOfA[6](arrOfint[6]),
            arrOfA[7](arrOfint[7]),
            arrOfA[8](arrOfint[8]),
            arrOfA[9](arrOfint[9]) { init B}
private:
      int arrOfint[10]; // array of As c-tor parameters
      A arrOfA[10];
};

void setup() {
      B b(3);
}

void loop() {}


Quote
or if there is another class "C"

This one's easier, member initialisation is a list, combine with the above methods if required.

Code:
class A {
public:
      A(int param) {}
};

class InitC {
public:
      InitC(int &arg1, int &arg2, int &arg3) {
      arg1 = complexLogicThatCalculates_Cs_first_arg;
      arg2 = complexLogicThatCalculates_Cs_second_arg;
      arg3 = complexLogicThatCalculates_Cs_third_arg;
      }
};


class C {
public:
      C(int p1, int p2, int p3) {}
};

class B {
public:
      B(int param) : a(param), InitC(cp1, cp2, cp3), c(cp1, cp2, cp3) {}
private:
      A a;
      int cp1, cp2, cp3;
      C c;
};

void setup() {
      B b(3);
}

void loop() {}

The main gotcha to remember is that the members are initialised in order of declaration in the class, not the order that they appear in the initialisation list.

Search for "C++ member initialization list" or "C++ array member initialization" and you'll get the details of the language syntax required.
43  Forum 2005-2010 (read only) / Syntax & Programs / Re: millis() rollover on: December 08, 2009, 05:21:20 am
Quote
Oh I see now, very clever.

So in response to your original post:

Since your code is using a subtraction, it will work correctly across the millis() rollover without modification.
44  Forum 2005-2010 (read only) / Syntax & Programs / Re: millis() rollover on: December 07, 2009, 09:10:38 pm
Assuming standard operating procedure is that you have a main loop executing, and you want to perform some action periodically.

After you perform the action (straight away the first time through the loop), you save the current millis() and continue. Next time around the loop you read the value of millis() again and subtract the value obtained last time you performed the action. If the subtraction results in a number that is larger than your period then you perform the action again and get the new version of millis(), otherwise you don't.

Assume for the sake of this explanation that millis() is only an 8-bit number (the concept extends to 16- and 32-bit numbers equally well).
Also assume you want your periodic function to run every 30 ms, and that the loop takes 10 ms.

First time through the loop you perform your action and get the value of millis():
Code:
unsigned char last = millis()
Let's say last = 8. Next time around the loop millis() returns 18, so you do the subtraction:
Code:
00010010 (18: current)
-00001000 (8: last)
---------
 00001010 (10)
this is repeated twice more until millis() returns 38 and then:
Code:
00100110 (38: current)
-00001000 (8: last)
---------
 00011110 (30)
now we would perform the action and last would become 38.
Eventually (after the action had been performed 8 times) last would become 248, then the interesting bits start to happen, the next time through the loop, 10 ms have elapsed so millis() should be 258. 258 cannot be represented in 8 bits, so with rollover millis() would become 2. So now we to the subtraction:
Code:
00000010 (2: current)
-11111000 (248: last)
---------
 00001010 (10)
The arithmetic unit "borrows" a bit (bit 9) and treats the minuend (the number being subtracted from) as if its value was 258 (0x102, 100000001 binary). In other words, inside the CPU the calculation actually looks like this:
Code:
100000010 (258: current)
-011111000 (248: last)
---------
 000001010 (10)
Twice more around the loop and you get this:
Code:
00010110 (22: current)
-11111000 (248: last)
---------
 00011110 (30)
Then you perform your action, set last to 22 and off you go.
45  Forum 2005-2010 (read only) / Syntax & Programs / Re: If statements. on: November 30, 2009, 06:33:29 pm
Code:
// then do the Play Led
   val = analogRead(analogPinPlay);
   if ((val > 400) && (val < 600)) {
     digitalWrite(ledPinPlay, HIGH);
   }
   else {
Pages: 1 2 [3] 4 5 ... 7