Outputting lowest array to Binary on LEDs issue!

Hey guy, me again. :slight_smile:

So this time I had to get 50 random numbers into an array, switch them to ascending order when there's an input, and then output the highest and lowest numbers in the array to LEDs in binary.

I have managed everything but outputting the lowest number in the array. I figured it would be the same as the highest array, but lower down on the LEDs.

Anyway here's the full code...

int incomingByte; //a variable to read incoming serial data into
int Array[50] = {
};
int pinArray[] = {
  6, 7, 8, 9, 10, 11, 12, 13
};
int highArray;
int lowArray;
int pinCount = 14; //amount of pins being used on the arduino
void setup() {
  //initialize serial communication:
  Serial.begin(9600);
  for (int thisPin = 0; thisPin < pinCount; thisPin++) //initialize the LED pins as an output
  {
    pinMode(pinArray[thisPin], OUTPUT);
  }
  // if analog input pin 0 is unconnected, random analog
  // noise will cause the call to randomSeed() to generate
  // different seed numbers each time the sketch runs.
  // randomSeed() will then shuffle the random function.
  randomSeed(analogRead(0));
  for (int i = 0; i < 50; i++) // repeats 50 times
  {
    Array[i] = random(256); // Puts a random number from 0-255 into the array
    Serial.println(Array[i]);

  }
}

void loop() {

  if (Serial.available() > 0) {
    //read oldest byte in the serial buffer:
    incomingByte = Serial.read();

    sort(Array, 50); //sorts the array
    for (int i = 0; i < 50; i++)
    {
      Serial.print(Array[i]);
      Serial.print(",");
    }
    Serial.println();
    lowArray = Array[0];
    highArray = Array[49];
    Serial.print("Low Array = ");
    Serial.println(lowArray);
    Serial.print("High Array = ");
    Serial.println(highArray);
    highestArrayBinary();
    delay(5000);
    allLedsOff();
    lowestArrayBinary();
    delay(5000);
    allLedsOff();
  }
}

void sort(int a[], int sizeOfArray) { // bubble sort to ascending order
  boolean swapped = true;
  while (swapped)
  {
    swapped = false;
    for (int index = sizeOfArray - 1; index >= 0; index--)
    {
      if (a[index] < a[index - 1]) {
        int tmp = a[index];
        a[index] = a[index - 1];
        a[index - 1] = tmp;
        swapped = true;
      }
    }
  }
}

void highestArrayBinary()
{
  int i = 128;
  int thisPin = 7;
  int remainder = highArray;
  while (remainder > 0)
  {
    while (remainder >= i)
    {
      double j = i / 2;
      digitalWrite(pinArray[thisPin], HIGH);
      remainder = remainder - i;
      i = i - j;
      thisPin--;
    }
    while (remainder < i)
    {
      int j = i / 2;
      if (j >= 1)
      {
        i = i - j;
        thisPin--;
      }
      else
      {
        i = 0;
      }
    }
  }
}

void lowestArrayBinary()
{
  int i = 128;
  int thisPin = 7;
  int remainder = lowArray;
  while (remainder > 0)
  {
    while (remainder >= i)
    {
      double j = i / 2;
      digitalWrite(pinArray[thisPin], HIGH);
      remainder = remainder - i;
      i = i - j;
      thisPin--;
    }
    while (remainder < i)
    {
      int j = i / 2;
      if (j >= 1)
      {
        i = i - j;
        thisPin--;
      }
      else
      {
        i = 0;
      }
    }
  }
}

void allLedsOff()
{
  for (int thisPin = 0; thisPin < pinCount; thisPin++) //initialize the LED pins as an output
  {
    digitalWrite(pinArray[thisPin], LOW);
  }
}

