0

I created and learned this code myself from many examples. I tried to add another chip to it, but I have no idea. Do I need to rewrite all of it? Just some simple code is needed.

int latchPin = 2;
int dataPin = 3;
int clockPin = 4;
const int analogPin = A0;   
const int ledPin = 13;       
const int EmptyEn = 0;
const int GreenOne = 100;    
const int GreenTwo = 200;
const int GreenThree = 300;
const int GreenFour = 400;
const int YellowOne = 500;
const int YellowTwo = 600;
const int RedOne = 750;
const int RedTwo = 900;
const int MaxHold = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
  int analogValue = analogRead(analogPin);
  if (analogValue > GreenOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > GreenOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B10000000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > GreenTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11000000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > GreenThree) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11100000);
    digitalWrite(latchPin, LOW);
    delay(1);
  }
  if (analogValue > GreenFour) {
    digitalWrite(latchPin, HIGH);
    shiftOut(dataPin, clockPin, MSBFIRST, B11110000);
    digitalWrite(latchPin, LOW);
    delay(1);
  }
  if (analogValue > YellowOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > YellowTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111100);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > RedOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111110);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > RedTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > MaxHold) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
    digitalWrite(latchPin, HIGH);
    delay(100);
  }
  Serial.println(analogValue);
  delay(1);
}
1
  • 1
    Can you give more guidance, such as stating what is wrong, posting any compile errors, and then asking a specific question?
    – SDsolar
    Apr 11 '18 at 2:34
2

Look for a repetition in your code.

  //Repeating code..
  if (analogValue > GreenOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000 );
    digitalWrite(latchPin, HIGH);
    delay(1);
  }

  if (analogValue > GreenTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B10000000 );
    digitalWrite(latchPin, HIGH);
    delay(1);
  }

You will notice that you have a lot of repetition of the general structure of a if-comparison (always with a different value) and then a shiftOut with a different value to be shifted out.

  //General code structure
  //Only things to change is someComparisonValue and someDataValue
  //the rest is the same.
  if (analogValue > someComparisonValue) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, someDataValue);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }

You can generalize and simplify the code by storing those different comparison values and data values in a look-up table (LUT). Now you could use two arrays to hold these values but you could also further condense it in a C struct, a "data structure".

Let's define a data structure which holds a threshold value and then the data to be shifted out as struct.

/* Defines a LUT entry */
struct LutEntry {
    int treshhold;  /* threshhold value */
    byte data;      /* data to be shifted out */
};

We can then pack the actual data into a single variable. Because this is constant data, it will take up flash memory instead of RAM.

static const LutEntry lutTable[] = {
    { GreenOne, B00000000},
    { GreenOne, B10000000},
    { GreenTwo, B11000000},
    { GreenThree, B11100000},
    { GreenFour, B11110000},
    { YellowOne, B11111000},
    { YellowTwo, B11111100},
    { RedOne, B11111110},
    { RedTwo, B11111111},
    { MaxHold, B00000000}
};

From there we can also see that there is a computable relationship between the index of the treshhold value and the data to be shifted out - an entry at index i will be associated with the data bitstring in which all bits from the MSB up to i inclusive are 1, the rest being 0. Except for MaxHold as special value. We could exploit this property to get rid of that data member entirely, but that is an exercise left to you.

Now we can re-write the loop code by simply taking a analogRead sample and then iterating through the entires of the LUT to shift out the corresponding data.

void loop() {
    int analogValue = analogRead(analogPin);
    int numLutEntries = (int)(sizeof(lutTable) / sizeof(lutTable[0]));

    for(int i=0; i < numLutEntries; i++) {
        if (analogValue > lutTable[i].treshhold) {
            digitalWrite(latchPin, LOW);
            shiftOut(dataPin, clockPin, MSBFIRST, lutTable[i].data);
            digitalWrite(latchPin, HIGH);
            delay(1);
        }       
    }
    Serial.println(analogValue);
    delay(1); 
}

Which transforms 69 lines of repeating code into 12 lines of non-repeating code.

After this general code cleanup it becomes easier to add another shift register: You can define a new look up table, or modify the structure of the old one, to hold the information you need (treshholds, data to be shifted out, the clock, data and latch pin for the register, ...). What logic needs to be there is something only you know, because the description "add another chip [to this code]" is quite broad.

In short:

  • DRY: Don't repeat yourself. If you use a piece of code over and over again with only slight variances in used values, make it a function
  • recognize the differences of the used data values in used code pieces and try to group them neatly together. Use the language feature of structs or class to express the meaning of this data
  • exploit certain properties / relationships of your data to save even more memory / computing time.

Not the answer you're looking for? Browse other questions tagged or ask your own question.