text:
What happens if I power the Arduino with both the USB and external power voltage simultaneously?
I am a new Arduino user. I am not sure whether I can connect both USB and external supply through power adaptor to Arduino simultaneously. Would this burn the controller?
Basically, I want to automatically shut down the computer after saving all open documents before my UPS battery goes out whenever I am not there to manually shut it down. I am trying to notify the computer about the power failures of main supply - AC 220V 50 Hz (notification/signal sent when power goes out) via USB using Arduino. I am thinking that this can be done by using the external voltage power supply pin. Whenever power goes out in the mains, the external voltage power supply pin will drop to 0 V from 7 V. The value of the voltage can be read using software ( I am unclear about this: Can it be done? If yes, how?). The Arduino will still be powered up as it is connected to USB of computer and thereby communicates to the computer about the power failure.

From arduinoBoardUno:

Power
The Arduino Uno can be powered via the USB connection or with an external power supply. The power source is selected automatically.

Put the external power through a voltage divider or transistor-based inverter and into an analog (divider) or digital (inverter) pin and check the appropriate value from the pin. Note that this does not require powering the Uno from external power, only connecting the grounds.

Ok. Thank you for the answer. What will happen when I power them through both USB connection and external power supply. If it selects automatically, what source will it select?

According to the schematic external power will be chosen if it's above 7.4V or so, otherwise USB power.

Only connect the grounds. Won't  that be done automatically by the Uno? (Or are you referring to the voltage divider setup?)

@AnnonomusPerson: Neither of the voltage divider nor inverter configuration require the Uno to be powered by the external supply; it is only used for sensing.

The answer may be factually correct, but it seems confusing to me (as a novice user). Is misses some summary (can I have both at the same time or no?). What is this voltage divider talk about? Do I have to use a voltage divider to have both powers at the same time, or is this an experiment to prove someting?

I am a novice user of Arduino. I am not sure whether I can connect both USB and external supply through power adaptor to Arduino simultaneously. Would this burn the controller?

Lets study the schematic of Arduino UNO R3
The input from the power supply plug (PWRIN, the power jack) goes through a diode D1 (to prevent reverse polarity), and feeds a NCP1117 regulator that down converts it to the 5v supply that feeds the 5v parts.

The alternative supply comes from the USB plug (USBVCC). The relevant circuit is shown below

The USB power lines goes through a P-mosfet (T1) that operates as a switch and then goes to the +5V node (that is the +5v regulator output as shown in the first schematic).
The mosfet is controlled by an LMV358 operational amplifier (OPAMP) that operates as a comparator.
The negative input of the opamp is tied to 3.3V and the positive one fed through a voltage divider with half the Vin supply level.

When Vin >6.6V then the + input of the opamp become higher than the - input and the opamp turns the mosfet off.
When Vin <6.6V then the + input of the opamp become lower than the - input and the opamp turns the mosfet on.

Note that Vin is after the input diode so it's about 0.6V lower than the external connected power supply level. So when there is power supply connected to the power input that is higher than 6.6V+0.6V (where 0.6V is the diode D1 voltage drop), then the USB supply line is cutoff (because the mosfet turns off) and the power is provided from the power plug. Connecting or disconnecting the USB supply in this case will not make a difference, so you can have both power supplies connected simultaneously, only when the power input drops below the specified level (about 6.6V+0.6V=7.2V), the USB will start powering the board.

+1 Excellent answer: very detailed, precise and didactic.

Note that the M7 has a nasty Vf curve; adding a few shields (or one large one) will push its Vf to 0.8V or higher.

Note that while D1 adds protection for the PWRIN pin it does not protect from eg reverse polarity on Vin.

I know this is a bit old but isn't there a danger of damaging something (your Arduino or a USB port)? For example, while plugged in to USB for serial output and using a battery pack for powering a motor shield, if your battery pack drops below 7.2V, the Arduino would try drawing all that current through USB, either destroying your board or your USB port. I know it's not the exact situation the OP was asking for but I arrived here via Google for a different situation so I think the clarification is useful. Awesome answer, by the way!

@sraboy Motor Shield uses the 5V line only for the logic circuitry  section, the motors are powered from a separate line. You describe a  situation where the motors are powered by the raw supply line Vin (7.2v battery) and the rest of the circuit from the 5V line. If the battery is depleted then the 5V of the USB with just keep powering the logic circuitry of the motor shield and Arduino, the motors would not get any power because there is no path from the 5V line (which is after the 5V regulator) to Vin (which is before the regulator).

@alexan_e I appreciate the clarification!

@alexan_e If you connect a motor to the VIN pin after the barrel plug (after the diode), won't the motor become a load to the USB if the VIN source is unplugged from the barrel plug? I think I fried the voltage regulator on my arduino in this manner.

@Mark The only path I see for the motor to become a USB load would be through the 1117 regulator (U1) that has the USB voltage connected to its output and the motor load you describe at the input Vin. I don't know if 1117 would allow current to travel in reverse from the output to the input, I haven't tested it.


text:
Serial data plotting programs
I need to plot serial data from Arduino.
I require support for:

Various data formats (e.g. signed, unsigned, 8 bits, 16 bits);
Plots several data on the same axes;
Exports / Imports file data.

As plotting serial data from Arduino is a common need, my question is:
What programs/utilities are available for plotting serial data from Arduino that meet the needs above?
What are the advantages / disadvantages of the method you have suggested?

I decided to reopen with your last edit. As this question stands, it seems to be on topic because it's specific. I'll be clear to anyone (since there's not a lot of these types of questions): if this gets too off topic, I may have to step in. However, the likelihood of that happening is rare. :) @JRobert If GnuPlot meets the requirements in the question, post it.

The "Interfacing with Other Software" page on the Arduino Playground shows a bunch of ways to plot serial data from an Arduino to an iPhone, a Windows PC, a Linux PC, etc.

There are some good applications for visualizing the serial data, including:

MegunoLink ($39.95; Lite free) - plotting, logging, programming, reporting and more.

Electric UI ($80; free for students) - cross platform, fully featured code based GUI framework for hardware.

MakerPlot ($59) - digital & analog plotting, monitoring, custom interfaces and more.

ArduinoPlot (free) - simple plotting.

arduino-plotter (free) - easy, light-weight plotting with support for all primitive types

Bridge Control Panel (free) - logging, plotting, and more.

RealtimePlotter (free) - 6 channels data plotting.

SimPlot (free) - 4 channel plotting.

Arduino Serial Plotter (free) - built in Arduino Editor under Tools > Serial Plotter.

(This is a community wiki, you can expand the list.)

I'm confused. I posted my own solution below but now I'm not sure if it wouldn't be better to edit your post since it's a wiki. What do you think ?

@Overdrivr Sure, go extend this wiki for others' sake!

GnuPlot
Advantages: It's very flexible, scriptable, and freely available.
Disadvantages: A bit complex to learn (but I figured out how to get started in a few minutes, and quite functional in an hour or two), runs in a terminal window (if you consider that a disadvantage).
Something I found very useful was to script it to reload my terminal program's logfile periodically so i got a dynamic graph as my experiment progressed.

Edit: Here is the GnuPlot script that plots it:
#!/usr/local/bin/gnuplot -rv
# Note reverse video here ^^^   til I find a way to put it in the script

# gpFanCtl - Plots DiffThermo fan controller data (aloft, alow, Tdiff, fan-state).
# $Id: gpFanCtl,v 1.8 2014-04-28 09:40:51-04 jrobert Exp jrobert $

set terminal x11 1 noraise
set xtics 3600
set mxtics 4
set xdata time

set ytics 1 nomirror
set mytics 2

set y2range [0:3]
set y2tics 1
set my2tics 4

set grid
set ylabel 'Temperature, degC'
set y2label 'Tdiff, degC' textcolor rgb '#00CD63'

cd '/Users/jrobert/Desktop'
plot "Logfile.txt" using ($0*4):1 title "Aloft" with lines lc rgb "red",\
     "Logfile.txt" using ($0*4):2 title "Alow" with lines lc rgb "#3982FF",\
     "Logfile.txt" using ($0*4):3 title "Tdiff" with lines lc rgb "#00CD63" axis x1y2,\
     "Logfile.txt" using ($0*4):4 title "Fan" with lines lc rgb "orange" axis x1y2;
pause 4
refresh
reread

This looks great. Could you add some demo code?

But it plots the data from Logfile.txt, not the realtime serial data. How to connect it to a serial port?

No, this script isn't "real-time" -- it could be up to around 4 seconds behind. Logfile.txt is the capture file output from a terminal program. In my case, the data collection system samples and logs every 4 seconds and the GnuPlot script replots the log file every 4 seconds. This is dynamic enough for what I'm doing with it (monitoring room temperatures).

SerialPlot (free).  It does everything you require and much more.
Other features:

Zoom in on data
Click on datapoints to see values
Send commands back to Arduino
Adjust total number of points plotted
Ability to show each channel in its own autoscaled plot
Interprets binary, ASCII and custom packets
Demo mode lets you play with features

Good answer, I liked serialplot, it found my COM port & baud rate automatically, I just had to change from binary to CSV and increase to 3 channels ( for a magnetometer) and it was plotting nicely.

This is the neatest and easy to use - but I do wish there was a mac Binary :)

AppImage available => ultra quick installation !

But seems that icon of SerialPlot is not visible in Ubuntu (AppImage).

Would love to give this tool a try, but can't seem to find any documentation on how to format the data sent to the serial port.

I use Matplotlib for any plotting I need to do.
It's not arduino specific in any way, but it is a very excellent Python plotting toolkit.
I've built a number of applications that plot data from a variety of microcontrollers in real-time to a graph, but that was really more of a two-step process: 1. Get data from device into computer, 2. plot realtime data.
Really, I think you should break your question into two parts:

How do you get data from an Arduino/Any serial device into a computer easily.
What is a good plotting library that is easy to use.

+1. Does the "Arduino real time plot Matlab"[https://www.youtube.com/watch?v=ntHZsLmNkgw] video use that same technique?

Yep. It uses a call that reads the arduino data into a matlab variable, and then a call that updates the matlab plot with the matlab variable.

Matplotlib is python, not matlab.

I disagree with you, this question should not be divided in 2. There are solutions (such as the one I posted below) that do take care of both, because it is annoying to reivent the wheel for remote monitoring and control of arduino applications, and also because writing python code for real time plots is actually very far from trivial. Things can be done with matplotlib but clearly there are better alternatives for that such as pyqtgraph.

For part 1: getting data from Arduino: https://github.com/ElectricRCAircraftGuy/eRCaGuy_PyTerm

You might be interested in Telemetry See on Github . It is a communication protocol, highly simple to use, with a clean interface, that enables bidirectionnal communication with Arduino/Mbed devices.
If you don't want to read this long post, see A walkthrough of all the awesome features in it
The power of this library comes from the desktop command line interface (that requires no programming skills in python).
It is able to open high-performance plots (much higher that what can be done with matplotlib) just by typing a command.
The protocol supports complexes data structures. For now arrays and sparse arrays can be send from the embedded board.
The plots opened from the command line interface understand the type of data, and for arrays, rather than plotting each sample versus time, sample will be plotted against its own index.
In a near future, it is planned to add support for spatial coordinates (xyz data), that will allow you to plot immediately spatial data. Once, again the plots will figure everything out, plot your data in 2D or 3D space and you can focus on developping your app.
I believe those features are simply unique for such a project.
Pytelemetry CLI
Once installed with pip, the command line can be started with
pytlm

Then you can connect, ls(list) received topics, print data received on a topic, pub(publish) on a topic, or open a plot on a topic to display received data in real-time

Get started
Wiki
PS : I am the author.
I developed it because I could not find a solution that would allow me to:

write quickly PC scripts to control an Arduino
debug quickly
plot complex data (not just a time varying value)

all of the above without using proprietary solutions or bloated GUIs.
Using this library, the time to setup a communication between Arduino and PC went from usually half a day to 5 minutes.

PS: logging of the serial port data in the python packages (raw data and decoded data) is also fully supported. I intend to use it to implement an offline replay function (simulate serial data flow)

Nobody had mentioned Processing which is super versatile. You can do a lot more than just plotting but if that's all you want to do you can use the gwoptics library; hook up Arduino and Processing as directed here.

Responding to my own question here.. I use Bridge Control Panel as mentioned.
Advantages: Lots of Features.
Disadvantages: Tricky to setup and very poor syntax/error reporting.
To use:
You need to write the Arduino Data over the Serial Port one byte at a time. For an int data type that would look as follows:
// RX8 [h=43] @1Key1 @0Key1
Serial.print("C");
Serial.write(data>>8);
Serial.write(data&0xff);

In Bridge the command to Read Data is:
RX8 [h=43] @1Key1 @0Key1

RX8 is the read command
[h=43] means the next valid byte is "C" in ASCII
then the High Byte of Key1
then the Low Byte of Key1
It looks like this in Bridge:

You can try serialchart. It's pretty strait forward program. It does exactly what you asked. The only disadvantage is that it requires data in CSV format (does not meet first point).
Screenshot from project page:

I tried this & found it very clunky to get working, no default config, doesn't autoscale, after half an hour faffing with the syntax I still didn't have a plot only a straight line, so I gave up & used SerialPlot which worked within a few minutes, just had to specify ascii text & number of channels.

You can use MATLAB Student Edition,
this can save your time for further analysis, too.
You can just open the COM port in MATLAB and plot the received signal and/or save the signal in the workspace or whatever. MATLAB makes everything easy!

Welcome to Arduino SE! Can you please edit your answer to add more information describing how it fits the OP's needs and maybe a little other information like a link or a photo? Thanks!

Good answer, wouldn't have thought of using Matlab, there's a SO thread here about it https://stackoverflow.com/questions/19483098/using-matlab-to-display-streaming-serial-data

CSV format is most versatile for any data (signed/unsigned, various size and precision).
Cross-platform (written in Java/Scala) tool Scsvlog can receive/parse CSV strings from serial port / socket, show values and draw charts (up to 8).

Tool can no longer be found now, unfortunately - the original link is dead and I can't seem to find any copies.

You can try out the software I developed for that propose. It's aimed to be easy to use. See SerialGraphicator - Open Source Free Serial Port Client capable of graph values that are received in JSON format.

While I haven't used it myself, "rqt_plot" running on the PC seems to be a popular way to plot data on a PC that comes over a serial port from an Arduino running a sketch that includes the rosserial_arduino library or the ros_arduino_bridge library.

Arduino Oscilloscope Tutorial
rosserial arduino
visualize everything using rqt_plot... my first arduino micro ros project
"7/24: Now that I have the Arduino set up using Kessel, I can visualize the data better using ROS tools"
etc.

I made an equivalent tool in python that print real time data from ADXL345 accelerometer.
https://github.com/mba7/SerialPort-RealTime-Data-Plotter
may be it will be helpful for someone

Just choose the serial com and speed and sent a serial data on the following format:

3 inputs, every input is a 2 bytes (Two's complement )
6 bytes seperated by a space
the packet is a string terminated by '\n'

Could be easily adapted to change this format

Can you explain how to use this, and what the advantages and disadvantages of this are?

I know you were probably after more advanced GUI output, but I managed to replicate a task that one would normally do with an oscilloscope:

using the serial plotter in the Arduino IDE and an ADC module you can get for $3 on eBay. I admit it's a bit crude, but it might be worth playing with the tool for a while, before you invest in Python/Matlab/ect level solutions. It was exceedingly easy to use. It would not take much to add SD card recording to the process.
See: https://edwardmallon.wordpress.com/2016/08/15/using-the-arduino-uno-as-a-basic-data-acquisition-system/

I know this is a very old question, but I recently created a mac application that solves this problem very well. You can find more information about it on www.bloonapp.com. There are some demo videos on the website that you can check out.

As of Aug 1 '18 this website is dead.

Serial Plotter is a simple program that I've made with Electron that receives data in the following format:
data1,data2,timestamp; and converts it into a realtime chart.

HITIPanel Serial data plotting and recording. You can zoom in/out, pan, export data to text or excel file, or import external data from text files. Come with a user interface to control and monitor the hardware.

SVisual Monitoring and recording of signals for Arduino and not only.

Video example
Download (free)

I am using processing.org for serial plotting from Arduino. It was the only app I could find that allowed me to make real histograms ( e.g. a million events in a hundred bins) and display various info numbers in addition to mean sigma for each channel. Two major problems:
A) it turned out to be based on Java with no unsigned bytes
B) synch ig with input required circular buffer and markers in the data. ( high speed, no handshake)

Almost useful. It needs:

logging serial data to a file OR
graphing from a file and updating every xxx milliseconds.

Live Graph is a better option and I use it in conjunction with Tera Term which gets the data via the USB/serial link (and saves it to a log file which then Live Graph polls).
Live Graph is slightly buggy when caching data and I haven't found a way to set a moving window to display results. Also, showing multiple graphs requires manual scaling, but in spite of all this, it's still very useful. It's written in java so you'll need the JRE. I prefer this over having to install python like some of the other graphing programs do. another downside is that it opens 4 different windows, which is a pain when I want to flip between it and Tera Term.
I've yet to find software that's

An executable (.EXE) so it has no external reliance
Includes a terminal emulator or serial data logger
Logs serial data
Graphs multiple items from a CSV
Allows for CSV AND tab-delimited data (which is way easier to read as it scrolls along while simultaneously monitoring the graph.
Allows setting of different scales for each overlaid graph without having to scale everything to [0..1] or setting a multiplier, i.e. allowing setting an [y0..y1] range for each item graphed.

Welcome to Arduino SE! Your answer is informative but could you please improve the formatting of the answer using the markdown guide you can view by pressing the ? button in the editor.

Telemetry Viewer
Advantages:

Easy to use
Intuitive and flexible UI
Open Source and free
Different types of Graphs
Very fast graph update rate

Disadvantages:

Stopped development
Binary data format is not complete yet.
Primitive graph controls like zoom, screenshot and ...

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Sublime Text 2 with stino, compilation gives "filename ... is incorrect" Arduino IDE 1.7.8
I can't compile a simple blink sketch.
Error is:
[Stino - Start building "t5"...]
[  3%] Creating C:\Users\lov\AppData\Local\Temp\Stino_build\t5\t5.ino.cpp.o...
The filename, directory name, or volume label syntax is incorrect.

See also see similar question, that answer not working here.
Path to IDE app is C:\Program Files (x86)\added\Arduino.

Rename the program file to t5.cpp .

I suggest you do not install into 'C:\Program Files (x86)\added\Arduino'. Windows does some weird things with that directory, believe me. I usually put it on the desktop or somewhere I have normal write access to.

I've been working with Sublime Text 3, and trying to get it to work with Arduino IDE 1.8.1.  It has not gone well. From what I've read Stino is not compatible with the IDE beyond 1.6.2 or so, as the IDE library management was completely redone, among other things. I have just gotten that combination [Sublime 3 & IDE 1.6.2] to work ok, but still seem to have some library problems.  As for Stino, it looks like there is a new version in the works, but not complete.  More info on Github.
It you actually succeed, I would like to know about it.

Sorry but this is too big for a comment.
Firstly please can you check the obvious, in Windows Explorer paste the path C:\Users\lov\AppData\Local\Temp\Stino_build\t5 into the address bar and does the directory exist. (I have fallen for that so many times)
Secondly do you have permission to create a file there?
Have you updated the IDE? Does blink compile?
Have you tried running the IDE as admin?
Hopefully one of those will fix it.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Using esp8266 instead of xbee
I am using xbee pro s2c to get data from arduino (temp, pressure etc.) and I am sending data another xbee module and read these data from serial port.
Question is that I want to use esp8266 instead of xbee. Is it possible? Can I communicate 2 esp module like xbee?

you would just need one ESP, which connects to both your wifi and the sensor. You could use 2 with ESP-NOW to get a non-wifi module communication going, but it's simpler to use wifi. You also likely don't even need an arduino; sensors can connect directly to the ESP.

You can make two ESP8266 modules talk together, yes. It's not "simple" like an XBee, since you have a generic WiFi network interface, so there's many many different ways of doing it. Typically one would be running as a WiFi Access Point (SoftAP) and the other would connect to it. Then you'd run some "server" code on one module (typically the SoftAP one) and the other acts as a client and connects to it (or sends data to it).

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Compiling error at ATmega2560
I have a error.The error is showing as:
exit status 1
Error compiling for board Arduino Mega or Mega 2560.
The Code is:
#include <Wire.h>

#include <LCD.h>

#include <LiquidCrystal_I2C.h>

#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);

SoftwareSerial BT(10,11); //Tx and Rx pins for BT communication const int temp_sensor = 0; //pin A0 (temperature sensor) const int fan = 22; //pin D2 (fan) float temp; //temperature value

int threshold = 21; //temperature threshold

const int LDRsensor = 1; //pin A1 (lighting sensor)

const int LED1 = 6; //pin D6 (LED 1)

const int LED2 = 7; //pin D7 (LED 2)

const int LED3 = 8; //pin D8 (LED 3)

const int LED4 = 9; //pin D9 (LED 4)

int LDRvalue; //natural light value

const int WL_sensor = 15; //pin A15 (water level sensor)

const int Wpump = 13; //pin D13 (water pump)

float water_level; //water level value

const int mov_sensor = 3; //pin D3 (movement sensor)

const int LEDalrm = 4; //pin D4 (alarm LED)

const int buzzer = 5; //pin D5 (buzzer)

int mov_value; //movement value (true or false)

char state; //data sent from App

char mode; //mode selected according to "state" value char order; //order to actuators according to "state" value
void setup() //this function is only executed one time

{

lcd.begin (16,2);

lcd.setBacklightPin(3,POSITIVE);

lcd.setBacklight(HIGH);

lcd.setCursor(0,0);

lcd.print("TFG");

lcd.setCursor(0,1);

lcd.print("Anna Merino");

delay(4000);

lcd.clear();

pinMode(temp_sensor, INPUT); //temperature sensor Mode

pinMode(fan, OUTPUT) ; //fan Mode

pinMode(LDRsensor, INPUT); //lighting sensor Mode

pinMode(LED1, OUTPUT); //LED1 Mode

pinMode(LED2, OUTPUT); //LED2 Mode

pinMode(LED3, OUTPUT); //LED3 Mode

pinMode(LED4, OUTPUT); //LED4 Mode

pinMode(WL_sensor, INPUT) ; //water level sensor Mode

pinMode(Wpump, OUTPUT); //water pump Mode

pinMode(mov_sensor, INPUT); //movement sensor Mode

pinMode(LEDalrm, OUTPUT); //alarm LED Mode

pinMode(buzzer, OUTPUT); //buzzer Mode

BT.begin(9600); //set data rate in bits per second (baud) for data transmission }
void loop() //function loop – continuously executed

{

if(BT.available()>0)

{

state = BT.read(); //transfer data sent by App to a local variable

}

if (state == 'Y')

{

mode = 'A';

}

else

if (state == 'Z')

{

mode = 'R';

}

else

if (state == 'X')

{

mode = 'D';

}

if (mode == 'A')

{

automaticmode(); //execute automatic function

}

else

if (mode == 'R')

{

remotemode(); //execute remote function

}

else

if (mode == 'D')

{

alarmmode(); //execute alarm function

}

}
void alarmmode() // alarm function

{

water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

if (digitalRead(mov_sensor)) //evaluate movement captured {

digitalWrite(LEDalrm, HIGH);

digitalWrite(buzzer, HIGH);

}

else

{

digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

}

if (water_level > 100) //water level control

{

digitalWrite(Wpump, HIGH);

}

else

{

digitalWrite(Wpump, LOW);

}

}
void automaticmode() // automatic function

{

LDRvalue = analogRead(LDRsensor); //data of natural light transmission to a local variable water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

temp = analogRead(temp_sensor); //data of temperature sensor transmission to a local variable temp = temp*0.4883; //adjustment of temperature value digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

lcd.setCursor(0,0);

lcd.print("Temperature");

lcd.setCursor(0,1);

lcd.print(temp); //LCD display – shows temperature value

lcd.setCursor(7,1);

lcd.print("ºC");

if (water_level > 100) //water level control

{

digitalWrite(Wpump, HIGH);

}

else

{

digitalWrite(Wpump, LOW);

}

if ((LDRvalue < 1023) & (LDRvalue >= 822)) //light control {

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 821)& (LDRvalue >= 617))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 616)& (LDRvalue >= 412))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 411)& (LDRvalue >= 206))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, LOW);

}