When doing the lowest number in the array, for some reason only the last two lights turn on, (1 & 2 in binary) this means that if the Lowest array is 1-3 it shows it. Also if the array would end with the 1st and 2nd pin, (e.g. 19, would be 16,2,1) then 2,1 would turn on but not the 16.

    while (remainder < i)
    {
      int j = i / 2;
      if (j >= 1)
      {
        i = i - j;
        thisPin--;
      }
      else
      {
        i = 0;
      }

I think the error is in this part, though I cannot see anything wrong.

In HighestArrayBinary, I used "i=i-j" rather than "i=i/2" because when i=1 it will not be able to half anymore, so i wont ever equal 0. So I made j a double, meaning it could equal 0.5, then when j < 1, i=0. This way i does eventually equal 0.

I have explained it in as much detail as I think you guys may need, if anybody can see what I have done wrong, any help would be greatly appreciated.

This is for a university assignment due tomorrow, which is why I'm posting here rather than emailing a lecturer, who'd probably not respond until tomorrow.

Attached is a screen shot of the assignment, which should explain in greater detail what I have had to do.

Again, any help would be very welcome and greatly appreciated.

~ Jake

UPDATE!

I removed the "allLedsOff();" function at the end of the loop, after where I call the "lowestArrayBinary" function.

I also added a "Serial.print" to where I thought the issues were, so that I could see in the serial monitor when it was doing which part of the code.

    while (remainder < i)
    {
      int j = i / 2;
      if (j >= 1)
      {
        Serial.println("LED off");
        i = i - j;
        thisPin--;
      }
      else
      {
        i = 0;
        Serial.println("i=0");
      }

Doing these things has, for some reason, made the program work as it should. I've tested it a few times now and all the LEDs seem to be working correctly and lighting up when they should.

Does anybody know why these simple changes made it work?

~ Jake

UPDATE AGAIN!

I took away the "Serial.println" parts I just added to see if it was them or removing the "allLedsOff" function that fixed my problem.
Doing so brought the issue back, meaning the issue is in this part...

    while (remainder < i)
    {
      int j = i / 2;
      if (j >= 1)
      {
        Serial.println("LED off");
        i = i - j;
        thisPin--;
      }
      else
      {
        i = 0;
        Serial.println("i=0");
      }
    }
     double j = i / 2;

Since i is an integer, if i is equal to 1, i/2 evaluates to 0, not 0.5.

So I could get rid of the j altogether and just do "i=i/2", and it will eventually reach 0?

Something evil happens in this loop during the last iteration (index == 0).

    for (int index = sizeOfArray - 1; index >= 0; index--)
    {
      if (a[index] < a[index - 1]) {
        int tmp = a[index];
        a[index] = a[index - 1];
        a[index - 1] = tmp;
        swapped = true;
      }
    }

aarg:

    double j = i / 2;

Since i is an integer, if i is equal to 1, i/2 evaluates to 0, not 0.5.

To clarify, the result of i/2 is 0.5
Since the only variable involved in this calculation is an integer, the result is cast to int, so it ends up being 0.
Only then this result is copied to j. I personally find this behaviour a bit strange. It would be nicer if the compiler would include the type of the receiving variable as well in his decision, where to cast the result.

However, you can manually tell the compiler which type to use, when casting the result.

    double j = (double) i / 2;

omgzzz:
So I could get rid of the j altogether and just do "i=i/2", and it will eventually reach 0?

If you repeatedly divide an integer by n (using integer division), it is guaranteed to reach 0 eventually.

Okay so I tried removing 'j' altogether, and just used "i=i/2", however for some reason the binary for the lowest number in the array is not shown and the 50 random numbers are printed again? Haha.
So then I tried putting 'j' back and just adding (double). So I had "int j = (double) i / 2;" this still for some reason printed the 50 random numbers again. :confused:

oqibidipo, isn't index supposed to reach 0? As indexes start at 0 I would still have to swap the 0th index if it was larger than the 1st index?

Many thanks for the effort though guys! :slight_smile:

~ Jake

omgzzz:
however for some reason the binary for the lowest number in the array is not shown

Huh? What does that mean? Especially as your program is essentially non-documented...

aarg:
Huh? What does that mean? Especially as your program is essentially non-documented...

Sorry, I'm just adding comments on the code now, and i'll re-post what I have now got.

What I meant there was when I call to the function "lowestArrayBinary" instead of it working and outputting the value of the lowest number in the array to the LED pins in binary, it just re-prints the 50 random numbers I have already printed. Sort of like it has started the loop again.

UPDATE!
Here the current code that I have...

int incomingByte; //a variable to read incoming serial data into
int Array[50] = {
};
int pinArray[] = {
  6, 7, 8, 9, 10, 11, 12, 13
};
int highArray;
int lowArray;
int pinCount = 14; //amount of pins being used on the arduino
void setup() {
  //initialize serial communication:
  Serial.begin(9600);
  for (int thisPin = 0; thisPin < pinCount; thisPin++) //initialize the LED pins as an output
  {
    pinMode(pinArray[thisPin], OUTPUT);
  }
  // if analog input pin 0 is unconnected, random analog
  // noise will cause the call to randomSeed() to generate
  // different seed numbers each time the sketch runs.
  // randomSeed() will then shuffle the random function.
  randomSeed(analogRead(0));
  for (int i = 0; i < 50; i++) // repeats 50 times
  {
    Array[i] = random(256); // Puts a random number from 0-255 into the array
    Serial.println(Array[i]);

  }
}

void loop() {

  if (Serial.available() > 0) {
    //read oldest byte in the serial buffer:
    incomingByte = Serial.read();

    sort(Array, 50); //sorts the array
    for (int i = 0; i < 50; i++)
    {
      Serial.print(Array[i]); //prints the array, now in ascending order
      Serial.print(",");
    }
    Serial.println();
    lowArray = Array[0];  //makes lowArray = to the array index 0
    highArray = Array[49];  //makes highArray = to the array index 49
    Serial.print("Low Array = "); //prints lowest array
    Serial.println(lowArray);
    Serial.print("High Array = "); //prints highest array
    Serial.println(highArray);
    highestArrayBinary();       //calls highestArrayBinary function
    delay(5000);
    allLedsOff();     //turns all LEDs off
    lowestArrayBinary();    //calls lowestArrayBintary function
    delay(5000);
  }
}

void sort(int a[], int sizeOfArray) { // bubble sort to ascending order
  boolean swapped = true;
  while (swapped) // loop until there are no swaps
  {
    swapped = false;
    for (int index = sizeOfArray - 1; index > 0; index--) //Bubble sort array
    {
      if (a[index] < a[index - 1]) { 
        int tmp = a[index];
        a[index] = a[index - 1];
        a[index - 1] = tmp;
        swapped = true;
      }
    }
  }
}

void highestArrayBinary() 
{
  int i = 128; //value of pins in binary
  int thisPin = 7; //index of current pin
  int remainder = highArray; //remainder is what I am going to be left with after taking away the value of the pins.
  //it is equal to the value of the highest index in the array.
  while (remainder > 0)
  {
    while (remainder >= i) //while remainder is larger than or equal to the value of the current pin
    {
      int j = i / 2; 
      digitalWrite(pinArray[thisPin], HIGH);
      remainder = remainder - i; //takes value of pin away from remainder
      i = i - j; //halves the value of i
      thisPin--; //moves to next pin
    }
    while (remainder < i) //while the value of the current pin is larger than the remainder
    {
      int j = i / 2;
      if (j >= 1)
      {
        i = i - j;  //halves the value of i
        thisPin--;  //moves to next pin
      }
      else
      {
        i = 0;
      }
    }
  }
}

void lowestArrayBinary() 
{
  int i = 128; //value of pins in binary
  int thisPin = 7; //index of current pin
  int remainder = lowArray; //remainder is what I am going to be left with after taking away the value of the pins.
  //it is equal to the value of the lowest index in the array
  while (remainder > 0)
  {
    while (remainder >= i) //while remainder is larger than or equal to the value of the current pin
    {
      int j = i / 2; 
      digitalWrite(pinArray[thisPin], HIGH);
      remainder = remainder - i; //takes value of pin away from remainder
      i = i - j; //halves the value of i
      thisPin--; //moves to next pin
    }
    while (remainder < i) //while the value of the current pin is larger than the remainder
    {
      int j = i / 2;
      if (j >= 1)
      {
        Serial.println("LED OFF");
        i = i - j;  //halves the value of i
        thisPin--;  //moves to next pin
      }
      else
      {
        i = 0;
      }
    }
  }
}

void allLedsOff()
{
  for (int thisPin = 0; thisPin < pinCount; thisPin++)
  {
    digitalWrite(pinArray[thisPin], LOW); //Turns off all LED pins
  }
}

This seems to work fine, but I don't think it will be accepted with it outputting "LED OFF" when it skips a pin in the lowestArrayBinary function.

omgzzz:
oqibidipo, isn't index supposed to reach 0? As indexes start at 0 I would still have to swap the 0th index if it was larger than the 1st index?

What's a[index - 1] when index == 0?

oqibidipo:
What's a[index - 1] when index == 0?

Haha, I see what you mean. I've changed it to "index>0;" rather than "index>=0;".
Thank you.

But still when I removed "Serial.println("LED OFF");" again the LEDs for lowestArrayBinary went back to doing what they did before and only the 1st/2nd ones work. :confused:

~ Jake

hydrocontrol:

double j = i / 2;

To clarify, the result of i/2 is 0.5
Since the only variable involved in this calculation is an integer, the result is cast to int, so it ends up being 0.

i is an integer.
2 is an integer.
The compiler will therefore do an integer division.
The result of this division will be converted to a double, and will be put into j.

In any event, this is not the way you extract bits from a numeric value. Look into the bit operators: ~ & | ^ << >> .

This is driving me insane ahaha, I had it but it just outputted something i didn't want.

Anyway, I looked into bit operators, and changed the "lowestArrayBinary" function to this...

void lowestArrayBinary()
{
  int remainder = lowArray;
  int j = 128;
  for (int i = 7; i >= 0; i--)
  {
    if (remainder >= j)
    {
      digitalWrite(pinArray[i], HIGH);
      Serial.println("PIN ON");
      remainder = remainder - j;
      j = j >> 1;
    }
    else 
    {
      Serial.println("PIN OFF");
      j = j >> 1;
    }

  }
}

From what i've picked up online, I think this cycles through each pin and if remainder goes into j it should light up and print "LED ON". If it doesn't go into j then it just gets halved and "LED OFF" gets printed.

However the LED lights don't work as they should again. "LED ON/LED OFF" is printed correctly, showing that it should be on, but any LEDs past the index 0 & 1 won't turn on.

UPDATE!
I unplugged the Arduino, then plugged it back in, loaded up the program and it worked.
Before I restarted it, it did say something about there not being enough memory.
But yeah, it all seems to be working now, so thanks guys!

Here's my final code for those who wish to see?

int incomingByte; //a variable to read incoming serial data into
int Array[50] = {
};
int pinArray[] = {
  6, 7, 8, 9, 10, 11, 12, 13
};
int highArray;
int lowArray;
int pinCount = 7; //amount of pins being used on the arduino
void setup() {
  //initialize serial communication:
  Serial.begin(9600);
  for (int thisPin = 0; thisPin <= pinCount; thisPin++) //initialize the LED pins as an output
  {
    pinMode(pinArray[thisPin], OUTPUT);
  }
  // if analog input pin 0 is unconnected, random analog
  // noise will cause the call to randomSeed() to generate
  // different seed numbers each time the sketch runs.
  // randomSeed() will then shuffle the random function.
  randomSeed(analogRead(0));
  for (int i = 0; i < 50; i++) // repeats 50 times
  {
    Array[i] = random(256); // Puts a random number from 0-255 into the array
    Serial.println(Array[i]);
  }
}

void loop() {

  if (Serial.available() > 0) {
    //read oldest byte in the serial buffer:
    incomingByte = Serial.read();

    sort(Array, 50); //sorts the array
    for (int i = 0; i < 50; i++)
    {
      Serial.print(Array[i]); //prints the array, now in ascending order
      Serial.print(",");
    }
    Serial.println();
    lowArray = Array[0];  //makes lowArray = to the array index 0
    highArray = Array[49];  //makes highArray = to the array index 49
    //Serial.print("Low Array = "); //prints lowest array
    //Serial.print("High Array = "); //prints highest array
    highestArrayBinary();       //calls highestArrayBinary function
    delay(5000);
    allLedsOff();     //turns all LEDs off
    lowestArrayBinary();    //calls lowestArrayBintary function
    delay(5000);
  }
}

void sort(int a[], int sizeOfArray) { // bubble sort to ascending order
  boolean swapped = true;
  while (swapped) // loop until there are no swaps
  {
    swapped = false;
    for (int index = sizeOfArray - 1; index > 0; index--) //Bubble sort array
    {
      if (a[index] < a[index - 1]) {  //if the next index is larger than the current index
        int tmp = a[index];
        a[index] = a[index - 1];  //swaps current index for next index
        a[index - 1] = tmp;  //swaps next index for current index
        swapped = true;    //says there was a swap on this pass, keep looping till there are no swaps.
      }
    }
  }
}

void highestArrayBinary()
{
  int remainder = highArray; //remainder is what I am going to be left with after taking away the value of the pins.
  int j = 128; //value of pins in binary
  int i = 7; //index of current pin
  while (i >= 0)
  {
    if (remainder >= j) //if remainder is larger or equal to the value of the current pin
    {
      digitalWrite(pinArray[i], HIGH);
      remainder = remainder - j; //takes value of pin away from remainder
      j = j >> 1; //halves the value of j
      i--; //moves to next pin
    }
    else
    {
      j = j >> 1; //halves the value of j
      i--; //moves to next pin
    }
  }
}

void lowestArrayBinary()
{
  int remainder = lowArray; //remainder is what I am going to be left with after taking away the value of the pins.
  int j = 128;  //value of pins in binary
  int i = 7;    //index of current pin
  while (i >= 0)
  {
    if (remainder >= j) //if remainder is larger or equal to the value of the current pin
    {
      digitalWrite(pinArray[i], HIGH);
      remainder = remainder - j;   //takes value of pin away from remainder
      j = j >> 1;   //halves the value of j
      i--;   //moves to next pin
    }
    else
    {
      j = j >> 1;   //halves the value of j
      i--;   //moves to next pin
    }
  }
}


void allLedsOff()
{
  for (int thisPin = 0; thisPin <= 7; thisPin++)
  {
    digitalWrite(pinArray[thisPin], LOW); //Turns off all LED pins
  }
}

Two functions for doing the same task with different parameters. Why?

void highestArrayBinary()
{
  int remainder = highArray; //remainder is what I am going to be left with after taking away the value of the pins.
  // REST: IDENTICAL CODE
}

void lowestArrayBinary()
{
  int remainder = lowArray; //remainder is what I am going to be left with after taking away the value of the pins.
  // REST: IDENTICAL CODE
}

If you're working with floating point numbers, tell the compiler about it. Since the Arduino IDE doesn't support the double data type, why not use:

float j =(double) i / 2.0;   // Now the compiler knows both operands are floats.

Also, j is a crappy name for a floating point number, since it's often an integer number used to control a loop.