Controlling a LOT of inputs! [Dev]

Hello, everyone, this is my FIRST post on the forums here! I'm really excited to gain some feedback on this project. So without further introduction, I'd like to get into the meat and potatoes of the project right away!

Obviously the main goal of the project which is implied by the category it is in as well as the title entails controlling A LOT of inputs. There are many great ways of doing this, and some of my favorites are using EEPROMs or UV erasable PROMs (in specific the AMD or ATMEL series) or the ever so popular TI 74HC595N.
Arduino has really made programming and controlling these things easier by allowing us to use the simple shiftOut() object, but generally, I see a lot of folks using large arrays of 8-bit UINTs into the object to attempt to control multiple shift registers or burn a program to a PROM. This is where my project comes into play!

A simple library which would provide a function just as versatile as shiftOut() only it accepts ANY integer from 0 - 16777215 (Which works out to be 3-Bytes long). Which would then, in turn, allow us to control an LED Matrix with 3-Bytes worth of possible patterns in a single line.

So here is what I have so far:

I usually like to program logic programs like this in C++ first to debug it about a million times before I decide to start burning my program into my microcontrollers.

This program will take ANY UINT32 long number and process it into two UINT8 numbers which when shifted out have the binary equivalent of the whole original number.

A short overview of the logical process:

The number 500 in binary is equal to: 1111101001
If we add the unused 0's at the end of the binary number we will get: 11111010010000000
The library has already used calculus theorems to determine the Byte size (which is two) so
now all that is left is to break it into two separate Bytes.

Byte-1 Byte-2
[11110100] [00000001]

[Byte-1, Byte-2]
Covert it into two UINT8 numbers: [244, 128]

Now using the existing shiftOut() algorithm we can shift each Byte out in integer form which is easy in Arduino. But we must shift it out in opposite order because the bytes as they come in will push the next set over.

Byte-1 -> shiftOut(dataPin, clockPin, bitOrder, Byte-1);

Output to internal latch => [11110100]

Byte-2 -> shiftOut(dataPin, clockPin, bitOrder, Byte-2);

Output to internal latch => [0000000111110100]

This final 16-Bit long binary output of 0000000111110100 = 500

I'm sure there's probably a thousand better ways to go about it compared to the way that I did, but here's the program running in C++ (For now).

[WARNING! MESSY CODE]

#include <iostream>
#include <math.h>

using namespace std;

// Global variables and constants
const double BASE_MULTIPLIER = 2;
double exponent = 0;
int bytes;

// Calculus functions
int f() {
    return pow(BASE_MULTIPLIER, (exponent * 8));
}

int g() {
    return pow(BASE_MULTIPLIER, ((exponent + 1) * 8));
}

void binaryBreakDown(int data) {
    
    /* Using the intermediate value theorem we are able to determine the set of bytes in which our integer resides
      y = f(x) <= c < g(x) it is important to set the first inequality greater than OR equal to in our case or we
      will run into mathmatical computational errors when we hit the first or last number of a certain Byte value */
    bool ivt = true;
    while(ivt) {
        if (f() <= data && data < g()) {
            bytes = exponent;
            cout << f() << " < " << data << " < " << g() << endl;
            ivt = false;
        } else {
            exponent++;
        }
    }
    
    // Populate an array called `bitSet` with the binary values according to its place in the array
    int bitSet[(int) ((bytes + 1) * 8)];
    for (int i = 0; i <= (sizeof(bitSet)/sizeof(*bitSet)); i++) {
        cout << "LOADED " << data % 2 << " -> BIT [" << i << "]" << endl;
        bitSet[i] = data % 2;
        data = data / 2;
    }
    
    // `decimalSet` will hold the value of each binary set in UINT8 format
    uint decimalSet[bytes + 1];
    
    // `setDecimal` is where the UINT8 values pulled from the binary array are added and stored
    uint setDecimal = 0;
    
    // `firstBit` will ensure there is no overlapping of data between two bytes (particularly the first and second set)
    bool firstBit = true;
    
    /* This algorithm swaps the bits in the array, this is important as when breaking down a decimal into
     its binary form the bits will read according to the least significant bit first. If you desire to have
     the least over the most significant bit be displayed the second loop must INCREMENT instead of DEINCREMENT*/
    for (int i = 0; i <= bytes; i++) {
        firstBit = (i > 0) ? 1 : 0;
        cout << (i * 7) + firstBit << " -> " << ((i + 1) * 7) + firstBit << endl;
        for (int j = ((i + 1) * 7 + firstBit); j >= ((i * 7) + firstBit); j--) {
            if (bitSet[j] == 1) {
                setDecimal += pow(2, (j - firstBit));
            }
        }
        cout << "TO SHIFT DIGIT -> " << setDecimal << endl;
        decimalSet[i] = setDecimal;
        setDecimal = 0;
    }
    cout << endl;
}


int main(int argc, const char * argv[]) {
    
    // HAS TO BE WITHIN 0, and 16777215 //
    int data = 500;
    binaryBreakDown(data);
    
}

Lots of good comments in there I will be posting AGAIN here shortly in this same thread with some mathematical diagrams and further explanations!

As I progress with this logic library, I will also be building an LED Cube (Size to be determined).

I had ordered all the parts to build it via. eBay but due to Chinese New Year, I probably won't have the parts for a very long time. So I will take the opportunity to buy some parts for another LED Cube via. amazon ! :slight_smile:

Ok let’s get some things straight first.

Obviously the main goal of the project which is implied by the category it is in as well as the title entails controlling A LOT of inputs. There are many great ways of doing this, and some of my favorites are using EEPROMs or UV erasable PROMs

You do not control inputs, you control outputs and you read inputs. You can not use ROMs with inputs in any way that makes sense.

But we must shift it out in opposite order because the bytes as they come in will push the next set over.

No what is wrong with just shifting them out and wiring the outputs to suit what you want?

As to your code, those functions are not calculus. You seem to be doing simple things in a very complex way.

This algorithm swaps the bits in the array, this is important as when breaking down a decimal into
its binary .......

No it is not useful for this at all. All variables are in binary, they need to be converted into decimal for printing but that is it.

Well I definately worded that wrong. I guess that's what I get for typing this up so late. I 100% meant to write outputs haha.