text:
What does avrdude: Device signature = 0x000000 mean? Faulty wiring? Software issue? Incorrect tutorial?
I followed this tutorial a couple of times and when I clicked on bootloader I get this error:
avrdude: Device signature = 0x000000

To see the configuration file click here.

Why do I get this error (Arduino can't communicate with chip, problem with software)?
How can I fix it?
Is something in the tutorial incorrect?

Keep in mind I use an Arduino Uno Rev. 3 and ATmega328P

There is one part of the tutorial that is incorrect - or rather missing.
When you open the serial port the Arduino resets. That includes when the serial port is opened by avrdude.
You need to prevent that from happening, so that the ArduinoISP sketch receives the serial data, not the Arduino's bootloader.
There's a number of ways of doing that:

Add a 10uF or greater capacitor between RESET and GND on the Arduino
Add a small (say 100R) resistor between RESET and 5V on the Arduino
Cut the RESET-EN trace on the underside of the Arduino

Of those my preferred method is the first: add a 10uF or greater capacitor between RESET and GND on the Arduino.

Update:
Now that you have provided photographs of your actual setup I can see that the ground wire between your Arduino and the breadboard is actually plugged into the VIN pin of the Arduino, not GND.

It already has a 10k resistor between 5V and pin 1 (on the chip)

So? That has absolutely nothing to do with the RESET pin of the Arduino.

OK! Thanks I will try again with the resistor/capacitor!

I still get the same error: avrdude:
Device signature = 0xffffff (probably .avr8x_mega)
avrdude: Yikes!  Invalid device signature.
Double check connections and try again, or use -F to override
this check.

And you did connect the capacitor to the Arduino's RESET pin, didn't you? Not the signal that goes to the RESET pin of your target ATmega?

I put a 10μf (16v) electrolytic capacitor between Arduino's RESET pin and Arduino's GND pin. I will send you a couple of pictures.

Then you may have wired something incorrectly.

These are the links to the pictures: https://photos.app.goo.gl/N5NBcmSgFeBrE6Dr7, https://photos.app.goo.gl/wKcDfGXizjdPJspw8. That's what I should do, right?

You have your GND wire plugged into VIN, not GND.

Yeah. I saw it. I put it to GND now and it worked! Thanks a lot!

Unfortunately the three prominent threads on the Arduino forum on this topic are closed, so their good but incomplete information is baked in time:

Invalid device signature error

Which references: Did I get these ArduinoISP instructions right?

Invalid Device signature = 0x000000
no clock on Atmega328p-AU

So let me add a bit more useful information in the hope it permeates.

Device signature = 0x000000

Means the MCU did not respond with a signature. There is a very thin chance that's because it reported all zeros when asked for a signature, but a much higher chance that it did not respond at all. Correct signature bytes are found here (eg. ATmega328P = 0x1E950F) and crucially, all Atmel microcontrollers have one.
Further, the error:

avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.

will occur if you're using ArduinoISP to flash a target Arduino and the target is not physically connected. So it really is an "all bets are off" message that doesn't pinpoint any particular cause. To troubleshoot, checking wiring if a good first step.
Do not, on the other hand, concern yourself with the external clock signal. In contrast to some guides, the ATmega328P at least comes factory configured to use an internal RC oscillator, so even a correctly connected crystal or resonator on the XTAL pins will not show any activity until the first successful flash.

Can confirm previous answer about changing SPI clock.
I edited ArduinoISP.ino example and changed #define SPI_CLOCK (1000000 / 6) to #define SPI_CLOCK (128000/6) and after that I successfully burned bootloader to my UNO

Answer is a duplicate of other answers.

One of the reason for getting weird device signature like 0x000000/0x0000ff/0xff0000
is not having the crystal clock right.
When I tried uploading the sketch I was getting this different device signatures. I had no idea it could be clock setting because we don't generally get this option to set the clock on regular Arduino boards upload options.
I was using this Atmega328PU clone Chinese board and wasn't able to upload a sketch.
Than I tried uploading the sketch using miniCore board (where by default it was External 16MHz Clock selected). Same signature issues still.
For some reason I tried uploading with 8MHz Clock and this time the device signature was right
i.e. device signature = 0x1e950f (probably m328p)
and was able to successfully upload the sketch.
I highly recommend trying this.


text:
Control laser diode from digital pin
I have a 200mw laser module that came with a 3v 1A power supply. I want to control it from a digital pin on an arduino uno.
Can I use a simple voltage divider like this or is there some consideration to current I'd need to take into account? The laser module was quite expensive so I'm hesitant to try it out.

simulate this circuit – Schematic created using CircuitLab

the arduino is not able to supply the necessary current ... other than that, your question is not related to the arduino, so it is off topic here

Your solution does not work, mainly because GPIOs are not intended to source current higher than a few mA. If you want the laser diode to emit a reasonable amount of power, you need to drive it with a transistor. A MOSFET-based low-side-switch would probably be the easiest solution. But note that you still need to limit the current, e.g. by using a series resistor.
Even better would be to use a constant current driver (you can use any led driver with appropriate rating).
If the power supply that came with the laser diode is a constant current source, it might be possible to switch its output directly (without resistor), but that depends on how it behaves when it is open-circuited.

source: Stack Exchange

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

sort: votes


text:
Attiny85 uploading error
I am getting an error while trying to upload programs to the Attiny85 through a USBTinyISP programmer, found here. Unfortunately, it isn't working. Following this tutorial for connecting the board and this tutorial for programming it with the Arduino IDE. My code is:
#include <SoftwareSerial.h>

void setup() {
  // put your setup code here, to run once:

}

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

}

A picture of my setup, which I checked at least 10 times:

However, I get this error message:
avrdude: Version 6.3, compiled on Jun 22 2016 at 16:05:21
     Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
     Copyright (c) 2007-2014 Joerg Wunsch

     System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

     Using Port                    : usb
     Using Programmer              : usbtiny
avrdude: usbdev_open(): Found USBtinyISP, bus:device: bus-0:\\.\libusb0-0001--0x1781-0x0c9f
         AVR Part                      : ATtiny85
         Chip Erase delay              : 400000 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : possible i/o
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    12     4    0 no        512    4      0  4000  4500 0xff 0xff
       flash         65     6    32    0 yes      8192   64    128 30000 30000 0xff 0xff
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
       lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

     Programmer Type : USBtiny
     Description     : USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/
avrdude: programmer operation not supported

avrdude: Using SCK period of 10 usec
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

An error occurred while uploading the sketch
avrdude done.  Thank you.

Can someone please help me to fix this problem?
Thank you.
P.S.: On a website that talked about this error message and a similar programmer said to take out a jumper. I took out the only jumper on the programmer and it did not affect the error message.
UPDATE:
I changed the support from "attiny" by David 0 Mellis to "ATTinyCore" by SpenceKonde. Here is a screenshot of my tools menu:

Now I get a different error:
    avrdude: Version 6.3, compiled on Jun 22 2016 at 16:05:21
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\loydn\Documents\Arduino\hardware\ATTinyCore-master\avr/avrdude.conf"

         Using Port                    : COM3
         Using Programmer              : arduino
         Overriding Baud Rate          : 2400
         Setting bit clk period        : 5.0
avrdude: ser_open(): can't open device "\\.\COM3": The system cannot find the file specified.

avrdude done.  Thank you.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

FIX!!!:
It turns out that it was a problem with the programmer. By connecting the Attiny85 to the 10-pin header instead of the 6-pin one, it was able to upload successfully.

Look at the last lines of the output, and do what it says Double check connections and try again, also it would be preferable to not connect anything to certain pins on your board.
Please add your code used.

The code is a simple serial sketch. Also, I am not connecting anything to the chip.

Answers should be posted as answers, not as part of the question :) Glad you worked it out, though. Unrelated, but there's no way to understand what your setup is from that picture. Consider using Fritzing or even a hand-drawn schematic instead. I just see a fuzzy pile of wires and a chip in a breadboard.

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


text:
Math on analog read wrong result
I'm trying to execute a math of analog read but I get some weird result.. I searched about int and floats but didn't understand..
My code is :
#include <SevSeg.h>

SevSeg sevSeg;

int bitsChange = analogRead(A0) ;
float fuel = (923 - bitsChange) * 0.121065375;
sevSeg.setNumber(round(fuel));

Assuming bitsChange = 683, so fuel has to be after rounding 29, what I get is 39!!!!
I want to know why I get this result to learn about it..

rather than assuming, set it and see for yourself...

I already set it and tried several time with other values, I get each time a wrong result, also tried to declare float and int inside the math but didn't get it solved... That's why I want to understand as I tried several times and failed to get it.

Try setting the value of bitsChange to 683 and printing the value of fuel to the serial port. You will probably see that it's exactly what it should be (i.e. the output is 29.06). Maybe there's something wrong with the setup of your seven segment display (i.e. displaced a segment)?

why are you making an assumption about the value of analogRead(A0) ... you have no code that verifies the assumption ... please use int bitsChange = 683; instead

jsotola, yes I did that and I get the correct result (29.06)..but when I let the analog read the input (3.32 Volts) which means 683 bits of the 1023 the result becomes 39!!

StarCat, I have checked the 7 segment display pins/setup visually and by passing random numbers through setNumber().. it's not the problem..

If you do Serial.println(bitsChange) after setting int bitsChange = analogRead(A0) what result do you see on the serial monitor?

@luker, both Serial.println() & setNumber() show 683 on serial monitor and 7 segment display.. even using (923 - bitsChange) shows the correct result (240), but once I use (*0.121065375) the math is not correct, there is something about this decimal value I cannot understand!!

Why does the decimal need to be so much precise? Can you try typecasting bitchange  Change to float? And also 923 to 923.0

@ArduinoFan, not need to be that precise (0.1211 is enough) but also I used 0.121 & getting the same wrong result, I tried also (bitsChange - 923) instead of +923!!! By saying "typecasting" you mean declaring bitsChange as a float? (if you mean that I declared it float and the same error)... I'm going crazy after trying all available solutions.

When I make the math (923 - bitsChange) * 2.0, the result is 480 which is correct, trying * 1.0, the result is 240, again correct... Once I use * 0.1 the result get wrong!!!! That's why I considered the issue is in the decimal value.