else if (LDRvalue < 205)

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, HIGH);

}

if (temp >= threshold) //temperature control

{

digitalWrite(fan, HIGH);

}

else if (temp < threshold)

{

digitalWrite(fan, LOW);

}

}

void remotemode() // remote function

{

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

digitalWrite(fan, LOW);

digitalWrite(Wpump, LOW);

digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

if(BT.available()>0)

{

state = BT.read(); //transfer data sent by App to a local variable

}

if (state == 'D') //actuators operation according to orders received {

digitalWrite(LED1, LOW);

}

else

if (state == 'C')

{

digitalWrite(LED1, HIGH);

}

else

if (state == 'F')

{

digitalWrite(LED2, LOW);

}

else

if (state == 'E')

{

digitalWrite(LED2, HIGH);

}

else

if (state == 'H')
{

digitalWrite(LED3, LOW);

}

else

if (state == 'G')

{

digitalWrite(LED3, HIGH);

}

else

if (state == 'J')

{

digitalWrite(LED4, LOW);

}

else

if (state == 'I')

{

digitalWrite(LED4, HIGH);

}

else

if (state == 'L')

{

digitalWrite(fan, LOW);

}

else

if (state == 'K')

{

digitalWrite(fan, HIGH);

}

else

if (state == 'N')

{

digitalWrite(Wpump, LOW);

}

else

if (state == 'M')

{

digitalWrite(Wpump, HIGH);

}
if (state == 'O')

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, HIGH);

}

else

if (state == 'P')

{

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

}

what is the error? ... you only included a small part of the error message .... also, please format your code so that all of it is legible

If you run the auto-formatter in the IDE (Ctrl-T), your error should become obvious.

The main issue with your code is the formatting. It seems that you have managed to 'comment out' some of the necessary { or } for some of the functions and/or if/else blocks, hence the failure to compile.
e.g.
BT.begin(9600); //set data rate in bits per second (baud) for data transmission }

The } at the end of that particular line is the closing brace for the void setup() function... but because it's after the // for the comment, the compiler won't see it, so it is effectively missing.
This code should now compile on your system... once all the missing { and } were un-commented.
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7);
SoftwareSerial BT(10, 11); //Tx and Rx pins for BT communication const int temp_sensor = 0; //pin A0 (temperature sensor) const int fan = 22; //pin D2 (fan) float temp; //temperature value

int threshold = 21; //temperature threshold

const int LDRsensor = 1; //pin A1 (lighting sensor)
const int LED1 = 6; //pin D6 (LED 1)
const int LED2 = 7; //pin D7 (LED 2)
const int LED3 = 8; //pin D8 (LED 3)
const int LED4 = 9; //pin D9 (LED 4)
const int WL_sensor = 15; //pin A15 (water level sensor)
const int Wpump = 13; //pin D13 (water pump)
const int mov_sensor = 3; //pin D3 (movement sensor)
const int LEDalrm = 4; //pin D4 (alarm LED)
const int buzzer = 5; //pin D5 (buzzer)

int LDRvalue; //natural light value
float water_level; //water level value
int mov_value; //movement value (true or false)

char state; //data sent from App
char mode;   //mode selected according to "state" value char order; //order to actuators according to "state" value

void setup() //this function is only executed one time
{
    lcd.begin(16, 2);
    lcd.setBacklightPin(3, POSITIVE);
    lcd.setBacklight(HIGH);

    lcd.setCursor(0, 0);
    lcd.print("TFG");
    lcd.setCursor(0, 1);
    lcd.print("Anna Merino");

    delay(4000);

    lcd.clear();

    pinMode(temp_sensor, INPUT); //temperature sensor Mode
    pinMode(fan, OUTPUT); //fan Mode
    pinMode(LDRsensor, INPUT); //lighting sensor Mode
    pinMode(LED1, OUTPUT); //LED1 Mode
    pinMode(LED2, OUTPUT); //LED2 Mode
    pinMode(LED3, OUTPUT); //LED3 Mode
    pinMode(LED4, OUTPUT); //LED4 Mode
    pinMode(WL_sensor, INPUT); //water level sensor Mode
    pinMode(Wpump, OUTPUT); //water pump Mode
    pinMode(mov_sensor, INPUT); //movement sensor Mode
    pinMode(LEDalrm, OUTPUT); //alarm LED Mode
    pinMode(buzzer, OUTPUT); //buzzer Mode

    BT.begin(9600); //set data rate in bits per second (baud) for data transmission
}

void loop() //function loop – continuously executed
{
    if (BT.available() > 0)
    {
        state = BT.read(); //transfer data sent by App to a local variable
    }

    if (state == 'Y')
    {
        mode = 'A';
    }
    else if (state == 'Z')
    {
        mode = 'R';
    }
    else if (state == 'X')
    {
        mode = 'D';
    }

    if (mode == 'A')
    {
        automaticmode(); //execute automatic function
    }
    else if (mode == 'R')
    {
        remotemode(); //execute remote function
    }
    else if (mode == 'D')
    {
        alarmmode(); //execute alarm function
    }
}

void alarmmode() // alarm function
{
    water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

    if (digitalRead(mov_sensor)) //evaluate movement captured
    {
        digitalWrite(LEDalrm, HIGH);
        digitalWrite(buzzer, HIGH);
    }
    else
    {
        digitalWrite(LEDalrm, LOW);
        digitalWrite(buzzer, LOW);
    }
    if (water_level > 100) //water level control
    {
        digitalWrite(Wpump, HIGH);
    }
    else
    {
        digitalWrite(Wpump, LOW);
    }
}

void automaticmode() // automatic function
{
    LDRvalue = analogRead(LDRsensor); //data of natural light transmission to a local variable water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable
    temp = analogRead(temp_sensor); //data of temperature sensor transmission to a local variable temp = temp*0.4883; //adjustment of temperature value digitalWrite(LEDalrm, LOW);

    digitalWrite(buzzer, LOW);

    lcd.setCursor(0, 0);
    lcd.print("Temperature");

    lcd.setCursor(0, 1);
    lcd.print(temp); //LCD display – shows temperature value

    lcd.setCursor(7, 1);
    lcd.print("ºC");

    if (water_level > 100) //water level control
    {
        digitalWrite(Wpump, HIGH);
    }
    else
    {
        digitalWrite(Wpump, LOW);
    }

    if ((LDRvalue < 1023) & (LDRvalue >= 822)) //light control
    {
        digitalWrite(LED1, LOW);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 821) & (LDRvalue >= 617))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 616) & (LDRvalue >= 412))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 411) & (LDRvalue >= 206))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, LOW);
    }
    else if (LDRvalue < 205)
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, HIGH);
    }

    if (temp >= threshold) //temperature control
    {
        digitalWrite(fan, HIGH);
    }
    else if (temp < threshold)
    {
        digitalWrite(fan, LOW);
    }
}

void remotemode() // remote function
{
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);

    digitalWrite(fan, LOW);
    digitalWrite(Wpump, LOW);
    digitalWrite(LEDalrm, LOW);
    digitalWrite(buzzer, LOW);

    if (BT.available() > 0)
    {
        state = BT.read(); //transfer data sent by App to a local variable
    }

    if (state == 'D') //actuators operation according to orders received
    {
        digitalWrite(LED1, LOW);
    }
    else if (state == 'C')
    {
        digitalWrite(LED1, HIGH);
    }
    else if (state == 'F')
    {
        digitalWrite(LED2, LOW);
    }
    else if (state == 'E')
    {
        digitalWrite(LED2, HIGH);
    }
    else if (state == 'H')
    {
        digitalWrite(LED3, LOW);
    }
    else if (state == 'G')
    {
        digitalWrite(LED3, HIGH);
    }
    else if (state == 'J')
    {
        digitalWrite(LED4, LOW);
    }
    else if (state == 'I')
    {
        digitalWrite(LED4, HIGH);
    }
    else if (state == 'L')
    {
        digitalWrite(fan, LOW);
    }
    else if (state == 'K')
    {
        digitalWrite(fan, HIGH);
    }
    else if (state == 'N')
    {
        digitalWrite(Wpump, LOW);
    }
    else if (state == 'M')
    {
        digitalWrite(Wpump, HIGH);
    }

    if (state == 'O')
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, HIGH);
    }
    else if (state == 'P')
    {
        digitalWrite(LED1, LOW);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
}

