Movement related to temperature

cattledog:
The DHT22 Temperature/Humidity sensor is not a device which communicates over the i2c bus. It has its own communication protocol which is used by the Arduino library for the sensor.

Reading the data sheets and doing Google searches about devices you want to use will be a good practice to develop.

Thank you, I did a Google search on the product number and data sheet and I got the info I needed. I see where each of them list i2c for their communication format. Also checked and learned you can have up to 127 i2c slaves.

Well I have all my sensors up and working but logging the data has been kicking my butt. There is a file I need off of Henning Karlsen website but the site is down DS3231 - Rinky-Dink Electronics is there any chance someone may have the file I need for the DS3231 and the Datalogger shield?

For the DS3231 I strongly recommend that you use Jack Christensen's library DS3232RTC.h. It works for the DS3231 and integrates perfectly with the Time Library. It is available through the library manager.

But my problem is with logging the data not the clock.

I'm also getting this error and I don't understand because I have the DHT.h file installed

Arduino: 1.8.5 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Users\Jeffs64\Downloads\FTWOQI2IYGFM1SH\FTWOQI2IYGFM1SH.ino:1:17: fatal error: dht.h: No such file or directory

#include <dht.h>

^

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.
Invalid library found in C:\Users\Jeffs64\Documents\Arduino\libraries\Arduino-Library-master: C:\Users\Jeffs64\Documents\Arduino\libraries\Arduino-Library-master
Invalid library found in C:\Users\Jeffs64\Documents\Arduino\libraries\doc: C:\Users\Jeffs64\Documents\Arduino\libraries\doc

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Please post the code which is giving the errors, and post the complete error message.

But my problem is with logging the data not the clock.

Please explain more. Are you using OpenLog, or the SD card module with SPI which use SD.h or SdFat.h?

I strongly recommend OpenLog for logging.

You don't have to to any extra programming at all -- it just records what you send out the serial port, using Serial.print() commands.

I'm using a Micro-SD-Storage-Board-SD-TF-Card-Memory-Shield-Module-SPI-For-Arduino-N30 (pic attached)

#include <dht.h>
dht DHT;
#define DHT11_PIN 7
#include <SD.h>                                  //The libraries we need
#include <SPI.h>
#include <Wire.h>

const int chipSelect = 8;                        //Maybe not yours!!.You have to put your cs pin here

File Datos;

void setup()
{
  Serial.begin(9600);
  SD.begin(chipSelect);


  Datos = SD.open("Datos.csv", FILE_WRITE);        //Will open and write once just for headers
  Datos.println("Tempeture,  Humidity,    Dewpoint");       //Print headers (not saved yet)
  Datos.close();                                   //Print saved

}

void loop()
{
  int chk = DHT.read11(DHT11_PIN);
  Serial.print("Temperature = ");
  Serial.print(DHT.temperature);
  Serial.print("*C");
  Serial.println();
  Serial.print("Humidity = ");
  Serial.print(DHT.humidity);
  Serial.print("%");
  Serial.println();
  double gamma = log(DHT.humidity / 100) + ((17.62 * DHT.temperature) / (243.5 + DHT.temperature));
  double dp = 243.5 * gamma / (17.62 - gamma);

  Serial.print("Dew point = ");
  Serial.print(dp);
  Serial.print(" *Celcius ");
  Serial.println();
  Datos = SD.open("Datos.csv", FILE_WRITE);       //Will open and write according to delay
  Datos.print(DHT.temperature);    //Print mesage(not saved yet)

  Datos.print(DHT.humidity);    //Print mesage(not saved yet)

  Datos.print(dp);    //Print mesage(not saved yet)

  Datos.println("");
  Datos.close();



  delay(1000);
}

It is a bad idea to open and close the SD file every time you pass through loop().

Open it once in setup, then close it when you are finished logging. If the power fails before you have a chance to close the file, you will lose at most the last couple of output records.

Where would I find information about how to turn this into a string so I don't have to have so many lines of code

    DateTime now = rtc.now();
    sdFile.print(now.month(), DEC);
    sdFile.print('/');
    sdFile.print(now.day(), DEC);
    sdFile.print('/');
    sdFile.print(now.year(), DEC);
    sdFile.print("  ");
    sdFile.print(now.hour(), DEC);
    sdFile.print(':');
    sdFile.print(now.minute(), DEC);
    sdFile.print(':');
    sdFile.print(now.second(), DEC);
    sdFile.println();
    delay(10000);   
    sdFile.close(); // close the file

Use the sprintf() function.

could you give me an example of what it would look like? I've looked it up online and i don't understand how it is used

Google "sprintf() examples", and get this, for one.

I did read that but not sure if I'm understanding correctly, would this code be correct?

// Example program to demonstrate sprintf()
#include<stdio.h>
int main()
{
    char buffer[50];
    int a = now.day, b = now.month, c= now.year;
    
    sprintf(buffer, "%d , %d , %d", a, b, c);
 
    // The string "Day, Month, Year" is stored 
    // into buffer instead of printing on stdout
    printf("%s", buffer);
 
    return 0;
}
[code\]

On Arduino, you would use Serial.println(buffer) instead of printf(), to display the result on the serial monitor.

Try something like this (you will have to add all required the RTC and/or TimeLib.h stuff):

void setup() {
    char buffer[50];
    Serial.begin(9600); //correct rate needed here
    sprintf(buffer, "%d , %d , %d", now.day(), now.month(), now.year());
    Serial.println(buffer);
}
void loop(){}

sprintf() does all sorts of handy things, for example %0d adds leading zeros, which is nice for time and date.

jremington:
On Arduino, you would use Serial.println(buffer) instead of printf(), to display the result on the serial monitor.

Try something like this (you will have to add all required the RTC and/or TimeLib.h stuff):

void setup() {

char buffer[50];
    Serial.begin(9600); //correct rate needed here
    sprintf(buffer, "%d , %d , %d", now.day(), now.month(), now.year());
    Serial.println(buffer);
}
void loop(){}




sprintf() does all sorts of handy things, for example %0d adds leading zeros, which is nice for time and date.

Thank you.

The good news is all sensors are up and running and all the data is being logged so I can read it in Excel. Next I need to work on getting the dial indicator connected and logging its output. I plan on doing that on a seperate board and testing it until I get it working correctly. Then I will add it to the main board and test some more. I will also need to do a lot of work cleaning up my sloppy coding.

I found this code for reading my dial indicator and it works almost great. My problem is that I can not add a delay function without messing up the serial display, it starts displaying random numbers. But if I let it scroll without a delay the readings are fine. Is there a way to get a reading every 5 minutes without breaking the current code?

//https://forum.arduino.cc/index.php?topic=8472.0
//indicator_3 K. Warner 10/29/10
//
//This Arduino code takes a 24 bit serial data stream from a CenTech (Harbor Freight) #93295 
//dial indicator and inverts it to ASCII on the serial port.  The encoder uses a 1.55V watch
//battery with its positive terminal grounded; HIGH is 0V and LOW is about 1.3V.  To trigger the 
//digital inputs on 5V logic the clock and data outputs are buffered with pullup transistors.  The 
//code and description are written with reference to the pulse streams as observed on an 
//oscilloscope connected to the buffer outputs, which are connected to digital inputs on an 
//Arduino Uno board; HIGH is 5V and LOW is 0V.
//
//The clock is connected to digital pin 2, which is used as interrupt 0; it has the form 
//    H560/L220/H560/L220/H560/L220/H560/L1000...repeat 6 times.../L280000/...
//with units in microseconds.  (Values are approximate.) The data output is connected to pin 3,
//and is inverted (NOT 2's complement, as some other indicator outputs are encoded).  The data
//has the form
//    L340/Bit0 440/L340/Bit1 440/L340/Bit2 440/L340/Bit3 1200/...6X.../L290000/...
//thus, the bits are read when the clock goes low.  The data has the form
//    B0...B11 - binary value of dial readout, inverted
//    B12..B19 - not used
//    B20 - sign bit ('-' is high, '+' is low)
//    B21..B22 - not used
//    B23 - units bit ('in' is high, 'mm' is low)
//
//NOTE THAT THIS ROUTINE HAS BEEN WRITTEN FOR A SPECIFIC INDICATOR.  The term "SPC output" is used
//by various manufacturers to describe a data output that can be used for process control (I take 
//"SPC" to mean "statistical process control" but there may be another meaning); in any event the 
//term DOES NOT describe a standard protocol.  Others have decoded outputs from Mitotoyo, Starrett,
//and generic (primarily Chinese) tools;  as far as can tell from a web search no one has posted a
//translator for this particular indicator.  I also do not know if it would work with other "CenTech"
//tools.
//
//