text:
Switching 4.2V circuit with 3.3V Arduino GPIO
I am trying to learn about MOSFETs and see this p channel MOSFET and this tutorial.  I am trying to use a 3.3V arduino GPIO pin to control a load that is powered from a 4.2V battery in much the same configuration as the circuit drawn in that tutorial.  Most other tutorials I see say the Gate Voltage needs to be equal or greater than the Source Voltage, but the tutorial I cited describes that actually the Voltage between the Gate and Source just needs to be more negative than the Threshold Voltage.  The P channel mosfet I cited is Vthreshold -2V to -4.  So my question is whether this P channel MOSFET would allow me to use a 3.3V arduino GPIO to control whether that 4.2V source is closed or open to the drain/load.  Looking at how that tutorial does the math, it seems in my case the GPIO being off would mean Vgs is 0 - 4.2 = -4.2 and therefore the MOSFET is in the ON state.  If GPIO is on at 3.3V then Vgs is 3.3 - 4.2 = -0.9 and therefore the MOSFET is OFF.  However, the tutorial doesn't say what happens when Vgate < Vsource but by an amount less than the Vthreshold so I don't know if my math is right.
In sum my questions are:

Is my math and prediction of the MOSFET states correct when that 3.3V GPIO is on or off?
If not, is it because of some other quality in this MOSFET and a different P MOSFET would work?
I presume that if I keep out of the Vgs upper and lower bounds then I avoid issues where the MOSFET is in a partially on and partially off state, is that correct?
Is it just impossible to use P MOSFETS in this way?

Note:  My questions only pertain to P MOSFETs.  For my project (switching a 1-2A disco light toy), it has to be a high side switch and that's even besides the point because I am more importantly trying to understand how the P channel mosfets work.

The threshold voltage is only critical when switching high currents. What's your load circuit? Is it in the order of mA or A?

I have three cases.  One is <200mA, another is 1A, the last is <2A

The MOSFET you chose will probably fail. Using a 30V device on a 24V system is asking for problems. Go to a minimum of a 60V MOSFET and use a UIS, Avalanche rated one. R4 is very week for what you need to do, I would suggest something in the 10K range to swamp out any leakage in the Arduino. If the MOSFET is properly rated the flyback diode is not needed but make a space for it incase you have to sub a MOSFET. Putting C2 in parallel with C1 will help. I do this a lot with electrolytics. I double up each one the needed size when one fails you don't notice it. I would suggest a couple of 220nF caps across the motor but that is application dependent.

The OP says he's switching 4.2v not 24v

OOPS right answer wrong question.


text:
Is it possible to extract the firmware of an Arduino BLE or IoT board wirelessly?
I've looked at previous questions regarding sketch extraction and know that it is possible to extract the hex code from an Arduino board using avrdude from the command line.
However, I want to see if the following is possible:

Connect to Arduino 33 IoT board
Extract onboard Firmware as a hex file
Disconnect from Arduino 33 IoT board.

I understand that getting the initial source code is not possible, but I am in particular looking to just get the hex code in a wireless manner. If it is not possible via the Arduino 33 IoT board, is there any Arduino board with which this can be done? Any help or guidance would be appreciated.

Technically, the firmware can read its own application section, but it won't send it to you wirelessly (or via any interface) if such a feature isn't implemented in that firmware. If you were to implement the firmware yourself, you can do (almost) anything. But if it is a third party firmware, this will not be possible.
The reason this works with arduinos and avrdude is, because firmware up- and download are implemented in hardware (ISP, works without a bootloader).

Thank you for the answer. Just to be sure, you're saying that for any Arduino device the methodology I stated in my initial question is just not possible unless I code it myself into the firmware beforehand?

@TjHasan Yes, that's it...


text:
Problem with my motor and L293D motor shield module
I connected my motor and a servo to my L293D motor shield and i used a 3.7 volt battery with 4800 mAh. I also connected a button to on and off the motor for a certain amount of time but only the servo is working properly while my motor doesn't run.
HERE IS THE CODE
int LEDPin=11;
int buttonPin=4;
int buttonNew;
int buttonOld=1;
int dt=100;
#include <Servo.h>
#include <AFMotor.h>
Servo myservo;
int servopin(10);
AF_DCMotor motor1(1);

void setup(){
  Serial.begin(9600);
  pinMode(LEDPin,OUTPUT);
  pinMode(buttonPin,INPUT);
  myservo.attach(servopin);
  motor1.setSpeed(200);
}

void loop(){
  buttonNew=digitalRead(buttonPin);
  if(buttonOld==0 && buttonNew==1){
    if (LEDState==0){
      digitalWrite(LEDPin,HIGH);
      myservo.write(0);
      Serial.print(buttonOld);
     int motorpos='0';
     int motorpos2='1';
      if (motorpos=='0'){
        motor1.run(FORWARD);
        delay(2000);
        motorpos='1';
      }
      if(motorpos='1'){
        motor1.run(RELEASE);
      }
       LEDState=1;
    }
    else{
      digitalWrite(LEDPin,LOW);
      myservo.write(90);
      Serial.print(buttonNew);
      int motorpos='0';
      int motorpos2='1';
      if (motorpos=='0'){
        motor1.run(BACKWARD);
        delay(2000);
        motorpos='1';
      }
      if (motorpos='1'){
        motor1.run(RELEASE);
      }
        LEDState=0;
    }
  }
  buttonOld=buttonNew;
  delay(dt);
}

what seems to be the problem because my motor doesn't work with this code but with a different code it works

just to be sure that the motor isn't broken or the problem

Sorry for that @jsotola I will consider it next time, thank you!

Posting a schematic, not a frizzy thing will help. You can lose a fair amount of voltage using the L293D shield. A MOSFET bridge would be much better.


text:
Need to operate 2 different sensors (MPU 6050 and Admp 401) simultaneously
I need to operate 2 different sensors (MPU 6050 and Admp 401) simultaneously. I have managed to run each one of them separately and I don't know how to manipulate the code so they could work together. My background in coding is basic and I'm not the one who wrote these codes.
Here are the sketches:
1.Code used for IMU (MPU-6050)
// CONNECTIONS
//Gyro - Arduino UNO R3
//VCC  -  5V
//GND  -  GND
//SDA  -  A4
//SCL  -  A5
//INT - port-2

#include <Wire.h>
//Declaring some global variables
int gyro_x, gyro_y, gyro_z;
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
boolean set_gyro_angles;

long acc_x, acc_y, acc_z, acc_total_vector;
float angle_roll_acc, angle_pitch_acc;

float angle_pitch, angle_roll;
int angle_pitch_buffer, angle_roll_buffer;
float angle_pitch_output, angle_roll_output;

long loop_timer;
int temp;

void setup() {
  Wire.begin();                                                        //Start I2C as master
  setup_mpu_6050_registers();                                          //Setup the registers of the MPU-6050
  for (int cal_int = 0; cal_int < 1000 ; cal_int ++){                  //Read the raw acc and gyro data from the MPU-6050 for 1000 times
    read_mpu_6050_data();
    gyro_x_cal += gyro_x;                                              //Add the gyro x offset to the gyro_x_cal variable
    gyro_y_cal += gyro_y;                                              //Add the gyro y offset to the gyro_y_cal variable
    gyro_z_cal += gyro_z;                                              //Add the gyro z offset to the gyro_z_cal variable
    delay(3);                                                          //Delay 3us to have 250Hz for-loop
  }

  // divide by 1000 to get avarage offset
  gyro_x_cal /= 1000;
  gyro_y_cal /= 1000;
  gyro_z_cal /= 1000;
  Serial.begin(115200);
  loop_timer = micros();                                               //Reset the loop timer
}

void loop(){

  read_mpu_6050_data();
 //Subtract the offset values from the raw gyro values
  gyro_x -= gyro_x_cal;
  gyro_y -= gyro_y_cal;
  gyro_z -= gyro_z_cal;

  //Gyro angle calculations . Note 0.0000611 = 1 / (250Hz x 65.5)
  angle_pitch += gyro_x * 0.0000611;                                   //Calculate the traveled pitch angle and add this to the angle_pitch variable
  angle_roll += gyro_y * 0.0000611;                                    //Calculate the traveled roll angle and add this to the angle_roll variable
  //0.000001066 = 0.0000611 * (3.142(PI) / 180degr) The Arduino sin function is in radians
  angle_pitch += angle_roll * sin(gyro_z * 0.000001066);               //If the IMU has yawed transfer the roll angle to the pitch angel
  angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);               //If the IMU has yawed transfer the pitch angle to the roll angel

  //Accelerometer angle calculations
  acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));  //Calculate the total accelerometer vector
  //57.296 = 1 / (3.142 / 180) The Arduino asin function is in radians
  angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296;       //Calculate the pitch angle
  angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296;       //Calculate the roll angle

  angle_pitch_acc -= 0.0;                                              //Accelerometer calibration value for pitch
  angle_roll_acc -= 0.0;                                               //Accelerometer calibration value for roll

  if(set_gyro_angles){                                                 //If the IMU is already started
    angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004;     //Correct the drift of the gyro pitch angle with the accelerometer pitch angle
    angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004;        //Correct the drift of the gyro roll angle with the accelerometer roll angle
  }
  else{                                                                //At first start
    angle_pitch = angle_pitch_acc;                                     //Set the gyro pitch angle equal to the accelerometer pitch angle
    angle_roll = angle_roll_acc;                                       //Set the gyro roll angle equal to the accelerometer roll angle
    set_gyro_angles = true;                                            //Set the IMU started flag
  }

  //To dampen the pitch and roll angles a complementary filter is used
  angle_pitch_output = angle_pitch_output * 0.9 + angle_pitch * 0.1;   //Take 90% of the output pitch value and add 10% of the raw pitch value
  angle_roll_output = angle_roll_output * 0.9 + angle_roll * 0.1;      //Take 90% of the output roll value and add 10% of the raw roll value
  Serial.print(" | Angle  = "); Serial.println(angle_pitch_output);

 while(micros() - loop_timer < 4000);                                 //Wait until the loop_timer reaches 4000us (250Hz) before starting the next loop
 loop_timer = micros();//Reset the loop timer

}

void setup_mpu_6050_registers(){
  //Activate the MPU-6050
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x6B);                                                    //Send the requested starting register
  Wire.write(0x00);                                                    //Set the requested starting register
  Wire.endTransmission();
  //Configure the accelerometer (+/-8g)
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x1C);                                                    //Send the requested starting register
  Wire.write(0x10);                                                    //Set the requested starting register
  Wire.endTransmission();
  //Configure the gyro (500dps full scale)
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x1B);                                                    //Send the requested starting register
  Wire.write(0x08);                                                    //Set the requested starting register
  Wire.endTransmission();
}

void read_mpu_6050_data(){                                             //Subroutine for reading the raw gyro and accelerometer data
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x3B);                                                    //Send the requested starting register
  Wire.endTransmission();                                              //End the transmission
  Wire.requestFrom(0x68,14);                                           //Request 14 bytes from the MPU-6050
  while(Wire.available() < 14);                                        //Wait until all the bytes are received
  acc_x = Wire.read()<<8|Wire.read();
  acc_y = Wire.read()<<8|Wire.read();
  acc_z = Wire.read()<<8|Wire.read();
  temp = Wire.read()<<8|Wire.read();
  gyro_x = Wire.read()<<8|Wire.read();
  gyro_y = Wire.read()<<8|Wire.read();
  gyro_z = Wire.read()<<8|Wire.read();
}

