body:
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;
      }
    }

title: Need to operate 2 different sensors (MPU 6050 and Admp 401) simultaneously

Answers: 0


body:
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();
    */
  }
}
```

title: How to reset a variable just before entering a function?

Answers: 2

body:
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.

body:
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.


body:
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");
    }

title: Unable to write, or read a sensor's registers. Do I have an error in my code?

Answers: 0


body:
**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
```cpp

#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);

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

Answers: 0


body:
: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.

title: How to connect an Output to a Pullup Input of another arduino

Answers: 1

body:
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.


body:
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][1].
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.

  [1]: https://www.pjrc.com/teensy/td_uart.html

title: Teensy 4.1 serial communication with 7N2 (7 databits no parity 2 stopbits)

Answers: 1

body:
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:

```c++
Serial.write(val | 0x80);
```
And:
```c++
uint8_t val = Serial.read() & 0x7F;
```


body:
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");
  }
}
```

title: ESP32 can't enter interrupt anymore after interrupt appears during delayMicrosecond function

Answers: 0


body: 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.

title: Mass testing of Arduinos

Answers: 5

body: 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.

body:
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.

body: 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).

body:
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:

 1. 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?
 2. How many GPIO pins are there? Will they be used to drive, sense or both?
 3. Are there any Analog pins?  Do they need to be tested over a range or just a select voltage?
 4. Are there any PWM outputs which need to be tested?

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

 1. If the GPIO aspect of a pin works any PWM feature for that pin may be assumed functional.
 2. 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)][1].

The ["Make a Pogo Pin Test Jig" project][2] at [Adafruit][3] addresses many of these concerns at a level that may be suitable to implement at the college level.

  [1]: https://en.wikipedia.org/wiki/In-circuit_test
  [2]: https://learn.adafruit.com/how-to-make-a-pogo-pin-test-jig
  [3]: https://www.adafruit.com/

body:
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:

1. a pin set to `OUPUT` `LOW` reads `LOW`
2. a pin set to `OUPUT` `HIGH` reads `HIGH`
3. a pin switched from `OUPUT` `HIGH` to `INPUT` reads `HIGH`
4. a pin switched from `OUPUT` `LOW` to `INPUT` reads `LOW`
5. 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.”

```c++
#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.


body:
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");

}

```

title: AccelStepper Library Help - Simultaneous Motor Driving

Answers: 1

body:
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.


body:
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);
}

```

title: SIM900A Module doesn't send SMS to user anymore, after previously working

Answers: 0


body:
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.
[![enter image description here][1]][1]
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)

  [1]: https://i.stack.imgur.com/1KoTZ.png

title: What kind of distance sensor are optimal to measure distances to surfaces at an angle to the sensor?

Answers: 1

body:
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.


body:
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();
    }
