Using 2D array to progressively increase the amount of LEDs on a matrix

Hi all,

Some of you have already helped me with the beginning of this project which I am thankful for but I have not been completely successful yet.

Trying to create a puzzle whereby scanning 10 different RFID tags will progressively increase the number of LEDs on a 32 x 8 LED matrix. This is for an escape room puzzle and will show a code after the 10 tags have all been scanned.

So what I have attempted to do is create a 2D array to cover the specific LED progressions and when a tag is scanned that has NOT been scanned before, go to the next stage of LEDs.

I've tried to use a variable called cellMutationStage to indicate the stage at which the LEDs should show depending on how many tags have been scanned.

I feel like I'm not a million miles away but if it doesn't work it doesn't work. I am currently not seeing any LEDs upon scanning where I did have a version where it showed the specific LEDs, though I couldn't get it to do the next stage.

Hard work this coding stuff, many thanks for any help!
Ben

#include <SPI.h>
#include <MFRC522.h>
#include <FastLED.h>
#include <Wire.h>

//pin declarations

#define LED_PIN  4
#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

//declaring an RFID read instance

MFRC522 mfrc522(SS_PIN, RST_PIN);

//For the LED Matrix

#define COLOR_ORDER GRB
#define CHIPSET     WS2811
#define cellColour 100,0,0 //RGB colour numbers, currently red
#define BRIGHTNESS 50
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 8;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) //Number of LEDs is the height x the width
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1]; //Don't ask, it works and if I change it it doesnt
CRGB* const leds( leds_plus_safety_pixel + 1);

//Arrays for the LED matrix stages and the size of each

int ledArray[2][14] = {
                      {25,28,106,110,125,146,164,169,180,227},
                      {25,28,106,110,125,146,164,169,180,227,46,116,173,234}
                      };

//RFID tags and their IDs

const int numTags = 10;
const String IDs[] = {"D3 54 07 0C", "43 0D 61 0D", "53 ED 08 0C", "13 A1 24 0C", "03 B3 1A 0C", "53 60 6F 0D", "C3 B0 18 0C", "63 04 27 0C", "13 DC 7B 0D", "93 A7 10 0C" };
String tagIDTracker[numTags]{}; //empty array to add the scanned IDs into

//variable for  stage progression

int cellMutationStage = 0;

void setup() {

  //Setups for the RFID reader, Serial monitor and the LED matrix
  
  Serial.begin(9600); 
  SPI.begin();
  mfrc522.PCD_Init();
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness( BRIGHTNESS );
  
}
void loop() {

//Standard RFID reader code section

String readRFID = "";
    
    // If the sensor detects a tag and is able to read it
    if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
      // Extract the ID from the tag
      readRFID = dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);

//If the tag that has been read is not in the tagIDTracker array, meaning it's not been scanned, then add 1 to the cellMutationStage 
//variable and then add the new tag to the tagIDTracker array so it cannot be scanned again. Print the cellMutationVariable so we can see if it's progressing

  if(readRFID != tagIDTracker[numTags]){
      //Update the cellMutationStage variable to go to the next stage of the LED lights
      cellMutationStage++;
      Serial.print(cellMutationStage);
      // Add the newly scanned tag to the empty array
      tagIDTracker[numTags] = readRFID;
    }

//first if statement for the lights, if cellMutationStage variable is on 0 (meaning nothing has been scanned) then show the first array of LEDs

  if (cellMutationStage == 0) {
  for(int i=0; i<10; i++)
    {
  leds[ledArray[0][i]].setRGB(cellColour);
  delay(100);
  FastLED.setBrightness( BRIGHTNESS );
  FastLED.show();
    }}}}



//heplper function to get the byte info from the RFID reader - works fine atm

String dump_byte_array(byte *buffer, byte bufferSize) {
  String read_rfid = "";
  for (byte i=0; i<bufferSize; i++) {
    read_rfid = read_rfid + String(buffer[i], HEX);
  }
  return read_rfid;
}

type or paste code here

Hello

I suggest to do something like this example : mCMttx - Online C++ Compiler & Debugging Tool - Ideone.com

Then increase cellMutationStage every time a new card is scanned, use this variable as an index of your ledArray

This looks wrong:

CRGB leds_plus_safety_pixel[ NUM_LEDS + 1]; //Don't ask, it works and if I change it it doesnt
CRGB* const leds( leds_plus_safety_pixel + 1);

And this too:

if(readRFID != tagIDTracker[numTags]){
...
tagIDTracker[numTags] = readRFID;

tagIDTracker[numTags] is not a valid element of tagIDTracker, it is outside of this array

1 Like

RFID tags are inherently numbers, not Strings so use uint32_t as your type, not String

You are going out of bounds on your array, so that is why you had to add an extra element. Better to fix the problem.

As for searching, you have to iterate over all the tags you have scanned so far to see if there is a match. This code should get you going in the right direction. You can also ditch your pattern array and just create the pattern for each mutation directly inside the switch/case statement

#include <SPI.h>
#include <MFRC522.h>
#include <FastLED.h>
#include <Wire.h>

//pin declarations

#define LED_PIN  4
#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

//declaring an RFID read instance

MFRC522 mfrc522(SS_PIN, RST_PIN);

//For the LED Matrix

#define COLOR_ORDER GRB
#define CHIPSET     WS2811
#define cellColour 100,0,0 //RGB colour numbers, currently red
#define BRIGHTNESS 50
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 8;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) //Number of LEDs is the height x the width
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1]; //Don't ask, it works and if I change it it doesnt
CRGB* const leds( leds_plus_safety_pixel + 1);

//Arrays for the LED matrix stages and the size of each

int ledArray[2][14] = {
  {25, 28, 106, 110, 125, 146, 164, 169, 180, 227},
  {25, 28, 106, 110, 125, 146, 164, 169, 180, 227, 46, 116, 173, 234}
};

//RFID tags and their IDs

const int numTags = 10;
const uint32_t IDs[numTags] = {
  0xD354070C,
  0x430D610D,
  0x53ED080C,
  0x13A1240C,
  0x03B31A0C,
  0x53606F0D,
  0xC3B0180C,
  0x6304270C,
  0x13DC7B0D,
  0x93A7100C
};

uint32_t tagIDTracker[numTags]; //empty array to add the scanned IDs into

//variable for  stage progression

int cellMutationStage = 0;

void setup() {

  //Setups for the RFID reader, Serial monitor and the LED matrix

  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness( BRIGHTNESS );

}
void loop() {

  // If the sensor detects a tag and is able to read it
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    // Extract the ID from the tag
    uint32_t readRFID = getID(mfrc522.uid.uidByte);

    //If the tag that has been read is not in the tagIDTracker array, meaning it's not been scanned, then add 1 to the cellMutationStage
    //variable and then add the new tag to the tagIDTracker array so it cannot be scanned again. Print the cellMutationVariable so we can see if it's progressing

    bool newTag = true; // assume the tag will be a new one
    for ( int i = 0; i < cellMutationStage; ++i ) {
      if (readRFID == tagIDTracker[i]) {
        newTag = false;   // it has already been scanned
        break;            // no need to continue searching
      }
    }

    if ( newTag == true ) {
      //Update the cellMutationStage variable to go to the next stage of the LED lights
      tagIDTracker[cellMutationStage] = readRFID;
      cellMutationStage++;
      Serial.print(cellMutationStage);
      if ( cellMutationStage >= numTags ) {
        // all tags scanned, do not go beyond array
        cellMutationStage = numTags - 1;
      }
    }

    // display pattern based on number of tags scanned

    switch ( cellMutationStage ) {
      case 0:   // nothing scanned, show first pattern
        for (int i = 0; i < 10; i++) {
          leds[ledArray[0][i]].setRGB(cellColour);
        }
        break;

      case 1:   // 1 id scanned, do whatever
        // TODO: fill array
        break;

      case 2:
        // TODO: fill array
        break;
    }
    FastLED.show();
  }
}



//heplper function to get the byte info from the RFID reader - works fine atm

uint32_t getID(byte * buffer) {
  uint32_t read_rfid = 0;
  for (byte i = 0; i < 4; i++) {
    read_rfid = (read_rfid << 8) + buffer[i];
  }
  return read_rfid;
}
1 Like

Thanks an absolute million.

It makes sense and I've more or less understood the code. I am unable to get it to switch to the next case though. I've done a simple version where it just shows 1 LED for now (will try include the arrays later) and scanning 1 RFID tag shows that LED. But scanning different ones doesn't then show the next one.

The LEDs are not turning off when I reset the arduino so I wonder if I need an LED.clear or leds[1].RGB = WHITE to turn them off or similar...maybe not but I will keep trying. Any advice massively appreciated as always.

#include <SPI.h>
#include <MFRC522.h>
#include <FastLED.h>
#include <Wire.h>

//pin declarations

#define LED_PIN  4
#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

//declaring an RFID read instance

