Data Logging question

I'm very new to this and don't even know how to properly ask this question but I'm going to try.

I have a very basic circuit and program that reads an analog in value which commands a digital out to be either HIGH or LOW, depending on if the analog in exceeds a specified value.

What I want to data log is the number of times the digital out goes HIGH, the duration of time in HIGH, and the peak analog in voltage of each occurrence.

From what I'm reading so far it seems data logging is based on set timing intervals but can it also be programmed to capture info in the way I described? And if so can someone point me to a tutorial that explains how to do that? Thanks

Yes; it's event-based data logging, instead of time-based.

And if so can someone point me to a tutorial that explains how to do that?

Not me, unfortunately, but I'd sort of expect that you might have some success with Google, but sorting the wheat from the chaff is a problem.
But if you want to actually learn to write the necessary code, we're here.

And by the way, welcome! You'll find this forum is quite friendly and helpful, but generally focussed on helping people do things themselves, not providing solutions, or web searches.
You may have missed it, but this:

will help you get along immensely.

Thank you, that helps. I didn't know the proper terms but now I can read up on event-based data logging. I will also read the linked material. Thanks for the warm welcome too!

There may be other terms that will help more, but I've been out of the logging industry for quite a while. The concept is simple, though, once you've mastered the basics of the Arduino world, so get back to me if you want to take this further by writing something yourself. You can message directly using the message feature, but be aware that most of us aren't necessarily here daily, so sometimes it takes a while to get attention.

Sounds good. I'm guessing I'll probably need help ironing out the programming once I get to that point. Thanks again, much appreciated.

What I want to data log is the number of times the digital out goes HIGH, the duration of time in HIGH, and the peak analog in voltage of each occurrence.

Key inputs to your application design will be features like:

  1. resolution of the analog input (what detail do you need for the 'peak Voltage' - to within a volt, a mV, in between)
  2. frequency of events - will you be recording tens, hundreds, or thousands of events, and what happens when you run out of storage
  3. what storage - SD, EEPROM, memory
  4. want to transmit the findings? How, when
  5. duration of event (is this a mS wide pulse, or many seconds wide)
  6. Time of event - an absolute time(YYYYMMDDHHSS.sss), or (seconds/milliseconds since last reference event, or reset, or whatever). Timestamps will require more hardware.

I could go on, but what you need to do now is sit down, think about the above, and write a description of exactly what you want your logger to do. That will help you either accept/reject solutions you find, or convince you that you need to 'roll your own' - and bring that description back here for tuning before you ever write any code.

You can try this idea:
potADC

Sketch: (untested)

unsigned long duration[10]; //10 samples
unsigned long timeMark[10];
int i = 0;

void setup()
{
  pinMode(7, OUTPUT);
  pinMode(8, INPUT);
}

void loop()
{
  if(analogRead(A0) >= 3.5)
  {
    timeMark[i] = millis();
    digitalWrite(7, HIGH);
    duration[i] = pulseIn(8, HIGH);
    i++;
  }
}

Ok, hopefully I'm following and this makes sense.

  1. I think the peak voltage resolution would be best shown in a higher resolution, like in mV. The only thing I'm trying to capture with that data point is if the number is trending up or down so I'm guessing a higher resolution would be best for that.

  2. I'm expecting at most a couple hundred events before uploading the data.

3, 4. I've chosen an SD shield to collect the data and manually upload it on my computer

  1. I honestly don't know what to expect for the duration of event. I'm trying to collect data on my sleep bruxism and clenching issues. My guess would be the events are many seconds long.

  2. I hadn't considered it but the absolute time of the events would be really nice to know. If I understand correctly the SD shield I ordered is capable of collecting that info.

program that reads an analog in value which commands a digital out to be either HIGH or LOW, depending on if the analog in exceeds a specified value.

What I want to data log is the number of times the digital out goes HIGH, the duration of time in HIGH, and the peak analog in voltage of each occurrence.

Here's some example code of how to time analog threshold events

byte sensorPin = A1; // Voltage Sensor connected to A1
byte digitalOutputPin = 13;
int sensorValue; // variable to store the value coming from the voltage sensor
int previousSensorValue;
int sensorThreshold = 512;
unsigned long startTime;
unsigned long endTime;
unsigned long duration;
unsigned int eventCount = 0;
unsigned int previousEventCount = 0;

void setup()
{
  Serial.begin(115200); // initialize the serial port
  pinMode(sensorPin, INPUT); // sets analog pin A1 to be an input
 pinMode(digitalOutputPin, OUTPUT);
 Serial.println("Starting analog event count");
}

