text:
Servo starts to shake when I added SIM900.begin(19200);
Hello I'm working on this mini project. This project works this way, Whenever someone type wrong password, LCD will display "Access Denied" and send an alert to SMS using GSM module.  I used 2 Arduinos for this project, The 1st Arduino is powered up by my laptop this is where the signal pins are connected the RX/TX of GSM is connected in (pin 10 and 11) respectively and the LCD is in pin (2-9) and Servo to (A4) . The second Arduino I used is powered up with a charger and used it for GSM power source it function well as it blinks every 2 sec. I'm really wondering why my servo is shaking whenever I add the  SIM900.begin(9600); at the setup in Arduino IDE?
This is the code

#include <Keypad.h>
#include <Password.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#include <SoftwareSerial.h>
SoftwareSerial SIM900(10, 11);

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Password password = Password( "9999" );
Servo myservo;

const byte ROWS = 4;
const byte COLS = 4;

char keys[ROWS][COLS] = {
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
};

byte rowPins[ROWS] = {3, 4, 5, 6};
byte colPins[COLS] = {7, 8, 9, 10};

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
int pos = 0;

void setup(){

  Serial.begin(9600);
  SIM900.begin(9600);

  myservo.attach(13);
  lcd.begin(16, 2);
  lcd.print("Arduino Password");
  lcd.setCursor ( 0, 1 );
  lcd.print (" Door  Lock ");
  delay ( 2000 );
  setup1();

}
void setup1(){

  lcd.clear();
  lcd.home();
  lcd.print("Enter your code:");
  keypad.addEventListener(keypadEvent);
}

void loop(){
  keypad.getKey();
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
    case PRESSED:
        Serial.println(eKey);
        switch (eKey){
          case '4': checkPassword(); break;
          case '2': password.reset(); break;
          case '8': lock(); break;
          default: password.append(eKey);
     }
  }
}

void checkPassword(){
  if (password.evaluate()){
    lcd.clear();
    lcd.print("Access granted");
    delay(1000);
    unlock();
  }else{
    lcd.clear();
    lcd.print("Access denied");
    delay(2000);
    sendSMS();
    delay(1000);

  }
  password.reset();
  delay(1000);
  setup1();
}

void unlock(){
  lcd.clear();
  lcd.print("Unlocking...");
  delay(2000);
  pos = 90;
  myservo.write(pos);
  lcd.clear();
  lcd.print("Unlocked! Press");
  lcd.setCursor(0, 1);
  lcd.print("* to lock!");
  delay(1000);
}

void lock(){
  lcd.clear();
  lcd.print("Locking...");
  delay(1000);
  pos = 0;
  myservo.write(pos);
  setup1();
}
void sendSMS() {

  SIM900.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
  SIM900.print("AT+CMGF=1\r");
  delay(100);
  SIM900.println("AT + CMGS = \"+6XXXXXXXXXX\"");
  delay(100);
  SIM900.println("Wrong password Typed");
  delay(100);
  SIM900.println((char)26);
  delay(100);
  SIM900.println();
  // Give module time to send SMS
  delay(5000);
}

Servo.h use interrupts to generate the control signal. However, SoftwareSerial really messes interrupts up.
You can't use SoftwareSerial with anything that relies on interrupts for timing, like Servo.h.
Solutions:

Use a better Arduino with an unused hardware UART
Use an external hardware PWM controller to drive the servos
Use the internal hardware PWM (you'd need to find a library to do this) to drive the servos.

You can't use SoftwareSerial with anything that uses Timer1.  You can use all the other interrupts that you want.

Is there any library available for gsm that won't messes interrupts? or can you  suggest a best article for the internal hardware PWM ?

@Delta_G SoftwareSerial disables interrupts when sending. It also blocks all interrupts while receiving. You can't sensibly use SoftwareSerial with any timer interrupts and have it do anything reliable.

@Chard You may get better luck with AltSoftSerial. I did see a hardware PWM library around once, but I can't recall where. Ask Google - she knows.

I tried to replace SoftwareSerial to AltSoftSerial but stil the servo is shaking.

Btw I'm using Arduino Uno

@Chard Get a more suitable board then - or an external PWM servo driver module.

So it means there's no possibility to work this project on Arduino Uno? why? is it because of the interrupt pins?

It is possible - it just isn't easy. You need a good understanding of the underlying hardware. The problem you have is lack of suitable hardware resources, so are having to use software emulation ("Bit Banging") to get around it. And that doesn't work well when you're trying to do other things as well.

Both SoftwareSerial and Servo are trying to use the same hardware timer, Timer1.  There are other servo libraries like ServoTimer2 that will allow you to use SoftwareSerial and there are other soft serial libraries that will allow you to use Servo.  It is a pretty common topic that comes up a lot.  If you search a little bit you should find several solutions.

I used the #include"ServoTimer2.h" and remove the #include<Servo.h>. but the servo is still shaking.

SoftwareSerial does not use a timer.  It uses PCINT to trigger reception, and both reception and transmission of data use a "tuned delay" based on _delay_loop_2 which is a hard blocking loop written in assembly (in delay_basic.h).


text:
Controlling multiple stepper motors non-simultaneously
I want to control multiple stepper motors one after another and at different speeds/directions. I am using the ULN2003 driver and the stepper has 5 coils.
My current code for controlling one motor is:

#include <Stepper.h>

const int stepsPerRevolution = 500;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(50);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
}

How would I define each stepper motor differently?
Sorry if I have not asked the question properly. I will try to clarify as time goes on.

How about multiple variables of the type Stepper, each representing one stepper motor? Do you understand how the code above works?

@chrisl Yes, I do understand how the code works. I just want to know how to control two different stepper motors. For example, above we have a stepper motor being defined as myStepper.... Oh, do I just have to replace ‘myStepper’ with ‘Stepper2’? Right??

Exactly. Each Stepper variable controls 1 motor. That should work.

just a note: that is a Stepper object, not a Stepper variable

Like @chris! suggested, you could include two Stepper variables. So in the line where you were initializing the variable, you could instead have:
Stepper steppermotor1(stepsPerRevolution, 8, 10, 9, 11);

Stepper steppermotor2(stepsPerRevolution, 4, 5, 6, 7);

and then continue on with the code for speed, rotation and so on for each motor.

just realized you got your answer after reading through the comments. Never mind then. Thanks :)

source: Stack Exchange

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

sort: votes


text:
Matlab and Arduino Serial communication
I'm new to Arduino and am learning how Serial communication works. I am trying to send a value from Matlab to Arduino, but it seems to be partly fruitful. If anyone can explain the difference between the acquiring input and predefined strings in Matlab
Here is the program I tried, and it is successful.
Arduino :
 %This program receives an array of chars and stores them in array and transmits them back

 const int no_of_fields = 3;
 int field_index = 0;
 int vec_to_hold[no_of_fields]; //Array to hold the numbers

void setup()
{
   Serial.begin(9600);
}
void loop()
{
   if(Serial.available())
    {
     char ch = Serial.read();
     if(ch >= '0'&& ch<= '9') //check if the received chars are digits
      {
         if(field_index<no_of_fields)
           {
              vec_to_hold[field_index] = (vec_to_hold[field_index] * 10) + (ch -'0'); //accumulate values to form and integer
           }
      }
     else if(ch == ',')
     {
       field_index++;
     }
     else if(ch == '\n')
     {
        for (int i = 0;i<min(no_of_fields,field_index+1);i++)
         {
         Serial.print(vec_to_hold[i]);
         vec_to_hold[i] = 0;
         }
        Serial.println();
        field_index = 0;
      }
   }
}

Here is the Matlab side of Code :
delete(instrfindall)
S = serial('COM3', 'BaudRate', 9600,'Terminator','LF'); %38400
fopen(S);
pause(0.1);
vec_sent = input('Enter : ','s');
fprintf(S,'%s\n',vec_sent);
pause(0.1);
t_value = fscanf(S,'%d');
disp(t_value);
delete(instrfindall)

The above code is working, but what if i don't want to enter the string. I want to be predefined.
For example in the above matlab code
vec_sent = '200,300,400';

If i convert this line
 vec_sent = input('Enter : ','s');

to
 vec_sent = '200,300,400';

it does not work. The RX pin on the Arduino blinks indicating something is coming on the serial, but TX pin is not at all blinking, and nothing appears in MATLAB except an error stating
 Warning: Unsuccessful read: A timeout occurred before the Terminator was reached..

I would be grateful if anybody points out what I am doing wrong.
Thanks in advance.

To confirm that the cause of the connection problem is not the software, you can try to connect using reliable software. Do do this, download and install the MATLAB support package for Arduino hardware: http://www.mathworks.com/hardware-support/arduino-matlab.html

The Arduino parsing code seems to function correctly. If I just use the IDE Serial Monitor window and enter "200,300,400", the Arduino replies "200300400".
The error message says that you either did not get the LF, or the LF did not arrive within 0.1 seconds.
One thing to try, as I do not have MATLAB, is to change how the Arduino replies.  On the Arduino, Serial.println will send a CR and a LF at the end.  Perhaps you should just do the LF explicitly instead:
for (int i = 0;i<min(no_of_fields,field_index+1);i++)
{
  Serial.print(vec_to_hold[i]);
  vec_to_hold[i] = 0;
}
Serial.print( (char)10 ); // just LF, not CR/LF with println
field_index = 0;

This will test whether the CR is causing a line termination problem in MATLAB.
Another possibility is that the pause(0.1) is too short.  The documentation states that this is highly dependent on the OS timer resolution.  Try pause(1).  This will test whether the time is too short.  At 9600, 0.1s is only 100 character times.

Yes i thought of it and tried it yesterday, but with  pause(2). It works perfectly when i put a pause of 2 seconds in MATLAB, but i couldn't come up with the reason. Since you just said that it(pause) might be the reason, would you care to explain why i have to extend the pause time when i am connecting it to Arduino.
I tried with pause(1) but not fruitful, the thought is killing me from yesterday why pause(2)??

Because MATLAB runs on so many OS's, it will exhibit slight differences between platforms.  In this case, the resolution of the timers used by MATLAB is only 1 second: pausing (0,1] could be no pause, pausing (1,2] is <= 1s, etc.  Because there are so many things going on in the background in Windows, and it's not a Real Time OS, the MATLAB developers may have simply said, "Windows Update might be running... Close enough!" :P  I have found MATLAB examples that use pause(1), so sub-second resolution isn't something you should count on.  Answered?  :)

Yes, i agree, it might be one of the reason. Do you think the (DTR - Data Terminal Ready) of the arduino might be the culprit here?
I have obeserved some scenarios arduino taking some time to print to serial monitor.

DTR is probably not the culprit. On the PC side, you must go out of your way to enable DTR handshaking. On the Arduino side, there's nothing in the HardwareSerial class that does hardware handshaking. I don't know which Arduino you're using, so I don't know what's handling the USB interface. If it's using an FTDI chip, it can do DTR/DSR handshaking. More likely, it's just waiting a little bit to gather serial data to send to the PC in a packet. Below some threshold (64 bytes?), it will wait to see if more data is coming.

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


text:
UNO analog input voltage reading not accurate
My loop code is this:
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(float(sensorValue*5000.0/1023));
delay(1);        // delay in between reads for stability

When I read 5V it gives 5000 mV. When I read 3.3V pin it gives 3211 mV. When I read 1442 mV battery it gives 1392. What do you think about this situation?
NOTE: There is no any additive circuit. Just wires.

How do you know your 1442mV battery is actually at 1442mV? Using a Voltmeter? Also, if you measure a 3.3V pin, it is usually off a bit, and I wouldn't be surprised to see 3211mV (or 3400mV) from a 3300mV regulator

Btw it is not necessary to use float(...) to print the number over the serial line, it will accept any data type :)

Both your measurement (e.g. using a voltmeter) and the ADC of the Arduino have a limited accuracy (cf.  table 28.7 in the datasheet of the ATmega328). Therefore you should never expect them to agree to all given digits.

All comments are true but it gives 5V correctly, why? And my voltmeter is not corrupted. I also read a voltage refence IC's output, there is a 40-50 mV error still.

Your question contains a number of errors and misconceptions.
Firstly the maximum output of a successive approximation ADC (here 0x3ff) corresponds to Vref - 1 LSB
The voltage will thus be sensorValue*5000.0/1024. Note this error is less than the error of ±2LSB.
Measuring your 5V is futile, as this is the default analog reference, so the result must be 0x3ff.
Measuring the 3.3V pin will give a relative value to the 5V reference. Both are produced from commercial grade regulators with a accuracy of ±5%.
You are also confusing the precision of the reading (10 bit) with accuracy which is a best ±5% ±2LSB.
If you really want to measure voltage you should use the internal 1.1V bandgap reference. You would of course need to reduce the 5V and 3.3V to less than 1.1V. This introduces another potential error (even if you use 1% resistors), but would give more accurate results which are directly comparable.

Is there 1.1V ref. exists in UNO?

Are you sure its not 1023 but 1024?

And note 5V pin is not at 5V, its 5.15 V. I think the problem is this.

@user30878 for 1.1V ref see http://arduino.cc/en/Reference/AnalogReference re 1024 see http://arduino.cc/en/Reference/AnalogRead (or read the Atmega data sheet)

Yes, if the 5V pin is 5.15 then the reference voltage will be high. Thus you need to multiply by 5/5.15 = 0.97 to correct the results. This gives figures which roughly agree with what you got. (3.20 instead of 3.3, and 1398 instead of 1442). Plus what the others said about accuracy.

Both your measurement (e.g. using a voltmeter) and the ADC of the Arduino have a limited accuracy (cf. table 28.7 in the datasheet of the ATmega328). Therefore you should never expect them to agree to all given digits.
Concerning the points raised in your comment:

All comments are true but it gives 5V correctly, why?

analogRead returns a value between 0 and 1023. For all voltages above an (unknown) threshold close to 5 V, it will saturate and always return 1023, no matter what the actual input voltage is. This value is then converted to 5.000 V in your code. What you are probably seeing is just the maximum value your code can return, not an accurate measurement of a 5 V input voltage.

And my voltmeter is not corrupted.

It doesn't have to be corrupted. It will still be off. Have a look at the manual to find the nominal accuracy. (Also note that accuracy and precision are two different things and different from the number of digits of the display, assuming your voltmeter is digital.)

Thanks for clear my mind for maximum voltage. I already know it but I was confused a bit.

I mean voltmeter is working correctly.

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


text:
Run a part of a code only 4 second
I have two different programs written for my Arduino. One control the rockets thrust vector. The other one is for parachute.
I need to first run rotationmatrices() for a 4 second and then parachute.
How could i do that?
Here is my code:
//Libraries
#include <Servo.h>
#include <Wire.h>
#include <MPU6050_tockn.h>
#include <AFMotor.h>
#include <I2Cdev.h>

MPU6050 mpu6050(Wire);

const int MPU = 0x68;
int16_t AcX, AcY, AcZ, Tmp, GyX, GyroY, GyroZ;
double PIDX, PIDY, errorX, errorY, previous_errorX, previous_errorY,
       pwmX, pwmY, previouslog, OutX, OutY, OutZ, OreX, OreY, OreZ;
double PreviousGyroX, PreviousGyroY, PreviousGyroZ, IntGyroX,
       IntGyroY, IntGyroZ, DifferenceGyroX, DifferenceGyroY,
       DifferenceGyroZ, matrix1, matrix2, matrix3;
double matrix4, matrix5, matrix6, matrix7, matrix8, matrix9, Ax, Ay;

//Upright Angle of the Flight Computer-Dik durum açısı
int desired_angleX = 0;

//Offsets for tuning
int servoX_offset = 100;

//Position of servos through the startup function
int servoXstart = 80;

//The amount the servo moves by in the startup function
int servo_start_offset = 20;

//Ratio between servo gear and tvc mount
float servo_gear_ratio = 5.8;

double OrientationX = 0;
double OrientationY = 0;
double OrientationZ = 1;
double accAngleX;
double accAngleY;
double yaw;
double GyroX;
double gyroAngleX;
double gyroAngleY;
double pitch;

Servo servoX;

AF_DCMotor motor1(1); // create motor #1
AF_DCMotor motor2(2); // create motor #2
AF_DCMotor motor3(3); // create motor #1
AF_DCMotor motor4(4); // create motor #2

int buzzer = 3;

double dt, currentTime, previousTime, s, p;

//"P" Constants-Orantısal Değişken
float pidX_p = 0;
float pidY_p = 0;

//"I" Constants-Integral Değişken
float pidY_i = 0;
float pidX_i = 0;

//"D" Constants-Türevsel Değişken
float pidX_d = 0;
float pidY_d = 0;

int pos;

//PID Gains
double kp = 0.2;
double ki = 0.0;
double kd = 0.05;

int state = 0;

void setup() {
    Serial.begin(9600);
    Wire.begin();
    mpu6050.begin();
    gyrocalibrate();

    servoX.attach(10);

    motor1.setSpeed(255);
    motor2.setSpeed(255);
    motor3.setSpeed(255);
    motor4.setSpeed(255);

    pinMode(buzzer, OUTPUT);
}

void loop() {
    mpu6050.update();
    //Defining Time Variables-Zaman değişkeni tanımlanması
    previousTime = currentTime;
    currentTime = millis();
    dt = (currentTime - previousTime) / 1000;
    launchdetect();
    rotationmatrices();
    parachute();
}

void parachute() {
    motor1.run(BACKWARD);
    delay(1500);
    motor1.run(RELEASE);
    delay(20000);
}

void gyrocalibrate() {
    mpu6050.calcGyroOffsets(true);
}

void rotationmatrices(x) {
    mpu6050.update();
    PreviousGyroX = IntGyroX;
    PreviousGyroY = IntGyroY;
    PreviousGyroZ = IntGyroZ;

    IntGyroX = mpu6050.getGyroAngleX() * (PI / 180);
    IntGyroY = mpu6050.getGyroAngleY() * (PI / 180);
    IntGyroZ = mpu6050.getGyroAngleZ() * (PI / 180);

    DifferenceGyroX = (IntGyroX - PreviousGyroX);
    DifferenceGyroY = (IntGyroY - PreviousGyroY);
    DifferenceGyroZ = (IntGyroZ - PreviousGyroZ);

    OreX = OrientationX;
    OreY = OrientationY;
    OreZ = OrientationZ;

    //X Matrices
    matrix1 = (cos(DifferenceGyroZ) * cos(DifferenceGyroY));
    matrix2 = (((sin(DifferenceGyroZ) * -1) * cos(DifferenceGyroX)
            + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * sin(DifferenceGyroX)));
    matrix3 = ((sin(DifferenceGyroZ) * sin(DifferenceGyroX)
            + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * cos(DifferenceGyroX)));

    //Y Matrices
    matrix4 = sin(DifferenceGyroZ) * cos(DifferenceGyroY);
    matrix5 = ((cos(DifferenceGyroZ) * cos(DifferenceGyroX)
            + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * sin(DifferenceGyroX)));
    matrix6 = (((cos(DifferenceGyroZ) * -1) * sin(DifferenceGyroX)
            + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * cos(DifferenceGyroX)));

    //Z Matrices
    matrix7 = (sin(DifferenceGyroY)) * -1;
    matrix8 = cos(DifferenceGyroY) * sin(DifferenceGyroX);
    matrix9 = cos(DifferenceGyroY) * cos(DifferenceGyroX);

    OrientationX = ((OreX * matrix1)) + ((OreY * matrix2))
                 + ((OreZ * matrix3));
    OrientationY = ((OreX * matrix4)) + ((OreY * matrix5))
                 + ((OreZ * matrix6));
    OrientationZ = ((OreX * matrix7)) + ((OreY * matrix8))
                 + ((OreZ * matrix9));

    Serial.println(Ax);
    OutX = OrientationX * 60;
    Ax = asin(OrientationX) * (-180 / PI);
    pidcompute();
}

void servowrite() {
    servoX.write(pwmX);
}

void pidcompute() {
    previous_errorX = errorX;
    errorX = Ax - desired_angleX;

    //Defining "P"
    pidX_p = kp*errorX;

    //Defining "D"
    pidX_d = kd*((errorX - previous_errorX)/dt);

    //Defining "I"
    pidX_i = ki * (pidX_i + errorX * dt);

    PIDX = pidX_p + pidX_i + pidX_d;
    pwmX = ((PIDX * servo_gear_ratio) + servoX_offset);
    servowrite();
}

void launchdetect() {
    if (mpu6050.getAccZ() > 1) {
        state = 1;
    }
    if (state == 1) {
    }
}

void abortstart() {
    if (OrientationX > 40 || OrientationY > 40) {
        digitalWrite(buzzer, HIGH);
    }
    else if (OrientationX < 40 || OrientationY < 40) {
    }
}

Look at the BlinkWithoutDelay example. Learn how to use millis() or micros(). There are many tutorials about that online and its an imprtant principle to learn for Arduino programming.

@chrisl Thanks so much.I will look at them.

at first glance, it looks like your progran stops running when launch is detected  ... the code listing is kind of messy and unfocused looking ... maybe it is an indication of the clarity of your thoughts about the project

here is an example of well formatted code ... it could use a blank line between the case statements, but overall, it should give you an idea of proper formatting ... https://arduino.stackexchange.com/questions/76834/arduino-micro-why-am-i-getting-6-00-as-a-result-instead-of-6-66 ...

you can do it like this using millis it's just an small portion of code just for your understanding you will require some editing for your code.
unsigned long milli1;
void setup()
{
}
void loop()
{
     // code before rotationmatrices() function to be active.
     milli1= millis();
     while(millis()-milli1 <= 4000)  //4000milli sec = 4 sec
     {
      rotationmatrices();
     }
     parachute();

}

That's not a proper use of millis, because it is blocking code as well. Take a look at BlinkWithoutDelay

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


text:
Run a dc motor for amount of time without delay
Hi everyone I have a project and I need to run a dc motor for amount of time without using delay I use DelayWithoutBlink technique.
In this code the motor should run for 5 second in cw then it will change the direction it will other 5second in ccw direction but it seems that there is something wrong with my code, any help would be greatly appreciated.
unsigned long timeRun = 5000;
boolean choiceOne = false;
boolean choiceTwo = false;
boolean directionOne;
boolean directionTwo;
unsigned long timeRunOne;
unsigned long timeRunTwo;

void setup() {
    Serial.begin(9600);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
}

void loop() {
    char t = Serial.read();
    if (t == 'a') {
        while (choiceOne == false) {
            digitalWrite(9, HIGH);
            digitalWrite(8, LOW);
            directionOne = true;
            timeRunOne = millis();
            if (directionOne && (millis()-timeRunOne > timeRun)) {
                choiceOne = true;
            }
        }
    }
    if (t == 'b') {
        while (choiceTwo == false) {
            digitalWrite(9, LOW);
            digitalWrite(8, HIGH);
            timeRunTwo = millis();
            directionTwo = true;
            if (directionTwo && (millis()-timeRunTwo > timeRun)) {
                choiceTwo = true;
            }
        }
    }
}

I wonder if you understand the concept of blink without delay.  Because your code still has delay.  The whole point is that without the delay the loop can run really really fast over and over and will catch when it is time to do things.  Once you introduce a while loop you have broken that because now loop cannot finish and repeat fast, it has to wait for that while loop.

When you do this right there will be no while and no delay.  The code will read like, if the motor is on and it's time to turn it of then turn it off.  Else if it is off and time to turn it on, check which direction it should be and turn it on

You also need to brush up on the difference between = and ==.  Google that one.

ok I will delete delay

there is something wrong with my code is a useless description of a problem ... what is the observed behavior?

In the question you talk about the direction changing automatically, yet in the code it is controlled by the serial port. What gives? 2. There are too many variables in your program. When you have so many booleans, chances are you really need a finite state machine. Also, the variables directionOne and directionTwo serve no purpose, as they are always true when you read them.


text:
How to input delay and increase volume measurements with hall sensor detection
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). However, my code keeps the volume measurement at 0.00 no matter how many times the hall effect is sensed, and I also can't figure out where to insert my delay statement so it does not double count the tips. Any suggestions?
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 = 1.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 - 1) * 5.0; // this is the liters per tip
            Serial.print(Volume);
            Serial.println(" 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()) {
                    long currentMillis = millis();
                    if (currentMillis - previousMillis >= 200) {
                        previousMillis = currentMillis;
                        Serial.print("Volume is now: ");
                        Serial.println(Volume);;
                    }
                }
                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(10000);
            // delay in between reads for stability
        }
    }
}

The float hall_count = 1.0; is a local variable within the loop(){..} function.  To persist state between calls loop(), it needs to be either a global variable declared outside of loop(), or to be static inside the loop, as in static float hall_count = 1.0;


text:
Using OR with a while loop
I am trying to get two limits to or on the same while statement. Can this be done?
while (digitalRead (home_limit)) {

This works for one(1) limit,
But when I try using two(2) limits  is does not work. I can't find the proper configuration. I tried this.
while (digitalRead (home_limit1) || (home_limit2)) {

I also tried other combinations with no luck.
Does anyone know how to do an or (||) statement with a while digital read?

Firstly, when posting code select it and press ctrl+k to formatt it properly.
Try putting digitalRead in for both conditions and also specify what digitalRead value it should be

In while(digitalRead(home_limit1) || home_limit2), the program will not evaluate home_limit2 as long as digitalRead(home_limit1) return 1, is that what you want? do you really means while(digitalRead(home_limit1) && home_limit2)? If this is not what you want, you will need to edit your post to explain in plain English of what you want first.

I have a slide with two limits on it. One at each end of the slide. I'm doing experiments with this slide. At one time during programming I want home_limit1 to operate as a home switch for the CW direction. In a different program I want the slide to run in the opposite direction, CCW and now home_limit2 will now act as a home switch. I just wanted to know if I could or 2 digital reads together as shown above. while(digitalRead(home_limit1) || home_limit2). This way I could change the logic below the statement and make the motor run to the counterclockwise Direction and trip home_limit2.

digitalRead() is a function. It takes one parameter (the pin number) and returns the state of that pin.  It's that return value that you want to OR with another. Which means you have to read the state of both pins, separately, and OR the results together:
while (digitalRead(home_limit1) || digitalRead(home_limit2)) {
    ....
}

Thank you, would it be possible to show me that code?Not sure how to use the return values of both to OR them in the program.

@BillPatton You mean aside from the example I've already given you?

Yes please. How would I go about accomplishing this in your estimation.

@BillPatton by using the code example that I already provided!

@BillPatton: Majenko's line of code in this answer is all you need. digitalRead(home_limit1) returns the state of this pin: a zero or a one. Likewise digitalRead(home_limit2) returns the state of that pin: a zero or a one. The while loop will be executed until both digitalReads return a zero.

Ok I see. I'll give that a try thank you very much.


text:
Make Arduino send and receive at the same time
I am working on a project where I connect a GPS module and GPRS SIM900 shield. The location will be sent when it recives a certain character.
Now my question is, can the Arduino receive from GPRS and GPS module data at the same time? The GPS is not given coordinates, however it works properly without receiving a message from the GPRS.
I am using softwareserial  for both. Should/can I use hardware serial and softwareserial?

You cannot receive from two softwareserial devices at the same time.

I am using SoftwareSerial for both.

As others have said, you cannot listen to 2 SoftwareSerial ports at the same time.

Should/can I use HardwareSerial and SoftwareSerial?
... can the Arduino receive from GPRS and GPS module data at the same time?

Yes, but...
This answer provides full details on choosing "good" combinations of hardware and software serial ports.  To summarize:

Use the HardwareSerial port (i.e., Serial) for one of the devices.  You can still use it for debug prints, as long as the device has some kind of command "format".  For example, if commands start with "AT", just make sure that none of your debug prints start with "AT".  It is the absolute best choice.  You would have to disconnect RX pin 0 from the device in order to upload new sketches over USB.
Use AltSoftSerial for the other device.  It is the most efficient software serial port, and it can be used at the same time as Serial.  It only works on two specific pins.
NeoSWSerial is the next best choice, at limited baud rates.  It can be used with the above choices, but transmitting on NeoSWSerial prevents them from receiving.
SoftwareSerial is the worst choice.  Receiving or transmitting on SoftwareSerial prevents all of the above from receiving anything.  It disables interrupts for long periods of time.

Probably you don't need to use both GPS and GPRS in same time. Just check for a certain character from GPRS in the loop and when it comes check the GPS data.
Why not connect GPS module to hardware serial?

you can connect gps to hardware serial port rx and gsm to software serial.  in similar way,  I solve the problem


text:
nrf24l01+ does not work with a battery, or very unreliably
For a project in progress, I have an Arduino UNO sending a message when a condition occurs, and a Raspberry Pi that listens to it. Both are fitted with NRF24L01+ modules with antennas.
It works perfectly when the Arduino is powered from a wall socket, for instance using a 9V / 1A power supply. But when I try it with a 9V battery (which is supposed to supply 600 mAh), the Raspberry Pi receives only 1/10 of the messages.
Could you tell me:

Why this happens
How I can solve this problem (software / wiring / capacitor / ...)
What would be the best way to power an Arduino whose only job is to detect that a switch closes, and emit a message over the air

Here is the code of the emitter (Arduino). And there is the code of the receiver (Raspberry Pi).
Thank you.

600mAh is capacity, not current.

4 rechargeable AA batteries (4 x 1.2V)(bypassing the voltage regulator). Note that you will probably only get a few days of usage out of batteries, because you are using an UNO, since the USB-to-Serial chip doesn't sleep.

Actually I think I should be able to use just two AA batteries. I was just testing the design on the UNO. It's really not a low power device... The regulator sucks a lot of current, and there is the power LED. So it's probably using most of the juice of the 9V battery already, doing nothing.

According to the datasheet of another 9V battery, I should not expect more than 30 - 50 mA of constant current. This is probably the reason why.
Long story made short: One can not power a NRFL01+ reliably with a 9V battery.
I'd be better off using 2xAA batteries.

According to my measurements, the Uno would take 50 mA from a 9 V battery. You are already at the upper end of the range you quoted. Now power up a transmitter and the voltage probably drops so low it fails. One can not power a NRFL01+ reliably with a 9V battery - more like, "One can not power a Uno reliably with a 9V battery".

I'd be better off using 2xAA batteries. - why not 3xAA batteries? That's only 4.5 volts. Put it straight onto the 5 V pin.

Does anyone have idea/guess, for how long it will run on 3xAA batteries ?

Another thing to consider is that a nrf24l01+ chip at full power will potentially be pulling more current than your 5v reg can supply, try a lower power setting on the PA.

This is exactly the opposite. NRF24L01+ draws maximum 14mA of current. Arduino Uno board draws much much more.

Add a 100uf capacitor between ground and 3.3v directly on the nrf breakout. They're very susceptible to noise on the power supply. I had issues with the same thing and this solved it. Also, make sure you're powering from 3.3v. Also make sure you solder the negative to the negative!

I got a similar problem while not exactly the same but it may include the solution. I have a arduino nano with the nrf24l01 with the adapter and antenna (PA LNA). Transmitter work well but the receiver only work/receive data when plug by USB to the computer, not using an external battery (by USB too). I search for hours looking for a solution (the capa, the robin nrf24 tutorial, SPI problem, power supply problem, trying with another nrf24 module...) without finding any reason for this unexpected behaviour. Then i figured out that  the USB cable that i use make a big difference: two were preventing transmission, one allowing transmission (the 3 cables perfectly work to upload sketch): i was thinking to a ground plan problem due to different size of USB cable but then i check the voltage arriving on the adapter of the nrf24l01. It was 4.7V for the cables that doesn't work, 4.6 with the cable that work. Then i just bypass the arduino alimentation of the nrf24l01  by using a regulated power supply directly applied on vcc and gnd of the adapter. By manually adjusting the voltage i could trigger the transmission with 4.5 V and stops it at 4.7V. I don't know why it's work like this (defect of the 5V to 3.3V regulator of the adapter?) but that do the trick for me. I know that it looks like a very unlikely solution for you but if you are desperate after hours of research, take a minute to put a voltmeter just before the adapter to look for difference in  the voltage in the condition where it works versus where it doesn't work.


text:
Can Ultimate GPS module use arduino micro instead of UNO?
i am doing a Ultimate GPS module like this:
it works when i use arduino UNO board, but when I use arduino micro board it doesn't work, so could anyone tell me how to fix it?.By the way I use the example code in GPS library.
UNO: the data looks like messy code

Micro: didn't give me any time, date or fix

Your photo shows the GPS connected to pins 0 and 1 (RX and TX) on the UNO.  But you don't show the sketch you are running.  Do you have it set that way in the sketch?
It turns out the micro and UNO are different in the way those pins work.  From http://arduino.cc/en/Main/arduinoBoardMicro

Serial: 0 (RX) and 1 (TX).  Used to receive (RX) and transmit (TX) TTL
  serial data using the ATmega32U4 hardware serial capability. Note that
  on the Micro, the Serial class refers to USB (CDC) communication; for
  TTL serial on pins 0 and 1, use the Serial1 class.

This suggests to me that you'd need to change the code to read pins 0 and 1.
Easier is probably to wire it up to pins 2 and 3 and use the defaults in the sketch
// If using software serial, keep this line enabled
// (you can change the pin numbers to match your wiring):
SoftwareSerial mySerial(3, 2);

https://learn.adafruit.com/downloads/pdf/adafruit-ultimate-gps.pdf    actually, the first photo is from Page 7. And the second photo is the result that showed on serial Monitor after i wired it like Page 11, the last one is the result after I change the board to micro. and I use example code in ultimate GPS library

The important parts of your question should be: how is it wired up and what is the sketch doing?  The only source for the first is the photo, so if it doesn't reflect your wiring, please tell us how it's wired  The current example library uses pins 2 and 3, so I don't know if you've modified yours.  Pasting the sketch (or at least the relevant bits from the top where the pins are set) would be recommended.

The Arduino Uno and Micro, in practice, work almost exactly the same. Just make sure that your wiring is correct (In this photo, the wires go from TX to TX and RX to RX, they should go between TX on one board and RX on the other, and vice versa.
Your code should work on a micro exactly as it does on an Uno. That is one of the best features of Arduino; the ability to port code to another board without much (if any) modification.

I am sure my wiring is correct. Actually, it should show me something on the serial Monitor after uploading the code, but it doesn't if I use Micro board.

@weiyulu That is strange. Can you get another sketch on the micro to send something on the serial monitor, to see if it is an issue with the micro or not?

https://learn.adafruit.com/downloads/pdf/adafruit-ultimate-gps.pdf   this is the ulitmate GPS guide, i just do what the guide ask me to do, and the serial monitor should show something like page 13, but in my serial monitor it doesn't show the correct data, like this:                                                                                Time: 0:0:0.0
Date: 0/0/200
Fix: 0 quality: 0

Right. I think what you are doing wrong is your wiring. For the sketch to work as on page 13, you need to connect TX on the GPS up to pin 3 of the Arduino and RX of the GPS up to pin 2 on the arduino. Then, make sure you have downloaded the library and uploaded the sample code. Then open your serial monitor and it should display as in page 13. Could you do this with both arduinos, making sure you wire up the pins not as in the photo above, but as I just said, and then tell me the results on both arduinos? The wiring as in page 11 By the way. @weiyulu

@ harry_p_6 this time i wired exact the same like page 11, but it still didn't work. I put the result photo in the question.

The micro and the uno are not always drop in replacements for each other. Serial on the Uno refers to pins 0 and 1, but on the leonardo/micro it is serial1 that is connected to 0 and 1.


text:
What phone carriers are available in the USA that are compatible with a sim900 breakout board
I was wondering what carriers are compatible with a sim900 breakout board. I know it needs a GSM network (AT&T,T-mobile,?) but what networks can I use?
It needs a 850/ 900/ 1800/ 1900 MHz frequency to work but who offers that frequency? I personally could not find what frequency cell phone companies offered. From how I understand it is that T-Mobile definitely will work.I have heard several different answers about companies like AT&T and I have seen discussion about sprint (which I don't understand because they are a CDMA carrier).
I have also heard that there are other carriers (Vondafone, nextel,Ting) that might be more cost effective for people like me who are only going to be using the text messaging.
Can someone please set me straight on who I can use.

Vonda Phone? You mean Vodafone?

My apologizes. I have corrected the error. Thank you.

SIM900 should be compatible with both AT&T and T-Mobile. T-Mobile uses 1900Mhz for 2G and AT&T uses 850Mhz and 1900Mhz. Although both carriers are upgrading to 4G, they still support 2G devices. My personal experience is that most quadband 2G devices still work with AT&T and T-Mobile and there is no technical reason why SIM900 shouldn't work. However, there can be issues with incompatible data plans that are compatible only with their own devices. You need to be careful when selecting the contract and buying the sim card.
Nextel and Ting uses Sprint's network which is CDMA and thus wouldn't work. However Vodafone seems to be using T-Mobile's network and may work.


text:
I need help producing 2 pwm signals
My project is to use an Arduino to control two solenoid valves with PWM and receive an input signal from a sensor as feedback.

The valves direct the flow of water which cause a hydraulic actuator to move which is detected by an LVDT sensor.
What I want my program to do is to allow me to set a desired displacement as a goal which causes the Arduino to dynamically change the duty cycle of the pwm signal based off of the feedback input the Arduino receives. I am going to implement a PID to control it.
The circuit consist of the Arduino sending PWM signals to two logic level NPN mosfets to control the solenoids that are powered by 2 external 12V sources.

What I specifically need help with is how to write the part of the program that will let me produce 2 PWM signals that will allow me to change the frequency of the pwm waves so that the solenoids have enough time to switch and then also the ability to set the duty cycle.
I am a total novice programmer and its my first time working with electronics. I'm just hoping someone can point me in the right direction.

What sort of frequency do you need to run the solenoids at? If it's on the order of 10Hz, 1Hz, or slower, you might consider implementing a software PWM rather than use hardware PWM.

If you only need two PWM pins, I suggest using hardware PWM with
Timer 1. The Timer 1 library makes the process quite easy. It
supports frequencies from 0.12 Hz up to a few MHz, although the
resolution degrades above 7.8 kHz.
Compared to an interrupt-based solution, hardware PWM has less jitter
and it does not consume CPU cycles. The drawback is that you will be
limited to 2 channels operating at the same frequency, but this
doesn't seem to be an issue for your project.

I agree, for one or two signals: noting the comment in the sourcecode regarding which pins may be used. I'd also comment that it's to Paul's credit that he respects the license of predecessor code.

You can try to use my AVR_Slow_PWM Library, which can provide these following features and generate 2 independent PWM signals to any GPIO pin. Certainly only if your hardware design can correctly use PWM signals.

This library enables you to use ISR-based PWM channels on AVR-based boards, such as Mega-2560, UNO,Nano, Leonardo, etc., using AVR core to create and output PWM any GPIO pin. Because this library doesn't use the powerful purely hardware-controlled PWM with many limitations, the maximum PWM frequency is currently limited at 500Hz, which is still suitable for many real-life applications

Just out of interest: are you using digitalWrite() for your software PWM?

Yes. digitalWrite() is used whenever a change is necessary.

I've been looking at something similar to this application over the last few days, trying to prepare a skeleton project as a learning exercise for a friend with limited programming experience. While the AVR_Slow_PWM Library looks very good in principle, in practice it desperately needs a simple example generating just one or two signals: nothing clever, just minimal setup and adjustment code similar to the TimerOne library's fan example and definitely not containing any interrupt handler etc. unless this really is necessary.

Tacking on this as a belated observation more than anything else.
Since there is no indication of an accumulator on the hydraulic circuit and the two valves are working in opposition, it might be necessary to maintain both complementary PWM ratios and consistent relative phase.
The TimerOne library appears- by eye- to maintain a consistent relative phase. The AVR_Slow_PWM library definitely doesn't.
If it is /not/ necessary to apply an offset to the PWM edges to accommodate the valves having different open and close times then it might be easiest to simply change the switching sense of one of the FETs with both driven from the same PWM signal (i.e. when one sees 75% on, the other sees 75% off).
If it /is/ necessary to apply an offset then it might end up being best to manually code something in a timer interrupt handler, particularly since I am told that typical valves should operate at about 10Hz but not much faster: this eliminates most of the standard PWM libraries.


text:
Save data permanently on ESP32
I'm working on a stage (this is my first bigger Arduino project), and I want to create an initializer for it, and for this, I want to store some variables in the memory of ESP32 WROVER-B. For this, I found this solution.
Based on their example (which works fine) I write a basic demo, using their Preferences.h:
#include <Preferences.h>

#define MAX_BUFF_LEN  255

Preferences preferences;

char c;
char str[MAX_BUFF_LEN];
uint8_t idx = 0;

void init(){
  preferences.remove("counter");
  preferences.begin("my-app", false);
  unsigned int counter = 0;
  Serial.printf("Current counter value: %u\n", counter);
  preferences.putUInt("counter", counter);
  preferences.end();
}

void readback(){
  preferences.begin("my-app", false);
  unsigned int counter = preferences.getUInt("counter", 0);
  Serial.printf("Current counter value: %u\n", counter);
  preferences.end();
}

void add(){
  preferences.begin("my-app", false);
  unsigned int counter = preferences.getUInt("counter", 0);
  counter++;
  Serial.printf("Current counter value: %u\n", counter);
  preferences.putUInt("counter", counter);
  preferences.end();
}

void setup() {
  Serial.begin(115200);
  //Serial.begin(9600);
  while (!Serial) ; // wait for serial port to connect. Needed for native USB
  Serial.println("start");
}

void loop() {
  if(Serial.available()>0){
    c = Serial.read();
    if(c != '\n')
      str[idx++] = c;
    else{
      str[idx] =  '\0';
      idx = 0;

      Serial.print("Recieved: ");
      Serial.println(str);
      if(*str == 'r')
        readback();
      if(*str == 'w')
        init();
      if(*str == 'a')
        add();
    }
  }
}

But every time I reset (I mean plug out and in) my ESP it starts counting at the beginning. Also if I disconnect the client on the serial port the same happens. What have I missed here, or how can I do it correctly?

You could try using the https://randomnerdtutorials.com/esp32-flash-memory/  EEPROM for example

@Avon97 which says "This tutorial is outdated. Follow the new tutorial instead: ESP32 Save Data Permanently using Preferences Library"


text:
GMS send SMS text messages many times
The GSM sends many SMS text messages and does not stop. How to send only one SMS?
This is my code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);
char msg;
int vibr_pin = 7;

void setup() {
  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);   // Setting the baud rate of Serial Monitor (Arduino)
  pinMode(vibr_pin, INPUT);
  delay(100);
}

void loop() {
  int a;
  a = digitalRead(vibr_pin);
  if (a == 0) {
    mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
    delay(1000);  // Delay of 1000 milli seconds or 1 second
    mySerial.println("AT+CMGS=\"+60125456758\"\r"); // Replace x with mobile number
    delay(1000);
    mySerial.println("test 1,2,3"); // The SMS text you want to send
    delay(100);
    mySerial.println((char) 26); // ASCII code of CTRL+Z
    delay(1000);
  }
}

EDIT:
After I change if (a==0) to if(a!=0), it only sends message when the vibration sensor is moving. How to send sms when sensor is not moving?

my vibration sensor sw-420

use a flag variable to remember if you sent a message

int a;
a = digitalRead(vibr_pin);
if (a == 0) {

This sends an SMS text message every time a is 0. I'm not sure what vibr_pin does, but maybe you want to check only for a trigger (from a != 0 to a == 0).
In that case, use a boolean to check if the SMS text message has been sent, and reset the boolean when a goes from !=0 to 0.

after i change if (a==0) to if(a!=0) it only send massage when the vibration sensor is moving. how to send sms when sensor not moving

Use a boolean (check when the sensor transitions from not moving to moving or vice versa). When that boolean is set (or reset) send the SMS and change the boolean.


text:
I want to get incomming call number and compare it
Hello i want to get and compare incomming call number, it works but not as I want.
When im calling from good number it print that I was calling form saved number when the number is stop calling i need to do it on start. And else is printing when nobody is calling. How can i do it? Here is my code:
String d = "";
void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial1.println("AT");
  delay(500);
  Serial1.println("AT+CLIP=1");
  delay(1000);
  Serial1.println("AT+CPIN=1439");
}
void loop()
{
 d = Serial1.readString();
 if(d.indexOf("xxxxxxxxx") >=0)
   {
 Serial.println("call is from saved number");
    } else {
       Serial.println("call is not from saved number");
      }
}

Hint#1: "readString()" has a timeout. What should your code do then? https://www.arduino.cc/en/Serial/ReadString

@MikaelPatel When it's recognised number I will be sending HTTP POST to my api.

You need to check that a string has received and not returned due to a timeout. It is only when a string with a number, a call, has been received that the valid phone number should be checked. Please fix the control logic of your sketch.

Could you help me with it? I'm new in C but I need it to build my system to mobile app

You could for instance add "if (d.length() == 0) return;" after "d = Serial1.readString();".

Should I add it below my if statements ?

The Arduino Serial class member function readString() has a builtin timeout. The function will return on timeout. The default timeout period is 1000 ms. The timeout can be set with setTimeout().
The sketch needs to filter out empty lines (timeout). This can be done by adding a check of the string length. See below for an example of checking:
void loop()
{
  String d = Serial1.readString();
  if (d.length() == 0) return;
  Serial.print(d);
  if (d.indexOf("xxxxxxxxx") >= 0) {
    Serial.println(": call is from saved number");
  }
  else {
    Serial.println(": call is not from saved number");
  }
}

Cheers!

It still doesn't work

Try the above and check the output to the serial monitor.

I have tried but the biggest problem is that serial print print call is from saved number after I decline calling

Please add an example of the output to the serial monitor. That would help understand the issue.

https://imgur.com/a/PKHDP84

Might want to use readStringUntil() if you want to capture per line and not until timeout. https://www.arduino.cc/en/Serial/ReadStringUntil

String d = Serial1.readStringUntil();  I got the following error : no matching function for call to 'HardwareSerial::readStringUntil()'

You need to give a terminator character. For instance '\r', please read the documentation page.

I will try it as soon as it will be possible. If it works I will give your answer "the best"


text:
compilation error when changing variable from char to String
I have a code with these two lines:
  char handshakecode = "S"; // Capital S
  char receive;

The lines of code are placed in a separate void, and not setup or loop.
When i change the two variables from char to String i get a error(complete error at bottom) when compiling to the arduino or verifying the code.
  String handshakecode = "S"; // Capital S
  String receive;

When i snippes out partial code for just that particular void, it compiles fine, so it must be in combination with the rest of the code, which i have left out from this post at the moment.
Is this a known error or am I doing something wrong?

In function 'global constructors keyed to 65535_0_WFS_v0.3.ino.cpp.o':
lto1.exe: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html for instructions.
lto-wrapper.exe: fatal error: C:\Program
  Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.15.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avr-gcc
  returned 1 exit status
compilation terminated.
c:/program
  files/windowsapps/arduinollc.arduinoide_1.8.15.0_x86__mdqgnx93n4wtt/hardware/tools/avr/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld.exe:
  error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status
exit status 1 Error compiling for board Arduino/Genuino Mega or Mega
  2560.

that does not look like a compilation error ... that looks like a compiler program failure .... try reinstalling the Arduino IDE

This is a known error with the windows store version of the IDE. Delete it and download it from Arduino.

@Majenko it happens with the regular version of the Arduino IDE also.

Interesting. It used to just be the app version. I guess they messed up the real version. Another reason to switch to UECIDE I guess :)

I encountered the bug using the standard Arduino IDE back when the new toolchain was still in beta testing, as well as with the production release. I'm normally all about using the latest versions of everything but I'm stuck with Arduino AVR Boards 1.6.21 until this gets fixed.

I just did a review of all occurrences of the bug and 22 were using the Windows App version of the Arduino IDE, 17 were using the regular Arduino IDE, 3 did not show which version they were using. In all cases, the OS was Windows. So this is good evidence that it's completely unrelated to which IDE version is used.

This bug is specific to the 5.4.0-atmel3.6.1-arduino2 version of avr-gcc used by Arduino AVR Boards 1.6.22 and newer. It has been reported here:
https://github.com/arduino/Arduino/issues/7949
Here's the workaround:

Tools > Board > Boards Manager
Wait for downloads to finish.
When you move the mouse pointer over "Arduino AVR Boards", you will see a "Select version" dropdown menu appear. Select "1.6.21".
Click "Install".
Wait for installation to finish.
Click "Close".

Due to a bug, this workaround doesn't work with Arduino IDE 1.8.6, but it will work with any other version of the Arduino IDE.
If you have File > Preferences > Check for updates on startup checked, the Arduino IDE may occasionally notify you that a new version of Arduino AVR Boards is available, you'll need to refrain from updating back to the new Arduino AVR Boards version, otherwise you'll be back to seeing the segmentation fault error again.


text:
Upload application from Visual Studio 2019 with PlatformIO
How upload application from Visual Studio? I can’t find upload process from standard VS in documentation https://docs.platformio.org/en/latest/ide/visualstudio.html
I hate VS Code.

Sorry but your question is far from both Arduino hardware and Arduino IDE.

I have final solution for uploading application from VS 2019.

Visual Studio have Tools > External Tools... where is possible add the PlatformIO command for uploading application pio run -v -t upload

After that is possible adding custom button to Toolbar
Fantastic thing is, that during upload you can Stop the process

I am using Visual Studio Code, but I suppose the plugin works similar in Visual Studio. Look at the screenshot below.

In red rectangle you have "Project tasks options", where you can find "Upload" button. This will not work, if you have not set at least one environment in platformio.ini file – see the documentation.
Example of the simple environment for Arduino Uno created in  platformio.ini file:
[env:uno]
platform = atmelavr
board = uno
framework = arduino

Of course, I use VS Code for Arduino, but this IDE is unworkable for my. My primary IDE for other development is full Visual Studio. There is support Resharper and many other features, that are on one place, and not in hundred extensions like in VS Code.
I hate VS Code

Ok, sorry, I missed the note about your relationship to VSCode O:-) In Visual Studio I was using Visual Micro plugin to handle Arduino boards, but I suppose that is not what you wanted to hear...

