Need help doing a circularbuffer with DHT22 and TinyRTC with Ethernet Shield

Hello Community,

me and a friend are really struggling at the moment on our project.

We have a Arduino Uno , Ethernet Shield, DHT22 and TinyRTC.

We are hosting a website with the Humidity , Temperature and Time.

Now we want to make something like a circular buffer with arrays so we can get the temperatur from the last 5 hours.

Actually the site works fine but we don’t know how to do the Array thing.

#include <RTClib.h>


#include <Wire.h>

#include <DHT.h>


#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
RTC_DS1307 rtc;

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36
}; //MAC address found on the back of your ethernet shield.
IPAddress ip(not relevant); // IP address dependent upon your network addresses.

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(1200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  dht.begin();

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  if (! rtc.begin()) {
    Serial.println("No RTC found");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is not configured");
  }
  rtc.adjust(DateTime(2018, 4, 28, 13, 31, 0));
}


void loop() {
DateTime now = rtc.now();
  Serial.print(now.year(), DEC);
  Serial.print('-');
  Serial.print(now.month(), DEC);
  Serial.print('-');
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  delay(3000);



  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
    
  }

  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 Temporary Redirect");
          client.println("Content-Type: text/html");
          client.println("Connection: persisent");  // the connection will be closed after completion of the response
          client.println("Refresh: 60");  // Alle 5 Sekunden aktualisierung
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          // Datenausgabe RTC
    
  client.println("<H2>");
  client.print(now.day(), DEC);
  client.print('.');
  client.print(now.month(), DEC);
  client.print('.');
  client.print(now.year(), DEC);
  client.print(" ");
  client.print(now.hour(), DEC);
  client.print(':');
  client.print(now.minute(), DEC);
  client.print(':');
  client.print(now.second(), DEC);
  client.println();
          // Datenausgabe DHT-22
          client.println("<H2>");
          client.print("Luftfeuchtigkeit: ");
          client.println("</H2>");
          client.println("<p />");
          client.println("<H1>");
          client.print(h);
          client.print(" %\t");
          client.println("</H1>");
          client.println("<p />");
          client.println("<H2>");
          client.print("Temperatur: ");
          client.println("</H2>");
          client.println("<H1>");
          client.print(t);
          client.println(" °");
          client.println("C");
          client.println("</H1>");



          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // Verbindung schließen:
    client.stop();
    Serial.println("client disonnected");
    
  }
}

This is our code right now. A bit messed up but it works. Right now we only need to add the Temperatur Statistic of the last 5 hours and then we would be finished with our projects.

I hope someone can help us.
Thank you so much !

You probably don't have enough memory to save all that data. Let's say you have about 800B of free RAM (which is probably rather optimistic given that you are using the Ethernet shield), that means that you can only record the temperature and humidity every 3 minutes (if you save them as 32-bit floats, if you save them as 16-bit fixed-point numbers, you can get twice that rate). If the record interval is fixed, you don't have to explicitly save the time.

Just create a struct that contains the two numbers you want to save, and create an array of 200 of these structs. Then keep a pointer to the element where you'll write the next reading (and a pointer to the oldest reading). Then just write the new record in the array every 3 minutes and increment the pointer. If the array is full (i.e. the two pointers are the same), increment the pointer to the oldest reading as well. That's a standard ring buffer, there are countles examples online.

Pieter

Hello PieterP ,

first of all thank you for your help. We still couldn't get it managed to set up :(

Could you help us ? Thanks!

Post your attempt.

if(millis()- time >= 60000){

time = millis();

for (unsigned int i = 0; i < 1; i++){
hA = dht.readHumidity();
tA = dht.readTemperature();

Idea was to read the humidity and temperature after a amount of time. But I end up that it is displaying 0.0 until de millis timer activates…

for (unsigned int i = 0; i < 1; i++)Why?

To be honest I am not really a expert. I thought I have to do it with an for loop. But at the moment I am very frustrated because I dont know what to do.

Keep an array index. At the current position, write the most recent result. Increment the index. If the index equals the array size, set the index to zero. Rinse and repeat.

Humidity could be rounded to the nearest 0.5% and stored in a byte. Environmental temperature is unlikely to exceed 323 K, or fall below 223 K, so could also be stored in a byte, as an offset, also to half degree accuracy.

TolpuddleSartre:
Keep an array index.
At the current position, write the most recent result.
Increment the index.
If the index equals the array size, set the index to zero.
Rinse and repeat.

Humidity could be rounded to the nearest 0.5% and stored in a byte.
Environmental temperature is unlikely to exceed 323 K, or fall below 223 K, so could also be stored in a byte, as an offset, also to half degree accuracy.

Since my reading english is not so good I can’t really tell what exactly you mean. Could you make an example or so ?

Although thanks for your help !

But my example would be written in English too, so I can't see how it would help.

Is there a section of the forum where your native language is used? Try the "International" section.

An array index is the value that goes between the square brackets.

thisIsAnArray [thisIsAnIndex]

You have to understand that we can’t teach you all the basics you need to complete this project. I’d recommend to get a book on programming that covers the basics, and start with simpler programs. It doesn’t necessarily need to be Arduino. You can’t just jump into the deep part of the pool. Also try to work on your English, because you’ll need it: most of the resources online will be in English.