Show Posts
Pages: [1] 2 3 ... 25
1  Using Arduino / Programming Questions / Re: Using millis on: August 06, 2014, 09:53:35 pm
Quote
Right after turning on the Arduino Uno, Pin 8 must go HIGH for 9,000 milliseconds. That must be followed by Pin 8 going LOW for 43,191,000 milliseconds.  (This completes a 12-hour time period).  This cycle to repeat indefinitely.

If you want to turn something on for nine seconds every twelve hours why not just say so? Be careful about overcomplicating your thinking.

The thing with millis is that it just starts counting milliseconds, from zero, when the Arduino boots. At any time you can find out this count with the millis() function. It returns an unsigned long value that is the millis count since boot up. If you save this value and then later on get the millis value you can find out the elapsed time with subtraction. Now, go check out blink without delay.
2  Using Arduino / Programming Questions / Re: Newb with Syntax understanding question. on: July 31, 2014, 08:54:16 pm
Code:
  pinMode (onboardled, OUTPUT);

Not sure how it works fine, onboardled is not declared anywhere. It can't compile in that state.

Here is how I would do it. You'll see many similarities except I haven't made extra functions and the debouncing is done by timing rather than delay. You can change the debounce time by changing the constant. I hope the variable names I have chosen make what's happening clear. It also uses internal resistors but could use external with only two minor changes.

Code:
const byte SWITCH_PIN = 8;
const byte LED_PIN = 11;
const unsigned long DEBOUNCE_MS = 50UL;

void setup()
{
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
  static int ledLevel = 0;
  static unsigned long debounceStartMS = 0;
  static int switchPinState = !digitalRead(SWITCH_PIN);

  int switchPinSignal = digitalRead(SWITCH_PIN);
  unsigned long nowMS = millis();

  if (switchPinState != switchPinSignal)
  {
    switchPinState = switchPinSignal;
    debounceStartMS = nowMS;
  }

  if (debounceStartMS && nowMS - debounceStartMS >= DEBOUNCE_MS)
  {
    debounceStartMS = 0;
    if (switchPinState == LOW)
    {
      ledLevel += 51;
      if (ledLevel >= 255) ledLevel = 0;
      analogWrite(LED_PIN, ledLevel);
    }
  }
}

A static variable is persistent just like a global except it is scoped only to the function in which it is declared. If you want to learn C++ it is imperative that you understand variable types and scope.

I haven't tried that particular code but it should do the trick.

The answer to the question is in how functions are declared. the first word , boolean is the return type or the type of variable that will be returned. If nothing is returned the function is declared as void see both loop() and setup() as examples. The return type can be almost any variable type, long, char, unsigned int, but they can't be an array or structure. Then you get the function name that you decide on. The part after the name in brackets declares variable types that will be passed to the function. That int last will be created when the function is called, it will be whatever value is passed and will disappear when the function ends. Again, variable types and scope.
3  Using Arduino / Programming Questions / Re: serial.Print not working on: July 02, 2014, 10:19:48 am
If you maintain a boolean variable true if PM false if AM then you could use the ternary operator.

Code:
boolean pm = true;

Serial.print( pm ? "PM" : "AM" ); // will print PM in this case

That is a functional equivalent to :

Code:
if (ampm ==1)
    {
    Serial.print("PM");
    }
    else
    {
    Serial.print("AM");
   }
4  Using Arduino / Programming Questions / Re: need a delay on a release of a button on: June 30, 2014, 12:07:54 pm
Why not just set the led timer on a button press and ignore releases? It all about handing the reading of the switch. Think of a switch as a signal that can either be LOW or HIGH and every time through loop() you check for a change from the last known signal state. If there is a change you start the debouncing timer. If the debouncing timer is set (non-zero) then you can see if it has been in that state long enough to be a valid state change (passes debouncing). Then you can act on the state, knowing it's a valid change. I think for your purposes you should just ignore button releases. Start timing the LED on presses.

By timing the led on presses it will automatically reset for another cycle any time it is pressed. Basically like the debounce timer. Then you can check for the LED timer being set and handle the LED switching.

