Log daily accumulated light levels

I want to record daily total light levels. I have a data logging shield to capture the data. But I am not sure whether my proposed approach is viable:

Create a variable to capture accumulated light level, read light sensor at intervals, (1 minute? 10 minutes?) and add reading to variable value.
Accumulate total for 24 hours - how best to trigger at 24 hours? Simply set a millis variable and trigger at 8,640,000 millis from initial millis? (Will millis hold that big a number??) Can I use the RTC in the shield to trigger an event in some manner?
Once I get to this point, I think I can muddle through - write the value of the accumulated light variable to the SD card in the shield together with date stamp, reset the variable to 0, restart the process of accumulating total light accumulation, (ie loop every 24 hrs. Or maybe better, every 12 hours)
Note that I fully appreciate that the accumulated light level will not represent any particular units. (I am essentially integrating an area under the curve using very widely-spaced data points). But this is of no importance whatsoever to me - I am essentially compiling a comparative measure with completely artificial units which I will correlate with observed hours of sunlight and cloud to create a look-up table.

Which RTC is fitted to your data logging shield?

Most have the ability to set alarms - sometimes only 1 alarm, but others support 2 alarms. You should be able to set the alarm to match your sample interval if you choose the correct interval.

If your RTC supports day of week, then you can monitor that for a change to detect the end of a day.

You need to provide schematics and code. No helper will dump that into Your mailbox.
There are ways, standards, to describe what the code is needed to do. It's not spelled "plenty of words".

Ok, I'll play your guessing game. I don't need to know which specific sensor you have in order to answer the question. But obviously, I need to know the range of values it produces.

Once you have decided how many readings per day, multiply that by the maximum reading and read up on C/C++ integer types to find one that it will fit in. Why is that difficult?

at intervals, (1 minute? 10 minutes?)

IDK, you have to tell me.

how best to trigger at 24 hours?

Best? If you're confused, just count readings. After all, you are timing them. If you take readings every minute, then after 24x60 readings, 24 hours will have elapsed.

Will millis hold that big a number??)

millis() is fully documented in the Arduino reference section on this site. But if you have an RTC, you can use it for timing instead of millis(). It's more accurate anyway.

To detect a minute change

if stored minute not equal to current minute
{
  stored minute = current minute
  do your once a minute stuff
}

Obviously, a day change is the same kind of logic.

I suggest saving an average instead of a total. The total does not contain more useful information than an average, but is needlessly larger.

I like to look at daily barometric pressure, rolling over a 48-hour (arbitrary) window.

Behind-the-scene an array keeps the rolling values from the barometer, new readings are "pushed" in and the oldest reading falls out.

There is nothing magical about 48 hours, just need to keep arrays reasonable to the amount of SRAM.

You could just as easy write each "update" to an SD, but then there is that sneaker-net to PC to import and visualize.

Worker routines:


void StoreHistory ( void ) {                                      // Creates a boxed border using lines 0 & 1
  int  n;                                                         // avoid compiler complaints in for(;;) loop
  // array [0] is reserved for newest value                       // Therefore [80] = [79], [79] = [78],..., [1]==[0] after shift
  for (n = 80; n > 0; n--)                                        // shift history array to the right, oldest value [80] is lost
  {
    pHistory[n]      = pHistory[(n - 1)];                         // shift data right, oldest value lost, [1] becomes [0] the current value
  }
  pHistory[0]        = M;                                         // save current "adjusted" pressure hPa [0]
}


void displayCurrent( void ) {
  int temp1, temp2;                                               // working vars for type conversion

  lcd.setTextSize(3);                                             // Print hPa and inHg legends and readings in large font
  lcd.setCursor(0, 1);  lcd.print("hPa   inHg   temp");
  lcd.setCursor(0, 35); lcd.print( M );

  if ( M < 1000 ) {
    lcd.print("   ");
  } else {
    lcd.print("  ");
  }

  temp1              = inHg / 10;                                 // Integer component
  temp2              = ((inHg / 10) - (float) temp1 ) * 100;      // 2 decimal places

  lcd.print(temp1); lcd.print(".");
  lcd.print(temp2);

  lcd.setCursor(235, 35);
  lcd.print( temperature, 0 );

  if (Fahrenheit) {
    lcd.print(" F");
  } else {
    lcd.print(" C");
  }
}


void displayHistory( void ) {
  long     M;
  long     minimum   = 1040L;
  long     maximum   = 985L;

  uint8_t  h, z;
  uint16_t x, y;

  z = 0;                                                          // z will span 0 to 319, full screen landscape width in pixels

  for ( x = 1; x < 240; x++ )                                     // 80 elements @1 element per 18 minutes = 10 elements per 3 hours
  {
    if ( x % 3 == 0 ) {                                           // this provides for skipping every 3th position for bar spacing
      z++;
    } else if (pHistory[z] != 0) {                                // array is initially init to zero value, no need to plot this
      if (pHistory[z] < minimum) minimum = pHistory[z];           // capture the lowest  24 hour pressure reading
      if (pHistory[z] > maximum) maximum = pHistory[z];           // capture the highest 24 hour pressure reading
      h = (pHistory[z] - 985) * 2;                                // h is for height and x2 is for scaling factor
      y = 200 - h;                                                // Adafruit's GFX y coordinates plots upside down, flip reference
      lcd.drawFastVLine(x,  y,   h, ILI9341_WHITE);               // 2 bars are drawn per array element and 1 blank space for separation
    }
  }

  y = 200 - ((minimum - 985) * 2);
  
  for (x = y ; x < 200; x++) {                                    // Alternate display mode
    lcd.drawFastHLine(1, x, 245, ILI9341_BLACK);
  }

//    drawFastHLine(uin86_t x0, uin86_t y0, uint8_t length, uint16_t color);
  lcd.drawFastHLine(1, y, 245, ILI9341_WHITE);                    // draw baseline   24 hour lowest reading
  y = 200 - ((maximum - 985) * 2);
  lcd.drawFastHLine(239, y, 6, ILI9341_YELLOW);                   // draw marker tic 24 hour highest reading
}


