Iduino logger shield ST1046, datalogger til en Arduino R3

Styrer man sit drivhus, eller andet, med en Arduino, så kommer der et tidspunkt, hvor man bliver træt af at notere lys osv og skrive det ind i Excel. Løsningen er en datalogger, der sættes på Arduino’en. Det er lækkert, når det fungerer, men absolut ikke noget man lige går til.

Jeg valgte et Iduino  data logg shield ST1046, ud fra pris og fragt. Den forhandles af Conrad, og der er en kort vejledning her. Den koster 79 kr, og kan ses her. Der skal et hukommelseskort i loggeren, jeg valgte et 4 GB til 49 kr, ses her, og en kortlæser, her var jeg ikke opmærksom, og valgte en til 8 kr, men den var til USB C stik, og det har min puter ikke, så det blev til en kortlæser fra AV-Cables til 39 kr. 

Dataloggeren sættes oven på Arduino’en, og så er man principielt kørende. Til alt andet findes der programmer på nettet, men der er ikke meget til dataloggere, og Iduino’en har anderledes interne forbindelser, så det tog lidt tid at finde ud af.

Mit program er baseret på NJarpa. I alle programmer på nettet startes der med at kontrollere kort og fil og skrive en meddelelse om hvorvidt det fungerer. Det har jeg strøget, for der er ikke noget at bruge det til. Når jeg får tid vil jeg sætte en lille LED på, der tænder når loggeren skriver, så man ikke afbryder strømmen med åben fil.

Dataforbindelsen på andre kort er til pin 0 eller 10, men på Iduinoen er den til 8:     const int chipSelect = 8;
En anden krølle er, at pin 10 må ikke bruges, og skal sættes til output, ellers virker programmet ikke:       pinMode(10 , OUTPUT);

Åbne en fil, skrive til den og lukke

File SlowG;        // Definer filen SlowG under setup
SlowG=SD.open(“SlowG.csv”,FILE_WRITE);    // Åbne filen for skrivning
SlowG.println(); // starter med linieskift, alt herunder skrives på samme linie
SlowG.print(now.day(), DEC); // se nedenunder
SlowG.print(“-“);
SlowG.print(now.month(), DEC);
SlowG.print(“-18 “);
SlowG.print(now.hour(), DEC);
SlowG.print(“:”);
SlowG.print(now.minute(), DEC);
SlowG.print(” ; “);
SlowG.close(); // Luk filen

Dato og tid skrives, så Excel kan forstå det, som:  dag-måned-18 time:minut
.print fortsætter skrivning på samme linie,  .println skriver og ender med linieskift.

Tid

Arduinoen har en simpel tidmåler, der tæller tusindedele sekunder siden start, Iduino’en derimod har et modul med batteribackup, der angiver år, dato og tid, en såkaldt RTC, Real Time Clock.

RTC kaldes med:
DateTime now = RTC.now();
now = RTC.now();
int minut = now.minute(); // de enkelte elementer kan kaldes
int s = now.second();

Logging

Vil man logge een gang i timen, f eks klokken hel, vælges det med:

if(minut == 0 && sekund == 0)

Troede jeg, for det fandt jeg på nettet, men jeg læser 5 temperaturer, og stopper 50 millisekunder hver gang, og skrivning til fil er langsommeligt, så sommetider er processoren ikke ledig når sekunderne er i nul.
Løsningen er enkel:

if(minut == 0 && sekund <5)
åbne filen, skrive og lukke, derefter stoppe Arduinoen, så der kun logges een gang i timen:
delay(6000); // stopper Arduino i 6000 millisekunder, men RTC kører videre.

Vil man logge f eks hvert kvarter, kan man finde et eksempel med if minut == 0 eller 15 eller 30 eller 45 – og det er lidt bøvlet. I stedet kan man bruge den funktion, der returnerer resten fra en division, i stedet for divisionstegn bruges %, så  (7 %5)  er lig 2. Jeg logger hvert 10. minut og bruger:

if(minut % 10 == 0 && s < 5)

Hvordan finder man ud af det

Find programmer på nettet, pas på at læse, hvad der står omkring dem, for sommetider spørges der om hvad fejl, der er i programmet.
Ting, man ikke kender, kan Googles. Ting, man ikke forstår, skal man ikke bruge.

Mit program

Programmet er ikke super, men virker. Det læser 5 temperaturer og solindstråling, og er ved at blive udvidet til gennemsnitsberegninger, så det virker måske sjusket, her er det:

#include <Wire.h>
#include “RTClib.h”
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <SD.h>

OneWire oneWire(ONE_WIRE_BUS_PIN); // Setup oneWire
DallasTemperature sensors(&oneWire); // oneWire to Dallas Temperature.
RTC_DS1307 RTC; // define the Real Time Clock object

const int chipSelect = 8; //CS pin of your data logger shield.Maybe not yours!!
File SlowG; //Name of the file

int stemp1 =0 ;
int stemp2 =0 ;
int stemp4 =0 ;
int stemp5 =0 ;
int stemp6 =0 ;
int n = 0;

int analogPin = 3; // potentiometer wiper (middle terminal) connected to analog pin 3
// outside leads to ground and +5V
int sol = 0;
int ssol = 0;

// Assign the addresses of your temp sensors.
//Every sensor has it own address.You must use 1 wire adress finder.

DeviceAddress T1 = { 0x28, 0x95, 0xA6, 0x50, 0x07, 0x00, 0x00, 0x49 };

DeviceAddress T2 = { 0x28, 0x8C, 0xB7, 0x50, 0x07, 0x00, 0x00, 0x35 };

DeviceAddress T4 = { 0x28, 0x94, 0x94, 0x50, 0x07, 0x00, 0x00, 0x79 };

DeviceAddress T5 = {0x28, 0xC9, 0x21, 0x31, 0x05, 0x00, 0x00, 0xD0 };

DeviceAddress T6 = { 0x28, 0x62, 0x3B, 0x31, 0x05, 0x00, 0x00, 0xB5 };

void setup()
{
pinMode(10 , OUTPUT); //For some data logger shields.Uncomment if you need

SD.begin(chipSelect); //Initialize the libraries
Wire.begin();
RTC.begin();
sensors.begin();

sensors.setResolution(T1, 12);
sensors.setResolution(T2, 12);
sensors.setResolution(T4, 12);
sensors.setResolution(T5, 12);
sensors.setResolution(T6, 12);

}

void loop()
{

sensors.requestTemperatures(); // Send the command to get temperatures

delay(50);
float temp1=sensors.getTempC(T1);
delay(50);
float temp2=sensors.getTempC(T2);
delay(50);
float temp4=sensors.getTempC(T4);
delay(50);
float temp5=sensors.getTempC(T5);
delay(50);
float temp6=sensors.getTempC(T6);
delay(50);

sol = analogRead(analogPin);
ssol = ssol + sol;

stemp1 = stemp1 + temp1;
stemp2 = stemp2 + temp2;
stemp4 = stemp4 + temp4;
stemp5 = stemp5 + temp5;
stemp6 = stemp6 + temp6;
n = n + 1;

DateTime now = RTC.now(); // Clock call
now = RTC.now();

int minut = now.minute();
int s = now.second();

if(minut % 10 == 0 && s < 5)

{

float gtemp1 = stemp1/n;
float gtemp2 = stemp2/n;
float gtemp4 = stemp4/n;
float gtemp5 = stemp5/n;
float gtemp6 = stemp6/n;

float gsol = ssol/n;

SlowG=SD.open(“SlowG.csv”,FILE_WRITE); // Print date and time

SlowG.println();

SlowG.print(now.unixtime());
SlowG.print(” ; “);
SlowG.print(now.day(), DEC);
SlowG.print(“-“);
SlowG.print(now.month(), DEC);
SlowG.print(“-18 “);
SlowG.print(now.hour(), DEC);
SlowG.print(“:”);
SlowG.print(now.minute(), DEC);
SlowG.print(” ; “);

SlowG.close(); //Save date and time

//sensors.requestTemperatures(); // Command all devices on bus to read temperature
SlowG=SD.open(“SlowG.csv”,FILE_WRITE);

SlowG.print(” “); //Print temp1
SlowG.print(temp1 ); //Print temp2
SlowG.print(” ; “); //Print temp1
SlowG.print(temp2 ); //Print temp2
SlowG.print(” ; “); //Print temp1
SlowG.print(temp4 ); //Print temp2
SlowG.print(” ; “); //Print temp1
SlowG.print(temp5 ); //Print temp2
SlowG.print(” ; “); //Print temp1
SlowG.print(temp6 ); //Print temp2
SlowG.print(” ; “); //Print temp1
SlowG.print(sol ); //Print temp2
SlowG.print(” ; “); //Print temp1
SlowG.print(n ); //Print temp2

SlowG.close(); //Print saved

stemp1 = 0;
stemp2 = 0;
stemp4 = 0;
stemp5 = 0;
stemp6 = 0;
ssol = 0;
n = 0;
delay(6000);
}
}

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *

This site uses Akismet to reduce spam. Learn how your comment data is processed.