Hur varmt är det under jorden? Blir det varmare längre ner? Hur varmt är det under marken på vintern? Några av dessa frågor kan man svara på genom att mäta temperaturen under marken. Mätningarna har genomförts med 10 stycken DS18B20 sensorer som satts fast i aluminiumrörstumpar för att ge lite skydd och en jämn temperatur. Anståndet mellan sensorerna valdes lite slumpmässigt utifrån vad som gick att montera enkelt. Sensorerna är anslutna med en gemensam CAT-5-kabel till en dator som avläser varje sensor med 5 minuters intervall. Ett år ger då lite mer ner än en miljon temperaturavläsningar som sparas och kan bearbetas vidare. Plats:Skellefteå, N64.7 E20.9 (WGS84)

Jordborrning i sand

Marken består av sand och grävningen gjordes med jordborr, Jula 725020. Jordborren funkar fint i sanden men är alldeles för kort så en förlängning måste tillverkas.

Jorsborrning
Hål i marken
Hållare till temperatursensorer.

Grafer av ytjordstemperaturen.

Marktemperatur 2013, hela året.
Det intressanta börjar i maj. Det syns att ytjorden snabbt blir varm och att dygnsvariationen tydligt kan ses en halvmeter ner i jorden.
September månad visar när temperaturen sjunker, och en snabb växling till att det är varmare längre ner i marken.
Lite djupare ner, kurvorna följs åt bra.
Sommartemperaturer med sensorer lite djupare ner under jorden.
Tre dagar i juli, ytjordstemperaturen ändras snabbast, 33cm ner syns förändringen men tydligt fördröjd. Ytjorden är kallast när det är som varmast en liten bit under ytan.

ESP8266-koden som används för att ladda upp temperaturerna till thingspeak.com nedan. Tempsensorernas adress måste anges så att rätt sensor är på rätt djup.

#include <ESP8266WiFi.h>  //https://github.com/esp8266/Arduino
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>    //https://github.com/tzapu/WiFiManager
#include "ThingSpeak.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <NewPing.h>
#define TRIGGER_PIN  D1  // Pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     D2  //Pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 350 // Maximum distance we want t ping for (in cm).
#define ONE_WIRE_BUS D4 // 1-wire data pin for temp sensors

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); 
// NewPing setup of pins and maximum distance.
#define CNT 921 // Array for averaging sonar value

int d[CNT];
unsigned long looptime;

// Assign the addresses of 1-Wire temp sensors, max 6 sensors, 8 if no rssi or sonar.
// Missing sensor will give -127.00C reading
DeviceAddress Temp1 = {  0x28, 0x44, 0xC3, 0xAF, 0x06, 0x00, 0x00, 0x39 }; //-10cm
DeviceAddress Temp2 = {  0x28, 0x70, 0x18, 0xB1, 0x06, 0x00, 0x00, 0x0B }; //-30cm
DeviceAddress Temp3 = {  0x28, 0x49, 0xA9, 0xAF, 0x06, 0x00, 0x00, 0xDF }; //-60cm
DeviceAddress Temp4 = {  0x28, 0xA5, 0x9F, 0xAF, 0x06, 0x00, 0x00, 0x93 }; //-100cm
DeviceAddress Temp5 = {  0x28, 0x57, 0xEB, 0xAF, 0x06, 0x00, 0x00, 0xFD }; //-150cm
DeviceAddress Temp6 = {  0x28, 0x2D, 0xB0, 0xB0, 0x06, 0x00, 0x00, 0xED }; //-200cm
DeviceAddress Temp7 = {  0x28, 0x0E, 0xDA, 0xB0, 0x06, 0x00, 0x00, 0xAE };

unsigned long sleeptime =251000; //milliseconds
unsigned long myChannelNumber = 75712;
const char * myWriteAPIKey = "XXXXXXXXXXXXX";
         
WiFiClient  client;
          
