How to make millis for serial.print

Hello,

I have a problem when using delay, the sensor results are not as expected.
but when I discard the code below, the sensor runs normally. seems like this is caused by delay?
I have tried using Millis but have not succeeded, too, it has been 1 month to find a way to make it work. but its not work :o :o . can anyone help me?

void koneksi()
{
  sim900.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//start up the connection
  delay(6000);
 
 
  sim900.println("AT+CIPSEND");//begin send data to remote server
  delay(1000);
  
  String str="GET https://api.thingspeak.com/update?api_key=UNBU5BHRCJNF9VR9&field1=" + String(liter);
  sim900.println(str);//begin send data to remote server
  delay(2000);

  sim900.println((char)26);//sending
  delay(5000);//waitting for reply, important! the time is base on the condition of internet 
  sim900.println();

  sim900.println("AT+CIPSHUT");//close the connectio
  delay(100);

}

I use a water flow sensor and a GSM shield SIM900 :slight_smile: :slight_smile:

I have tried a number of ways but the sensor is still disturbed by delay. even though I already used millis below. Can someone help me?

void ATResponse()
{
mySerial.println("AT+CPIN?");
unsigned long start=millis();
while(millis()-start<5000){
if(mySerial.available()){
char c=mySerial.read();
Serial.write(c);
}
}
}

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

#define INTERVAL1 5000
#define INTERVAL2 7000
#define INTERVAL3 9000

unsigned long millis_1 = 0;
unsigned long millis_2 = 0;
unsigned long millis_3 = 0;

void displayTime(unsigned long);
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(millis() > millis_1 + INTERVAL1)
{
millis_1 = millis();
displayTime(millis_1);
Serial.println("1");
}
if(millis() > millis_2 + INTERVAL2)
{
millis_2 = millis();
displayTime(millis_2);
Serial.println("2");
}
if(millis() > millis_3 + INTERVAL3)
{
millis_3 = millis();
displayTime(millis_3);
Serial.println("3");
}
}
void displayTime(unsigned long time_millis)
{
Serial.print("Time: ");
Serial.print(time_millis/1000);
Serial.print("s - ");
}

Serial monitor :
Time: 5s - 1
Time: 7s - 2
Time: 10s - 3
Time: 10s - 1
Time: 14s - 2
Time: 15s - 1
Time: 20s - 3
Time: 20s - 1
Time: 21s - 2
Time: 25s - 1
Time: 28s - 2
Time: 30s - 3
Time: 30s - 1
Time: 35s - 2
Time: 35s - 1
Time: 40s - 3
Time: 40s - 1
Time: 42s - 2
Time: 45s - 1
Time: 49s - 2

little progress. but the results are not sequential?
anyone can explain?. it has been a little successful but I want to sequence it like this: 1,2,3,1,2,3,1,2,3,1,2,3.

if(millis() > millis_1 + INTERVAL1)
The form is:

  if(millis() - millis_1 >= INTERVAL1)

Take another look at the beginner's millis() tutorial.

is it possible for the millis to return to 0?

as expected below:

Time: 5s - 1
Time: 7s - 2
Time: 10s - 3

Time: 5s - 1
Time: 7s - 2
Time: 10s - 3

Time: 5s - 1
Time: 7s - 2
Time: 10s - 3

Time: 5s - 1
Time: 7s - 2
Time: 10s - 3

rizafajar:
is it possible for the millis to return to 0?

as expected below:

I don't understand the question.

millis() returns the number of millisecs since the Arduino was restarted. If the Arduino is left running it will roll over back to 0 and start counting up again after about 49 days.

...R

It's not surprising that your numbers aren't presented in sequence. It first goes wrong when time is 15 seconds and a 1 appears because you're displaying a 1 every 5 seconds. Can you show what you want the serial output to look like? i.e. what number should be shown at what time.

Moreover, what are you really trying to do or is this just a programming exercise?

Here, have this on me

unsigned long periods[] = {5000, 7000, 9000};
byte state = 0;
unsigned long startTime;
unsigned long currentTime;

void setup()
{
  Serial.begin(115200);
  report();
}

void loop()
{
  currentTime = millis();
  if (currentTime - startTime >= periods[state])
  {
    startTime = currentTime;
    state++;
    if (state == 3)
    {
      state = 0;
    }
    report();
  }
}

void report()
{
  Serial.print("Elapsed time in milliseconds ");
  Serial.println(millis());
  Serial.print("\nEntering state ");
  Serial.print(state);
  Serial.print(" for ");
  Serial.print(periods[state]);
  Serial.println(" milliseconds");
}

Feel free to pick out what you need and use it

wildbill:
It's not surprising that your numbers aren't presented in sequence. It first goes wrong when time is 15 seconds and a 1 appears because you're displaying a 1 every 5 seconds. Can you show what you want the serial output to look like? i.e. what number should be shown at what time.

Moreover, what are you really trying to do or is this just a programming exercise?

this is school homework, I have done 2 months but I don't understand what's wrong with my program. this is the first time I experienced this problem. the sensor results don't match the original, maybe it's because of delay. I use a water flow sensor with sim900.

#include  <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <String.h>
 #define INTERVAL1 6000
#define INTERVAL2 8000
#define INTERVAL3 10000
#define INTERVAL4 13000
#define INTERVAL5 14000


unsigned long millis_1 = 0;
unsigned long millis_2 = 0;
unsigned long millis_3 = 0;
unsigned long millis_4 = 0;
unsigned long millis_5 = 0;
unsigned long millis_6 = 0;