MFRC522 mfrc522(SS_PIN, RST_PIN);

//For the LED Matrix

#define COLOR_ORDER GRB
#define CHIPSET     WS2811
#define cellColour 100,0,0 //RGB colour numbers, currently red
#define BRIGHTNESS 50
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 8;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) //Number of LEDs is the height x the width
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1]; //Don't ask, it works and if I change it it doesnt
CRGB* const leds( leds_plus_safety_pixel + 1);

//Arrays for the LED matrix stages and the size of each

int ledArray1[] = {25,28,106,110,125,146,164,169,180,227};
int ledArray2[] = {25,28,106,110,125,146,164,169,180,227,46,116,173,234};

//RFID tags and their IDs

const int numTags = 1;
const uint32_t IDs[] = {"D3 54 07 0C", "43 0D 61 0D", "53 ED 08 0C", "13 A1 24 0C", "03 B3 1A 0C", "53 60 6F 0D", "C3 B0 18 0C", "63 04 27 0C", "13 DC 7B 0D", "93 A7 10 0C" };
uint32_t tagIDTracker[numTags]; //empty array to add the scanned IDs into

//variable for  stage progression

int cellMutationStage = 0;

void setup() {

  //Setups for the RFID reader, Serial monitor and the LED matrix
  
  Serial.begin(9600); 
  SPI.begin();
  mfrc522.PCD_Init();
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness( BRIGHTNESS );
  
}
void loop() {

//Standard RFID reader code section

String readRFID = "";
    
    // If the sensor detects a tag and is able to read it
    if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
      // Extract the ID from the tag
      uint32_t readRFID = getID(mfrc522.uid.uidByte);

//If the tag that has been read is not in the tagIDTracker array, meaning it's not been scanned, then add 1 to the cellMutationStage 
//variable and then add the new tag to the tagIDTracker array so it cannot be scanned again. Print the cellMutationVariable so we can see if it's progressing

bool newTag = true; // assume the tag will be a new one
    for ( int i = 0; i < cellMutationStage; ++i ) {
      if (readRFID == tagIDTracker[i]) {
        newTag = false;   // it has already been scanned
        break;            // no need to continue searching
      }
    }

      if ( newTag == true ) {
      //Update the cellMutationStage variable to go to the next stage of the LED lights
      tagIDTracker[cellMutationStage] = readRFID;
      cellMutationStage++;
      Serial.print(cellMutationStage);
      if ( cellMutationStage >= numTags ) {
        // all tags scanned, do not go beyond array
        cellMutationStage = numTags - 1;
      }
    }

//first if statement for the lights, if cellMutationStage variable is on 0 (meaning nothing has been scanned) then show the first array of LEDs

switch ( cellMutationStage ) {
      case 0:   // nothing scanned, show first pattern
          leds[1].setRGB(cellColour);
          break;

      case 1:   // 1 id scanned, do whatever
          leds[2].setRGB(cellColour);
          break;
    }
    FastLED.show();
  }
}



//heplper function to get the byte info from the RFID reader - works fine atm

uint32_t getID(byte * buffer) {
  uint32_t read_rfid = 0;
  for (byte i = 0; i < 4; i++) {
    read_rfid = (read_rfid << 8) + buffer[i];
  }
  return read_rfid;
}

That's not going to work. I changed those to 32 bit integers but you are still trying to assign a String. Get rid of all the Strings in your code and do yourself a favor. Did you try my entire code vs. bits and pieces? This version will send more output to the serial monitor

#include <SPI.h>
#include <MFRC522.h>
#include <FastLED.h>
#include <Wire.h>

//pin declarations

#define LED_PIN  4
#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

//declaring an RFID read instance

MFRC522 mfrc522(SS_PIN, RST_PIN);

//For the LED Matrix

#define COLOR_ORDER GRB
#define CHIPSET     WS2811
#define cellColour 100,0,0 //RGB colour numbers, currently red
#define BRIGHTNESS 50
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 8;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) //Number of LEDs is the height x the width
CRGB leds[ NUM_LEDS ]; //Don't ask, it works and if I change it it doesnt

//Arrays for the LED matrix stages and the size of each

int ledArray[2][14] = {
  {25, 28, 106, 110, 125, 146, 164, 169, 180, 227},
  {25, 28, 106, 110, 125, 146, 164, 169, 180, 227, 46, 116, 173, 234}
};

//RFID tags and their IDs