void setup() {
Serial.begin(9600);
Serial.println("Startar...");
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//reset saved settings
//wifiManager.resetSettings();
//set custom ip for portal
//wifiManager.setAPConfig(IPAddress(10,0,1,1),
IPAddress(10,0,1,1), IPAddress(255,255,255,0));
//fetches ssid and pass from eeprom and tries to connect
//if it does not connect it starts an access point with the specified name
       
wifiManager.autoConnect("NodeMCU-01-wifi-setup");
  
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
sensors.begin();
// set the resolution
sensors.setResolution(Temp1, 12);
sensors.setResolution(Temp2, 12);
sensors.setResolution(Temp3, 12);
sensors.setResolution(Temp4, 12);
sensors.setResolution(Temp5, 12);
sensors.setResolution(Temp6, 12);

ThingSpeak.begin(client);
}

void loop() {
looptime=millis(); // Kolla tiden för ett varv
int i;
long m;
long m2; //mean value from middle of array
int loopcount;
m2=0;
loopcount=0;
Serial.println("Start pinging!");
for(i=0; i<CNT; i++)
                { 

                 d[i] = (sonar.ping_cm());

                 delay (40);

                 loopcount=loopcount+1;

                 if (loopcount==40) {

                  Serial.print((i*100)/CNT);

                  Serial.print("% ");

                  loopcount=0;

                 } //end if 40 loops

        }  


Serial.println(" ");
Serial.println("Done pinging, start sorting");
sort(d,CNT);
Serial.println("Done sorting");
for(i=900; i<CNT-10; i++)
     {
                 m2=m2+d[i];
                 // Serial.println(d[i]);
        } 
m2=m2/(CNT-910);  

//Print Temperatures
Serial.println("Getting temperatures...");
sensors.requestTemperatures();
float t1 = sensors.getTempC(Temp1);
delay(50);
float t2 = sensors.getTempC(Temp2);
delay(50);
float t3 = sensors.getTempC(Temp3);
delay(50);
float t4 = sensors.getTempC(Temp4);
delay(50);
float t5 = sensors.getTempC(Temp5);
delay(50);
float t6 = sensors.getTempC(Temp6); 
ThingSpeak.setField(1,t1); 
ThingSpeak.setField(2,t2);
ThingSpeak.setField(3,t3); 
ThingSpeak.setField(4,t4);
ThingSpeak.setField(5,t5); 
ThingSpeak.setField(6,t6);
ThingSpeak.setField(7,m2); //average sonar reading in field 7

Serial.print("Temp 1 is: "); 
Serial.print(t1);
Serial.println("C: ");
Serial.print("Temp 2 is: "); 
Serial.print(t2);
Serial.println("C: ");
Serial.print("Temp 3 is: "); 
Serial.print(t3);
Serial.println("C: ");
Serial.print("Temp 4 is: "); 
Serial.print(t4);
Serial.println("C: ");
Serial.print("Temp 5 is: "); 
Serial.print(t5);
Serial.println("C: ");
Serial.print("Temp 6 is: "); 
Serial.print(t6);
Serial.println("C: ");
Serial.println("");
Serial.print("Medel2, values cut:");
Serial.println(m2);    
// print your WiFi IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("RSSI:");
Serial.println(rssi);
ThingSpeak.setField(8,rssi); 
// Write the fields that you've set all at once.
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  
delay(sleeptime);

Serial.print("Looptime last loop ");
Serial.print((millis()-looptime)/1000);
Serial.print(" Seconds, and of that was ");
Serial.print(sleeptime/1000);
Serial.println(" seconds sleeptime, the rest pingtime");
     
 }
void sort(int a[], int size) {
    for(int i=0; i<(size-1); i++) {
                   for(int o=0;
              o<(size-(i+1)); o++) {
                   
              if(a[o] > a[o+1]) {
                                 
              int t = a[o];
                                 
              a[o] = a[o+1];
                                 
              a[o+1] = t;
                            
        }
      }
   }
 }