void displayTime(unsigned long);

SoftwareSerial mySerial(6, 5);

LiquidCrystal_I2C  lcd(0x27,2,1,0,4,5,6,7); // 0x27 = alamat I2C modul


int led = 8;

unsigned long interval=1000; // the time we need to wait
unsigned long previousMillis=0; // millis() returns an unsigned long.
  
boolean currentMillis = true ;
boolean currentMillis2 = true ;

long offTime1 = 10000;
long offTime2 = 7000;
long offTime3 = 8000;

unsigned long interval1=4000; // the time we need to wait
unsigned long previousMillis1=0; // millis() returns an unsigned long.

  unsigned long interval2=2000; // the time we need to wait
unsigned long previousMillis2=0; // millis() returns an unsigned long.
  
  unsigned long interval3=6000; // the time we need to wait
unsigned long previousMillis3=0; // millis() returns an unsigned long.

/*
Liquid flow rate sensor -DIYhacking.com Arvind Sanjeev

Measure the liquid/water flow rate using this code. 
Connect Vcc and Gnd of sensor to arduino, and the 
signal line to arduino digital pin 2.
 
 */

byte statusLed    = 8; // pin led

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2; // sensor water flow sensor di pin 2

// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 6.9; // Sensor aliran efek aula menghasilkan sekitar 4,5 pulsa per detik per
// liter / menit mengalir.

volatile byte pulseCount;  

float flowRate = 0;
float flowMilliLitres = 0;
float totalMilliLitres = 0;
float meterkubik = 0;

unsigned long oldTime;

void setup()
{
  mySerial.begin(9600);  
  Serial.begin(9600);   // Inisialisasi koneksi serial untuk melaporkan nilai ke host
  lcd.begin(16,2); 
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
 // Atur garis LED status sebagai output
  pinMode(statusLed, OUTPUT);
  digitalWrite(statusLed, LOW);  // Kami memiliki LED aktif-rendah yang terpasang
  
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

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

  // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
  // Configured to trigger on a FALLING state change (transition from HIGH
  // state to LOW state)
  
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}

/**
 * Main program loop
 */
void loop()
{
   
   if((millis() - oldTime) > 1000)    // Hanya memproses counter sekali per detik
  { 
    // Nonaktifkan interupsi saat menghitung laju alir dan mengirim nilainya
    // tuan rumah
    detachInterrupt(sensorInterrupt);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    
    // Note the time this processing pass was executed. Note that because we've
    // disabled interrupts the millis() function won't actually be incrementing right
    // at this point, but it will still return the value it was set to just before
    // interrupts went away.

    // Perhatikan waktu operan ini dieksekusi. Perhatikan itu karena kami sudah
    // disable interrupts the millis () function sebenarnya tidak akan bertambah benar
    // pada titik ini, tetapi masih akan mengembalikan nilai yang ditetapkan sebelumnya
    // interupsi pergi.
    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 multiply by 1000 to
    // convert to millilitres.

       // Bagilah laju aliran dalam liter / menit dengan 60 untuk menentukan berapa banyak liter
    // melewati sensor dalam interval 1 detik ini, lalu kalikan dengan 1000 ke
    // konversikan ke mililiter.
    flowMilliLitres = (flowRate / 60) * 1000;
    meterkubik = (totalMilliLitres / 1000);
    // Tambahkan mililiter yang dilewatkan dalam detik ini ke total kumulatif
    totalMilliLitres += flowMilliLitres;
      
    unsigned int frac;
    
    // Print the flow rate for this second in litres / minute
    lcd.clear();
    lcd.setCursor(0,1); // letak 
    lcd.print("F:");
    lcd.print(int(flowRate));  // Print the integer part of the variable
    lcd.print("L/min");     // Print tab space
   
    // Print the cumulative total of litres flowed since starting
    lcd.setCursor(10,1); // letak
    lcd.print("T:");        
    lcd.print(meterkubik);
    lcd.print("L");
   
    // 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);
  }
  jaringan();
  {
  if (mySerial.available())
    Serial.write(mySerial.read());
    }
}

/*        
Insterrupt Service Routine
 */
void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

void ShowSerialData()
{
  while(mySerial.available()!=0)
    Serial.write(mySerial.read());
}
void jaringan(){
if(millis() > millis_1 + INTERVAL1)
  {
    millis_1 = millis();
    displayTime(millis_1);
    Serial.println("1");
    mySerial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");
  }
  if(millis() > millis_2 + INTERVAL2)
  {
    millis_2 = millis();
    displayTime(millis_2);
    Serial.println("2");
    mySerial.println("AT+CIPSEND");
  }
  if(millis() > millis_3 + INTERVAL3)
  {
    millis_3 = millis();
    displayTime(millis_3);
      Serial.println("3");
  String str="GET https://api.thingspeak.com/update?api_key=UNBU5BHRCJNF9VR9&field1=" + String(flowRate);
  mySerial.println(str);//begin send data to remote server
  }
  if(millis() > millis_4 + INTERVAL4)
  {
    millis_4 = millis();
    displayTime(millis_4);
    Serial.println("4");
    mySerial.println((char)26);//sending
  }
  if(millis() > millis_5 + INTERVAL5)
  {
    millis_5 = millis();
    displayTime(millis_5);
    Serial.println("5");
   mySerial.println();
  mySerial.println("AT+CIPSHUT");//close the connectio
  }
}

void displayTime(unsigned long time_millis)
{
    Serial.print("Time: ");
    Serial.print(time_millis/1000);
    Serial.print("s - ");
}