It's ok, I edited my post:) PlatformIO is OpenSource,therefore is better for hobby users than Visual Micro.
I will try PlatformIO CLI pio run -t upload. It is not what I want, but maybe it will enough.


text:
Mesure sensor voltage by 328p and OP Amp in parallel
I am designing a circuit to measure the temperature via a thermistor via the ADC pin on a 328p and I am looking for some advice. As a failover I am also using an OP Amp as a comparator, to see whether the voltage exceeds a certain threshold. My question is the following. What can I do to protect the analog voltage line of the thermistor from interferences from the 328p? Can I connect the thermistor out directly to the 328p and to the MCU? My ideas are the following:

Using an in-line diode before the 328P adc pin, so that it can measure voltage but not interfere with it.
Using an OP Amp voltage follower to provide the voltage to the 328p pin

Is there a better way to do so? Are my possibilities feasible or are there any problems? What are the advantages and disadvantages of one or the other solution?
I am thankful for any help or advice.

simulate this circuit – Schematic created using CircuitLab

The ADC input is very high impedance, so unlikely to interfere with other measurements on the same pin.  You don't need either the diode or the separate op-amp.

@Boggyman however if the output impedance of Thermistor and R1 is around 50k, and you are measuring also something else, there will be much bigger crosstalk than if you have lower output impedance (recommendation from datasheet is up to 10k). However if he's measuring single slowly changing signal, then it won't be affecting it much

@KIIV I am quite new to this, R1 is 100k and I am measuring the voltage via 328p and the OpAmp. What exactly do you mean by crosstalk? Why should the impedance be lower? Hope I am understanding correctly that impedance is the measure of resistance in an AC circuit?

@jack There is a sampling capacitor (few pF), if you are charging it through 100k resistor, it'll take much more time to charge/discharge it from different voltage level, than if you have few kiloohms. And if it takes more than sampling time, you'll be measuring nonsenses. Mainly if you are measuring  something near 0V  and something with high impedance near 5V, it'll be really far from it's real value.

@KIIV thanks a lot for your explanation. I am sampling rather slowly on the 328p (one sample every 5s or so). Do you know where I can find the sampling rate for the OpAmp (LM324DT), I am that I have to ask, I am not even sure an OpAmp has a sampling rate

