[Solved] Mega says 903 times 100 is 24764.

I am starting to supect that my arduino Mega doesn’t have the processing power I need. I have gone to great lengths to debug pieces of the issue. Will someone please load this simple code and tell me if their arduino Mega calculates it correctly?

float FLOAT = 903; // number stored in sd file
int INT = 0;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
}

void loop() { 
  Serial.print("Float is ");
  Serial.println(FLOAT);
  Serial.print("float * 100 is ");
               INT = (FLOAT*100);
               Serial.println(INT);
               Serial.println("");
               Serial.println("Wait.... I thought it was");
               Serial.println("---------------------");
               Serial.println(FLOAT*100);
               Serial.println("");
               Serial.println("Am I crazy?");
               Serial.println("");
               
               delay(5000);
}

What I’ve done is basically take a float and multiplied that by 100, and turned in into an interger. The problem is, when I do that the mega reads the integer as 24764 but reads the float as 90300. Is that simple math to much for a mega? Or do I need to use special consideration when turning floats to ints?

Crazy.jpg

Look up int in the ref section!

Mark

Earlier is was saying when INT=FLOAT (without the times 100) the number was 902, instead of 903. I'm having a hard time replicating those results though. I tried multiplying times 100 to see if it was a rounding issue.

Quick, what's the biggest number an int can hold?

Try making INT a long and see what happens.

I am starting to supect that my arduino Mega doesn't have the processing power I need.

It does, but you need to choose the appropriate data type.

On ATmega 8-bit microcontrollers the default size for an int is 16 bits, for a long 32 bits.

If you want values outside these ranges an int will not do:

unsigned int : 0 .. 65535 int : -32768 .. 32767

A long will handle values over a billion.

I was able to replicate the orginal problem. Here I am trying to convert 903 into a int. 903 is only 3 digits, which shouldn’t require it to be a long. But the serial monitor says it is 902 instead of 903. Maybe my math for reading the number from the sd card is off?

#include <SD.h>
char sdNumberFile[] = "sd.txt"; // name of sd file information is stored to
float StoredNumber = 903; // number stored in sd file
int Number = 0;
void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
   pinMode(53, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
  }
  Serial.println("initialization done.");
  
}

