Go Down

Topic: Fading three LEDs consecutively over three days. (Read 3 times) previous topic - next topic

kkachurak

Adjusted the fadeStepInterval to 338824 which should step through 255 levels of brightness over roughly 24 hours. But it seems that LED1 waits the duration of 338824 milliseconds and then just starts to fade quickly to off, followed by LED2 and LED3, all taking roughly 30 seconds each to fade out completely.

Also - now the RFID reader refuses to scan until the last LED is midway through dimming??? Strange behavior!  =(

Here's the entire code:
Code: [Select]

int RFIDResetPin = 13;

void(* resetFunc) (void) = 0; //declare reset function @ address 0

//Register your RFID tags here
char tag1[14] = "046F3AB283603";

int dayOne = 5;  // pin 5
int dayTwo = 6;  // pin 6
int dayThree = 9;   // pin 9
int completed = 0;
unsigned long fadeStepInterval = 338824;
unsigned long prevFadeTime = 0;
int brightnessa = 255;
int brightnessb = 255;
int brightnessc = 255;


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

 pinMode(RFIDResetPin, OUTPUT);
 digitalWrite(RFIDResetPin, HIGH);

 //ONLY NEEDED IF CONTROLING THESE PINS - EG. LEDs
 pinMode(2, OUTPUT);
 pinMode(dayOne, OUTPUT);
 pinMode(dayTwo, OUTPUT);
 pinMode(dayThree, OUTPUT);

}

void loop(){

 char tagString[13];
 int index = 0;
 boolean reading = false;

 while(Serial.available()){

   int readByte = Serial.read(); //read next available byte

   if(readByte == 2) reading = true; //begining of tag
   if(readByte == 3) reading = false; //end of tag

   if(reading && readByte != 2 && readByte != 10 && readByte != 13){
     //store the tag
     tagString[index] = readByte;
     index ++;
   }
 }

 checkTag(tagString); //Check if it is a match
 clearTag(tagString); //Clear the char of all value
 resetReader(); //eset the RFID reader
 
 unsigned long currTime = millis();

if (brightnessa != 0)
  if(currTime - prevFadeTime >= fadeStepInterval)
    brightnessa--;

if (brightnessa == 0 && brightnessb != 0)
 if(currTime - prevFadeTime >= fadeStepInterval)
    brightnessb--;


if (brightnessb == 0 && brightnessc != 0)
 if(currTime - prevFadeTime >= fadeStepInterval)
    brightnessc--;

   

analogWrite(dayOne, brightnessa);
analogWrite(dayTwo, brightnessb);
analogWrite(dayThree, brightnessc);

 
}


void checkTag(char tag[]){
///////////////////////////////////
//Check the read tag against known tags
///////////////////////////////////

 if(strlen(tag) == 0) return; //empty, no need to contunue

 if(compareTag(tag, tag1)){ // if matched tag1, do this
   lightLED(2);
      delay(100);
   resetFunc();

 }

}

void lightLED(int pin){
///////////////////////////////////
//Turn on LED on pin "pin" for 250ms
///////////////////////////////////
 Serial.println(pin);

 digitalWrite(pin, HIGH);
 delay(250);
 digitalWrite(pin, LOW);
}

void resetReader(){
///////////////////////////////////
//Reset the RFID reader to read again.
///////////////////////////////////
 digitalWrite(RFIDResetPin, LOW);
 digitalWrite(RFIDResetPin, HIGH);
 delay(150);
}

void clearTag(char one[]){
///////////////////////////////////
//clear the char array by filling with null - ASCII 0
//Will think same tag has been read otherwise
///////////////////////////////////
 for(int i = 0; i < strlen(one); i++){
   one[i] = 0;
 }
}

boolean compareTag(char one[], char two[]){
///////////////////////////////////
//compare two value to see if same,
//strcmp not working 100% so we do this
///////////////////////////////////

 if(strlen(one) == 0) return false; //empty

 for(int i = 0; i < 12; i++){
   if(one[i] != two[i]) return false;
 }

 return true; //no mismatches
}

