View unanswered posts | View active topics It is currently Sun Jul 31, 2016 5:29 am






Reply to topic  [ 14 posts ] 
Creating a file with EV3 
Author Message
Rookie

Joined: Sat Dec 20, 2014 9:18 am
Posts: 6
Post Creating a file with EV3
Hi!

I've been trying to create a file with my EV3 brick to write there the observations with the corresponding numbers from the US sensor, so I could further visualize them and plot a graph on my PC. However, I couldn't find such functions for EV3 in Help section (only for NXT) and the source code from the wiki page also didn't work (assume because of wrong function names). Is it possible with RobotC?

Probably, I can achieve this creating enough variables for each reading but it will consume quite an amount of memory, right?

Thanks,
Victor.


Sat Dec 20, 2014 9:42 am
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Creating a file with EV3
Functions for file manipulation and datalogging were added in 4.28. Update and go check out the examples in the Sample folders :)

= Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Wed Dec 24, 2014 11:27 am
Profile WWW
Rookie

Joined: Sat Dec 20, 2014 9:18 am
Posts: 6
Post Re: Creating a file with EV3
Wow! Thank's a lot! I don't know if it is a coincidence, that I post a problem and after a while you came up with a new version woth a solution to this problem,
but in any case, that's great!

I have only one question remain: where are exactly the examples for file operations? I have searched in "Advanced examples" and "Datalogging" folders, but couldn't find anything, only for datalogging. I am especially interested in reading from file, because I have already dealed up with writing functions on my old NXT brick, so now I can plot a nice graph in Excel and analyze how robot sences the environment!

Thanks,
Victor.


Thu Dec 25, 2014 8:07 am
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Creating a file with EV3
I think the example I made did not get included with the installer. No worries though, I have it here. I basically made this to test the opcodes :)

= Xander

Code:
char * filename = "testFile";
char readBuffer[128];

void testLongs()
{
   writeDebugStreamLine("Testing Longs");

   long fileHandle;

   long writeValue = 0x11DD0000;
   long readValue;

   fileHandle = fileOpenWrite(filename);
   for (int i = 0; i < 10; i++)
   {
      fileWriteLong(fileHandle, writeValue++);
   }
   writeDebugStreamLine("fileHandle: %d", fileHandle);
   fileClose(fileHandle);

   fileHandle = fileOpenRead(filename);
   while (fileReadLong(fileHandle, &readValue))
   {
      writeDebugStreamLine("Read: 0x%X", readValue);
   }
   fileClose(fileHandle);
}

void testFloats()
{
   writeDebugStreamLine("Testing Floats");


   long fileHandle;

   float writeValue = 8.167;
   float readValue;

   fileHandle = fileOpenWrite(filename);
   for (int i = 0; i < 10; i++)
   {
      fileWriteFloat(fileHandle, writeValue);
      writeValue*=5;
   }
   writeDebugStreamLine("fileHandle: %d", fileHandle);
   fileClose(fileHandle);

   fileHandle = fileOpenRead(filename);
   while (fileReadFloat(fileHandle, &readValue))
   {
      writeDebugStreamLine("Read: %f", readValue);
   }
   fileClose(fileHandle);
}

void testShorts()
{
   writeDebugStreamLine("Testing Shorts");


   long fileHandle;

   short writeValue = 2;
   short readValue;

   fileHandle = fileOpenWrite(filename);
   for (int i = 0; i < 10; i++)
   {
      fileWriteShort(fileHandle, writeValue);
      writeValue*=2;
   }
   writeDebugStreamLine("fileHandle: %d", fileHandle);
   fileClose(fileHandle);

   fileHandle = fileOpenRead(filename);
   while (fileReadShort(fileHandle, &readValue))
   {
      writeDebugStreamLine("Read: %d", readValue);
   }
   fileClose(fileHandle);
}