2.Code used for MEMS mic (ADMP401)
int mic = A0;               // A0 is the audio output of the pin, and since sound is analog, its connected to the analog pin in arduino
const int sampleTime = 2;   // sampling time for the input audio sound is 2ms
int micOut;

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

void loop() {
int micOutput = findPTPAmp();       // we use a PTPAmp function to find the peak to peak amplitude
   VUMeter(micOutput);
}

int findPTPAmp(){

   unsigned long startTime= millis();  // Start of sample window
   unsigned int PTPAmp = 0;
// the above two are 2 time variables to find PTP amplitude

   unsigned int maxAmp = 0;
   unsigned int minAmp = 1023;
// these 2 are the signal variables to find PTP AMplitude
// We basically try to Find the max and min of the mic output within the 2 ms timeframe
   while(millis() - startTime < sampleTime)
   {
      micOut = analogRead(mic);
      if( micOut < 1023) //to prevent erroneous readings; cause output can’t be greater than 1023
      {
        if (micOut > maxAmp)
        {
          maxAmp = micOut; //save only the max reading
        }
        else if (micOut < minAmp)
        {
          minAmp = micOut; //save only the min reading
        }
      }
   }

  PTPAmp = maxAmp - minAmp;
  double micOut_Volts = (PTPAmp * 3.3) / 1023; // Convert ADC into voltage formula ; 3.3 is the Vcc.

  //Uncomment this line for help debugging (be sure to also comment out the VUMeter function)
  //Serial.println(PTPAmp);

  return PTPAmp;
}

// Volume Unit Meter function: map the PTP amplitude to a volume unit between 0 and 10.
// Map the mic PTP Amp to a volume unit between 0 and 10.
// We use Amplitude instead of voltage to give a larger and more accurate range for the map function that we use next in the code.

int VUMeter(int micAmp){
  int preValue = 0;

  int fill = map(micAmp, 23, 750, 0, 10);

// val = map(val, 0, 1023, 0, 255);
val equals value of analogRead(0)
0, 1023 is the range of values that a reading from analogRead(0) could be.
0,255 is the range of values you are converting the value to.

  // only print the volume unit value if it differs from the previous value
  while(fill != preValue)
  {
    Serial.println(fill);
    preValue = fill;
  }
}

Hello, what exactly is your problem in doing this? Is it, that you don't know how to combine 2 sketches? The 2 sensors don't have anything in common (one is an I2C sensor, one is an analog sensor connected to the ADC), so I would guess this comes down to "how combine sketches". If yes, you might wanna look at this question, where there are given general instructions on how to do that


text:
How to reset a variable just before entering a function?
I am facing a problem where the if condition in the function waterNowrun is able to execute once after the program starts as the variable v is 0 at the start, but upon starting it again the if does not execute as v is not <10.
After some debugging I had decided that v would have to be reset before entering the function, and so I set v to 0 in the loop, then what happened is that the if was always satisfied and did not go to the else.
Is it possible to do it? Maybe with interrupts or something else?
Hardware-ESP8266 based NodeMCU
In conclusion-
I want a reset a variable v once just before the function waterNowrun starts, how do I do it?
My code-
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "DHT.h"
#include "LiquidCrystal_PCF8574.h"

#define BLYNK_PRINT Serial
#define DHT_PIN_DATA  12
// LCD definations
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 25
#define DHTTYPE DHT22

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "ymri80lFL9_xZhf6WIRHtQ1qadfafdEWOt9zBy";
char ssid[] = "-Hotspot-82DB";
char pass[] = "b35288qqafdd";
int autoSch;
int waterNow;
int morTime;
int afterTime;
int postNoon;
int eveTime;
int schTime;
int minStep;
int interval;
int count;
int flag = 0;
int soilHum = A0;
int v;
unsigned long previousMillis = 0;

DHT dht(DHT_PIN_DATA, DHTTYPE);
LiquidCrystal_PCF8574 lcdI2C;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 600000);
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1

BLYNK_CONNECTED() {
  Blynk.syncAll();
}

BLYNK_WRITE(V0)
{
  autoSch = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V1)
{
  morTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V2)
{
  afterTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V6)
{
  postNoon = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V3)
{
  eveTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V10)
{
  waterNow = param.asInt(); // assigning incoming value from pin V1 to a variable
Serial.println("Boo BOO is BOO BOO billa");
}

BLYNK_WRITE(V4)
{
  schTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V7)
{
  minStep = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void setup()
{
  dht.begin();
  lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(14, OUTPUT);
  digitalWrite(14, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  pinMode(0, INPUT_PULLUP);
  Serial.begin(9600);

  //WiFi.begin(ssid, password);
  Blynk.begin(auth, ssid, pass);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  timeClient.begin();
  Blynk.syncAll();
}

void loop()
{
  Blynk.run();
  time_run();
  lcd();
  butPress();

  timeClient.update();
  if (waterNow != 1) {
    Blynk.virtualWrite(V10, 0);
   // digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, minStep * 60);

    Blynk.syncAll();
  }
  if (waterNow == 1) {
    waterNowrun(v = 0);

  } else if (autoSch == 0) {
    auto_run1();
  } else if (autoSch == 1) {
    sch_run2();
  } else {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }
  Blynk.syncAll();
  Serial.println(timeClient.getFormattedTime());
  Serial.println(analogRead(A0));
}
void butPress() {
  if (digitalRead(0) == LOW) {
    if (flag == 0) {

      digitalWrite(14, HIGH);
      delay(3000);
      digitalWrite(14, LOW);

      flag = 1;
    }
    else {
      digitalWrite(14, LOW);
      flag = 0;
    }
  }
}

void test() {
  if (v < 10) {
    digitalWrite(14, HIGH);
    v++;
    delay(500);

  } else {
    digitalWrite(14, LOW);

  }

}

void lcd() {
  //lcdI2C.clear();
  lcdI2C.setCursor(0, 0);
  timeClient.update();
  lcdI2C.print(timeClient.getFormattedTime());

  if (autoSch == 0) {
    lcdI2C.setCursor(9, 0);
    lcdI2C.print("Auto     ");
  } else {
    lcdI2C.print(" Sch   ");
  }

  if (digitalRead(14) == 1) {
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now           ");
  }
  else
  {

    if (int(timeClient.getHours()) < 6 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) < 12 && afterTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12n ");
    } else if (int(timeClient.getHours()) < 14 && postNoon == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at:14pn ");
    } else if (int(timeClient.getHours()) < 18 && eveTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18e ");
    } else if (int(timeClient.getHours()) >= 18 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else {
      lcdI2C.selectLine(2);
      lcdI2C.print("My name is billa");
    }

  }

}

void waterNowrun(int v) {
  /*
    Serial.println (currentMillis);
    Serial.println (previousMillis);
    Serial.println(interval);
  */

  if (v < 10) {

    Serial.println("Boo Boo");

    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now :");
    /*
      lcdI2C.print((minStep * 60) - ((currentMillis - previousMillis) / 1000));
      Blynk.virtualWrite(V8, ((interval / 1000) - ((currentMillis - previousMillis) / 1000)));
    */
    Blynk.syncAll();
    delay(500);
    v++;
  } else {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, 0);

    Blynk.syncAll();

  }
}

void sch_run2() {
  if (schTime == 1) {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  } else if (schTime == 0) {
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }

}

void time_run() {
  Blynk.virtualWrite(V11, int(timeClient.getHours()));
  Blynk.virtualWrite(V12, int(timeClient.getMinutes()));
  Blynk.virtualWrite(V13, float(dht.readTempC()));
  Blynk.virtualWrite(V14, float(dht.readHumidity()));

}

void auto_run1() {
  if (morTime == 1 && String(timeClient.getFormattedTime()) > "06:00:00" && String(timeClient.getFormattedTime()) < "06:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (afterTime == 1 && String(timeClient.getFormattedTime()) > "12:00:00" && String(timeClient.getFormattedTime()) < "12:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (postNoon == 1 && String(timeClient.getFormattedTime()) > "14:00:00" && String(timeClient.getFormattedTime()) < "14:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (eveTime == 1 && String(timeClient.getFormattedTime()) > "12:59:00" && String(timeClient.getFormattedTime()) < "13:01:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else  {
    //(String(timeClient.getFormattedTime() == "06:20:00" || "12:20:00" || "14:20:00" || "13:48:00"))
    //waterNowrun();
    /*
      Blynk.virtualWrite(V10, 0);
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.virtualWrite(V8, 0);
      Blynk.syncAll();
    */
  }
}

The logic behind your explanation is not entirely clear to me, but the variable int v inside the waternowRun function is a local variable that is only valid inside this function and not the same as the "global" variable int v. This probably causes the confusion. If you want to retain the value of a local variable between function calls, you could declare it as a static variable but that might or might not be what you want. This is also a programming question and not an Arduino specific question.

And this is exacly why it's discouraged to use global variables... Anyway, test() function changes global variable v (great name if you wanted to encrypt the code). The waterNowrun(int v) changes local variable conveniently named v that shadows global v... take a pick what's messing it up

@StarCat Can you please explain how static variables work?

If's explained quite clearly here: https://www.tutorialspoint.com/what-is-the-lifetime-of-a-static-variable-in-a-cplusplus-function. If you declare a variable static inside of a function (for example static int counter;, it will keep its value when the function is called multiple times, as in the example from the link. Normally a local variable is re-allocated (reset) when leaving a function and re-entering it.

@StarCat I tried it does not work

The purpose of the waterNowrun function and 'v' seems to be to turn on some water and keep it running for 10 iterations, before turning it off?
I would split the waterNowrun into two functions:
void waterOn() {
    Serial.println("Boo Boo");
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now :");
    /*
      lcdI2C.print((minStep * 60) - ((currentMillis - previousMillis) / 1000));
      Blynk.virtualWrite(V8, ((interval / 1000) - ((currentMillis -     previousMillis) / 1000)));
    */
    Blynk.syncAll();
    delay(500);
}

void waterOff() {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, 0);
    Blynk.syncAll();
}

In the loop() I would do
...
if (waterNow != 1) {
    waterOff();
}
if (waterNow == 1) {
    if (v < 10) {
        waterOn();
        v++;
    }
    else {
        waterOff();
        v = 0;
    }
} else if (autoSch == 0) {
    auto_run1();
} else if (autoSch == 1) {
    sch_run2();
} else {
    waterOff();
}
...

But do yourself a favour and rename v to waterPeriod or something that is easier to remember.

Appreciate the help...  Just for clarification I'll try to explain what I've understood- So if waterNow is 1 and v<10 then waterOn until v> or = 10, go to the else statement and do WaterOff which also turns waterNow to 0 hence exiting the if statement and setting v=0, to reset the state of the variable.                              Is that what I am supposed to understand?

Hi, sorry for not getting back to you before. Yes, that's right. When you start out, waterNow is false (or 0) and v is 0. When waterOn is true (or 1), we get to the waterNow==1 branch. v is 0, so < 10, the water is turned on and v is incremented. For the next iterations, we do the same, until v reaches 10. Then we go to the else branch, turns off the water and resets V. Now waterNow and v are 0 like when we  started.

If going through waterOn again and again is a problem, you can try
if (v == 0) {
waterOn();
}
if (v++ == 10) {
waterOff();
v = 0;
}
EDIT: Seems like comments are formatted. Linebreaks after branckets and ;

It isn't clear what behavior you expect from v, especially since you have two of them - the global v at the head of your program, and the parameter v of the function waterNowrun(int v).
My understanding of what you want is that the function should maintain control of v. If so,

Get rid of the global v';
In loop(), don't pass anything to waterNowrun()
Inside waterNowrun() declare static int v = 0;. That initialization to zero will only happen once, before the program starts (not on every entry to the function, even though it kind of reads like that). From then on, only your waterNowrun() function can change v.

That may not be the only logic change you need to make - I don't understand what you're trying to do with v and can't critique that. But at least now v will be entirely controlled from within the function, and it will not change between invocations of the function.
Some background: A static variable declared within a function is like a global in that it has a fixed memory address for the entire program run; unlike a local (including a function parameter) that gets reallocated in memory each time the function is entered (and therefore must be initialized on every entry). But unlike a global, it is invisible - not known about - anywhere outside of that function.

Unfortunately this answer does not solve the problem as I am facing the same issue as before where the function works one time but not a second

Please clarify what it is you're trying to accomplish.

I'm trying to turn on watering for a particular number of iterations and then turn it off, the problem is that the iterations counter v remains = or > 10 hence not entering the function  a second time

Try to add a "v = 0;" line after the two other waterOff(); calls.

You need to reset the counter when you turn off the water and increase it while the water is on.


text:
Unable to write, or read a sensor's registers. Do I have an error in my code?
I'm trying to write to register the change some settings for a sensor I'm using (BNO055) and then read the same register to verify if the changes are successful.
However, the only value I'm able to read from the register is 1. Is the issue with my code or something to do with the sensor?
Thank you for your help. I've included what I think the relevant code is.
/**************************************************************************/
void write_register(uint8_t sensor_address, uint8_t register_address, uint8_t register_value) {
  wire_custom.beginTransmission (sensor_address);
  wire_custom.write(register_address);
  wire_custom.write(register_value);
  wire_custom.endTransmission ();
}

/**************************************************************************/
byte read_register(uint8_t sensor_address, uint8_t register_address, uint8_t bytes) {
  uint8_t result;
  wire_custom.beginTransmission (sensor_address);
  wire_custom.write(register_address);
  wire_custom.endTransmission ();
  wire_custom.requestFrom(sensor_address, bytes);
  result = wire_custom.read();
  return result;
}

/**************************************************************************/
void setup(void)
{
  wire_custom.begin(I2C_SDA, I2C_SCL, 400000);

  Serial.begin(115200);

  if (!bno.begin())
  {
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while (1);
  }
  delay(1000);
  bno.setExtCrystalUse(true);

  // updating range
  bno.setMode(Adafruit_BNO055::OPERATION_MODE_CONFIG);
  delay(1000);
  write_register (0x28, 0x0A, 0b00111000);
  // bno.setMode(Adafruit_BNO055::OPERATION_MODE_GYRONLY);
  delay(1000);
  register_1 = read_register (0x28, 0x0A, 1);
}

/**************************************************************************/
void loop(void)
{
  sensor_calibration ();

  sensor_data (x_placeholder, y_placeholder);

  // printing register 1
  Serial.print(register_1);
  Serial.print("\n");
}

I'm not familiar with the BNO055 but from the datasheet it looks like there are two register map pages (which can be changed via register #7) that can be either 0 (which is the default configuration at boot) or 1. The register you attempt to write (0x0A) is the low byte of the Y axis acceleration data (which presumably is read-only) when register page #0 (default) is selected or the Gyroscope configuration in page #1. Make sure the correct register page is selected.

Thank you for the assistance. I will experiment with this and update with the outcome.

Seems the setMode function from the library I'm using isn't working, so I will investigate that. Happy to accept the comment as an answer to the question, but isn't letting me. Thanks for your help.


text:
ESP32-DEV is connected to Wifi but not working properly
Hardware:

Board ESP32 Dev Module
Version/Date today's master
IDE name Arduino IDE
Flash Frequency 80Mhz
PSRAM enabled no
Upload Speed 115200
Computer OS Windows 10

Description:
I am doing a project where I want to collect data from different sensors and then display it on my Adafruit IO Dashboard. I have created a separate config.h file where I have stored the WiFi Credentials (in my case I am using Mobile Hotspot as Wifi), and also my Adafruit IO Key.
The code is compiled and uploaded successfully, and in my phone I can see esp32-arduino is connected to my mobile hotspot, nut when I open the Serial Monitor it shows "Connecting....." and also no data is being published on the Adafruit Dashboard

#include "config.h"
#include "max6675.h"
#include "EmonLib.h"

#define CURRENT_CAL 62.6
EnergyMonitor emon1;

#define sound_PIN 34
#define vib_PIN 35
#define smoke_PIN 33
#define current_PIN 39
#define alarm_PIN 25

int thermoDO = 19;
int thermoCS = 23;
int thermoCLK = 5;
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

float Normal_Sound_Level= 250;
float Normal_Vib_Level = 5000;
int Normal_Smoke_Level= 20;
int Normal_Temp_Level = 50;
float Normal_Current_Level= 20.00;
float First_Current_Reading=70.00;

boolean is_Relay_on=true;
boolean is_Machine_on=true;
String Machine_Power;
String Machine_Power_Status;
String Alarm_State;
boolean AlarmState=false;
String reason;
int relay_PIN=32;

AdafruitIO_Feed *temperature = io.feed("temperature");
AdafruitIO_Feed *Vibration = io.feed("vibration-intensity");
AdafruitIO_Feed *Smoke = io.feed("smoke-intensity");
AdafruitIO_Feed *Current = io.feed("current");

AdafruitIO_Feed *power = io.feed("power");

void setup() {
pinMode(sound_PIN, INPUT);
pinMode(vib_PIN, INPUT);
pinMode(smoke_PIN, INPUT);
pinMode(current_PIN, INPUT);
pinMode(relay_PIN, OUTPUT);
pinMode(alarm_PIN, OUTPUT);

  Serial.begin(115200);

  while(! Serial);

  Serial.print("Connecting to Adafruit IO");
  io.connect();

power->onMessage(handleMessage);

  while(io.status() < AIO_CONNECTED) {
    Serial.println("Connecting.......");
    Serial.println("If it Takes a Long Time, Check WIFI Username/Password!");
    delay(500);
  }

  Serial.println();
  Serial.println(io.statusText());

  if (is_Relay_on==true){
  power->save(HIGH);
}

 emon1.current(current_PIN, CURRENT_CAL);
}

void loop() {

   io.run();

switch (is_Relay_on) {
    case true:
      digitalWrite(relay_PIN,HIGH);
      Machine_Power="ON";
      AlarmState=false;
      Alarm_State="OFF";

      break;

    case false:
      digitalWrite(relay_PIN,LOW);
      is_Machine_on=false;
      Machine_Power="OFF";
      AlarmState=true;
      Alarm_State="Triggered";

       break;

    default:
      break;
  }

while (( is_Machine_on)==true) {

  float sound_intense = analogRead(sound_PIN);
 if (sound_intense>Normal_Sound_Level){
  is_Relay_on= false;
  reason="((((((Abnormal Sound Values))))))";
}

float Vib_intense = analogRead(vib_PIN);

  if (Vib_intense>Normal_Vib_Level){
  is_Relay_on= false;
  reason="((((((Abnormal Vibration Values))))))";
}

int smoke_intense = analogRead(smoke_PIN);

if (smoke_intense>Normal_Smoke_Level){
 is_Relay_on= false;
 reason="((((((Abnormal Smoke Values))))))";
}

if (thermocouple.readCelsius()>Normal_Temp_Level){
 is_Relay_on= false;
 reason="((((((Abnormal Temperature Values))))))";
}

  emon1.calcVI(20,100);

  float currentDraw   = emon1.Irms-2;
  int supplyVoltage   = 220;

  if (currentDraw<0){
    currentDraw=-currentDraw*0;
  }
else{
  currentDraw=currentDraw;
}

if (currentDraw>=First_Current_Reading){
  currentDraw=0;
}

  if (currentDraw>Normal_Current_Level){
  is_Relay_on= false;
  reason="((((((Abnormal Current Withdrawal Values))))))";
}

Current->save(currentDraw);
temperature->save(thermocouple.readCelsius());
Vibration->save(Vib_intense);
Smoke->save(smoke_intense);

  Serial.println(" ");
  Serial.println("..................................................");
  Serial.println(" ");
  Serial.print("Recieved Machine Power: ");
  Serial.println("ON");
  Serial.println(" ");
  Serial.println("----->Sending----->-----> (((WIFI)))");
  Serial.println(" ");
  Serial.print("Machine Power: "); // Print the voltage.
  Serial.println(Machine_Power); // Print the voltage.
  Serial.print("Alarm State: "); // Print the voltage.
  Serial.println(Alarm_State); // Print the voltage.
  Serial.print("Sound Intensity: "); // Print the voltage.
  Serial.println(sound_intense);
  Serial.print("Vibration Intensity: "); // Print the voltage.
  Serial.println(Vib_intense); // Print the voltage.
  Serial.print("Smoke Density: "); // Print the voltage.
  Serial.println(smoke_intense); // Print the voltage.
  Serial.print("Temperature: ");
  Serial.println(thermocouple.readCelsius());
  Serial.print("Current: ");
  Serial.println(currentDraw);
  Serial.print("Voltage: ");
  Serial.println(supplyVoltage);
  Serial.print("Watts: ");
  Serial.println(currentDraw * supplyVoltage);
  //power->save(HIGH);
 // wait one second (1000 milliseconds == 1 second)

 delay(5000);
 break;
}

if (AlarmState==true) {
 dacWrite(alarm_PIN, 255); // buzzer ON
  delay(600);
  dacWrite(alarm_PIN, 0);
}
else{
  dacWrite(alarm_PIN, 0);
}

while (( is_Machine_on)==false) {

  Serial.println(" ");
  Serial.println("..................................................");
  Serial.println(" ");
  Serial.println(">>>>>>>>>>Stopped Sending<<<<<<<<<<");
  Serial.println(" ");
  Serial.print("Recieved Machine Power: ");
  Serial.println("OFF");
  Serial.print("Machine Power: "); // Print the voltage.
  Serial.println(Machine_Power); // Print the voltage.
  Serial.print("Alarm State: "); // Print the voltage.
  Serial.println(Alarm_State); // Print the voltage.
  Serial.print("Reason: ");
  Serial.print(reason);
  Serial.println(" ");

power->save(LOW);
 delay(1000);
 break;
}

}

void handleMessage(AdafruitIO_Data *data) {
  if(data->toPinLevel() == HIGH){

    Serial.print("Recieved Machine Power: ");
    Serial.println("ON");
       is_Relay_on=true;
         is_Machine_on=true;

  }else{
    Serial.print("Recieved Machine Power: ");
    Serial.println("OFF");
       is_Relay_on=false;
       reason="(((((( Manual Online Shut Down ))))))";

  }
}

This is the config.h:
#define IO_USERNAME    "xyz"
#define IO_KEY         "xyz"
#define WIFI_SSID       "test"
#define WIFI_PASS       "pass"
#include "AdafruitIO_WiFi.h"
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

It would help to include all of your code in the question (obfuscate your WiFi and Adafruit credential), or, even better, the minimum code that reproduces the problem. Also, what firmware is running on the ESP?

http://collabedit.com/qfvkd  - You can see the whole code here, cannot paste the whole code in comments because of character limit.

please no code in comments, ever ... add code to the post

Ok I have included the full code as well as that of config.h file.


text:
How to connect an Output to a Pullup Input of another arduino
:tldr; Could problems occur if one connects a HIGH Output of one arduino to a PULLUP_INPUT of another while using differed power sources?
Hi I'm building some devices for a LARP Dungeon (think Escape room).
For that we have interfaces, riddles and switches(triggers).
Interfaces provide access to sound/light/DMX sytems for riddles.
Riddles check conditions and send state information to the interfaces.
To keep things simple, states are boolean (like riddle is solved, a critical mistake has been made,..)
I would like to use PULLUP_INPUTs on the receiving end so I can use simple switches to GND as controls. In some cases a switch might be connected directly to an interface. Mostly there is a riddle in-between. In those cases an OUTPUT of the riddle's Arduino will be connected to the PULLUP_INPUT of the Interface's Arduino. There will be multiple riddle Arduinos connected to one or even multiple Interfaces.
Due to cable length, differed power sources etc. the potential to GND of the involved Arduinos might be differed. So I assume this difference will flow over the pullup resistor of the interfaces into their 5V. The internal PULLUP is ~20kOhms so current should not be a problem but can the voltage, which might be a little higher than the one of the input, cause problems?
Or would it be better to set the Output of a riddle Arduino to INPUT while the signal line should be HIGH so it gets a high impedance? Switching between: OUTPUT:LOW while active and INPUT while inactive.

If a voltage higher than Vcc is applied to a pin, current will barely flow through the pullup but through protection diodes...

Thanks! That should resolve my concerns.

I might have been unclear: that is actually a bad thing. Those clamping diodes are meant to protect IOs from transients, not from a persistent overvoltage. Applying a constant voltage of typ. 0.5V above Vcc can destroy the GPIO... but it is only relevant if the two devices have different Vcc.

Connecting any signal that is within the voltage range of the receiving Arduino is safe. So if you use Arduino UNOs or similar with a 5V operating level, you can connect any signal between 0 and 5V to an input. It does not matter whether the input is in pull-up-mode or not. So connecting an output to an input of another Arduino (or even of the same Arduino) is safe. In addition to the signal values, you do need to connect the ground of both Arduinos.
The only thing you must not do is connect two outputs together (because if one of them is high and the other is low, you have a shortcut that will potentially fry one or both of the boards). And you would need to be careful if you used different types of Arduinos, like a Uno and a Due, because they run at different voltage levels.

All correct, but also note: The two MCUs need the same reference, but they have separate power sources, so you also'll need to connect their grounds together.

True, added that.

Yes all GNDs are connected as well. From my understanding a IO-Pin which is set to INPUT_PULLUP is connected via a internal resistor to the 5V-Pin of its Arduino. An OUTPUT is directly connected to 5VPin when HIGH. Depending on the load and accuracy of each linear converter the real voltage between 5V-Pin and GND might be different for each Arduino. I have read that this voltage is critical for any Arduino and must not change. Load on any Arduino may change. So I fear that current might go back into the INPUT_PULLUP. I guess the difference will be <100mV.. Maybe I'm over thinking this.

@KarlSanathos: The internal resistor that is used to create the pull-up is large enough that whatever current you attempt to draw from it is small enough not to cause any harm. The voltage on an input pins is absolutely not critical, as long as it is not significantly above 5V. If it is around 2.5V, the input reading might be random, but still this won't break anything.


text:
Teensy 4.1 serial communication with 7N2 (7 databits no parity 2 stopbits)
I have ported a project from arduino Due to a teensy 4.1
In the project I read data from a sensor which speaks serial at 7 databits, no parity and 2 stopbits (no configurable).
Now it seems that teensy does not support this dataformat.
Could I read my sensor in a way using teensy 4.1? I could maybe use softwareserial but the format does not seem to be configurable.

maybe try to use SERIAL_7N1 | SERIAL_2STOP_BITS, I don't see why it shouldn't support it

Hi @KIIV I tried but it doesn't compile: 'SERIAL_7N1' was not declared in this scope. 7 databits with no parity is not listed in the supported dataformats.

Weird, how about  8N1 with masking that last bit to logic 1, so it'll look like 2 stop bits?

There is no difference between 7N2 and 8N1. You just have the most significant bit of your data value being the first of the two stop bits.
To transmit just set the most significant bit to 1.
To receive just ignore the most significant bit.
For example:
Serial.write(val | 0x80);

And:
uint8_t val = Serial.read() & 0x7F;


text:
ESP32 can't enter interrupt anymore after interrupt appears during delayMicrosecond function
I have a strange problem with my ESP32 project. I use an ADPS-9960 for gesture control which triggers an external interrupt. In the interrupt handler itself I only set a variable that causes the execution of a function in the loop. When I trigger an interrupt during the delay function the interrupt stops working. This means the loop is still running, but the interrupt routine doesn't get executed anymore.
#include <Arduino.h>
#include <Wire.h>
#include <SparkFun_APDS9960.h>
#include <ESP32Servo.h>
// Pins
#define APDS9960_INT    25 // Needs to be an interrupt pin

#define SERVO 4

// Constants
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
void IRAM_ATTR interruptRoutine();
int detectorPin = 19;

Servo myservo;

void setup()
{
  // Set interrupt pin as input
  pinMode(APDS9960_INT, INPUT_PULLUP);
  // Initialize Serial port
  Serial.begin(9600);
  Serial.println();
  Serial.println(F("--------------------------------"));
  Serial.println(F("SparkFun APDS-9960 - GestureTest"));
  Serial.println(F("--------------------------------"));

  // Initialize interrupt service routine
  attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
  // Initialize APDS-9960 (configure I2C and initial values)
  if ( apds.init() )
  {
    Serial.println(F("APDS-9960 initialization complete"));
  }
  else
  {
    Serial.println(F("Something went wrong during APDS-9960 init!"));
  }
  apds.setGestureGain(GGAIN_1X); // ohne diese Zeile geht es nicht zuverlässig

  // Start running the APDS-9960 gesture sensor engine
  if ( apds.enableGestureSensor(true) )
  {
    Serial.println(F("Gesture sensor is now running"));
  }
  else
  {
    Serial.println(F("Something went wrong during gesture sensor init!"));
  }

  myservo.attach(SERVO);
  myservo.write(20);

  pinMode(detectorPin, INPUT);
}

void loop()
{
  if( isr_flag == 1 )
  {
    detachInterrupt(digitalPinToInterrupt(APDS9960_INT));
    handleGesture();
    isr_flag = 0;
    attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
  }

  if(digitalRead(detectorPin))
    Serial.println("ON");

  else
    Serial.println("OFF");
}

void IRAM_ATTR interruptRoutine()
{
  if(isr_flag == 0)
    isr_flag = 1;
}

void  handleGesture()
{
    if ( apds.isGestureAvailable() )
    {
      if( apds.readGesture() == DIR_FAR )
      {
        Serial.println("FAR");
        myservo.write(165);
        delayMicroseconds (5000000);
        myservo.write(20);
      }
      else
        Serial.println("FALSE");
  }
}

isr_flag needs to be declared as volatile. Please do this and try again

Hey @chrisl thanks for your reply. I changed it to volatile int isr_flag = 0;  but unfortunaltely the problem is still present.

Why are you using delayMicroseconds() for delaying 5s. I think the parameter type is only unsinged int. According to the Arduino documentation the max is 16383us. Please use delay() for such long delays. In older versions delayMicroseconds() also disabled interrupts. So that might be your problem

I used dealyMicroseconds() because I missunderstood the documentation of àttachInterrupt(). Unfortunately usingdelay()` didn't solve the problem, if an interrupt appears during the delay function I am still not able to enter the interrupt after this. The problem is very hard to localize as there seems no good way to debug in the Arduino IDE.

Can you please check, when exactly the ISR is executed (especially after the first delay() call), by connecting a LED and toggling it in the ISR (but not in the if statement, just in the ISR)?

@chris Thanks again for the reply. When i make the gesture during the delay the ISR doesn't seem to be executed as the LED doesn't get toggled.
I have looked in the reference example and I have noticed  something strange. They declare 2 as interrupt pin, but then use 0 in the attachInterrrupt/detachInterrupt, this have to be a mistake right?
link

Mhh, now I don't see any more reasons, why the ISR shouldn't trigger again after the 5s and the servo movement. Are you sure, that the delay is the problem? Maybe remove it and try again. I'm currently poking in the dark a bit

Yes I'm pretty sure this has to do something with the delay, because when I use a gesture which causes a execution of the else block in handleGesture() there seems to be no problem. The thing I will try next is using a simple button for the external interrupt and look if anything changes. Thanks for your support so far!


text:
Mass testing of Arduinos
I am using Arduino for an IoT class (40 students). I have set up a test program to check all sensors and actuators used in the class (we need to recycle for next semester). However, I would also like to check the Arduino's themselves (and also NodeMCU´s) in case some of the units have been broken. I have an idea of testing input/output of each pin to make sure its working - using LEDs and buttons, but if anyone has some ideas to improve testing, it would be great to hear from you.

Thank you all for your valuable input.  Unfortunately, I have to do the testing myself since students are working from home (Covid-19). So each student receives a package with all components and does the labs under online supervision.  That is why testing is important. I had the same class last summer with good results, but with brand new components.

Testing microcomputers is a very complicated task. In your case I would suggest writing some programs to do exactly what you are saying. Then let the students do the testing. When the class starts you have to teach them the basics, this will check the computers etc and also the test equipment on there benches. At the end of testing they will have knowledge of the basics they will need to continue with the class. You can also have the students do this at the end of the semester to get a head start on any problems.

A complete test would obviously be something fairly complex, and would
probably require building some sort of rig. You can, however, perform a
minimal test that checks for common failure modes, without connecting
any extra hardware.
I assume the pin I/O stages are the easiest thing to break. You can then
check that, when you read a pin that is set to OUTPUT, you get the
value that the pin is supposed to be outputting. You can leverage the
stray capacitances of floating pins to test them as inputs: the
capacitance should make the pin “remember” its previous output value for
some time, and that time should be really short if the internal pull-up
is enabled.
The following program tests pins 2–13 and A0–A5 of an Uno. It checks
that:

a pin set to OUPUT LOW reads LOW
a pin set to OUPUT HIGH reads HIGH
a pin switched from OUPUT HIGH to INPUT reads HIGH
a pin switched from OUPUT LOW to INPUT reads LOW
a pin switched from OUPUT LOW to INPUT_PULLUP reads LOW, then
switches to HIGH less than a microsecond later

Pins 0 and 1 are not tested, as they are connected to the serial port.
On the other hand, if you can upload a sketch, you know those pins work
at least as RX/TX.
Note that the program uses direct port access, as the Arduino functions
for accessing the pins are too slow for this kind of tests. If all
works, the program prints “All tests passed.”. Otherwise specific error
messages are printed, followed by “Some tests failed.”
#include <avr/cpufunc.h>
#include <util/delay.h>

int failures = 0;

static void log_failure(char port_name, const char * reason)
{
    failures++;
    Serial.print("FAIL: Port ");
    Serial.print(port_name);
    Serial.print(", read ");
    Serial.println(reason);
}

static inline __attribute__((always_inline))
void test_port(const char port_name, uint8_t mask,
    volatile uint8_t *pin, volatile uint8_t *ddr, volatile uint8_t *port)
{
    *port = 0;
    *ddr = mask;   // OUTPUT LOW
    _NOP();
    if ((*pin & mask) != 0)
        log_failure(port_name, "OUTPUT LOW");
    *port = mask;  // OUTPUT HIGH
    _NOP();
    if ((*pin & mask) != mask)
        log_failure(port_name, "OUTPUT HIGH");
    *ddr = 0;      // INPUT_PULLUP
    *port = 0;     // INPUT -> HIGH
    _NOP();
    if ((*pin & mask) != mask)
        log_failure(port_name, "INPUT HIGH");
    *ddr = mask;   // OUTPUT LOW
    *ddr = 0;      // INPUT -> LOW
    _NOP();
    if ((*pin & mask) != 0)
        log_failure(port_name, "INPUT LOW");
    *port = mask;  // INPUT_PULLUP
    _NOP();
    uint8_t r1 = *pin;
    _delay_us(1);
    uint8_t r2 = *pin;
    if ((r1 & mask) != 0 || (r2 & mask) != mask)
        log_failure(port_name, "INPUT_PULLUP");
}

void setup()
{
    Serial.begin(9600);
    TIMSK0 &= ~_BV(TOIE0);  // disable timer interrupt

    test_port('B', 0x3f, &PINB, &DDRB, &PORTB);  // PB0..PB5
    test_port('C', 0x3f, &PINC, &DDRC, &PORTC);  // PC0..PC5
    test_port('D', 0xfc, &PIND, &DDRD, &PORTD);  // PD2..PD7

    if (failures == 0)
        Serial.println("All tests passed.");
    else
        Serial.println("Some tests failed.");
}

void loop(){}

As an extension, analog inputs could be tested in a manner similar to
test 5: if the analog sampling is done at the right time, you can
get a reading that is somewhere mid-range.

I'd add a second Arduino to supply a HIGH and LOW signal to the Arduino being tested (to test the INPUT), and to verify that the tested Arduino can output HIGH and LOW. Testing inputs, outputs, and being able to upload you test sketch will catch the most common problems.
Testing the regulator would be my next thing, but that also depends on whether you're previous course was using the regulator.

When I make a new (Uno-like) board, I test for shorts and opens with sketch that blinks each pin in sequence. @Gerben's suggestion to test the inputs as well makes a lot of sense for your application. Plus the basic ability to power up (working barrel-connector input & voltage regulator, working USB connector and USB communication) would another test I'd make. I'd probably boards that have a socketed chip for my future purchases (if you're not already).

There are a number of open issues which need to be addressed in order to narrow the scope of this project to a manageable and reasonable effort.  For instance:

Which Arduino (board and processor) are you using?  Does the board power off a regulated USB 5 volt source?  Or does it use a regulator which needs testing?
How many GPIO pins are there? Will they be used to drive, sense or both?
Are there any Analog pins?  Do they need to be tested over a range or just a select voltage?
Are there any PWM outputs which need to be tested?

To simplify testing we might make some assumptions.  For example:

If the GPIO aspect of a pin works any PWM feature for that pin may be assumed functional.
If a given voltage at a Analog Input pin results in a reasonable analog to digital conversion then all other reasonable voltages will result in the expected analog to digital conversion.

For testing many UUTs (Units Under Test), it is almost always better to build a fixture.  This might be simple cables connected to another (carefully controlled) Arduino all the way to a bed-of-nails In Circuit Tester (ICT).
The "Make a Pogo Pin Test Jig" project at Adafruit addresses many of these concerns at a level that may be suitable to implement at the college level.


text:
AccelStepper Library Help - Simultaneous Motor Driving
I’m working on a 4 wheeled robot driven with stepper motors. I have a Raspberry Pi that sends a random (based on input image) pulse count to the Arduino board serially and then steps that amount. I’m using an Arduino CNC board to drive all 4 stepper motors, just FYI. My problem is that currently my steppers will not simultaneously move. I’ve read over the documentation for the AccelStepper library pretty well and tried some of the example code with no luck. I have a lot of function/ parsing code prior to the actual stepper code. It’s almost at the end, the function called ‘yMovement’.
Currently, the int value is received then yStepper moves, then yStepper1 moves after.
My updated code now makes them move simultaneously but the done command does not behave as before.
#include <AccelStepper.h>

const int stepperCount = 4;
AccelStepper FLStepper(AccelStepper::FULL2WIRE, 2, 5);
AccelStepper FRStepper(AccelStepper::FULL2WIRE, 3, 6);
AccelStepper BRStepper(AccelStepper::FULL2WIRE, 4, 7);
AccelStepper BLStepper(AccelStepper::FULL2WIRE, 12, 13);

bool movementComplete = false;

// defines pins numbers

//Front left wheel
const int stepX = 2;
const int dirX  = 5;

//Front right wheel
const int stepY = 3;
const int dirY  = 6;

//Back left wheel
const int stepZ = 4;
const int dirZ  = 7;

//Back right wheel
const int stepA = 12;
const int dirA  = 13;
const int enPin = 8;

char split = ':';         //this is the character that would be used for seperating the different parts of your commands
                          //the syntax for commands would be:   command:value1:value2

int listSize = 5;                                     //the amount of commands in the list
String commands[] = {"hello", "add", "sub", "YMOV", "XMOV"};     //the list of every command name

void setup()
{
  Serial.begin(115200);     //sets the data transfer rate for the serial interface
                          //9600 is good for basic testing, but should be as high
                          //as possible for both devices.
  FRStepper.setMaxSpeed(500);
  FRStepper.setAcceleration(400);
  BRStepper.setMaxSpeed(500);
  BRStepper.setAcceleration(400);

  FLStepper.setMaxSpeed(500);
  FLStepper.setAcceleration(400);
  BLStepper.setMaxSpeed(500);
  BLStepper.setAcceleration(400);

  pinMode(stepX, OUTPUT);
  pinMode(dirX, OUTPUT);

  pinMode(stepY, OUTPUT);
  pinMode(dirY, OUTPUT);

  pinMode(stepZ, OUTPUT);
  pinMode(dirZ, OUTPUT);

  pinMode(enPin, OUTPUT);

  digitalWrite(enPin, LOW);
  digitalWrite(dirX, HIGH);
  digitalWrite(dirY, HIGH);
  digitalWrite(dirZ, HIGH);
  digitalWrite(dirA, HIGH);

}

void loop()
{
  CommCheck(); //checks serial buffer for data commands
  runMotors();
}

void runMotors()
{

  if ((FLStepper.distanceToGo() != 0) || (FRStepper.distanceToGo() != 0) || (BLStepper.distanceToGo() != 0) || (BRStepper.distanceToGo() != 0))
  {

    FLStepper.run();
    //BLStepper.run();
    FRStepper.run();
    //BRStepper.run();
    movementComplete = true;
  }
  if (movementComplete == true)
  {
    CommConfirm();
    movementComplete = false;
  }
  //if ((FLStepper.distanceToGo() == 0) && (FRStepper.distanceToGo() == 0) && (BLStepper.distanceToGo() == 0) && (BRStepper.distanceToGo() == 0))
  //if ((FLStepper.distanceToGo() == 0) || (FRStepper.distanceToGo() == 0) || (BLStepper.distanceToGo() == 0) || (BRStepper.distanceToGo() == 0))
  //{
    //movementComplete = true;
  //}
}
void CommCheck()
{
  if(Serial.available())                    //checks to see if there is serial data has been received
  {
    //int len = Serial.available();           //stores the character lengh of the command that was sent
                                             //this is used for command parsing later on

    String command = Serial.readString();   //stores the command as a text string
    int len = command.length();
    //Serial.println(command);
    Serial.flush();
    //command.remove(len-2,1);                //removes characters added by the pi's serial data protocol
    //command.remove(0,2);
    //len -= 3;                               //updates the string length value for parsing routine

    int points[2] = {0, 0};                 //offset points for where we need to split the command into its individual parts

    for(int x = 0; x < len; x++)            //this loop will go through the entire command to find the split points based on
    {                                       //what the split variable declared at the top of the script is set to.
      //Serial.print("Char ");
      //Serial.print(x);
      //Serial.print("- ");
      //Serial.println(command[x]);
      if(command[x] == split)               //this goes through every character in the string and compares it to the split character
      {
        if(points[0] == 0)                  //if the first split point hasn't been found, set it to the current spot
        {
          points[0] = x;
        }
        else                                //if the first spot was already found, then set the second split point
        {                                   //this routine is currently only set up for a command syntax that is as follows
          points[1] = x;                    //command:datavalue1:datavalue2
        }
      }
    }
    CommParse(command, len, points[0], points[1]);      //now that we know the command, command length, and split points,
  }                                                     //we can then send that information out to a routine to split the data
}                                                       //into individual values.

void CommParse(String command, int len, int point1, int point2)
{
  //Serial.print("Command Length: ");
  //Serial.println(len);
  //Serial.print("Split 1: ");
  //Serial.println(point1);
  //Serial.print("Split 2: ");
  //Serial.println(point2);

  String com = command;                 //copy the full command into all 3 parts
  String val1 = command;                //this is needed for the string manipulation
  String val2 = command;                //that follow

  com.remove(point1, len - point1);     //each of these use the string remove to delete
  val1.remove(point2, len - point2);    //the parts of the command that aren't needed
  val1.remove(0, point1 + 1);           //basically splitting the command up into its
  val2.remove(0, point2 + 1);           //individual pieces
  val2.remove(val2.length()-1,1);

  CommLookup(com, val1, val2);    //these pieces are then sent to a lookup routine for processing
}

void CommLookup(String com, String val1, String val2)
{

  int offset = 255;                   //create a variable for our lookup table's offest value
                                      //we set this to 255 because there won't be 255 total commands
                                      //and a valid command can be offset 0, so it's just to avoid
                                      //any possible coding conflicts if the command sent doesn't
                                      //match anything.

  for(int x = 0; x < listSize; x++)   //this goes through the list of commands and compares
  {                                   //them against the command received
    if(commands[x] == com)
    {
      offset = x;                     //if the command matches one in the table, store that command's offset
    }
  }

  switch(offset)                //this code compares the offset value and triggers the appropriate command
  {
    case 0:                                 //essentially a hello world.                       |  Syntax: hello:null:null
      CommHello();                          //this activates the hello world subroutine        |  returns Hello!
      break;
    case 1:                                 //adds both values together and return the sum.    |  Syntax: add:value1:value2
      CommAdd(val1.toInt(), val2.toInt());  //this activates the addition subroutine           |  returns value1 + value2
      break;
    case 2:                                 //subtracts both values and return the difference  |  Syntax: subtract:value1:value2
      CommSub(val1.toInt(), val2.toInt());  //this activates the subtraction subroutine        |  returns value1 - value2
      break;
    case 3:
      yMovement(val1.toInt(), val2.toInt());
      break;
    case 4:
      xMovement(val1.toInt(), val2.toInt());
    default:                                        //this is the default case for the command lookup and will only
      Serial.println("Command not recognized");     //trigger if the command sent was not known by the arduino
      break;
  }
}

void CommHello()                               //each of these routines are what will be triggered when they are successfully processed
{
  Serial.println("Hello!");
  CommConfirm();
}

void CommAdd(int val1, int val2)
{
  Serial.println(val1 + val2);
  CommConfirm();
}

void CommSub(int val1, int val2)
{
  Serial.println(val1 - val2);
  CommConfirm();
}

void yMovement(int val1, int val2)
{
  if (val1 < 0) {
    int yMoveNew = (val1 * (-4));
    //Serial.println(val1 * (-1));
    //delay(500);

    FRStepper.moveTo(-yMoveNew);

    BRStepper.moveTo(-yMoveNew);

    FLStepper.moveTo(-yMoveNew);

    BLStepper.moveTo(-yMoveNew);

    //delayMicroseconds(500);
  }

  else {

    int yMoveNew = (val1 * 4);
    //Serial.println(val1);
    //delay(500);
    FRStepper.moveTo(yMoveNew);

    BRStepper.moveTo(yMoveNew);

    FLStepper.moveTo(yMoveNew);

    BLStepper.moveTo(yMoveNew);

    //delayMicroseconds(500);

  }
}

void xMovement(int val1, int val2)
{
  if (val1 < 0) {
    int xMoveNew = (val1 * (-4));
    //Serial.println(val1 * (-1));
    //delay(1000);
    FLStepper.moveTo(-xMoveNew);

    BLStepper.moveTo(-xMoveNew);

    FRStepper.moveTo(-xMoveNew);

    BRStepper.moveTo(-xMoveNew);

    //delayMicroseconds(500);
  }

  else {

    int xMoveNew = (val1 * 4);
    //Serial.println(val1);
    //delay(1000);
    FLStepper.moveTo(xMoveNew);

    BLStepper.moveTo(xMoveNew);

    FRStepper.moveTo(xMoveNew);

    BRStepper.moveTo(xMoveNew);

    //delayMicroseconds(500);

  }
}
void CommConfirm()
{
  Serial.println("Done");

}

With the AccelStepper.move() function, you are setting the target position of the motor. Then you run the motor with AccelStepper.runToPosition(). But that is a blocking function. It will not exit, until the motor reached it's target position. So you just picked the wrong function from the AccelStepper library.

Small adjacent about simultaneous action on microcontrollers: Since most microcontrollers, like in the Arduino, only have one core, they can only do exactly one thing at a time. But you can still execute things one after another, but so fast, that a human would say, they where happening at the same time. For this we need to divide down the actions into small chunks, that are executed very fast. In your case we have the big actions of running multiple motors to their target positions. Each of these big actions take long in total, but we can divide them down. And with stepper motors that is really easy, because one step would be one small chunk of that action.
So we want to go through our code very fast, successively checking for each motor, if it is time to do a step with it. If yes, we only do that one step. Then we proceed further to the next motor.

The AccelStepper library helps you in doing this checking if it is time to do a step. This is what happens in the AccelStepper.run() function. You just need to call it regularily, fast enough to not miss the time for a step.
So the solution is to remove all the calls to AccelStepper.runToPosition() and instead call the AccelStepper.run() function for all your stepper motors directly in the loop() function.

Thanks for the help!
The problem now is that my commConfirm() function does not send at the right time. I tried adding it in the loop with run() but now realize why it doesn't work like that because technically run() is being ran every step. So the done command is send as soon as the motors start.

You have if (movementComplete == true) for executing commConfirm() with the variable set in the if statement above. Make it an else if clause of the if statement above (but checking for false instead of true) and set movementComplete = true; in that if else clause. The else will cause that part to only be executed, when the distances to go are zero, and only executes once. So something like else if(movementComplete == false){ commConfirm(); movementComplete = true;}. Also make sure to reset movementComplete to false, when you start another movement via Serial.

Thanks for the help! Shortly after I figured it out!


text:
SIM900A Module doesn't send SMS to user anymore, after previously working
I'm trying to make a hydroponics project that collects data from sensors and sends it to the user through SMS every 15 minutes. However, when I try to run tests now, the pump part of the code works perfectly fine but the earlier part of the code that deals with sending the SMS doesn't work. I've tested the sim module by itself and it works, so it's not a hardware problem. What seems to be the problem here?
#include <SoftwareSerial.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <GravityTDS.h>
#include <Servo.h>

#define ONE_WIRE_BUS 5
#define DHTPIN 7
#define DHTTYPE DHT11
#define TdsSensorPin A1
#define PUMPPIN 11

SoftwareSerial mySerial(9, 10);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DHT dht(DHTPIN, DHTTYPE);
GravityTDS gravityTds;
Servo myservo;

char msg;
char call;

void setup()
{
  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);    // Setting the baud rate of Serial Monitor (Arduino)
  dht.begin();

  sensors.begin();

  gravityTds.setPin(A1);
  gravityTds.setAref(5.0);
  gravityTds.setAdcRange(1024);
  gravityTds.begin();

  myservo.attach(PUMPPIN);
}

void loop()
{
  const unsigned long SECOND = 1000;
  const unsigned long MINUTE = 60*SECOND;
  const unsigned long HOUR = 60*MINUTE;

  delay(30L * SECOND);
  int h = dht.readHumidity();
  float t = dht.readTemperature();
  float tdsValue = 0;
  float temperature = t;
  gravityTds.setTemperature(temperature);
  gravityTds.update();
  tdsValue = gravityTds.getTdsValue();

  sensors.requestTemperatures();

  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=\"+************\"\r"); // Replace x with mobile number
  mySerial.print(h);// The SMS text you want to send
  mySerial.print("% humidity, ");
  mySerial.print(t);
  mySerial.print(" degrees Celsius air temperature, ");
  mySerial.print(sensors.getTempCByIndex(0));
  mySerial.print(" degrees Celsius water temperature, ");
  mySerial.print(tdsValue,0);
  mySerial.print(" ppm");

  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);

  myservo.write(0);   //Clockwise maximum speed rotation
    delay(30L * SECOND);
  myservo.write(90);
  delay(15L * MINUTE);
}

You might want to [edit] out your phone number

maybe you forgot to pay your cellphone bill ... test the SMS function without any of the other code

I've checked the module itself and it still sends, so the SMS module by itself cans till send text messages.

When you do AT+CMGS="+xxxxxxxxx\r", you are supposed to wait for the acknowledge return by the module, it will shows a prompt >, only then you can send the message out. If you don't do that, add a delay(1000) after the AT+CMGS line. You basically send the data prematurely.


text:
What kind of distance sensor are optimal to measure distances to surfaces at an angle to the sensor?
I want to try measuring the orientation of an object by measuring the distance between a "flat" surface to the surface of the rotated object. The problem I assume is that if the surface being measured is at an angle to the distance sensors, the beamed lights from laser or infrared proximity sensors, for example, would be reflected at an angle and not return to the sensors at all.

Would this actually happen, or am I misunderstanding some properties of these sensors? Which sensors would work in this kind of application, and which sensors would not work for sure (I read from another post that ultrasonic sensors would definitely not work in this case)?
(Added a crude sketch of the problem I think is going to happen)

What type of surface does the object have? Is it rough or reflective?

I'm looking to try to measure the orientation of a truck-trailer surface, so I imagine it would be a smooth surface of painted sheet metal. I'm not sure how reflective this would be considered, but something like: https://ryder.com/used-trucks/-/media/Project/UsedTrucks/UVS/Images/Vehicles/Types/Truck-Types---Trailers/truck_types_dry_trailer_image.jpg?h=468&w=624

You can try a TOF (time of flight) laser distance sensor. That normally works, when the surface is not too reflecting for the laser light

A laser distance sensor will work when the surface is not like  a mirror. The more power you use the better the sensor will work (but be careful about laser safety). An ultrasonic sensor on the other hand is less affected by the reflectivity of the surface, but sees a very wide signal if the surface is not perpendicular. This probably won't give you usable measurements.

Honestly, I don't think anyone here can give you a definitive answer. The results depend on many variables in your whole application setup. I would suggest just testing it. For this the only really viable options (besides some mechanical solution) are ultrasonic or laser TOF. I would start with ultrasonic, since these are really cheap. If you don't get good results with them, try a TOF sensor.

Using ultrasonic sensors would be a very sensible solution in your use case.
I am currently working on a similar project with a company in Denmark, where the objective is to detect cars on parking spaces. For this task, I used two of these ultrasonic sensors from DFRobot for the prototype:
https://www.dfrobot.com/product-1935.html
They were very easy and simple to setup on an Arduino UNO and worked perfectly fine even when two were sensing at once.
Though I have to mention, that they need a serial connection each, but this can be worked around using a multiplexer or a developer board with more serial connections.
I also found that the ultrasonic sensors work better than time of flight sensors in outdoor conditions. They are very robust and wont be as affected by dirt for instance.
A little speck on the lens of a ToF sensor and it will be rendered useless.
Ultrasonic sensors are also widely used in the car industry for parking aid solutions where they have to detect lots of different surfaces and be very precise in doing so.
Ultrasonic sensors are great. And yes, they can interfere with each other, but as long as you dont put them on top of one another, it should not be an issue.
You should be able to detect the distance to a trailer in two different places using ultrasonic sensors as long as the trailer is within the sensors range.

Hey, thanks for the response! I've read online that ultrasonic sensors don't work with angled surfaces (around 5 degrees off perpendicular). What has been your experience with this? Would the readings give completely wrong numbers, or simply numbers that are close, but with a larger margin of error? Or has this not been a problem at all in your experience? Thanks!

It will depend on what sensors you'll choose. You can easily find sensors with more play than 5 degrees. I found that the one i linked will work until around 12-14 degrees, but if this is not enough, you could perhaps use two sensors attached to stepper motors at each of the trailer and let them spin around sensing at different angles. Alternatively, you could construct some kind of parabolic array. This will require a few more sensor though.


text:
How to add colour change to the strobe coding?
I have this strobe effect working. However, I would like to change the colour of the LEDs after each 'strobe sequence'. How can it be achieved?
The code I am using is this one:
    // Basic code NeoPixel
    // wwww.arduinoplatform.com

    #include <Adafruit_NeoPixel.h>
    #ifdef __AVR__
     #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
    #endif

    // Which pin on the Arduino is connected to the NeoPixels?
    // On a Trinket or Gemma we suggest changing this to 1:
    #define LED_PIN    6

    // How many NeoPixels ar
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, 6, NEO_GRB + NEO_KHZ800);

    void setup() {
      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    }

    // *** REPLACE FROM HERE ***

    void loop() {
      // Slower:
      // Strobe(0xff, 0x77, 0x00, 10, 100, 1000);
      // Fast:
      Strobe(0xFF, 0x00, 0xF8, 10, 50, 1000);
    }

    void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
      for(int j = 0; j < StrobeCount; j++) {
        setAll(red,green,blue);
        showStrip();
        delay(FlashDelay);
        setAll(0,0,0);
        showStrip();
        delay(FlashDelay);
      }

     delay(EndPause);
    }

    // *** REPLACE TO HERE ***

    void showStrip() {
     #ifdef ADAFRUIT_NEOPIXEL_H
       // NeoPixel
       strip.show();
     #endif

    }

    void setPixel(int Pixel, byte red, byte green, byte blue) {
     #ifdef ADAFRUIT_NEOPIXEL_H
       // NeoPixel
       strip.setPixelColor(Pixel, strip.Color(red, green, blue));
     #endif
    }

    void setAll(byte red, byte green, byte blue) {
      for(int i = 0; i < 64; i++ ) {
        setPixel(i, red, green, blue);
      }
      showStrip();
    }

change the first three parameters in Strobe(0xFF, 0x00, 0xF8, 10, 50, 1000);

I guess you want to cycle through a list of defined colors with your strobe effect. For that you can save the colors in a 2-dimensional array and then cycle through the array with a for loop. The 2-dimensional array is then a group of colors, each defined by the 3 numbers for a RGB value. Somewhat like this:
#define NUM_COLORS   5
byte colors[NUM_COLORS][3] = {
    {0xFF, 0, 0},
    {0, 0xFF, 0},
    {0, 0, 0xFF},
    {0xFF, 0xFF, 0},
    {0, 0xFF, 0xFF}
};

void loop(){
    for(int i=0;i<NUM_COLORS;i++){
        Strobe(colors[i][0], colors[i][1], colors[i][2], 10, 50, 1000);
    }
}

Note, that this is not a complete code, but only the interesting parts. You can incorporate this into your code. You can change the number of colors and the colors itself to your liking (I only took some example values, that are easy to recognize).


text:
Smooth Servo movement for robotic arm: An ongoing answer and soluton
This is not and will not be a duplicate.
This is a thread meant to share a solid soliton I figured out with the rest of the community and update it as I optimize it, ad-hoc.
So I had visited StackExchange Arduino community to check if there is a better way to make a servo move smoother, since if we assing a new position to a servo that is attached on an arm, it moves like an attacking karateka.
I found these threads:
Smooth servo control library
(Dat-ha provided a piece of code that I suggest a correction here)
I also checked this:
My Servo Won't Sweep Smoothly
I will self-answer and update this thread, as I make a full arm code working properly and include instructions for the rest of the people to save everyone some time. I still haven't added the capacitor that is suggested on the threads but I will ASAP.

As explained in the answers, the delay function blocks the code from executing until the delay finishes

Your original solution uses blocking code (the for loops with delay() calls in them). Surely that works, but it can easily get you in trouble, when extending the project with more functionalities (since nothing else can be done during the sensor movement). So I would suggest a way to ditch all blocking for loops and delays, so that other code can run during the servo movement. For this we can use millis() and the coding principle from the BlinkWithoutDelay example, that comes with the Arduino IDE.
#include <Servo.h>

Servo servo1;
int set_angle = 0;
int current_angle = 90; // setting starting angle to 90 degrees
unsigned long servo_timestamp = 0;
#define SERVO_INTERVAL    10   // changing the servo position every 10ms, defines the speed of the servo

void setup()
{
    servo1.attach(11);  // connect Servo to pin 11
    pinMode(A0, INPUT); // Connect potentiometer or Joystick x or y pin to A0 input
}

void loop(){
    if(millis()-servo_timestamp > SERVO_INTERVAL){
        servo_timestamp += SERVO_INTERVAL; // increment our timestamp by the servo interval
        // Measure the new set_angle only, if we really want to move the sensor
        int val1 = analogRead(A0); // Read the potentiometer position
        set_angle = map(val1, 0, 1023, 0, 180); // Map the value to be used with servo

        // Increment or decrement the current angle according to the set_angle
        // and don't change it, when we already are at the set_angle
        if(set_angle > current_angle){
            current_angle++;
        } else if(set_angle < current_angle){
            current_angle--;
        }
        // Write the new angle to the servo
        servo1.write(current_angle);
    }
}

For learning more about the non-blocking coding style using millis(), you can google for it and look at the BlinkWithoutDelay example. There are many resources for this on the web. The combination of timestamp and millis() if statement executes the code inside the if statement at the regular interval SERVO_INTERVAL. There we read the potentiometer and calculate the new setpoint for the servo angle. Then we increment or decrement the current angle by 1 depending on the set angle. And then we write that new angle to the servo.
You can change the speed by either changing SERVO_INTERVAL or by in-/decrementing current_angle by more than only 1.
The code outside the if statement still runs at full speed. So in the (a bit less than) 10ms, that the servo code isn't running, you can execute other code. Also this code will react immediately, where a blocking code would first let the servo run to the set position and only then change again.
Note: The above code isn't tested. It's purpose is to show the principle. There might be small errors, that I haven't seen.

Thank you for showing me around. For real. I had no idea this thing existed. So in case we need to do more things than that, my way would be really troublesome indeed, since I would need to add the code in both if statements making it really heavier than it should be.
I think your suggestion is better. Not to mention that this solution makes thing work optimal, while mine is creating delays that WILL interfere with other stuff. When I will find the time I will test it and include your code with reference in the OP. Kudos!

Here are the simulation results of the code from Chrisl

The code (same as the other answer)
#include <Servo.h>

Servo servo1;
int set_angle = 0;
int current_angle = 90; // setting starting angle to 90 degrees
unsigned long servo_timestamp = 0;
#define SERVO_INTERVAL    10   // changing the servo position every 10ms, defines the speed of the servo

void setup()
{
    servo1.attach(11);  // connect Servo to pin 11
    pinMode(A0, INPUT); // Connect potentiometer or Joystick x or y pin to A0 input
}

void loop(){
    if(millis()-servo_timestamp > SERVO_INTERVAL){
        servo_timestamp += SERVO_INTERVAL; // increment our timestamp by the servo interval
        // Measure the new set_angle only, if we really want to move the sensor
        int val1 = analogRead(A0); // Read the potentiometer position
        set_angle = map(val1, 0, 1023, 0, 180); // Map the value to be used with servo

        // Increment or decrement the current angle according to the set_angle
        // and don't change it, when we already are at the set_angle
        if(set_angle > current_angle){
            current_angle++;
        } else if(set_angle < current_angle){
            current_angle--;
        }
        // Write the new angle to the servo
        servo1.write(current_angle);
    }
}

You can tweak the code and see the changes online- Link to the arduino simulation

  #include <Servo.h>
    Servo servo1;
    int previousangle1;
    int dc;
    void setup()
      {
        dc = 10;    // Delay calibration
        servo1.attach(11);  // connect Servo to pin 11
        pinMode(A0, INPUT); // Connect potentiometer or Joystick x or y pin to A0 input
        previousangle1 = 90; // Initialize position to 90 degrees (180 degree servo)
      }

    void loop()
      {

      int val1 = analogRead(A0); // Read the potentiometer position
      int angle1 = map(val1, 0, 1023, 0, 180); // Map the value to be used with servo

      if(angle1>previousangle1)
      {
        for(int i=previousangle1; i<=angle1; i++)
        {
          servo1.write(i); //turn servo by 1 degrees
          delay(dc);        //delay for smoothness
        }
      }
      // Fix: This needed to be an else if
      // Original piece of code had it as a second stand alone if
      else if(angle1<previousangle1)
      {
        for(int j=previousangle1; j>=angle1; j--)
        {
          servo1.write(j);
          delay(dc);
        }
      }
      delay(dc);
      previousangle1 = angle1;
      }

What you need to do now, is make similar code, with different variables for all 4 servos.
I still have to check the addition of a capacitor to make it work even better.
Original code is taken from here:
https://arduino.stackexchange.com/a/29970/76974
I will edit this, adding code for the rest of the servos later on.