//Global declarations
volatile long valout=0;  //valout is a 32 bit long integer that will contain the 24 bit data
volatile int n=0;  //n is a pointer for the 24 data bits in valout
word value=0;  //value will contain the binary value of the 12 bit data
char sign='+';  //the data sign
String unit="xxx";  //the units string
float unit_div=1;  //the scale factor for mm or in
int unit_plcs=1;  //the number of places to the right of the dp to display
float val_final=0;  //the final value to be displayed, as a floating point number which takes care of the dp position

//Initial settings and start interrupt
void setup()
{
  Serial.begin(9600);  //set com to 9600 baud
  pinMode(2,INPUT);  //Set the pins to input; actually this is the default
  pinMode(3,INPUT);
  attachInterrupt(0,clk,FALLING);  //Set the interrupt to read the data pin when the clock goes low
}

//Read the bits returned from the interrupt, convert and send the data out; loop continuously
void loop()

{
  
  while (n!=23);  //this is a critical step - loop while the pointer is not equal to 23
  //- the pointer increments during the interrupt to a total of 24 bits
  if (bitRead(valout,20)==HIGH)  //Read the sign bit (bit 20)
  { 
    sign='-';
  } 
  else 
  {
    sign='+';
  }
  if (bitRead(valout,23)==HIGH)  //Read the units bit (bit 23)
  { 
    unit = " in";
    unit_plcs = 4;
    unit_div = 2000;
  } 
  else 
  {
    unit = " mm";
    unit_plcs = 2;
    unit_div = 100;
  }
  for (int m=0; m<=11; m++)  //Read the first 12 bits of valout to get the actual value
  {
    bitWrite(value,m,bitRead(valout,m));
  }
  val_final=float(value)/unit_div;  //scale the data as determined by the units
  Serial.print(sign);  //print the sign
  Serial.print(val_final,unit_plcs);  //print the value
  Serial.println(unit);  //print the unit type
  n=0;  //reset the bit pointer
   
}

//The interrupt handler - on the falling edge of each clock pulse, read the corresponding data bit
void clk()   
{
  bitWrite(valout,n,!digitalRead(3));   //Read the data bit and write its inverse to the n bit in valout
  n=n+1;  //increment the pointer
}

I think the issue with this dial indicator reading code, is that there is no synchronization between the reading, and the start and stop of the data stream. I think the reading process needs to begin after the long low period between cycles is detected. I have used a CHANGE interrupt to sense any long period between edges.

Here's an attempt to modify the code so that the reading is synchronized with the data stream. It can be optimized with register level commands if it actually works. There are some issues with how the code is handling the data from the interrupt, but if it currently is working, that can be addressed later. I also think the code can be changed from a blocking while(n!=23) to a non blocking if(n==23) structure.

This revision compiles. Surprise me and tell me it actually reads the indicator :slight_smile:

//https://forum.arduino.cc/index.php?topic=8472.0
//indicator_3 K. Warner 10/29/10
//
//This Arduino code takes a 24 bit serial data stream from a CenTech (Harbor Freight) #93295 
//dial indicator and inverts it to ASCII on the serial port.  The encoder uses a 1.55V watch
//battery with its positive terminal grounded; HIGH is 0V and LOW is about 1.3V.  To trigger the 
//digital inputs on 5V logic the clock and data outputs are buffered with pullup transistors.  The 
//code and description are written with reference to the pulse streams as observed on an 
//oscilloscope connected to the buffer outputs, which are connected to digital inputs on an 
//Arduino Uno board; HIGH is 5V and LOW is 0V.
//
//The clock is connected to digital pin 2, which is used as interrupt 0; it has the form 
//    H560/L220/H560/L220/H560/L220/H560/L1000...repeat 6 times.../L280000/...
//with units in microseconds.  (Values are approximate.) The data output is connected to pin 3,
//and is inverted (NOT 2's complement, as some other indicator outputs are encoded).  The data
//has the form
//    L340/Bit0 440/L340/Bit1 440/L340/Bit2 440/L340/Bit3 1200/...6X.../L290000/...
//thus, the bits are read when the clock goes low.  The data has the form
//    B0...B11 - binary value of dial readout, inverted
//    B12..B19 - not used
//    B20 - sign bit ('-' is high, '+' is low)
//    B21..B22 - not used
//    B23 - units bit ('in' is high, 'mm' is low)
//
//NOTE THAT THIS ROUTINE HAS BEEN WRITTEN FOR A SPECIFIC INDICATOR.  The term "SPC output" is used
//by various manufacturers to describe a data output that can be used for process control (I take 
//"SPC" to mean "statistical process control" but there may be another meaning); in any event the 
//term DOES NOT describe a standard protocol.  Others have decoded outputs from Mitotoyo, Starrett,
//and generic (primarily Chinese) tools;  as far as can tell from a web search no one has posted a
//translator for this particular indicator.  I also do not know if it would work with other "CenTech"
//tools.
//
//
//New Declarations for CHANGE interrupt
volatile unsigned long triggered = micros();
volatile unsigned long lastTriggered = triggered;
volatile unsigned long period = 0;
volatile boolean synch = false;

//Global declarations
volatile long valout=0;  //valout is a 32 bit long integer that will contain the 24 bit data
volatile int n=0;  //n is a pointer for the 24 data bits in valout
word value=0;  //value will contain the binary value of the 12 bit data
char sign='+';  //the data sign
String unit="xxx";  //the units string
float unit_div=1;  //the scale factor for mm or in
int unit_plcs=1;  //the number of places to the right of the dp to display
float val_final=0;  //the final value to be displayed, as a floating point number which takes care of the dp position

//Initial settings and start interrupt
void setup()
{
  Serial.begin(9600);  //set com to 9600 baud
  pinMode(2,INPUT);  //Set the pins to input; actually this is the default
  pinMode(3,INPUT);
  //attachInterrupt(0,clk,FALLING);  //Set the interrupt to read the data pin when the clock goes low
  attachInterrupt(0,clk,CHANGE); //use CHANGE interrupt to detect extended LOW period
}

//Read the bits returned from the interrupt, convert and send the data out; loop continuously
void loop()

{
  
  while (n!=23);  //this is a critical step - loop while the pointer is not equal to 23
  //- the pointer increments during the interrupt to a total of 24 bits
  
  if (bitRead(valout,20)==HIGH)  //Read the sign bit (bit 20)
  { 
    sign='-';
  } 
  else 
  {
    sign='+';
  }
  if (bitRead(valout,23)==HIGH)  //Read the units bit (bit 23)
  { 
    unit = " in";
    unit_plcs = 4;
    unit_div = 2000;
  } 
  else 
  {
    unit = " mm";
    unit_plcs = 2;
    unit_div = 100;
  }
  for (int m=0; m<=11; m++)  //Read the first 12 bits of valout to get the actual value
  {
    bitWrite(value,m,bitRead(valout,m));
  }
  val_final=float(value)/unit_div;  //scale the data as determined by the units
  Serial.print(sign);  //print the sign
  Serial.print(val_final,unit_plcs);  //print the value
  Serial.println(unit);  //print the unit type
  
  noInterrupts();
  n=0;  //reset the bit pointer
  synch = false;
  valout= 0;
  triggered = micros();
  lastTriggered = triggered;
  interrupts();
   
}