void testChars()
{
   writeDebugStreamLine("Testing Chars");


   long fileHandle;

   char writeValue = 1;
   char readValue;

   fileHandle = fileOpenWrite(filename);
   for (int i = 0; i < 10; i++)
   {
      fileWriteChar(fileHandle, writeValue);
      writeValue+=5;
   }
   writeDebugStreamLine("fileHandle: %d", fileHandle);
   fileClose(fileHandle);

   fileHandle = fileOpenRead(filename);
   while (fileReadChar(fileHandle, &readValue))
   {
      writeDebugStreamLine("Read: %d", readValue);
   }
   fileClose(fileHandle);
}

void testData()
{
   writeDebugStreamLine("Testing Data");

   long fileHandle;

   char * string1 = "I like peanutbutter";
   int strlen1 = strlen(string1);

   char * string2 = "ROBOTC is cool";
   int strlen2 = strlen(string2);

   fileHandle = fileOpenWrite(filename);
   writeDebugStreamLine("fileHandle: %d", fileHandle);

   writeDebugStreamLine("strlen1: %d", strlen1);
   fileWriteData(fileHandle, string1, strlen1 + 1); // gets the 0 terminator as well
   fileWriteData(fileHandle, string2, strlen2 + 1); // gets the 0 terminator as well

   fileClose(fileHandle);

   fileHandle = fileOpenRead(filename);
   memset(readBuffer, 0, 128);
   fileReadData(fileHandle, readBuffer, strlen1 + 1);
   writeDebugStreamLine(readBuffer);
   fileReadData(fileHandle, readBuffer, strlen2 + 1);
   writeDebugStreamLine(readBuffer);

   fileClose(fileHandle);
}


task main()
{
   testLongs();
   testFloats();
   testShorts();
   testChars();
   testData();
}

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Thu Dec 25, 2014 8:23 am
Profile WWW
Rookie

Joined: Sat Dec 20, 2014 9:18 am
Posts: 6
Post Re: Creating a file with EV3
Thank you for your fast answer!

I have copied your code and at first it didn't work. It compiled at PC sucesfully, but my EV3 brick crashed (or something like that) so I have to reboot it. I have tried several times and then reduced the program to simply write a string to a file. It didn't work either, but it showed a message with some specific code and so I download firmware to a robot (file "librobotc.so") and it worked! I assume it also has changed, right? I didn't know that. Finally, I was able to read a message from EV3 on my PC. =)

I hope everything will go right now!


Thu Dec 25, 2014 9:34 am
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Creating a file with EV3
Victor,

Make sure you have updated the kernel image too. So first do this:
Attachment:
Screenshot at 15-28-00.png
Screenshot at 15-28-00.png [ 20.63 KiB | Viewed 4594 times ]


and then do this:
Attachment:
Screenshot at 15-28-14.png
Screenshot at 15-28-14.png [ 18.15 KiB | Viewed 4594 times ]


Then you will be running the latest version of both the Linux kernel and the ROBOTC firmware.

regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Thu Dec 25, 2014 10:29 am
Profile WWW
Rookie

Joined: Sat Dec 20, 2014 9:18 am
Posts: 6
Post Re: Creating a file with EV3
Thanks, now I know that!


Thu Dec 25, 2014 1:24 pm
Profile
Rookie

Joined: Wed Mar 26, 2014 12:39 pm
Posts: 7
Post Re: Creating a file with EV3
hey,
are there also the C standard file operations available for ROBOTC one would expect to have for C compilers?
fclose
feof
ferror
fflush
fgetc
fgetpos
fgets
fopen
fprintf
fputc
fputs
fread
freopen
fscanf
fseek
fsetpos
ftell
fwrite


Fri Dec 26, 2014 10:37 am
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Creating a file with EV3
No, only these are provided. There are currently no plans to provide a full list of standard stdio.h functionality.