PaulS

Put each { on a new line. Then, use Tools + Auto Format.

Then, tell me why you call checkTag(), clearTag(), and resetReader() on every pass through loop.

This:
Code: [Select]
if (brightnessa != 0)
   if(currTime - prevFadeTime >= fadeStepInterval)
     brightnessa--;

if (brightnessa == 0 && brightnessb != 0)
  if(currTime - prevFadeTime >= fadeStepInterval)
     brightnessb--;


if (brightnessb == 0 && brightnessc != 0)
  if(currTime - prevFadeTime >= fadeStepInterval)
     brightnessc--;

is unnecessarily complicated.

This:
Code: [Select]
  if(currTime - prevFadeTime >= fadeStepInterval)
  {
    if (brightnessa != 0)
      brightnessa--;

    else if (brightnessb != 0)
      brightnessb--;

    else if (brightnessc != 0)
      brightnessc--;
  }

is a lot simpler.

kkachurak

Okay, I did the auto-format. Not positive what that does, but I did it  :P

Also, replaced the unnecessarily complicated code with the simpler code you showed me. Lights still fade as expected, but I've yet to test the three day timing.

The reason I assume I call checkTag(), clearTag(), and resetReader() through every loop is because that's how it scans the RFID hardware for potential tag swipes. That chunk of code came from a RFID sequencing project, seen here: http://bildr.org/2011/02/rfid-arduino/

Still - the RFID refuses to read any swipes until it gets to the last LED, which is odd.

Here is the revised code:

Code: [Select]


int RFIDResetPin = 13;

void(* resetFunc) (void) = 0; //declare reset function @ address 0

//Register your RFID tags here
char tag1[14] = "046F3AB283603";

int dayOne = 5;  // pin 5
int dayTwo = 6;  // pin 6
int dayThree = 9;   // pin 9
int completed = 0;
unsigned long fadeStepInterval = 50;
unsigned long prevFadeTime = 0;
int brightnessa = 100;
int brightnessb = 100;
int brightnessc = 100;


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

  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);

  //ONLY NEEDED IF CONTROLING THESE PINS - EG. LEDs
  pinMode(2, OUTPUT);
  pinMode(dayOne, OUTPUT);
  pinMode(dayTwo, OUTPUT);
  pinMode(dayThree, OUTPUT);

}

void loop()
{

  char tagString[13];
  int index = 0;
  boolean reading = false;

  while(Serial.available()){

    int readByte = Serial.read(); //read next available byte

    if(readByte == 2) reading = true; //begining of tag
    if(readByte == 3) reading = false; //end of tag

    if(reading && readByte != 2 && readByte != 10 && readByte != 13){
      //store the tag
      tagString[index] = readByte;
      index ++;
    }
  }

  checkTag(tagString); //Check if it is a match
  clearTag(tagString); //Clear the char of all value
  resetReader(); //eset the RFID reader

    unsigned long currTime = millis();

if(currTime - prevFadeTime >= fadeStepInterval)
  {
    if (brightnessa != 0)
      brightnessa--;

    else if (brightnessb != 0)
      brightnessb--;

    else if (brightnessc != 0)
      brightnessc--;
  }

  analogWrite(dayOne, brightnessa);
  analogWrite(dayTwo, brightnessb);
  analogWrite(dayThree, brightnessc);

}


void checkTag(char tag[]){
  ///////////////////////////////////
  //Check the read tag against known tags
  ///////////////////////////////////

  if(strlen(tag) == 0) return; //empty, no need to contunue

  if(compareTag(tag, tag1)){ // if matched tag1, do this
    lightLED(2);
    delay(100);
    resetFunc();

  }

}

void lightLED(int pin)
{
  ///////////////////////////////////
  //Turn on LED on pin "pin" for 250ms
  ///////////////////////////////////
  Serial.println(pin);

  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
}

