Shop OBEX P1 Docs P2 Docs Learn Events
uSD I/O — Parallax Forums

uSD I/O

RsadeikaRsadeika Posts: 3,837
edited 2013-05-19 04:56 in Propeller 1
I am working with SimpleIDE 0-9-28 on my Windows 7 PC, and below is a simple program example that is found in the Propeller C Tutorials(online). This is a very straight forward program that captures a keypress and then writes to the uSD card. The data that is captured is in byte form, that is handled by a '%d' or '%s' to be presentable on the screen, while on the uSD card it appears as gibberish symbols that is byte code. This is all well and good.

Since I am working on a program that will be obtaining data from a Sensirion SHT11 module, I am wondering how I can manipulate the input data so it would be in a readable form when opened by notepad, or any other such program, when stored on the uSD card. Specifically the form would be a database, so I can present it in graph style or anything else. Another problem arises is when the data is now in a non-byte form, then using an fread command runs into some problems. Any easy solutions for this?

Thanks
Ray
/*
 SDio.c
   
*/

#include "simpletools.h"                      

/* Activity Board */
int DO = 22, CLK = 23, DI = 24, CS = 25;
FILE* fp;


int main()                                    
{
  // Add startup code here.
  pause(300);
  printf("uSD I/O test program.\n");

  sd_mount(DO, CLK, DI, CS);
  fp = fopen("test.txt", "a");

  int n,status,m;

  while(1)                                   
  {
    // Add main loop code here.
    printf("> ");
    status = scanf("%s", &n);
    if(!status) break;
    fwrite(&n, 4, 1, fp);
  }
  fclose(fp);
/* Display contents of file. */
  printf("\nYou entered:\n");
  fp = fopen("test.txt", "r");
  while(1)
  {
    status = fread(&m,4, 1, fp);
    if(!status) break;
    printf("n = %d\n", m);
  }
  fclose(fp);  
}
«1