Code:
// Your problem is that you have to focus your attention first on reading the button.
// Once you do that properly handling the LED is quite trivial.
// Handling the button properly means detecting state changes and debouncing

// use constants for pin numbering
// ALLCAPS style denotes global constant
const byte SWITCH_PIN = 2;
const byte LED_PIN = 13;
const unsigned long DEBOUNCE_TIME = 20UL;
const unsigned long LED_ON_TIME = 1000UL * 60UL * 5UL; // 5 minutes


// global variables to handle switch reading
unsigned long debounceTimer = 0;
int switchState;
// for LED timing
unsigned long ledTimer = 0;
boolean ledOn = false;

void setup()
{
  pinMode (SWITCH_PIN, INPUT_PULLUP);
  switchState = digitalRead(SWITCH_PIN);
  pinMode (LED_PIN, OUTPUT);
}

void loop()
{
  unsigned long currentTime = millis();
  int currentSwitchState = digitalRead(SWITCH_PIN);

  if (switchState != currentSwitchState)
  {
    switchState = currentSwitchState;
    debounceTimer = currentTime;
  }

  if ((debounceTimer > 0) && (currentTime - debounceTimer >= DEBOUNCE_TIME))
  {
    debounceTimer = 0;
    if (switchState == HIGH) // released
    {
      // nothing to do on button release
    }
    else // switchState == LOW pressed
    {
      // start the timer for the LED
      ledTimer = currentTime;
    }
  }

  if (ledTimer > 0)
  {
    // check for LED turn on
    if (!ledOn)
    {
      digitalWrite(LED_PIN, HIGH);
      ledOn = true;
    }
    // check for LED turn off
    if (ledOn && (currentTime - ledTimer >= LED_ON_TIME))
    {
      digitalWrite(LED_PIN, LOW);
      ledOn = false;
      ledTimer = 0;
    }
  }
}

That ignores releases so if you hold the button for longer than five minutes it will turn off at five anyway. To reset the led timer the button has to be released then pressed again. I think that represents fairly typical operation of such a button.
5  Using Arduino / Programming Questions / Re: if and else statements not working with boolean on: June 09, 2014, 06:25:46 pm
Ah yes, I see what you mean, is there a way of making value1 increase and value2 decrease at the same time? without using the Boolean? Or could I use the 'switch' function to do what I need?

Code:
int value = 0;
int incrementValue = 1;

void loop()
{
    analogWrite(Pin1, value); 
    analogWrite(Pin2, 255 - value);  // think about it           
    delay(10);  // read blink without delay to rid yourself of delays     
    value = value + incrementValue;
    if (value == 255 || value == 0)
    {
        incrementValue = incrementValue * -1;
    }
}
6  Using Arduino / Programming Questions / Re: creating a counter on: June 06, 2014, 08:15:22 pm
Got bored. Knocked this out. May be more than you wanted but there it is. It works as promised.

Code:
const byte LED_PIN = 13;
const byte BUTTON_PIN = 2;
const byte NUMBER_OF_BLINKS = 10;
const unsigned long DEBOUNCE_TIME = 20UL;
const unsigned long BLINK_DURATION = 500UL;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  static boolean blinking = false;
  static byte blinkCount = 0;
  static boolean ledState = false;
  static unsigned long lastBlinkTime = 0;
  static unsigned long debounceTimer = 0;
  static int lastButtonState = digitalRead(BUTTON_PIN);

  int buttonState = digitalRead(BUTTON_PIN);
  unsigned long currentMillis = millis();

  if (blinking)
  {
    if (currentMillis - lastBlinkTime >= BLINK_DURATION)
    {
      ledState = !ledState;
      digitalWrite(LED_PIN, ledState ? HIGH : LOW);
      lastBlinkTime = currentMillis;
      blinkCount++;
    }
    if (blinkCount == NUMBER_OF_BLINKS)
    {
       blinking = false;
       blinkCount = 0;
       // be sure the led is off
       digitalWrite(LED_PIN, LOW);
       ledState = false;
    }
  }
 
  else {
    if (lastButtonState != buttonState)
    {
      lastButtonState = buttonState;
      debounceTimer = currentMillis;
    }
    if (debounceTimer > 0 && currentMillis - debounceTimer >= DEBOUNCE_TIME)
    {
      debounceTimer = 0;
      blinking = true;
    }
  }
}
7  Using Arduino / Programming Questions / Re: creating a counter on: June 06, 2014, 07:40:18 pm
Buttons are a challenge. The first Arduino project I did had buttons and I left them until the end thinking they are easy. They were the most challenging facet of the project.