OpAmps doesn't have sampling rate, it has parameters like input impedance (but it's usually so big so it's usually ommited and defined by external resistors)

Thanks a lot for your help!


text:
Problem sending IR signal on Arduino Leonardo/Uno (IRRemote library)
I am trying to use my Arduino Leonardo (or Uno!) as a remote with the IRRemote library. The current setup picks up and decodes a signal perfectly, but fails to retransmit it.
I have tested the infrared LED and it works.
I have tested the setup against a television IR receiver at very close range.
My board consists of:

I am using the example IRRecord code (included below) with one change -- I made STATUS_PIN P3 (instead of P13), as I read that P13 is used to transmit IR signal on the Leonardo. I made this change after testing all PWM pins (including P3) for transmitting the IR signal. I'd appreciate any help to get this working.
I have also tried this on an Arduino Uno to no effect. This is driving me a little crazy!
Code below.
/*
 * IRrecord: record and play back IR signals as a minimal
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * An IR LED must be connected to the output PWM pin 3.
 * A button must be connected to the input BUTTON_PIN; this is the
 * send button.
 * A visible LED can be connected to STATUS_PIN to provide status.
 *
 * The logic is:
 * If the button is pressed, send the IR code.
 * If an IR code is received, record it.
 *
 * Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;
int BUTTON_PIN = 12;
int STATUS_PIN = 3;

IRrecv irrecv(RECV_PIN);
IRsend irsend;

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(BUTTON_PIN, INPUT);
  pinMode(STATUS_PIN, OUTPUT);
}

// Storage for the recorded code
int codeType = -1; // The type of code
unsigned long codeValue; // The code value if not raw
unsigned int rawCodes[RAWBUF]; // The durations if raw
int codeLen; // The length of the code
int toggle = 0; // The RC5/6 toggle state

// Stores the code for later playback
// Most of this code is just logging
void storeCode(decode_results *results) {
  codeType = results->decode_type;
  int count = results->rawlen;
  if (codeType == UNKNOWN) {
    Serial.println("Received unknown code, saving as raw");
    codeLen = results->rawlen - 1;
    // To store raw codes:
    // Drop first value (gap)
    // Convert from ticks to microseconds
    // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
    for (int i = 1; i <= codeLen; i++) {
      if (i % 2) {
        // Mark
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
        Serial.print(" m");
      }
      else {
        // Space
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
        Serial.print(" s");
      }
      Serial.print(rawCodes[i - 1], DEC);
    }
    Serial.println("");
  }
  else {
    if (codeType == NEC) {
      Serial.print("Received NEC: ");
      if (results->value == REPEAT) {
        // Don't record a NEC repeat value as that's useless.
        Serial.println("repeat; ignoring.");
        return;
      }
    }
    else if (codeType == SONY) {
      Serial.print("Received SONY: ");
    }
    else if (codeType == PANASONIC) {
      Serial.print("Received PANASONIC: ");
    }
    else if (codeType == JVC) {
      Serial.print("Received JVC: ");
    }
    else if (codeType == RC5) {
      Serial.print("Received RC5: ");
    }
    else if (codeType == RC6) {
      Serial.print("Received RC6: ");
    }
    else {
      Serial.print("Unexpected codeType ");
      Serial.print(codeType, DEC);
      Serial.println("");
    }
    Serial.println(results->value, HEX);
    codeValue = results->value;
    codeLen = results->bits;
  }
}

void sendCode(int repeat) {
  if (codeType == NEC) {
    if (repeat) {
      irsend.sendNEC(REPEAT, codeLen);
      Serial.println("Sent NEC repeat");
    }
    else {
      irsend.sendNEC(codeValue, codeLen);
      Serial.print("Sent NEC ");
      Serial.println(codeValue, HEX);
    }
  }
  else if (codeType == SONY) {
    irsend.sendSony(codeValue, codeLen);
    Serial.print("Sent Sony ");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == PANASONIC) {
    irsend.sendPanasonic(codeValue, codeLen);
    Serial.print("Sent Panasonic");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == JVC) {
    irsend.sendPanasonic(codeValue, codeLen);
    Serial.print("Sent JVC");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == RC5 || codeType == RC6) {
    if (!repeat) {
      // Flip the toggle bit for a new button press
      toggle = 1 - toggle;
    }
    // Put the toggle bit into the code to send
    codeValue = codeValue & ~(1 << (codeLen - 1));
    codeValue = codeValue | (toggle << (codeLen - 1));
    if (codeType == RC5) {
      Serial.print("Sent RC5 ");
      Serial.println(codeValue, HEX);
      irsend.sendRC5(codeValue, codeLen);
    }
    else {
      irsend.sendRC6(codeValue, codeLen);
      Serial.print("Sent RC6 ");
      Serial.println(codeValue, HEX);
    }
  }
  else if (codeType == UNKNOWN /* i.e. raw */) {
    // Assume 38 KHz
    irsend.sendRaw(rawCodes, codeLen, 38);
    delay(100);
    Serial.println("Sent raw");
  }
}

int lastButtonState;

void loop() {
  // If button pressed, send the code.
  int buttonState = digitalRead(BUTTON_PIN);
  if (lastButtonState == HIGH && buttonState == LOW) {
    Serial.println("Released");
    irrecv.enableIRIn(); // Re-enable receiver
  }

  if (buttonState) {
    Serial.println("Pressed, sending");
    digitalWrite(STATUS_PIN, HIGH);
    sendCode(lastButtonState == buttonState);
    digitalWrite(STATUS_PIN, LOW);
    delay(50); // Wait a bit between retransmissions
  }
  else if (irrecv.decode(&results)) {
    digitalWrite(STATUS_PIN, HIGH);
    storeCode(&results);
    irrecv.resume(); // resume receiver
    digitalWrite(STATUS_PIN, LOW);
  }
  lastButtonState = buttonState;
}

if you have another arduino, then use it to confirm that the transmitted data is same as the remote control

@jstotola I am using the code above to capture the signal from the TV's remote and then retransmit it from the Arduino to the TV. The capture component works perfectly, but it is not sending a signal -- any signal at all.

I measured voltage across the IR LED while holding down the signal button + looked through a digital camera to see if the LED lights up. I also tried supplementing the IR LED with a visible-light LED.


