Shop OBEX P1 Docs P2 Docs Learn Events
Storing Weather data from CM2302 sensor onto SD card file doesn't save anything. — Parallax Forums

Storing Weather data from CM2302 sensor onto SD card file doesn't save anything.

mundaneeffortmundaneeffort Posts: 29
edited 2020-01-01 18:09 in Customer Projects
Hello,
I am working on a small project right now to try and store weather data collected onto an SD card, where eventually the file could be run through a matlab program and plot the weather over time. I'm having a problem right now figuring out how to get the SD card to actually write the data to a text file, when I run the program an .ATA file gets created, but it contains no actual data. I was wondering if anyone had any idea where I might be going wrong. I know the dht22 library functions converts the integer values into floats, but I am wondering where the raw data is actually stored, or even the decimal converted data. I'm guessing it is in some array somewhere that I could access?
#include "simpletools.h"
#include "dht22.h"

int DO = 22, CLK = 23, DI = 24, CS = 25;      // SD card pins on Propeller BOE
int NUM = 0;



// ------ Main Program ------
int main() {
  int n;
  sd_mount(DO, CLK, DI, CS);                  // Mount SD card
  FILE* fp = fopen("TempHumData.txt", "w");          // Open a file for writing
  while (NUM < 3) {
    int n = dht22_read(5);
    fwrite(&n, 400,15,fp);
    print("%s%03.2f%s\r", "The temperature is ", ((float) dht22_getTemp(FAHRENHEIT)) / 10.0, " degrees F");
    print("%s%03.2f%s\r", "Humidity is ", ((float) dht22_getHumidity()) / 10.0, "%");
    pause(2000);
    NUM = NUM + 1;
  }
  fclose(fp);
  fp = fopen("TempHumData.txt", "w");
  fread(&n, 400, 15, fp);
  print(".2f%", n);
  fclose(fp);
}