const int numTags = 10;
const uint32_t IDs[numTags] = {
  0xD354070C,
  0x430D610D,
  0x53ED080C,
  0x13A1240C,
  0x03B31A0C,
  0x53606F0D,
  0xC3B0180C,
  0x6304270C,
  0x13DC7B0D,
  0x93A7100C
};

uint32_t tagIDTracker[numTags]; //empty array to add the scanned IDs into

//variable for  stage progression

int cellMutationStage = 0;

void setup() {

  //Setups for the RFID reader, Serial monitor and the LED matrix

  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness( BRIGHTNESS );

}
void loop() {

  // If the sensor detects a tag and is able to read it
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    // Extract the ID from the tag
    uint32_t readRFID = getID(mfrc522.uid.uidByte);
    Serial.print("Read tag: 0x");
    Serial.println( readRFID, HEX );

    //If the tag that has been read is not in the tagIDTracker array, meaning it's not been scanned, then add 1 to the cellMutationStage
    //variable and then add the new tag to the tagIDTracker array so it cannot be scanned again. Print the cellMutationVariable so we can see if it's progressing

    bool newTag = true; // assume the tag will be a new one
    for ( int i = 0; i < cellMutationStage; ++i ) {
      if (readRFID == tagIDTracker[i]) {
        newTag = false;   // it has already been scanned
        break;            // no need to continue searching
      }
    }

    if ( newTag == true ) {
      Serial.print("Found a new tag: 0x");
      Serial.println( readRFID, HEX );
      //Update the cellMutationStage variable to go to the next stage of the LED lights
      tagIDTracker[cellMutationStage] = readRFID;
      cellMutationStage++;
      Serial.print("cell Mutation Stage = ");
      Serial.println(cellMutationStage);
      if ( cellMutationStage >= numTags ) {
        // all tags scanned, do not go beyond array
        cellMutationStage = numTags - 1;
      }
    }
    else {
      Serial.println("Tag has already been scanned");
    }

    // display pattern based on number of tags scanned

    switch ( cellMutationStage ) {
      case 0:   // nothing scanned, show first pattern
        leds[0] = CRGB::Red;
        break;

      case 1:   // 1 id scanned, do whatever
        leds[0] = CRGB::Black;
        leds[1] = CRGB::Blue;
        break;

      case 2:
        leds[1] = CRGB::Black;
        leds[2] = CRGB::Green;
        break;
    }
    FastLED.show();
  }
}



//heplper function to get the byte info from the RFID reader - works fine atm

uint32_t getID(byte * buffer) {
  uint32_t read_rfid = 0;
  for (byte i = 0; i < 4; i++) {
    read_rfid = (read_rfid << 8) + buffer[i];
  }
  return read_rfid;
}

Thanks a lot for all your help, I have a functioning code and learnt quite a few things.

There's a couple of small things I cannot work out how to do and 1 strange LED which shows on the matrix which I can't find a reference to.

  1. How to get rid of the strange top left LED?
  2. Where to add a delay in the cases to allow the lights to come on one-by-one rather than all at the same time? I tried adding it in several different lines but it didn't make any difference to the behaviour.

Code below, as always any help massively appreciated
Ben

#include <SPI.h>
#include <MFRC522.h>
#include <FastLED.h>
#include <Wire.h>

//pin declarations

#define LED_PIN  4
#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

//declaring an RFID read instance

MFRC522 mfrc522(SS_PIN, RST_PIN);

//For the LED Matrix

#define COLOR_ORDER GRB
#define CHIPSET     WS2811
#define cellColour 100,0,0 //RGB colour numbers, currently red
#define BRIGHTNESS 50
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 8;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) //Number of LEDs is the height x the width
CRGB leds[ NUM_LEDS ]; //Don't ask, it works and if I change it it doesnt

//Arrays for the LED matrix stages and the size of each

int ledArray1[] = {30, 105, 109, 146, 164, 174, 227};
int ledArray1Size = sizeof (ledArray1);

int ledArray2[] = {116, 230};
int ledArray2Size = sizeof (ledArray2);

int ledArray3[] = {49, 93, 145, 150, 161, 205, 212, 225};
int ledArray3Size = sizeof (ledArray3);

int ledArray4[] = {59, 166, 169, 222};
int ledArray4Size = sizeof (ledArray4);

int ledArray5[] = {43, 108, 107, 153, 226};
int ledArray5Size = sizeof (ledArray5);

int ledArray6[] = {46, 94, 171, 228, 229};
int ledArray6Size = sizeof (ledArray6);

int ledArray7[] = {54, 106, 155, 212};
int ledArray7Size = sizeof (ledArray7);