void resetReader()
{
  ///////////////////////////////////
  //Reset the RFID reader to read again.
  ///////////////////////////////////
  digitalWrite(RFIDResetPin, LOW);
  digitalWrite(RFIDResetPin, HIGH);
  delay(150);
}

void clearTag(char one[])
{
  ///////////////////////////////////
  //clear the char array by filling with null - ASCII 0
  //Will think same tag has been read otherwise
  ///////////////////////////////////
  for(int i = 0; i < strlen(one); i++){
    one[i] = 0;
  }
}

boolean compareTag(char one[], char two[])
{
  ///////////////////////////////////
  //compare two value to see if same,
  //strcmp not working 100% so we do this
  ///////////////////////////////////

  if(strlen(one) == 0) return false; //empty

  for(int i = 0; i < 12; i++)
  {
    if(one[i] != two[i]) return false;
  }

  return true; //no mismatches
}

PaulS

Quote
Put each { on a new line. Then, use Tools + Auto Format.

You missed a part...

Code: [Select]
if(readByte == 2) reading = true; //begining of tag
So, you know a tag was swiped, because there is data.

Code: [Select]
    if(readByte == 3) reading = false; //end of tag
You know that you have found the end of the tag's data. Would this be a good time to call checkTag(), clearTag(), and resetReader()?

Code: [Select]
      tagString[index] = readByte;
      index ++;

If you null terminated the array, you could use strcmp() below, instead of comparing one character at a time.

Code: [Select]
  for(int i = 0; i < 12; i++){
    if(one[i] != two[i]) return false;
  }

Your stored tag has 13 characters. You are only comparing the first 12. Why?

Code: [Select]
  analogWrite(dayThree, brightnessc);
Wouldn't matching names, like day3 and brightness3 make more sense?

Quote
Still - the RFID refuses to read any swipes until it gets to the last LED, which is odd.

I'm not understanding this. On each pass through loop, you are checking for serial data from the RFID reader, possibly adjusting one or more brightnessX values, and writing three values to three pins. Of course you can't read again until the value has been written to the last pin, but that should happen in a few hundred nanoseconds.

wildbill

Code: [Select]
if(currTime - prevFadeTime >= fadeStepInterval)
  {
    if (brightnessa != 0)
      brightnessa--;

    else if (brightnessb != 0)
      brightnessb--;

    else if (brightnessc != 0)
      brightnessc--;
  }


Shouldn't there be a prevFadeTime = currTime ; somewhere between those braces?

Perinerzia

#35
Feb 14, 2012, 11:57 am Last Edit: Feb 14, 2012, 12:04 pm by Albee Reason: 1
Hi, maybe it's all wrong, but it's simple and should work (compiled, but not tested)
Code: [Select]
// Led to pin 9 10 and 11

#include <avr/sleep.h>

int i=0;
int led=9;

void setup(){
 pinMode(9, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 digitalWrite(9, HIGH);
 digitalWrite(10, HIGH);
 digitalWrite(11, HIGH);
}

void loop()
{
 for (i=255; i>=0; i--)
 {
   analogWrite(led, i);
   delay(338824);
 }
 led++;
 if (led==12)
 {
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   sleep_enable();
   sleep_mode();
 }
}


Plug a button or what you want to the reset pin and I think it's done... or it's all a big fail, i don't know

PaulS

Quote
Shouldn't there be a prevFadeTime = currTime ; somewhere between those braces?

Good idea. It was missing from the code I simplified, so I overlooked the need.

kkachurak

#37
Feb 16, 2012, 03:24 pm Last Edit: Feb 16, 2012, 03:29 pm by kkachurak Reason: 1
I've narrowed down the issue to my three analogWrite() instructions.

This is my code, and even with the instructions for altering brightness1, 2 and 3, the RFID instruction works flawlessly:
Code: [Select]

int RFIDResetPin = 13;
int completed = 0;
unsigned long fadeStepInterval = 864000;
unsigned long prevFadeTime = 0;
int brightness1 = 100;
int brightness2 = 100;
int brightness3 = 100;

void(* resetFunc) (void) = 0; //declare reset function @ address 0

//Register your RFID tags here
char tag1[14] = "046F3AB283603";


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

 pinMode(RFIDResetPin, OUTPUT);
 digitalWrite(RFIDResetPin, HIGH);

 //ONLY NEEDED IF CONTROLING THESE PINS - EG. LEDs
 pinMode(2, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(9, OUTPUT);
}

void loop(){
 
 char tagString[14];
 int index = 0;
 boolean reading = false;

 while(Serial.available()){

   int readByte = Serial.read(); //read next available byte

   if(readByte == 2) reading = true; //begining of tag
   if(readByte == 3) reading = false; //end of tag

   if(reading && readByte != 2 && readByte != 10 && readByte != 13){
     //store the tag
     tagString[index] = readByte;
     index ++;
   }
 }

 checkTag(tagString); //Check if it is a match
 clearTag(tagString); //Clear the char of all value
 resetReader(); //reset the RFID reader

   unsigned long currTime = millis();

 if(currTime - prevFadeTime >= fadeStepInterval)
 {
   if (brightness1 != 0)
     brightness1--;

   else if (brightness2 != 0)
     brightness2--;

   else if (brightness3 != 0)
     brightness3--;

   prevFadeTime = currTime;
 }
 


}

void checkTag(char tag[]){
 ///////////////////////////////////
 //Check the read tag against known tags
 ///////////////////////////////////

 if(strlen(tag) == 0) return; //empty, no need to contunue

 if(compareTag(tag, tag1)){ // if matched tag1, do this
   lightLED(2);
   delay(250);
   resetFunc();

 }

}

void lightLED(int pin){
 ///////////////////////////////////
 //Turn on LED on pin "pin" for 100ms
 ///////////////////////////////////
 Serial.println(pin);

 analogWrite(pin, 255);
 delay(100);
 analogWrite(pin, 0);

}

void resetReader(){
 ///////////////////////////////////
 //Reset the RFID reader to read again.
 ///////////////////////////////////
 digitalWrite(RFIDResetPin, LOW);
 digitalWrite(RFIDResetPin, HIGH);
 delay(150);
}

void clearTag(char one[]){
 ///////////////////////////////////
 //clear the char array by filling with null - ASCII 0
 //Will think same tag has been read otherwise
 ///////////////////////////////////
 for(int i = 0; i < strlen(one); i++){
   one[i] = 0;
 }
}

boolean compareTag(char one[], char two[]){
 ///////////////////////////////////
 //compare two value to see if same,
 //strcmp not working 100% so we do this
 ///////////////////////////////////

 if(strlen(one) == 0) return false; //empty

 for(int i = 0; i < 12; i++){
   if(one[i] != two[i]) return false;
 }

 return true; //no mismatches
}


If I add the following to my loop:
Code: [Select]

 analogWrite(dayOne, brightness1);
 analogWrite(dayTwo, brightness2);
 analogWrite(dayThree, brightness3);


...Then the leds light up and fade as instructed, which is great, but the RFID fails to read data. Is this a conflict? Can I not do analogWrites and digitalWrites simultaneously? I even changed the lightLED function on pin 2 to an analogWrite to see if that might help, but to no avail.

PaulS

Code: [Select]
  while(Serial.available())
{
  // Read the data and note the presence of start and end markers
}


Then:
Code: [Select]
  checkTag(tagString); //Check if it is a match
  clearTag(tagString); //Clear the char of all value
  resetReader(); //reset the RFID reader

I can't understand why you won't put this code in the "yes, there is serial data" block, so that you don't do this unless you just read a tag.

kkachurak

Turns out, this was a hardware issue. I connected the proper resistors prior to the LEDs within my circuit and things seem to be working swimmingly so far.

Go Up