[Solved] Mega says 903 times 100 is 24764.

What's the point?

To convert every AVR user to the SAM architecture. Just $50 or so any you can save editing your code with the word "long". EDIT: (sometimes).

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

OK now I'm confused. I just compiled it here (Arduino MEGA R3, IDE 1.0.6...

[b]Float is 903.00 
float * 100 is 32767 

Wait.... I thought it was 
--------------------- 
90300.00 

Am I crazy? [/b]

Where on earth did 32767 come from? ? ? ?

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

While doing test I discovered each{ takes up freeRam until it finds the }.

Well, no it doesn't. Brackets do not take up RAM at all. Nor does the amount of code between them (necessarily). That depends of course on what the code does.

This does:

Serial.print("Problem Reading ");

Change that to:

Serial.print(F("Problem Reading "));

Then it uses less RAM.

I got 24764 on my Mega. (IDE 1.0.5).

Thomas499: 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.

I am 100% certain that you have almost no idea what you are doing.

[quote author=Nick Gammon date=1422847519 link=msg=2071473] I got 24764 on my Mega. (IDE 1.0.5). [/quote]

Well that's interesting. I use IDE v1.0.6 along with the lastest AVR-GCC.

I completely deleted my /hardware/tools directory and compiled my own:

[b]root@michael:/# avr-gcc -v
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/avr/4.9.2/lto-wrapper
Target: avr
Configured with: ../configure --target=avr --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2
Thread model: single
gcc version 4.9.2 (GCC)[/b]

...but that shouldn't make any difference.

(actually I compiled all my own AVR-LIBC, AVR-BINUTILS, AVR-GCC, AVR-GDB and AVRDUDE directly from source).

I can't imagine that there is a difference between 1.05 and 1.06 that would cause this. Any ideas?

Thomas499: 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.

Once you use proper programming techniques, you'll be amazed by how far you can push the processing limits of a Atmega328.

You are opening a file from the SD card in every single loop from your program. That is like several thousand times every second. No wonder you "met the limit of the processing power". Not even a Core-i7 can resist bad coding.

You are opening a file from the SD card in every single loop from your program. That is like several thousand times every second. No wonder you "met the limit of the processing power". Not even a Core-i7 can resist bad coding.

I am trying to understand the difference in doing it only once, and per each loop. To my understanding, once it closes the brackets, that's it. It doesn't hold any processing data from the loop it closed. So if it could do it once ok, then why would it matter if it does it every loop? What am I not understanding?

I am 100% certain that you have almost no idea what you are doing.

I'm learning. Might be through trial and error, but I am learning. Once I figure it out I won't ever make the same mistake again.

Thomas499: I am trying to understand the difference in doing it only once, and per each loop. To my understanding, once it closes the brackets, that's it. It doesn't hold any processing data from the loop it closed. So if it could do it once ok, then why would it matter if it does it every loop? What am I not understanding?

You're missing the time and processing power it takes to open a file and set all that up. You don't tear your house down every morning when you leave for work and then rebuild it when you get home? If you held that object as static or global then you'd only have to pay that tax once.

You can't think about memory usage in terms of opening and closing brackets. I think you've misunderstood something there.

Thomas499:
I am trying to understand the difference in doing it only once, and per each loop. To my understanding, once it closes the brackets, that’s it. It doesn’t hold any processing data from the loop it closed. So if it could do it once ok, then why would it matter if it does it every loop? What am I not understanding?
I’m learning. Might be through trial and error, but I am learning. Once I figure it out I won’t ever make the same mistake again.

You’re missing the point. “Closing the brackets” is not the issue. The issue is the opening, reading, writing and closing of the SD card over and over again.

Each time you open a file, a lot of things have to happen (such as allocating buffers, reading the directory, finding a match between the filename you are opening and the filenames on the SD card, etc…) then when you read or write, the data has to be located by reading the directory, getting the pointers to the address of the data, than copying that data to buffers, etc…), then to close the file, the code has to wait for all transfers to finish, then write out any changes to the directory and/or file allocation tables, then wait for those transactions to complete, then deallocate buffers, clean up the stack and finally exit.

So you see the simple words “open” and “read” and “close” involve a LOT of code and processor activity. When you do them over and over again in a loop, of course it’s going to be slow.

An analogy would be… imagine you have to create a presentation to give at the office. Would you generate one page, then send it to the printer, then walk across the office to get the sheet, then go back to your desk and print that sheet again (for the next person in the meeting), then walk over to the printer again and grab the sheet, then do this - say - 10 times if there are 10 people at the meeting, then generate the second page, then make another 10 trips to the printer and back, etc…?

You see what’s going on here?

You don’t tear your house down every morning when you leave for work and then rebuild it when you get home?