```

title: How to add colour change to the strobe coding?

Answers: 1

body:
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).


body:
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:

https://arduino.stackexchange.com/questions/29966/smooth-servo-control-library
(Dat-ha provided a piece of code that I suggest a correction here)

I also checked this:
https://arduino.stackexchange.com/questions/1241/my-servo-wont-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.

title: Smooth Servo movement for robotic arm: An ongoing answer and soluton

Answers: 3

body:
      #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.

body:
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.

body:
Here are the simulation results of the code from Chrisl
[![enter image description here][1]][1]

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][2]

  [1]: https://i.stack.imgur.com/n3bqZ.gif
  [2]: https://wokwi.com/arduino/projects/298559881968878089


body:
I am coding my arduino for an upcoming robot competition. I have managed to upload my code and run it on my arduino once or twice, however now I am unable to upload code. I now receive the following message:
```
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
```
I have unplugged USB, pushed the reset button, checked all the settings (ports, programmer, etc), unplugged the arduino and even tried running basic code such as Blink. I've been searching for hours and now I'm not sure what to do. I am getting no response and I'm finding this really frustrating. Does anyone have any advice as to how to resolve this issue?

title: Unable to upload to arduino

Answers: 0


body: Im trying to make a macro pad using Arduino Uno r3 and 4x4 matrix (cherry blue clone) . I know using a pro micro is better than uno cause there isn't HID compatibility in uno but since i already have one , i want to work with this . I have already tested the macro pad after compiling and flashing a keyboard.hex file . But wondering if i buy a bt module like HC-06 (which is about 3.2$ here ) would that be able to send inputs even aftar flashing ? I have like basics coding knowledge so i have no clue what flashing actually would do to the module so . Anyone know would making that macro pad BT compatible    be possible or not ?

title: Arduino Uno R3 HID with HC-06 BT module

Answers: 1

body:
It is unclear to me, where you flashed what, so I will describe some basics.

The Uno cannot act as a keyboard/HID device, since the microcontroller on it (the Atmega328p) doesn't have native USB capability. For connecting to USB the Uno has a USB-to-Serial chip on it (actually another microcontroller, the Atmega32u4 I think). So with the Uno you only have a serial connection, unless you hack the Atmega32u4 and program it with your own firmware (firmware is a term for software, that runs very near to the hardware, in this case directly on the microcontroller, in contrast to normal software running on an operating system on a computer; so in the middle between hard- and software, thus **firm**ware).

Flashing is the same as programming a microcontroller. It has this name, because the program is saved in flash memory on the microcontroller (that is a specific type of memory technology; the same technology, that USB sticks use for storing your data). Flashing the HC-06 means programming it with a different firmware.

All bluetooth devices use the same base technology (thought to be clear, BLE is a different technology). The role of the device depends on the characteristic/profile, that it exposes to the host. There are profiles for HID, Serial, Audio, ... .

The HC-06 is a bluetooth slave device, which acts as a bluetooth-serial-bridge (like the Atmega32u4 acts as a USB-serial-bridge). But this is a software limitation. The HC-06 has standard bluetooth hardware, but the firmware on it just gives you the Serial profile (in fact a HC-06 is mostly the same like the master device HC-05, just different firmware and corresponding breakout boards can break out other pins). So by flashing (programming) it with a different firmware, you can get different profiles. If you find a firmware, that gives you HID functionality, you can flash that to the HC-06 and use it. Though this is a bit hacky I think (haven't done it myself), so it might be a bit too much for a beginner.

**Bluetooth Slave/Master:** The bluetooth protocol uses fixed roles for the two connected devices. One is the master and one is the slave. The master controls, if the communication is really happening. For example a bluetooth headset is a slave device. You cannot connect the bluetooth headset to your bluetooth keyboard, because both are slave devices. You always need one master and one slave. The HC-05 is basically the same module as the HC-06, but it's firmware enables it do be master or slave (configurable by you). So some devices support both modes, but still in any specific connection they can only have one of the modes (need to either master OR slave at any time).

>  Anyone know would making that macro pad BT compatible be possible or not ?

Possible, yes. But I suggest you invest in buying a ready to use bluetooth HID controller (immediately found [this one from adafruit][1], though you might might cheaper versions). That will be way easier, than directly jumping into flashing a HC-06. Though that is still a possible path to go.

Another way to go would be to just use the serial functionality and write a small program for your PC, which reads from the Serial interface and issues key strokes according to the serial data. Then you don't need to reflash the HC-06.

  [1]: https://www.adafruit.com/product/1535


body:
I want to achieve printing `Hello World` in the serial monitor using Tinkercad to simulate Arduino.

[Here][1] is a very simple example code for real Arduino.

```arduino
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Hello World!");
}

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

}
```

However, putting an Uno board, typing this code, and clicking "Start Simulation" in Tinkercad doesn't show the `Hello World` message.

Is it doable? If so how?

For real Arduino, you need to select Arduino serial port and open Serial Monitor. But I can't find such an option for Tinkercad. I can't find Serial Monitor in Thinkercad.

My real purpose is to use Serial Monitor output to test code snippets. Right now I don't have real Arduino board with me, so I thought a simulator would be ideal. If I can easily check the values of variables, it doesn't have to be Serial Monitor.

Sorry if this is not a place to ask questions about simulators.

  [1]: https://arduinogetstarted.com/tutorials/arduino-hello-world

title: How can I run Hello World using Serial Monitor in Tinkercad Arduino simulator?

Answers: 1

body:
I mean where would you expect it to print ```Hello World``` ... On the Serial Monitor, right? So first open it by clicking on the Serial Monitor button at the bottom of the code tab in Tinkercad.

I tried your code and it works perfectly fine.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/AlW5l.png


body:
I'm very new to microcontrollers. I'd like to start developing for the esp32, as it has integrated wifi & bluetooth for quite cheap. This being said, i don't have a board yet. Is there a way i can emulate an esp32 board, so i can start programming and debugging my code?

As i'm very new, any advice is welcome.

Thanks

title: Code for ESP32 without Development Board

Answers: 2

body: If you are new to microcontrollers then start with basic arduino code and components.  Since the esp chips can be coded with the Arduino framework it will be an almost seemless transition from Arduino board to ESP board.  Build some circuits on tinkercad.com, write some code, and simulate them. Once you have those basics down hopefully your esp board will have arrived and you can start building your project.

body:
Welcome to Arduino Stack exchange. There are a lot of discussions and half-completed, or project-specific models available for the ESP32 simulator. **My sincere advice is to go ahead and buy real hardware**. By the time you take to set up the simulators (download the repo, set environment variables, connect GDB debugger or other), you would have received the ESP32 hardware itself.

Why you should go for real hardware?
------------------------------------

 - An emulator can never match the timing of real ESP32 hardware. if you
   have any timing-related issue, you cannot fix it using an ESP32 emulator
 - Real issues in hardware (bounce/debounce of switches, surge current and brownout voltages, rise time and reflections etc - won't appear in the ESP32 simulators
 - EMC issues due to floating inputs, Port pin current limits or even self-heating of components are not considered in most the simulators
 - A code running on the emulator can't always run on the real hardware without modifications, especially when it involved multiple threads and priorities

Still, other options are available online but it depends on your comfort
-------------------------------------------------------------------------

 - [ESP32 Simulator by Wokwi](https://docs.wokwi.com/guides/esp32) - The ESP32 Simulator is currently in preview (affiliation disclosure)

 - [ESP32 simulator from mireq][1] - ESP-IDF contains a small amount of hardware-specific code, FreeRTOS and few multi-platform libraries. This project uses FreeRTOS port for POSIX, LWIP for TCP/IP layer and mbedtls for cryptography functions.
In addition, several useful APIs from esp-idf are implemented eg. logging. With this project, you can write a program, which will be runnable and testable on Linux.

 - [ESP32 machine emulator][2] - The purpose of this package is to enable you to test-drive (TDD) your MicroPython code in an IDE running on your computer. It seems a lot of people are test-driving python, but not many are test-driving MicroPython. That’s understandable, since many MicroPython projects are simple, and emulating real hardware in a test environment is difficult.

 - [Bridges][3] - Pretend your PC a Raspberry Pi or an ESP32 to connect I2C / SPI / GPIO / UART peripherals.

 **Note** You should also check when is the last time the projects were updated. The latest ones and active ones are always a better choice as they are expected to have better usability, and stable simulations.

______________________________
A few screenshots from Wokwi ESP32 Simulator

[![enter image description here][4]][4]
[![enter image description here][5]][5]

  [1]: https://github.com/mireq/esp32-simulator
  [2]: https://pypi.org/project/esp32-machine-emulator/
  [3]: https://github.com/Wei1234c/Bridges/blob/master/notebooks/readme/Bridges_readme_en.md
  [4]: https://i.stack.imgur.com/8RNql.gif
  [5]: https://i.stack.imgur.com/us5Hh.gif


body:
I'm reading RFID cards' `UID` with an ESP8266 and trying to send that information to my web server hosted on a Raspberry Pi. I'm currently storing the `UID` in an int array, but the `http.POST();` function takes a string input. I tried adding each `UID` digit together, but that doesn't work either.

How would you go about sending the uid in the request?

My code:
```cpp
    /*
    Created by TheCircuit
*/

