breaking up an int

Hey guys,

Having a mental blank - been soldering all day, coding the last couple of hours, neighbor is mowing lawn with some oversized mower, wife is eating some d___ noisy crunchy food, I just can't think.
How do I break a 3-digit number into it's 3 digits?
Got 15 of them in an unsigned int array to break up and spread across 6 MAX7219s, with pairs of them driving 3+3+1 and 2+3+3 to make the 15 groups of 3 seven-segment displays.

I just want to break up each int into 3 bytes that I can then send to the MAX7219s.

Thanks a heap.

Robert

341 % 10 = 1
(341/10) % 10 = 4
341/100 = 3

// -------------------------------------
int arr [10];

int
digits (
    int     val)
{
    int i;
    for (i = 0; val; i++, val /= 10)
        arr [i] = val % 10;
    return i;
}

// -------------------------------------
void
disp (
    int val)
{
    int n = digits (val);

    for (int i = 0; i < n; i++) {
        Serial.print (" ");
        Serial.print (arr [i]);
    }
    Serial.println ("");
}


// -------------------------------------
void
setup (void)
{
    Serial.begin (9600);
   disp (123); 
   disp (456); 
   disp (7890); 
}

// -------------------------------------
void
loop  (void)
{
}

Please, explain/describe your problem with a numerical example along with schematics of the hardware setup.

C'mon, that's too simple. Thanks guys. Never used modulo before.

GolamMostafa, the hardware/schematics are not important. It's enough to know that I have an array of 15 3 digits ints (0-999) that needed to be broken up into an array of 45 bytes that MAX7219s will display.

I usually keep track when counting things digit by digit, when a digit hits 10 I roll it back to 0 and increment the next, dealing with double rollover at 99 and 999. That way the digits are already broken up when I want to display them.

Spent today mounting a bunch of stuff to large piece of oriented strand board, digging up screws and standoffs, making a stable test environment for the 15 digits with 1284P board, mounting 16 push buttons (one is power), mounting the power supply, mounting the RPi, mounting a couple of little speakers, mounting a 7" LCD display. Next step is putting crimp pins on the button harnesses. Gonna take a break and work in the modulo code first.

Of course you are now obligated to show us the working version :wink:

Kept it simple, I think I might need to swap ends, or move digits within the MAX7219s.
Even compiled into the overall program correctly the first time:

// if = 1, a change was made and we are updating digits here
// and displaying in the next tab