Comments

  • mundaneeffortmundaneeffort Posts: 29
    edited 2020-01-02 04:40
    I know no one replied, but perhaps someone will look at this in the future and save themselves some time!

    Figured out what I need for now, perhaps my phrasing was too ambiguous. Creating an array of the values myself and using fprintf to write them as decimal integers solved my problem.

    I still have some random bits of code in here I was using for debugging purposes, but it works!
    #include "simpletools.h"
    #include "dht22.h"
    
    int DO = 22, CLK = 23, DI = 24, CS = 25;      // SD card pins on Propeller BOE
    int NUM = 0;
    
    
    
    // ------ Main Program ------
    int main() {
      int n, status;
      int array1[3];
      int array2[3];
      int i;
      sd_mount(DO, CLK, DI, CS);                  // Mount SD card
      //FILE* fp = fopen("TempHumData.txt", "w");          // Open a file for writing
      while(NUM < 3) {
        int n = dht22_read(5);
        array1[NUM] = ((float) dht22_getTemp(FAHRENHEIT));
        array2[NUM] = ((float) dht22_getHumidity());
        //fwrite(&n, 400,15,fp);
        print("%s%03.2f%s\r", "The temperature is ", ((float) dht22_getTemp(FAHRENHEIT)) / 10.0, " degrees F");
        print("%s%03.2f%s\r", "Humidity is ", ((float) dht22_getHumidity()) / 10.0, "%");
        pause(2000);
        print("\n%d", array1[NUM]);
        print("\n%d\n", array2[NUM]);
        NUM = NUM + 1;
        }
        
      FILE* fp = fopen("THData.txt", "wt");  
      
      for(i=0; i<3; i++)
    {
      fprintf(fp, "%d %d \n", array1[i], array2[i]);
    }  
      //print("\n%d", array1[i]);
      //print("\n%d", array2[i]);
       
      fclose(fp);
                  
      print("\nHi");                    
    }    
    

    I attached pictures of both the terminal log and data file I wrote too. Hope this helps someone in the future.

    Cheers!

    914 x 509 - 15K
    915 x 319 - 8K
  • hi @mundaneeffort,

    first of all welcome to the forum.

    Second, it is sort of funny that one finds a solution shortly after writing a post, happens quite often to me. Just describing the problem leads to a solution.

    Enjoy!

    Mike
  • mundaneeffortmundaneeffort Posts: 29
    edited 2020-01-02 18:02
    msrobots wrote: »
    hi @mundaneeffort,

    first of all welcome to the forum.

    Second, it is sort of funny that one finds a solution shortly after writing a post, happens quite often to me. Just describing the problem leads to a solution.

    Enjoy!

    Mike

    Yea it's weird how it works like that. It helps to get the problem out of your head and onto something you can look at.

    I just realized I need a time stamp too, I'm wondering what my options are there.
  • Cluso99Cluso99 Posts: 18,069
    Note that without the close, the data is written (some buffering may occur depending on which routine you're using) but the file header is not updated.

    The safest way is to have a file of sufficient length already written with zeros or some other known value, and then open and re-write the file with records as needed. This way, all your data is there (perhaps excluding the last) when a power fail or reset for some other reason happens.

    If you know your file is contiguous, you can just do a low level sector write.
  • mundaneeffortmundaneeffort Posts: 29
    edited 2020-01-03 00:28
    Cluso99 wrote: »
    Note that without the close, the data is written (some buffering may occur depending on which routine you're using) but the file header is not updated.

    The safest way is to have a file of sufficient length already written with zeros or some other known value, and then open and re-write the file with records as needed. This way, all your data is there (perhaps excluding the last) when a power fail or reset for some other reason happens.

    If you know your file is contiguous, you can just do a low level sector write.

    I'm only writing 2 floats to the text file everytime I run, I've changed the fp = fopen("TempHumData.txt", "w") to fp = fopen("TempHumData.txt", "a") so that the data appends rather than overwrites it and closes.

    Right now I'm working on how to get the propeller to take a sample every 30 minutes, append the data file and then close.

    I know sleep would be easy but, I think this poses power consumption problems as I plan on running this with a battery pack outside for a few days in a row at least.

    I think using waitcnt and clkfreq is what I'm looking for, here's a really brief pseudo code idea:

    -Place gauge outside and run, manually record real time. (Not programming :smile: )
    -Create 10 minute delay using waitcnt and clkfreq, reset clock and add 1 to a variable
    -If variable == 2; run data collection loop, reset clock and reset variable to 0

    I'm not concerned with hyper accurate time readings (like it's fine if I take the temperature and humidity at 12:02 rather than at 12), just with accidentally creating an overflow problem with my timer and not actually getting the reading done. I think the waitcnt register maxes out at around 50 seconds real time before resetting. Perhaps I could just make my program count higher...


    EDIT: Lowering the clock speed though! Hmmmm..
    Bean wrote: »
    If you are going over 56 seconds, you always have the option of running the propeller at a slower clock.
    Running at 10MHz (PLLx2) will allow you almost 8 minutes before you have to worry about roll-over.

    Bean

    source: https://forums.parallax.com/discussion/147677/timing-using-a-propeller-as-a-stopwatch

    This seems like a tasty fix, gotta investigate lowering the clock speed.

  • mundaneeffortmundaneeffort Posts: 29
    edited 2020-01-03 02:35
    Actually four double A batteries in a pack will run the controllers single cog for multiple days without anymore clock frequency manipulation needed.

    My assembly is weak and I can't find a good example to change up the clock frequency using inline assembly that I can wrap my head around.

    Just using sleep it is! For now...
  • mundaneeffortmundaneeffort Posts: 29
    edited 2020-01-03 04:11
    If anyone else is interested in doing something like this here is where I am so far.

    Essentially I just sleep for 30 minutes, and though this is an increased power draw compared to waitcnt it should still last days powered from 4 AA batteries. I wrapped everything up in a while loop and reset the count after 30 minutes.

    Seems simple and effective so far, I was wondering if anyone has any knowledge of long term clock issues with sleep. Like does the clock get messed up over time. I tested it over 30 minutes and it executed just fine as written below, I just worry if this will continue to function properly over multiple days.

    Also, should I repost the finished project with pictures and complete code when I'm done with it in a new thread?
    #include "simpletools.h"
    #include "dht22.h"
     	
    	
    int DO = 22, CLK = 23, DI = 24, CS = 25;      // SD card pins on Propeller BOE
    int Count = 0;
    int DatCount = 0;
    
    
    // ------ Main Program ------
    int main() {
      int n, status;
      int array1[3];
      int array2[3];
      int i;
      float AveT, AveH;
      sd_mount(DO, CLK, DI, CS);                  // Mount SD card
      
      while(1)
      {
      
      while(Count < 3) 
      {
        int n = dht22_read(5);
        array1[Count] = ((float) dht22_getTemp(FAHRENHEIT));    //store temps values
        array2[Count] = ((float) dht22_getHumidity());          //store humidity values
        print("%s%03.2f%s\r", "The temperature is ", ((float) dht22_getTemp(FAHRENHEIT)) / 10.0, " degrees F");
        print("%s%03.2f%s\r", "Humidity is ", ((float) dht22_getHumidity()) / 10.0, "%");
        pause(2000);
        Count = Count + 1;
      }
        AveT = (array1[0]+array1[1]+array1[2])/30.00;
        AveH = (array2[0]+array2[1]+array2[2])/30.00;
        print("\nThe average value over three samples is %.2f degress F.\n",AveT);
        print("\nThe average humidty over three samples is %.2f%\n",AveH);
        
      FILE* fp = fopen("THData.txt", "a");  
      
    
    
      fprintf(fp, "%.2f %.2f \n", AveT, AveH);
      fflush(fp);
       
      fclose(fp);
                  
      print("\nHi\n\n");   
      sleep(1*60*30);  
      Count = 0; 
      DatCount = DatCount + 1;
      if(DatCount == 3)
      {
        break;
      }                  
    }    
    
    }
    
  • Cluso99Cluso99 Posts: 18,069
    edited 2020-01-03 05:05
    Haven’t looked at your code

    You will need to keep the xtal oscillator running for accuracy, but you can lower the run frequency to 5MHz (xtal * 1) and use waitcnt to lower again. IIRC overflow is ~53s at 80MHz, so 16 x 53s gives around 14min, so try using 10mins and perform every third count.
  • mundaneeffortmundaneeffort Posts: 29
    edited 2020-01-03 07:28
    Cluso99 wrote: »
    Haven’t looked at your code

    You will need to keep the xtal oscillator running for accuracy, but you can lower the run frequency to 5MHz (xtal * 1) and use waitcnt to lower again. IIRC overflow is ~53s at 80MHz, so 16 x 53s gives around 14min, so try using 10mins and perform every third count.

    You dont think sleep will work if I'm not concerned with power management.

    I have a 4 AA battery pack, should last a few days I think. I'm not hyper concerned with the clock accuracy either. If the weather is taken at 12:01 rather than 12 its not a huge deal.

    I think this should work. I timed an hour and a half and got three measurements and it stored correctly.

    Would I need inline assembly to get that clock frequency down? I looked at the propeller manual but didn't really understand the code I was seeing.
  • Cluso99Cluso99 Posts: 18,069
    I’m not sure how C sets the PLL.
    Also not sure what sleep translates to.
    You will need help from someone with C experience.
  • I have a project posted in the "Customer Projects" called "ThermoProp". The outdoor unit runs on 3 AA batteries and transmits the temperature and humidity via XBee about every 10 minutes to a master unit. The master unit has saves the data when received. The master has a clock chip (DS3231) and writes the data to a uSD card every 15 minutes (on the quarter-hour). The outdoor unit spends most of its time 'asleep' and only wakes up to take a temp/humidity reading and send it via XBee. The batteries last 80-90 days on average. I'm at work right now so I don't have access to the code, but you might look for my project and see how I put everything to sleep. The code is in Spin, however.

    Good luck!
  • JLocke wrote: »
    I have a project posted in the "Customer Projects" called "ThermoProp". The outdoor unit runs on 3 AA batteries and transmits the temperature and humidity via XBee about every 10 minutes to a master unit. The master unit has saves the data when received. The master has a clock chip (DS3231) and writes the data to a uSD card every 15 minutes (on the quarter-hour). The outdoor unit spends most of its time 'asleep' and only wakes up to take a temp/humidity reading and send it via XBee. The batteries last 80-90 days on average. I'm at work right now so I don't have access to the code, but you might look for my project and see how I put everything to sleep. The code is in Spin, however.

    Good luck!

    Awesome, I'm looking to redo some of the project to make it more robust over the summer and will definitely check out that thread.
Sign In or Register to comment.