int ledArray8[] = {33, 52, 100, 158, 203};
int ledArray8Size = sizeof (ledArray8);

int ledArray9[] = {50, 91, 148, 206, 209};
int ledArray9Size = sizeof (ledArray9);

int ledArray10[] = {51, 53, 92, 147, 170, 204, 219};
int ledArray10Size = sizeof (ledArray10);


//RFID tags and their IDs

const int numTags = 10;
const uint32_t IDs[numTags] = {
  0xD354070C,
  0x430D610D,
  0x53ED080C,
  0x13A1240C,
  0x03B31A0C,
  0x53606F0D,
  0xC3B0180C,
  0x6304270C,
  0x13DC7B0D,
  0x93A7100C
};

uint32_t tagIDTracker[numTags]; //empty array to add the scanned IDs into

//variable for  stage progression

int cellMutationStage = 0;

void setup() {

  //Setups for the RFID reader, Serial monitor and the LED matrix

  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness( BRIGHTNESS );
  }
  
void loop() {

  // If the sensor detects a tag and is able to read it
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    // Extract the ID from the tag
    uint32_t readRFID = getID(mfrc522.uid.uidByte);
    Serial.print("Read tag: 0x");
    Serial.println( readRFID, HEX );

    //If the tag that has been read is not in the tagIDTracker array, meaning it's not been scanned, then add 1 to the cellMutationStage
    //variable and then add the new tag to the tagIDTracker array so it cannot be scanned again. Print the cellMutationVariable so we can see if it's progressing

    bool newTag = true; // assume the tag will be a new one
    for ( int i = 0; i < cellMutationStage; ++i ) {
      if (readRFID == tagIDTracker[i]) {
        newTag = false;   // it has already been scanned
        break;            // no need to continue searching
      }
    }

    if ( newTag == true ) {
      Serial.print("Found a new tag: 0x");
      Serial.println( readRFID, HEX );
      //Update the cellMutationStage variable to go to the next stage of the LED lights
      tagIDTracker[cellMutationStage] = readRFID;
      cellMutationStage++;
      Serial.print("cell Mutation Stage = ");
      Serial.println(cellMutationStage);
      if ( cellMutationStage >= numTags ) {
        // all tags scanned, do not go beyond array
        cellMutationStage = numTags;
      }
    }
    else {
      Serial.println("Tag has already been scanned");
    }

    // display pattern based on number of tags scanned

    switch ( cellMutationStage ) {

      case 1:   // 1 id scanned, do whatever
        for (int i = 0; i <=ledArray1Size; i++) {
        leds[ledArray1[i]] = CRGB::Red;
        }
        break;

      case 2:
        for (int i = 0; i <=ledArray2Size; i++) {
        leds[ledArray2[i]] = CRGB::Red;
        }
        break;

      case 3:
        for (int i = 0; i <= ledArray3Size; i++) {
        leds[ledArray3[i]] = CRGB::Red;
        }
        break;

      case 4:
        for (int i = 0; i <=ledArray4Size; i++) {
        leds[ledArray4[i]] = CRGB::Red;
        }
        break;
 
      case 5:
        for (int i = 0; i <=ledArray5Size; i++) {
        leds[ledArray5[i]] = CRGB::Red;
        }
        break;

      case 6:   // 1 id scanned, do whatever
        for (int i = 0; i <=ledArray6Size; i++) {
        leds[ledArray6[i]] = CRGB::Red;
        }
        break;

      case 7:
        for (int i = 0; i <=ledArray7Size; i++) {
        leds[ledArray7[i]] = CRGB::Red;
        }
        break;

      case 8:
        for (int i = 0; i <= ledArray8Size; i++) {
        leds[ledArray8[i]] = CRGB::Red;
        }
        break;

      case 9:
        for (int i = 0; i <=ledArray9Size; i++) {
        leds[ledArray9[i]] = CRGB::Red;
        }
        break;
 
      case 10:
        for (int i = 0; i <=ledArray10Size; i++) {
        leds[ledArray10[i]] = CRGB::Red;
        }
        break;


    }
    FastLED.show();
  }
}



//heplper function to get the byte info from the RFID reader - works fine atm

uint32_t getID(byte * buffer) {
  uint32_t read_rfid = 0;
  for (byte i = 0; i < 4; i++) {
    read_rfid = (read_rfid << 8) + buffer[i];
  }
  return read_rfid;
}

OK I solved the delay issue and also managed to get rid of the LED 0 but not sure why it comes on in the first place.

Many thanks!
Ben

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.