Storing water flow values in a SD Card

Hi !

I’m trying to test a water flow sensor within my project station. It has a Eletrical painel with an Arduino controlling all the relays. The objective is to test if the flow sensor is well connected and if its online with arduino and painel. And obviously test how accurate the sensor is. I’ve seen many tutorials about coding for this sensor, which were really helpfull to me.

Then I modified it a little bit for my needs, so here it is :

#include <SD.h>
#include <SPI.h>

#include <Arduino.h>

#include <string.h>

File file;
float fatorCalibrador = 4.5;

volatile byte contaPulso;  

float taxaFluxo;
unsigned int fluxoML;
unsigned long totalML;

unsigned long oldTime;

void setup() {
  
  Serial.begin(9600);
  pinMode(CS_SD_PIN, OUTPUT);
  contaPulso        = 0;
  taxaFluxo          = 0.0;
  fluxoML   = 0;
  totalML  = 0;
  oldTime           = 0;

  pinMode(SENSOR_PIN, INPUT);
  // The sensor is connected to pin 2 which uses pin 0 for interrupts.
  // Sets the trigger when a FALLING change status is detected (from HIGH to LOW)
  attachInterrupt(0, contadorPulso, FALLING);
  
  if (!SD.begin(CS_SD_PIN)) {
    Serial.println("The card has failed to initialize"); 
    return;
  }
  
  pinMode(BOMBA_CAPTACAO_LIGA, OUTPUT);
  pinMode(BOMBA_CAPTACAO_DESLIGA, OUTPUT);
  pinMode(BOMBA_INJEC_LIGA, OUTPUT);
  pinMode(BOMBA_INJEC_DESLIGA, OUTPUT);
  pinMode(VALVULA_DESCARTE, OUTPUT);
  pinMode(PA_MISTURA_LIGA, OUTPUT);
  pinMode(PA_MISTURA_DESLIGA, OUTPUT);
  pinMode(SILO_1, OUTPUT);
  pinMode(SILO_2, OUTPUT);
  pinMode(VALVULA_L2, OUTPUT);
  pinMode(CONTRA_LAVAGEM, OUTPUT);
  pinMode(BOIA_INFERIOR, INPUT);
  pinMode(BOIA_SUPERIOR, INPUT);
  
  // ---------- Declarando o estado inicial de todos os pinos
  digitalWrite(BOMBA_CAPTACAO_DESLIGA, HIGH);
  digitalWrite(BOMBA_CAPTACAO_LIGA,LOW);
  delay(2000);
  
  
  digitalWrite(PINO_SENSOR_SILO, HIGH);
  delay(2000);
  digitalWrite(SILO_1,LOW);

void loop() {


 //Processar contadores apenas  uma vez por segundo
   if((millis() - oldTime) > 1000)    
  { 
    
    detachInterrupt(0);
        
    
    
    taxaFluxo = ((1000.0 / (millis() - oldTime)) * contaPulso) / fatorCalibrador;
    
    oldTime = millis();
    
   
    
    fluxoML = (taxaFluxo / 60) *1000;
    
    
    totalML += fluxoML;
      
    unsigned int fracao;
    
    file = SD.open("TESTE.cal", FILE_WRITE);
    
    if(file){
      
      file.print("Taxa de fluxo: ");
      file.print(int(taxaFluxo));
      file.print(".");
      
      
      fracao = (taxaFluxo - int(taxaFluxo)) * 10;
  
      file.print(fracao, DEC) ;      
      file.print("L/min");
  
      file.print("Taxa de Fluxo atual: ");             
      file.print(fluxoML);
      file.print("mL/Seg");
  
      
      file.print("Quantidade de líquido na saída: ");         
      file.print(totalML,DEC);
      file.println("mL"); 
      
    }
    
    
    contaPulso = 0;
    
    
    attachInterrupt(0, contadorPulso, FALLING);

      if(totalML>2000){
      digitalWrite(PINO_SENSOR_SILO,LOW);
      digitalWrite(SILO_1,HIGH);
      digitalWrite(SILO_2,HIGH);
      delay(1000);
      
      digitalWrite(BOMBA_CAPTACAO_DESLIGA, LOW);
      digitalWrite(BOMBA_CAPTACAO_LIGA,HIGH);
      file.close();
       
     } 
  }
  
  
 
}


void contadorPulso()
{
  
  contaPulso++;

So since i dont have an LCD display to check the values in real moment, I’m thought about writing them to the SD Card, when it reaches 2000mL it should shutt the solenoids off, and that’s not happening. Seems my code is messing within the loop function

What is the question?

Delta_G: What is the question?

Sorry I had to edit the post, there it is.

The code you posted won't even compile.

Before you post corrected code, put EVERY { on a line BY ITSELF. Do the same with the }. Use Tools + Auto Format to properly indent your code.

You should not be detaching and attaching the interrupt handler. Figure out what should not be interrupted, and disable and re-enable all interrupts before and after the critical code. That critical code does nothing more than copy some values.

PaulS:
The code you posted won’t even compile.

Which IDE are you using? It is compiling just fine here.

I’ve added some comments and also idented the code, please consider this :

#include <SD.h>
#include <SPI.h>

#include <Arduino.h>

#include <string.h>

#include "DefinicoesGlobais.h"

File file;
float fatorCalibrador = 4.5;

volatile byte contaPulso;

float taxaFluxo;
unsigned int fluxoML;
unsigned long totalML;

unsigned long oldTime;


void setup() {

  Serial.begin(9600);
  pinMode(SD_CS_PIN, OUTPUT);
  contaPulso        = 0;
  taxaFluxo          = 0.0;
  fluxoML   = 0;
  totalML  = 0;
  oldTime           = 0;

  pinMode(2, INPUT);
  // The sensor is connected to pin 2 which uses pin 0 for interrupts.
  // Sets the trigger when FALLING change is detected (from HIGH to LOW).
  attachInterrupt(0, contadorPulso, FALLING);

  if (!SD.begin(CS_SD_PIN)) {
    Serial.println("The card has failed to initialize");
    return;
  }

  pinMode(BOMBA_CAPTACAO_LIGA, OUTPUT);
  pinMode(BOMBA_CAPTACAO_DESLIGA, OUTPUT);
  pinMode(BOMBA_INJEC_LIGA, OUTPUT);
  pinMode(BOMBA_INJEC_DESLIGA, OUTPUT);
  pinMode(VALVULA_DESCARTE, OUTPUT);
  pinMode(PA_MISTURA_LIGA, OUTPUT);
  pinMode(PA_MISTURA_DESLIGA, OUTPUT);
  pinMode(SILO_1, OUTPUT);
  pinMode(SILO_2, OUTPUT);
  pinMode(VALVULA_L2, OUTPUT);
  pinMode(CONTRA_LAVAGEM, OUTPUT);
  pinMode(BOIA_INFERIOR, INPUT);
  pinMode(BOIA_SUPERIOR, INPUT);

  digitalWrite(BOMBA_CAPTACAO_DESLIGA, HIGH);
  digitalWrite(BOMBA_CAPTACAO_LIGA, LOW);
  delay(2000);

  digitalWrite(PINO_SENSOR_SILO, HIGH);
  delay(2000);
  digitalWrite(SILO_1, LOW);

}


void loop() {


  //Process the counters once per second
  if ((millis() - oldTime) > 1000)
  {
    // Disables the interrupt while flow tax is being calculated.
    detachInterrupt(0);

    taxaFluxo = ((1000.0 / (millis() - oldTime)) * contaPulso) / fatorCalibrador;

    oldTime = millis();

    fluxoML = (taxaFluxo / 60) * 1000;

    //Adds the amount of mL in this very second to the total amount.
    totalML += fluxoML;

    unsigned int fracao;

    file = SD.open("TESTE.cal", FILE_WRITE);

    if (file) {

      file.print("Flow tax: ");
      file.print(int(taxaFluxo));
      file.print(".");

      //Determina a parte fracionaria. a Multiplicação por 10 nos dá o primeiro decimal.
      fracao = (taxaFluxo - int(taxaFluxo)) * 10;

      file.print(fracao, DEC) ;
      file.print("L/min");

      file.print("Present Flow tax: ");
      file.print(fluxoML);
      file.print("mL/Seg");

      // Shows the total and cumulative amount of water flown since the beggining.
      file.print("Total amount : ");
      file.print(totalML, DEC);
      file.println("mL");

    }

    // Resets the counter so we can increment again.
    contaPulso = 0;

    // Enables the interrupt  again, sice we've sent the output data.
    attachInterrupt(0, contadorPulso, FALLING);

    if (totalML > 2000) {
      digitalWrite(PINO_SENSOR_SILO, LOW);
      digitalWrite(SILO_1, HIGH);
      digitalWrite(SILO_2, HIGH);
      delay(1000);

      digitalWrite(BOMBA_CAPTACAO_DESLIGA, LOW);
      digitalWrite(BOMBA_CAPTACAO_LIGA, HIGH);
      file.close();

    }
  }



}


void contadorPulso()
{
  // Incremento do contador de pulso.
  contaPulso++;
}

Thanks !

The code as posted in the first post will not compile on any version. You're missing some braces. I notice there's no closing brace on setup. Perhaps you didn't copy what you have in the IDE right, but as posted it wouldn't compile.

You are still improperly attaching and detaching the interrupt handler.

Also, look at the code involved with opening, writing to, and closing the file. You open the file, and write to it. Then, only if the value in totalML is greater than 2000, you close the file. That is just NOT right.

PaulS: You are still improperly attaching and detaching the interrupt handler.

I'm a beginner with this. I simply followed the tutorial I've seen in internet and made no changes in the interrupt matter, when you say I'm not using them properly I have no idea what to change, should I use them or not?

PaulS: Also, look at the code involved with opening, writing to, and closing the file. You open the file, and write to it. Then, only if the value in totalML is greater than 2000, you close the file. That is just NOT right.

Since I'm measuring the water flow and printing the values in the SD Card, why is this wrong? Should I close the file everytime a value is written then? I apreciate you will to help, yet I'm a bit lost :confused:

Should I close the file everytime a value is written then?

You should close the file every time you open it.

PaulS: You should close the file every time you open it.

Did you understand what I' trying to do ? The idea is to open the file once, write the values within it(until volume is lower than 2000) and close. If that's not right, I should open and close the file for each value ( this seems wrong to me by the way). I really can't figure how to manage this as you are suggesting.

I could add a file.close() command in the if (arquivo) loop.. right after the prints, line 109. But as I said, this seems wrong to me, do you agree?

The idea is to open the file once, write the values within it(until volume is lower than 2000) and close.

So, one open, one close. That IS closing the file every time you open it. You MUST do both together.