Comments

  • RaymanRayman Posts: 14,665
    edited 2013-05-13 07:20
    Since you're on this subject...

    I'm trying to decide between fixing FSRW to work in xmm-split mode or using the stardard I/O...

    But, I can't find a simple example of using standard I/O to just read a file...
    Is there one?

    Maybe I'll try this example with your changes.
    Can I just use stdio.h instead of simpletools.h?
  • RaymanRayman Posts: 14,665
    edited 2013-05-13 07:25
    If sd access is already included in PropGCC, maybe I should just use that instead...

    Do I need the simpletools.h to make it work like in this example?
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-13 07:32
    I am using simpletools.h because it is what you get when you start out in Simple View. Also, simpletools.h contain(s) stdio.h and other necessary header calls.
    Lastly, the call to scanf uses a %s format but supplies an integer argument. I imagine you really mean to use %d?
    The actual example uses %d, and all that it allows are numbers on the keyboard; I wanted to also capture letters, hence %s. I guess I am breaking SOP with this.

    Ray
  • tdlivingstdlivings Posts: 437
    edited 2013-05-13 08:54
    David Betz wrote: »
    This is a rather odd sample. For one thing, if you select the correct board configuration file there is no need to call sd_mount. Also, the return value of fopen is never checked which isn't good programming practice. Also, this isn't really valid ANSI C code because I don't believe ANSI C allows declarations in the middle of code. They have to be at the start of a block. Lastly, the call to scanf uses a %s format but supplies an integer argument. I imagine you really mean to use %d?

    I noticed the C++ style of variable declaration and wondered it C had added that style since I last used C back in the Turbo C days.
    The examples on Parallax site use it and I like it.
    I do not think it needs to be pure ANSI C to be a good teaching tool for C and C++ programming and for sure for programming propeller code.

    I guess it could also be a bug and we are using the C++ part to the compiler as a default and that was not what was selected in the IDE.

    Tom
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-13 10:12
    Below is the actual program that I used as a reference, which is in the /SimpleIDE/Learn/Examples/Devices/Memory on your HD, and can be found on the Learn website. Since I already picked up some C programming bad habits, maybe the experts should correct the program below, where it needs to be corrected. A good example can go a long way.

    Ray
    /*
      SD Datalogger.side
    
      Application prompts you to type numbers into SimpleIDE Terminal, and
      records to SD.  Plays back all numbers after you type q and press Enter.
      
      http://learn.parallax.com/propeller-c-simple-devices/sd-card-data
    */
    
    #include "simpletools.h"                      // Include simpletools header    .
    
    int DO = 22, CLK = 23, DI = 24, CS = 25;      // SD card pins on Propeller BOE
    
    int main(void)                                // Main function
    {
      pause(1000);                                // Delay for terminal
      printf("Enter several values.\n");          // User instructions
      printf("To exit, type q then Enter\n");
    
      sd_mount(DO, CLK, DI, CS);                  // Mount SD card
    
      FILE* fp = fopen("test.txt", "w");          // Open a file for writing
    
      int n, status;                              // Number & status variables
      while(1)                                    // Endless loop
      {
        printf("> ");                             // User prompt
        status = scanf("%d", &n);                 // Get number & status
        if(!status) break;                        // Status 0? Break out of loop
        fwrite(&n, 4, 1, fp);                     // Write number to SD card
      } 
      fclose(fp);                                 // Close the file
      
      printf("\nYou entered:\n");                 // List heading
    
      fp = fopen("test.txt", "r");                // Open a file for writing
      while(1)
      {
        status = fread(&n, 4, 1, fp);             // Read from SD & get status
        if(!status) break;                        // If no more, break loop
        printf("n = %d\n", n);                    // Display value
      } 
      fclose(fp);                                 // Close the file
    }    
    
  • dgatelydgately Posts: 1,630
    edited 2013-05-13 10:25
    Rsadeika wrote: »
    Below is the actual program that I used as a reference, which is in the /SimpleIDE/Learn/Examples/Devices/Memory on your HD, and can be found on the Learn website. Since I already picked up some C programming bad habits, maybe the experts should correct the program below, where it needs to be corrected. A good example can go a long way.

    Ray
    /*
      SD Datalogger.side
    
      Application prompts you to type numbers into SimpleIDE Terminal, and
      records to SD.  Plays back all numbers after you type q and press Enter.
      
      http://learn.parallax.com/propeller-c-simple-devices/sd-card-data
    */
    
    #include "simpletools.h"                      // Include simpletools header    .
    
    int DO = 22, CLK = 23, DI = 24, CS = 25;      // SD card pins on Propeller BOE
    
    int main(void)                                // Main function
    {
      pause(1000);                                // Delay for terminal
      printf("Enter several values.\n");          // User instructions
      printf("To exit, type q then Enter\n");
    
      sd_mount(DO, CLK, DI, CS);                  // Mount SD card
    
      FILE* fp = fopen("test.txt", "w");          // Open a file for writing
    
      int n, status;                              // Number & status variables
      while(1)                                    // Endless loop
      {
        printf("> ");                             // User prompt
        status = scanf("%d", &n);                 // Get number & status
        if(!status) break;                        // Status 0? Break out of loop
        fwrite(&n, 4, 1, fp);                     // Write number to SD card
      } 
      fclose(fp);                                 // Close the file
      
      printf("\nYou entered:\n");                 // List heading
    
      fp = fopen("test.txt", "r");                // Open a file for writing
      while(1)
      {
        status = fread(&n, 4, 1, fp);             // Read from SD & get status
        if(!status) break;                        // If no more, break loop
        printf("n = %d\n", n);                    // Display value
      } 
      fclose(fp);                                 // Close the file
    }    
    

    I think you are able to include inline declarations in this code because the "Other Compiler Options" has been set to "-std=c99". I think I remember removing that option and having to move all my declarations to the top of functions or as globals... Just a guess as I'm not positive that was the issue.

    dgately
  • dgatelydgately Posts: 1,630
    edited 2013-05-13 10:28
    Geez Dave, you are quick! :smile: not that it is a bad thing!


    dgately
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-13 10:48
    I just checked my "Other Compiler Options", and it has been set to "-std=c99". As I mentioned, I am using the SimpleIDE 0-9-28 Simple View, which is going to be what Parallax will be using in there Learn C program. Since David mentioned C versions, if I keep using the Learn C examples, what version of C will I be learning, and does that make any difference in the long run?

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2013-05-13 11:03
    dgately wrote: »
    I think you are able to include inline declarations in this code because the "Other Compiler Options" has been set to "-std=c99". ....

    Yes. Parallax requested that -std=c99 be included on any Simple Projects. If folks don't understand what is trying to be achieved with Simple View and SImple Libraries, they should spend time with the Parallax Propeller C Web Site and Educational Tutorials.

    Also, it would be nice to know if things are missing from the User Guide. For example, some of the Simple View -vs- Project View behaviors are not documented. The Propeller-Load document describes using config files and _cfg_ variable patching; it was not included in the User Guide and is available as a separate document. The User Guide content is owned by Parallax. All SimpleIDE Simple View decisions are owned by Parallax.

    Simple View is the Parallax version of Project View. You can choose between one view and another with the Menu Tools -> Set Simple/Project View. Simple View is designed for Educational customers. Project View operates the way 0-8-5 did except for some enhancements I thought were useful that were introduced in Simple View such as the New Project methodology (Project View New Project gives a small template for the main file where as Simple View New Project uses the educational templates); the Add Library, Add Tab, and Open Tab tools; the Create Project Library.

    As far as C versions, it depends on the requirements and coding standard if any of an organization. Some people are pedantic, uptight, and argumentative; others don't care (people you won't mind working with). If you want a job writing C programs, it's good to know what are the basic extensions to C89 that C99 brings so that you can deal with the pedantic C89 types.
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-13 11:24
    Not trying to turn my own thread into a pedantic C thread, I just checked with Wikipedia, and they make a statement: "ANSI C11 is the new C standard". So, I guess the question is, why C99, and not C11? Just skimming through the description I noticed it will have heavy emphasis on multithreading, isn't that what the P2 is going to be doing?

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2013-05-13 11:45
    C99 was the latest standard implemented with our GCC baseline version. When Parallax is ready to support C11 it can be done.
  • tdlivingstdlivings Posts: 437
    edited 2013-05-13 11:51
    First I like what Parallax is doing with SimpleTools and making it similar to
    Ardunio to teach programming in a C or C++ syntax for microcontrollers ie propeller.
    For pure ANSI C that should be a seperate class taken by students.

    Second back to the original question asked I created an example and attached the
    file it created on the SD card and an excel file that used it.
    /*
     Write a simple comma seperated file to SD Card
    */
    #include "simpletools.h"                      // Include simple tools
    
    int DO = 22, CLK = 23, DI = 24, CS = 25;
    
    int main()                                    // Main function
    
    {
    
      int count = 0;
      int yval = 0;
    
        sd_mount(DO, CLK, DI, CS);
    
        FILE* fp = fopen("data.csv","w");
    
        // Wait for a key to be pressed on the terminal 
    
        char ch = getchar();
    
        // Write a text file
    
        printf("Writing file\n"); 
    
        for(int idx = 0;idx < 11;idx++) {
    
          count = idx;
    
          yval = 10 * count;
    
          fprintf(fp,"%d,%d\n",count,yval);
    
          pause(500);
    
        }
    
        fclose(fp);
    
        printf("Done Writing File\n");
    
        
    
    }
    

    For some reason the file with an extention of csv would not add here so I renamed it txt

    Tom
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-14 08:36
    This is my version of working the uSD to store some data. I tried leaving off sd_mount() and it did not get loaded up automatically, like it used too in 0-8-5, so I am not sure as to what is going on with that. Next I will see if I can find my old program for using the software RTC and add a time stamp for each temp/humidity reading.

    Hopefully as more interest gets stirred up for C, somebody will create some specific C code for using the Sensirion module that Parallax sells, hint, hint. I have a similar prototype with a Sensirion module that uses a GG PPUSB board and it is written in Spin. I want to create something similar that is written in C, then I can do some comparisons.

    Ray
    /*
    *  MyTempLog.c
    *
    * May 11, 2013
    *
    * Uses JLocke ThermoProp Spin examples that are converted
    * to C using spin2cpp.
    *   
    */
    
    #include "simpletools.h"                      
    #include "sensirion.h"
    
    /* This is for Activity Board */
    #define Sht11Data 15
    #define Sht11Clk  14    // Use a 4.7k resistor for pulldown
    
    /* Forward declarations */
    void sht11(void);
    void DisplayFile(void);
    
    int DO = 22, CLK = 23, DI = 24, CS = 25;
    int fTemp, Humid;
    
    FILE *pab;
    FILE *txt;
    
    /* Main function */
    int main()                                    
    {
      // Add startup code here.
      int status, n;
    
      sd_mount(DO, CLK, DI, CS);                  
      pause(300);
      printf("My Temp/Humidity Log Program\n");
      printf("Menu: 0 - Quit, 1 - Get info, 2 - Display Info\n");
    
      while(1)
      {
        printf("> ");
        scanf("%d", &n);
        if(n == 1) // 1 = Get temp
        {
           sht11();
        }
        if(n == 2) // 2 = Read and display
        {
          //printf("Nothing yet\n");
          DisplayFile();
        }
        if(n == 0) break;  // 0 = Quit
      }
        printf("Program stoped.\n");
        fclose(txt);
    }
    
    void sht11()
    {
      char tbuff[4];
      int tTemp;
    
      sensirionSpin_Start(Sht11Data,Sht11Clk);
      sensirionSpin_Config(33,NULL,NULL,NULL);
      pause(100);
      fTemp = sensirionSpin_Gettemperaturef();
      Humid = sensirionSpin_Gethumidity();
      pause(100);
      printf("Temp: %d\n", fTemp);
      printf("Humidity: %d\n", Humid);
    
    // Add a write to the uSD card
    
      pab = fopen("TempLog.pab", "a");
      fwrite(&fTemp, 1, 2, pab);
      fwrite(&Humid, 1, 2, pab);
      fclose(pab);
      txt = fopen("TempLog.txt", "a");
      fprintf(txt,"T%d ", fTemp);
      fprintf(txt,"H%d;", Humid);
      fclose(txt);
    
    }
    
    void DisplayFile()
    {
      int status;
    
      pab = fopen("TempLog.pab", "r");
      while(1)
      {
        status = fread(&fTemp, 1, 2, pab);
        if(!status) break;
        printf("Temp: %d\n", fTemp);
        status = fread(&Humid, 1, 2, pab);
        if(!status) break;
        printf("Humidity: %d\n", Humid);
      }
      fclose(pab);
    }
    
    
  • jazzedjazzed Posts: 11,803
    edited 2013-05-14 09:07
    Rsadeika wrote: »
    This is my version of working the uSD to store some data. I tried leaving off sd_mount() and it did not get loaded up automatically, like it used too in 0-8-5, so I am not sure as to what is going on with that. ...

    What board type are you using when removing the mount? Can you copy/paste the build status here?
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-14 09:32
    I am using the Activity Board. The build status does not show any errors, but the program stops at the point where it should be writing out to the uSD card. When I replace the sd_mount(), then the program runs as expected.

    Ray
    Project Directory: E:/PropGCC/MyTempLog/
    
    propeller-elf-gcc.exe -I . -L . -I C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools -L C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools/cmm/ -I sensirion -I C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools -L C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools/cmm/ -Os -mcmm -m32bit-doubles -fno-exceptions -std=c99 -c sensirion.c -o cmm/sensirion.o
    propeller-elf-gcc.exe -I . -L . -I C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools -L C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools/cmm/ -I sensirion -I C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools -L C:/Users/Ray/Documents/SimpleIDE/Learn/Simple Libraries/Utility/libsimpletools/cmm/ -o cmm/MyTempLog.elf -Os -mcmm -m32bit-doubles -fno-exceptions -std=c99 cmm/sensirion.o MyTempLog.c -ltiny -lsimpletools -ltiny -lsimpletools -lsimpletools
    propeller-elf-objdump -h cmm/MyTempLog.elf
    Done. Build Succeeded!
    
    propeller-load.exe -Dreset=dtr -I C:/propgcc/propeller-load/ -b ACTIVITYBOARD -p COM6 cmm/MyTempLog.elf -r
    Propeller Version 1 on COM6
    Loading cmm/MyTempLog.elf to hub memory
    
    12040 bytes sent
    
    Verifying RAM ... 
    OK
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-14 10:01
    I just checked the .cfg file, and looks like it has everything.

    Ray
    # Propeller activity board configuration.
    # IDE:SDXMMC
        clkfreq: 80000000
        clkmode: XTAL1+PLL16X
        baudrate: 115200
        rxpin: 31
        txpin: 30
        cache-driver: eeprom_cache.dat
        cache-size: 8K
        cache-param1: 0
        cache-param2: 0
        eeprom-first: TRUE
        sd-driver: sd_driver.dat
        sdspi-do: 22
        sdspi-clk: 23
        sdspi-di: 24
        sdspi-cs: 25
    
    
  • edited 2013-05-14 10:17
    The simpletools library takes care of a lot of things for you in exchange for that sd_mount funciton call. You can remove simpletools and sd_mount, but in exchange, you will have to add all this before your main function.
    #include <propeller.h>
    #include <stdio.h>
    
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FileDriver;
    
    _Driver *_driverlist[] = {
      &_SimpleSerialDriver,
      &_FileDriver,
      NULL
    };
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-05-14 10:37
    How does sd_mount handle boards with a multiplexed CS, such as the C3 board?
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-05-14 10:47
    I think it's fine to have a simple version of the mount that only handles the 4-pin SD interface. It's less stuff for a newbie to have to learn, and it makes it easier for Spin programmers who are familiar with FSRW.
  • RaymanRayman Posts: 14,665
    edited 2013-05-14 11:52
    One thought... I think it's clearer to use MISO and MOSI instead of DO and DI...
  • SRLMSRLM Posts: 5,045
    edited 2013-05-15 11:39
    Wasn't there some posts by David Betz in this thread, discussing the use of .cfg vs explicit pin calls? I was going to reply, but it seems they disappeared.
  • edited 2013-05-15 12:39
    Discussion moved offline.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-05-17 09:17
    SRLM wrote: »
    Wasn't there some posts by David Betz in this thread, discussing the use of .cfg vs explicit pin calls? I was going to reply, but it seems they disappeared.
    Yes, I had originally suggested it might be easier to use auto mounting of the SD card. However, I had forgotten that to do that required explicitly including a list of drivers in the user's code. That is more cumbersome than just using the sd_mount function provided by the simple tools library so it isn't really a good option for education. I withdrew my messages because they were just confusing the issue. The current sd_mount function provides an easy solution for mounting the SD card and also makes explicit the pins being used and this is probably a better approach for educational material where it is probably best not to have too many things "hidden under the hood".
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-17 12:20
    Below is my version of a temperature/ humidity data log program. Using the CMM mode, the program size is 27K, so if I were to add an XBee component to this, it just may be to large for CMM. If the activity Board had some sort of setting for using the uSD card as XMM space, that could be a way of getting larger programs to work, but that just might be impossible. So, I guess it is time to just wait for a RAM expansion module that would work with the Activity Board, but that probably would not work either.

    Ray
    /*
    *  MyTempLog.c
    *
    * May 11, 2013
    *
    * Uses the Activity Board.
    *
    * Uses JLocke ThermoProp Spin examples that are converted
    * to C using spin2cpp.
    * Added a Time Stamp with a capture of temp/humidity.
    *  
    */
    
    #include "simpletools.h"                      
    #include "sensirion.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <unistd.h>
    #include <sys/rtc.h>
    #include <propeller.h>
    
    
    /* This is for Activity Board */
    #define Sht11Data 15
    #define Sht11Clk  14    // Use a 4.7k resistor for pulldown
    
    /* Use for prompttime buffer size. */
    #define BUFFERLEN 10
    
    /* Forward declarations */
    void sht11(void);
    void DisplayFile(void);
    void settime(void);
    void printtime(void);
    int getdst(void);
    int prompttime(char *prompt);
    
    int DO = 22, CLK = 23, DI = 24, CS = 25;
    int fTemp, Humid;
    
    FILE *pab;
    FILE *txt;
    
    /* Main function */
    int main()                                    
    {
      // Add startup code here.
      int status, n;
    
      _rtc_start_timekeeping_cog();  // Runs asm function,
                                     // works in LMM,CMM,XMM modes
    
      sd_mount(DO, CLK, DI, CS);                  
      pause(300);
      printf("My Temp/Humidity Log Program\n");
      printf("Menu: 0 - Quit, 1 - Get info, 2 - Display Info\n");
      printf("      3 - Set Time, 4 - Time\n");
      printtime();
    
      while(1)
      {
        printf("> ");
        scanf("%d", &n);
        if(n == 1) sht11(); // 1 = Get temp
        if(n == 2) DisplayFile(); // 2 = Read and display
        if(n == 3) settime();  // Set the time
        if(n == 4) printtime();  // Print the time
        if(n == 0) break;  // 0 = Quit
      }
        printf("Program stoped.\n");
    //    fclose(txt);
    }
    
    void sht11()
    {
      time_t now;
      now = time(NULL);
    
      sensirionSpin_Start(Sht11Data,Sht11Clk);
      sensirionSpin_Config(33,NULL,NULL,NULL);
      pause(100);
      fTemp = sensirionSpin_Gettemperaturef();
      Humid = sensirionSpin_Gethumidity();
      pause(100);
      printf("Temp: %d\n", fTemp);
      printf("Humidity: %d\n", Humid);
    
    // Add a write to the uSD card
    
      pab = fopen("TempLog.pab", "a");
      fwrite(&fTemp, 1, 2, pab);
      fwrite(&Humid, 1, 2, pab);
      fclose(pab);
      txt = fopen("TempLog.txt", "a");
      fprintf(txt,"%s", asctime(localtime(&now)));
      fprintf(txt,"T%d ", fTemp);
      fprintf(txt,"H%d;", Humid);
      fclose(txt);
    
    }
    
    void DisplayFile()
    {
      int status;
    
      pab = fopen("TempLog.pab", "r");
      while(1)
      {
        status = fread(&fTemp, 1, 2, pab);
        if(!status) break;
        printf("Temp: %d\n", fTemp);
        status = fread(&Humid, 1, 2, pab);
        if(!status) break;
        printf("Humidity: %d\n", Humid);
      }
      fclose(pab);
    }
    
    void printtime(void)
    {
      time_t now;
      now = time(NULL);
      printf("%s", asctime(localtime(&now)));
    }
    
    
    
    int getdst(void)
    {
      int rc = 0;
      printf("Use daylight savings time [y/n] ?");
      fflush(stdout);
      rc = (getchar() == 'y') ? 1 : 0;
    //  getchar();
      return rc;
    }
    
    int prompttime(char *prompt)
    {
      int rc = 0;
      char *endp;
      char buffer[BUFFERLEN];
      do {
        printf("Enter %s: ",prompt);
        fflush(stdout);
    
        fgets(buffer,BUFFERLEN,stdin);
        fflush(stdin);
    
        rc = strtol(buffer, &endp, 10);
    
        if(endp == buffer)
        {
          if('\n' == *endp)
          {
            rc = 0;
            break;
          }
          printf("Invalid entry \"%c....\" Please enter a number.\n", *endp);
        }
      } while(endp == buffer);
      return rc;
    }
    
    void settime(void)
    {
      struct timeval tv;
      struct tm t;
    
      t.tm_isdst = getdst();
      t.tm_year = prompttime("Year")-1900;
      t.tm_mon = prompttime("Month")-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);
      printf("Set time all done.\n");
    }
    
  • edited 2013-05-17 13:27
    Yeah, I'm currently in the middle of converting Spin/PASM XBee, FSRW, and Parallax Serial Terminal to get smaller program memory footprints.

    Andy
  • edited 2013-05-17 14:12
    Rsadeika, Could you zip and upload that project?

    Andy
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-17 15:17
    Attached below is a zip of the MyTempLog project, I think I put everything necessary in there.

    Ray
  • edited 2013-05-17 19:43
    Alright, I haven't tried your code, but I do think it should be possible to run this off the SD card in XMM mode and log to a file there too. (Tested it on a program that has been causing me some difficulty, and it worked well.)

    1) In Simple View, click the lower-left Show Project Manager button if it isn't already in view.

    2) Set Board type to ACTIVITYBOARD-SDXMMC.

    3) Set Memory Model to XMMC External Flash Code Main Ram.

    After that, you can Run with Terminal, or Load EEPROM & Run. If you use Load EEPROM & Run, make sure to Click Program -> Open Terminal, then Program -> Reset Port.

    Andy
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-18 03:16
    @Andy, I tried the suggestions, and the program locks up when I try to run '1 - get info' menu selection. The settime function works, but there is something in 'Get info' that is causing a problem, I will see if I can narrow it down.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-18 03:36
    Well, I narrowed that down very quickly:
    fTemp = sensirionSpin_Gettemperaturef();
    Humid = sensirionSpin_Gethumidity();
    These two functions are what is causing the problem, which are part of the spin2cpp conversion of the Spin sensirion examples that I used. I guess I could look at the sensirion.c code, but I am not sure what I would be looking for. Maybe somebody can spot the problem, I attached the sensirion stuff.

    Ray

    sensirion.c
    //
    // automatically generated by spin2cpp v1.03 on Sat May 11 07:56:31 2013
    // spin2cpp --ccode sensirion.spin 
    //
    
    #include <propeller.h>
    #include "sensirion.h"
    
    #ifdef __GNUC__
    #define INLINE__ static inline
    #define Yield__() __asm__ volatile( "" ::: "memory" )
    #define PostEffect__(X, Y) __extension__({ int32_t tmp__ = (X); (X) = (Y); tmp__; })
    #else
    #define INLINE__ static
    static int32_t tmp__;
    #define PostEffect__(X, Y) (tmp__ = (X), (X) = (Y), tmp__)
    #define Yield__()
    #define waitcnt(n) _waitcnt(n)
    #define locknew() _locknew()
    #define lockret(i) _lockret(i)
    #define lockset(i) _lockset(i)
    #define lockclr(i) _lockclr(i)
    #define coginit(id, code, par) _coginit((unsigned)(par)>>2, (unsigned)(code)>>2, id)
    #define cognew(code, par) coginit(0x8, (code), (par))
    #define cogstop(i) _cogstop(i)
    #endif
    
    INLINE__ int32_t Min__(int32_t a, int32_t b) { return a < b ? a : b; }
    INLINE__ int32_t Max__(int32_t a, int32_t b) { return a > b ? a : b; }
    INLINE__ int32_t Shr__(uint32_t a, uint32_t b) { return (a>>b); }
    INLINE__ int32_t Lookup__(int32_t x, int32_t b, int32_t a[], int32_t n) { int32_t i = (x)-(b); return ((unsigned)i >= n) ? 0 : (a)[i]; }
    
    static  int32_t	sensirionSpin_Sendcommand(int32_t Cmd);
    static  int32_t	sensirionSpin_Readword(void);
    static  int32_t	sensirionSpin_Readbyte(int32_t Ack);
    static  int32_t	sensirionSpin_Writebyte(int32_t Value);
    static  int32_t	sensirionSpin_Wait(void);
    static sensirionSpin thisobj;
    static uint8_t dat[] = {
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xdf, 0xff, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0xf6, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    };
    int32_t sensirionSpin_Start(int32_t Data_pin, int32_t Clock_pin)
    {
      thisobj.Dpin = Data_pin;
      thisobj.Cpin = Clock_pin;
      OUTA &= ~(1<<thisobj.Cpin);
      DIRA = ((DIRA & (~(1 << thisobj.Cpin))) | (1 << thisobj.Cpin));
      {
        int32_t _idx__0000;
        for(_idx__0000 = 1; _idx__0000 <= 9; (_idx__0000 = (_idx__0000 + 1))) {
          OUTA ^= (1<<thisobj.Cpin);
          OUTA ^= (1<<thisobj.Cpin);
        }
      }
      return 0;
    }
    
    int32_t sensirionSpin_Config(int32_t Volt, int32_t Heater, int32_t Otpreload, int32_t Measres)
    {
      static int32_t look__0001[] = {164, 655, };
      static int32_t look__0002[] = {38483, 615724, };
      static int32_t look__0003[] = {(-2), (-428), };
      static int32_t look__0004[] = {84, 1342, };
    
      Volt = (Min__((Max__(20, Volt)), 55));
      Measres = (Min__((Max__(0, Measres)), 1));
      ((int32_t *)&dat[0])[0] = (((-438) * Volt) + (-634991));
      ((int32_t *)&dat[4])[0] = Lookup__(Measres, 0, look__0001, 2);
      ((int32_t *)&dat[12])[0] = Lookup__(Measres, 0, look__0002, 2);
      ((int32_t *)&dat[16])[0] = Lookup__(Measres, 0, look__0003, 2);
      ((int32_t *)&dat[24])[0] = Lookup__(Measres, 0, look__0004, 2);
      sensirionSpin_Writestatus((((Heater << 2) + (Otpreload << 1)) + Measres));
      return 0;
    }
    
    int32_t sensirionSpin_Gettemperaturec(void)
    {
      thisobj.Tc = (((*(int32_t *)&dat[0]) + ((*(int32_t *)&dat[4]) * sensirionSpin_Readtemperature())) >> 14);
      return thisobj.Tc;
    }
    
    int32_t sensirionSpin_Gettemperaturef(void)
    {
      sensirionSpin_Gettemperaturec();
    //  return (((((thisobj.Tc << 12) * 9) / 5) + (32 << 12)) >> 12);
    /* This is adjusted code to get a reading that is closer to actual. */
      return(((((thisobj.Tc << 12) * 9) / 5) + (31 << 12)) >> 12);
    }
    
    int32_t sensirionSpin_Gethumidity(void)
    {
      int32_t	Raw_rh, Linear_rh, Tmp;
      Raw_rh = sensirionSpin_Readhumidity();
      Linear_rh = (((*(int32_t *)&dat[8]) + ((*(int32_t *)&dat[12]) * Raw_rh)) + ((Raw_rh * (*(int32_t *)&dat[16])) * Raw_rh));
      Tmp = (Linear_rh + ((thisobj.Tc - 25) * ((*(int32_t *)&dat[20]) + ((*(int32_t *)&dat[24]) * Raw_rh))));
      return (Tmp >> 20);
    }
    
    int32_t sensirionSpin_Readtemperature(void)
    {
      int32_t	Ack;
      Ack = sensirionSpin_Sendcommand(Cmd_temperature);
      sensirionSpin_Wait();
      return sensirionSpin_Readword();
    }
    
    int32_t sensirionSpin_Readhumidity(void)
    {
      int32_t	Ack;
      Ack = sensirionSpin_Sendcommand(Cmd_humidity);
      sensirionSpin_Wait();
      return sensirionSpin_Readword();
    }
    
    int32_t sensirionSpin_Readstatus(void)
    {
      int32_t	Ack;
      Ack = sensirionSpin_Sendcommand(Cmd_readstatus);
      return sensirionSpin_Readbyte(1);
    }
    
    int32_t sensirionSpin_Writestatus(int32_t N)
    {
      int32_t	Ack;
      Ack = sensirionSpin_Sendcommand(Cmd_writestatus);
      sensirionSpin_Writebyte((N & 0x47));
      return 0;
    }
    
    int32_t sensirionSpin_Reset(void)
    {
      int32_t	Ack;
      Ack = sensirionSpin_Sendcommand(Cmd_reset);
      waitcnt((CNT + ((CLKFREQ * 15) / 1000)));
      return 0;
    }
    
    int32_t sensirionSpin_Sendcommand(int32_t Cmd)
    {
      DIRA &= ~(1<<thisobj.Dpin);
      OUTA &= ~(1<<thisobj.Cpin);
      OUTA = ((OUTA & (~(1 << thisobj.Cpin))) | (1 << thisobj.Cpin));
      OUTA &= ~(1<<thisobj.Dpin);
      DIRA = ((DIRA & (~(1 << thisobj.Dpin))) | (1 << thisobj.Dpin));
      OUTA &= ~(1<<thisobj.Cpin);
      OUTA = ((OUTA & (~(1 << thisobj.Cpin))) | (1 << thisobj.Cpin));
      DIRA &= ~(1<<thisobj.Dpin);
      OUTA &= ~(1<<thisobj.Cpin);
      return sensirionSpin_Writebyte(Cmd);
    }
    
    int32_t sensirionSpin_Readword(void)
    {
      return ((sensirionSpin_Readbyte(0) << 8) + sensirionSpin_Readbyte(1));
    }
    
    int32_t sensirionSpin_Readbyte(int32_t Ack)
    {
      int32_t result = 0;
      DIRA &= ~(1<<thisobj.Dpin);
      {
        int32_t _idx__0005;
        for(_idx__0005 = 1; _idx__0005 <= 8; (_idx__0005 = (_idx__0005 + 1))) {
          result = ((result << 1) | ((INA >> thisobj.Dpin) & 0x1));
          OUTA ^= (1<<thisobj.Cpin);
          OUTA ^= (1<<thisobj.Cpin);
        }
      }
      DIRA = ((DIRA & (~(1 << thisobj.Dpin))) | (1 << thisobj.Dpin));
      OUTA = ((OUTA & (~(1 << thisobj.Dpin))) | ((Ack & 0x1) << thisobj.Dpin));
      OUTA ^= (1<<thisobj.Cpin);
      OUTA ^= (1<<thisobj.Cpin);
      DIRA &= ~(1<<thisobj.Dpin);
      return result;
    }
    
    int32_t sensirionSpin_Writebyte(int32_t Value)
    {
      int32_t result = 0;
      Value = (0xffffffff ^ Value);
      OUTA &= ~(1<<thisobj.Dpin);
      {
        int32_t _idx__0006;
        for(_idx__0006 = 1; _idx__0006 <= 8; (_idx__0006 = (_idx__0006 + 1))) {
          DIRA = ((DIRA & (~(1 << thisobj.Dpin))) | (((Shr__(Value, 7)) & 0x1) << thisobj.Dpin));
          Value = (Value << 1);
          OUTA ^= (1<<thisobj.Cpin);
          OUTA ^= (1<<thisobj.Cpin);
        }
      }
      DIRA &= ~(1<<thisobj.Dpin);
      result = ((INA >> thisobj.Dpin) & 0x1);
      OUTA ^= (1<<thisobj.Cpin);
      OUTA ^= (1<<thisobj.Cpin);
      return result;
    }
    
    int32_t sensirionSpin_Wait(void)
    {
      int32_t	T;
      T = CNT;
      while (!(!((((INA >> thisobj.Dpin) & 0x1)) || (((CNT - T) / (CLKFREQ / 1000)) > 250)))) {
        Yield__();
      }
      return 0;
    }
    

    seisirion.h
    //
    // automatically generated by spin2cpp v1.03 on Sat May 11 07:56:31 2013
    // spin2cpp --ccode sensirion.spin 
    //
    
    #ifndef sensirionSpin_Class_Defined__
    #define sensirionSpin_Class_Defined__
    
    #include <stdint.h>
    
    #define Cmd_temperature (3)
    #define Cmd_humidity (5)
    #define Cmd_readstatus (7)
    #define Cmd_writestatus (6)
    #define Cmd_reset (30)
    #define Hires (0)
    #define Lores (1)
    #define Off (0)
    #define On (1)
    #define Yes (0)
    #define No (1)
    
    typedef struct sensirionSpin {
      int32_t	Tc;
      uint16_t	Dpin, Cpin;
      char dummy__;
    } sensirionSpin;
    
      int32_t	sensirionSpin_Start(int32_t Data_pin, int32_t Clock_pin);
      int32_t	sensirionSpin_Config(int32_t Volt, int32_t Heater, int32_t Otpreload, int32_t Measres);
      int32_t	sensirionSpin_Gettemperaturec(void);
      int32_t	sensirionSpin_Gettemperaturef(void);
      int32_t	sensirionSpin_Gethumidity(void);
      int32_t	sensirionSpin_Readtemperature(void);
      int32_t	sensirionSpin_Readhumidity(void);
      int32_t	sensirionSpin_Readstatus(void);
      int32_t	sensirionSpin_Writestatus(int32_t N);
      int32_t	sensirionSpin_Reset(void);
    #endif
    
    
Sign In or Register to comment.