Show Posts
Pages: 1 2 3 [4] 5 6 7
46  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 {
47  Forum 2005-2010 (read only) / Syntax & Programs / Re: Bit Flipping Nibbles and Bytes on: October 26, 2009, 05:56:28 pm
My favourite resource for this type of thing is Jorg's fxt book: http://www.jjj.de/fxt/
A library is available too of course.
48  Forum 2005-2010 (read only) / Syntax & Programs / Re: working on buttons and can't find the problem. on: August 17, 2009, 06:21:30 pm
2.2k[ch8486] is fine. 1/2 watt is overkill, but won't make any difference. 5V across a 2.2k[ch8486] resistor will dissipate only 33 mW. You'd need to put 33V across it to dissipate 500 mW. (power in a resistor is V^2/R). Also this resistor will cause the arduino to sink 2.3 mA through the resistor when the button is pressed. Even with a 4 buttons pressed, that's only 9 mA, which the IC can easily handle.
49  Forum 2005-2010 (read only) / Syntax & Programs / Re: working on buttons and can't find the problem. on: August 16, 2009, 11:32:58 pm
Your pins 3, 4 & 5 of X2 are open-circuit (floating) when the switches are not pressed, this will cause digitalRead() to return HIGH sometimes, and LOW sometimes. To make the reading reliable, you need to pull the inputs definitely LOW when the button is not pressed. You do this with a moderate-value resistor connected between the input pin and ground. When the button is not pressed, the input is pulled LOW. WHen the button is pressed, the input is pulled high by the +5V supply, and a small amount of current flows through the resistor.

See: http://en.wikipedia.org/wiki/Pull-down_resistor

The alternative if you don't want to add more hardware is to utilise the ATMega168's internal pull-up resistors on the input pins. You turn them on by writing a HIGH value to the pins when they are set to INPUT mode. You will need to change the other side of your switches to connect to the GND rather than +5V because when the switch is open, the internal pullup will drive the input HIGH. you will also need to change your code so that it interprets a LOW input value as "button pressed".
50  Forum 2005-2010 (read only) / Syntax & Programs / Re: working on buttons and can't find the problem. on: August 16, 2009, 11:09:20 pm
Your inputs are floating when the buttons are open. You need to either:

1. Pull-down your inputs via 4.7k external resistors, or
2. swap your left-hand side connection to GND rather then +5V, enable the internal pull-ups on each input with digitalWrite(inputx, HIGH), and swap your logic so you test for LOW instead of HIGH (since your buttons are now pulling the inputs LOW when pressed.
51  Forum 2005-2010 (read only) / Syntax & Programs / Re: Whats up with GOTO command? on: May 11, 2009, 08:37:01 pm
Unconditional jumps are used extensively in C, "break" and "continue" are both unconditional jumps - "goto" is simply an unconditional jump to a label.

goto's implemented over short distances to clear labels are justified when you need to balance speed, minimisation of stack use and minimisation of code size.

The most useful situation I have seen goto's used is in the context of a device driver, when a sequence of resources need to be secured prior to an operation being performed. In the event of an error associated with the allocation of one of the resources, the resources already allocated need to be released in the opposite order to their allocation (it's good practice to do this to avoid deadlock). goto offers a concise solution to this operational paradigm:

Code:
get resource A
if (error)
  goto out_a;
get resource B
if (error)
  goto out_b;
get resource C
if (error)
  goto out_c;
perform actions;
goto out;
out_c:
  undo C
out_b:
  undo B:
out_a:
  undo A
out:
  return ret;

The alternative, using nested if's, looks worse and requires a lot of extra work if you add another resource to allocate, or if you use functions then you use up limited stack space (unless you inline, and then you get code bloat)

Frankly, if you can follow program flow which uses break or continue (which don't have labels), you should be able to follow program flow which uses goto sparingly and clearly. If you can't, then you have no business touching someone else's device driver code.

Overall, I think that the education strategy of goto avoidance is worthwhile, but at some point you ought to become proficient enough to be trusted with all of a language's features, judiciously applied.

52  Forum 2005-2010 (read only) / Syntax & Programs / Re: Whats up with GOTO command? on: May 07, 2009, 07:44:36 pm
Quote
GOTO is evil, plain and simple

Not true.

Quote
Seriously though you can always write code better without it.

Also not true, and it depends on what you mean by "better". If by "better" you mean any of "more readable", "faster" or "more efficient" then there are many cases where *not* using goto will result in "worse" code.

There's a good discussion on this in the lkml (Linux kernel mailing list) archive from 2003. http://kerneltrap.org/node/553/2131

In this particular case, goto shouldn't be used, and it's initial use reflects the O.P.'s inexperience and that's fine, but making unilateral statements about a language feature that is useful in a small subset of problems is unhelpful. A better rule is "don't use goto unless you have exhausted all other language features and goto still looks better"
53  Forum 2005-2010 (read only) / Syntax & Programs / Re: Problems with floating point division on: April 25, 2009, 05:46:49 am
The problem here is that the float conversion only happens after all the arithmetic evaluation takes place, ie. all the divisions in your code are integer.

You need to cast the chars to floats before you divide and use float literals (like 10.0) rather than integer literals (like 10):

Code:
latFloat = (lat[0]-0x30)*10 + (lat[1]-0x30) + ((lat[2]-0x30)*10 + (lat[3]-0x30) + (float)(lat[5]-0x30)/10.0 + (float)(lat[6]-0x30)/100.0 + (float)(lat[7]-0x30)/1000.0 + (float)(lat[8]-0x30)/10000.0)/60.0;
54  Forum 2005-2010 (read only) / Syntax & Programs / Re: Help with Nunchuck Code on: February 19, 2009, 09:46:44 pm
That wasn't code, it was pseudo-code to illustrate the point. That's why it won't compile. Braces are mismatched for a start.

Try this first - it should give you left & right turn behaviour.

Code:
void loop() {
  chuck.begin();
  chuck.update(); // Read the data from the nunchuck
  x = chuck.readJoyX(); // need to first assign X
  if (x < 100){ // Move one direction
    a.write(2250);
    b.write(750);
    c.write(750);
    d.write(2250);
   }
   else if (x > 160) {// move another direction
      a.write(750);  
      b.write(2250);
      c.write(2250);
      d.write(750);
   }
   else { // i.e. 100 <= x <= 160
   a.write(1500);
   b.write(1500);
   c.write(1500);
   d.write(1500);
   }
}
 

Make sure you declare x above the functions (before setup())

Code:
int x;
55  Forum 2005-2010 (read only) / Syntax & Programs / Re: Help with Nunchuck Code on: February 19, 2009, 05:45:55 pm
You need a better understanding of what values of X & Y the controller is returning when you move the stick around.

I can see some obvious problems with your code.

First I suggest you simply loop and output the values of X & Y to the Arduino console (via serial). That will show you the sort of values you need to test for to decide when to move and in which direction.

Once you have done that you will know what values of X & Y the controller returns when it is centred (I expect the value to be about 128), left (expect X=0), right (expect X=255), forward (expect Y=0) and back (expect Y=255). You can use your "threshold", but not in the manner you are currently doing. Try testing for < 100 and > 160:

Code:
if (x < 100){ "left" }
else if (x > 160) { "right"}
else "stop"

similar for Y. You need to make sure that if you don't completely separate the tests for X and Y as in that case your code (as it stands now) will for instance if X = 200 and Y = 128 (ie joystick is right), your code will test X and command a right turn but then immediately test Y and stop the servos. This means you really need to test both X & Y at the same time and have cases for stop, left, right, forward, back, left-forward, left-back, right-forward and right-back. Once you have determined which of these 9 cases you are in, you can command the servos to move.

Also I suggest you replace the calls to the servos inside your "if" statements with calls to output text (via serial) to the Arduino IDE console, for instance inside your first "if" you should print "backwards". This will let you know whether your code is working without making your servos go crazy.


56  Forum 2005-2010 (read only) / Syntax & Programs / Re: Encryption with arduino board on: December 17, 2008, 08:15:52 pm
Try twofish. It was designed to be implemented on 8-bit hardware, and needs only 36 bytes of RAM (if the key is stored in EEPROM).

Try this search for more info.
57  Forum 2005-2010 (read only) / Interfacing / Re: max with a rotary encoder on: April 16, 2008, 10:10:06 pm
If you pay $100 for your industrial-grade encoder you get nicely conditioned, pristine square waves out of your 2 outputs. A $2 encoder, however, is really two (three if it has a push-button) mechanical switches in a housing, and they are surprisingly bouncy. The Playground code is good for the former, but not the latter. Have a read of http://www.ganssle.com/debouncing.pdf, you will see (page 16) that using interrupts on the output of undebounced switches is a really bad idea unless you are sure the flip-flops in your micro can handle the bounce rise-times & pulse widths.

The solution is to use the debounce code in Ganslee document (page 20), triggered on a 1 ms timer interrupt. I've spent the last few evenings getting the following code to work, and it's really reliable. I've used the FrequencyTimer2 lib from the Playground, but since you have a fixed frequency you can probably hack it down significantly. The core routine (the timer interrupt) appears below, I have omitted the timer setup.

Note that there are four transitions that you can update the value of encoder0Pos on, I am only using one because my encoder goes through all 4 states in one "click", so I get one step per "click". Uncomment the others if yours is different. Note also that encoder0Pos needs to be declared volatile, this prevents the compiler from caching its value if you set it then read it back immediately (the interrupt may have triggered & the value updated between the two operations, you want the updated value, not the one you just wrote).

Add another element to the State[] array and process it in the same manner if you want to debounce the push-button as well. My encoder doesn't have one, so neither does my code.

The code assumes that A & B are connected to pins configured as input ( pinMode(encoder0PinA, INPUT); ), with the internal pullups enabled ( digitalWrite(encoder0PinA, HIGH); ), and the common pin to ground.


Code:
#define encoder0PinA  2
#define encoder0PinB  4

volatile int encoder0Pos = 0;

// Service routine called by a timer interrupt
void DebounceSwitch()
{
  static unsigned char rawEncoder0A = 1;
  static unsigned char rawEncoder0B = 1;
  static unsigned char debouncedEncoder0A = 1;  // debounced state of encoder0PinA
  static unsigned char debouncedEncoder0B = 1;  // debounced state of encoder0PinB
  static uint16_t State[] = { 0, 0  }; // Current debounce status of encoder pins { A, B }

  rawEncoder0A = digitalRead(encoder0PinA);
  rawEncoder0B = digitalRead(encoder0PinB);

  // Encoder Pin A
  State[0]=(State[0]<<1) | rawEncoder0A | 0xe000;
  if(State[0]==0xf000) { // High --> Low Transition
    if (!debouncedEncoder0B) {   // check channel B to see which way
      // encoder is turning  
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }
    debouncedEncoder0A = 0;
  }
  if(State[0]==0xefff) { // Low --> High Transition
    //if (!debouncedEncoder0B) {  // check channel B to see which way
    //  // encoder is turning
    //  encoder0Pos = encoder0Pos - 1;         // CCW
    //}
    //else {
    //  encoder0Pos = encoder0Pos + 1;         // CW
    //}
    debouncedEncoder0A = 1;
  }

  // Encoder Pin B
  State[1]=(State[1]<<1) | rawEncoder0B | 0xe000;
  if(State[1]==0xf000) { // High --> Low Transition
    //if (debouncedEncoder0A == HIGH) {   // check channel A to see which way
    //  // encoder is turning  
    //  encoder0Pos = encoder0Pos + 1;          // CW
    //}
    //else {
    //  encoder0Pos = encoder0Pos - 1;          // CCW
    //}
    debouncedEncoder0B = 0;
  }
  if(State[1]==0xefff) { // Low --> High Transition
    //if (debouncedEncoder0A == HIGH) {  // check channel A to see which way
    //  // encoder is turning
    //  encoder0Pos = encoder0Pos - 1;         // CCW
    //}
    //else {
    //  encoder0Pos = encoder0Pos + 1;         // CW
    //}
    debouncedEncoder0B = 1;
  }

  // Clamp
  if (encoder0Pos < 0) encoder0Pos = 0;
  if (encoder0Pos > 32) encoder0Pos = 32;

}

Hope this helps,

Sam.
58  Forum 2005-2010 (read only) / Development / Re: New MCP23017 library! on: December 30, 2009, 02:21:53 am
This library is GPL licensed. Anybody who doesn't wish to release their source code is unable to use it.

Generally Arduino libraries are LGPL.
59  Forum 2005-2010 (read only) / Development / Re: Overflow-immune timer on: November 28, 2010, 07:20:39 pm
Have a look at his thread for the explanation: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1260223964/1
60  Forum 2005-2010 (read only) / Development / Re: Frequency Measurement FFT, DFT on: February 01, 2010, 08:02:00 pm
Quote
I'm guessing the spectrum data is in "spectrum", so the power of the fundamental should be in "spectrum
  • "
spectrum[0] is the DC component of the input (ie. zero frequency).

If you want the "fundamental frequency", that's the lowest frequency in a harmonic series, which can likely only be found by statistical analysis.

It might be safe to take the "modal" frequency, ie. the frequency bin with the highest value, and call that the fundamental.
Pages: 1 2 3 [4] 5 6 7