#define SS_PIN 4  //D2
#define RST_PIN 5 //D1

#include <SPI.h>
#include <MFRC522.h>

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

const char* ssid = "****";
const char* password = "****";
const char* serverName = "****";
int RELAY = 2; //D6

int UIDs[1][4] = {
  {83, 111, 39, 47}
};

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

void setup()
{
  Serial.begin(9600);   // Initiate a serial communication
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522

  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, HIGH);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
}

boolean compareUIDs(int a[4], int b[4]) {
  for (int i = 0; i < 4; i++) {
    if (a[i] != b[i]) return false;
  }

  return true;
}

void loop()
{
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

  // mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

  int UID[4];
  for (int i = 0; i < 4; i++) {
    UID[i] = mfrc522.uid.uidByte[i];
  }

  Serial.print(UID[0]);
  Serial.print(" ");
  Serial.print(UID[1]);
  Serial.print(" ");
  Serial.print(UID[2]);
  Serial.print(" ");
  Serial.print(UID[3]);
  Serial.println();

  for (int i = 0; i < sizeof(UIDs); i++) {
    boolean success = compareUIDs(UIDs[i], UID);
    if (success) {
      Serial.println("ACCESS GRANTED");
      digitalWrite(RELAY, LOW);

      if (WiFi.status() == WL_CONNECTED) {
        HTTPClient http;

        // Your Domain name with URL path or IP address with path
        http.begin(serverName);

        // Specify content-type header
        http.addHeader("Content-Type", "application/json");

        int httpResponseCode = http.POST("UID GOES HERE");

        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);

        // Free resources
        http.end();
      }

      delay(2000);
      digitalWrite(RELAY, HIGH);
      return;
    }
  }
}
```

title: How to send int array with ESP8266 http post request?

Answers: 1

body:
You could use the (awesome) ArduinoJSON library, but likely overkill for this app. I found it more useful to parse JSON than to construct it.

You could simply print to a buffer and the POST that:

```
char payload[MAX_PAYLOAD];
sprintf(payload, "{\"uid1\":%d,\"uid2\":%d,\"uid3\":%d,\"uid4\":%d}", UID[0], UID[1], UID[2], UID[3]);

http.POST(payload);

```

You would `#define MAX_PAYLOAD` with a value that will be sufficient to hold all the information.

Notice that `sprintf` allows you to use any formatting options you want (e.g. hexadecimal, etc).

If you wanted to send it as an array:

```c++
sprintf(payload, "{\"uid\":[%d,%d,%d,%d]}", UID[0], UID[1], UID[2], UID[3]);
```


body:
I have been trying to use the Arduino PID library for controlling the rate of turn (in deg/sec) of a wall-following robot.

The robot's operating system uses TIMER5 on an Arduino MEGA2560 to update a number of time-sensitive parameters (heading, front/back/left/right distances, etc) which are used throughout the code. For turn rate control, the difference between the current and previous headings (appropriately modified for 0/180 transitions) is multiplied by 10 to get deg/sec, and then this value is the 'input' to a PID. The PID output is a speed control to the wheels to achieve the desired turn rate setpoint.

Unfortunately, the current Arduino PID library has an internal timer (that can be changed, but not disabled) which has it's own idea of time.  In addition, the PID library's internal timer isn't available to the outside world - it is only used in PID::Compute().

The typical code configuration for using a PID is something like the following:

    loop()
    {
     //lots of other stuff
     if(TIMER5 ISR has been triggered)
     {
      //compute turn rate = 10*delta_heading
     }

     if(myPID.Compute()) //the internal timer is used inside this function
     {
        //use the PID output to control something (like wheel speeds)
     }
    }

loop() runs at max speed, but myPID.Compute() only generates a new output when the internal PID timer elapses (otherwise it returns immediately without doing anything).  However, the turn rate input is being computed on a different schedule, leading to unpredictable behavior.

A possible solution is:

    loop()
    {
     //lots of other stuff

     if(myPID.Compute()) //the internal timer is used inside this function
     {
      New_Hdg_Val = GetNewHdgVal();
      turn_rate = ComputeTurnRate(New_Hdg_Val, Prev_Hdg_Val);
      Prev_Hdg_Val = New_Hdg_Val;

        //use the PID output to control something (like wheel speeds)
     }
    }

So now the turn rate is computed on the same time intervals as PID::Compute(), which looks OK, as long as the timer value being used by the PID is the same as the TIMER5 ISR value being used by the rest of the program; clunky, inelegant, but maybe OK.

Unfortunately, because the PID computes a new output value inside PID::Compute(), the new value computation comes BEFORE the turn rate computation, which means the turn rate being used to produce the new output uses turn rate information that is AT LEAST 100mSec out of date (assuming the default 100mSec PID sample time setting) - ouch!!

So, how do others use the Arduino PID library in systems with an external (to the PID library) timing source?

title: How do I synch the Arduino PID library with an external timer for turn-rate control?

Answers: 0