In future, when posting a question, please also list WHICH libraries you are using. e.g. there is more than one LiquidCrystal_I2C library... and probably only one right one. Also, that will only be part of the error message. Give the entire message - as the end bit isn't of much use!


text:
Arduino Timer0 Piggyback
As described here
https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers
I use timer 0 to get my own timer with a milliseconds resolution.
It is setup like this:
void setup (void)
{
    ...
    cli();
    OCR0A  = 0xAB;
    TIMSK0 |= (1 << OCIE0A);
    sei();
    ...
}

The value 0xAB is chosen randomly and should not affect the behaviour.
The interrupt handler looks like this:
ISR(TIMER0_COMPA_vect)
{
    if (myTimer != 0)
        myTimer--;
    return;
}

This works just OK but having a closer look at the actual timing values using millis() I've found that the timer values given by this ISR are about 2-3% too long.
According to adafruit.com this method should exactly follow the built-in millis() timer of the Arduino.
In my program there are no other interrupts active. There are some Serial.print() outputs, maybe they affect the timing?
The solution I've found looks like this:
ISR(TIMER0_COMPA_vect)
{
    static unsigned long timeLast;

    unsigned long timeNow = millis();
    uint8_t timeDiff = (uint8_t)(timeNow - timeLast);
    timeLast = timeNow;

    if (myTimer != 0)
        myTimer -= timeDiff;

    return;
}

Instead of simply decrementing the timer, the timer value is decreased by the actual amount of time since the last call of the ISR.
With this my timer follows exactly the millis().
But why doesn't the first approach give an exact timing? Apparently there are some cases where the time between calls of the ISR is not 1ms but 2ms.

Does that mean that millis() already returns the corrected value i.e. millis() gives the actual number of milliseconds and not the 1.024ms?

The Arduino core configures Timer 0 for a period of 1,024 µs. Your
ISR will then be called at very regular intervals, and is a good place
to have timing-related code. You just have to keep in mind that the unit
of time is not one millisecond, but 1.024 ms.
If this “weird” unit bothers you, then you could do what the Arduino
timing ISR does: keep track of how late, relative to a 1 ms
period, you are getting. When you notice you are 1 ms late, count
one extra millisecond.


text:
Serial Communication, if statement not working
#include <SoftwareSerial.h>
SoftwareSerial my (D6,D7); //(Rx,Tx)
String msg;

void setup() {
Serial.begin(115200);
my.begin(9600);
}

void gas()
{

  Serial.println(msg);
  if (msg == "0")
  {
    Serial.println("Gas Leakage !!");
  }
  if(msg == "1") {
    delay(1);
  }
}

void loop() {

  msg = my.readStringUntil('\n');
  gas();
}

//I am using software serial to exchange data from Arduino UNO to NodeMCU, i am receiving the data correctly but the "if statement condition" is not working with it. how can i make the if statement work?

Maybe you also have an \r in your string. How exactly are you sending the message?

my problem solved by changing the if (msg == "0") with if (msg[0] == '0') ,, but I don't know why?

I would guess exactly the reason I stated above

what does that terminator \r \n means? in serial communication ?

Please answer the question, how exactly you are sending the message. Then I will write a proper answer to your question. Are you using Serial.println()? Or are you forwarding the data from the Serial Monitor set to both line endings?

yes I am using Serial.println()

https://www.arduino.cc/reference/en/language/functions/communication/serial/println/

You are using Serial.println() to send the message. That function will add the combination \r\n as line ending to your message, which are the ASCII codes for return carriage and newline.
In your receiving code, you read until \n, so your message now reads "0\r", which is of course not equal to "0". Thus the if condition will never trigger.
When using msg[0] == '0' you are taking the first character out of the string and compare that to the character '0' (especially note the difference between "0", which is a string, and '0', which is a single character). Since you are only using the first character of the string, the \r is out of the picture; you aren't using it.
What to do now?

You could send your message only with the \n character as line ending. For this only use Serial.print() instead of Serial.println() and add the line Serial.print("\n"); directly after you send your message.

You could write your own read-until code and just ditch every occurrence of the \r character.

You can use msg.trim() to remove any white space characters at the start or end of your string, including the \r at the end. Then you can use the code, that you already wrote.

Note, that using Strings on an Arduino is mostly considered evil. Especially if you want to use the code for a longer period or you are using String very often. The memory for a String is allocated dynamically, which can easily lead to heap fragmentation. For a better and longer explanation, look at The Evils of Arduino Strings, a blog entry from Majenko, who is one of our biggest contributors here.


text:
Measured voltage higher than AREF
What happen when a  voltage measured by analogRead() is higher than AREF voltage?
Example: AREF = 2.5V AO = 3.2V
What is the maximum voltage ?

About which microcontroller are you asking? Normally AREF must be within a rather small range around Vcc.

AREF is basically top value of ADC, AVCC must be around Vcc.  If your AO will be bigger than Vcc, then internal protection diodes takes place (so Vcc might be pulled to AO level, eventually protection diode might get destroyed by over current, or MCU by overvoltage)

You will be reading the maximum ADC value. If you were sampling a waveform the top of it would be clipped off at 2.5v.


text:
ESP8266 MCU not clearing memory?
I am still new at this.
Using Arduino IDE
My MCU was working as a web server with HTML code on SD card using the Webserver sketch. After trying to include other inputs it stopped working with "Timed out waiting for packet header"
Decided to abandon that for a while.
I loaded the standard Blink sketch, repowered MCU, pressed rst and Flash in prescribed sequence. Powered card and checked for compilation - All OK.
Uploaded Blink sketch and  got "esptool FatalError: Timed out waiting for packet error" again. Repeated power down etc. but same. Something seems to be lingering.
Arduino: 1.8.15 (Windows 7), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Serial, None, All Flash Contents, 115200"

C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\tools\python3\3.7.2-post1/python3 C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0/tools/upload.py --chip esp8266 --port COM10 --baud 115200 erase_flash --before default_reset --after hard_reset write_flash 0x0 C:\Users\IAN\AppData\Local\Temp\arduino_build_567362/Blink.ino.bin

esptool.py v3.0

Serial port COM10

Connecting....

Chip is ESP8266EX

Features: WiFi

Crystal is 26MHz

MAC: 3c:71:bf:3b:03:1f

Uploading stub...

Running stub...

Stub running...

Configuring flash size...

Traceback (most recent call last):

  File "C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0/tools/upload.py", line 66, in <module>

    esptool.main(cmdline)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 3599, in main

    detect_flash_size(esp, args)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 2848, in detect_flash_size

    flash_id = esp.flash_id()

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 688, in flash_id

    return self.run_spiflash_command(SPIFLASH_RDID, b"", 24)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 948, in run_spiflash_command

    old_spi_usr = self.read_reg(SPI_USR_REG)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 562, in read_reg

    val, data = self.command(self.ESP_READ_REG, struct.pack('<I', addr))

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 386, in command

    p = self.read()

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 331, in read

    return next(self._slip_reader)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 2636, in slip_reader

    raise FatalError("Timed out waiting for packet %s" % waiting_for)

esptool.FatalError: Timed out waiting for packet header

esptool.FatalError: Timed out waiting for packet header

fail after "Stub running..." is unusual. try a different USB cable and port

Tried rebooting PC and different USB port.
Cable is new and working.
I have already researched for 2 days.

how is the ESP8266 powered during all this?

Powered via USB


text:
Timer2 and INT1 in Arduino UNO
In my project Pin 3 of Arduino UNO is as External interrupt (INT1) and at the same time, I have to run Timer2. INT1 dosen't work When Timer2 is run. Timer2 is run just as timer. Is it my mistake or it is logical?
I connect a key to pin 3 as external interrupt and also run timer. Every time INT1 on pin 3 senses rising edge Button_ISR() is called.
but because of running timer2, Button_ISR() is not called.
THis is my code:
int buttonPin = 3;
void setup()
{
  pinMode(buttonPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(3), button_ISR, RISING);
  Serial.begin(9600);
  TCCR2B = 0x07; // clock frequency / 1024
  //OCR2B = 0x00;  // Output compare
  TCNT2 = 0;     // Set counter 2 to zero
  TIMSK2 = 0x01; // Enable overflow interrupt

}

void loop()
{

}

void button_ISR()
{
  Serial.print("button_ISR()");
  Serial.print("\n");
}

And if you cut out the timer config the button code is running correctly? The pin being OC2B should not matter here, since you are disabling the output compare mode. Thus the timer hardware is not connected to the pin hardware

Can you put a bit of debugging code in the loop to verify that pin 3 is going HIGH?

you have enabled the overflow interrupt. have you handled it?

Here are my 2 cents:
Your code is missing the handler for the timer. You have enabled the Timer overflow interrupt, but you have ISR prepared for it. So, the control is ending up reaching unhandled interrupt ISR which is a Restart
Arduino is restarting all the time.
Adding one line should fix it temporarily.
ISR(TIMER2_OVF_vect) {}

Here is the updated code. I can see that the code is now running (not restarting at least)
https://wokwi.com/arduino/projects/307835582788141632
    int buttonPin = 3;
    void setup()
    {
      pinMode(buttonPin, INPUT_PULLUP);
      Serial.begin(9600);
      Serial.println("ready!");
      TCCR2B = 0x07; // clock frequency / 1024
      //OCR2B = 0x00;  // Output compare
      TCNT2 = 0;     // Set counter 2 to zero
      TIMSK2 = 0x01; // Enable overflow interrupt
      attachInterrupt(digitalPinToInterrupt(3), button_ISR, RISING);

    }

    void loop()
    {

    }

void button_ISR()
{
  Serial.print("button_ISR()");
  Serial.print("\n");
}

ISR(TIMER2_OVF_vect) {}

Here is the disassembly code found on the Wokwi Arduino simulator for your sketch

and if you see the location  0xf6:

you will see that the code is doing a soft reset ( JMP 0). I hope this is helpful to you. Please feel free to ask if you have any questions.

I just changed the switch configuration to active LOW, but it should not matter.


