Jasper Tavernier
Jasper Tavernier

Reputation: 37

Reading multiple sensors with different datatypes

I'm trying to read multiple sensors and saving all that data in one, singular, *.txt file. This is needed to enable it to analize and easily fill a database. But here is the catch, not all the sensors give int values, and as I learned the hard way, "String" gives to much unpredictable errors.

I want to read:

all saved as int
I also want to save

I tried to fill them into array but I'm overlooking something. Can someone please point me in the correct direction to make it work, that would help me alot!

For your interest, it should become a datalogger for a trailer for horses. So I get feedback about forces while driving and also the climate of the trailer and trigger camera and sound to monitor the animals (will be next step to livestream it and make it a IOT-system).

The code:

#include <SPI.h>

//SDcard
  #include <SD.h>
  Sd2Card card;
  SdVolume volume;
  SdFile root;
  const int chipSelect = 10;
  File DataFile;

// Multiplexer 16 kanalen CD74HC4067
  int pinS0 = 4;
  int pinS1 = 5;
  int pinS2 = 6;
  int pinS3 = 7;
  int pinSIG = A0;

//RTC
  #include "RTClib.h"
  RTC_DS1307 rtc;
  char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//Acelerometer
  int RawMin = 0;  // initialize minimum and maximum Raw Ranges for each axis
  int RawMax = 1023;

//DHT1&2
  #include <DHT.h>
  #define DHTPIN2 8 
  #define DHTTYPE2    DHT11     // DHT 11 or DHT22
  DHT dht2(DHTPIN2, DHTTYPE2);
  #define DHTPIN1 13 
  #define DHTTYPE1    DHT11     // DHT 11 or DHT22
  DHT dht1(DHTPIN1, DHTTYPE1);
 
//  uint32_t delayMS;

  int Temp2 = 0;
  int Hum2  = 0;
  int Temp1 = 0;
  int Hum1  = 0;
  
//LDR
  int LDRValue = 0;
  
//Sound
  int SoundValue=0;

//Camera
  unsigned long StartMillis;  //some global variables available anywhere in the program
  unsigned long CurrentMillis;
  const unsigned long Period = 10000;  //the value is a number of milliseconds
  byte Parameter = 0; //parameter for using multiple timer to have start and stop statement camer
  int Trigger = 9;
  String FilmStatus;
  
 //PIR
  int PIRValue = 0;                    // variable for reading the pin status

//Header print
  int Hoofding = 1;       //NOG TE Doen!! (if lus om header ook te printen op SD

//String declaration
    String  AccelString1,AccelString2, Header;
    //int Data[10];
//  String DataString,AccelString2, AccellString1, DHTString, FilmStatus;
 
 void setup() {
  //Start Serial monitor --> needs to be disabled to work on battery
    Serial.begin(9600);
     
    while (!Serial) {   // wait for serial port to connect. Needed for native USB port only ( against usb inconsistency)
      ; 
    }

  //Multiplexer
     pinMode(pinS0, OUTPUT); 
     pinMode(pinS1, OUTPUT); 
     pinMode(pinS2, OUTPUT); 
     pinMode(pinS3, OUTPUT);      
     
  //Start SD + basic check up + make file/ read file
     QcheckSD();
     DataFile = SD.open("DataFile.txt", FILE_WRITE);
  // if the file opened, write to it:
     if (DataFile) {
        Serial.println("Writing to DataFile.txt possible.");
        DataFile.close();  
     } else {
      // if the file didn't open, print an error:
        Serial.println("error opening DataFile.txt");
     }
     
  //start RTC
     checkRTC();
  //Check time RTC
     checkTime();

  //DHT start
     dht2.begin();
     dht1.begin();

  //Camera start background
    pinMode(Trigger, OUTPUT);
    digitalWrite(Trigger, LOW);
    delay (1000);

    StartMillis = millis();  //initial start time    

  //Stings
    AccelString1= String();
    AccelString2= String();
    FilmStatus= String();  
  
  //HEADER
    String Header=String("X1;Y1;Z1;X2;Y2;Z2;T1;H1;T2;H2;LDR;Sound;PIR;Millis;FilmStatus"); 
    Serial.println(Header);
  
   }