body:
I'm trying to run a SPS-15RF stepper motor from an old cd rom drive. I'm using a CNC shield and a4988 driver with a 6v power supply. The motion is smooth and fine. I know it has 18 pulse/revolution and works with 5v but It gets quite unexpectedly hot. It feels that it can burn my fingers if I keep it running.
What is wrong with it? is it related to micro-stepping or sth else!?[![enter image description here][1]][1]

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/i7MAP.jpg
  [2]: https://i.stack.imgur.com/6Emq3.jpg

title: CD rom stepper getting warm

Answers: 0


body:
I am thinking of using an ultrasonic sensor outdoors, and am wondering if the presence of wind (say up to 20km/h) would significantly impact the accuracy of the readings, or would this not be a large concern?

Thanks.

title: Does natural outdoors wind affect the readings of an ultrasonic sensor significantly?

Answers: 0


body:
I am trying to optimize the memory usage of my ESP8266 arduino sketch by using 8.3 SFN folder names internally, but LFN when needed for user output. Unfortunately when opening a folder by using the SFN, getName also returns the SFN:

    sdfat::SdFile _currentFolder;
    _currentFolder.open("BLUBBE~1");
    char foldername[100];
    _currentFolder.getName(foldername, sizeof(foldername));

results in "BLUBBE~1" while

    sdfat::SdFile _currentFolder;
    _currentFolder.open("blubberblub");
    char foldername[100];
    _currentFolder.getName(foldername, sizeof(foldername));

results in "blubberblub" (and getSFN would return "BLUBBE~1"). Is there any chance to open the folder using the SFN "BLUBBE~1", but get the LFN ("blubberblub") later on?

title: Get LFN from SFN with SDFat

Answers: 0


body:
The project is Like a secured PiggyBank but it will count the coins inside it.
Im using a coin sensor at default it has 5v, then goes to zer if inserted with a coin.
I have 2 codes The one was form my old project then second one was a coinslot code got in youtube.

Im hoping someone can guide me where to deelte some codes, then add it at one lsit of code.
Behavior of the project
-Start > Display Total : Amount > if I will unlock the solenoid it will display Welcome "NAME" .
Hope you can get my Idea. Some of code inside of the solenoid was not perfect sorry for that I just get it from scrath without proper knowledge.

 This is code for FINGERPRINT TO SOLENOID LOCK

    #include <Adafruit_Fingerprint.h>    //Libraries needed
    #include <SoftwareSerial.h>
    #include <LCD.h>
    #include <LiquidCrystal_I2C.h>

    #define I2C_ADDR 0x27          //LCD i2c stuff
    #define BACKLIGHT_PIN 3
    #define En_pin 2
    #define Rw_pin 1
    #define Rs_pin 0
    #define D4_pin 4
    #define D5_pin 5
    #define D6_pin 6
    #define D7_pin 7

    int in2 = 4;

    int But1=8;  // In order to add a push button I got the 5v from the pin 8 instead of "5v" arduino pin
    int But2=9;

    String Names[] = { "RAVEN", "Surtr", "Tech",}; //Those are the names affected to the fingertemplates IDs
                                                     //The first on which is Names[0] : Yassine has the ID 1 in the fingerprint sensor

    SoftwareSerial mySerial(2, 3);                  //Fingerprint sensor wiring RX 3, TX 2
    LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); //LCD declaring

    Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);                    //Fingerprint sensor declaring

    void setup()
    {
      pinMode(in2, OUTPUT);
      digitalWrite(in2, HIGH);
      pinMode(But1, OUTPUT);    //Push button stuff, I made the pin 8 permanent LOW level
      digitalWrite(But1,LOW);
      pinMode(But2,INPUT_PULLUP);     //And I read the button state on pin 9

      Serial.begin(9600);               //Serial begin incase you need to see something on the serial monitor
      finger.begin(57600);              //Sensor baude rate
      lcd.begin (16,2);
      lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
      lcd.setBacklight(HIGH);
      lcd.home();
      finger.getTemplateCount();        //Counts the number of templates stored in the sensor flash memory
      delay(2000);
      introScreen();
    }

    void loop()
    {
      int result = getFingerprintIDez();  //This function keeps looping and waiting for a fingerprint to be put on the sensor
      //delay(50);
      bool Button1=digitalRead(But2);  //Reading the state of the pushbutton
      if(Button1==LOW or result >= 0){
        //If the button is pressed it opens the doorlock as the button is meant to be inside
        OpenDoor();
        introScreen();
      }
    }

    void introScreen()
    {
        lcd.clear();
        lcd.print("Place finger");
    }

    //Main function taken from the "fingerprint" example and modified
    //Only the modifications are commented
    int getFingerprintIDez() {
      uint8_t p = finger.getImage();        //Image scanning
      if (p != FINGERPRINT_OK)  return -1;

      p = finger.image2Tz();               //Converting
      if (p != FINGERPRINT_OK)  return -1;

      lcd.clear();                     //And here we write a message or take an action for the denied template
      p = finger.fingerFastSearch();     //Looking for matches in the internal memory
      if (p != FINGERPRINT_OK){          //if the searching fails it means that the template isn't registered
        lcd.print("Access denied");
        delay(2000);
        introScreen();
        return -1;
      }
                //If we found a match we proceed in the function

      lcd.print("Welcome");                  //Printing a message for the recognized template
      lcd.setCursor(2,1);
      lcd.print(Names[finger.fingerID-1]); //Then print the name we gave it and the -1 is to remove the shift as the ID starts from "1" but the array from "0"
      return finger.fingerID;
    }

    /*The two following functions depends on your locking system
     *mine has a DC motor that should turn in both ways for opening and closing
     *that's why I'm using H bridge, you could have a solenoid with a transistor
     *then you'll need only opening sequence but controlling the transistor
     *as the closing is spring loaded...
     */

    void OpenDoor(){
      digitalWrite(in2, LOW); // turn on motor
      delay(5000);
      digitalWrite(in2, HIGH); // turn off motor
    }