text:
String Split Issue
I am getting multiple messages from a GPS device at different frequencies. After getting strings I have to save this data on the SD card. It works well when we have the same frequencies messages but if the frequencies are not same the saved data gets some blank spaces.
I am using the split strings method.
    CR1A = String1.indexOf(13);  //finds location of first
    String1A = String1.substring(0, CR1A + 2 );   //captures first data String
    CR1B = String1.indexOf(13, CR1A + 2 ); //finds location of second ,
    String1B = String1.substring(CR1A , CR1B + 2 ); //captures second data String
    CR1C = String1.indexOf(13, CR1B + 2 );
    String1C = String1.substring(CR1B , CR1C + 2 );
    CR1D = String1.indexOf(13, CR1C + 2 );
    String1D = String1.substring(CR1C , CR1D + 2 );
    CR1E = String1.indexOf(13, CR1D + 2 );
    String1E = String1.substring(CR1D , CR1E + 2 );
    CR1F = String1.indexOf(13, CR1E + 2 );
    String1F = String1.substring(CR1E , CR1F + 2 );

    strID = (String1A.substring(0, 2));
    if (strID == "$G") {
      File dataFile = SD.open("GPS1.txt", FILE_WRITE);
      // if the file is available, write to it:

      strID = (String1A.substring(0, 5));
      if (strID == "$GPGG") {
        dataFile.print(dt);
        dataFile.print(" ");
        dataFile.print(tm);
        dataFile.print(msec);
        dataFile.print(",");
        dataFile.print(String1A);
        String1A = "";
      }

      strID = (String1D.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1B);
        String1B = "";
      }
      strID = (String1C.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1C);
        String1C = "";
      }
      strID = (String1D.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1D);
        String1D = "";
      }
      strID = (String1E.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1E);
        String1E = "";
      }
      strID = (String1F.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1F);
        String1F = "";
      }
      dataFile.close();
    }

EDIT:
This is the code now I am using. I have turned off all the commands which extract strings from my available data received at the serial port. I am just using an interrupt timer for it.. and it is working perfectly. But I didn't like this simple method and I don't know it's a good way to get strings like this or not as I am not a good programmer.
#include <TimerOne.h>
#define RxTimeOut 5