That’s my problem then. The way I have it set up, it doesn’t open and close each file per loop, but when the time comes it does open and close a lot of files. So would I need to put in a delay? The way I have it written right now because I haven’t figured out how to read strings yet (from sd cards). Well I take that back, I do remember I did an experiment where it would pull the strings from the sd card and print them correctly, but then I couldn’t add numbers to the outcome. For example, if the number of interest in the string was 9, I could get it to say 9, but I couldn’t say take 9 and add one to it. The way I had it working, that wouldn’t work.

The way I have it now it opens one file and read a number, then close that file and open another file and read a number. Then it puts those number in a string. Doing this, I can add one to it, but obviously I ran into some side effects.

I think that’s my problem. The opening and closing doesn’t end with the brackets. So either I need to incorporate a delay, or need to figure out how to read strings from an sd card where I can take the numbers and add to them.

The thing about reading numbers from an SD card or Serial or something is that they are coming in as ASCII codes. So a 0 is realy 48 and 1 is 49 and 2 is 50. Looking at an ASCII code and getting the real number that goes with it is trivial. The simple thing to do is to subtract '0' from each digit. There are also functions like atoi and strtol that take longer ASCII strings and pull the numbers out.

But this isn't python. You can't read a number in as a string and then expect to be able to just turn around and use it as an int.

And can you expand on this idea with a delay? I'm not following your logic there. I don't see how a delay would help at all. That would just tie the processor up that much longer.

But this isn’t python. You can’t read a number in as a string and then expect to be able to just turn around and use it as an int.

If I wanted to do that, could I get a rasberry pi, and somehow hook it to the arduino? I know a raspberry pi can run python, I am unsure if I can get the pi to do that, and then send it to the arduino though…

And can you expand on this idea with a delay? I’m not following your logic there. I don’t see how a delay would help at all. That would just tie the processor up that much longer.

Well I know if you send to much to the serial printer it will skip. If you add a delay at that point, it will print what it would have otherwise skipped. I was thinking similar logic would work with the sd card. Apparently, my logic was flawed there.

Well, I could use a blink without delay function that activates when the sd card closes a file, and make it so another sd file won’t open until that time has passed. But I am just brainstorming here. Any suggestions or ideas are welcome.

Thomas499: If I wanted to do that, could I get a rasberry pi, and somehow hook it to the arduino? I know a raspberry pi can run python, I am unsure if I can get the pi to do that, and then send it to the arduino though...

Well, that would be silly when you can just do it all with the Arduino. My point wasn't that you need python. Quite the opposite. My point was that you need to quit thinking like python.

Here is how I have been reading comma delimited text files

if (myChar == '\n') {
        if (foundit) {
           int     commaPosition;  // the position of the next comma in the string
          commaPosition = currentLine.indexOf(',');
          currentLine =currentLine.substring(commaPosition+1, currentLine.length());
          commaPosition = currentLine.indexOf(',');
          myName =currentLine.substring(0,commaPosition);
          currentLine =currentLine.substring(commaPosition+1, currentLine.length());
          commaPosition = currentLine.indexOf(',');
          myCredit =currentLine.substring(0,commaPosition);
          currentLine =currentLine.substring(commaPosition+1, currentLine.length());
          commaPosition = currentLine.indexOf(',');
        
          //Serial.println(myName);
          myNewCredit = 0;
          myNewCredit = StrToFloat(myCredit);
          //Serial.println(myNewCredit);
          foundit = 0;
          
          }
          currentLine = "";

        }

Thank you jasit. I was about to tears trying to figure this out. Below shows what I was trying. I want to read a sd file, and take the numbers and put them in a format that I can add to. The string in the sd file is 90,low,15.6,125*

#include <SD.h>

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

float Addone = 0.0;

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



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.print("Number Files Found ");
          Serial.println(NumberFile.read());
          Serial.print("Contents are ");
          
        
          
        
          char c = (NumberFile.available() - '0');  //convert to ASCII format
          Serial.println(c);
        
        
        
        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="";
      Addone = angle;
    }  
    else {     
      readString += c; //makes the string readString
    }
  ind1 = readString.indexOf(',');  //finds location of first ,
  angle = readString.substring(0, ind1);   //captures first data String

          NumberFile.close();
        } else { Serial.print("Problem Reading ");
                 Serial.println(sdNumberFile);
               }
               Serial.print("before adding 1 angle was" );
               Serial.println(Addone);
               Serial.print("after adding one angle is ");
               Addone++;
               Serial.println(Addone);
         
}

With your code this is what i’ve done But i’m still struggling.

#include <SD.h>

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

