% operator gives unknown & unexpected result

Hi,

“The modulo operator % computes the remainder. When a = 9 is divided by b = 4, the remainder is 1. The % operator can only be used with integers.”

Although, in the following piece of code, the condition “if( (t %10) == 1 )” and the ones after aren’t being run.
Already verified if I swap t for a number (1, 101, etc) the code following the “if” statement will run.

Already declared the “alarm” array as just an integer but had no luck.

//(...)

//global variable
unsigned int *alarm[14][4] = { {06, 30, 0, 0}, {0, 0, 0, 0} };
//  alarm[x][4] = d*E6 + s*E5 t*E4 q*E3 q*E2 s*E1 s*1

  

//(...)
//in setup function:

short int i;
  for(i=0; i<15; i++)
  {
    alarm[i][0]=0;
    alarm[i][1]=0;
    alarm[i][2]=0;
    alarm[i][3]=0;
  }
  alarm[1][2]=1;
  alarm[1][3]=1111111;
//(...)
//(...) in another function

 int t;

//(...) still in this another function

      {
        tft.print("  ON");
        t = alarm[i][3]; 
        if( (t %10) == 1 ) {tft.setCursor(0, e[i]); tft.print( "Dom " );}
        if( (t %100) == 1 ) {tft.setCursor(0, e[i]); tft.print( "2a " );}
        if( (t %1000) == 1 ) {tft.setCursor(0, e[i]); tft.print( "3a " );}
        if( (t %10000) == 1 ) {tft.setCursor(0, e[i]); tft.print( "4a " );}
        if( (t %100000) == 1 ) {tft.setCursor(0, e[i]); tft.print( "5a " );}
        if( (t %1000000) == 1 ) {tft.setCursor(0, e[i]); tft.print( "6a " );}
        if( (t %10000000) == 1 ) {tft.setCursor(0, e[i]); tft.print( "Sab " );}
      }

I am not receiving any error message.

I found the mod operator to work quite well:

void IRAM_ATTR onTimer()
{
  BaseType_t xHigherPriorityTaskWoken;
  iTicCount++;
  xEventGroupSetBitsFromISR(eg, OneMilliSecondGroupBits, &xHigherPriorityTaskWoken);
  if ( (iTicCount % 2) == 0 )
  {
    if ( (xSemaphoreTakeFromISR(sema_ReceiveSerial_LIDAR, &xHigherPriorityTaskWoken)) == pdTRUE ) // grab semaphore, no wait
    {
      xEventGroupSetBitsFromISR(eg, evtReceiveSerial_LIDAR, &xHigherPriorityTaskWoken); // trigger every 2mS, if not already processing
    }
  }
  if ( (iTicCount % 3) == 0 )
  {
    if ( (xSemaphoreTakeFromISR(sema_HexaPodAdjustment, &xHigherPriorityTaskWoken)) == pdTRUE ) // grab semaphore, no wait
    {
      xEventGroupSetBitsFromISR(eg1, evtWalk_Forward, &xHigherPriorityTaskWoken);
    }
  }
  if ( iTicCount == OneK )
  {
    xEventGroupSetBitsFromISR(eg, OneSecondGroupBits, &xHigherPriorityTaskWoken); // trigger every 1X a second
    // reset counter to start again
    iTicCount = 0;
  }
  if ( !bLIDAR_OK )
  {
    xSemaphoreTakeFromISR ( sema_iLIDAR_Power_Reset, &xHigherPriorityTaskWoken );
    ++iLIDAR_Power_Reset;
    xSemaphoreGiveFromISR ( sema_iLIDAR_Power_Reset,  &xHigherPriorityTaskWoken);
    if ( iLIDAR_Power_Reset >= 4000 )
    {
      xEventGroupSetBitsFromISR(eg, evtfLIDAR_Power_On, &xHigherPriorityTaskWoken);
    }
  }
} // void IRAM_ATTR onTimer()

As an example of my use of the % operator.

Thanks for replying, I see you usually compare the result of the % operator with zero, I switched my code so it compares with zero as well and it just worked fine.

        if( (t %10) != 0 ) {tft.setCursor(0, e[i]); tft.print( "Dom " );}
        if( (t %100) != 0 ) {tft.setCursor(0, e[i]); tft.print( "2a " );}
        if( (t %1000) != 0 ) {tft.setCursor(0, e[i]); tft.print( "3a " );}
        if( (t %10000) != 0 ) {tft.setCursor(0, e[i]); tft.print( "4a " );}
        if( (t %100000) != 0 ) {tft.setCursor(0, e[i]); tft.print( "5a " );}
        if( (t %1000000) != 0 ) {tft.setCursor(0, e[i]); tft.print( "6a " );}
        if( (t %10000000) != 0 ) {tft.setCursor(0, e[i]); tft.print( "Sab " );}

Perhaps the result of the % operator was 0.1 or lower, which makes sense now that I think about it. Once more thank you for replying.