void loop()
{
  previousSensorValue = sensorValue;
  sensorValue = analogRead(sensorPin); // read the value from the voltage sensor

  if (sensorValue >= sensorThreshold && previousSensorValue < sensorThreshold)
  {
    Serial.print("Rising analog Event:");
    Serial.println(sensorValue);
    startTime = millis();
    digitalWrite(digitalOutputPin, HIGH);
  }

  if (sensorValue < sensorThreshold && previousSensorValue >= sensorThreshold)
  {
    Serial.print("Falling analog Event:");
    Serial.println(sensorValue);
    endTime = millis();
    duration = endTime - startTime;
    eventCount++;
    digitalWrite(digitalOutputPin, LOW);
  }

  if (eventCount != previousEventCount)
  {
    Serial.print("Event Number: ");
    Serial.print(eventCount);
    Serial.print('\t');
    Serial.print("Duration: ");
    Serial.println(duration);
    previousEventCount = eventCount;
  }
}

So in this example I'd be jumping pin 7 and 8? I'm wondering why not just collect duration data from pin 7 alone? Or is that not possible for some reason? Sorry, all of this is very new to me and I really don't know what's possible or not possible and the reasons why. Thanks

Thanks, much appreciated. There's a lot to digest here and it's far beyond my current understanding. But this gives me a map of things I need to learn.

this means i remains high for as long as the analog value exceeds the threshold and goes low when < threshold?

for each occurrence, the total time or perhaps the max duration?

Does your Arduino have internet connection? If so you could probably very easily get your time from the internet and log it that way, without any extra hardware. I have an ESP32 where I already coded that, so if you need that, I can give you the code. For all the other stuff you probably need to have at least some idea of programming an problem solving skills.
I would probably do something like storing the current state, if it changes make an entry to an array, also note the voltage and whatever you need if its higher than before and if the state changes again calculate your log like the time it took, the peak in that period etc.

Depending on the nature of your analog signal, you may want to consider using a low pass filter or "leaky integrator" to get a smoothed response.

Again depending on the nature of your analog signal, you may want to use hysteresis, that is to say two thresholds, one which must be exceeded for the signal to be interpreted as on, and a lower one which must be gone under to now be finding the off condition to obtain.

With but a single threshold, when the reading was near that number you might get multiple indications of high and low, or on and off, in a small time frame.

Both are just code, not too complicate at that.

a7

1 Like

Yes, it remains high for as long as the value exceeds the threshold. And for each event I'd like to know the total time the threshold was exceeded. I'll be using this info to get averages and then graph it to see trends over time.

When I dealt with logging 12 sources (on a PC) with 4 different clocks I

logged every line beginning with PC time as an unsigned long in HEX digits.
Decimal digits take converting binary to decimal lots of steps where hexadecimal from binary is blazing fast and there is always 8 chars on the left edge of the log and logs with more than 40 lines should not be read by humans anyway but by post-processes to extract data reports.
Thus analog read >= threshold should get a line and so should the first read < just to get timing. An Uno can get you 9 analog reads per ms so maybe a lot of >= lines are possible.
Keep log lines brief while collecting, expand afterwards for display.

Log to SD. Serial Monitor is massively slower, the serial buffer has 64 chars room and then printing holds everything up till the print command can fit the end of the message into the serial buffer after the start has already printed. SD default buffer holds 512 chars and usually transfer is at SPI burst speed but sometimes the card milli-pauses so don't verbose-fill the buffer!

If you only log the changes, timestamps should make total sense.

If you have an RTC, log time data from that perhaps once a minute up to once an hour and use micros() for log line timestamps. Arduino millis() is +/- 1 ms while micros() is good to the nearest 4 microseconds and no +/-.

Do not convert analog reads to V or mV except in post-process. You gain no accuracy whatsoever and you slow all floats math on a cpu with no fpu.
Analog read delivers an int 0 to 1023. What value in that range is your threshold? Math with ints, if ( read >= 512 ) is > 100x faster than with floats on Arduino (some compatibles have an AMD chip with FPU) so avoid floats like the plague if you want fast. Print the read to the log and where does it change to V or mV? Post-process!

Do this and if you don't need full speed on 1 channel, you may collect and log multiple channels at the same time.

I don't have my Arduino connected to the internet. The thing is I'm super new to all this and I'm really just trying to go the most basic route at the moment. I realize I'd need to learn many things in order to fully understand what I'm trying to accomplish but I'm not sure how long it would take me to wrap my head around all that information and become completely fluent in all this. I intend to learn over time but I'd really like to get this working asap, regardless if I truly understand all aspects of it at this point. Maybe it would be best to hire someone to do this for me through some kind of gig website? Is there such a thing?

There's a subforum here for gigs-for-hire, if that's what you want. You'll need to clearly specify what it is you really want, etc.

you want a count of times > thres.
do you want time for each of those events or the total of all events?

1 value for count
N values for times