Code:
// Open a file for reading (really a define that calls _OpenFile() with the right ev3FileFlags)
// File name can contain a path, but this will be ignored.  All ROBOTC data files like this
// reside under /home/root/lms2012/prjs/rc-data.  This cannot be changed and sub folders
// are not supported.
// Returns a file descriptor, which is used for writing and subsequently closing the file
#define fileOpenWrite(X) _OpenFile(X, fileFlagWriteOnly|fileFlagCreate|fileFlagTruncate)

// Open a file writing (really a define that calls _OpenFile() with the right ev3FileFlags)
// File name can contain a path, but this will be ignored.  All ROBOTC data files like this
// reside under /home/root/lms2012/prjs/rc-data.  This cannot be changed and sub folders
// are not supported.
// Returns a file descriptor, which is used for reading and subsequently closing the file
#define fileOpenRead(X)    _OpenFile(X, fileFlagReadOnly)

// this is an "internal" function and should not be used directly, returns a file descriptor
// The flags are one or more of the ones in ev3FileFlags, OR'd together.
intrinsic long _OpenFile(const char *pzFileName, ev3FileFlags nFlags);

// Close the file. Returns true if the close() went off without an issue, false if it didn't.
intrinsic bool fileClose(long nFileDescriptor);

// Write a signed long value to the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileWriteLong(long nFileDescriptor, long data);

// Read a signed long value from the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileReadLong(long nFileDescriptor, long *pData);

// Write a float value to the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileWriteFloat(long nFileDescriptor, float data);

// Read a float value from the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileReadFloat(long nFileDescriptor, float *pData);

// Write a signed 2 byte (short) value to the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileWriteShort(long nFileDescriptor, short data);

// Read a signed 2 byte (short) value from the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileReadShort(long nFileDescriptor, short *pData);

// Write an unsigned single byte value to the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileWriteChar(long nFileDescriptor, char data);

// Read an unsigned single byte value from the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileReadChar(long nFileDescriptor, char *pData);

// Write arbitrary data to the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic bool fileWriteData(long nFileDescriptor, char *pData, long nWriteLen);

// Read arbitrary data from the file descriptor
// Returns true if action did not cause an error, false if it did
intrinsic long fileReadData(long nFileDescriptor, char *pData, long nReadLen);

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Fri Dec 26, 2014 12:12 pm
Profile WWW
Rookie

Joined: Sat Dec 20, 2014 9:18 am
Posts: 6
Post Re: Creating a file with EV3
Today I was finally able to write a file on my EV3 in a .csv format. If you look at it using standart text editor, such as WordPad, it will look like:

Image

Although, it looks much better in Excel:

Image

Now I can clearly see that there is a period in my data (not that I had doubts about that, but still)! I even know now, how to evaluate an approximate value of the period in this time series, despite the fact that the graphics are not exactly same.

However, I still do not know, how to make EV3 to read a specific number on an intersection of rows and columns in this file, using the existing functions. Is it even possible in RobotC now?

Thanks,
Victor.


Fri Dec 26, 2014 1:42 pm
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Creating a file with EV3
Hi Victor,

I did not implement anything like that on the EV3. It looks like you're trying to do datalogging. However, there are functions on the brick that would allow you do just that. Take a look at the datalogging functions:
Code:
// Open a datalog file for writing to. Datalog files are named datalog-<datalogIndex>.txt
// The file has a comma separated values (CSV) format with the specified number of columns.
// If the append flag is set to false or omitted, an existing log file will be truncated and overwritten.
// Please note that if the old datalog file contains a different number of columns and the append
// flag is set to "true", the resulting CSV file may become useless.
// All ROBOTC data files like this reside under /home/root/lms2012/prjs/rc-data.
// This cannot be changed and sub folders are not supported.
// Returns true if action did not cause an error, false if it did
intrinsic bool datalogOpen(long nDatalogIndex, long nColumns, bool bAppend = false)
      asm(opcdEV3_ROBOTC, ev3Fcn_DatalogOpen, variable(nDatalogIndex), variable(nColumns), variable(bAppend), functionReturn);

// Flush the buffers and close the datalog file
// Returns true if action did not cause an error, false if it did
intrinsic bool datalogClose()
      asm(opcdEV3_ROBOTC, ev3Fcn_DatalogClose, functionReturn);

// Flush the buffers to the datalog file.  Useful if the program has a bug and
// crashes or exits before the datalogClose(); could be called.  Reduces the chance
// of partial writes to the log file.
// Returns true if action did not cause an error, false if it did
intrinsic bool datalogFlush()
      asm(opcdEV3_ROBOTC, ev3Fcn_DatalogFlush, functionReturn);

// Add a signed, unsingle byte value to the datalog on the specified column.
// Columns are numbered from 0
// Returns true if action did not cause an error, false if it did
intrinsic bool datalogAddChar(long nIndex, char data)
      asm(opcdEV3_ROBOTC, ev3Fcn_DatalogAddChar, variable(nIndex), variable(data), functionReturn);

// Add a signed,2-byte (short) value to the datalog on the specified column.
// Columns are numbered from 0
// Returns true if action did not cause an error, false if it did
intrinsic bool datalogAddShort(long nIndex, short data)
      asm(opcdEV3_ROBOTC, ev3Fcn_DatalogAddShort, variable(nIndex), variable(data), functionReturn);

// Add a signed, 4-byte (long) value to the datalog on the specified column.
// Columns are numbered from 0
// Returns true if action did not cause an error, false if it did
intrinsic bool datalogAddLong(long nIndex, long data)
      asm(opcdEV3_ROBOTC, ev3Fcn_DatalogAddLong, variable(nIndex), variable(data), functionReturn);

// Add a float value to the datalog on the specified column.
// Columns are numbered from 0
// Returns true if action did not cause an error, false if it did
intrinsic bool datalogAddFloat(long nIndex, float data)
      asm(opcdEV3_ROBOTC, ev3Fcn_DatalogAddFloat, variable(nIndex), variable(data), functionReturn);

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Sat Dec 27, 2014 2:46 am
Profile WWW
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Creating a file with EV3
And here's an example:
Code:

task main()
{
   // The first argument is a datalog index number.
   // The filename will be saved in the rc-data folder as
   // datalog-<INDEX>.txt
   // The format is a comma separated value file.
   // The 2nd argument is the number of columns you wish to have in the file
   // The 3rd argument specifies if you wish to append to the datalog, if it
   // exists.
   if (!datalogOpen(0, 4, false))
      writeDebugStreamLine("Unable to open datalog");

   // You can add an entry at the specified column number
   for (int i = 0;i < 2; i++)
   {
      datalogAddChar(0, 1 + i);
      datalogAddShort(1, 9000 + i);
      datalogAddLong(2, 2388738 + i);
      datalogAddFloat(3, 678.98 / i);
   }

   // Make sure you close the file properly
   datalogClose();
}

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Sat Dec 27, 2014 2:48 am
Profile WWW
Rookie

Joined: Sat Dec 20, 2014 9:18 am
Posts: 6
Post Re: Creating a file with EV3
Yes, it is quite similar. At the beginning I want to use Datalogging instead of File Read/Write operations, but then I thought that the file will look better with headings for each column. Although it is practically the same.

Does Datalogging provide a "read" operation that I need? I can't see it from the example or from functions list.

By the way, are there some Low Level Commands for this? I mean, I can add a specific character before each value, that corresponds to a specific column and then read from the very beginning of the file to this certain position and ask to return some bytes after it. Will this work?


Sat Dec 27, 2014 9:32 am
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Creating a file with EV3
Hi Victor,

No, there are no specific datalogging read functions. Other than the functions provided, there are no "low level" functions to prepend data with a specific character. I am not sure why you would need to do this, it's a comma separated file, so you just need to count the commas. There is a strtok()-like function that I made for my driver suite, which you can download here: https://github.com/botbench/robotcdrive ... e/common.h

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Sun Dec 28, 2014 5:28 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 14 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.