Shop OBEX P1 Docs P2 Docs Learn Events
fwrite() values to uSD — Parallax Forums

fwrite() values to uSD

RsadeikaRsadeika Posts: 3,837
edited 2015-01-14 15:11 in Learn with BlocklyProp
Below is my test function for writing values to the uSD card. I finally got something to write to the file, but it is gibberish, I am not seeing my float number. The variable v3 has been declared as global float v3, but it seems like &v3 is not doing the deed. Anybody have a remedy for this?

Thanks

Ray

void mvolts()
{
  char inBuff[2];
/*              ADC port 3  load.          */
/* This now uses [V+ 10K_|_10K V-] resistor setup.   */
  v3 = adc_volts(3);
  v3 = (v3*2.00);
  
  writeStr(xbee,"mBattery ");
  writeFloat(xbee,v3);   // This now showing the correct voltage.
  writeStr(xbee," Volts\n");
  writeStr(xbee,"Log this?y/n");
  readStr(xbee, inBuff, 2);
  if(!strcmp(inBuff, "y"))
  {
    fp = fopen("Sol_dat.txt", "a+");
    fwrite(&v3,sizeof(float),1,fp);
    fclose(fp);
  }
  else
  {
    writeStr(xbee,"Done");
  }  
}
«1

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-09 12:22
    I'm able to write a float using fwrite. How are you checking the value that's being written? Does your file increase by 4 bytes after every call to fwrite?

    How large is your executable. With both floating point and file I/O it might be close to 32K, and you might be running out of memory. What memory model are you using? Can you reduce your code down to a small program that shows the problem, and post the code?
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-09 12:36
    The Board Type ACTIVITYBOARD-SDXMM, Memory Model XMMC External Flash ... The code size of the complete program is Code Size 81.400 bytes(82,320). You made mention of four bytes, I thought that the float value would be contained in one byte, or are you referring to something else. Anyway here is the complete program.

    Ray
    /*
      SAabsun.c
      Solar power unit monitor program.
      Jan 9, 2015
      Version 0.0.1
      Using ACTIVITYBOARD-SDMMC/XMMC External..., settings
      Version 0.0.2
      Added SD card access. Functionality to come in stages.
    */
    #include "simpletools.h"
    #include "simpletext.h"
    #include "fdserial.h"
    #include "adcDCpropab.h"
    
    FILE *fp;
    serial *xbee;
    
    float v3,v2,v1,v0,y3,y1,y4;
    /* SD card */
    int DO = 22, CLK = 23, DI = 24, CS = 25;
    
    void menu();
    void mvolts();
    void avolts();
    void bvolts();
    void solpan();
    
    /*
    void led26();
    */
    
    int main()
    {
      // Add startup code here.
    /* Start the new COGs. */
    //int *cog1 = cog_run(&led26, 10);
    //pause(100);
    /* Mount the SD file system. */
    sd_mount(DO, CLK, DI, CS);
    pause(100);
    fp = fopen("Sol_dat.txt", "a+");
    
      char inBuff[40];
    /* Initialise the ADC. */
      adc_init(21, 20, 19, 18);
    
    /*                     Rx  Tx  mode  BAUD   */  
      xbee = fdserial_open(11, 10,  0,   9600);
      pause(50);
     
      while(1)
      {
        // Add main loop code here.
        if(fdserial_rxReady(xbee))
        {
          readStr(xbee, inBuff, 40);
          if(!strcmp(inBuff, "help")) menu();
          else if(!strcmp(inBuff, "mbat")) mvolts();
          else if(!strcmp(inBuff, "abat")) avolts();
          else if(!strcmp(inBuff, "bbat")) bvolts();
          else if(!strcmp(inBuff, "solpan")) solpan();
          else
          {
            writeLine(xbee,"Unknown Command.");    
          }      
        }    
      }
      return 0;  
    }
    
    void menu()
    {
      writeStr(xbee,"Menu -  help, mbat, abat, bbat, solpan \n");
    }
    
    /*
    Check the voltage of the Parallax Power Pack that is 
    powering the Activity Board.
    */
    void mvolts()
    {
      char inBuff[2];
    /*              ADC port 3  load.          */
    /* This now uses [V+ 10K_|_10K V-] resistor setup.   */
      v3 = adc_volts(3);
      v3 = (v3*2.00);
      
      writeStr(xbee,"mBattery ");
      writeFloat(xbee,v3);   // This now showing the correct voltage.
      writeStr(xbee," Volts\n");
      writeStr(xbee,"Log this?y/n");
      readStr(xbee, inBuff, 2);
      if(!strcmp(inBuff, "y"))
      {
        fp = fopen("Sol_dat.txt", "a+");
        fwrite(&v3,sizeof(float),1,fp);
        fclose(fp);
      }
      else
      {
        writeStr(xbee,"Done");
      }  
    }
    
    /*
    Check the voltage of the primary battery for the solar system.
    */
    void avolts()
    {
    /*                   ADC port 2 load.           */
    /* This now uses [V+ 1K_1K_1K_|_1K V-] resistor setup.   */
    /* This will be worked in after the battery gets
       put on line with the PWM solar controller. */
    //  float y3,y1;
      int x;
      for(x=0;x<1000;x++)
      {
        y1 = adc_volts(2);
        y3 = y3 + y1;
      }
      y3 = (y3/1000);
      y3 = (y3*4.00);
      v2 = y3;
    
      writeStr(xbee,"aBattery ");
      writeFloat(xbee,v2);  // After manipulation, reads correct voltage.
      writeStr(xbee," Volts\n");  
    }
    
    /*
    Check the voltage of the secondary battery for the solar system.
    */
    void bvolts()
    {
    /*                   ADC port 1 load.            */
    /* This now uses [V+ 1K_1K_1K_|_1K V-] resistor setup.   */
    /* This will be worked in after the battery gets
       put on line with the PWM solar controller. */
    //  float y3,y1;
      int x;
      for(x=0;x<1000;x++)
      {
        y1 = adc_volts(1);
        y4 = y4 + y1;
      }
      y4 = (y4/1000);
      y4 = (y4*4.00);
      v1 = y4;
    
      writeStr(xbee,"bBattery ");
      writeFloat(xbee,v1);  // After manipulation, reads correct voltage.
      writeStr(xbee," Volts\n");
    }
    
    /*
    Check voltage levels of the solar panel.
    */
    void solpan()
    {
    /*                   ADC port 1 load.            */
    /* This now uses [V+ 1K_1K_1K_|_1K V-] resistor setup.   */
      v0 = adc_volts(1);
      v0 =(v0*4.00);   // Calculation based on manipulation
                       // to actual battery voltage reading.
      
      writeStr(xbee,"Solar Panel ");
      writeFloat(xbee,v0);  // After manipulation, reads correct voltage.
      writeStr(xbee," Volts\n");
    }
    
    
    
    /*
    Future COG functions when they are able to run in XMMC space.
    */
    /*
    void led26()
    {
      while(1)
      {
        high(26);
        pause(500);
        low(26);
        pause(500);  
      }
    }
    */
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-09 13:13
    I don't have an activity board, but I tried it on my C3 board, and my program works OK. I think one problem with your program is that you do an fopen of Sol_dat.txt at the beginning of main, and then you open the file again in your other routine. Comment out the fopen in main and that might fix the problem.

    Also, try commenting out the call to sd_mount. I don't think it's needed in XMMC mode when using the SD as external memory. The call to sd_mount may be conflicting with the SD cache driver.

    The size of float variables is 4 bytes, so sizeof(float) should have a value of 4.

    I don't see where you read the file Sol_dat.txt, so how do you know that the file is not being written correctly? You might try writing a program using fopen("Sol_dat.txt", "r"), and using fread(&x, 1, 4, fp) to read back a value.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-09 14:03
    I don't see where you read the file Sol_dat.txt, so how do you know that the file is not being written correctly?
    Yes, I do that manually, turn off AB, extract uSD card, insert to uSD holder, insert to USB port on PC, open the folder, repeat as required. My next step was going to be, create some code to read the file, and dir if possible. Actually, I was hoping that Andy and crew were working on some functions for dealing with the file system, things like dir, del, ..., etc.

    Thanks Dave I will try the other recommendations also.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-09 14:55
    @Dave, I tried the recommendations, and I was still getting gibberish. The big problem is that before I added the mount_sd(), the program was compiling too a >32K bytes, so I need to have access to XMM in order to work in the SD file system stuff. I guess I will have to look at this with fresh eyes tomorrow.

    Ray
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-09 17:06
    Ray,

    Can you try running the attached test program. You will need to change the board type to ACTIVITYBOARD-SDXMM before you build it. It should print out the following lines when you run it:
    2015.000000
    2016.000000
    2017.000000
    2018.000000
    
    Every time you run it the same four lines will be repeated an additional time.

    BTW, fwrite will write the binary values of the floating point numbers, and not the ASCII values. So if you are seeing gibberish it may be because you are trying to interpret it as ASCII instead of binary.

    Dave
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-09 17:48
    Are you perhaps expecting to be able to "type Sol_dat.txt" and see the floating point number in text? I am wondering that because you name the file with a ".txt" extension which is usually reserved for text files. Your fwrite function call will write the float to the file in binary and you will, in fact, get gibberish if you just try to type the contents of the file as text.

    Edit: Oops, I just noticed that Dave Hein already mentioned this possibility.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-10 03:23
    In regards to Project View, Andy says:
    This view is no longer actively supported by Parallax because it was designed to be used by a small and advanced group during Propeller GCC testing.
    If I remember correctly jazzed created SimpleIDE (Project View), to use all the features of PropGCC, now it is starting to look like Parallax is going with a watered down version of C for the Propeller. Which is fine for Parallax, and in the long run fine for me. Now I just have to ask myself, "Where does the Propeller really fit in if there is no more support for some of the more advanced features of C, as can be used with the Propeller?".

    I jokingly mentioned SimpleIDE RC5, well it looks like probably RC2 will be the last one before it goes to SimpleIDE 1.0. And I doubt that it will contain any of the features that I have been squawking about; I guess I could go the command line route with PropGCC. Make files, I get a headache just saying those two words, but what other choice is there?

    This latest program that I am developing will probably have to get makeover, meaning remove SimpleIDE and features, and start from the ground level of PropGCC. Hopefully some of the original developers, of PropGCC, will stick around to answer some queries as they arise, if not then there is always...

    Ray
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-10 04:37
    I don't think Parallax has dropped support for project view in SimpleIDE. They just don't use it in their tutorials because they are intended for beginners. However, if you do decide to use the command line tools, you may not find them as difficult as you think. We have some Makefile fragments that are used by most of the propgcc demo programs that make it a little easier to create Makefiles and you can use any text editor to edit the files. I use BBEdit on the Mac but there are lots of nice editors around that do syntax coloring and auto indent if that is what you want. Once you have a Makefile created, you only really ever have to type "make" to build your program and "make run" to run it if you're willing to use the terminal emulator that is built into propeller-load. Anyway, most of the propgcc developers are still here to help.

    As a second thought, you might consider trying PropWare:

    http://forums.parallax.com/showthread.php/157005-FYI-PropWare-Complete-build-system-and-library-for-PropGCC?highlight=propware

    This was written by SwimDude0614 and uses cmake which is supposed to be easier to use than make. I'm sure he'd be happy to help you get started. I haven't had time to try it myself but he's put a lot of work into it and the library has many drivers for common Propeller peripherals.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-10 05:04
    @David, My opinion only-
    I don't think Parallax has dropped support for project view in SimpleIDE. They just don't use it in their tutorials because they are intended for beginners.
    There have been more than one question asked about things pertaining to SimpleIDE Project View, either there has been no response from Parallax or the response was, to paraphrase, go read the manual. In my book, that means go support yourself. Sure, they will not remove Project View in this release, but all you will get, as an official response is, go read the manual.
    ...However, if you do decide to use the command line tools, ...
    Has anybody created a short tutorial for this? I went to the PropGCC site, and found a lot of fragmented information about usage. About PropWare, I am well aware of its existence, but it looks like there is a trend that is starting to develop here, people start developing a program for use, and then it goes dormant, and then the developer disappears.

    I know this is just a hobby, for me at least, but how many times can I start from scratch?

    Ray
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-10 05:14
    Rsadeika wrote: »
    @David, My opinion only-

    There have been more than one question asked about things pertaining to SimpleIDE Project View, either there has been no response from Parallax or the response was, to paraphrase, go read the manual. In my book, that means go support yourself. Sure, they will not remove Project View in this release, but all you will get, as an official response is, go read the manual.


    Has anybody created a short tutorial for this? I went to the PropGCC site, and found a lot of fragmented information about usage. About PropWare, I am well aware of its existence, but it looks like there is a trend that is starting to develop here, people start developing a program for use, and then it goes dormant, and then the developer disappears.

    I know this is just a hobby, for me at least, but how many times can I start from scratch?

    Ray
    I don't think the developer of PropWare has disappeared and I think he'd be happy to have another user of his library. You're right that there is a lack of good documentation for propgcc. When we started, I had hoped that Parallax tech writers would create some of their famous world-class documentation for propgcc but I don't think they have the bandwidth to do anything beyond the educational materials that are critical to Parallax's business. That means we have to rely on volunteers to document things like the command line tools. A little of this has been done in the wiki pages but I agree we need to do more. However, I think the forum support has been fairly good. Post your questions and we'll try to help the best we can.

    Edit: Also, make is not a Parallax tool and neither is gcc. There is lots of information on the web about how to use both. I know that's not a real substitute for good Propeller-based documentation but it is a start.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-10 06:10
    Ray, there are two buttons on the bottom tool bar that make the project view and build status visible. Unfortunately, these settings don't persist after you exit, and you need to click on them again to show the windows after startup. I think Parallax should document this better, and make the settings persist after exiting.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-10 06:25
    Dave Hein wrote: »
    Ray, there are two buttons on the bottom tool bar that make the project view and build status visible. Unfortunately, these settings don't persist after you exit, and you need to click on them again to show the windows after startup. I think Parallax should document this better, and make the settings persist after exiting.
    It probably wouldn't be too hard to add a check box to the options dialog (or whatever it is called) to cause those settings to persist. I'll have to check with Parallax to see if they would be okay with that.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-10 07:39
    Thanks Dave and David. I am not absolutely sure as to what the next step should be, for me. I do have Geany on my Windows desktop, I still somewhat remember how to create a batch file, so maybe for a temporary start I could go that way. The PropGCC editor could be Geany and the batch file could be used to compile the program. Hmm, I think I remember doing something like that before SimpleIDE, talk about taking a thousand steps backward.

    As to the little program that Dave provided, I tried it out and it worked as described. So I know that from a base start, at least that works. Now I will have to figure how to use the correct sequence of commands to compile and load a program to the Propeller, from the command line.

    Ray
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-10 10:45
    Ray, I don't understand why you would switch from SimpleIDE to the command line. I would think SimpleIDE would be a better development environment for you. What feature is missing from SimpleIDE that you would need?
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-11 03:23
    Ray, I don't understand why you would switch from SimpleIDE to the command line.
    The short answer? If I want to implement the use of COGs in XMMC, with this SimpleIDE release, it is not possible.

    Now back to resolving the problem with writing float values to the SD card. My full intent with the function will be to datalog the specific data, meaning the line of data in the xxx.txt file would look something like this: 'mbat 01102015 7.9567 V'. If I ever figure out a way of manipulating the values on the file, I have to make sure that I am doing something cogent up front.

    The code below is my recent attempt to put ascii string in the xxx.txt file. I am using sprint(), but it seems to only convert the right side of the decimal part of the float number. If I have something like v3 = 7.99675, after the use of sprint(), I only see .99675, no legible left side of decimal. I think I am getting close but not yet there.

    Ray

    void mvolts()
    {
      char inBuff[2];
      char outBuff[10];
    /*              ADC port 3  load.          */
    /* This now uses [V+ 10K_|_10K V-] resistor setup.   */
      v3 = adc_volts(3);
      v3 = (v3*2.00);
      
      writeStr(xbee,"mBattery ");
      writeFloat(xbee,v3);   // This now showing the correct voltage.
      writeStr(xbee," Volts\n");
      writeStr(xbee,"Log this?y/n");
      readStr(xbee, inBuff, 2);
      if(!strcmp(inBuff, "y"))
      {
        fp = fopen("Sol_dat.txt", "a+");
        sprintf(outBuff,"%f",v3);
        fwrite(outBuff,sizeof(float),1,fp);
        fread(outBuff,1,1,fp);
        fclose(fp);
        writeStr(xbee,outBuff);
      }
      else
      {
        writeStr(xbee,"Done");
      }  
    }
    
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-11 04:37
    You're closer here but there are still a few problems. Try this:
    void mvolts()
    {
      char inBuff[2];
      char outBuff[10];
    /*              ADC port 3  load.          */
    /* This now uses [V+ 10K_|_10K V-] resistor setup.   */
      v3 = adc_volts(3);
      v3 = (v3*2.00);
      
      writeStr(xbee,"mBattery ");
      writeFloat(xbee,v3);   // This now showing the correct voltage.
      writeStr(xbee," Volts\n");
      writeStr(xbee,"Log this?y/n");
      readStr(xbee, inBuff, 2);
      if(!strcmp(inBuff, "y"))
      {
        fp = fopen("Sol_dat.txt", "a+");
        sprintf(outBuff,"%f",v3);
        fwrite(outBuff,strlen(outBuff),1,fp);
    // why do you need to read the file? You already have the string in outBuff.
    // if you do want to re-read it from the file, you'll have to fseek to the start of the file and then use fscanf to read the floa
    //    fread(outBuff,1,1,fp); 
        fclose(fp);
        writeStr(xbee,outBuff);
      }
      else
      {
        writeStr(xbee,"Done");
      }  
    }
    
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-11 04:39
    Rsadeika wrote: »
    The short answer? If I want to implement the use of COGs in XMMC, with this SimpleIDE release, it is not possible.
    Eventually, Parallax will release the default branch with SimpleIDE but until that time you could just install it over the release_1_0 version that comes with SimpleIDE. Unfortunately, I have yet to post binary releases of the default branch. I guess I need to do that soon! In any case, SimpleIDE will work fine with the default branch as far as I know.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-11 05:37
    Tweaking it a little further, the sprintf and fwrite could be combined into fprintf. So you could do something like fprintf(fp, "mbat %02d%02d%d %f V\n", month, day, year, v3). This assumes you have the variables month, day and year that contain the current date.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-11 06:23
    Dave Hein wrote: »
    Tweaking it a little further, the sprintf and fwrite could be combined into fprintf. So you could do something like fprintf(fp, "mbat %02d%02d%d %f V\n", month, day, year, v3). This assumes you have the variables month, day and year that contain the current date.
    I was going to suggest that but then noticed that he was sending the same string to writeStr so I figured the sprintf was the best approach after all.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-11 06:42
    The use of writeStr, writeFloat, etc. is another thing I was wondering about. I assume these are functions provided by the simple library. My preference would be to use the stdio functions fprintf and fgets instead of the functions in the simple library. I suppose the simple library is intended to make C look more Spin-like, but I think it's better to teach beginning C programmers to use stdio. I find the use of print versus printf to be somewhat confusing. Oh well, I guess that ship has already sailed.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-11 06:59
    You guys are way ahead of me, below is my latest. I am seeing the mbat and the correct float number on the SD card. I added 'fwrite(";/n",1,3,fp);', hoping that a CR would be added to the end of the data and perform a CR. Right now I am getting the data on one line, what I would like to do is have the data placed in a columnar fashion with a semicolon designating the data end. I thought that by using 'a+', that would not only append the data to the file, but would also go to the next line. I was wrong.

    I have the code example that jazzed provided, last century I think :-), for a softRTC, so I will try to work that into the program for date and time stuff, but, how will the program deal with the COG that the softRTC program uses, in XMMC mode? I am assume that the COG that gets started is to have a running clock going? If this does not work, then I would need some other way of having a running clock.

    Then the next step will be for function that allows for opening the xxx.txt file and be able to see the contents of the file on the terminal screen. Not sure how that would work in the context of SimpleIDE simpletools structure.

    Ray
    void mvolts()
    {
      char inBuff[2];
      char outBuff[10];
    /*              ADC port 3  load.          */
    /* This now uses [V+ 10K_|_10K V-] resistor setup.   */
      v3 = adc_volts(3);
      v3 = (v3*2.00);
      
      writeStr(xbee,"mBattery ");
      writeFloat(xbee,v3);   // This now showing the correct voltage.
      writeStr(xbee," Volts\n");
      writeStr(xbee,"Log this?y/n");
      readStr(xbee, inBuff, 2);
      if(!strcmp(inBuff, "y"))
      {
        fp = fopen("Sol_dat.txt", "a+");
        fwrite("mbat ",1,5,fp);
        sprintf(outBuff,"%f",v3);
        fwrite(outBuff,strlen(outBuff),1,fp);
        fwrite(";/n",1,3,fp);
        //fread(outBuff,1,1,fp);
        fclose(fp);
        //writeStr(xbee,outBuff);
      }
      else
      {
        writeStr(xbee,"Done");
      }  
    }
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-11 08:38
    A newline in C is "\n", not "/n". "/n" will just give you the characters '/' and 'n'. You may also need to add a carriage-return if you want to view the file on Windows. So you would need to include "\r\n" at the end of your string for Windows. notepad requires the CR, but wordpad and some other Windows program do not require a CR for each line.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-11 10:39
    The function below is what I am using now, it works as expected, even the file, when opened with notepad looks the way I want. The next thing is to provide a running clock so I can add date and time to the data item. Not sure as to the best way to approach this?

    The program so far: Code Size 93,180 bytes (94,100 total). How large can I make the program before I start to see it run at snails pace?

    Ray

    void mvolts()
    {
      char inBuff[2];
      char outBuff[10];
    /*              ADC port 3  load.          */
    /* This now uses [V+ 10K_|_10K V-] resistor setup.   */
      v3 = adc_volts(3);
      v3 = (v3*2.00);
      
      writeStr(xbee,"mBattery ");
      writeFloat(xbee,v3);   // This now showing the correct voltage.
      writeStr(xbee," Volts\n");
      writeStr(xbee,"Log this?(y/n) \n");
      writeStr(xbee,"? ");
      readStr(xbee, inBuff, 2);
      if(!strcmp(inBuff, "y"))
      {
        fp = fopen("Sol_dat.txt", "a+");
        fprintf(fp,"mbat %f V;\r\n",v3);
        fclose(fp);
      }
      else
      {
        writeStr(xbee,"Done");
      }  
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-11 13:30
    The program below seems to working, but I am not sure why. I implemented the softRTC code, which uses '_rtc_start_timekeeping_cog();', so why is this working in XMMC? The only problem with this setup is once you turn off the Activity Board, you have to set the clock on start up of the program. I am not sure how I could automate this clock re-setting thing on a new start up, anybody have any good ideas? The program: Code Size 102,484 bytes (103,476 total).

    Ray


    /*
      SAabsun.c
      Solar power unit monitor program.
      Jan 9, 2015
      Version 0.0.1
      Using ACTIVITYBOARD-SDMMC/XMMC External..., settings
      Version 0.0.2
      Added SD card access. Functionality to come in stages.
      Version 0.0.3
      Added a running clock.
    */
    #include "simpletools.h"
    #include "simpletext.h"
    #include "fdserial.h"
    #include "adcDCpropab.h"
    #include <sys/rtc.h>
    
    #define BUFFERLEN 10
    
    FILE *fp;
    serial *xbee;
    
    float v3,v2,v1,v0,y3,y1,y4;
    /* SD card */
    int DO = 22, CLK = 23, DI = 24, CS = 25;
    
    void menu();
    void mvolts();
    void avolts();
    void bvolts();
    void solpan();
    
    /* Time keeping */
    char timebuff[16];
    char datebuff[16];
    void Set_Clock();
    int getdst();
    int prompttime(char *prompt);
    void Get_Time();
    void Get_Date();
    
    /*
    void led26();
    */
    
    int main()
    {
      // Add startup code here.
    /* Start the new COGs. */
    //int *cog1 = cog_run(&led26, 10);
    //pause(100);
    /* Mount the SD file system. */
    /* Start time keeping COG. */
    _rtc_start_timekeeping_cog();
    pause(100);
    
    sd_mount(DO, CLK, DI, CS);
    pause(100);
    
    
      char inBuff[40];
    /* Initialise the ADC. */
      adc_init(21, 20, 19, 18);
    
    /*                     Rx  Tx  mode  BAUD   */  
      xbee = fdserial_open(11, 10,  0,   9600);
      pause(50);
     
      while(1)
      {
        // Add main loop code here.
        if(fdserial_rxReady(xbee))
        {
          readStr(xbee, inBuff, 40);
          if(!strcmp(inBuff, "help")) menu();
          else if(!strcmp(inBuff, "mbat")) mvolts();
          else if(!strcmp(inBuff, "abat")) avolts();
          else if(!strcmp(inBuff, "bbat")) bvolts();
          else if(!strcmp(inBuff, "solpan")) solpan();
          else if(!strcmp(inBuff, "setclock")) Set_Clock();
          else if(!strcmp(inBuff, "time")) Get_Time();
          else if(!strcmp(inBuff, "date")) Get_Date();
          else
          {
            writeLine(xbee,"Unknown Command.");    
          }      
        }    
      }
      return 0;  
    }
    
    void menu()
    {
      writeStr(xbee,"Menu -  help, mbat, abat, bbat, solpan \n");
      writeStr(xbee,"        setclock, time, date, date, \n");
    }
    
    /*
    Check the voltage of the Parallax Power Pack that is 
    powering the Activity Board.
    */
    void mvolts()
    {
      char inBuff[2];
      char outBuff[10];
    /*              ADC port 3  load.          */
    /* This now uses [V+ 10K_|_10K V-] resistor setup.   */
      v3 = adc_volts(3);
      v3 = (v3*2.00);
      
      writeStr(xbee,"mBattery ");
      writeFloat(xbee,v3);   // This now showing the correct voltage.
      writeStr(xbee," Volts\n");
      writeStr(xbee,"Log this?(y/n) \n");
      writeStr(xbee,"? ");
      readStr(xbee, inBuff, 2);
      if(!strcmp(inBuff, "y"))
      {
        Get_Time();
        Get_Date();
        fp = fopen("Sol_dat.txt", "a+");
        fprintf(fp,"mbat %s %s %f V;\r\n",datebuff,timebuff,v3);
        fclose(fp);
      }
      else
      {
        writeStr(xbee,"Done");
      }  
    }
    
    /*
    Check the voltage of the primary battery for the solar system.
    */
    void avolts()
    {
    /*                   ADC port 2 load.           */
    /* This now uses [V+ 1K_1K_1K_|_1K V-] resistor setup.   */
    /* This will be worked in after the battery gets
       put on line with the PWM solar controller. */
    //  float y3,y1;
      int x;
      for(x=0;x<1000;x++)
      {
        y1 = adc_volts(2);
        y3 = y3 + y1;
      }
      y3 = (y3/1000);
      y3 = (y3*4.00);
      v2 = y3;
    
      writeStr(xbee,"aBattery ");
      writeFloat(xbee,v2);  // After manipulation, reads correct voltage.
      writeStr(xbee," Volts\n");  
    }
    
    /*
    Check the voltage of the secondary battery for the solar system.
    */
    void bvolts()
    {
    /*                   ADC port 1 load.            */
    /* This now uses [V+ 1K_1K_1K_|_1K V-] resistor setup.   */
    /* This will be worked in after the battery gets
       put on line with the PWM solar controller. */
    //  float y3,y1;
      int x;
      for(x=0;x<1000;x++)
      {
        y1 = adc_volts(1);
        y4 = y4 + y1;
      }
      y4 = (y4/1000);
      y4 = (y4*4.00);
      v1 = y4;
    
      writeStr(xbee,"bBattery ");
      writeFloat(xbee,v1);  // After manipulation, reads correct voltage.
      writeStr(xbee," Volts\n");
    }
    
    /*
    Check voltage levels of the solar panel.
    */
    void solpan()
    {
    /*                   ADC port 1 load.            */
    /* This now uses [V+ 1K_1K_1K_|_1K V-] resistor setup.   */
      v0 = adc_volts(1);
      v0 =(v0*4.00);   // Calculation based on manipulation
                       // to actual battery voltage reading.
      
      writeStr(xbee,"Solar Panel ");
      writeFloat(xbee,v0);  // After manipulation, reads correct voltage.
      writeStr(xbee," Volts\n");
    }
    
    
    
    /*
    Future COG functions when they are able to run in XMMC space.
    */
    /*
    void led26()
    {
      while(1)
      {
        high(26);
        pause(500);
        low(26);
        pause(500);  
      }
    }
    */
    
    /* Time keeping functions. */
    void Set_Clock()
    {
      struct timeval tv;
      struct tm t;
    
      t.tm_isdst = getdst();
      t.tm_year = prompttime("Year(xxxx) ")-1900;
      t.tm_mon = prompttime("Month(xx) ")-1;
      t.tm_mday = prompttime("Day of the month ");
      t.tm_hour = prompttime("Hour ");
      t.tm_min = prompttime("Minute ");
      t.tm_sec = prompttime("Second ");
    
      tv.tv_sec = mktime(&t);
      settimeofday(&tv, 0);
    }
    
    int getdst()
    {
      int rc = 0;
      char inBuff[2];
    
      //print("Use daylight savings time [y/n] ? ");
      writeStr(xbee,"Use daylight savings time (y/n)");
      //fflush(stdout);
      readStr(xbee, inBuff, 2);
      if(!strcmp(inBuff, "y"))
      {
        rc = 1;
      }
      else
      {
        rc = 0;
      }  
    
      //rc = (getchar() == 'y') ? 1 : 0;
      //getchar();
      return rc;
    }
    
    int prompttime(char *prompt)
    {
      int rc = 0;
      char *endp;
      char buffer[BUFFERLEN];
    
      do
      {
        writeStr(xbee,"Enter: ");
        writeStr(xbee,prompt);
        //fflush(stdout);
    
        //fgets(buffer, BUFFERLEN,stdin);
        readStr(xbee,buffer,10);
        //fflush(stdin);
    
        rc = strtol(buffer, &endp, 10);
    
        if(endp == buffer)
        {
          if('\n' == *endp)
          {
            rc = 0;
            break;
          }
          //print("Invalid entry \"%c....\" Please enter a number.\n", *endp);
            writeStr(xbee,"Invalid entry ... Please enter a number,\n");
        }
      } while(endp == buffer);
      return rc;
    }
    
    void Get_Time()
    {
    //  char timebuff[16];
      time_t now = 0;
    
      now = time(&now);
      strftime(timebuff,16,"%T",localtime(&now));
      //print("%s\n",timebuff);
      writeStr(xbee,timebuff);
      writeStr(xbee,"\n");
    }
    
    void Get_Date()
    {
    //  char timebuff[16];
      time_t now = 0;
    
      now = time(&now);
      strftime(datebuff,16,"%b %d, %Y",localtime(&now));
      //print("%s\n",timebuff);
      writeStr(xbee,datebuff);
      writeStr(xbee,"\n");
    }
    
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-11 13:33
    You can start other COGs that are running PASM drivers. You just can't launch another COG that is running XMMC C code.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-12 06:33
    This is my attempt at opening a file, reading it, and then displaying the contents. I have at least three lines of data on the SD card, but it only displays one line, but the bad part is it hangs the program after the line of data is displayed. I have 'fclose(fp)', so I am assuming that the file got closed and everything is good to go back to the interactive loop?

    Ray

    /* SD card */
    void sd_File()
    {
      int val = 500;
      
      fp = fopen("Sol_dat.txt", "r");
      fread(&val,4, 10, fp);
      writeStr(xbee,&val);
      fclose(fp);
    }
    
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-12 07:13
    I'm afraid you're mixing up binary data with text data. Your program writes the textual representation of floating point numbers using either sprintf or fprintf if you've followed some of the suggestions from this thread. This will write text to the file. To read those textual representations of floating point numbers you'll need to use sscanf or fscanf in a similar way to how you wrote the numbers in the first place with sprintf or fprintf. Your call to fread will only read the first four digits of the textual representation of the number and will pack them into a 32 bit int. This will produce a nonsense value.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-01-12 08:27
    The very first thing that I tried was 'fprintf(xbee, "%s",&val), but nothing showed on the screen, so that is when I went with 'writeStr(xbee,&val)', at least I got something, in fact the exact line that was on the SD. So, if I go with something like 'fprintf(xbee,"%f",&val)', will that work without hanging my program? I am assuming that val contains 500 bytes of info, and the fprintf() should push it out the xbee, or am I off track on this one?

    Ray
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-12 09:27
    You declare val as an int with an initial value of 500. An int variable is 32 bits in size, so it only has 4 bytes. You then do fread(&val, 4, 10, fp) which reads 40 bytes from Sol_dat.txt and places it in memory starting at the address of val. Since val is declared locally it resides on the stack. Therefore, you are placing the first 40 bytes of Sol_dat.txt onto the stack starting at the address of val, which is only 4 bytes in size. This will cause your program to failure since you are overwriting things on the stack, such as saved register values and the return address.

    If you want to dump out the contents of Sol_dat.txt you should declare a char buffer that's at least as large as the largest line in the file. Then use fgets to read the line. Your code would look something like this:
    void sd_File()
    {
      char buffer[80];
    
      fp = fopen("Sol_dat.txt", "r");
      while (fgets(buffer, 80, fp))
      {
        writeStr(xbee, buffer);
      }
      fclose(fp);
    }
    
Sign In or Register to comment.