/*
  ** MEGA MINI **
  ** MOSI - pin 51
  ** MISO - pin 50
  ** CLK - pin 52
  ** CS - pin 53 (for MKRZero SD: SDCARD_SS_PIN)
  ** SDA - pin 20
  ** SCL - pin 21
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include "math.h"
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
#define DS1307_CTRL_ID 0x68
unsigned long int ticks = 0;
RTC_DS1307 rtc;
bool flag = false;
String GPSmessage = "";
const int chipSelect = 53;
String dataString = "";
//String dataString1 = "";
//String dataString2 = "";
//String dataString3 = "";
bool stringComplete = false;
bool string1Complete = false;
bool string2Complete = false;
bool string3Complete = false;
String strID = "";

unsigned long msec;
const long interval = 500;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

unsigned long CurrentBaudRate = 9600;

unsigned long x = 0;

int Up = 3;
int Dn = 4;
int Mnu = 5;

String String1;
String inputString1 = "";         // a String to hold incoming data
boolean NewDataFlag1 = 0;
unsigned int Serial1TimeOut = 0;

String String2;
String inputString2 = "";         // a String to hold incoming data
boolean NewDataFlag2 = 0;
unsigned int Serial2TimeOut = 0;

String String3;
String inputString3 = "";         // a String to hold incoming data
boolean NewDataFlag3 = 0;
unsigned int Serial3TimeOut = 0;

void timerIsr()
{
  serial1Event();
  serial2Event();
  serial3Event();

  if (Serial1TimeOut > 0)Serial1TimeOut--;
  if (Serial1TimeOut == 0 && NewDataFlag1 == 1)
  {
    String1 = inputString1;
    inputString1 = "";
    NewDataFlag1 = 0;
  }

  if (Serial2TimeOut > 0)Serial2TimeOut--;
  if (Serial2TimeOut == 0 && NewDataFlag2 == 1)
  {
    String2 = inputString2;
    inputString2 = "";
    NewDataFlag2 = 0;
  }

  if (Serial3TimeOut > 0)Serial3TimeOut--;
  if (Serial3TimeOut == 0 && NewDataFlag3 == 1)
  {
    String3 = inputString3;
    inputString3 = "";
    NewDataFlag3 = 0;
  }

}

void setup() {

  Timer1.initialize(5000); // Timer event time
  Timer1.attachInterrupt( timerIsr );

  Serial.println("Sonay di nathli");

  //========================================= SD Card =======================================================//
  //  Serial.println("Initializing SD card...");

  // see if the card is not present:
  if (!SD.begin(chipSelect)) {
    //    Serial.println("Card failed, or not present");
    //     don't do anything more:
    return;
  }
  //  Serial.println("SD card Ready");

  //====================================================== RTC =============================================//
  if (!rtc.begin())
  {
    //    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (!rtc.isrunning()) {
    //    Serial.println("RTC is NOT running, let's set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  //================================================ OLED Baudrate selection ====================================================//
  pinMode(Up, INPUT_PULLUP);
  pinMode(Dn, INPUT_PULLUP);
  pinMode(Mnu, INPUT_PULLUP);

  unsigned char bdindx = EEPROM.read(0);
  if (bdindx > 3) bdindx = 0;
  if (bdindx == 0) CurrentBaudRate = 4800;
  if (bdindx == 1) CurrentBaudRate = 9600;
  if (bdindx == 2) CurrentBaudRate = 19200;
  if (bdindx == 3) CurrentBaudRate = 115200;
  delay (500);

  while (!Serial) { }// wait for serial port to connect
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(CurrentBaudRate);
  Serial1.begin(CurrentBaudRate);
  Serial2.begin(CurrentBaudRate);
  Serial3.begin(CurrentBaudRate);
  Serial.println(CurrentBaudRate);
  delay (1000);

  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
  display.clearDisplay();
  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.display();

}

String String1A, String1B, String1C, String1D, String1E, String1F;
String String2A, String2B, String2C, String2D, String2E, String2F;
String String3A, String3B, String3C, String3D, String3E, String3F;
int CR1A, CR1B, CR1C, CR1D, CR1E, CR1F;
int CR2A, CR2B, CR2C, CR2D, CR2E, CR2F;
int CR3A, CR3B, CR3C, CR3D, CR3E, CR3F;

// ============================================ Showing baud rate on screen (position) ===========================================//

void DrawBaudRate(unsigned long BdRt)
{
  unsigned char Xoffset = 0;
  if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
  if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
  if (BdRt >= 100000 ) Xoffset = 25;
  //  display.drawRect(0,0,128,64,SSD1306_WHITE);
  //  display.setTextSize(2);
  //  display.setCursor(15,10);
  //  display.println("Baudrate");
  //  display.setTextSize(2);
  //  display.setCursor(15,10);
  //  display.println(tm);
  //  display.setCursor(Xoffset,37);// 6 digit
  //  display.println(BdRt);
  //  display.display();
  //  delay(10);
}

// ================================================== Selection of Baud Rate ========================================================//
unsigned long SelectBaudRate(unsigned long BdRt)
{
  unsigned char BdRtIndx = 0;
  unsigned int FlashCnt = 0;

  if (BdRt == 4800) BdRtIndx = 0;
  if (BdRt == 9600) BdRtIndx = 1;
  if (BdRt == 19200) BdRtIndx = 2;
  if (BdRt == 115200) BdRtIndx = 3;

  unsigned char Xoffset = 0;
  if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
  if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
  if (BdRt >= 100000 ) Xoffset = 25;
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(15, 10); display.println("Select Baudrate");
  display.setCursor(15, 20); display.println("by Up/Dn Buttons");
  display.setTextSize(2);
  display.setCursor(Xoffset, 37); // 6 digit
  display.println(BdRt);
  display.display();
  delay(10);

  while (digitalRead(Mnu) == 0) delay(10);
  delay(100);

  while (digitalRead(Mnu) == 1)
  {
    delay(10);
    FlashCnt++;

    if (digitalRead(Up) == 0)
    {
      if (BdRtIndx < 3) BdRtIndx++;
    }

    if (digitalRead(Dn) == 0)
    {
      if (BdRtIndx > 0) BdRtIndx--;
    }

    if (BdRtIndx == 0) BdRt = 4800;
    if (BdRtIndx == 1) BdRt = 9600;
    if (BdRtIndx == 2) BdRt = 19200;
    if (BdRtIndx == 3) BdRt = 115200;

    if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
    if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
    if (BdRt >= 100000 ) Xoffset = 25;
    display.clearDisplay();
    display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
    display.setTextSize(1);
    display.setCursor(15, 10); display.println("Select Baudrate");
    display.setCursor(15, 20); display.println("by Up/Dn Buttons");
    display.setTextSize(2);
    display.setCursor(Xoffset, 37); // 6 digit
    if (FlashCnt > 1) display.println(BdRt);
    if (FlashCnt > 2) FlashCnt = 0;
    display.display();
    delay(250);

    //while(digitalRead(Up)==0 || digitalRead(Dn)==0) delay(10);
  }
  while (digitalRead(Mnu) == 0) delay(10);

  display.clearDisplay();
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
  display.setTextSize(2);
  display.setCursor(20, 10); display.println("Saving");
  display.setCursor(20, 35); display.println("Changes");
  display.display();
  delay(2000);

  EEPROM.write(0, BdRtIndx);

  return (BdRt);

}

//=================================================== OLED showing time ===============================================//
char Time[]     = "  :  :  ";
byte i, second, minute, hour;

void DS3231_display() {
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour   = (hour >> 4)   * 10 + (hour & 0x0F);
  // End conversion

  Time[7]     = second % 10 + 48;
  Time[6]     = second / 10 + 48;
  Time[4]     = minute % 10 + 48;
  Time[3]     = minute / 10 + 48;
  Time[1]     = hour   % 10 + 48;
  Time[0]     = hour   / 10 + 48;
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
  draw_text(16, 25, Time, 2);                         // Display the time
}

void blink_parameter() {
  byte j = 1;
  while (j < 10 && digitalRead(Up) && digitalRead(Dn)) {
    j++;
    delay(25);
  }
}

byte edit(byte x_pos, byte y_pos, byte parameter) {
  char text[3];
  sprintf(text, "%02u", parameter);
  while (!digitalRead(Up));                     // Wait until button B1 released
  while (true) {
    while (!digitalRead(Dn)) {                  // If button B2 is pressed
      display.clearDisplay();
      parameter++;
      if (i == 0 && parameter > 23)                  // If hours > 23 ==> hours = 0
        parameter = 0;
      if (i == 1 && parameter > 59)                  // If minutes > 59 ==> minutes = 0
        parameter = 0;
      sprintf(text, "%02u", parameter);
      draw_text(x_pos, y_pos, text, 2);
      delay(200);                                    // Wait 200ms
    }
    display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
    draw_text(x_pos, y_pos, "  ", 2);
    blink_parameter();
    draw_text(x_pos, y_pos, text, 2);
    blink_parameter();
    if (!digitalRead(Up)) {                     // If button B1 is pressed
      i++;                                           // Increament 'i' for the next parameter
      //      display.clearDisplay();

      return parameter;                              // Return parameter value and exit
    }
  }
}

void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
  display.setCursor(x_pos, y_pos);
  display.setTextSize(text_size);
  display.print(text);
  display.display();
}

//---------------------------------------------
void loop() {

  // ========================================= Editing time and displaying on OLED ============================================//
  if (!digitalRead(Up)) {                       // If button B1 is pressed
    i = 0;
    while (!digitalRead(Up));                   // Wait for button B1 release

    hour   = edit(16, 25, hour);                     // Edit hours
    minute = edit(52, 25, minute);                   // Edit minutes

    // Convert decimal to BCD
    minute = ((minute / 10) << 4) + (minute % 10);
    hour = ((hour / 10) << 4) + (hour % 10);
    // End conversion

    // Write data to DS3231 RTC
    Wire.beginTransmission(0x68);               // Start I2C protocol with DS3231 address
    Wire.write(0);                              // Send register address
    Wire.write(0);                              // Reset sesonds and start oscillator
    Wire.write(minute);                         // Write minute
    Wire.write(hour);                           // Write hour
    Wire.endTransmission();                     // Stop transmission and release the I2C bus
    delay(200);                                 // Wait 200ms
  }

  Wire.beginTransmission(0x68);                 // Start I2C protocol with DS3231 address
  Wire.write(0);                                // Send register address
  Wire.endTransmission(false);                  // I2C restart
  Wire.requestFrom(0x68, 7);                    // Request 7 bytes from DS3231 and release I2C bus at end of reading
  second = Wire.read();                         // Read seconds from register 0
  minute = Wire.read();                         // Read minutes from register 1
  hour   = Wire.read();                         // Read hour from register 2
  Wire.beginTransmission(0x68);                 // Start I2C protocol with DS3231 address
  Wire.write(0x11);                             // Send register address
  Wire.endTransmission(false);                  // I2C restart
  Wire.requestFrom(0x68, 2);                    // Request 2 bytes from DS3231 and release I2C bus at end of reading
  DS3231_display();                             // Diaplay time & calendar

  delay(50);                                    // Wait 50ms

  { display.clearDisplay();
    if (digitalRead(Mnu) == 0) CurrentBaudRate = SelectBaudRate(CurrentBaudRate);
    //  DrawBaudRate(CurrentBaudRate);
    delay(10);

    x++;
    if (x > 123456) x = 0;
  }

  // ======================================= Reading Date and Time from RTC =============================================//
  DateTime now = rtc.now();
  char dt[16];
  char tm[16];
  char buffer [16];
  uint8_t thisSec, thisMin, thisHour;
  thisSec = now.second();
  thisMin = now.minute();
  thisHour = now.hour();
  sprintf(dt, "%02d-%02d-%02d", now.year(), now.month(), now.day());
  sprintf(tm, "%02d%02d%02d", now.hour(), now.minute(), now.second());
  sprintf (buffer, "%02d:%02d:%02d", thisHour, thisMin, thisSec);
  msec = millis() % 1000; //TO USE LAST 3 DIGITS OF MILLIS OF ARDUINO

  //SERIAL_PORT_1

//  if (string1Complete)
  { Serial.print (String1);
//    CR1A = String1.indexOf(13);  //finds location of first
//    String1A = String1.substring(0, CR1A + 2 );   //captures first data String
//    CR1B = String1.indexOf(13, CR1A + 2 ); //finds location of second ,
//    String1B = String1.substring(CR1A , CR1B + 2 ); //captures second data String
//    CR1C = String1.indexOf(13, CR1B + 2 );
//    String1C = String1.substring(CR1B , CR1C + 2 );
//    CR1D = String1.indexOf(13, CR1C + 2 );
//    String1D = String1.substring(CR1C , CR1D + 2 );
//    CR1E = String1.indexOf(13, CR1D + 2 );
//    String1E = String1.substring(CR1D , CR1E + 2 );
//    CR1F = String1.indexOf(13, CR1E + 2 );
//    String1F = String1.substring(CR1E , CR1F + 2 );
//
//    strID = (String1A.substring(0, 5));
//    if (strID == "$GPGG") {
//      Serial.println(String1);
//    }
//    strID = (String1B.substring(0, 5));
//    if (strID == "$GPVT") {
//      Serial.println(String1B);
//    }
//    strID = (String1C.substring(0, 5));
//    if (strID == "$GPZD") {
//      Serial.println(String1C);
//    }
//    strID = (String1D.substring(0, 5));
//    if (strID == "$GPGL") {
//      Serial.println(String1D);
//    }
//    strID = (String1E.substring(0, 5));
//    if (strID == "$GPGN") {
//      Serial.println(String1E);
//    }
//    strID = (String1F.substring(0, 5));
//    if (strID == "$GPGR") {
//      Serial.println(String1F);
//    }
//    strID = (String1.substring(0, 2));
//    if (strID == "$") {
      File dataFile = SD.open("GPS1.txt", FILE_WRITE);
      // if the file is available, write to it:

      strID = (String1A.substring(0, 5));
      if (strID == "$GPGG") {
        dataFile.print(dt);
        dataFile.print(" ");
        dataFile.print(tm);
        dataFile.print(msec);
        dataFile.print(",");
        dataFile.print(String1);
        Serial.print (String1);
        String1 = "";
        Serial.print (String1);
        dataFile.close();
      }
//    }
//      strID = (String1D.substring(4, 6));
//      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
//        dataFile.print(String1B);
//        String1B = "";
//      }
//      strID = (String1C.substring(4, 6));
//      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
//        dataFile.print(String1C);
//        String1C = "";
//      }
//      strID = (String1D.substring(4, 6));
//      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
//        dataFile.print(String1D);
//        String1D = "";
//      }
//      strID = (String1E.substring(4, 6));
//      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
//        dataFile.print(String1E);
//        String1E = "";
//      }
//      strID = (String1F.substring(4, 6));
//      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
//        dataFile.print(String1F);
//        String1F = "";
//      }

//    }
    else {
      File dataFile = SD.open("ES2.txt", FILE_WRITE);

      if (dataFile) {
        dataFile.print(dt);
        dataFile.print(" ");
        dataFile.print(tm);
        dataFile.print(msec);
        dataFile.print(",");
        dataFile.println(String1);
        Serial.print (String1);
//        dataFile.println(String1B);
        String1A = "";
        String1B = "";
        dataFile.close();
      }
    }
//  }
  string1Complete = false;
  }

}

//-----------------------------------------------------------------------------------------------------------------

void serial1Event() {
  while (Serial1.available()) {
    char inChar1 = (char)Serial1.read();
    inputString1 += inChar1;
    Serial1TimeOut = RxTimeOut;
    NewDataFlag1 = 1;

    if (NewDataFlag1 == 1) {
      string1Complete = true;
    }

  }
}

You never check that indexOf() does find the '\r'. Why do you try to process five messages at a time instead of processing them one by one?

Please provide a more detailed description of what message data you have in that string, what errornous output you get and where in the code that happens.

If (strID == "TG" || "DA" || "LL" || "NS" ... that is nonsense

I will provide you my complete program. Actually there is no delay between sentences so when the processor writes one sentence to sd card 2nd message arrives and most of the time it saves glitch in sd card.

If you're curious, "DA", "LL", and "NS" are all truthy in C++.  So, the above mentioned nonsense is functionally equivalent to if (true).

@OmarRai, just to be clear, you want to be using the "edit" link under your question to add additional details to the question.  If you want to intact with the people asking you questions you want to "Add comment".  The only time you're going to "Post Your Answer" is if you've managed to solve our own problem.

I do not know what the “frequencies” have to do with your problem, but I
would bet that you would get more reliable results if you handle one
NMEA sentence at a time, instead of trying to handle six of them at
once, and hoping to get the right ones.
Below is a function that processes one complete sentence at a time. It
records the sentence to the SD file if its type belongs to a list of
“interesting” types you want to monitor:
// Sentence types that are to be recorded.
const char monitoredTypes[6][4] = {
    "GGA", "VTG", "ZDA", "GLL", "GNS", "GRS"
};

// Process a complete, CRLF-terminated NMEA sentence.
void processSentence(String &sentence) {

    // Sanity check.
    if (sentence.substring(0, 3) != "$GP") {
        Serial.print("WARNING: invalid sentence: ");
        Serial.print(sentence);
        return;
    }

    // Record the sentence if it has an interesting type.
    String type = sentence.substring(3, 6);
    for (int i = 0; i < 6; i++) {
        if (type == monitoredTypes[i]) {
            File dataFile = SD.open("GPS1.txt", FILE_WRITE);
            if (type == "GGA") {  // this type seems to be special
                dataFile.print(dt);
                dataFile.print(" ");
                dataFile.print(tm);
                dataFile.print(msec);
                dataFile.print(",");
            }
            dataFile.print(sentence);
            dataFile.close();
        }
    }
}

The way to use it is to buffer the incoming characters until you get a
complete sentence (identified by the final LF), then submit that buffer
to this function:
String buffer;

void loop() {
    while (Serial.available() > 0) {
        char c = Serial.read();
        buffer += c;

        // On end of sentence, process and clear the buffer.
        if (c == '\n') {
            processSentence(buffer);
            buffer = "";
        }
    }
}

Note that it wouldn't take too much work to get rid of the String
class and use plain C strings instead. Plain strings are way more memory
friendly.


text:
fingerprint scanner and GSM module- how do i put a timer condition using if statements?
I am using a fingerprint sensor and GSM module on Arduino MEGA 2560. I want a fingerprint to be scanned every minute, if a minute elapses with no finger scanned, then the next code for the GSM to send an SMS must be executed

const unsigned long timeLimit = 60000;
unsigned long prevTime;
unsigned long currTime;

void setup() {
  prevTime = millis();
}

void loop() {
  unsigned long currTime = millis();
  getFingerprintID(); //fingerprint func
  if (currTime - prevTime <= timeLimit) {
    if (finger.fingerSearch() == FINGERPRINT_OK) { //if the fingerprint matches
      prevTime = currTime;
    }
  } else {
    Serial.print("MAXIMUM TIME OF ");
    Serial.print(currTime / 1000);
    Serial.print(" SECONDS HAS LAPSED\n");
  }
}

Consider looking at this https://forum.arduino.cc/t/using-millis-for-timing-a-beginners-guide/483573 What you need to do is create a timer that every 60 seconds executes the code that you want and sets a flag if it was successful and based on that you can do whatever you need with the GSM.

do something like this ... modify the millis code in the comment from @Coder_fox to increment a counter every second ... the millis code does nothing else ...... check for fingerprint, if detected then clear the counter to zero, do nothing else ...... check the counter, if 60 then send SMS

@Coder_fox the issue i have now is that the timer starts when i run the code and lapses within 60 seconds regardless of how many times the fingerprint was scanned within the time period

i cleaned up your version. make sure to update the prevTime variable.
const unsigned long timeLimit = 60000;
unsigned long prevTime ;
unsigned long currTime;
unsigned long elapsedTime;
int id;
void setup() {
prevTime=millis();
}

void loop() {
  if (fingerprint()){
    currTime = millis();
    elapsedTime = currTime- prevTime;
    if (elapsedTime < 60*1000) {
      prevTime = currTime;
    } else {
       sendSms();
    }
  }
}

void sendSms() {
Serial.print("MAXIMUM TIME OF ");
Serial.print(currTime/1000);
Serial.print(" SECONDS HAS LAPSED\n");
}

bool fingerprint(){
  bool fingerPrintAccepted = false;
  if (finger.fingerSearch()==FINGERPRINT_OK){
    fingerPrintAccepted = true;
  }
  return fingerPrintAccepted;
}


text:
LightBlue to Arduino connection log does not display serial monitor printed data
I'm writing code so that, every time a hall monitor senses, my code additively measures 5 liters of volume as it prints each detection. Then, this data is sent via Bluetooth to a phone. (This is for a tipping bucket device that distributes 5 liters of water every time it tips). I am using the LightBlue app for the bluetooth connection. My code connects to the bluetooth app, but the LightBlue log does not show what's being printed on my serial monitor. Does anyone have any suggestions?
    // https://makersportal.com/blog/2018/10/3/arduino-tachometer-using-a-hall-effect-sensor-to-measure-rotations-from-a-fan
#include <ArduinoBLE.h>
// digital pin 2 is the hall pin

int hall_pin = 2;

// set number of hall trips for RPM reading (higher improves accuracy)

float hall_thresh = 1000000000.0;

// BLE Battery Service
        BLEService Vol_valServ("180F");

        // BLE Battery Level Characteristic
        BLEUnsignedCharCharacteristic VolumeChar("2A19",  // standard 16-bit characteristic UUID
            BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

        long previousMillis = 0;  // last time the volume level was checked, in ms
void setup() {

  // initialize serial communication at 9600 bits per second:

  Serial.begin(9600);

   while (!Serial);

          pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected

          // begin initialization
          if (!BLE.begin()) {
            Serial.println("starting BLE failed!");

            while (1);
          }

          /* Set a local name for the BLE device
             This name will appear in advertising packets
             and can be used by remote devices to identify this BLE device
             The name can be changed but maybe be truncated based on space left in advertisement packet
          */
          BLE.setLocalName("VolumeMonitor");
          BLE.setAdvertisedService(Vol_valServ); // add the service UUID
          Vol_valServ.addCharacteristic(VolumeChar); // add the battery level characteristic
          BLE.addService(Vol_valServ); // Add the battery service

          /* Start advertising BLE.  It will start continuously transmitting BLE
             advertising packets and will be visible to remote BLE central devices
             until it receives a new connection */

          // start advertising
          BLE.advertise();

          Serial.println("Bluetooth device active, waiting for connections...");

}

// the loop routine runs over and over again forever:

void loop() {

  // preallocate values for tach

  float hall_count = 0.0;

  float start = micros();

  bool on_state = false;

  // counting number of times the hall sensor is tripped

  // but without double counting during the same trip

  while (true) {

    if (digitalRead(hall_pin) == 0) {

      if (on_state == false) {

        on_state = true;

        hall_count += 1.0;

      }

    } else {

      on_state = false;
      float Volume = (hall_count) * 5.0; // this is the liters per tip

      Serial.print( "hall_count");
      Serial.print( hall_count);
      Serial.println(" Volume");
      Serial.print(Volume);

        // wait for a BLE central
        BLEDevice central = BLE.central();

        // if a central is connected to the peripheral:
        if (central) {
          Serial.print("Connected to central: ");
          // print the central's BT address:
          Serial.println(central.address());
          // turn on the LED to indicate the connection:
          digitalWrite(LED_BUILTIN, HIGH);

          while (central.connected()) {

if (digitalRead(hall_pin)==0){

if (on_state==false){

on_state = true;

hall_count+=1.0;

}

} else{

on_state = false;
float Volume = (hall_count)*5.0; // this is the liters per tip

Serial.println( Volume);

Serial.println("Volume");
VolumeChar.writeValue(Volume);

delay(2000);
        // delay in between reads for stability

            }
          }

          digitalWrite(LED_BUILTIN, LOW);
          Serial.print("Disconnected from central: ");
          Serial.println(central.address());

          }

          if (hall_count >= hall_thresh) {

            break;

          }

        // print information about Time and RPM

        float end_time = micros();

        float time_passed = ((end_time - start) / 1000000.0);

        Serial.print("Time Passed: ");

        Serial.print(time_passed);

        Serial.println("s");

delay(2000);
        // delay in between reads for stability
      }
    }
  }


text:
Using Adafruit RTClib without fragmenting the heap
I'm getting ready to add DS1307 support to my Arduino app, and was horrified when I looked at the sourcecode for the RTC_DS1307 class in Adafruit's RTClib library...
DateTime RTC_DS1307::now() {
  uint8_t buffer[7];
  buffer[0] = 0;
  i2c_dev->write_then_read(buffer, 1, buffer, 7);

  return DateTime(bcd2bin(buffer[6]) + 2000U, bcd2bin(buffer[5]),
                  bcd2bin(buffer[4]), bcd2bin(buffer[2]), bcd2bin(buffer[1]),
                  bcd2bin(buffer[0] & 0x7F));
}

