This is a simulation of a difference engine calculating cubes. It is running on a nano.
The sketch is appended. The display sticks are the MAX7219 8-digit 7-segment modules available on eBay.
I used shiftOut rather than the SPI library because SPI.transfer() hangs on the nano i am using despite working just fine on a Uno.
// Difference Engine
#define mosi 11 // assigned by SPI protocol
#define sck 13 // ""
long Register[8]; //eight difference engine registers
long Turns; //turns of the crank
char chipSel[8] = {2, 3, 4, 5, 6, 7, 8, 9}; //eight displays with separate chip selects
void setup() {
pinMode(mosi, OUTPUT); //serial data
pinMode(sck, OUTPUT); //and clock
for (int i = 0; i < 8; i++) { //all eight sticks
startupMAX(chipSel[i]); //start them up
}
Register[0] = 6; //initial values for computing cubes
Register[1] = 12;
Register[2] = 7;
Register[3] = 1;
Turns = 1; //turns of the crank. Number whose cube
//was just calculated
}
void loop() { //turn the crank
Register[4] = ++Turns; //display turns in the fifth stick
Register[3] = Register[3] + Register[2]; //differences
Register[2] = Register[2] + Register[1];
Register[1] = Register[1] + Register[0];
for (int i = 0; i < 8; i++) {
displayDec(chipSel[i], Register[i]); //display the results
}
delay(4000);
}
void startupMAX(char CS) {
digitalWrite(CS, HIGH); //try to make this come up high
pinMode(CS, OUTPUT);
shift16(CS, 0x0000); //nop to get it in sync
shift16(CS, 0x0f00); //get it out of lamp test mode
shift16(CS, 0x09ff); //decode all digits
shift16(CS, 0x0a04); //medium intensity
shift16(CS, 0x0b07); //display all digits
shift16(CS, 0x0c01); //normal operation
for (int i = 1; i < 9; i++) { //blank all digits
shift16(CS, (i << 8 | 0x0f));
}
}
int displayDec(char CS, long theNumber) { //display a decimal number
//on the appropriate stick
//handles negative (not needful)
long power10[8] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
int digit; //the digit we are currently working on
int value; //working
boolean leading = true; //will blank leading zeroes
boolean negative = false; //assume not negative
long myCopy = theNumber; //working copy of input
if (myCopy < 0) { //test for negative
myCopy = abs(myCopy); //convert to positive
negative = true; //note negative
}
if ((negative == true) && (myCopy > 9999999)) { //test for less than -9,999,999
for (int i = 1; i < 8; i++) { //display
shift16(CS, i << 8 | 0xB); // EEEEEEE
}
shift16(CS, 0x080a); // leading minus sign
return true;
}
if ((negative == false) && (myCopy > 99999999)) { //test for > 99,999,999
for (int i = 1; i < 9; i++) { //display EEEEEEEE
shift16(CS, i << 8 | 0xB);
}
return true;
}
for (digit = 7; digit > -1; digit--) { //each digit, each power of 10
value = 0;
if ((negative == true) && (digit == 7)) { //test for negative and right-most digit
value = 10; //minus sign
}
else {
while (myCopy >= power10[digit]) { //if so, can subtract once more
value++; //result
myCopy = myCopy - power10[digit]; //reduce by power of ten
}
}
unsigned int pattern = digit + 1 ; //form the command: register number
pattern = pattern << 8; //aligned
if ((value == 0) && (leading == true) && (digit != 0)) { //replace leading zeroes
value = 0x0f; //with blank decode
}
else if ((value > 0) && (value != 10)) { //still leading zeroes?
leading = false; //no more
}
pattern = pattern | value; //the number to display
shift16(CS, pattern); // display it
} // goes with for (digit....
return false; //success
}
void setIntensity(char CS, char intensity) {
shift16(CS, (0x0a00 | intensity)); //form the command and send it
}
void shift16(char CS, unsigned int shiftee) { //actually write a MAX7219 register
digitalWrite(CS, LOW); //chip select
shiftOut(mosi, sck, MSBFIRST, shiftee >> 8); //could not get SPI() to run on a nano
shiftOut(mosi, sck, MSBFIRST, shiftee);
digitalWrite(CS, HIGH);
}