Calling Functions.

Hey guys,

ive been dabbling in arduino for only a little bit and ive decided id try to make a candle that responds to inputs from the serial monitor.

I've made functions for high and low intensity settings, as well as an "off" setting. I can get the program to read Serial inputs and reply with corresponding messages but the code wont loop my called functions to make it look like the LED's are flickering.

When i tried using a while loop and a do while loop i could get 1 function to loop but then the program would stop reading Serial inputs and the setting wont change.

Any chance someone can help me out/point me in the direction of another post that may educate me?

Cheers.
H

p.s. here's the code.

//EEPROM stores small amounts of data for when power goes off. (i.e. RGB values)

#define rPin 11
#define gPin 6
#define bPin 9
#define candlePin 5
#define delayTime 20

int flame = random(80,255);
char serialInput;
char candleSetting;

void setup() { // put your setup code here, to run once:

Serial.begin(9600);

pinMode (rPin, OUTPUT);
pinMode (gPin, OUTPUT);
pinMode (bPin, OUTPUT);

Serial.println(F("Ready for instruction"));
}

void loop() {

checkSerialInput();

if (candleSetting=='H'){
Serial.println("candle is now on HIGH");
delay(50);
candleLightHigh();

}

if(candleSetting == 'L'){
Serial.println ("candle is now on LOW");
delay(50);
candleLightLow();

} else if(candleSetting == '0'){
Serial.println ("candle in now OFF.");
delay(50);
candleLightOff();
}

}

//////////////////////////FUNCTIONS///////////////////////////

void checkSerialInput() {
if (Serial.available()){
serialInput= Serial.read();
candleSetting=serialInput;
}
}

void candleLightHigh () {

analogWrite(rPin, flame);
analogWrite(gPin, flame/3);
delay(delayTime);

}

void candleLightLow () {
analogWrite(rPin, flame/10);
delay(delayTime);
analogWrite(gPin, flame/20);
delay(delayTime);

}

void candleLightOff(){
analogWrite(rPin, LOW);
analogWrite(gPin, LOW);
analogWrite(bPin, LOW);
}

Read this: Read this before posting a programming question

Specifically the part about using code tags.

Try:
if (Serial.available()){
Changing to
if (Serial.available() > 0) {

I don't see what difference that will make, LarryD. Unless Serial.available() returns a negative number those two forms should be the same.

void checkSerialInput() {
  if (Serial.available()){     
  serialInput= Serial.read();         
  candleSetting=serialInput;
}
}

I think the fundamental issue here is that, if there is nothing available, candleSetting is unchanged, and thus you will think you read the same thing again.

I have been working with RGB LED effects lately and use Blink Without Delay for my timing so that the button that changes mode will be responsive. Also the use of a simple state machine to organize my code. I have modified your code with those concepts. I only modified the candleLightHigh() function, I will leave the others to you. Note that no while loops are used, so the code is not blocking.

//EEPROM stores small amounts of data for when power goes off. (i.e. RGB values)

#define rPin 11
#define gPin 6
#define bPin 9
#define candlePin 5
#define delayTime 200  // long delay for print in candleLightHigh function.  change to suit

int flame = random(80,255);
char serialInput;
char candleSetting;

// timing variables
unsigned long candleLastTime;
unsigned long candleInterval = delayTime;
// is new data available from serial port?
boolean newData = false;
// state control
byte state = 0;

void setup()
{                                     // put your setup code here, to run once:

    Serial.begin(9600);

    pinMode (rPin, OUTPUT);
    pinMode (gPin, OUTPUT);
    pinMode (bPin, OUTPUT);

    Serial.println(F("Ready for instruction"));
}

void loop()
{

    checkSerialInput();

    // if new data available process and change state
    if(newData == true)
    {
        if (candleSetting=='H')
        {
            Serial.println("candle is now on HIGH");
            state = 1;
        }
        if(candleSetting == 'L')
        {
            Serial.println ("candle is now on LOW");
            state = 2;
        }
        else if(candleSetting  == '0')
        {
            Serial.println ("candle in now OFF.");
            state = 3;
        }
        newData = false;  // data processed,  wait for new data
    }

    // call function based on current state
    switch(state)
    {
    case 1:
        candleLightHigh();
        break;
    case 2:
        candleLightLow();
        break;
    case 3:
        candleLightOff();
        break;
    }
}




//////////////////////////FUNCTIONS///////////////////////////

void checkSerialInput()
{
    if (Serial.available())
    {
        serialInput= Serial.read();
        candleSetting=serialInput;
        newData = true;  // new data
    }
}

// modified function based on blink without delay (BWOD)
void candleLightHigh ()
{
    // if interval has elapsed, get new random number and send to LEDs
    if(millis() - candleLastTime > candleInterval)
    {
         // new random number every interval milliseconds
        flame = random(80,255); 
        // I don't have an LED, prints show that function is executing
        Serial.println(flame);
        analogWrite(rPin, flame);
        analogWrite(gPin, flame/3);
        candleLastTime = millis();  // reset time to now
        //candleInterval = random(200, 800);  // option to randomise interval to avoid 
                                              // regular pulse  change numbers to suit
    }
}

//  Your turn to use BWOD on the other functions
void candleLightLow ()
{
    analogWrite(rPin, flame/10);
    delay(delayTime);
    analogWrite(gPin, flame/20);
    delay(delayTime);

}


void candleLightOff()
{
    analogWrite(rPin, LOW);
    analogWrite(gPin, LOW);
    analogWrite(bPin, LOW);
}