//The interrupt handler - on the falling edge of each clock pulse, read the corresponding data bit
/*void clk()   
{
  bitWrite(valout,n,!digitalRead(3));   //Read the data bit and write its inverse to the n bit in valout
  n=n+1;  //increment the pointer
}
*/

void clk()
{

  triggered = micros();
  period = triggered - lastTriggered;
  lastTriggered = triggered;

  if (period >= 250000) //try extending this value?
  {
    synch = true;
  }

  if (synch)
  {
    if (digitalRead(2) == LOW) //respond only to falling edges after synch
    { 
      bitWrite(valout, n, !digitalRead(3)); //Read the data bit and write its inverse to the n bit in valout
      n = n + 1; //increment the pointer
    }
  }
}

cattledog:
I think the issue with this dial indicator reading code, is that there is no synchronization between the reading, and the start and stop of the data stream. I think the reading process needs to begin after the long low period between cycles is detected. I have used a CHANGE interrupt to sense any long period between edges.

Here's an attempt to modify the code so that the reading is synchronized with the data stream. It can be optimized with register level commands if it actually works. There are some issues with how the code is handling the data from the interrupt, but if it currently is working, that can be addressed later. I also think the code can be changed from a blocking while(n!=23) to a non blocking if(n==23) structure.

This revision compiles. Surprise me and tell me it actually reads the indicator :slight_smile:

//https://forum.arduino.cc/index.php?topic=8472.0

//indicator_3 K. Warner 10/29/10
//
//This Arduino code takes a 24 bit serial data stream from a CenTech (Harbor Freight) #93295
//dial indicator and inverts it to ASCII on the serial port.  The encoder uses a 1.55V watch
//battery with its positive terminal grounded; HIGH is 0V and LOW is about 1.3V.  To trigger the
//digital inputs on 5V logic the clock and data outputs are buffered with pullup transistors.  The
//code and description are written with reference to the pulse streams as observed on an
//oscilloscope connected to the buffer outputs, which are connected to digital inputs on an
//Arduino Uno board; HIGH is 5V and LOW is 0V.
//
//The clock is connected to digital pin 2, which is used as interrupt 0; it has the form
//    H560/L220/H560/L220/H560/L220/H560/L1000...repeat 6 times.../L280000/...
//with units in microseconds.  (Values are approximate.) The data output is connected to pin 3,
//and is inverted (NOT 2's complement, as some other indicator outputs are encoded).  The data
//has the form
//    L340/Bit0 440/L340/Bit1 440/L340/Bit2 440/L340/Bit3 1200/...6X.../L290000/...
//thus, the bits are read when the clock goes low.  The data has the form
//    B0...B11 - binary value of dial readout, inverted
//    B12..B19 - not used
//    B20 - sign bit ('-' is high, '+' is low)
//    B21..B22 - not used
//    B23 - units bit ('in' is high, 'mm' is low)
//
//NOTE THAT THIS ROUTINE HAS BEEN WRITTEN FOR A SPECIFIC INDICATOR.  The term "SPC output" is used
//by various manufacturers to describe a data output that can be used for process control (I take
//"SPC" to mean "statistical process control" but there may be another meaning); in any event the
//term DOES NOT describe a standard protocol.  Others have decoded outputs from Mitotoyo, Starrett,
//and generic (primarily Chinese) tools;  as far as can tell from a web search no one has posted a
//translator for this particular indicator.  I also do not know if it would work with other "CenTech"
//tools.
//
//
//New Declarations for CHANGE interrupt
volatile unsigned long triggered = micros();
volatile unsigned long lastTriggered = triggered;
volatile unsigned long period = 0;
volatile boolean synch = false;

//Global declarations
volatile long valout=0;  //valout is a 32 bit long integer that will contain the 24 bit data
volatile int n=0;  //n is a pointer for the 24 data bits in valout
word value=0;  //value will contain the binary value of the 12 bit data
char sign='+';  //the data sign
String unit="xxx";  //the units string
float unit_div=1;  //the scale factor for mm or in
int unit_plcs=1;  //the number of places to the right of the dp to display
float val_final=0;  //the final value to be displayed, as a floating point number which takes care of the dp position

//Initial settings and start interrupt
void setup()
{
  Serial.begin(9600);  //set com to 9600 baud
  pinMode(2,INPUT);  //Set the pins to input; actually this is the default
  pinMode(3,INPUT);
  //attachInterrupt(0,clk,FALLING);  //Set the interrupt to read the data pin when the clock goes low
  attachInterrupt(0,clk,CHANGE); //use CHANGE interrupt to detect extended LOW period
}

//Read the bits returned from the interrupt, convert and send the data out; loop continuously
void loop()

{
 
  while (n!=23);  //this is a critical step - loop while the pointer is not equal to 23
  //- the pointer increments during the interrupt to a total of 24 bits
 
  if (bitRead(valout,20)==HIGH)  //Read the sign bit (bit 20)
  {
    sign='-';
  }
  else
  {
    sign='+';
  }
  if (bitRead(valout,23)==HIGH)  //Read the units bit (bit 23)
  {
    unit = " in";
    unit_plcs = 4;
    unit_div = 2000;
  }
  else
  {
    unit = " mm";
    unit_plcs = 2;
    unit_div = 100;
  }
  for (int m=0; m<=11; m++)  //Read the first 12 bits of valout to get the actual value
  {
    bitWrite(value,m,bitRead(valout,m));
  }
  val_final=float(value)/unit_div;  //scale the data as determined by the units
  Serial.print(sign);  //print the sign
  Serial.print(val_final,unit_plcs);  //print the value
  Serial.println(unit);  //print the unit type
 
  noInterrupts();
  n=0;  //reset the bit pointer
  synch = false;
  valout= 0;
  triggered = micros();
  lastTriggered = triggered;
  interrupts();
 
}

//The interrupt handler - on the falling edge of each clock pulse, read the corresponding data bit
/*void clk() 
{
  bitWrite(valout,n,!digitalRead(3));  //Read the data bit and write its inverse to the n bit in valout
  n=n+1;  //increment the pointer
}
*/

void clk()
{

triggered = micros();
  period = triggered - lastTriggered;
  lastTriggered = triggered;

if (period >= 250000) //try extending this value?
  {
    synch = true;
  }

if (synch)
  {
    if (digitalRead(2) == LOW) //respond only to falling edges after synch
    {
      bitWrite(valout, n, !digitalRead(3)); //Read the data bit and write its inverse to the n bit in valout
      n = n + 1; //increment the pointer
    }
  }
}

Really wish it would have worked but I'm afraid nothing displayed in the serial monitor. Thanks for trying

I figured it out. I put the delay before the serial.print and now everything is working correctly.
5/16/2018 15:53:20
Humidity: 41.50 [%] Temp: 75.92 [F]
+0.19 mm

The delay function is throwing in an error every now and then so I tried the millis() function but I am having a small problem.
When I use int period = 10000; up to 30000 it works but when I try and go 40000 or above it stops working. Even in this sample code it stops after 30000
What am I doing wrong or missing?

int period = 40000;
unsigned long time_now = 0;
 
void setup() {
    Serial.begin(115200);
}
 
void loop() {
    time_now = millis();
   
    Serial.println("Hello");
   
    while(millis() < time_now + period){
        //wait approx. [period] ms
    }
}