text:
Arduino RGB IR Controller -> led always close to white
I use arduino nano.
When i use this code the rgb light on the fan is showing the colors right
int rossoPin = 11;
int verdePin = 12;
int bluPin = 10;
void setup(){
  pinMode(rossoPin, OUTPUT);
  pinMode(verdePin, OUTPUT);
  pinMode(bluPin, OUTPUT);
}
void loop(){
    for(int i = 0; i < 256; i++){
    rgb(255-i, i, 0);
    delay(10);
  }
  for(int i = 0; i < 256; i++){
    rgb(0, 255-i, i);
    delay(10);
  }
  for(int i = 0; i < 256; i++){
    rgb(i, 0, 255-i);
    delay(10);
  }
}
void rgb(int red, int green, int blue){
  analogWrite(rossoPin, red);
  analogWrite(verdePin, green);
  analogWrite(bluPin, blue);
}
,but when i use the full controller code it wont work nothing(ex.white color when it's on off state)
FULL CODE:
link to the code

Your code is for a single RGB LED or a simple dump RGB LED strip.  The linked code is for a NeoPixel (WS2812B) strip. Which are you using?

The controller is for an a-rgb strip and I want to control also a single rgb led on a fan, so i have added the function void fanON() which has the above code that works separatly

Does the IR code get correctly received? Honestly I don't want to analyse over 700 lines of code. You should deactivate parts of your code, until you found the problematic code

in the setup i call the function rgb(0, 0, 0); and it supposed to turn off the led when i start the arduino without any input, but the led is showing white. And yes the IR get correctly received. When i press on my ir remote the strip changes color but the led on the fan no->still white


text:
Arduino interruption (on pin change)
I use the interrupt function to fill an array with values received from digitalRead().
void setup() {
    Serial.begin(115200);
    attachInterrupt(0, test_func, CHANGE);
}

void test_func() {
    if (digitalRead(pin) == HIGH) {
        test_array[x] = 1;
    } else if(digitalRead(pin) == LOW) {
        test_array[x] = 0;
    }
    x = x + 1;
}

That problem is that when I print test_array there are values like: 111 or 000.
As I understand it, if I use the CHANGE option in the attachInterrupt() function, then the data sequence should always be 0101010101 without repeating.
The data changes quite fast since it comes from a radio module.

Interrupts don't debounce the button. Are you using hardware debouncing?

Please post the complete code, including pin, x and test_array definition, and also loop() method; it would enable us to see if this can be a concurrency issue when accessing variables modified by test_func.

You should not digitalRead() twice in the ISR: think about what would happen if you get LOW on the first call and HIGH on the second. Instead, if (digitalRead(pin) == HIGH) ... else ...; or, better yet, this single-line ISR: test_array[x++] = digitalRead(pin);.

@EdgarBonet nice! +1 to that comment. I hope you don't mind I've added something to my answer to include what you've mentioned here. Also if you decide to put up your own answer including this detail then I'll remove my addition and give yours an up vote so you get the rep for it.

@Clayton Mills: I am preparing an (overly long and marginally tangential) answer, but you can keep your edit, it is perfectly fine with me.

Why are you doing this in the first place? The only reasonable expectation is that the array would have 1010101010 in it. Thus if it doesn't that is just measurement error. As Edgar Bonet ably explained, such error could happen with fast sequences.

As a sort of prologue to this overly long answer...
This question got me deeply captivated with the problem of interrupt
latency, to the point of losing sleep in counting cycles instead of
sheep. I am writing this response more for sharing my findings
than for just answering the question: most of this material may actually
not be at a level suitable for a proper answer. I hope it will be
useful, however, for readers that land here in search of solutions for
latency problems. The first few sections are expected to be useful to a
wide audience, including the original poster. Then, it gets hairy along
the way.
Clayton Mills already explained in his answer that there is some latency
in responding to interrupts. Here I will focus on quantifying the
latency (which is huge when using the Arduino libraries), and on the
means to minimize it. Most of what follows is specific to the hardware
of the Arduino Uno and similar boards.
Minimizing the interrupt latency on the Arduino
(or how to get from 99 down to 5 cycles)
I will use the original question as a working example, and restate the
problem in terms of interrupt latency. We have some external event that
triggers an interrupt (here: INT0 on pin change). We need to take some
action when the interrupt is triggered (here: read a digital input). The
problem is: there is some delay between the interrupt being triggered
and our taking the appropriate action. We call this delay "interrupt
latency". A long latency is detrimental in many situations. In this
particular example, the input signal may change during the delay, in
which case we get a faulty reading. There is nothing we can do to avoid
the delay: it is intrinsic to the way interrupts work. We can, however,
try to make it as short as possible, which should hopefully minimize the
bad consequences.
The first obvious thing we can do is take the time-critical action,
inside the interrupt handler, as soon as possible. This means calling
digitalRead() once (and only once) at the very beginning of the
handler. Here is the zeroth version of the program upon which we will
build:
#define INT_NUMBER 0
#define PIN_NUMBER 2    // interrupt 0 is on pin 2
#define MAX_COUNT  200

volatile uint8_t count_edges;  // count of signal edges
volatile uint8_t count_high;   // count of high levels

/* Interrupt handler. */
void read_pin()
{
    int pin_state = digitalRead(PIN_NUMBER);  // do this first!
    if (count_edges >= MAX_COUNT) return;     // we are done
    count_edges++;
    if (pin_state == HIGH) count_high++;
}

void setup()
{
    Serial.begin(9600);
    attachInterrupt(INT_NUMBER, read_pin, CHANGE);
}

void loop()
{
    /* Wait for the interrupt handler to count MAX_COUNT edges. */
    while (count_edges < MAX_COUNT) { /* wait */ }

    /* Report result. */
    Serial.print("Counted ");
    Serial.print(count_high);
    Serial.print(" HIGH levels for ");
    Serial.print(count_edges);
    Serial.println(" edges");

    /* Count again. */
    count_high = 0;
    count_edges = 0;  // do this last to avoid race condition
}

I tested this program, and the subsequent versions, by sending it trains
of pulses of varying widths. There is enough spacing between the pulses
to ensure that no edge is missed: even if the falling edge is received
before the previous interrupt is done, the second interrupt request will
be put on hold and eventually serviced. If a pulse is shorter than the
interrupt latency, the program reads 0 on both edges. The reported
number of HIGH levels is then the percentage of correctly read pulses.
What happens when the interrupt is triggered?
Before trying to improve the code above, we will take a look at the
events that unfold right after the interrupt is triggered. The hardware
part of the story is told by the Atmel documentation. The software part,
by disassembling the binary.
Most of the time, the incoming interrupt is serviced right away. It may
happen, however, that the MCU (meaning "microcontroller") is in the
middle of some time-critical task, where interrupt servicing is
disabled. This is typically the case when it is already servicing
another interrupt. When this happens, the incoming interrupt request is
put on hold and serviced only when that time-critical section is done.
This situation is hard to avoid completely, because there are quite a
few of those critical sections in the Arduino core library (which I will
call "libcore" in the following). Fortunately, these sections are
short and run only every so often. Thus, most of the time, our interrupt
request will be serviced right away. In the following, I will assume
that we do not care about those few instances when this is not the case.
Then, our request is serviced immediately. This still involves a lot of
stuff that can take quite a while. First, there is a hardwired sequence.
The MCU will finish executing the current instruction. Fortunately, most
instructions are single-cycle, but some can take up to four cycles.
Then, the MCU clears an internal flag that disables further servicing of
interrupts. This is intended to prevent nested interrupts. Then, the PC
is saved into the stack. The stack is an area of RAM reserved for this
kind of temporary storage. The PC (meaning "Program Counter") is an
internal register holding the address of the next instruction the MCU is
about to execute. This is what allows the MCU to know what to do next,
and saving it is essential because it will have to be restored in order
for the main program to resume from where it was interrupted. The PC is
then loaded with a hardwired address specific to the request received,
and this is the end of the hardwired sequence, the rest being
software-controlled.
The MCU now executes the instruction from that hardwired address. This
instruction is called an "interrupt vector", and is generally a "jump"
instruction that will bring us to a special routine called an ISR
("Interrupt Service Routine"). In this case, the ISR is called
"__vector_1", a.k.a. "INT0_vect", which is a misnomer because it is
an ISR, not a vector. This particular ISR comes from libcore. Like any
ISR, it starts with a prologue that saves a bunch of internal CPU
registers on the stack. This will allow it to use those registers and,
when it is done, restore them to their previous values in order not to
disturb the main program. Then, it will look for the interrupt handler
that was registered with attachInterrupt(), and it will call that
handler, which is our read_pin() function above. Our function will
then call digitalRead() from libcore. digitalRead() will look into
some tables in order to map the Arduino port number to the hardware I/O
port it has to read and the associated bit number to test. It will also
check whether there is a PWM channel on that pin that would need to be
disabled. It will then read the I/O port... and we are done. Well, we
are not really done servicing the interrupt, but the time-critical task
(reading the I/O port) is done, and it is all that matters when we are
looking at latency.
Here is a short summary of all the above, together with the associated
delays in CPU cycles:

hardwired sequence: finish current instruction, prevent nested
interrupts, save PC, load address of vector (≥ 4 cycles)
execute interrupt vector: jump to ISR (3 cycles)
ISR prologue: save registers (32 cycles)
ISR main body: locate and call user-registered function (13 cycles)
read_pin: call digitalRead (5 cycles)
digitalRead: find the relevant port and bit to test (41 cycles)
digitalRead: read the I/O port (1 cycle)

We will assume the best case scenario, with 4 cycles for the
hardwired sequence. This gives us a total latency of 99 cycles, or
about 6.2 µs with a 16 MHz clock. In the following, I will
explore some tricks that can be used to lower this latency. They come
roughly in increasing order of complexity, but they all need us to
somehow dig into the internals of the MCU.
Use direct port access
The obvious first target for shortening the latency is digitalRead().
This function provides a nice abstraction to the MCU hardware, but it is
too inefficient for time-critical work. Getting rid of this one is
actually trivial: we just have to replace it with digitalReadFast(),
from the digitalwritefast
library. This cuts the latency almost by half at the cost of a small
download!
Well, that was too easy to be any fun, I will rather show you how to do
it the hard way. The purpose is to get us started into low-level stuff.
The method is called "direct port access" and is nicely documented on
the Arduino reference at the page on Port
Registers. At this
point, it is a good idea to download and take a look at the ATmega328P
datasheet.
This 650-page document may seem somewhat daunting at first look. It is,
however, well organised into sections specific to each of the MCU
peripherals and features. And we only need to check the sections
relevant to what we are doing. In this case, it is the section named
I/O ports. Here is a summary of what we learn from those readings:

The Arduino pin 2 is actually called PD2 (i.e. port D, bit 2) on the
AVR chip.
We get the whole port D at once by reading a special MCU register called
"PIND".
We then check bit number 2 by doing a bitwise logical and (the C ‘&’
operator) with 1 << 2.

So, here is our modified interrupt handler:
#define PIN_REG    PIND  // interrupt 0 is on AVR pin PD2
#define PIN_BIT    2

/* Interrupt handler. */
void read_pin()
{
    uint8_t sampled_pin = PIN_REG;            // do this first!
    if (count_edges >= MAX_COUNT) return;     // we are done
    count_edges++;
    if (sampled_pin & (1 << PIN_BIT)) count_high++;
}

Now, our handler will read the I/O register as soon as it is called. The
latency is 53 CPU cycles. This simple trick saved us 46 cycles!
Write your own ISR
The next target for cycle-trimming is the INT0_vect ISR. This ISR is
needed for providing the functionality of attachInterrupt(): we can
change interrupt handlers at any time during program execution. However,
although nice to have, this is not really useful for our purpose. Thus,
instead of having the libcore's ISR locate and call our interrupt
handler, we will save a few cycles by replacing the ISR by our
handler.
This is not as hard as it sounds. ISRs can be written like normal
functions, we just have to be aware of their specific names, and define
them using a special ISR() macro from avr-libc. At this point it would
be good to have a look at the avr-libc's documentation on
interrupts,
and at the datasheet section named External Interrupts. Here is the
short summary:

We have to write a bit in a special hardware register called EICRA
(External Interrupt Control Register A) in order to configure the
interrupt to be triggered on any change of the pin value. This will be
done in setup().
We have to write a bit in another hardware register called EIMSK
(External Interrupt MaSK register) in order to enable the INT0
interrupt. This will also be done in setup().
We have to define the ISR with the syntax ISR(INT0_vect) { ... }.

Here is the code for the ISR and setup(), everything else is
unchanged:
/* Interrupt service routine for INT0. */
ISR(INT0_vect)
{
    uint8_t sampled_pin = PIN_REG;            // do this first!
    if (count_edges >= MAX_COUNT) return;     // we are done
    count_edges++;
    if (sampled_pin & (1 << PIN_BIT)) count_high++;
}

void setup()
{
    Serial.begin(9600);
    EICRA = 1 << ISC00;  // sense any change on the INT0 pin
    EIMSK = 1 << INT0;   // enable INT0 interrupt
}

This comes with a free bonus: since this ISR is simpler than the one it
replaces, it needs less registers to do its job, then the
register-saving prologue is shorter. Now we are down to a latency of 20
cycles. Not bad considering that we started close to 100!
At this point I would say we are done. Mission accomplished. What
follows is only for those who are not afraid of getting their hands
dirty with some AVR assembly. Otherwise you can stop reading here, and
thank-you for getting so far.
Write a naked ISR
Still here? Good! For proceeding further, it would be helpful to have at
least some very basic idea of how assembly works, and to take a look at
the Inline Assembler
Cookbook
from the avr-libc documentation. At this point, our interrupt entry
sequence looks like this:

hardwired sequence (4 cycles)
interrupt vector: jump to ISR (3 cycles)
ISR prologue: save regs (12 cycles)
first thing in the ISR body: read the IO port (1 cycle)

If we want to do better, we have to move the reading of the port into
the prologue. The idea is the following: reading the PIND register will
clobber one CPU register, thus we need to save at least one register
before doing that, but the other registers can wait. We then need to
write a custom prologue that reads the I/O port right after saving the
first register. You have already seen in the avr-libc interrupt
documentation (you have read it, right?) that an ISR can be made
naked, in which case the compiler will emit no prologue or epilogue,
allowing us to write our own custom version.
The problem with this approach is that we will probably end up writing
the whole ISR in assembly. Not a big deal, but I would rather have the
compiler write those boring prologues and epilogues for me. So, here is
the dirty trick: we will split the ISR in two parts:

the first part will be a short assembly fragment that will

save a single register to the stack
read PIND into that register
store that value into a global variable
restore the register from the stack
jump to the second part

the second part will be regular C code with compiler-generated
prologue and epilogue

Our previous INT0 ISR is then replaced by this:
volatile uint8_t sampled_pin;    // this is now a global variable

/* Interrupt service routine for INT0. */
ISR(INT0_vect, ISR_NAKED)
{
    asm volatile(
    "    push r0                \n"  // save register r0
    "    in r0, %[pin]          \n"  // read PIND into r0
    "    sts sampled_pin, r0    \n"  // store r0 in a global
    "    pop r0                 \n"  // restore previous r0
    "    rjmp INT0_vect_part_2  \n"  // go to part 2
    :: [pin] "I" (_SFR_IO_ADDR(PIND)));
}

ISR(INT0_vect_part_2)
{
    if (count_edges >= MAX_COUNT) return;     // we are done
    count_edges++;
    if (sampled_pin & (1 << PIN_BIT)) count_high++;
}

Here we are using the ISR() macro to have the compiler instrument
INT0_vect_part_2 with the required prologue and epilogue. The compiler
will complain that "‘INT0_vect_part_2’ appears to be a misspelled
signal handler", but the warning can be safely ignored. Now the ISR has
a single 2-cycle instruction before the actual port read, and the total
latency is only 10 cycles.
Use the GPIOR0 register
What if we could have a register reserved for this specific job? Then,
we would not need save anything before reading the port. We can actually
ask the compiler to bind a global variable to a
register.
This, however, would require us to recompile the whole Arduino core and
libc in order to make sure the register is always reserved. Not really
convenient. On the other hand, the ATmega328P happens to have three
registers that are not used by the compiler nor any library, and are
available for storing whatever we want. They are called GPIOR0, GPIOR1
and GPIOR2 (General Purpose I/O Registers). Although they are mapped
in the I/O address space of the MCU, these are actually not I/O
registers: they are just plain memory, like three bytes of RAM that
somehow got lost in a bus and ended up in the wrong address space. These
are not as capable as the internal CPU registers, and we cannot copy
PIND into one of these with the in instruction. GPIOR0 is interesting,
though, in that it is bit-addressable, just like PIND. This will allow
us to transfer the information without clobbering any internal CPU
register.
Here is the trick: we will make sure that GPIOR0 is initially zero (it
is actually cleared by hardware at boot time), then we will use the
sbic (Skip next instruction if some Bit in some I/o register is Clear)
and the sbi (Set to 1 some Bit in some I/o register) instructions as
follows:
sbic PIND, 2   ; skip the following if bit 2 of PIND is clear
sbi GPIOR0, 0  ; set to 1 bit 0 of GPIOR0

This way, GPIOR0 will end up being 0 or 1 depending on the bit we wanted
to read from PIND. The sbic instruction takes 1 or 2 cycles to execute
depending on whether the condition is false or true. Obviously, the PIND
bit is accessed on the first cycle. In this new version of the code, the
global variable sampled_pin is not useful anymore, since it is
basically replaced by GPIOR0:
/* Interrupt service routine for INT0. */
ISR(INT0_vect, ISR_NAKED)
{
    asm volatile(
    "    sbic %[pin], %[bit]    \n"
    "    sbi %[gpio], 0         \n"
    "    rjmp INT0_vect_part_2  \n"
    :: [pin]  "I" (_SFR_IO_ADDR(PIND)),
       [bit]  "I" (PIN_BIT),
       [gpio] "I" (_SFR_IO_ADDR(GPIOR0)));
}

ISR(INT0_vect_part_2)
{
    if (count_edges < MAX_COUNT) {
        count_edges++;
        if (GPIOR0) count_high++;
    }
    GPIOR0 = 0;
}

It should be noted that GPIOR0 has to always be reset in the ISR.
Now, the sampling of the PIND I/O register is the very first thing done
inside the ISR. Total latency is 8 cycles. This is about the best we can
do before getting stained with terribly sinful kludges. This is again a
good opportunity to stop reading...
Put the time-critical code in the vector table
For those still here, here is our current situation:

hardwired sequence (4 cycles)
interrupt vector: jump to ISR (3 cycles)
ISR body: read the IO port (on 1st cycle)

There is obviously little room for improvement. The only way we could
shorten the latency at this point is by replacing the interrupt vector
itself by our code. Be warned that this should be immensely distasteful
to anyone who values clean software design. But it is possible, and I
will show you how.
The layout of the ATmega328P vector table can be found in the datasheet,
section Interrupts, subsection Interrupt Vectors in ATmega328 and
ATmega328P. Or by disassembling any program for this chip. Here is how
it looks like. I am using avr-gcc and avr-libc's conventions (__init
is vector 0, addresses are in bytes) which are different from Atmel's.
address │ instruction     │ comment
────────┼─────────────────┼──────────────────────
 0x0000 │ jmp __init      │ reset vector
 0x0004 │ jmp __vector_1  │ a.k.a. INT0_vect
 0x0008 │ jmp __vector_2  │ a.k.a. INT1_vect
 0x000c │ jmp __vector_3  │ a.k.a. PCINT0_vect
  ...
 0x0064 │ jmp __vector_25 │ a.k.a. SPM_READY_vect

Each vector has a 4-byte slot, filled with a single jmp instruction.
This is a 32-bit instruction, unlike most AVR instructions which are
16-bit. But a 32-bit slot is too small to hold the first part of our
ISR: we can fit the sbic and sbi instructions, but not the rjmp.
If we do that, the vector table ends up looking like this:
address │ instruction     │ comment
────────┼─────────────────┼──────────────────────
 0x0000 │ jmp __init      │ reset vector
 0x0004 │ sbic PIND, 2    │ the first part...
 0x0006 │ sbi GPIOR0, 0   │ ...of our ISR
 0x0008 │ jmp __vector_2  │ a.k.a. INT1_vect
 0x000c │ jmp __vector_3  │ a.k.a. PCINT0_vect
  ...
 0x0064 │ jmp __vector_25 │ a.k.a. SPM_READY_vect

When INT0 fires, PIND will be read, the relevant bit will be copied into
GPIOR0, and then the execution will fall through to the next vector.
Then, the ISR for INT1 will be called, instead of the ISR for INT0. This
is creepy, but since we are not using INT1 anyway, we will just "hijack"
its vector for servicing INT0.
Now, we just have to write our own custom vector table to override the
default one. It turns out it is not so easy. The default vector table is
provided by the avr-libc distribution, in an object file called
crtm328p.o that is automatically linked with any program we build.
Unlike library code, object-file code is not meant to be overridden:
trying to do that will give a linker error about the table being defined
twice. This means we have to replace the whole crtm328p.o with our
custom version. One option is to download the full avr-libc source
code, do our
custom modifications in
gcrt1.S,
then build this as a custom libc.
Here I went for a lighter, alternative approach. I wrote a custom
crt.S, which is a simplified version of the original from avr-libc. It
lacks a few rarely used features, like the ability to define a "catch
all" ISR, or to be able to terminate the program (i.e. freeze the
Arduino) by calling exit(). Here is the code. I trimmed the repetitive
part of the vector table in order to minimize scrolling:
#include <avr/io.h>

.weak __heap_end
.set  __heap_end, 0

.macro vector name
    .weak \name
    .set \name, __vectors
    jmp \name
.endm

.section .vectors
__vectors:
    jmp __init
    sbic _SFR_IO_ADDR(PIND), 2   ; these 2 lines...
    sbi _SFR_IO_ADDR(GPIOR0), 0  ; ...replace vector_1
    vector __vector_2
    vector __vector_3
    [...and so forth until...]
    vector __vector_25

.section .init2
__init:
    clr r1
    out _SFR_IO_ADDR(SREG), r1
    ldi r28, lo8(RAMEND)
    ldi r29, hi8(RAMEND)
    out _SFR_IO_ADDR(SPL), r28
    out _SFR_IO_ADDR(SPH), r29

.section .init9
    jmp main

It can be compiled with the following command line:
avr-gcc -c -mmcu=atmega328p silly-crt.S

The sketch is identical to the previous one except that there is no
INT0_vect, and INT0_vect_part_2 is replaced by INT1_vect:
/* Interrupt service routine for INT1 hijacked to service INT0. */
ISR(INT1_vect)
{
    if (count_edges < MAX_COUNT) {
        count_edges++;
        if (GPIOR0) count_high++;
    }
    GPIOR0 = 0;
}

To compile the sketch, we need a custom compile command. If you have
followed so far, you probably know how to compile from the command line.
You have to explicitly request silly-crt.o to be linked to your program,
and add the -nostartfiles option to avoid linking in the original
crtm328p.o.
Now, the reading of the I/O port is the very first instruction executed
after the interrupt triggers. I tested this version by sending it short
pulses from another Arduino, and it can catch (although not reliably)
the high level of pulses as short as 5 cycles. There is nothing more we
can do to shorten the interrupt latency on this hardware.

Good explanation! +1

(For a future edit: 1) "loosing sleep" → "losing sleep" 2) "Skip next" → "skip next". Otherwise excellent writing. The (misleading) indentation in the code in the question could be fixed at the same time.)

@PeterMortensen: Thanks for the correction! I kept the Uppercase “S” in “Skip next” in order to show where the acronym sbic comes from.

...Some say he's still optimizing that interrupt vector to this day...

The interrupt is being set to fire on a change, and your test_func is set as the Interrupt Service Routine (ISR), called to service that interrupt. The ISR then prints the value of the input.
At first glance you would expect the output to be as you have said, and alternating set of high lows, as it only gets to the ISR on a change.
But what we're missing is that there is a certain amount of time that it takes for the CPU to service an interrupt and branch to the ISR.
During this time the voltage on the pin may have changed again. Particularly if the pin is not stabilised by hardware de-bouncing or similar. Because the interrupt is already flagged and hasn't been serviced yet, this extra change (or many of them, because a pins level can change very quickly relative to the clock speed if it has low parasitic capacitance) will be missed.
So in essence without some form of de-bouncing, we have no guarantee that when the input changes, and the interrupt gets marked for servicing, that the input will still be at the same value when we get to reading its value in the ISR.
As a generic example the ATmega328 Datasheet  used on the Arduino Uno details interrupt times in section 6.7.1 - "Interrupt Response Time". It states for this microcontroller the minimum time to branch to an ISR for servicing is 4 clock cycles, but can be more (extra if executing multi-cycle instruction at interrupt or 8 + sleep wake time if the MCU is in sleep.)
As @EdgarBonet mentioned in comments, the pin could also similarly change during ISR execution. Because the ISR reads from the pin twice, it would not add anything to the test_array if it encountered a LOW on the first read and a HIGH on the second. But x would still increment, leaving that slot in the array unchanged (possibly as uninitialised data depending on what was done to the array earlier).
His one line ISR of test_array[x++] = digitalRead(pin); is a perfect solution to this.