Due timer for Flow meter

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
darkzues01
 
Posts: 2
Joined: Mon Nov 18, 2013 12:25 pm

Due timer for Flow meter

Post by darkzues01 »

I have been using a flow meter for a project. I was using the code adafruit supplied for the flow meter and everything worked fine when I was using it with the Arduino MEGA. However, I am switching over to the Arduino Due and the timer interrupts are different between the chip types. I have been trying to read and understand how to change this code to get it to work with no luck any help would be appreciated.

Code: Select all

#include "LiquidCrystal.h"
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 2

// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer; // in hertz
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
  }
}

void setup() {
   Serial.begin(9600);
   Serial.print("Flow sensor test!");
   lcd.begin(16, 2);
   
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
}

void loop() // run over and over again
{
  lcd.setCursor(0, 0);
  lcd.print("Pulses:"); lcd.print(pulses, DEC);
  lcd.print(" Hz:");
  lcd.print(flowrate);
  //lcd.print(flowrate);
  Serial.print("Freq: "); Serial.println(flowrate);
  Serial.print("Pulses: "); Serial.println(pulses, DEC);
  
  // if a plastic sensor use the following calculation
  // Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
  // Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
  // Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
  // Liters = Pulses / (7.5 * 60)
  float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;

/*
// if a brass sensor use the following calculation
float liters = pulses;
liters /= 8.1;
liters -= 6;
liters /= 60.0;
*/
  Serial.print(liters); Serial.println(" Liters");
  lcd.setCursor(0, 1);
  lcd.print(liters); lcd.print(" Liters ");
 
  delay(100);
}
The compiler errors out on the timer TIMER0_COMPA_VECT.

darkzues01
 
Posts: 2
Joined: Mon Nov 18, 2013 12:25 pm

Re: Due timer for Flow meter

Post by darkzues01 »

Figure it out.

Code: Select all


#define FLOWSENSORPIN 2

float literCount = 256;
float number = 256;
double f;

unsigned long lastTime;
int counter;

// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;

//TC1 ch 0
void TC3_Handler()
{  
   TC_GetStatus(TC1, 0);
   uint8_t x = digitalRead(FLOWSENSORPIN);
       
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    //Serial.println(lastflowratetimer);
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
    }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer; // in hertz
  lastflowratetimer = 0;
}

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
        pmc_set_writeprotect(false);
        pmc_enable_periph_clk((uint32_t)irq);
        TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
        uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above
        TC_SetRA(tc, channel, rc/2); //50% high, 50% low
        TC_SetRC(tc, channel, rc);
        TC_Start(tc, channel);
        tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
        tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
        NVIC_EnableIRQ(irq);
}

void setup(){
    Serial.begin(9600);
    startTimer(TC1, 0, TC3_IRQn, 1000); //TC1 channel 0, the IRQ for that channel and the desired frequency
    
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);

}

void loop(){
  
  float liters = pulses;
  liters = 33.814*(pulses/ (7.5*60));
  liters /= 12.7;
  
  Serial.println(pulses);
  Serial.println(liters);
  Serial.println(digitalRead(FLOWSENSORPIN));
  delay(100);
}

User avatar
Garygibson4285
 
Posts: 1
Joined: Sat Jan 02, 2016 8:37 pm

Re: Due timer for Flow meter

Post by Garygibson4285 »

The sketch works great by itself with my Arduino DUE. However, I can't get it to work when used as part of a larger sketch. I don't understand where to place the individual functions or calls.i.e. (void TC3_Handler(), void startTimer), and the such. I need to use it with a VB.net program where I use characters to call which routines to use located in the sketch. Please help and show me where the different pieces go! Thanks in advance.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”