Propeller zone monitor system(zms)

2»

Comments

  • It seems like I am making some headway, the csv file seems to be looking a little like what I want. Still have to figure out how to deal with the float values.

    Ray
    /* COG2*/
    void unit_SD()
    {
        sd_mount(DO, CLK, DI, CS);
        pause(50);
        
        while(1)
        {
        FILE* fp = fopen("test1.csv", "a");
        month = readDs1302(dsMon);
        day = readDs1302(dsDate);
        year = readDs1302(dsYear);
        hours = readDs1302(dsHour);
        minutes = readDs1302(dsMin);
        seconds = readDs1302(dsSec);
    
        fprintf(fp,"%x/%x/%x",month,day,year);
        fprintf(fp,",%x:%x:%x",hours,minutes,seconds);
    
        fprintf(fp,",%d",gtemp);  // float
        fprintf(fp,",%d",ghumid); // float
        fprintf(fp,",%d\n",gbatt); // float
        
        fclose(fp);
        pause(5000);
      }    
        
    }
    
    csv printout.
    9/29/18,14:49:16,1117008691,1113561498,1089785036
    9/29/18,14:49:21,1117008691,1113561498,1089785036
    9/29/18,14:49:26,1117008691,1113561498,1089785036
    9/29/18,14:49:31,1117034906,1113587712,1089785036
    9/29/18,14:49:36,1117008691,1113561498,1089785036
    9/29/18,14:49:41,1117008691,1113561498,1089785036
    9/29/18,14:49:46,1117008691,1113561498,1089785036
    9/29/18,14:49:51,1117034906,1113587712,1089785036
  • Rsadeika wrote: »
    It seems like I am making some headway, the csv file seems to be looking a little like what I want. Still have to figure out how to deal with the float values.

    Ray
    /* COG2*/
    void unit_SD()
    {
        sd_mount(DO, CLK, DI, CS);
        pause(50);
        
        while(1)
        {
        FILE* fp = fopen("test1.csv", "a");
        month = readDs1302(dsMon);
        day = readDs1302(dsDate);
        year = readDs1302(dsYear);
        hours = readDs1302(dsHour);
        minutes = readDs1302(dsMin);
        seconds = readDs1302(dsSec);
    
        fprintf(fp,"%x/%x/%x",month,day,year);
        fprintf(fp,",%x:%x:%x",hours,minutes,seconds);
    
        fprintf(fp,",%d",gtemp);  // float
        fprintf(fp,",%d",ghumid); // float
        fprintf(fp,",%d\n",gbatt); // float
        
        fclose(fp);
        pause(5000);
      }    
        
    }
    
    csv printout.
    9/29/18,14:49:16,1117008691,1113561498,1089785036
    9/29/18,14:49:21,1117008691,1113561498,1089785036
    9/29/18,14:49:26,1117008691,1113561498,1089785036
    9/29/18,14:49:31,1117034906,1113587712,1089785036
    9/29/18,14:49:36,1117008691,1113561498,1089785036
    9/29/18,14:49:41,1117008691,1113561498,1089785036
    9/29/18,14:49:46,1117008691,1113561498,1089785036
    9/29/18,14:49:51,1117034906,1113587712,1089785036

    Assuming that gtemp, ghumid, and gbatt are floating point variables (based on your comments), what you want is the following:
    /* COG2*/
    void unit_SD()
    {
        sd_mount(DO, CLK, DI, CS);
        pause(50);
        
        while(1)
        {
        FILE* fp = fopen("test1.csv", "a");
        month = readDs1302(dsMon);
        day = readDs1302(dsDate);
        year = readDs1302(dsYear);
        hours = readDs1302(dsHour);
        minutes = readDs1302(dsMin);
        seconds = readDs1302(dsSec);
    
        fprintf(fp,"%x/%x/%x",month,day,year);
        fprintf(fp,",%x:%x:%x",hours,minutes,seconds);
    
        fprintf(fp,",%f",gtemp);  // float
        fprintf(fp,",%f",ghumid); // float
        fprintf(fp,",%f\n",gbatt); // float
        
        fclose(fp);
        pause(5000);
      }    
        
    }
    

    If I read the previous posts in this thread correctly (was just skimming), it appears that you are attempting to use a reduced code size fprintf. A common method for reducing the code size of the printf family of functions is eliminating floating point support so the above may not work. I would encourage you to question whether you really need to be using floating point in general due to its code size and execution speed costs when a processor doesn't natively support floating point operations.

    Here is the documentation for the printf family of functions, including all the format string conversion and formatting specifiers. Whenever you are using a printf style function it is vital that your format string's conversion specifiers match the types of the variables you are attempting to print. gcc has a printf format warning (-Wformat) which can catch these kinds of errors and is enabled by -Wall. There is also a format attribute which is used to tell the compiler that a function is printf style allowing compile time format string error checking.
  • Dave HeinDave Hein Posts: 5,642
    edited September 29 Vote Up0Vote Down
    The simple fprintf routine that I posted doesn't support floating point. However, you can print a floating point value by printing the integer and fractional portions of the number using the %d format. The following function will print a floating point number with 3 digits for the fractional part.
    void PrintFloat(FILE *fd, float x)
    {
        int i, j;
    
        if (x < 0.0)
        {
            fputc('-', fd);
            x = -x;
        }
        i = (int)x;
        j = (int)((x - (float)i) * 1000.0 + 0.5);
        fprintf(fd, "%d.%03d\n", i, j);
    }
    
  • Thank You Dave!
    Now it is getting much better, much closer to what I am looking for. Now I am wondering how the csv file will work with my SQLite program. Will the contents of the csv file be understandable to the SQLite program, in other words, will the comma separated values be stored as separate values in the database.

    The program size is 25,560, shoot I have all kinds of room left in the program.


    Now I just have to do a function for:
    i = (int)gtemp;
    j = (int)((gtemp - (float)i) * 1000.0 + 0.5);
    
    that should reduce the code a little bit.

    Ray
    /* COG2*/
    void unit_SD()
    {
        sd_mount(DO, CLK, DI, CS);
        pause(50);
        int i,j,a,b,c,d;
        
        while(1)
        {
        FILE* fp = fopen("test1.csv", "a");
        month = readDs1302(dsMon);
        day = readDs1302(dsDate);
        year = readDs1302(dsYear);
        hours = readDs1302(dsHour);
        minutes = readDs1302(dsMin);
        seconds = readDs1302(dsSec);
    
        fprintf(fp,"%x/%x/%x",month,day,year);
        fprintf(fp,",%x:%x:%x",hours,minutes,seconds);
    
        i = (int)gtemp;
        j = (int)((gtemp - (float)i) * 1000.0 + 0.5);
        fprintf(fp, ",%d.%02d",i, j);
        //fprintf(fp,",%d",gtemp);  // float
        a = (int)ghumid;
        b = (int)((ghumid - (float)a) * 1000.0 + 0.5);
        fprintf(fp,",%d.%02d",a,b);
        //fprintf(fp,",%d",ghumid); // float
        c = (int)gbatt;
        d = (int)((gbatt - (float)c) * 1000.0 + 0.5);
        fprintf(fp,",%d.%02d\n",c,d);
        //fprintf(fp,",%d\n",gbatt); // float
        
        fclose(fp);
        pause(5000);
      }    
        
    }
    
    
    csv file
    9/29/18,16:59:32,73.700,56.900,7.820
    9/29/18,16:59:37,73.500,56.900,7.820
    9/29/18,16:59:42,73.700,56.900,7.820
    9/29/18,16:59:47,73.500,56.900,7.820
    9/29/18,16:59:53,73.700,57.00,7.820
    9/29/18,16:59:58,73.700,56.900,7.820
  • Yes, I wasn't trying to butt in which is why I left it until now to speak up. I'd like to see how you get your project done in C, but I don't want to see you shelve any hardware due to software issues as this reflects badly on the Propeller chip itself. I'm busy enough and if Dave can help you sort it out then I think that it is a good thing because it should help to improve and shape the software tools just as I have always endeavored to improve Tachyon, not as "a language" but as a useful and practical tool to get the job done.

    Please don't give up. My motto is "No effort, no joy" or in other words "solving problems and getting things to work is fun".


    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • Thanks Peter for the encouragement to keep at it. No, you were not butting in, I was starting to look for other ways of doing this project. I really want to thank Dave Hein again, basically two lines of code, to get motivated again.

    Today I want to add, to the html, a start/stop command for the data logging session. I have done similar coding in another project, so I do not anticipate any problems. Once I get that done, then I will give the program a closer look and see if I can determine where I can get some code savings. After that I will put this into zip file and attach it to a post. Hopefully one of the C experts will give it a once over to see if they find some code cutting areas.

    Ray
  • First, a question for Parallax, do you know of a source for a CO2 and Oxygen sensor(s), that fit your base unit. I will probably be purchasing the Methane sensor and base unit, to see how that would work with my zms unit.

    Below I have attached a zip file that contains the C program and the html file that goes with it. A warning, I could not get the 'Start/Stop' commands, in the html, to work correctly. I also did not do any code reduction, this is a "raw" first attempt conglomeration, if you will.

    Since I now have a print out of everything, I will probably try to reorganize the bread board, to make room for the new addition of the gas sensors, when they become available. Also, I will probably be looking at code simplification/reduction, not sure if I will make much headway in that area.

    I think what I may have to do is create another zms bread board unit, since I will be ordering the gas sensor, I might as well order some more parts to duplicate the original zms unit.

    Ray
    zip
    101K
  • Dave HeinDave Hein Posts: 5,642
    edited October 1 Vote Up0Vote Down
    Ray, I looked at your code in the zip file, and everything looks good. I don't have wifi.h or the WIFI library, so I couldn't build it, but as long as it works for you that's all that really matters.
    I noticed that you use sprint(), which I didn't know existed. If you ever need to save some space you could eliminate fprintf, and used sprint() and fputs() instead. Or you could create and fprint() based on the source code for sprint().
    [soapbox]
    Just as an editorial comment, I think it was a mistake for Parallax to create the formatted print functions without the "f" suffix. I think it would have been much better to use the standard library names, such as printf and sprintf, and just provide a linker option to use a smaller library. That's what I thought tinylib was for, but maybe tinylib doesn't provide enough functionality such as floating point. In that case a mediumlib could have been created to support floating point. I just think that the functions with the "f" suffix misleads novices, and confuses everyone else.
    [/soapbox]
  • I don't have wifi.h or the WIFI library, so I couldn't build it,
    If you are using SimpleIDE, it is in the Simple Libs folder under Networking. You would probably have to update to the latest Simple Library download.

    Since Dave made no mention on the html portion, hopefully somebody that knows what they are doing will look at that and figure out why the Start/Stop does not work correctly, if that is where the problem exists.
    Or you could create and fprint() based on the source code for sprint().
    I do not think that I am there as a C programmer to do that.

    I am now following Eric's new Basic language, maybe it will end up doing what I just did in C, but it would be done in his new Basic derivative. It looks like things are starting to perk up a little here on the forum.

    Ray
  • I got a new computer last week, and I loaded the latest version of SimpleIDE that is listed on the Parallax site. However, I don't see a Networking folder, and it doesn't contain a file named wifi.h. Do you have a link for the SimpleIDE download that you used?

    The code for sprint.c is
    #include <stdarg.h>
    #include "simpletext.h"
    
    int sprint(char *buf, const char *fmt, ...)
    {
      va_list args;
      int r;
      va_start(args, fmt);
      r = _dosprnt(fmt, args, buf);
      va_end(args);
      return r;
    }
    
    An fprint.c based on this would look like this.
    #include <stdarg.h>
    #include "simpletext.h"
    
    int fprint(FILE *fd, const char *fmt, ...)
    {
      va_list args;
      int r;
      char buf[256];
      va_start(args, fmt);
      r = _dosprnt(fmt, args, buf);
      va_end(args);
      fputs(buf, fd);
      return r;
    }
    
  • Dave,
    I downloaded the latest version of Simple Libraries (v9/7/18) from this page:
    https://parallax.com/downloads/propeller-c-learn-folder

    There is a network folder in that version.
    Tom
  • RsadeikaRsadeika Posts: 3,196
    edited October 1 Vote Up0Vote Down
    I was just going to post the twm47099 post, but he beat me to it.

    Ray
  • Thanks. I wasn't aware of the update to the Learn folder. I grabbed it, and now I can compile and link your program. I tried the fprint() code that I posted, and it only saves about 300 bytes over the other version of fprintf(). They are both substantially smaller than the library version of fprintf().
  • I am trying to figure out why the Start/Stop is not working as expected. I verified that the html part is working, because when I use the Start/Stop, the putStr() shows up in the terminal. But the s_sd = 1 is not affecting the if() loop in COG 2.

    In the COG 2, I have an if(s_sd == 1), that is supposed to start the while(1) loop. In the top of the program I have 'volatile int s_sd = 0;', which is supposed to make this a global value. I am not sure why this is not working as expected. I have a 'volatile gbatt', that seems to be working as expected. Is my 'if(s_sd == 1)' concept being used incorrectly?

    Ray

    if(strstr(path,"/startstop") !=0)
          {
            wifi_scan(POST, handle, "go%c",&startSD);
            if(startSD != 0)
            {
              switch(startSD)
              {
               case 'S':
                s_sd = 1;  // This s_sd is volatile global
                putStr("Start SD!");  // debug
                break;
               case 'T':
                s_sd = 0;
                putStr("Stop SD!");  //debug
                break;
              } // switch
            } // if(startSD != 0)        
          }  // if(strstr
    
    /* COG2*/
    void unit_SD()
    {
        sd_mount(DO, CLK, DI, CS);
        int c,d;
        //s_sd = 0;
        
      if(s_sd == 1)
      {
        while(1)
        {
          FILE* fp = fopen("test1.csv", "a");
          
          c = (int)gbatt;
          d = (int)((gbatt - (float)c) * 1000.0 + 0.5);
          fprintf(fp,",%d.%02d\n",c,d);
    
          fclose(fp);
          pause(30000);
        } // while
      }      
    }
    /**********************/
    
  • Since I am having some trouble implementing the Start/Stop in the html to have the correct affect on an if or while loop to make the SD to work as I want, could an on/off for the COG be an alternative.

    I have never used this coding approach before, turn a COG on and then turn it off. Not sure how that works in C. Has anybody done this and would be willing to share an example?

    So, the way I envision this, in the html, when I hit the Start it would then turn on the SD COG. Then when I hit the Stop, it would then turn off the SD COG. And maybe a similar approach could be used for mounting an unmounting of the SD card itself. It would be nice if there was some code to make the SD card behave the way it does on a PC.

    Ray
  • Below is my version, which is not working as expected. When I run the program, it does start the SD COG, but I am not sure if the cog_num(c_id) is getting the number of the COG I just started.

    When I checked the datalog contents I noticed that the date and time is not being logged. When I do the Stop part, it seems like it is stopping the whole program. If that is the case, then the cog_end(c_id) has the wrong COG number that I want. Anybody have any ides as to what is going on.

    Ray
            wifi_scan(POST, handle, "go%c",&startSD);
            if(startSD != 0)
            {
              switch(startSD)
              {
               case 'S':  // Start
                cog_run(unit_SD, 128);
                pause(150);
                cog_num(c_id);
                break;
               case 'T':  // Stop
                cog_end(c_id);
                pause(150);
                break;
              }          
            } 
    
  • Something strange is going on, and I can not pin it down.

    In the main(), I do a cog_run(unit_CM2302, 128), I also do a cog_num(c_id_1). When I run the program, I see a print out of the number 0, which is the same number (cog_num(c_id)) I see when I run the switch(startSD). So, I am starting two different COGs, but I am getting back the same ID number. Is this a BUG or am I using the commands incorrectly? Anybody!

    Ray
    int main()
    {
      // Add startup code here.
      //sd_mount(DO, CLK, DI, CS);
      //int c_id;
      cog_run(unit_CM2302, 128);
      pause(150);
      cog_num(c_id_1);
      putDec(c_id_1);
      putStr("\n");
    
    switch(startSD)
              {
               case 'S':  // Start
                cog_run(unit_SD, 128);
                pause(150);
                cog_num(c_id);
                break;
               case 'T':  // Stop
                cog_end(c_id);
                pause(150);
                break;
              } 
    
  • OK, so I got this to work, sort of. It does do a data logging start and I can do a data logging stop, and repeat it. But when I pull the SD card out, and put it back in, the Start/Stop no longer works.

    So, I guess when I stop the SD COG, it is not stopping the cd_mount() COG that was started in the main SD COG. This is really getting to be confusing, especially when you have a COG that is starting within a COG.

    At this point I can Start and Stop a data logging session, and as long as do not take the SD card out I am OK. But, once I stop the SD session, I want to see what is on the SD card. Not sure what the coding should look like for it to do what I am after.

    Ray
    switch(startSD)
              {
               case 'S':  // Start
                c_id = cog_run(unit_SD, 128);
                pause(150);
                cog_num(c_id);
                putDec(c_id);  // Print to terminal
                putStr("\n");
                break;
               case 'T':  // Stop
                cog_end(c_id);
                pause(150);
                putDec(c_id);  // Print to terminal
                putStr("\n");
                break;
              } 
    
  • Well, everything just came to sudden halt. It looks like I either fried my WX WiFi SIP module or the module decided to give up. The blue LED still flashes, but I cannot get to it with 192.168.4.1. Not sure what other options I have to remedy the situation.

    Ray
  • Have you restarted your router/AP and power cycled everything? Once in a while my module has that issue and a router reboot fixes it. No idea why.
  • Thanks pmrobert, yesterday I thought I tried just about everything, but could not reach the WiFi module. Today I did some of the similar things, plus what you suggested, and I was able to get to the WiFi module. So, I am not sure what made the difference.

    After checking the WiFi module, I noticed that it had lost its IP address, not sure how that would affect the WiFi 192.168.4.1 address though. So, I will have to do some more testing to see if it is ready to go back too work.

    Since I had to pull the FLiP module and the WiFi module and place it on another breadboard, for testing, I guess this gives me an opportunity to re-build the zms unit on the other breadboard. I have to make room for more sensors, as they become available.

    Ray
  • Just an update as to what I have been doing with the zms project.

    I had it working on the breadboard, using a FLiP module and components. Then I moved the components, less the ADC chip, onto the WX Activity Board, and got it to work there. I compared the code size for both, and it seemed they were about the same.

    Now, I am working with fastspin(BASIC) and the WX Activity Board, making some headway. After I get it done I will then compare code size for all three. But, first indications, look like all three will be about the same code size.

    Ray
Sign In or Register to comment.