void loop() {
    
  //RTC
    DateTime now = rtc.now();
    
  //Acelerometer 1&2
    //Read raw values
     int xRaw2 = MUX(9);
     int yRaw2 = MUX(10);
     int zRaw2 = MUX(11);

    // Convert raw values to 'milli-Gs"
     long xScaled2 = map(xRaw2, RawMin, RawMax, -3000, 3000);
     long yScaled2 = map(yRaw2, RawMin, RawMax, -3000, 3000);
     long zScaled2 = map(zRaw2, RawMin, RawMax, -3000, 3000);

    // re-scale to fractional Gs
     float xAccel2 = xScaled2 / 1000.0; //used to be float
     float yAccel2 = yScaled2 / 1000.0;
     float zAccel2 = zScaled2 / 1000.0;

     AccelString2 = String(xAccel2+';'+ yAccel2+';'+ zAccel2);  
     
    //Read raw values
     int xRaw1 = MUX(1);
     int yRaw1 = MUX(2);
     int zRaw1 = MUX(3);

    // Convert raw values to 'milli-Gs"
     long xScaled1 = map(xRaw1, RawMin, RawMax, -3000, 3000);
     long yScaled1 = map(yRaw1, RawMin, RawMax, -3000, 3000);
     long zScaled1 = map(zRaw1, RawMin, RawMax, -3000, 3000);

    // re-scale to fractional Gs
     float xAccel1 = xScaled1 / 1000.0;
     float yAccel1 = yScaled1 / 1000.0;
     float zAccel1 = zScaled1 / 1000.0;

     String AccelString1 =String( xAccel1+';'+ yAccel1+';'+zAccel1);
     
  //DHT1&2
     Temp2= dht2.readTemperature();
     Hum2=  dht2.readHumidity();
     Temp1= dht1.readTemperature();
     Hum1=  dht1.readHumidity();

  //LDR reading
    LDRValue = analogRead (A3); //analog read van arduino omdat ander interferentie met mic!!!

  //Sound
    SoundValue= MUX(3);

  //Camera
    CurrentMillis = millis();
    if (Parameter==0)
    {
      digitalWrite(Trigger, HIGH);      
      delay(50);
      
      digitalWrite(Trigger, LOW);
      FilmStatus= String("StartTrigger");      
      Parameter=1;
    }
  
    if (CurrentMillis-StartMillis>=Period && Parameter==1)
    { 
      digitalWrite(Trigger, HIGH);    
      FilmStatus= String("EndTrigger"); 
      delay(50);
            
      digitalWrite(Trigger, LOW);   
      
      StartMillis=CurrentMillis;
      Parameter=0;
    }

  //PIR
    PIRValue = MUX(6);
  //Fill array
    int Data[8]={Temp1,Hum1,Temp2,Hum2,SoundValue,PIRValue,LDRValue,CurrentMillis};
    float FloatData[6]={xAccel1,yAccel1,zAccel1,xAccel2,yAccel2,zAccel2};
    String StringData[1]={FilmStatus};
  //File open en save to SD
    DataFile = SD.open("DataFile.txt", FILE_WRITE);

    for (byte i = 0; i <8 ; i = i + 1) {
      DataFile.print(Data[i]);
      DataFile.print(";");
      
      Serial.print(Data[i]);
      Serial.print(";");
    }
    for (byte i = 0; i <6 ; i = i + 1) {
      DataFile.print(FloatData[i]);
      DataFile.print(";");
      
      Serial.print(FloatData[i]);
      Serial.print(";");
    }

    DataFile.print(StringData[1]);
    Serial.print(StringData[1]);
    
    DataFile.println("EOF");
    Serial.println("EOF");
    DataFile.close();
     
  //delay (500);
    
}

void QcheckSD()
{
 Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done."); 
    
}

void checkRTC()
{
 
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
     abort();
   } else{
    Serial.println( "found RTC");
   }

   if (! rtc.isrunning()) {
       Serial.println("RTC is NOT running, let's set the time!");
       // When time needs to be set on a new device, or after a power loss, the
       // following line sets the RTC to the date & time this sketch was compiled
       rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
       // This line sets the RTC with an explicit date & time, for example to set
       // January 21, 2014 at 3am you would call:
       // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
   }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));

}

void checkTime()
{
  DateTime now = rtc.now();

    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
        
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();  
}
int MUX(int channel){
  // Define connection with arduino
  int MUXpin[] = {pinS0, pinS1, pinS2, pinS3};
  // Table of all combinations of pins 
  int channely[16][4]={
    {0,0,0,0},{1,0,0,0},{0,1,0,0},{1,1,0,0},{1,0,1,0},{0,1,1,0},{1,1,1,0},
    {0,0,0,1},{1,0,0,1},{0,1,0,1},{1,1,0,1},{0,0,1,1},{1,0,1,1},{0,1,1,1},{1,1,1,1}   // Kanaal 1-15
  };
  //Configuration of te control pin with a for loop
  for(int i = 0; i < 4; i ++){
    digitalWrite(MUXpin[i], channely[channel][i]);
  }
  // Reading of analogvalue of SIGpin
  int ValueSIG = analogRead(pinSIG);
  return ValueSIG;
}

Really appreciate your time, I know there is still some "junk" in the code from previous attempts to get it working. All suggestions are welcome, I'm eager to improve!

PS; if you need any hardwork specs let me know!

Upvotes: 0

Views: 555

Answers (1)

Dean Johnson
Dean Johnson

Reputation: 1852

Define a structure for the statistics you are trying to capture:

struct Stats {
    int temperature;
    int humidity;
    int lightIntensity;
    int sound;
    float accel; // This needs to be 6 floats I think?
    std::string text;
}

When you start reading data, instantiate one of these and populate it:

Stats s; // create
s.temperature = Mux(9); // Or however you read the values...
s.humidity = Mux(10);

Then create a function for printing a Stats object:

void printStats(const Stats& s) {
    // ... setup DataFile

    // Print values into file...
    DataFile.print(s.temperature);
    DataFile.print(";");
    DataFile.print(s.humidity);
    /// ... and so on
}

Upvotes: 2

Related Questions