This code is for COINSLOT

    #include <Wire.h>
    #include <LCD.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM.h>
    #define coinSlot 6

    LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified module

    int coinCount = 0;
    int coinSlotSignal;
    int requiredCoins = 1;
    boolean coinInserted = false;

    void setup() {
      Serial.begin(9600);
     pinMode(coinSlot, INPUT_PULLUP);

     lcd.setBacklightPin(3,POSITIVE);
     lcd.setBacklight(LOW); // You can turn the backlight off by setting it to LOW instead of HIGH
     lcd.begin(16, 2);
    lcd.write(EEPROM.read(5));
    }

    void loop() {
      while(!coinInserted){
      coinSlotSignal = digitalRead(coinSlot);
      if(coinSlotSignal < 1) {
        coinCount += 1;
        coinInserted = true;
    EEPROM.write(0,coinCount);
    Serial.println(EEPROM.read(0));

    lcd.setCursor(0,0);
    lcd.print("TOTAL:");
    lcd.setCursor(0,1);
    lcd.print(coinCount);
    }
      }

    while(coinInserted) {
      coinSlotSignal = digitalRead(coinSlot);
      if(coinSlotSignal >0) {
        coinInserted = false;

      }
    }
    if(coinCount >= requiredCoins) {
      delay(1500);
    }
    }

title: How to edit this IR sensor code to COINSLOT sensor

Answers: 0


body:
I was trying to make esp32 face recognition using the esp32 camera web server example in arduino ,
and everything works fine untill i press on face detection the frame is frozen , module restarted and put this error to serial monitor :

```

CORRUPT HEAP: Bad head at 0x3ffe2eb4. Expected 0xabba1234 got 0x00000008
abort() was called at PC 0x4008a64d on core 1

ELF file SHA256: 0000000000000000

Backtrace: 0x4008df7c:0x3ffe1c30 0x4008e1f5:0x3ffe1c50 0x4008a64d:0x3ffe1c70
0x4008a779:0x3ffe1ca0 0x400f97cb:0x3ffe1cc0 0x400f5a61:0x3ffe1f80 0x400f59f0:0x3ffe1fd0
0x40093545:0x3ffe2000 0x40082976:0x3ffe2020 0x4008a545:0x3ffe2040 0x4000bec7:0x3ffe2060
0x400d1bc9:0x3ffe2080 0x401194f5:0x3ffe2230 0x40119bfd:0x3ffe2260 0x40119cb5:0x3ffe22f0
0x4011a088:0x3ffe2310 0x40118774:0x3ffe2330 0x401187cb:0x3ffe2370 0x4008fe86:0x3ffe2390

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4

```
I tried erasing flash bt it made the same error again
I am using Arduino IDE 1.8.12 , esp32-cam
operating at 5 volts from the programmer (also tried other external power supplies)
and these are the pictures of settings : (also used wrover kit in programming settings with huge app >3mb)

[Chip name][1]
[![enter image description here][1]][1]
[ESP32 Cam][2]
[![enter image description here][2]][2]
[FTDI Programmer][3]
[![enter image description here][3]][3]
[AI THINKER][4]
[![enter image description here][4]][4]
[Settings][5]
[![enter image description here][5]][5]

I want to make a face recognition door lock , if this doesn't work could anyone refer me to how can I get facial recognition on esp32 cam with any other way?

  [1]: https://i.stack.imgur.com/uJ79S.jpg
  [2]: https://i.stack.imgur.com/CJW2q.jpg
  [3]: https://i.stack.imgur.com/NA28L.jpg
  [4]: https://i.stack.imgur.com/ybbFg.jpg
  [5]: https://i.stack.imgur.com/Re66W.jpg

title: Can't enable face detection on esp32 cam : CORRUPT HEAP: Bad head at 0x3ffe2eb4. Expected 0xabba1234 got 0x00000008 abort()

Answers: 3

body: I ran into this issue with the same setup. This Github issue seems identical to ours, and applying the fix in this comment quickly resolved it for me: https://github.com/espressif/arduino-esp32/issues/5128#issuecomment-851785970. Good luck!

body: Rollback your ESP32 board driver to 1.04. works for me ;-)

body:
I don't have enough reputation to be able to add a comment, but using the answer from [Andrew Hart][1] I was able to resolve this.  For completeness of this thread in case the [linked][2] solution ever disappears:

Locate these sections from the app_httpd.cpp:

    if (net_boxes){
        detected = true;
        if(recognition_enabled){
            face_id = run_face_recognition(image_matrix, net_boxes);
        }
        draw_face_boxes(image_matrix, net_boxes, face_id);
        free(net_boxes->score);
        free(net_boxes->box);
        free(net_boxes->landmark);
        free(net_boxes);

and

    fr_recognize = esp_timer_get_time();
    draw_face_boxes(image_matrix, net_boxes, face_id);
    free(net_boxes->score);
    free(net_boxes->box);
    free(net_boxes->landmark);
    free(net_boxes);

replace the 4 `free`'s in each block with `dl_lib_free`.

  [1]: https://arduino.stackexchange.com/users/77396/andrew-hart
  [2]: https://github.com/espressif/arduino-esp32/issues/5128#issuecomment-851785970


body:
I'm trying to port my esp32 program to esp8266, and i've come across a problem where i can't get a response from a HTTPS GET request on esp8266, but on my esp32 the same code works fine.
The function i'm using looks like this:

    void GetHTTP()
    {
      if (WiFi.status() == WL_CONNECTED)
      {
        HTTPClient http;
        http.begin(requestURL);
        int httpCode = http.GET();
        if (httpCode > 0)
        {
          requestData = http.getString();
          GenerateTable();
          //GetDelimiterCount(requestData, delimiterStart);
        }
        http.end();
      }
    }
I've also tried running my request with the esp8266 "BasicHttpsClient" and "BasicHttpClient", and in both cases the program returns the error: "connection failed" from `https.errorToString(httpCode).s_str()`
or http code "-1" without any API specific error codes.

I'm requesting from Trafiklab's [realtime infromation v4 API][1] And
the request looks somewhat like this:
> https://api.sl.se/api2/realtimedeparturesV4.json?<apikeysandparams>

I've omitted the API key and parameters i use from this URL. The response is also correct when requested by any browser.

Could this be something to do with SSL? I'm completely out of clues as to what the differences between esp32's and esp8266's http-client libraries might be. I'm also using the latest version of the ESP8266 Boards libraries (2.7.4).

  [1]: https://www.trafiklab.se/node/15754/documentation

title: HTTPS GET request working on esp32 but not on esp8266

Answers: 1

body:
I ended up using

> ESP8266WiFi.h

 instead of

> ESP8266WiFiMulti.h

This fixed both my original code and the basic HTTPS example. I still don't understand what difference it made though.


body:
I have an ic (CT1642 1442) it's a led driver 8 bit, i want to use it with my arduino nano and i don't have any idea how to use it.
If someone can help me ill be thankfull.

title: Using a leds driver ic with arduino

Answers: 0