void drawLegends( void )
{
  // Legends and axis for display
  lcd.setTextSize(1);
  // Atlanta: High = 30.79 on 1/6/1924	Low = 29.08 on 1/11/1918
  // 2X scaling: 1040 - 1026 = 14 x 2 = 28 pixels
  lcd.setCursor(240,  84); lcd.print("_ 1040= 30.71");            // setup Y legends
  lcd.setCursor(240, 112); lcd.print("_ 1026= 30.30");
  lcd.setCursor(240, 140); lcd.print("_ 1012= 29.88");
  lcd.setCursor(240, 168); lcd.print("_  998= 29.47");
  lcd.setCursor(240, 194); lcd.print("_  985= 29.09");
  // tiny fonts for timeline legend @53 char/line (6px/char)
  lcd.setCursor(0, 205); lcd.print("N        ^         ^         ^         ^  Historical ");
  lcd.setCursor(0, 213); lcd.print("O        1         2         3         4  Timeline   ");
  lcd.setCursor(0, 221); lcd.print("W        2         4         6         8  In Hours   ");
  lcd.drawFastVLine(0,  88, 112, ILI9341_RED);                    // setup Y axis
  lcd.drawFastHLine(0, 200, 238, ILI9341_RED);                    // setup X axis
  lcd.drawFastHLine(0, 201, 238, ILI9341_RED);                    // setup X axis double-width X axis for emphasis
}

I highly recommend mapping your LCD resources on paper before you start coding:


  
**************************** ILI9341 320x240 DISPLAY LAYOUT ****************************
0,0
----------------------------------------------------------------------------> 319
| nnnT                                                                 DOW
|              lcd.fillRect( 0,  0, 319, 59, 0);     // blank top
|
|
|<- 059 
|
|              lcd.fillRect( 0, 60, 319, 114, 0);     // blank middle
|                              HH:MM:SS A
|
|
|
|<- 174
|              lcd.fillRect( 0, 175, 319, 64, 0);     // blank lower
|
| MON DD YYYY
|
|<- 239
*/

/*
 https://learn.adafruit.com/downloads/pdf/adafruit-gfx-graphics-library.pdf

 **************************** Adafruit_GFX functions ****************************


BP180_GLCD_48.zip (33.3 KB)

Thank you for telling me this is possible. You have been very helpful, and I am grateful for your time.

Negative responses such as this are not helpful and contribute to the perception in the community that this forum is both very exclusive, arrogant, and intolerant. (Unless I am misinterpreting what I perceive as a remarkably hostile response.)

I have neither schematic nor code at this time, (which, incidentally, is why I posted in the "Project Guidance" forum, and not in the "Programming" one.) I make absolutely no claim to expertise in programming, but the approach I was taught many years ago was to start planning a project by creating a "Pseudo-code" outline program flow, followed by actual coding to "make it work". I am at this initial stage, and all I was asking for was guidance on what is possible, as well as "approaches". I am gratified by the gracious assistance that a number of your fellows have been willing to offer.

I am not looking for anybody to "dump schematics and code into my mailbox", and I am not sure just what the phrases about "ways and standards" and "plenty of words" connote. (Although I might comment that pseudo-code is, by its nature, verbose.)

1 Like

Pseudocode is honoured on this forum. Please post it. Also why dwell on unhelpful responses when you can run with the helpful ones...

Dude: I don't program in any language I cannot spell from memory :laughing:

Programming is difficult 'nuff without having to consult my 5 pound Mirriam-Webster.

Oops! Sorry, I did not appreciate that replies to individual posts do not remain attached specifically to the one post, (as in Facebook). I shall respond to everyone together:
I wasn't trying to create a "guessing game". As aarg observes, you don't need to know which specific sensor I have, but nor do you need to know the range of values it produces - I wasn't asking how to read values, nor how to write them. And you are absolutely correct that I need to fit the type of variable to the anticipated storage requirement. No, this is not difficult. I obviously failed seriously in making clear what I was actually seeking - guidance on recording data over time frames of days rather than seconds or minutes. The musings about appropriate intervals and the best ways to measure intervals were just that - thinking out loud - but not actually intended to be answered. (Most of my programming experience in the past was with a high-end DbMS, which had multiple built-in time parameters. I am learning to work with the restricted choices available here.) I shall take more care in future to confine my posts to very specific concrete questions, and keep my musings to myself.

I am more than satisfied that you have been awfully generous with your time and willingness to guide me, and that I have everything I need to proceed. I may very well need to come back at some point in the future once I get into the nitty-gritty of coding, but I thank you all for now. And you can move on to more legitimate needy individuals.

And I have no desire to fight with oppositional individuals. I was only trying to reflect the reputation in the community of this forum, and the impact negative comments may have on less secure individuals.

Hold on, that is not true. You asked about the capacity of variables to store accumulated values. Obviously, the range of those individual values directly impacts the answer to that question.

Focus on your original question and you will get along fine here. I'm already tired of your complaints, and putting you on my ignore list.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.