Show Posts
Pages: 1 2 [3] 4 5 ... 10
31  Forum 2005-2010 (read only) / Syntax & Programs / Re: GICR |= (1<<INT0) on: December 29, 2006, 05:37:18 pm
Hey Macsimski,

I'm glad I could be of help!  I have been programming in C/C++ for over 15 years now, so it is fun to use some of that experience to help other people.

On the other hand, one thing I have no experience with is how the Wiki stuff here is used... I don't know what is appropriate or how to format things.  I would be willing to take the stuff I wrote here and expand it for a general FAQ entry, but I have no idea where to begin.  Can someone "official" at Arduino help me?

- Don
32  Forum 2005-2010 (read only) / Syntax & Programs / Re: GICR |= (1<<INT0) on: December 28, 2006, 03:52:24 pm
The |= is called the "bitwise-OR assignment operator".  Doing this:

    x |= y;

is the same as the following:

    x = x | y;

Both expressions do a bitwise OR of the values of x and y, then store the result in x.
What is a bitwise OR?  That means each bit of both x and y are independently processed according to this rule:  if either or both bits are 1, the result is 1, but if both bits are 0, the result is 0.

The expression like (1<<INT0) is called a left-shift.  It literally causes the bits in the left operand to be shifted left by the count specified by the right operand.  Because the computer represents all numbers internally using binary, doing (1<<A) is the same as raising 2 to the A power.  For example:

    1 << 0 == 1
    1 << 1 == 2
    1 << 2 == 4
    ...
    1 << 8 == 256
    etc

This might make more sense if we express everything in binary, as is now supported by Arduino:

   1 << 3 == B1000

So, when I look in various header files, I find:

#define    INT0    6

Now let us consider what happens when you do: GICR |= (1<<INT0).  Suppose the current value stored in GICR (in binary) is 00000011.  The value of (1<<INT0) is (1<<6), which in binary is 01000000.  So when you do a bitwise or of 00000011 and 01000000, you get: 01000011.  Then this value is stored in GICR.  So the net result is that you have made sure that the given bit is set to 1 inside GICR.

