Go Down

Topic: SD Card Logging + attachInterrupt Problem! (Read 1 time) previous topic - next topic

TCPR

Hello everyone,

I am trying to make a data logger to log a few sensors. It's everything working properly until I start logging data to the SD card.
The problem is that I have a Hall Effect sensor connected to the board using attachInterrupt() to calculate wheel speed, but when the SD card logging is on the reading go crazy.

I made a sketch to test just this issue, only hall sensor + sd card connected to the board with two different SD libraries and the problem still occurs.

This is an example of what I get when I put a magnet in front of the hall sensor, or even if I just pass it fast in front of the sensor like 1 or 2 times:

Quote
DATA, 318, 309, 311
DATA, 319, 311, 313
RPMcount: 227
DeltaT: 1640
V: 208.71
DATA, 320, 312, 314
RPMcount: 50
DeltaT: 554
V: 136.75
DATA, 318, 309, 311


Line DATA is what is being write to SD. In this sketch I'm not logging data from hall sensor if it matters.
RPMcount should always be equal 4!

Here is my simplified code:
Code: [Select]
#include <SD.h>

const int chipSelect = 51;

volatile byte rpmcount_D1 = 0;
unsigned long timeold_D1 = 0;
float rpm_D1 = 0, V_D1 = 0;
const int rodaD1 = 2;

void setup()
{
  Serial.begin(57600);
  Serial.print("Initializing SD card...");
//  pinMode(53, OUTPUT);
 
  if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); return; }
  Serial.println("card initialized.");
 
// Velocidade das Rodas ------------------------------------------------------
  pinMode(rodaD1,INPUT);
  attachInterrupt(0, rev_add, FALLING);
// Velocidade das Rodas ------------------------------------------------------

}

void loop()
{
 
// Bloco do Sensor Hall ------------------------------------------------
  if (rpmcount_D1 >= 4) {
    rpm_D1 = 6283.19 / (millis() - timeold_D1) * rpmcount_D1/4;
    V_D1 = rpm_D1 * 0.9576; // V [Km/h]
    Serial.print("RPMcount: "); Serial.println(rpmcount_D1, DEC);
    Serial.print("DeltaT: "); Serial.println((millis()-timeold_D1), DEC);
    rpmcount_D1 = 0; timeold_D1 = millis();
    Serial.print("V: ");Serial.println(V_D1);
  }
// Bloco do Sensor Hall -------------------------------------------------

    // make a string for assembling the data to log:
    String dataString = "";
    // read three sensors and append to the string:
   
    //dataString += String(tempo);
   dataString += "DATA";
    dataString += ", "; // Adiciona o tempo no inicio da String
    for (int analogPin = 0; analogPin < 3; analogPin++) {
      int sensor = analogRead(analogPin);
      dataString += String(sensor);
      if (analogPin < 2) { dataString += ", "; }
    }
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    // if the file is available, write to it:
    if (dataFile) {
      dataFile.println(dataString);
      dataFile.close();
      // print to the serial port too:
      Serial.println(dataString);
    } 
    // if the file isn't open, pop up an error:
    else { Serial.println("Error opening datalog.txt"); }
}

// Funcoes do Sensor Hall --------------------------------------
void rev_add() { rpmcount_D1++; }


Thanks for your help and sorry for my "engrish"!
Cheers!

leozhi

Hey, were you able to resolve this issue?

Nick_Pyner

Here is my simplified code:
[

It seems too simple - or incomplete. You do not seem to be establishing any time cycle.

This is an adaptation of the Jaycar water flow meter

Code: [Select]
/**
 * Water Flow Gauge
 *
 * Uses a hall-effect flow sensor to measure the rate of water flow
 * Copyright 2009 Jonathan Oxer <jon@oxer.com.au>
 * Copyright 2009 Hugh Blemings <hugh@blemings.org>
 *
 */

#include <LiquidCrystal_I2C.h>
#include "Wire.h"
#include <SD.h>
#define DS1307_ADDRESS 0x68
LiquidCrystal_I2C lcd(0x27,20,4);

File myFile;
char filename[] = "00000000.CSV";
#include "Wire.h"

byte sensorInterrupt = 0;  // 0 = pin 2; 1 = pin 3
byte sensorPin       = 2; //

// The flow sensor outputs approximately 4.5 Hz/litre/minute of flow.
float calibrationFactor = 9.0;

volatile byte pulseCount; 

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;

int  second, minute, hour, weekDay, monthDay, month, year;
int daily, maxflow, yesterday;

void setup()
{
   lcd.setCursor (0,0);
  lcd.print("Initializing");
  delay(2000);
  lcd.setCursor (0,1);

  pinMode(10, OUTPUT);

  if (!SD.begin(4))
  {
    lcd.print("failed!");
    delay (2000);
    return;
  }
  lcd.print("init. OK!");
  delay(2000);

  lcd.clear();
   
      lcd.setCursor(0, 0);
      lcd.print("Flow: ");
      lcd.setCursor(11, 0);   
      lcd.print("L/min");
     
      lcd.setCursor(0, 1);
      lcd.print("Total: ");
      lcd.setCursor(14, 1);   
      lcd.print("Litres");
     
      lcd.setCursor(0, 2);
      lcd.print("daily");     
      lcd.setCursor(14, 2);   
      lcd.print("Litres");
         
  // Initialize a serial connection for reporting values to the host

  // Set up the pair of counter reset buttons and activate internal pull-up resistors

  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount          = 0;
  flowRate            = 0.0;
  flowMilliLitres          = 0;
  totalMilliLitres         = 0;
  oldTime             = 0;

  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}

void loop()
{
  GetClock();
  if (hour == 6 && minute == 0 && second <2)
  {
    filewrite();
  }

  if((millis() - oldTime) > 1000)    // Only process counters once per second
  {
    // Disable the interrupt while calculating flow rate and sending the value to
    // the host
    detachInterrupt(sensorInterrupt);

    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;

    oldTime = millis();

    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then conv. to ml.
   flowMilliLitres = (flowRate / 60) * 1000;

    // Add the litres passed in this second to the cumulative total
    totalMilliLitres += flowMilliLitres;

    unsigned int frac;
     frac = (flowRate - int(flowRate)) * 10;

    lcd.setCursor(6, 0);

    if(int(flowRate) < 10)
    {
      lcd.print(" ");
    }
    lcd.print((int)flowRate);   // Print the integer part of the variable
    lcd.print('.');             // Print the decimal point
    lcd.print(frac, DEC) ;      // Print the fractional part of the variable
    lcd.setCursor(7, 1);
    lcd.print(int(totalMilliLitres / 1000));

    // Reset the pulse counter so we can start incrementing again
    pulseCount = 0;

    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
}

/**
 * Invoked by interrupt0 once per rotation of the hall-effect sensor. Interrupt
 * handlers should be kept as small as possible so they return quickly.
 */
void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

byte bcdToDec(byte val)  {
  // Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void GetClock(){
  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);

  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  monthDay = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

void filewrite() {
  daily=totalMilliLitres-yesterday;
  yesterday=totalMilliLitres; 
 
        myFile = SD.open(filename, FILE_WRITE);//<<<<<<<<<<<<< OPEN
  myFile.print(year);
  myFile.print(":");
  myFile.print(month);
  myFile.print(":");
  myFile.print(monthDay);
  myFile.print(",");

  myFile.print(int(daily / 1000));
  myFile.print(",");
  myFile.println(int(totalMilliLitres / 1000));
       myFile.close();//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLOSE
}


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy