NXC: strange behaviour storing numbers to a file

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

NXC: strange behaviour storing numbers to a file

Post by HaWe »

I have a problem storing 512 value to a file:

1st question:
if I have 512 ints to store then my declarated file size for CreateFile() should be 512*2 plus a little more for eof() etc, or am I wrong?


2nd question:
my array length is 512
although my counter should count from 0...512 writing all array values to a file it keeps on counting up to several millions or so and doesn't stop when 512 has been reached -
what's wrong with my code?

Code: Select all


#define MaxRecLen 512

int  SoundRecord[MaxRecLen];             // detection: 0...MaxRecLen


//**************************************************************************
// File I/O
//**************************************************************************

string sFileName = "FILE001.dat";

void SoundSave() {

  unsigned int nFileSize = 16+(MaxRecLen*2); // nFileSize = number_of_integers*2 plus a little more
  byte fHandle, i;
  int IOresult, counter=0;
  int ibuf;
  
  ClearScreen();
  TextOut( 0,48, "SpeechRecogn "+version);
  PlayTones(Buzz);

  DeleteFile(sFileName);
  IOresult = CreateFile(sFileName, nFileSize, fHandle);
  if (IOresult == LDR_SUCCESS) {
    ClearScreen();
    for (i=0; i<512; i++)   {
        counter+=1;
        ibuf= SoundRecord[i];
        printf1( 0, 24, "counter =%5d", counter);
        printf1( 0, 16, "loudness=%5d", ibuf);

        WriteLn(fHandle, ibuf);
    }
    CloseFile(fHandle);
    PlayTones(ChordUp);
  }
  else
  PlayTones(sdError);
  
  while(!btnhit());
  ClearScreen();
}



// task main() {

// *SNIP*

// SoundSave();

// *SNIP*

}
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: NXC: strange behaviour storing numbers to a file

Post by spillerrec »

1) No, it shouldn't be needed as far as I know.

2) The problem is the for loop. The i variable is byte, so each time it reaches 255 it resets to 0 and therefore never becomes higher than 512 so that the loop can end.
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: strange behaviour storing numbers to a file

Post by HaWe »

1) how should the filesize be used correctly when creating a file?
2) oh no, sure, thx, I must have been blind :oops:
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: NXC: strange behaviour storing numbers to a file

Post by spillerrec »

It should just be 512*2. I haven't heard or experienced the need to make room for some extra bytes that are beyond your control. It should fail to write anything after the size limit is reached, so it shouldn't be too difficult to detect if all data is saved properly if you upload it to your computer.
Notice though that if you upload it to your computer and want to read the stored data, multi-byte types (like int and float) are stored in little-endian byte order.

You should be able to save the whole array in one operation, but I need to confirm is this is doable with the high-level API too first.
EDIT: Yeah, it does work, you should be able to just do something like:

Code: Select all

Write( fHandle, SoundRecord );
You use WriteLn() in your program, you should be aware that this function adds two bytes to the file after each write, a carriage return and a line feed, which is most likely not what you want.
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: strange behaviour storing numbers to a file

Post by HaWe »

You use WriteLn() in your program, you should be aware that this function adds two bytes to the file after each write, a carriage return and a line feed, which is most likely not what you want.
well, I want to process my data by Excel or a C program (Fourier Transformation) on my PC; actually the best way I've been thinking of had been to seperate the numbers by a ";" but I didn't know how to do this and I'm not quite sure if my "writeln processed data " will work with Excel - I'll have to see how to make the data Excel-compatible. There es an Excel export function in RoboLab (as Ive been told) but I couldn't find something in NXC so far.
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: NXC: strange behaviour storing numbers to a file

Post by spillerrec »

ARGH, accidently hit alt followed by X while writing closing my browser...

My Danish version of Excel 2010 supports tabulator separated files. Like this: (\t is a tab)

Code: Select all

203\t49
2165\492
924\t84
Which will create a 2x3 table. The newline characters I used was CRLF, I don't know which other are supported.
However you need to write the numbers in text format, so you need to convert each number. The problem here is that you might not know the final size of the file as it depends on how large the numbers are. One way to deal with it is to store the data into an array as you can just do

Code: Select all

ArrayBuild( array, array, newdata );
to add stuff and automatically make it larger as needed. Then you would just have to pass the array size as the filesize. The downside would be that the file can't be larger than your currently available ram.
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: strange behaviour storing numbers to a file

Post by HaWe »

So I assume I can also use my number-by-number-method?

with FormatNum to convert nums to string and then added "\t" or ";"
(depends on what my Excel and/or my ANSI C program need)?

And as my numbers max have 3 digits, it will probably 3+2 or 3+1 byte per number, so file size will be max 5*512 (CMIIW)?
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: strange behaviour storing numbers to a file

Post by HaWe »

got it working, thanks for your help!

Code: Select all

void SoundSave() {

  unsigned int nFileSize = (MaxRecLen*4); //3 byte for number (text) plus 1 (";") each
  byte fHandle;
  int IOresult, counter=0;
  int ibuf, i;
  string s;
  
  PlayTones(Buzz);

  DeleteFile(sFileName);
  IOresult = CreateFile(sFileName, nFileSize, fHandle);

  if (IOresult == LDR_SUCCESS) {
    ClearScreen();
    for (i=0; i<MaxRecLen; i++)   {
        counter+=1;
        ibuf= SoundRecord[i];

        printf1( 0, 24, "counter =%5d", counter);
        printf1( 0, 16, "loudness=%5d", ibuf);

        s=NumToStr(ibuf);
        s=s + ";" ;
        fputs(s, fHandle);
    }
    CloseFile(fHandle);
    PlayTones(ChordUp);
  }
  else
  PlayTones(sdError);

}
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests