#include <LiquidCrystal.h>
#include <Adafruit_NeoPixel.h>

volatile int flow_frequency; // Measures flow sensor pulses

// Calculated litres/hour

float vol = 0.0,l_minute;

unsigned char flowsensor = 2; // Sensor Input

unsigned long currentTime;

unsigned long cloopTime;

LiquidCrystal lcd(12, 11, 5, 4, 3, 9);

// Time
signed short seconds, minutes;

char timeline[16];

// LED ring
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 13, NEO_GRB + NEO_KHZ800);

int nextLED = 40 - (40/24);
int nextLEDindex = 23;

// buzzer
const int buzzer = 9;

int nextTone = 1;

void flow () // Interrupt function
{

   flow_frequency++;

}

void setup()
{

   pinMode(flowsensor, INPUT);

   digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up

   Serial.begin(9600);

   lcd.begin(20, 4);

   attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING); // Setup Interrupt

   lcd.clear();

   lcd.setCursor(0,0);

   lcd.print("Water Flow Meter");

   currentTime = millis();

   cloopTime = currentTime;

   // LED ring starts with all lights green
   strip.begin();
   strip.setBrightness(150); //adjust brightness here
   colorWipe(strip.Color(0, 255, 0), 50); // Green

   // buzzer
   pinMode(buzzer, OUTPUT);

}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {

      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

// Delete light after time goes: every 40/24 one gets deleted
void deleteLight(int index) {
  strip.setPixelColor(index, strip.Color(0,0,0));
  if (index == 12) {
    for (int i = 0; i < index; i++) {
      strip.setPixelColor(index, strip.Color(255,255,0));
    }
  }
  if (index == 6) {
    for (int i = 0; i < index; i++) {
      strip.setPixelColor(index, strip.Color(255,0,0));
    }
  }
  strip.show();
}

void loop ()
{

   currentTime = millis();

   // Every second, calculate and print litres/hour

   if(currentTime >= (cloopTime + 1000))
   {

    cloopTime = currentTime; // Updates cloopTime

    if(flow_frequency != 0){
      Serial.println(" flow rate = 1 ");
      // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.

      l_minute = (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour

      lcd.clear();

      lcd.setCursor(0,0);

      lcd.print("Water Flow Meter");

      lcd.setCursor(0,1);

      l_minute = l_minute/60;

      vol = vol +l_minute;

      lcd.print("Vol:");

      lcd.print(vol);

      lcd.print(" L");

      flow_frequency = 0; // Reset Counter

      Serial.print(l_minute, DEC); // Print litres/hour

      Serial.println(" L/Sec");

      seconds++;
      if (seconds == 60) {
        seconds = 0;
        minutes++;
      }

      lcd.setCursor(0,2);

      sprintf(timeline,"%0.2d min %0.2d sec", minutes, seconds);
      lcd.print("Time: ");
      lcd.print(timeline);

      // turn led off if necessary
      if (vol <= nextLED && nextLEDindex >= 0) {
        deleteLight(nextLEDindex);
        nextLED = nextLED - 40/24;
        nextLEDindex = nextLEDindex - 1;
      } 

      // if one liter spent, make sound
      if (vol >= nextTone) {
        tone(buzzer, 1000);
        nextTone++;
      }
      else {
        noTone(buzzer);
      }

    }

    else {
      Serial.println(" flow rate = 0 ");

      lcd.clear();

      lcd.setCursor(0,0);

      lcd.print("Water Flow Meter");

      lcd.setCursor(0,1);

      lcd.print("Vol:");

      lcd.print(vol);

      lcd.print(" L");

      seconds++;
      if (seconds == 60) {
        seconds = 0;
        minutes++;
      }

      sprintf(timeline,"%0.2d min %0.2d sec", minutes, seconds);
      lcd.setCursor(0, 2);
      lcd.print("Time: ");
      lcd.print(timeline);

    }

   }

}

uno1:A5.2
uno1:A4.2
uno1:AREF
uno1:GND.1
uno1:13
uno1:12
uno1:11
uno1:10
uno1:9
uno1:8
uno1:7
uno1:6
uno1:5
uno1:4
uno1:3
uno1:2
uno1:1
uno1:0
uno1:IOREF
uno1:RESET
uno1:3.3V
uno1:5V
uno1:GND.2
uno1:GND.3
uno1:VIN
uno1:A0
uno1:A1
uno1:A2
uno1:A3
uno1:A4
uno1:A5
uno2:A5.2
uno2:A4.2
uno2:AREF
uno2:GND.1
uno2:13
uno2:12
uno2:11
uno2:10
uno2:9
uno2:8
uno2:7
uno2:6
uno2:5
uno2:4
uno2:3
uno2:2
uno2:1
uno2:0
uno2:IOREF
uno2:RESET
uno2:3.3V
uno2:5V
uno2:GND.2
uno2:GND.3
uno2:VIN
uno2:A0
uno2:A1
uno2:A2
uno2:A3
uno2:A4
uno2:A5
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT
pico:GP0
pico:GP1
pico:GND.1
pico:GP2
pico:GP3
pico:GP4
pico:GP5
pico:GND.2
pico:GP6
pico:GP7
pico:GP8
pico:GP9
pico:GND.3
pico:GP10
pico:GP11
pico:GP12
pico:GP13
pico:GND.4
pico:GP14
pico:GP15
pico:GP16
pico:GP17
pico:GND.5
pico:GP18
pico:GP19
pico:GP20
pico:GP21
pico:GND.6
pico:GP22
pico:RUN
pico:GP26
pico:GP27
pico:GND.7
pico:GP28
pico:ADC_VREF
pico:3V3
pico:3V3_EN
pico:GND.8
pico:VSYS
pico:VBUS
lcd1:VSS
lcd1:VDD
lcd1:V0
lcd1:RS
lcd1:RW
lcd1:E
lcd1:D0
lcd1:D1
lcd1:D2
lcd1:D3
lcd1:D4
lcd1:D5
lcd1:D6
lcd1:D7
lcd1:A
lcd1:K
$abcdeabcde151015202530354045505560fghijfghij
dht1:VCC
dht1:SDA
dht1:NC
dht1:GND
buzzer1:1
buzzer1:2
encoder1:CLK
encoder1:DT
encoder1:SW
encoder1:VCC
encoder1:GND
ring1:GND
ring1:VCC
ring1:DIN
ring1:DOUT
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
lcd2:VSS
lcd2:VDD
lcd2:V0
lcd2:RS
lcd2:RW
lcd2:E
lcd2:D0
lcd2:D1
lcd2:D2
lcd2:D3
lcd2:D4
lcd2:D5
lcd2:D6
lcd2:D7
lcd2:A
lcd2:K
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
dht2:VCC
dht2:SDA
dht2:NC
dht2:GND
r1:1
r1:2
r2:1
r2:2