You have a state machine that can have two states, blinking or not blinking. What changes between the states is a button press being detected or done with blinking. If the machine is blinking don't read the button (unless you want to stop the blinking or something). If the machine is not blinking then it can spend its time polling the button waiting for a press so it can start blinking.

You need a boolean variable to indicate blinking.

Code:
boolean blinking = false;

if (blinking)
    {
        // do the blinking when done do this
        blinking = false;
    }
else if (digitalRead(buttonPin) == LOW) // I use internal pullups myself
    {
        blinking = true;
    }

I wouldn't read the button that way myself. It's better to watch for its state to change then act on the new state. Check out the state change detection example as well as debouncing. This sketch could easily be done without delay() as well.
8  Using Arduino / Programming Questions / Re: Push button question on: May 31, 2014, 08:28:51 pm
Looks to me like this is basic button reading with a long debounce time.

I read buttons this way mostly. It seems to work for most situations.

Code:
const byte BUTTON_PIN = 2; // for a switch on pin 2
const unsigned long DEBOUNCE_TIME = 20;
const long BAUD_RATE = 115200;
unsigned long debounceTimer = 0;
int lastButtonState = HIGH;

void setup()
{
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  lastButtonState = digitalRead(BUTTON_PIN);
  Serial.begin(BAUD_RATE);
}

void loop()
{
  unsigned long currentMillis = millis();  // get the millis for the loop start
  int buttonState = digitalRead(BUTTON_PIN);  // read the switch
  if (lastButtonState != buttonState) // check for any state change
  {
    lastButtonState = buttonState; // save new state
    debounceTimer = currentMillis;  // start the timer
  }
  if (debounceTimer > 0 && currentMillis - debounceTimer >= DEBOUNCE_TIME) // see if we are debouncing and whether we are done
  {
    debounceTimer = 0; // reset the timer
    if (buttonState == LOW)
    {
      Serial.println(F("Button has been held"));
    }
  }
}

All you need to do with that code is change the value of DEBOUNCE_TIME to 500. The beauty of this is that the button must be actually held for the length of time as any state change will restart the timer. It also has to be released before it can be used again. Note that I set the internal pullups so the button state is LOW when pressed.
9  Using Arduino / Programming Questions / Re: Function calling and if statments on: May 29, 2014, 09:56:27 am
Quote
Local variables are NOT initialized. The variable name is simply associated with an address in memory that held who know what last time it was used.

I learn something new every day. I probably haven't run into it because I never do it. I like to declare my variables with a value.

This actually makes it worse for him.
10  Using Arduino / Programming Questions / Re: Function calling and if statments on: May 29, 2014, 08:54:24 am
Code:
////תחילת מסלול,מטרה לקבל קורס ולא לחזור על הפעולה עד למסלול חדש לנקודה הבאה
if (NewCourse)
{
float longtitudeE;//נקודות ציון של נקודה סופית שצריכות להינתן לנו,להוסיף פקודה לקבלת קלט
float latitudeE;
float longtitudeS;//נקודות ציון של נקודת התחלה מהג'פס
float latitudeS;//
float Rs = sqrt(square(longtitudeE - longtitudeS) + (square(latitudeE - latitudeS));
float Alpha = StartFunction(longtitudeE, latitudeE, longtitudeS, latitudeS);//////////////קריאה לפונקציית התחלה במידה ובנקודה חדשה
}

You need to do some reading about how variables in C/C++ are scoped. None of those variables will exist after the block of code is executed. Also you essentially have this as Rs. Rs = sqrt(square(0 - 0) + (square(0 - 0)) as those variables will be initialized at 0 without another value supplied. Also note the unmatched parentheses.
11  Using Arduino / Programming Questions / Re: Do something only if the sensor is low for more than 1 second on: May 23, 2014, 10:30:35 am
The one problem with Crossroad's approach is that it won't detect if the sensor went back to HIGH in that one second. So it doesn't really check that the sensor was LOW for the second only that it is still LOW after.

I'd handle it much like reading a switch. Using state change detection. It's similar to debouncing.

Code:
int currentSensorState;
int lastSensorState;
unsigned long readTimer;

void loop() {
  unsigned long currentMillis = millis();
  // I'll assume you read the sensor something like this
  currentSensorState = digitalRead(SENSOR_PIN);
  // check for change from last state
  if (lastSensorState != currentSensorState)
  {
    lastSensorState = currentSensorState; // store the change
    readTimer = currentMillis;          // start the timer
  }
  // check if timing and if timing finished
  if (readTimer > 0 && currentMillis - readTimer >= 1000)
  {
    // reset timer
    readTimer = 0;
    // If it makes it here it has been in the new state for a second
    if (currentSensorState == LOW)
    {
      // do stuff for LOW state
    }
    else
    {
      // do stuff for HIGH state if you want
    }
  }
}

If, at any time during the one second, the sensor's state changes the readTimer will be set to a new millis() value and the timer will start again. Thus the sensor will have to be LOW for the entire second to pass.
12  Using Arduino / Programming Questions / Re: Millis mayhem!! on: May 15, 2014, 07:21:30 pm
Even if one was to declare val and remove the extra brace it still won't work.

Code:
    int value = 49;
     long previousMillis = 0;

     long interval = 3000; //delay

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

     void loop()
   {

       unsigned long currentMillis = millis();

       if( currentMillis - previousMillis > interval)
       {
         Serial.write(val);
         previousMillis = currentMillis + 2000; //2sec addition  <<====
        }

        previousMillis = currentMillis;  // <<<----- This line needs to be in the if statement block.
       }
   }

Each time through loop() previousMillis is set to currentMillis so the interval can never be exceeded. val will never print. Even if it existed.
13  Using Arduino / Programming Questions / Re: Millis mayhem!! on: May 15, 2014, 07:11:29 pm
What are you trying to do? Your code is all wrong in so many ways.
14  Using Arduino / Programming Questions / Re: Programming for two button switches blink on: May 14, 2014, 07:51:44 pm
Where do you get reading2 from?

All variables used with millis timing should be unsigned long.
15  Using Arduino / Programming Questions / Re: Efficiency on: May 12, 2014, 03:57:01 pm
It's not very efficient because it repeats code and is blocking. You want several LEDs to blink if their associated button is held. A class is a great approach for this. Here's an example.

Code:
// make an led blink while a button is held down
// create LED object with switch
class myBlinker
{
    byte ledPin;
    byte buttonPin;
    unsigned long blinkInterval;
    unsigned long lastBlinkMillis;

  public:

    myBlinker(byte led, byte button)
    {
      ledPin = led;
      buttonPin = button;
    }

    void begin(unsigned long interval)
    {
      pinMode(ledPin, OUTPUT);
      pinMode(buttonPin, INPUT_PULLUP);
      blinkInterval = interval;
    }

    void run()
    {
      if (digitalRead(buttonPin) == LOW)
      {
        unsigned long currentMillis = millis();
        if (currentMillis - lastBlinkMillis >= blinkInterval)
        {
          lastBlinkMillis = currentMillis;
          digitalWrite(ledPin, !digitalRead(ledPin));
        }
      }
      else digitalWrite(ledPin, LOW);
    }
};

const unsigned long BLINK_INTERVAL = 500UL;

myBlinker left(13, 2);
myBlinker middle(5, 2);
myBlinker right(6, 3);

void setup()
{
  left.begin(BLINK_INTERVAL);
  middle.begin(BLINK_INTERVAL);
  right.begin(BLINK_INTERVAL);
}

void loop()
{
  left.run();
  middle.run();
  right.run();
}

This sketch uses internal pullups, if you use external resistors you'll have to make some changes.
Pages: [1] 2 3 ... 25