if (updateDisplay == 1) {
  updateDisplay = 0; // clear for next button press

  // 341 % 10 = 1
  // (341/10) % 10 = 4
  // 341/100 = 3

  dataBank[2] =  dataCount[0] / 100;     // hundreds
  dataBank[1] = (dataCount[0] / 10) % 10; // tens
  dataBank[0] =  dataCount[0] % 10;      // ones

  dataBank[5] =  dataCount[1] / 100;     // hundreds
  dataBank[4] = (dataCount[1] / 10) % 10; // tens
  dataBank[3] =  dataCount[1] % 10;      // ones

  dataBank[8] =  dataCount[2] / 100;     // hundreds
  dataBank[7] = (dataCount[2] / 10) % 10; // tens
  dataBank[6] =  dataCount[2] % 10;      // ones

  dataBank[11] =  dataCount[3] / 100;     // hundreds
  dataBank[10] = (dataCount[3] / 10) % 10; // tens
  dataBank[9] =  dataCount[3] % 10;      // ones

  dataBank[14] =  dataCount[4] / 100;     // hundreds
  dataBank[13] = (dataCount[4] / 10) % 10; // tens
  dataBank[12] =  dataCount[4] % 10;      // ones

  dataBank[17] =  dataCount[5] / 100;     // hundreds
  dataBank[16] = (dataCount[5] / 10) % 10; // tens
  dataBank[15] =  dataCount[5] % 10;      // ones

  dataBank[20] =  dataCount[6] / 100;     // hundreds
  dataBank[19] = (dataCount[6] / 10) % 10; // tens
  dataBank[18] =  dataCount[6] % 10;      // ones

  dataBank[23] =  dataCount[7] / 100;     // hundreds
  dataBank[22] = (dataCount[7] / 10) % 10; // tens
  dataBank[21] =  dataCount[7] % 10;      // ones

  dataBank[26] =  dataCount[8] / 100;     // hundreds
  dataBank[25] = (dataCount[8] / 10) % 10; // tens
  dataBank[24] =  dataCount[8] % 10;      // ones

  dataBank[29] =  dataCount[9] / 100;     // hundreds
  dataBank[28] = (dataCount[9] / 10) % 10; // tens
  dataBank[27] =  dataCount[9] % 10;      // ones

  dataBank[32] =  dataCount[10] / 100;     // hundreds
  dataBank[31] = (dataCount[10] / 10) % 10; // tens
  dataBank[30] =  dataCount[10] % 10;      // ones

  dataBank[35] =  dataCount[11] / 100;     // hundreds
  dataBank[34] = (dataCount[11] / 10) % 10; // tens
  dataBank[33] =  dataCount[11] % 10;      // ones

  dataBank[38] =  dataCount[12] / 100;     // hundreds
  dataBank[37] = (dataCount[12] / 10) % 10; // tens
  dataBank[36] =  dataCount[12] % 10;      // ones

  dataBank[41] =  dataCount[13] / 100;     // hundreds
  dataBank[40] = (dataCount[13] / 10) % 10; // tens
  dataBank[39] =  dataCount[13] % 10;      // ones

  dataBank[44] =  dataCount[14] / 100;     // hundreds
  dataBank[43] = (dataCount[14] / 10) % 10; // tens
  dataBank[42] =  dataCount[14] % 10;      // ones

Won't know that I have digits going to the right displays until I get these wiring harnesses made up. Off to the soldering iron ...

"Never used modulo before."

You??

Me. Never used it. Usually I am doing stuff for speed. In this case it's simple button pushes, one of 15, add to an existing count and show the new total, lock the button out for a second or so. No speed needed at all. I'm out of 4-pin crimp housings, will wire up other stuff in the meantime while I wait for a couple of days on delivery.

For speed, repeated subtraction can beat division, even though it seems ungainly:

// compare two methods of conversion int to string
// 2020-5-23 aarg

unsigned long startTime;
unsigned long elapsedTime;
int maxRepTime = 0;
int maxModTime = 0;
char *res;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("series...");
  for (int i = 31111; i <= 32000; i++) {
    startTime = micros();
    res = toStr(i);
    elapsedTime = micros() - startTime;
    if (elapsedTime > maxRepTime) maxRepTime = elapsedTime;

    Serial.print("#=");
    Serial.print(i);
    Serial.print(" repDiv=");
    Serial.print(toStr(i));
    Serial.print(" us = ");
    Serial.print(elapsedTime);

    startTime = micros();
    res = toStrMod(i);
    elapsedTime = micros() - startTime;
    if (elapsedTime > maxModTime) maxModTime = elapsedTime;
    Serial.print(", modDiv=");
    Serial.print(toStrMod(i));
    Serial.print(" us = ");
    Serial.println(elapsedTime);
  }
  Serial.print("max rep method time = ");
  Serial.println(maxRepTime);
  Serial.print("max mod method time = ");
  Serial.println(maxModTime);
}

void loop() {
}

char* toStr (int val) {
  static char result[6];
  strncpy(result, "00000", 6);

  const int decade[] = {10000, 1000, 100, 10};
  for (int index = 0; index < 4; index++)
  {
    while (val >= decade[index])
    {
      result[index]++;
      val -= decade[index];
    }
  }
  result[4] += val;
  return result;
}

char* toStrMod (int num) {
  static char result[6];

  for (int len = 4; len >= 0; --len)
  {
    result[len] = num % 10 + '0';
    num /= 10;
  }
  result[5] = '\0';
  return result;
}

prints (showing just the last few lines...)

#=31997 repDiv=31997 us = 32, modDiv=31997 us = 84
#=31998 repDiv=31998 us = 32, modDiv=31998 us = 84
#=31999 repDiv=31999 us = 32, modDiv=31999 us = 84
#=32000 repDiv=32000 us = 20, modDiv=32000 us = 84
max rep method time = 40
max mod method time = 92

I'm not sure if this will be helpful, but a few years ago I wrote some code on a different microcontroller P8X32A (Parallax Propeller) that controls a 6 digit 17 segment display. The display was connected to two PCA9555's, one controlled the digits, the other controlled the segments. It was alot of multiplexing. I was intending on using 3 homemade modules to control 3 sets of displays over I2C. But, if you watch the video, you can see all the flickering I was getting. SPI bus expanders would have been much faster. Also note that the micro I used is 8 core 80Mhz.

Anyway, the code is in SPIN but the logic is simple enough to translate to C. PPDB - Using the full PPDB - Updated Code Version 1.4 — Parallax Forums

Maybe it will help....

CrossRoads:
[...] the hardware/schematics are not important. It's enough to know that I have an array of 15 3 digits ints (0-999) that needed to be broken up into an array of 45 bytes that MAX7219s will display.

cc-type 15x3-digits array would require 6 MAX7219 chips as drivers. Naturally, I would be interested to see how you have done the cascading and also the coding to see the method of initialization and handling the display.