void loop() { 
  if (SD.exists(sdNumberFile)) 
  //======================= Number File saved on SD Card ================================
        { 
         Serial.print(sdNumberFile); 
         Serial.println(F(" File Found."));
                                                                                                                                   
                                                                                                                                   
        } else {                                                                                                                   
                                                                                                                                   
                Serial.print(sdNumberFile);
                Serial.println(F(" File not found."));
                Serial.println("formatting ");
                Serial.println(F("..."));                                                                                                                     
                                                                                                                                   
                                                                                                                                     
                                                                                                                                   
                 File NumberFile = SD.open(sdNumberFile, FILE_WRITE); 
                 NumberFile.print(903);
                 NumberFile.close(); 
               }
               Serial.println("");
        File NumberFile = SD.open(sdNumberFile);
        if (NumberFile)
        { StoredNumber = 0;
          float tP = pow(10, (NumberFile.available() - 1)); // tP stands for Number Power
          while(NumberFile.available())
          { float tD = (NumberFile.read() - '0');           // tD stands for Number Digit
            StoredNumber = tD*tP+StoredNumber;
            tP = tP/10;
          }        
          NumberFile.close();
        } else { Serial.print("Problem Reading ");
                 Serial.println(sdNumberFile);
               }
               Serial.print("Stored Number is ");
               Number = (StoredNumber);
               Serial.println(StoredNumber);
               Serial.println(Number);
               delay(5000);

I am baffled by your number conversion. How about just reading into a string and then doing atoi on it?

Well That’s what I was trying to do originally. Epic failure. I wanted to read a string from a sd card that looked like 90,low,15.6,125* See below where I got.

#include <SD.h>

String readString; //main captured String 
String angle; //data String
String fuel;
String speed1;
String altidude;

int ind1; // , locations
int ind2;
int ind3;
int ind4;
char sdNumberFile[] = "sd.txt"; // name of sd file information is stored to
int StoredNumber = 0; // number stored in sd file



void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
   pinMode(53, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
}

void loop()
{
	// nothing happens after setup

        File NumberFile = SD.open(sdNumberFile);
        if (NumberFile)
        { Serial.println("Number File Found");
          char c = NumberFile.available();  //gets one byte from sd card
          
        
        
        
        if (c == '*') 
        { Serial.println();
          Serial.print("captured String is : "); 
          Serial.println(readString); //prints string to serial port out
      
      ind1 = readString.indexOf(',');  //finds location of first ,
      angle = readString.substring(0, ind1);   //captures first data String
      ind2 = readString.indexOf(',', ind1+1 );   //finds location of second ,
      fuel = readString.substring(ind1+1, ind2+1);   //captures second data String
      ind3 = readString.indexOf(',', ind2+1 );
      speed1 = readString.substring(ind2+1, ind3+1);
      ind4 = readString.indexOf(',', ind3+1 );
      altidude = readString.substring(ind3+1); //captures remain part of data after last ,

      Serial.print("angle = ");
      Serial.println(angle); 
      Serial.print("fuel = ");
      Serial.println(fuel);
      Serial.print("speed = ");
      Serial.println(speed1);
      Serial.print("altidude = ");
      Serial.println(altidude);
      Serial.println();
      Serial.println();
      
      readString=""; //clears variable for new input
      angle="";
      fuel="";
      speed1="";
      altidude="";
    }  
    else {     
      readString += c; //makes the string readString
    }
  ind1 = readString.indexOf(',');  //finds location of first ,
  angle = readString.substring(0, ind1);   //captures first data String

        { StoredNumber = 0;
          int tP = pow(10, (NumberFile.available() - 1)); // tP stands for Threat Number Power
          while(NumberFile.available() && readString.substring(0, ind1))
          { int tD = (NumberFile.read() - '0');           // tD stands for Threat Number Digit
            StoredNumber = tD*tP+StoredNumber;
            tP = tP/10;
            Serial.print("tP is ");
            Serial.println(tP);
          }               
          
          NumberFile.close();
        } else { Serial.print("Problem Reading ");
                 Serial.println(sdNumberFile);
               }
}

The code above is a modified version of the code Zoomkat provided (see below for working version)

//zoomkat 11-12-13 String capture and parsing  
//from serial port input (via serial monitor)
//and print result out serial port
//copy test strings and use ctrl/v to paste in
//serial monitor if desired
// * is used as the data string delimiter
// , is used to delimit individual data 

String readString; //main captured String 
String angle; //data String
String fuel;
String speed1;
String altidude;

int ind1; // , locations
int ind2;
int ind3;
int ind4;
 
void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 11-12-13"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like 90,low,15.6,125*
  //or 130,hi,7.2,389*

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == '*') {
      //do stuff
      
      Serial.println();
      Serial.print("captured String is : "); 
      Serial.println(readString); //prints string to serial port out
      
      ind1 = readString.indexOf(',');  //finds location of first ,
      angle = readString.substring(0, ind1);   //captures first data String
      ind2 = readString.indexOf(',', ind1+1 );   //finds location of second ,
      fuel = readString.substring(ind1+1, ind2+1);   //captures second data String
      ind3 = readString.indexOf(',', ind2+1 );
      speed1 = readString.substring(ind2+1, ind3+1);
      ind4 = readString.indexOf(',', ind3+1 );
      altidude = readString.substring(ind3+1); //captures remain part of data after last ,

      Serial.print("angle = ");
      Serial.println(angle); 
      Serial.print("fuel = ");
      Serial.println(fuel);
      Serial.print("speed = ");
      Serial.println(speed1);
      Serial.print("altidude = ");
      Serial.println(altidude);
      Serial.println();
      Serial.println();
      
      readString=""; //clears variable for new input
      angle="";
      fuel="";
      speed1="";
      altidude="";
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

But of course, any help in converting a string from an sd card to ints would be greatly appreciated. I just need to make sure I can take the numbers read from the sd card, and add to them if needed.

If you were using c-strings (null terminated char arrays) then it would be super easy. I don't know how to do it with the Stupid String class.

With char arrays you could use either itoa or strtol depending on how big the numbers are.

float FLOAT = 903; // number stored in sd file
int INT = 0;

This is just too dumb for words.

Just to translate PaulS's comment for you: Choose better data names, maybe.

For one thing, in C data-names in all capitals are usually constants. Second, calling a float variable FLOAT is confusing, don't you think? In your head you are thinking "upper-case FLOAT is a lower-case float".

If you were using c-strings (null terminated char arrays) then it would be super easy. I don't know how to do it with the Stupid String class.

With char arrays you could use either itoa or strtol depending on how big the numbers are.

Lets pretend that I am an absolute newb that just the other day was informed there is a difference in String and string... or something like that. The preloaded library is all I know, and every time I try to go out on my own and find the answers without asking for help.... well it isn't a very productive method. Any examples would be greatly appreciated.

float FLOAT = 903; // number stored in sd file int INT = 0;

This is just too dumb for words.

I tried to make the example easier to follow, for the helpers consideration. Maybe it wasn't the best idea of wording....

Look up "getline" for the SD card. You shouldn't have to fool around reading individual bytes.

I was already pushing the limits on memory though, Strings take a lot of memory.... I tried to improvise. I then met the limit of processing power.

I find that a little hard to believe. I have a sketch that reads in an entire .hex file and programs another microprocessor with it. That runs on an Atmega328 which has 32 kB of memory compared to the Mega's 256 kB.

Plus the "limit of processing power" is just that you used the wrong data type. It can handle large numbers.

For example (again on the Atmega328) I have a post that describes using big numbers, example output being:

60! = 8320987112741390144276341183223364380754172606361245952449277696409600000000000000
61! = 507580213877224798800856812176625227226004528988036003099405939480985600000000000000
62! = 31469973260387937525653122354950764088012280797258232192163168247821107200000000000000
63! = 1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000
64! = 126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000
65! = 8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000
66! = 544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000
67! = 36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000
68! = 2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000
69! = 171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000
70! = 11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000
71! = 850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000
72! = 61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000
73! = 4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000
74! = 330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000
75! = 24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000
76! = 1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000
77! = 145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000
78! = 11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000
79! = 894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000
80! = 71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000

Now if I can calculate 80 factorial on one of these chips I think you can calculate 903 * 100 if you do it right.

I am 100% certain that I ran out of freeRam.

While doing test I discovered each{ takes up freeRam until it finds the }. So in my extremely long brackets every now and then under certain circumstances it runs out of freeRam. I think I need to find a way to shorten the brackets. That's what I consider processing power.

Thomas499: I am starting to supect that my arduino Mega doesn't have the processing power I need. I have gone to great lengths to debug pieces of the issue. Will someone please load this simple code and tell me if their arduino Mega calculates it correctly?

I don't know why everyone has to be a smarta$$... but I will give you your answer, plain and simple.

An "int" is a 16 bit variable. If it's signed, it can range from +32767 to -32768.

If it's unsigned, it ranges from 0 to 65535.

Now, take your value 903 and multiply by 100. You get 90300. See? The result is too large for an int to hold. But, it tries anyway and overflows.

Now, watch what happens: Start by "pouring" your value into an int. The value starts at 0 and climbs up all the way to 65535, then ROLLS AROUND AGAIN TO ZERO.

So, 65536 of your 90300 has been "poured in" so far. How much is left?

90300 - 65536 = (drumroll.......) 24764!

So the int looped around back to zero and started going up again. It held the rest of your value and stopped at 24764.

Do you see that?

What you need, obviously, is a variable that has more than 16 bits. A "long int" has 32 bits and can count either from +2147483647 to -2147483648 (if it's signed) or from 0 to 4294967295 if it's unsigned.

It's way large enough to hold 90300 and indeed will work.

Hope this helps and hope it clarifies what the problem was.

Original code untouched on the Due (where an int is 32-bit):

dlloyd: Original code untouched on the Due (where an int is 32-bit):

What's the point? The OP said he was using a Mega, and an int on a Mega is 16 bits.