So now, the other part of your question:  how do you turn that bit back off?  To do this, we need to introduce 2 more operators:  bitwise AND, and bitwise NOT (also known as one's complement).  The expression

   x &= y;

is the same as:

   x = x & y;

In both cases, a given bit in both x and y must be 1 for a 1 to end up being stored back in x.  For example, expressed in binary, 00001111 & 01010101 == 00000101.

The bitwise NOT operator is a tilde character '~'.  It is a unary operator, meaning it operates only a single value that follows it.  In binary, the value of ~01000000 == 10111111.  So, to answer your question, the way to turn off a bit would be something like:

    GICR &= ~(1<<INT0);

Let's see how this works:  Suppose that GICR is 01000011, because you have already set the bit, and now you want to turn that bit back off.  The value of (1<<INT0), as we have already seen, is 01000000.  So the value of ~(1<<INT0) is 10111111.  Then when we AND 01000011 with 10111111, only the bits that are 1 in both will be 1 in the result, which is 00000011.

I hope this helps explain the bitwise operators in C++.
33  Forum 2005-2010 (read only) / Syntax & Programs / Re: array help on: February 08, 2007, 04:06:01 pm
Actually, I think you need to set i=0, not just reset it afterward.  In other words, you need "i=0;" before "while (i<smiley-cool".  Otherwise, the value of "i" is not initialized to any particular value.
34  Forum 2005-2010 (read only) / Syntax & Programs / Re: having trouble programming the solenoids on: January 22, 2007, 10:29:54 am
I did not study your code very carefully, but I did notice something that is most certainly not what  you want.  You declare global variables like:

  int oscOn1;
  int oscOn2;
  int oscOn3;
  int oscOn4;

Then, inside your setup() function, you declare other local variables that have the same name:

void setup()
{
  // ....
  int oscOn1=24;
  int oscOn2=24;
  int oscOn3=24;
  int oscOn4=24;
}

Doing this has no effect, because those are local variables, meaning they cease to exist as soon as the setup() function returns.  You should either remove the "int" so that you are no longer hiding the global variables with new local variables, like this:

void setup()
{
  // ....
  oscOn1=24;
  oscOn2=24;
  oscOn3=24;
  oscOn4=24;
}

Or, even better in my opinion, go ahead and initialize your global variables at the same time you declare them:

  int oscOn1=24;
  int oscOn2=24;
  int oscOn3=24;
  int oscOn4=24;

  void setup()
   {
        // ....
   }

Hope this helps!

- Don
35  Forum 2005-2010 (read only) / Syntax & Programs / Re: some syntax not in arduino refernce guide? on: January 20, 2007, 12:52:47 pm
Here is another example of using a function:

Code:
int sum_of_squares (int x, int y)
{
    return (x*x) + (y*y);
}

void setup()
{
    Serial.begin (9600);
}

void loop()
{
    Serial.println (sum_of_squares(3,4));
    delay(1000);
}

See if you can figure out what this code does.  Then try running it on your board with the serial monitor watching to see if you are correct.
36  Forum 2005-2010 (read only) / Syntax & Programs / Re: some syntax not in arduino refernce guide? on: January 20, 2007, 12:47:18 pm
This will explain a lot of the mysterious operators you see in C++:

http://www.arduino.cc/playground/Code/BitMath

To answer some of the syntax questions that won't be explained there:

Code:
byte qt401_transfer(byte data_out)
{
    // ... code omitted ...
}

This is an example of a function declaration.  The part inside parentheses is the list of parameters that are supposed to be passed to the function.  It says, this function requires one parameter, of type "byte", and it is named "data_out".  So you would call this function using something like:

Code:
   byte return_value = qt401_transfer(17);

This would send the byte value 17 as "data_out" inside the function qt401_transfer.  As soon as the function returns, data_out no longer exists.  It acts a lot like a local variable declared inside the function, only its value is passed in by the caller.  

Whatever value is returned by the function (using the "return" statement) gets assigned into "return_value" in this example.

The operators like "--" and "++" are decrement and increment respectively.  The "--" operator decreases a variable by 1, and "++" increases by 1.

If the "--" or "++" comes before the variable it modifies, the increment/decrement is performed before the value of the variable is used.  This is called pre-increment/pre-decrement.  If it occurs afterward, the value of the variable is used, and then it is incremented/decremented, and this is called post-increment/post-decrement.

For example:

Code:
   int x = 57;
    Serial.println (x);    // will display 57 on the serial monitor
    Serial.println (x++);  // also displays 57, because x is incremented after its value is accessed
    Serial.println (x);    // x is now 58, so that is what you will see
    Serial.println (++x);  // x is incremented before its value is used, so you will see 59.

37  Forum 2005-2010 (read only) / Syntax & Programs / Re: printing BYTE (8bit) to serial on: January 10, 2007, 09:30:28 am
As far as I can tell (without my hardware right now, but looking at runtime code), I see no reason why Serial.print(x,BYTE) should limit you to 7 bits... 8 bits should work just fine.
38  Forum 2005-2010 (read only) / Syntax & Programs / Re: need a quick syntax check (pwm led + pushbutto on: January 16, 2007, 10:06:52 pm
You're welcome... and the kitty says... Meow!  smiley
39  Forum 2005-2010 (read only) / Syntax & Programs / Re: need a quick syntax check (pwm led + pushbutto on: January 16, 2007, 07:36:15 pm
The thing I notice is that most of the program logic is based on the value of the variable "i"... but you never change the value of the variable "i".  It is always zero.
40  Forum 2005-2010 (read only) / Syntax & Programs / Re: Serial.print on: January 08, 2007, 09:56:02 pm
It prints to the serial port.  You can monitor this with the "Serial Monitor" built into the Arduino IDE (it's the rightmost of the buttons above the editor window).  You need to call Serial.begin(baudrate) before doing Serial.print().  Put that in your setup() function.  Then click on the Serial Monitor button and set the same baud rate.  Hope this helps...
41  Forum 2005-2010 (read only) / Syntax & Programs / Re: how to make and use a class on: January 06, 2007, 03:10:05 pm
OK, now I understand.  I too have had problems trying to #include a header file in the same directory as my sketch.  Looks like Arduino does NOT put the sketch directory inside the C++ include path.  But it looks like maybe you are trying to make a reusable library.  Try taking a look at this:

http://www.arduino.cc/en/Main/Libraries
42  Forum 2005-2010 (read only) / Syntax & Programs / Re: how to make and use a class on: January 06, 2007, 01:23:20 pm
Please post your code and I will see if I can help.
43  Forum 2005-2010 (read only) / Syntax & Programs / Re: how to make and use a class on: January 06, 2007, 11:43:47 am
I see a few things that might help:
- Make sure you put a semicolon ';' after the final '}' in the class declaration.
- you will need to make some things "public" if you access them from outside the class.  By default, members of a class are "private".
- You should declare variables as members of the class if they are part of the object.

Here is an example of what I mean:

Code:
class OneWireLib
{
public:
    OneWireLib()
    {
        int y =1;       // this 'y' will go away once the constructor returns (it is a local variable)
        somevar = 99;     // initialize class member variables here in the constructor
    }

    void ConvertTemp()
    {
         int x =1;
    }

    int GetSomeVar()    // example of method for using private data
    {
        return somevar;
    }

private:
     int somevar;      // put variables that are part of the object here
};        // <===  note semicolon here... terminates the class declaration

OneWireLib  onewire;     // declare an instance of the OneWireLib class

void setup()
{
    int x = onewire.GetSomeVar();     // example of calling a class method
}
44  Forum 2005-2010 (read only) / Syntax & Programs / Re: reset millis() ? on: January 03, 2007, 07:33:14 pm
To go off on a tangent a little bit, I wondered when  I saw the source code that functions like millis() did not disable interrupts while accessing timer0_overflow_count:

Code:
unsigned long millis()
{
    // (comments omitted)
    return timer0_overflow_count * 64UL * 2UL / (F_CPU / 128000UL);
}

Because it requires multiple atmega8 instructions to fetch the value of a 4-byte long integer like timer0_overflow_count, isn't it possible for a timer interrupt to occur in the middle of those instructions and mess up the result?  I wonder if the following might make the code safer:

Code:
unsigned long millis()
{
    // (comments omitted)
    unsigned long safe_copy;

    cli();    
    safe_copy = timer0_overflow_count;
    sei();

    return safe_copy * 64UL * 2UL / (F_CPU / 128000UL);
}

Likewise, to reset the timer to zero, it might be better to do:

Code:
cli();
timer0_overflow_count = 0;
sei();
45  Forum 2005-2010 (read only) / Syntax & Programs / Re: reset millis() ? on: January 03, 2007, 05:30:04 pm
Instead of using millis(), you could use timer0_overflow_count directly.  Just add this toward the top of your sketch:

    extern volatile unsigned long timer0_overflow_count;

The only tricky bit is that it will not be quite milliseconds.  Each increment of timer0_overflow_count is 125/128 of a millisecond, or 0.9765625 milliseconds.  But the nice thing is that it will take a lot longer for this to overflow:  48.5 days by my calculations.

You would also have to avoid any runtime function that uses millis(), such as delay().
Pages: 1 2 [3] 4 5 ... 10