float Addone = 0.0;

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



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.print("Number Files Found ");
          Serial.println(NumberFile.read());
          Serial.print("Contents are ");
          
          
          
        
          char currentLine = (NumberFile.available() - '0');  //convert to ASCII format
          Serial.println(currentLine);
        
        if (readString == '\n') {
        if (NumberFile) {
           int     commaPosition;  // the position of the next comma in the string
          commaPosition = readString.indexOf(',');
          currentLine =currentLine.substring(commaPosition+1, currentLine.length());
          commaPosition = currentLine.indexOf(',');
          myName =currentLine.substring(0,commaPosition);
          currentLine =currentLine.substring(commaPosition+1, currentLine.length());
          commaPosition = currentLine.indexOf(',');
          myCredit =currentLine.substring(0,commaPosition);
          currentLine =currentLine.substring(commaPosition+1, currentLine.length());
          commaPosition = currentLine.indexOf(',');
        
          //Serial.println(myName);
          myNewCredit = 0;
          myNewCredit = StrToFloat(myCredit);
          //Serial.println(myNewCredit);
          foundit = 0;
          
          }
          currentLine = "";

        } 

        
  ind1 = readString.indexOf(',');  //finds location of first ,
  angle = readString.substring(0, ind1);   //captures first data String

          NumberFile.close();
        } else { Serial.print("Problem Reading ");
                 Serial.println(sdNumberFile);
               }
               Serial.print("before adding 1 angle was" );
               Serial.println(Addone);
               Serial.print("after adding one angle is ");
               Addone++;
               Serial.println(Addone);
         
}

Can anyone help me?

That would be so much smaller and simpler using strtok()....

Regards, Ray L.

Your reading is far too complex. This code reads one line from your file and displays its contents:

#include <SdFat.h>

// SD chip select pin
const uint8_t chipSelect = SS;

// file system object
SdFat sd;

float angle;
char fuel [10];
float speed;
float altitude;

// Format: 90,low,15.6,125

bool processLine (char * buffer)
  {
  char * token;
  token = strtok (buffer, ",");
  if (!token)
    return false;  // failure
  angle = atof (token);
  
  token = strtok (NULL, ",");
  if (!token)
    return false;  // failure
  strncpy (fuel, token, sizeof (fuel) - 1);
  
  token = strtok (NULL, ",");
  if (!token)
    return false;  // failure
  speed = atof (token);
    
  token = strtok (NULL, ",");
  if (!token)
    return false;  // failure
  altitude = atof (token);
  
  return true; // success
  }

bool readFile () {
  int lineNumber = 0;
  const int maxLine = 80;
  char buffer[maxLine];
  
  ifstream sdin("N.txt");
  
  // check for open error
  if (!sdin.is_open()) 
    {
    Serial.println (F("Could not open file."));
    return false;
    }

  while (sdin.getline (buffer, maxLine))
    {
    lineNumber++;
    int count = sdin.gcount();
    if (sdin.fail()) 
      {
      Serial.print (F("Line "));
      Serial.println (lineNumber);
      Serial.print (F(" too long."));
      return false;
      }  // end of fail (line too long?)
      
    // ignore empty lines
    if (count > 1)
      {
      bool result = processLine (buffer);
      if (!result)
        {
        Serial.print (F("Failed to parse line: "));
        Serial.println (buffer);
        return false;  
        }
      return true;  // success!
      }  // end of non-blank line
    }    // end of while each line

  return false;  // failure
}  // end of readFile

//------------------------------------------------------------------------------
void setup(void) {
  Serial.begin(115200);

  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) 
    sd.initErrorHalt();

  // read the file
  if (readFile())
    {
    Serial.print (F("Angle = "));
    Serial.println (angle);
    Serial.print (F("Fuel = "));
    Serial.println (fuel);
    Serial.print (F("Speed = "));
    Serial.println (speed);
    Serial.print (F("Altitude = "));
    Serial.println (altitude);
     
    }
}
//------------------------------------------------------------------------------
void loop(void) {}

I don’t know why you are storing the results as String type. You want numbers, don’t you?

My output:

Angle = 90.00
Fuel = low
Speed = 15.60
Altitude = 125.00

That was on my Uno (Atmega328P) which has plenty of power to read a file and process the numbers in it.

I used the SDfat library:

Delta_G: The thing about reading numbers from an SD card or Serial or something is that they are coming in as ASCII codes. So a 0 is realy 48 and 1 is 49 and 2 is 50. Looking at an ASCII code and getting the real number that goes with it is trivial. The simple thing to do is to subtract '0' from each digit. There are also functions like atoi and strtol that take longer ASCII strings and pull the numbers out.

But this isn't python. You can't read a number in as a string and then expect to be able to just turn around and use it as an int.

Why not?

int = atoi (string);