... and realized that it appears to be instantiating a new throw-away DateTime object on the heap every time you call now()... which AFAIK, is the ultimate Arduino C++ taboo.
I was about to tear into the class and rewrite it to reuse a singleton DateTime object that gets created once and reused forever... but then I remembered about return value optimization.
Is this actually a scenario where RVO will automagically kick in to save the day and prevent a heap-allocation (by pre-allocating space for the DateTime object on the caller's stack prior to calling now()), or is this library indeed doing something as taboo as I think it is?

I wrote a minimal sketch that calls RTC_DS1307::now(), disassembled
it, and here is what I saw:

The caller allocates 6 bytes on the stack for holding the return
value.

It writes the address of this stack location in the register pair
r25:r24, as per the AVR calling convention,1 then calls
RTC_DS1307::now().

As the callee computes the fields of the resulting DateTime (by
means of inlined calls to bcd2bin()), it writes them directly into
the caller's stack frame, with no intermediate copy in RAM.

This looks to me like return value optimization.
However, in order to witness this behavior, I had to call
RTC_DS1307::now() twice. If the method is called from a single place
within the sketch, the compiler inlines it, and there isn't even a
function call to begin with.
Then, of course, the heap is never touched.
1 You would expect the this pointer to be passed as the
first argument, in r25:r24. It would seem it has been optimized out,
which makes sense given that there is only one RTC_DS1307 object in
the whole sketch.

Surely the heap is never touched in any case?

with no intermediate copy in RAM - using RAM is not the same thing as using the heap.

@NickGammon: The heap is not touched by RTC_DS1307::now(). On AVR, new calls malloc. Thus, if the heap is ever touched, avr-nm the_sketch.elf | grep malloc will show you: malloc, __malloc_heap_start, __malloc_heap_end and __malloc_margin.

I wish I could give points for both answers, but I'm going with Edgar's due to the info about being able to determine with certainty whether the heap is being touched by something. I've been dying to find info about that particular topic for months.

Edgar Bonet's answers are usually excellent. I think we are in agreement that there is no problem with heap fragmentation in this particular case.

I wonder how could one assume some heap allocation from the code presented in the question. I guess return of object by copy is not intuitive. Usually the compiler even optimizes it so there is no copying.

I think you are confusing the stack and the heap. For something to appear in the heap you would expect to see the words new or malloc which I don't see.
What is happening here is that a DateTime object is being created (in the stack frame of the current function) by RTC_DS1307::now which is being (presumably) copied into a variable of that type in the caller's stack frame when the function returns.
No memory is being wasted here.

it appears to literally be instantiating a new throw-away DateTime object on the heap

What gives you that idea? The heap is not involved without you using new or malloc.

The heap is a block of memory used for dynamic memory allocation by using malloc or new, generally speaking. Typically it will be allocated past the place in RAM where variables are allocated (ie. after all the variables) and grow upwards, whereas the stack will be allocated at the end of available memory and grow downwards. Thus they don't clash until they collide, either by using too much stack (eg. by recursive function calls) or by allocating too much of the heap (by repeatedly calling malloc and without calling free).
When you use the heap, by using malloc you will get a pointer which you can then use, and pass around. That memory which you have reserved is yours until you free it, by literally calling free. In C++ something very similar is done by using new and delete.
If you don't call malloc or use new then you aren't using the heap, end of story.

Prior to about an hour ago, I didn't realize there was a mechanism in c++ to create an object on a subroutine/method's stack & atomically copy it to the caller's stack upon return. I thought the called method/subroutine's stack vanished the instant return executed, so an object created in & returned by a method/subroutine had to either go in the heap or use RVO. Up to now, I always tiptoed around it by doing the 'Android' thing & passing my return-object containers TO methods & reusing them.

@Bitbang3r Well, yes, you could always pass one by reference.

@Bitbang3r See amended answer for more explanations about the heap.

In most cases, thanks to return value optimization the returned object is constructed in the stack frame of the caller, avoiding the copying step.


text:
PWM of a frequency signal?
Working on my first real sketch, so will try to keep this short.  Feel free to ask more info if needed.
To power a flyback transformer I need to apply PWM -to- a PWM signal.  The easiest way to describe this is that while a standard PWM signal is 'on' for some set time, then 'off' for the remainder of the period, I need to send a signal where the 'on' is actually a 14kHz square wave of 50% duty...then pulse this signal ~1 to 100% duty at ~500Hz.
No problem with the 14kHz PWM - I found the PWM.h library and set that up.
But what is the best way to chop that up with a second PWM at, say 500Hz?
With some amount of kludge, can I 'bit bang' it with DO - WHILE?  Will WHILE read a variable outside the loop?  Are there easier ways?
i=1;
do {                                //Pulse microsecond 'frames' of high freq signal?
                                    //ie 14kHz carrier PWM'd at 500Hz = 2000 microseconds per 'frame' cycle
                                    //at 50% duty would be 1000 micros high and 1000 micros low

    pwmWrite( outpin, 128 );        //Turn on 14kHz carrier at 50% duty
    delayMicroseconds(1000);        //Delay to generate the 'HIGH' portion of the frame
    pwmWrite( outpin, 0 );          //Turn 14kHz carrier off
    delayMicroseconds(1000);        //Delay to generate the 'LOW' portion of the frame
   } while (i == 1);                //...and keep doing loop while the state is '1' or 'ON'

delay(1000);                        //?Will this allow the above loop  to repeat while waiting here for 1 second?
i=0;                                //i != 1, so break out of the while loop above?
                                    //then continue doing other stuff below...

Any help greatly appreciated.

A 14kHz 50% pwm is not a pwm, it is a tone of 14kHz. How accurate should the 14kHz carrier and the 500Hz modulation frequency be? It is possible with 'tone' for the 14kHz and 'millis' for the 500Hz.

Your do ... while here is an infinite loop.

Thanks for the input.  I considered the tone() command as well.  In this instance they are virtually interchangeable.  tone() might save one step because it is automatically 50% duty, where i have to specify 50% (128) with every call of pwmWrite.  Accuracy is not critical.  The 14kHz tone/pwm I currently have is more than accurate enough.  The 500Hz could drift around quite a bit, too.  Seems like I need to set up the i variable going into the loop and increment it from inside there?

Consider using the TimerOne library to set up a timer/interrupt-based callback for the 500Hz portion, which toggles a 14kHz tone().

Possibly this is a better way to attack from the WHILE side? (sorry, not getting code to work)
'  i = 1 ;
while (i<=100) {
pwmWriteHR( pinout, 128 );
delayMicroseconds(500);
pwmWriteHR( pinout, 0 );
delayMicroseconds(500);
(i ++);
}'

It should work, but it's a contrived way to write a basic for loop.

Using tone() (which uses Timer2) for the carrier signal, and Timer1 for the modulation makes use of peripherals that are part of the microcontroller and thus don't need a while loop to direct. You just set it up/start it and it goes. If you use the TimerOne library, the only significant additional code is to toggle the tone() function on and off. The function you write to do that is repeatedly called at the rate you set in TimerOne.

On an Arduino Mega (or an Uno with the ATmega328P replaced with an ATmega328PB, but then you'd have to adapt the code slightly), this can be done via the output compare modulator:
void setup() {
  // CTC, OC0A toggle on compare match, prescale 1/8
  TCCR0A = _BV(COM0A0)|_BV(WGM01);
  TCCR0B = _BV(CS01);

  // toggle every 35.5 μs at 16 MHz and 1/8 prescale
  OCR0A = 70;

  // phase and frequency correct PWM, TOP is OCR1A, OC1C clear going up and set going down, no prescale
  TCCR1A = _BV(COM1C1)|_BV(WGM10);
  TCCR1B = _BV(WGM13)|_BV(CS10);

  // period of 2 ms at 16 MHz and no prescale
  OCR1A = 16000;

  // on-time of 1 ms at 16 MHz and no prescale
  OCR1C = 8000;

  // no interrupts from the timers
  TIMSK0 = 0;
  TIMSK1 = 0;

  // only output a 1 when both timers are outputting a 1
  PORTB &= ~_BV(PORTB7);

  // halt the timers and reset the prescaler
  GTCCR |= _BV(TSM);
  GTCCR |= _BV(PSRSYNC);

  // reset both timers
  TCNT0 = 0;
  TCNT1 = 0;

  // enable output
  DDRB |= _BV(DDB7);

  // let the timers run
  GTCCR &= ~_BV(TSM);
}

void loop() {
  // Just adjust the frequencies and duty cycle as required here.
  // Everything is handled by the hardware and takes effect immediately upon writing to the register.
  // OCR1A: the desired period of the slower signal, in 8ths of microseconds. Can be up to 65535.
  // OCR1C: the desired on-time of the slower signal, in 8ths of microseconds. Can be up to 65535.
  // OCR0A: 1 less than the desired period of the faster signal, in microseconds. Can be up to 255.
  // The on-time of the faster signal is always half of the period.
  // If necessary, you can trade precision for more range for any of the above values by adjusting the prescaler.
}

With that sketch, pin 13 on the Mega will have the desired waveform. There's two big advantages to this method. First, it doesn't require any CPU resources at all (no loops or interrupts) once it's set up, so you can dedicate all of loop to reading the potentiometer and adjusting the duty cycle without worrying about glitches in the output. Second, being entirely hardware controlled means its output will be accurate and perfectly consistent (the 500 Hz component is perfect, and the 14 kHz component is approximately 14085 Hz). The one disadvantage, though, is that millis and everything else in the Arduino library that uses timers internally won't work quite right, since we're using the same hardware timers that they depend on.

@Sam43 This is now updated to let you vary the duty cycle of the 500Hz signal.

Your 14kHz carrier can be generated by the tone() function that is part of the Arduino core. You can then use the TimerOne library to toggle the tone on and off.
Here is an untested sample sketch demonstrating the usage:
#include <TimerOne.h>

const uint8_t outpin=4;

void setup() {
  // put your setup code here, to run once:
  pinMode(outpin, OUTPUT);
  Timer1.initialize(1000);  // 1000 microseconds per half-cycle
  Timer1.attachInterrupt(toggleCarrier);
}

void loop() {
  // put your main code here, to run repeatedly:

}

void toggleCarrier() {
  static uint8_t isPlaying;
  if (isPlaying) {
    noTone(outpin);
    isPlaying=0;
  } else {
    tone(outpin, 14000);
    isPlaying=1;
  }
}

This code work great as written for the case of a 50% duty cycle at 500Hz. Thank you!! I have a lot more to study with timers and interrupts.
The last piece of the puzzle is that I am reading a variable pot and converting that 0-1023 reading to 1-100% duty on the 500Hz signal. So given the 2000 microsecond full cycle I would read the pot, then cycle anywhere from 20uS on/ 1800uS off, to the full 2000uS on.
I suspect I could add more code to the toggleCarrier() section, but is that the best method? set up another timer?
TIA!


text:
nodeMCU - Millis() - Simple Counter - How long is LED on?
PROGRESS, now I have this (WITH GREAT HELP):
void setup() {
   Serial.begin(9600);
// initialize digital pin 13 as an output.
}
uint32_t timer_start = 0;
int timer_running = false;

void loop()
 {
// Get LDR information
  int sensorValue = analogRead(A0);         // read the input on analog pin 0
  float voltage = sensorValue * (5.0 / 1023.0);     // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V)
  float lux = voltage * 100;

 if (lux>150) {
    if (!timer_running) {
      // Timer is not already running, so capture the start time
      timer_start = millis();
      timer_running = true;
    }
  } else {
    if (timer_running) {
      // The timer is currently running; stop it calculate/print the run time
      timer_running = false;
      Serial.println((millis()-timer_start) / 1000.0, 3); // format however you like here

    }
  }

 }

This now tells me how many millis the gymnast is in the air, divided by 1000.0 with 3 decimals. If I start the Serial Monitor when the gymnast is in the trampoline bed, then I can get the seconds of air_time the gymnast has. Is there a way to have this script running ONLY for 10 loops?

You test if the lux is above 150 and always execute that code as long as the lux is above 150. You need to know the moment that the lux is above 150 for the first time. Have a look at this example: https://www.arduino.cc/en/Tutorial/StateChangeDetection Turning millis into minutes and seconds can be done with /60 and %60 after the elapsed millis is divided by 1000.

I think you need to maintain a static unsigned long last_off = 0; state variable in loop{}, resetting at the end of the else clause: last_off = millis();  and also report at the beginning of the else clause if some on_time=millis()-last_off is greater than some threshhold.  Are you having problems with the formatting?  Or with calculating the on time?

With your updated code, you did not maintain the same code structure as in the given example. In your updated code, the if (lux>150) {...} block has the timer start and stop code, where instead, the if (lux>150) {...} block should have the timer starting code, and the else {...} block (meaning, where lux<=150) should have the timer stopping code.

Declare a global (or static) boolean variable to keep track of whether the timer is running or not, as well as a variable to hold the start millis() value. When the lux drops below your threshold, subtract the current millis() from the start value, and you have the duration in milliseconds, which is trivial to convert to mm:ss.sss format.
Example code (not a complete sketch)
uint32_t timer_start = 0;
uint8_t timer_running = false;

void loop() {
  if (lux>150) {
    if (!timer_running) {
      // Timer is not already running, so capture the start time
      timer_start = millis();
      timer_running = true;
    }
  } else {
    if (timer_running) {
      // The timer is currently running; stop it calculate/print the run time
      timer_running = false;
      Serial.print(millis()-timer_start); // format however you like here
    }
  }
}

This now tells me how many millis the gymnast is in the air, divided
  by 1000.0 with 3 decimals. If I start the Serial Monitor when the
  gymnast is in the trampoline bed, then I can get the seconds of
  air_time the gymnast has. Is there a way to have this script running
  ONLY for 10 loops?

Certainly. If it is assumed that you want a cumulative total air-time, then you need to declare another global or static variable to hold the cumulative air-time, and you need to have another variable to keep track of how many cycles have passed.
void setup() {
   Serial.begin(9600);
// initialize digital pin 13 as an output.
}
uint32_t timer_start = 0;
int timer_running = false;
uint32_t total_time = 0;
uint8_t jump_count = 0;

void loop()
{
// Get LDR information
  int sensorValue = analogRead(A0);         // read the input on analog pin 0
  float voltage = sensorValue * (5.0 / 1023.0);     // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V)
  float lux = voltage * 100;

  if (jump_count<10) {
    if (lux>150) {
      if (!timer_running) {
        // Timer is not already running, so capture the start time
        timer_start = millis();
        timer_running = true;
      }
    } else {
      if (timer_running) {
        // The timer is currently running; stop it calculate/print the run time
        timer_running = false;
        // Add this-jump air time to the cumulative total:
        total_time += millis()-timer_start;
        // Increment jump_count
        jump_count++;

        Serial.println((millis()-timer_start) / 1000.0, 3); // format however you like here
      }
    }
  } else {
    // Print the total air-time for 10 jumps;
    Serial.println((total_time)) / 1000.0, 3);
  }
}

Why uint16_t and uint8_t? Why not just int?

Those types are not critical. On Arduino, memory is tight, so it's simply a preference to use the smallest necessary variable type. timer_running can fit in the smallest type, uint8_t, while any result from millis() is an unsigned long, equivalent to uint32_t (fixed in the example code; should not have been uint16_t)

Alright, thx. Now for the timer_running, what is the reason for the "!" exclamation mark? And does the timer go in the void setup, in the void loop or in between?

! is the negation operator. So you are checking if NOT(timer_running) then do whatever. So if the timer is already running, you do not save the current millis() because you're already counting time.

What it is counting? All I see are 1 and 0's?

It's counting milliseconds. That's why, when the light goes off, you take the current value of millis() and subtract the millis() value that was saved when the light first when on, and you get the duration in milliseconds. As noted, converting that to hours/minutes/seconds/milliseconds is trivial. Do you understand the code you wrote?

Hi Jose, the latest sketch you provided, works. It does however Serial.println the Total time over and over again, is there a way to only print this once? I plan later on to include a LCD or screen in another fashion but for now, a Serial.print is better than nothing. Regarding my understanding the code I wrote. The answer will be that, I have never learned this anywhere, but I experience and learn by doing / watching / asking. What I don't understand in this code is: Why do we need jump_count++ and not only jump_count+. I understand the rules of if, else, while, etc but it's all learn by doin

Let us continue this discussion in chat.