"if( (t %10) == 1 )" True for 1, 11, 21, 31, 41, etc. "if( (t %100) == 1 )" True for 1, 101, 201, 301, etc. "if( (t %1000) == 1 )" True for 1, 1001, 2001, 3001, etc

unsigned int *alarm[14][4] = { {06, 30, 0, 0}, {0, 0, 0, 0} };

Why is alarm an 2D array of pointer to int?

  alarm[1][3]=1111111;

Even if alarm were the correct type, that is NOT a valid value, on most Arduinos.

        t = alarm[i][3];

t ans alarm[ i ] [3] are not the same type.

Applying the modulo operator to t is not going to give predictable results.

F1_: Thanks for replying, I see you usually compare the result of the % operator with zero, I switched my code so it compares with zero as well and it just worked fine.

Perhaps the result of the % operator was 0.1 or lower, which makes sense now that I think about it. Once more thank you for replying.

I like using the % operator to detect even and odd values.

As has been pointed out, it is a good idea to use values to mod in your value set that are unique or you'll get more then one correct answer.

The % result is an integer.

You are welcome.

In addition to what others have pointed out, you are referencing alarm[ 14 ] [ x ] in the for loop, which is out of range.

unsigned int *alarm[14][4] = { {06, 30, 0, 0}, {0, 0, 0, 0} };

//(...)

short int i;
  for(i=0; i<15; i++)
  {
    alarm[i][0]=0;
    alarm[i][1]=0;
    alarm[i][2]=0;
    alarm[i][3]=0;
  }
  alarm[1][2]=1;
  alarm[1][3]=1111111;
//(...)

Idahowalker: I like using the % operator to detect even and odd values.

That's a very inefficient and expensive technique in terms of processor cycles, especially on an 8-bit processor without hardware for performing division. Just do:

 if (myVariable & 0b1) {
    // it's odd
  } else {
    // it's even
  }

johnwasser: "if( (t %10) == 1 )" True for 1, 11, 21, 31, 41, etc. "if( (t %100) == 1 )" True for 1, 101, 201, 301, etc. "if( (t %1000) == 1 )" True for 1, 1001, 2001, 3001, etc

Understood, thanks for your attention johnwasser.

PaulS: unsigned int *alarm[14][4] = { {06, 30, 0, 0}, {0, 0, 0, 0} };

Why is alarm an 2D array of pointer to int?

Due to the size of the array I made it a pointer, perhaps not the best option indeed.

PaulS:   alarm[1][3]=1111111;

Even if alarm were the correct type, that is NOT a valid value, on most Arduinos. Applying the modulo operator to t is not going to give predictable results.

Please don't mind the comments, most of them were just guidance to make something later.

PaulS:         t = alarm[i][3];

t ans alarm[ i ] [3] are not the same type.

Applying the modulo operator to t is not going to give predictable results.

In fact, the array alarm is pretended to have small values that may go up to decimal "59". I understand your statement perfectly, thanks a lot for your time PaulS.

Idahowalker: I like using the % operator to detect even and odd values.

As has been pointed out, it is a good idea to use values to mod in your value set that are unique or you'll get more then one correct answer.

The % result is an integer.

You are welcome.

Understood, thank you Idahowalker.

david_2018: In addition to what others have pointed out, you are referencing alarm[ 14 ] [ x ] in the for loop, which is out of range. (...)

Indeed it was, thank you david_2018.

gfvalvo: That's a very inefficient and expensive technique in terms of processor cycles, especially on an 8-bit processor without hardware for performing division. Just do:

 if (myVariable & 0b1) {
    // it's odd
  } else {
    // it's even
  }

You are right, I opted for that due to the big dimension of the code, I will do as you advice and optimize the code in the end. Thank you gfvalvo.

F1_: ... unsigned int *alarm[14][4] = { {06, 30, 0, 0}, {0, 0, 0, 0} }; ...

Octal?

The array is intended to save minutes and hours thus the expected maximum being 59.
Meanwhile, the 3rd value may go up to 127, since it stores chosen days of the week in a binary number, I forgot to mention that.

The question was "why is it important that 6 be represented in octal, and not simply in decimal?"

I assume.

AWOL: I assume.

Correctly.

Damn, I may actually be psychic after all.

Or I’ve just been here too long.

On reflection, I suspect the latter

It turns out I had no idea that the 6 was being represented as an octal number, is it because of the 0 before the 6?

Did some search and found out it is indeed the 0. I will be more careful where I write zeros from now on, I had no idea that was how to declare an octal number.

Thank you very much for pointing it out Coding Badly and AWOL.

Yup

AWOL: On reflection, I suspect the latter

https://www.youtube.com/watch?v=pyhii0W6LAo

[quote author=Coding Badly link=msg=4185964 date=1558726864]

[/quote] Yup. (The physical likeness with Abe is remarkable)