body:
I am getting this error in my code.
`Fatal exception 9(LoadStoreAlignmentCause):`

Using core version `2.4.2`

Stack trace

 Decoding stack results
 0x40213e9c: dns_gethostbyname at core/dns.c line 1472
 0x40204c21: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&, unsigned int) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp line 468
 0x40205038: WiFiClient::connect(char const*, unsigned short) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/WiFiClient.cpp line 98
 0x4020306b: setPostString(int, int, Array8Int, char*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 516
 0x40203f8a: uploadAgrigis(char const*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 335
 0x40209080: Print::println() at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/Print.cpp line 178
 0x402048e0: loop() at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 243

struct declaration

    struct Array8Int {
        int array[8];
    };

loop

    char post[300] = "";
    int pulseChange05m = rainCheck(slaveData);
    int now10 = floor(unixtimeServer/10)*10;
    Array8Int slaveData = slaveCheck(now()); // update slaveData array
    setPostString(now10, pulseChange05m, slaveData, post);

functions

 void setPostString(int unixtimeEvent, int pulseChange, Array8Int postData, char* postStr) {
   bool flag = true;
   float rainHour = pulseChange*0.25;
   if (hour() == 10) { // 7 AM palmital
     rainCount = 0;
     rainCount05m = 0;
   }
   rainCountHour = rainCount;
   int humidityBme280HourAvg = 0;
   int pressureBme280HourAvg = 0;
   int temperatureBme280HourAvg = 0;
   int lightSensorHourAvg = 0;
   int pressureBme280HourMin = 100000;
   int temperatureBme280HourMin = 1000;
   int temperatureBme280HourMax = -1000;
   int counterLoop = counterHour;
   for(int i=0;i<counterLoop;i++) {
     lightSensorHourAvg += lightSensorHour[i];
     pressureBme280HourAvg += pressureBme280Hour[i];
     temperatureBme280HourAvg += temperatureBme280Hour[i];
     temperatureBme280HourMax= max(temperatureBme280HourMax,temperatureBme280Hour[i]);
     pressureBme280HourMin = min(pressureBme280HourMin,pressureBme280Hour[i]);
     temperatureBme280HourMin = min(temperatureBme280HourMin,temperatureBme280Hour[i]);
     humidityBme280HourAvg += humidityBme280Hour[i];
   }
   pressureBme280HourAvg = pressureBme280HourAvg/counterLoop;
   temperatureBme280HourAvg = temperatureBme280HourAvg/counterLoop;
   lightSensorHourAvg = (int)lightSensorHourAvg/counterLoop;

   strcat(postStr, stationId);
   strcat(postStr,"&3="); // chuva hora
   strcat(postStr, dtostrf(rainHour,6,2,charDummy));
   strcat(postStr,"&8=");
   strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
   strcat(postStr,"&9="); //temperature avg
   strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
   strcat(postStr,"&10="); //temperature avg
   strcat(postStr, dtostrf(temperatureBme280HourMax,6,2,charDummy));
   strcat(postStr,"&11="); //temperature avg
   strcat(postStr, dtostrf(temperatureBme280HourMin,6,2,charDummy));
   strcat(postStr,"&20=");
   strcat(postStr, dtostrf(pressureBme280HourAvg,10,0,charDummy));
   strcat(postStr,"&22=");
   strcat(postStr, dtostrf(pressureBme280HourMin,10,0,charDummy));
   strcat(postStr,"&101=");
   strcat(postStr, dtostrf(lightSensorHourAvg,6,0,charDummy));
   strcat(postStr,"&time=");
   strcat(postStr, dtostrf(unixtimeEvent,16,0,charDummy));
   strcat(postStr,"&endline=1");
   strcat(postStr, "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
 }
 int rainCheck(Array8Int slaveData) {
   int pulseChange = slaveData.array[0];
   return pulseChange;
 }

title: NodeMCU 1.0 - Exception 9 `Fatal exception 9(LoadStoreAlignmentCause):`

Answers: 2

body:
> Fatal exception 9(LoadStoreAlignmentCause):

This is caused by you (or some code you are running) attempting to read or write a 32 bit value from memory that is not "aligned" to 32 bits.  It is most often the result of trying to cast portions of a byte array (for instance a buffer received over UDP) to a 32-bit integer.  The compiler is not clever enough to know that the byte array portion you are casting isn't at a 32-bit boundary and thus doesn't know to use the 8-bit load/store instructions to access the memory.

Mapping a `struct` over a buffer can also have similar issues where the buffer is 8-bit aligned and the `struct` contains 32-bit words.

You can combat it by forcing the alignment of any buffers which you treat in such a way with the `__attribute__((aligned(4))` tag:

    uint8_t __attribute__((aligned(4))) buffer[128];

You can also "pack" structures to tell the compiler "These variables are mis-aligned and should not be padded to 32-bits":

    struct foo {
        uint8_t bar1;
        uint32_t bar2;
    } __attribute__((packed));

If in doubt, though, just pull individual bytes out of buffers (or wherever) and build up your larger integers manually with bit shifting and OR operators (`<<` and `|`), and do the reverse for filling byte buffers.

body:
I had this error including on new cards
it worked on one card and not on another
the reason is that my eeprom was not initialized
the nodemcu 8266 that was working properly, was the one I used for development. Because i was using test to write on my eeprom so the value was put in it.
I did not understand what append After, I try flashing reload original setup etc...
I read your answer and I pass this program (which is a stupid manual writing of my eeprom)
I make it running once
and after that
I could load my other programs without problems
~~~~

    #include <EEPROM.h>
struct credential {
  char WIFI_SSID [39] = " ";
  char WIFI_PASSWORD [39] = " ";
  char SMTP_HOST[44] = " ";
  uint16_t SMTP_PORT = 465;
  char AUTHOR_EMAIL[39] = " ";
  char AUTHOR_PASSWORD[39] = " ";
  char RECIPIENT_EMAIL[39] = " ";
  uint16_t  NbOfProbe = 1; //number of probe 1-to 16
  char TypeOfDevice[16] = "f";// F or f fridge R freezer O hot  exemple fRoFRr
  char AlertMin [54] = "30";//with always a sign like-10+0+2 the sign act like a separator
  char AlertMax [54] = "38";//with always a sign like-10+0+2 the sign act like a separator
  uint16_t  NbOfMinNormMail = 60 ;//time to wait in sec between 2 normal messages eg 14400 sec(4 hours)
  uint16_t  PowerOffMinWait = 1 ;
  uint16_t  TempOffLimitWait = 1;
  char AlertPowerMsg[41] = "alerte coupure de courant "; //Message alerte coupure de courant
  char AlertTempMsg[41] = "alerte temperature hors limite";
  char NormalTempMsg[41] = "Tout est ok ";
  char DateMsg[16] = "vide";
};
typedef struct credential settingcredent;
settingcredent parametersEeprom;
uint addr = 0;
void setup()
{
  Serial.begin(115200);
delay (100);
/*
  // fake data
  struct {
    uint val = 0;
    char str[20] = "";
  } data;
*/
  // commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
  // this step actually loads the content (512 bytes) of flash into
  // a 512-byte-array cache in RAM
 //                                                                          EEPROM.begin(512);

  // read bytes (i.e. sizeof(data) from "EEPROM"),
  // in reality, reads from byte-array cache
  // cast bytes into structure called data
 //
 showeprom ();

  strncpy(parametersEeprom.WIFI_SSID,"myssid",39);
  strncpy(parametersEeprom.WIFI_PASSWORD,"passmyssid",39);
  strncpy(parametersEeprom.SMTP_HOST,"smtp.gmail.com",44);
  parametersEeprom.SMTP_PORT=465;
  strncpy(parametersEeprom.AUTHOR_EMAIL,"iottest@gmail.com",39);
  strncpy(parametersEeprom.AUTHOR_PASSWORD,"iottest01",39);
  strncpy(parametersEeprom.RECIPIENT_EMAIL,"johndoe@hotmail.fr",39);
  parametersEeprom.NbOfProbe = 4; //number of probe 1-to 16
  strncpy(parametersEeprom.TypeOfDevice,"rffo",16);// F or f fridge R freezer O hot  exemple fRoFRr
  strncpy(parametersEeprom.AlertMin,"-20+0+2+23",54);//with always a sign like-10+0+2 the sign act like a separator
  strncpy(parametersEeprom.AlertMax,"-15+5+7+28",54);//with always a sign like-10+0+2 the sign act like a separator
  parametersEeprom.NbOfMinNormMail = 60 ;//time to wait in sec between 2 normal messages eg 14400 sec(4 hours)
  parametersEeprom.PowerOffMinWait = 10 ;
  parametersEeprom.TempOffLimitWait = 20;
  strncpy(parametersEeprom.AlertPowerMsg,"alerte coupure de courant ",41); //Message alerte coupure de courant
  strncpy(parametersEeprom.AlertTempMsg, "alerte temperature hors limite",41);
  strncpy(parametersEeprom.NormalTempMsg, "Tout est ok ",41);
  strncpy(parametersEeprom.DateMsg,"vide",16);
  EEPROM.put(addr, parametersEeprom);
  EEPROM.commit();

  EEPROM.get(addr,parametersEeprom);
  Serial.println("New values are: "+String(parametersEeprom.WIFI_PASSWORD)+","+String(parametersEeprom.WIFI_SSID)+","+String(parametersEeprom.SMTP_HOST));
}
void showeprom ()
{
  EEPROM.begin(sizeof(parametersEeprom));
  EEPROM.get(addr, parametersEeprom); //read data from array in ram and cast it into struct called parametersEeprom

  Serial.println("-------------------------"); //Showing the details
  Serial.print("your SSID ="); Serial.println( parametersEeprom.WIFI_SSID);
  Serial.print("your password for SSID ="); Serial.println( parametersEeprom.WIFI_PASSWORD);
  Serial.print("your SMTP_HOST ="); Serial.println( parametersEeprom.SMTP_HOST);
  Serial.print("your SMTP_PORT ="); Serial.println( parametersEeprom.SMTP_PORT);
  Serial.print("Your less secure email="); Serial.println( parametersEeprom.AUTHOR_EMAIL);
  Serial.print("Your password for not secure email="); Serial.println( parametersEeprom.AUTHOR_PASSWORD);
  Serial.print("Your email that must receive msg like MeTheBoss@MyCompany.com="); Serial.println( parametersEeprom.RECIPIENT_EMAIL);
  Serial.print("The number of thermometers probe you have is ="); Serial.println( parametersEeprom.NbOfProbe);
  Serial.print("Enter in order type of device (F)ridge f(R)ezzer (O)ven like RFFO="); Serial.println( parametersEeprom.TypeOfDevice);
  Serial.print("Enter mintemp in order per device like(suppose RFFO) -22-1+5+180="); Serial.println( parametersEeprom.AlertMin);
  Serial.print("Enter maxtemp in order per device like(suppose RFFO) -16+4+10+220="); Serial.println( parametersEeprom.AlertMax);
  Serial.print("Number of sec between 2 normal mails like(4hours) 240 ="); Serial.println( parametersEeprom.NbOfMinNormMail);
  Serial.print("Number of sec to wait before sending message Power off like 5 ="); Serial.println( parametersEeprom.PowerOffMinWait);
  Serial.print("Number of sec to wait before sending message warning temp like 5 ="); Serial.println( parametersEeprom.TempOffLimitWait);
  Serial.print("Message power down(30 char) like WARNING POWER OFF GRID="); Serial.println( parametersEeprom.AlertPowerMsg);
  Serial.print("Message temperature off min/max(30 char) like WARNING TEMPERATURE ABNORMAL="); Serial.println( parametersEeprom.AlertTempMsg);
  Serial.print("Message report state of all fridges freezer Oven like Everything is OK in the kitchen ="); Serial.println( parametersEeprom.NormalTempMsg);
  Serial.print("Enter date of the modif parameters like 08/23/21-18:25="); Serial.println( parametersEeprom.DateMsg);

}
void loop()
{
  delay(10000);
  showeprom ();

}

~
~

I hope that this experiment can be usefull
I cannot explain why it work


body:
I have a 2-motor robot project that uses a MP6050 for relative heading (yaw) measurements, and I'm having problems with the I2C bus when the motors are running.  I have done most of the things suggested here and elsewhere; 2.2K pullups vs default, shortest possible (3cm) I2C wires, MPU6050 as far away from the motor drivers as possible, reduced I2C clock speed to 100KHz, etc, etc (for additional details, see my [blog post][1] on the subject).

So, my question is, why is the I2C bus so sensitive to RFI/EMI, especially with 2.2K pullups to +5V?  Looking at the levels with my O'scope shows a 0-4.6V swing, so it's hard to believe that EMI-induced currents could be high enough across 2.2K to pull the 'high' level low enough to be considered a '0', so something else must be going on.  Maybe the EMI is getting into the MPU6050 output driver circuit, causing it to turn off?  If so, maybe capacitive bypasses on the I2C lines would help.  Any ideas?  Are other IMU modules less susceptible to motor driver EMI?

TIA,

Frank

  [1]: https://www.fpaynter.com/2019/07/mpu6050-imu-motor-noise-troubleshooting/

title: Why is Arduino I2C so sensitive to RFI/EMI?

Answers: 1

body:
Put a ground plate between your data lines and the power+signal lines used to drive the motor. A GPS ground plate is fine, see link below. You can just cut a piece of metal sheet to fit, or even use folded metal foil connected to ground. Motors are just noisy, and I2C is sensitive. Even updating a I2C LCD can cause noise. I like to use shielded wire (like for headphone- or HDMI cable) if my data lines are more than an inch long. You can shield lines with metal foil and heatshrink, but that’s a mess.

Use an opto-isolator to turn on your motors if a ground plate is not enough. If they only drive in one direction, add a catch diode and a 330pF cap to trim the noise. But they are probably most noisy when running. Good luck with that.

https://www.imnasa.com/en/ground-plate-200x64x12mm-for-gps-etc.html


body:
On my first big Arduino-project I made a game using the following Arduino's and the I2C-protocol:

- 1x Mega as master
- 4x Mega as slave
- 2x Uno as slave

The Arduino's controll a physical game where the players have to push 96 different buttons, according to how certain lights are controlled by relays. The two uno's are used for a MP3-shield and a timer.

My code might not be perfect at all, but I'm happy with how it works. The only problem is that sometimes my master freezes. This is on different moments, but always when the master processes multiple I2C-communications. Sometimes it completes the whole game without problem, but other times it freezes at different moments.

I used a 1ms delay at the end of the loop on all arduino's, because it looked like this might make the connection most stable. The I2C-cables are up to about 1m long, I can't make them shorter. I added 5K1-resesistors from the 5v-line of the master-Mega on the SDA and SCL line. Alle buttons and relays in the game are connected to seperate power sources and don't use the internal pullups.

The code is quite long, so I uploaded the code of the master and the code of 1 mega slave to Github: https://github.com/mrcbrgrs/Arduino-mega-buttons-game. Some comments might be in Dutch, sorry for that.

Who has an idea how I can stop the Mega from freezing?

title: I2C freeze on master

Answers: 0


body:
I've been working with MEGA before. This code works completely with MEGA. I'm still at beginner level in Arduino.

**Q:** How do I adapt this code to DUE?

**Note:** I'm asking this question because I think the only problem in adaptation seems to be `SoftwareSerial`.
<!-- language-all: lang-cpp -->
```
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(52,53);    // TX,RX
int bar_analog=0;
int head_analog=0;
int bar_anim=0;
int strip_anim=0;
int motor_speed=1;
int direct=0;
int level=0;
boolean debug = true;
int IN1a=49;
int IN2a=48;
int PWM1=3;
int IN1b=22;
int IN2b=23;
int PWM2=4;
int hiz=100;
int PWM_kare=2;
int INA_kare = 51;
int INB_kare = 50; //LED '+'sı OUTPUT B'de olduğu için INB'yi  HIGH yapıyoruz.
void m1_cw() {
    digitalWrite(IN1a,HIGH);
    digitalWrite(IN2a,LOW);
    analogWrite(PWM1,hiz);
}
void m1_ccw() {
    digitalWrite(IN1a,LOW);
    digitalWrite(IN2a,HIGH);
    analogWrite(PWM1,hiz);
}
void m2_cw() {
    digitalWrite(IN1b,HIGH);
    digitalWrite(IN2b,LOW);
    analogWrite(PWM2,hiz);
}
void m2_ccw() {
    digitalWrite(IN1b,LOW);
    digitalWrite(IN2b,HIGH);
    analogWrite(PWM2,hiz);
}
void m1_stop() {
    digitalWrite(IN1a,LOW);
    digitalWrite(IN2a,LOW);
    analogWrite(PWM1,0);
}
void m2_stop() {
    digitalWrite(IN1b,LOW);
    digitalWrite(IN2b,LOW);
    analogWrite(PWM2,0);
}
void mast_up() {
    digitalWrite(24,HIGH);
    digitalWrite(25,LOW);
}
void mast_down() {
    digitalWrite(24,LOW);
    digitalWrite(25,HIGH);
}
void mast_stop() {
    digitalWrite(24,LOW);
    digitalWrite(25,LOW);
}
void kare() {
    analogWrite(PWM_kare,head_analog);
    digitalWrite(INB_kare, HIGH);
    digitalWrite(INA_kare, LOW);
}
void setup() {
    Serial.begin(9600);
    bluetooth.begin(9600);
    Serial.println("Program is starting...");
    Serial.println("by Berke Ogulcan Parlak");
    pinMode(IN1a,OUTPUT);
    pinMode(IN2a,OUTPUT);
    pinMode(IN1b,OUTPUT);
    pinMode(IN2b,OUTPUT);
    pinMode(PWM1,OUTPUT);
    pinMode(PWM2,OUTPUT);
    pinMode(24,OUTPUT);
    pinMode(25,OUTPUT);
    pinMode(INA_kare, OUTPUT);
    pinMode(INB_kare, OUTPUT);
    pinMode(PWM_kare, OUTPUT);
    digitalWrite(IN1a,LOW);
    digitalWrite(IN2a,LOW);
    digitalWrite(IN1b,LOW);
    digitalWrite(IN2b,LOW);
    digitalWrite(PWM1,LOW);
    digitalWrite(PWM2,LOW);
    digitalWrite(24,LOW);
    digitalWrite(25,LOW);
    digitalWrite(INA_kare, LOW);
    digitalWrite(INB_kare, LOW);
    digitalWrite(PWM_kare, LOW);
}

void loop() {
    if (bluetooth.available()) {
        while (bluetooth.available())
        {                                                //AppInventor'dan çektiğimiz verileri,değişkenlere atıyoruz.
            bar_analog = bluetooth.parseInt();
            head_analog = bluetooth.parseInt();
            bar_anim = bluetooth.parseInt();
            strip_anim = bluetooth.parseInt();
            motor_speed = bluetooth.parseInt();
            direct = bluetooth.parseInt();
            level = bluetooth.parseInt();
            if (debug) {                                   // Arduin seri ekranından değerleri okumak için gereklidir.
                Serial.print("Bar Brightness: ");
                Serial.println(bar_analog);
                Serial.print("Bar Animation Type: ");
                Serial.println(bar_anim);
                Serial.print("Headlight Brightness: ");
                Serial.println(head_analog);
                Serial.print("Strip Animation Type: ");
                Serial.println(strip_anim);
                Serial.print("Motor Speed Level: ");
                Serial.println(motor_speed);
                Serial.print("Direction: ");
                Serial.println(direct);
                Serial.print("Mast Goes: ");
                Serial.println(level);
                Serial.println("--------------------------------");
            }
            if (bluetooth.read() == '\n') {               //Yazdırma işlemleri bu satırda yapılacak..

            }
        }}
    if(direct==1) { //ileri
        m1_ccw();
        m2_ccw();
    }
    else if(direct==2) { //geri
        m1_cw();
        m2_cw();
    }
    else if(direct==3) { //sol
        m1_ccw();
        m2_cw();
    }
    else if(direct==4) { //sağ
        m1_cw();
        m2_ccw();
    }
    else if(direct==0) { //durur
        m1_stop();
        m2_stop();
    }
    if(level==1) { //mast yukarı
        mast_up();
    }
    else if(level==2) { //mast aşağı
        mast_down();
    }
    else if(level==0) { //mast durur
        mast_stop();
    }
    kare();            //kare LED aktif.
}
```

title: Convert Arduino MEGA Code to Arduino DUE Code?

Answers: 1

body:
SoftwareSerial is a workaround for Arduino versions without enough Hardware Serial ports, which is not the case of Arduino Mega or Arduino Uno which have 4.

Delete `SoftwareSerial`, replace all occurrences of `bluetooth` by `Serial1`, and rewire the Serial communication from pins `52`|`53` into pins `18`|`19` instead of (TX|RX)

Besides, the Arduino Due tends to be more "strict" than Arduino Mega compiler.

Besides that, your code will compile with no issues.

Also, remember Arduino Due is 3.3V and not 5V.


body:
 I have a project that require me to use magnetic contact sensor. I will put the sensor at the door. So the idea is i want every time someone open the door, the buzzer will make a sound, but it will only stay for 3 seconds. When the door is close, buzzer will do nothing and when someone open the door again, the buzzer will make a sound for 3 seconds again. That is the loop. Here is my code. Sorry it's messy. I changed it few times and it still not working like what I want.

    const int buzzer = 13;
    const int sensor = 4;

    int state; // 0 close - 1 open switch

    void setup()
    {
      pinMode(sensor, INPUT_PULLUP);
    }

    void loop()
    {
      state = digitalRead(sensor);

      if (state == HIGH){
        tone(buzzer,1000);
        delay(3000);
        noTone(buzzer);
      }

      else{
        noTone(buzzer);
      }

    }

title: how to set buzzer on and off

Answers: 1

body:
When I have a state-machine problem such as this, I diagram it first - here's mine, based on how I understand your requirements:

[![State Diagram][1]][1]

Most state machines are only activated when an external event happens, so not much happens inside the state-boxes. But since your application only does this one thing, you can actually do your testing inside the states. This is the difference between between blocking- and non-blocking programming - we can afford to block (delay until something happens) because there is nothing else we have to do in the meanwhile.

And my code for the state-machine (which I haven't tested, but it compiles without error):

    const int buzzer = 13;
    const int sensor = 4;

    int state; // 0 close - 1 open switch

    void setup()
    {
       pinMode(sensor, INPUT_PULLUP);
    }

    void loop()
    {
       // Wait for sensor HIGH
       while( digitalRead(sensor) == LOW )
          ;

       // Sensor HIGH - Alarming
       tone(buzzer, 0.52);
       delay(3000);

       // Wait for sensor LOW
       noTone(buzzer);
       while( digitalRead(sensor) == HIGH )
          ;

       // (goes to Wait for sensor HIGH)
    }

  [1]: https://i.stack.imgur.com/CtD4R.jpg


body: How do I find out what my esp3286 core version using Arduino IDE?

title: NodeMCU what is my esp3286 core version

Answers: 1

body: Tools Menu -> Board -> Boards Manager - scroll down to the core and see what version it is.


body:
Consider a scenario where two (or more) `master` devices (the NodeMCU's, in this case) share an `I2C bus` with one (or more) `slave` device(s), like thus:

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

Would this be a feasible setup?  In other words,  could both `masters` request (not simultaneously) from the `slave`?

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

title: Arduino slave with 2 masters sharing the same I2C Bus?

Answers: 2

body:
The situation you describe is called MultiMaster. It is normally done in hardware using the I2C peripheral in the MCU. However the ESP8266 doesn't have one (or if it does, it's not used), and uses bit-banging to implement I2C in software. If you can add MultiMaster functionality to the ESP8266's Wire library then possibly yes, you could do it.

Another option is to have some other communication channel between the two masters (it could be as simple as a wire with a pullup resistor - see below) so that only one master communicates at a time.

Electrically there is no problem with your setup - I2C is a fully open-drain system (or should be implemented as such - hence the pullup resistors needed on the SCL and SDA pins), so multiple devices can drive the lines at the same time. It's just that if they do you will get data corruption and communication won't happen.

----

Example: Semaphore Wire Implementation

1. Connect any two GPIO pins together with a wire. Add a pullup resistor to the wire (10kΩ should suffice).
2. Both GPIO pins are set to INPUT.

When a master wants to send it first reads the GPIO pin:

* If it is HIGH then it is "clear to send". So it sets the GPIO to OUTPUT and pulls the line LOW.
* If it is LOW then it waits for a random amount of time and tries again.

Once communication is finished the master sets the GPIO pin to INPUT again.

body:
Changed diagram after comments and accepted answer:

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

  [1]: https://i.stack.imgur.com/nvCyT.png
  [2]: https://i.stack.imgur.com/qklDJ.png


body:
I designed a PWS (personal weather station) which will be placed in a difficult to access location.  In case of the master crashing and not requesting from the slave for a certain amount of time (stay alive protocol), is it possible to reset the master from the slave by powering a digital pin?

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

Note, I improvised a pull down circuit so that the Arduino Nano's D7 (or any other digital pin) 5V output could be pulled down to 3.3V.

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

title: Reset NodeMCU master from Arduino slave

Answers: 2

body:
There is no need for a voltage divider or a level conversion on the reset pin of the esp8266. The esp8266 has internal pull-up on reset pin. To reset the esp8266 the reset pin must be connected to ground for a very short moment.

To pull the reset pin LOW with pin of the other MCU we do:

    void resetEsp() {
      pinMode(ESP_RESET_PIN, OUTPUT);
      delay(1);
      pinMode(ESP_RESET_PIN, INPUT);
    }

ESP_RESET_PIN is the pin wired to reset pin of the esp8266. It is not configured in `setup()` and it is never set `HIGH` (we don't want to send 5 V to esp8266). Setting the ESP_RESET_PIN to `OUTPUT` connects it to ground, setting it back to `INPUT` hands the control of the line back to esp8266 reset pin's internal pull-up.

body:
As per verification from Juraj, this would be correct wiring for his answer:

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

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


body:
I'm planning to wire a few Arduinos together via RS485, and have one of them act as a hub that collects information from the others and presents it via http on an Ethernet connection.

For instance an Aduino MKR with [ETH shield][1] and [485 shield][2]. Can I expect these to work together? My worry is having 2 shields that potentially need lots of bandwidth, timing issues etc.

  [1]: https://store.arduino.cc/mkr-eth-shield
  [2]: https://store.arduino.cc/arduino-mkr-485-shield

title: one Arduino with RS485 and Ethernet shields: does this work?

Answers: 1

body:
Should be no problem.

The ETH shield uses SPI to communicate with a W5500 chip. That chip does most of the network processing for you.

The 485 shield just connects to the UART TX and RX pins. It's just serial communications with a couple of control pins from there on out.

Neither use any pins that the other one uses.


body:
How can I display / capture Arduino IDE's `Serial1` output?
Can I display it using `Arduino IDE` or using a script in `Python`?

This python script ([courtesy of Chad G][1]) works for the Serial:

 #!/usr/bin/env python3

 import serial
 import sys

 if len(sys.argv)<2:
     print("Please give serial port number")
     exit()
 port=sys.argv[1]
 ser= serial.Serial('/dev/ttyUSB'+port,9600,timeout=5)

 while True:
     try:
  stringMe = str(ser.readline().strip())
  if len(stringMe)>3:
      print(stringMe)

     except:
  print(sys.exc_info())
  ser.close()
  exit()

called as (for USB0):

    python3 Arduino/tools/multiMonitor/monitorUsb1.py 0

or, if I want to save to a log file:

    python3 Arduino/tools/multiMonitor/monitorUsb1.py 0 >> Arduino/tools/multiMonitor/log/usb00.txt

  [1]: https://arduino.stackexchange.com/a/67229/30341

title: Arduino IDE display DEBUG PORT Serial1 output

Answers: 1

body:
`Serial1` (on most Arduino boards that have `Serial1`) is connected to a pair of pins on the GPIO headers and nowhere else.

To get it to your computer you will have to feed those TX and RX pins through a USB to TTL UART (FT232, CP2102, etc) adaptor.

From there on in it's exactly the same as using `Serial` but of course with a different device name.


body:
TL, DR : What is the method (in terms of sensors and algorithm) to get the roll, pitch angles of an aircraft at any instant?

I am planning to build a hobby aircraft. I am so confused about which kind of sensors should I use and how to use them in order to get the roll, pitch and yaw angles of the aircraft.

I think I also have some problems understanding the concept. I consider these P, R, Y angles similar to the x,y,z coordinates as if they are able to describe the **attitude** of a body. If something in the below list contains "nonsense" arguments, please also enlighten me about them.

What I want is to be able to know at any instant:

1. What is the pitch angle of the aircraft, i.e how much degrees its nose pointing away from the horizontal plane of the earth.
2. What is the yaw angle, i.e to what direction(north, east etc) is the aircraft pointing through.
3. What is the roll angle, i.e what is the angle between aircrafts body surface ( wing to wing **x** tail to head surface ) and the horizontal plane of the earth/sky.

In some sources there is something going on as the importance of order of the application of roll, pitch and yaw. But I cannot understand why this is related.

I have used accelerometer values by inputting them into some formulas on the internet (those arctangent formulas, which everybody uses but nobody explains well) to get the roll and pitch values. However could not understand how to manipulate them in order to meet my requirements (different axis orientations of the sensor).

I also have basic understanding about what a gyroscope is.

I have an MPU6050(Accelerometer+Gyroscope).

P.S : my goal is to build a quadcopter but I guess in order to understand these concepts a fixed wing standard plane model.

title: A proper way to get the roll, pitch and yaw values

Answers: 1

body:
> In some sources there is something going on as the importance of order of the application of roll,pitch and yaw. But I cannot understand why this is related.

Take your right hand: point your thumb upwards, your index finger away from you, and your middle finger to the left. You now have a righthanded coordinate system: your thumb is the x axis, your index finger the y axis, and your middle finger the z axis.

First rotate +90° around the x axis (thumb). Your index finger now points to the left, and your middle finger towards you. Next, rotate +90° around the y axis (index finger). Your thumb now points away from you, your index finger to the left, and your middle finger upwards.

Now, move back to the initial position, and apply the same two rotations in a different order, first around the y axis and then the x axis:
Rotate +90° around the y axis (index finger). Your thumb is now pointing to the right, your index finger away from you, and your middle finger upwards. Next, rotate +90° around the x axis (thumb). Your thumb now points to the right, your index finger upwards, and your middle finger towards you.

This is different from the last result: order of rotation matters.

> I have used accelerometer values by inputting them into some formulas on the internet(those arctangent formulas, which everybody uses but nobody explains well)

When the aircraft is moving at a constant velocity, the accelerometer just measures the acceleration due to gravity, which is a vector pointing exactly downward, (0, 0, -g) in the global coordinate system. This is always true, regardless of the orientation of the sensor.
If the sensor is perfectly level, the sensor's local coordinate system is aligned with the global coordinate system, so the sensor also measures (0, 0, -g).

When the sensor is tilted, the measured vector also has an x and y components.
To keep things simple, imagine the case where the sensor is tilted around the positive y axis.
The sensor now measures an x component as well as a z component: (x, 0, -z).

As you can see from the following image, the angle of rotation `θ = atan2(x, z)`.

![gravity acceleration vector](https://i.stack.imgur.com/lGzHt.png)
The black arrow is the acceleration due to gravity, and the red and blue arrows are the x and z axes of the coordinate system of the (tilted) sensor.

***

However, accelerometer measurements are not useful for determining the orientation when the sensor is accelerating, because then the measured vector no longer points exactly downward (in the global coordinate system).

Gyroscopes measure angular velocity. By integrating the angular velocity, you get the angle.
There's one caveat: it is impossible to integrate exactly, because we only have measurements at discrete points in time. This means we have to use something like Euler's method, which is known to result in drift of the orientation estimate. To make matters worse, the measurement is noisy, and this noise is integrated as well, resulting in an even larger error.

Luckily, you can combine both imperfect measurements into a single, better orientation estimate using a sensor fusion algorithm. I've successfully used [Sebastian Madgwick's algorithm](https://x-io.co.uk/open-source-imu-and-ahrs-algorithms/) for my quadcopter.
It uses the measurements of the accelerometer to minimize gyro drift.

Note that this algorithm uses quaternions instead of Euler angles (roll, pitch, yaw), because the latter suffer from gimbal lock, and because quaternions geneally require less processing power.

Also note that you cannot determine the yaw angle using the accelerometer, so you'll get some drift on that measurement.

It's a good idea to do all of your calculations using quaternions. You probably won't need Euler angles for your quadcopter, except maybe for debugging purposes.

If you want to, you can also get the quaternion from the acceleration vector directly:

```cpp
    Quaternion quaternionFromDirection(Vec3f v) {
        /*
         * Formula:
      * q = cos(ϑ / 2) + sin(ϑ / 2)·(x·i + y·j + z·k)
      * where (x y z) is a unit vector representing the axis about which
      * the body is rotated; ϑ is the angle by which it is rotated.
      *
         * Source:
         * https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Using_quaternion_as_rotations
         *
      * The rotational axis (x y z) can be calcuated by taking the normalized
         * cross product of (0 0 1) and the given vector. The angle of rotation
         * ϑ can be found using |A×B| = |A||B|·sin(ϑ).
      */

        // First check the edge case where v == (0 0 z), i.e. vertical
        if (v.x == 0 && v.y == 0)
            return {1, 0, 0, 0};

        // Calculate the cross product and its norm.
        Vec3f cross     = {v.y, -v.x, 0};
        float crossNorm = cross.norm();
        cross /= crossNorm;

        // Calculate the angle ϑ.
        float angle = std::asin(crossNorm / v.norm());

        // Calculate the resulting quaternion.
        return {
            std::cos(angle / 2),            //
            std::sin(angle / 2) * cross.x,  //
            std::sin(angle / 2) * cross.y,  //
            std::sin(angle / 2) * cross.z,  //
        };
    }
```


body:
I have previously connected [5V 10A relay switches][1] to my Arduino.

But for my new project I need to use a [5V 30A relay switch][2] with my Arduino.

In 10A relay switches, we make connection with Arduino using GND, VCC and IN.

But for 30A switches, there are DC+, DC-, IN.

My question is that, how do I connect my Arduino to the relay using these pins?

  [1]: https://www.amazon.in/dp/B01HXJDBII/ref=pd_lpo_sbs_dp_ss_1?pf_rd_p=cd818f9c-142a-4b42-ad2c-f0421857aaf5&pf_rd_s=lpo-top-stripe&pf_rd_t=201&pf_rd_i=B00C59NOHK&pf_rd_m=A1VBAL9TL5WCBF&pf_rd_r=MJP2SHRW2PN89Y5J5V18&pf_rd_r=MJP2SHRW2PN89Y5J5V18&pf_rd_p=cd818f9c-142a-4b42-ad2c-f0421857aaf5
  [2]: https://www.amazon.in/xcluma-1-Channel-Module-Optocoupler-Trigger/dp/B072THSX9Q/ref=sr_1_1?keywords=5v 30a&qid=1564212590&s=industrial&sr=1-1

title: Connect 5v 30a relay with Arduino Uno

Answers: 1

body:
From the Amazon page you linked to:

> 1 dc+ : Dc power supply positive pole
> 2 dc- :Dc power supply negative pole (i.e. ground)

Arduino:
VCC: positive DC power supply
GND: ground

[technically][1], VCC = the voltage at the collector of a transistor, these days it's used as shorthand for the positive output pin of an IC.

  [1]: https://en.wikipedia.org/wiki/IC_power-supply_pin


body:
 For an application I use Arduino DUE and VNH2SP30 as the motor driver.I think this motor drive is only compatible with 5V logic but DUE provide 3.3V logic.Will my problem be solved if I use logic level shifter to convert 3.3V logic level to 5V?In the meantime, I control the speed and direction of the motor with the following code:

    analogWrite(PWM_kare,head_analog);
    digitalWrite(INB_kare, HIGH);
    digitalWrite(INA_kare, LOW);

title: Arduino DUE and 5V logic sensor?

Answers: 1

body:
According to [the datasheet](https://www.elecrow.com/download/VNH2SP30 Datasheet.pdf) (page 5) the "Input High Level Voltage" is 3.25V.  That means that any voltage over 3.25V will count as a HIGH.

That is kind of borderline for 3.3V logic which can drop below 3.3V for a HIGH depending on load and other circumstances.

So while it *might* work off 3.3V I would say for reliable operation you should use some form of level shifting in your circuit, yes.

A simple, cheap, MOSFET-based logic level shifter will do the job - there is no need for anything fancy.


body:
I just bought a Ethernet Shield for my Arduino UNO. I connected it to my arduino and flashed the Example code for Ethernet Shield, but the code didn't work. The COLL LED on ethernet shield is glowing and I checked with my router, it has not assigned any IP to my ethernet shield. I tried all of the examples given, but none of them worked. Help me in understanding wrong I am doing here?

Ethernet Shield(W5100) Link: https://www.banggood.in/Ethernet-Shield-Module-W5100-Micro-SD-Card-Slot-For-Arduino-UNO-MEGA-p-908461.html?rmmds=search&cur_warehouse=CN

Exampled code given in Arduino (DhcpAddressPrinter):
```
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // start the Ethernet connection:
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    } else if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    // no point in carrying on, so do nothing forevermore:
    while (true) {
      delay(1);
    }
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  switch (Ethernet.maintain()) {
    case 1:
      //renewed fail
      Serial.println("Error: renewed fail");
      break;

    case 2:
      //renewed success
      Serial.println("Renewed success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;

    case 3:
      //rebind fail
      Serial.println("Error: rebind fail");
      break;

    case 4:
      //rebind success
      Serial.println("Rebind success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;

    default:
      //nothing happened
      break;
  }
}
```

Output
```
Initialize Ethernet with DHCP:

```

Code I wrote for Webserver:
```
#include<SPI.h>
#include<Ethernet.h>

int led = 8;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xEF, 0xED};
EthernetServer server(80);
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  Ethernet.begin(mac);
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  EthernetClient client = server.available();

  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);

        if (readString.length() < 100) {
          readString += c;
        }

        if (c = '\n') {
          Serial.print(readString);
          client.println("<HTTP/1.1 200 0K>");
          client.print("<Connection-Type: text/html>");
          client.println("<Connection: close>");
          client.println("");

          client.println("<!DOCTYPE html>");
          client.println("<html>");
          client.println("<head>");
          client.println("<title>Webserver</title>");
          client.println("</head>");
          client.println("<body>");
          client.println("<a href=\"/?button1on\"\"><button>LED ON</button></a>");
          client.println("<a href=\"/?button2off\"\"><button>LED OFF</button></a>");
          client.println("<body style=background-color:powderblue>");

          delay(1);
          client.stop();

          if (readString.indexOf("?button1on") > 0) {
            digitalWrite(led, HIGH);
          }

          if (readString.indexOf("?button2off") > 0) {
            digitalWrite(led, LOW);
          }
          readString = "";
        }
      }
    }
  }
}
```

Output
```
Server is at 0.0.0.0

```
Thank You

title: Ethernet Shield Issue

Answers: 0


body:
I am trying to give power to my Arduino Board using a 12V 7.3 Ah Lead-Acid Battery but I am unable to do it.

I connected the battery to Arduino Uno (via DC Pin) and it worked for a couple of minutes but then, it automatically stopped working. I checked the voltage of the battery using a Multimeter from the same DC Pin which was connected with battery and board. The voltage was 12.62 volts.
Then I thought my board might have been fried. So, I checked the board by connecting it with a 12V 2 Amp DC adapter and I found that my board was not fried and it was working fine with the Adaptor. The Adaptor was giving 12.48 volts voltage. Then, I again checked the board using battery but still it didn't work. I tried charging the battery via a charger but it still didn't work. I tried these steps multiple times but the results were always same.

I checked with my 12V DC Fan & some other devices also and it works perfectly, but it doesn't work with my Arduino Board.
This indicates that my battery is in a good condition but not working with Arduino Board only. While Arduino is also in a good condition, working with 12V DC Adaptors but not with the Battery.

Please Help!

title: How can I give power to Arduino Uno using a 12V 7.5 Ah Lead-Acid battery?

Answers: 1

body:
The input voltage on the DC pin [is specified as](https://store.arduino.cc/usa/arduino-uno-rev3) 7 to 12V. Your battery may well be supplying more than that, causing the voltage regulator to overheat and shut down.

> The voltage was 12.62 volts.

That is out of spec for the Arduino Uno. When you operate out of specified voltages anything can happen, and that anything may not be very good.

You could get a [buck converter](https://en.wikipedia.org/wiki/Buck_converter) to lower the voltage.

Certainly a Uno should be able to run for a long time on a 7 Ah battery (provided you are supplying voltages in range for it, preferably using a buck converter or similar to make sure that a fully-charged battery does not supply too high a voltage).


body:
I have a sound sensor that was working perfectly fine as I was using it as a clap sensor to turn lights on and off. However, I tried to change the code to make it work a little smoother and for whatever reason it stopped working. I then tried to write a very simple script to allow it to turn on and off using just one clap but now it treats the sound sensor as if it's always inputting HIGH. Any ideas why this might be happening?

note: I've turned up the sensitivity and can see that the sound sensor isn't always HIGH. Even when it's too high to hear me clap it still turns the LED on and off as if the if statement below was always true.

    int SENSOR = 2;
    int LED = 13;

    void setup() {
      // put your setup code here, to run once:
      pinMode(LED, OUTPUT);
      pinMode(SENSOR, INPUT);
    }

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

      if(digitalRead(SENSOR) == HIGH){
        digitalWrite(LED, (digitalRead(LED) == HIGH ? LOW : HIGH));
        delay(100);
      }
    }

This is the sound sensor module I am using: [Robojax Sound Detection Microphone Module][1]

  [1]: https://www.amazon.ca/Robojax-Detection-Microphone-Module-Arduino/dp/B07PPYK3ND/

title: Why does my code treat my sound sensor as if it's always HIGH

Answers: 1

body:
The robojax microphone switch I was using outputs LOW when it senses a sound rather than outputting HIGH as I assumed. The solution was just to replace all the if statements testing for a HIGH input with LOW.

note: sorry about not looking into the microphone earlier.


body:
I'm working on a home automation project using NodeMCU ESP8266. Most of the example projects I see online provide their WiFi SSID and password in plain text at the beginning of the code by storing them into some variable

Is there a secure way of doing that? I'm worried if my ESP8266 gets hacked by someone online, they'll now have my WiFi SSID and the password. Is there a way of encrypting this information before passing it to ESP8266. Or is there a way of creating a separate WiFi password which will only be used by the ESP8266?

title: How to connect ESP8266 to my home WiFi securely

Answers: 0


body:
I need a simple code to turn on 12 outputs one after another 2 seconds apart. A pushbutton will initiate this and the outputs will stay on for 3 minutes at which time all outputs will turn off awaiting the pushbutton input

So far:

    Void setup
    pinMode (10,output);
    PinMode (11,output);
    PinMode (12,output);

    Void loop
    delay(100);
    digitalWrite (10,HIGH);
    delay (2000);
    digitalWrite(11,HIGH);
    delay(2000)
    digitalWrite(12,HIGH);

    delay(180000);
    digitalWrite (11,LOW);
    digitalWrite (12,LOW);
    digitalWrite (10,LOW);
    exit(0);

Push remote reset button to restart.

Only tried 3 outputs for now and haven’t tried “Crossroads” code yet but I will.

title: Timing 12 relays

Answers: 2

body:
Simple code:

<!-- language: lang-c++ -->

    byte buttonPin = 2;
    byte relayPins [] = {3,4,5,6,7,8,9,10,11,12,13,14,};
    byte x;

    void setup() {
      pinMode(buttonPin, INPUT_PULLUP);
      for (x=0; x<12; x=x+1) {
        pinMode(relayPins[x], OUTPUT);
      }
    }

    void loop() {
      if (digitalRead(buttonPin) == LOW) {
        for (x=0; x<12; x=x+1) {
          digitalWrite(relayPins[x], HIGH); // drive base of NPN or N-MOSFET to sink current
          delay(2000);
        }
        delay(180000); // dumb 3 minute delay
        for (x=0; x<12; x=x+1) {
          digitalWrite(relayPins[x], LOW);
        }
      }
    }

And of course, supporting hardware to drive relay coils.

body:
Don't use Delay. CrossRoads provided a decent starting point for your code, but his code is based on `delay()`, which is a dead end.

Instead of delay, use a bool `running` to track whether you're relay sequence is running or not. Also have an `unsigned long` `startTime`, and an array of bools to track if each relay is on or off.

If !running, check the button. If the button is pressed, set running to true, and set startTime to `millis()`.

Then, use millis() to figure out where you are in the sequence. Calculate `(millis()-startTime)/1000/num_relays`. Let's call it `relayIndex`.

When `relayIndex` is less than `num_relays - 1`, check the bool for that relay, and if it's off, set it on and turn on that relay. When `relayIndex` reaches `num_relays-1`, you're done turning on relays. Now it's time to wait for 3 minutes to go by. After 3 minutes, turn off all the relays and relay bools, and set `running=false`. Have the reset button do the same thing.

## EDIT ##

Also note that controlling relays from an Arduino (or from other solid state devices for that matter) requires special hardware and precautions. You should probably use a "digital" relay (something like [this][1], or better yet [**this**][2] 6 channel relay) that isolates the Arduino control line from the high current needed to drive the relay.

Failing that, you should build a control circuit from a MOSFET transistor and a "flyback diode". Without flyback diodes, the inductive coils on your relays emit "[**back EMF**][3]" which will likely fry your transistors (and possibly the Arduino)

  [1]: https://www.amazon.com/Tolako-Arduino-Indicator-Channel-Official/dp/B00VRUAHLE/ref=asc_df_B00VRUAHLE/?tag=hyprod-20&linkCode=df0&hvadid=309803885710&hvpos=1o2&hvnetw=g&hvrand=11611615258717876708&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9008140&hvtargid=pla-568715033020&psc=1
  [2]: https://www.amazon.com/NOYITO-6-Channel-Trigger-Optocoupler-Isolation/dp/B07HWHJTBC/ref=asc_df_B07HWHJTBC/?tag=hyprod-20&linkCode=df0&hvadid=242027088707&hvpos=1o2&hvnetw=g&hvrand=6696300912666984277&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9008140&hvtargid=pla-583600390012&psc=1
  [3]: https://en.wikipedia.org/wiki/Counter-electromotive_force


body:
1. I have connected `pin 3` to a DC motor and using `analogWrite` and `DigitalWrite` to try making it start. However, nothing happens.

2. If I try to move the pin from `pin 3` to `5V` or `3.3V` the motor starts.

**Q:** What could be the problem since it does not start using pin 3 (or others). I am using `HIGH` on `digitalWrite` and `255` on `analogWrite`.

* I just bought a starter kit. [It has FREENOVE written on it][1].

* Here is a link to the [tutorial and software][2].

Thanks for any help!

  [1]: https://www.ebay.com/itm/Freenove-Ultimate-Starter-Kit-with-UNO-R3-Arduino-Compatible-Breadboard/302057861688?hash=item46540d3238
  [2]: https://git.io/fj8Jq

title: DC motor does not work using PWN or Digital pins

Answers: 3

body:
The Tutorial.pdf document that describes the components in the kit does not tell you what the current draw of the motor is. Chapter 10 has 2 tutorials on how to use the motor with a relay or L293D IC. This suggests to me that the motor draws a lot more current than a digital output can provide.

The tutorial using the L293D gives you the ability to vary the speed of the motor using PWM, so it would be a good place to start.

Hopefully pin 3 was not damaged by the excess current flow when the motor was attempted to be powered from it.

body: The digital/analog pins cannot directly source enough current to run a motor. Use the pin to control a switching device like a mosfet which then controls current flow to the motor.

body:
You should read up on controlling motors from digital circuits and follow a tutorial until you understand the "gotchas".

You have to be careful with the pins on an Arduino and not trying to draw too much current from them. A motor very likely needs several times more current than an Arduino digital pin can provide (you should keep the current draw on an Arduino pin ≤20 mA. Your motor might well draw 10 times that much. You might have damaged or destroyed the pin you used.

Secondly, motors use inductive coils (electromagnets). Inductors have an effect called "back EMF" that causes a reverse surge of current when you remove power from them. That will also fry whatever solid state component is driving the inductor. (The Arduino pin if you're trying to drive the inductor directly, or a transistor if you're switching the current to the inductor using a transistor.) You need a "flyback diode" on the inductor to protect the circuit that drives it.


body:
In the following code :-
The aim of code is " when push button is pressed , led is on and when push button is is pressed again led is of"

    #define led 12
    #define button 7
    boolean trigger = false;
    boolean previous = false;
    void setup()
    {
      pinMode(led , OUTPUT);
      pinMode(button , INPUT);
    }
    void loop()
    {
      int current = digitalRead(button) ;
      if (current && !previous)
      {
        trigger = !trigger;
      }
      previous = current;
      digitalWrite(led , trigger);
    }

My Questions are as follows:-

 1. When i used digitalread(button) instead of introducing variable i.e
    current. LED shows abnormal behavior. Why ?
 2. What is the purpose of current = previous expression. Whats its
    significance?
 3. Also please explain the working of a code in a brief manner in a
    loop.
 4. Why I should use Boolean instead of int?

title: arduino boolean function

Answers: 1

body:
> When i used digitalread(button) instead of introducing variable i.e
> current. LED shows abnormal behavior. Why ?

Likely this is because of [switch bounce][1].  The processor is very fast compared to the bounces a mechanical switch makes when operated.  So the results can be unexpected.  You can get around this problem in [software by using a state machine][2].  Or in [hardware by using capacitors to filter out bouncing.][3]

> What is the purpose of current = previous expression. Whats its
> significance?

The program is tracking the state of the switch.  So you need to know the previous state of the switch to know if the state of the switch has changed.

> Also please explain the working of a code in a brief manner in a loop.

The two fixed or reserved function names in an Arduino sketch are "setup" and "loop".  "setup" is called only once on boot up.  And "loop" is called over and over again after "setup"is called.  In "loop" the code reads that state of the button, then tests to see if the state of the button is true and the previous state is false.  If it is, then toggle the variable which tracks the state of the LED.  Then the code will always save the current state as the past state and turns on / off the LED according to the value tracking the state of the LED.

Now comes the tricky part.  Assume the switch is perfect and does not bounce.  The toggling only occurs when the switch is 1st pressed.  That is because the next time through "loop" both trigger & previous are true and the test will then be false and the LED will not be toggled.  Not until after the switch is released does the code reset previous to false.  Now if the switch is pressed again, for only 1 iteration through "loop", the test will be true and the LED will be toggled.

This approach depends on the switch not to bounce.  And is difficult to understand.  Consider using a 4 state machine (button up / LED off, button down / LED on, button up / LED on, button down/ LED off) rather than this 2 state machine (button down / LED toggle, button up / LED steady).

> Why I should use Boolean instead of int?

Bools only have two states.  Integers can have many states.  It is less confusing and less error prone to use a variable that only has two states if that is the intent of the program.

  [1]: https://en.wikipedia.org/wiki/Switch#Contact_bounce
  [2]: https://www.arduino.cc/en/tutorial/debounce
  [3]: https://hackaday.com/2015/12/09/embed-with-elliot-debounce-your-noisy-buttons-part-i/


body:
I am working on a project to make a speaker with reactive lighting. I need to be able to sample stereo audio at a decent rate for songs. The `audioRead ()` function can do about `8 kHz` and I have heard you can push it up till `35 kHz` but than you can only use it for mono and you cannot use the arduino for anything else.

* Someone recommended that I use an ADC. What can it do for me?

* Is the arduino's operating speed a limitation?

* If not the arduino which other micro-controller is suitable for this purpose.

title: Sampling stereo audio at greater than 40 Hertz using arduino

Answers: 2

body: The first part of the speed limitation on the Arduino is that the ADC is painfully slow.  If you had a faster ADC chip then you could take analog readings faster so you can take more per second.  Once you're over that threshold then the next limitation you run into is the speed with which Arduino can communicate with that ADC.  So make sure you get something fast (like SPI).

body:
If you are only interested in getting a reading of the sound intensity,
then 8 kHz may be enough. You can also convert the signal to mono
using a pair of resistors. If you want the Arduino to do other stuff
while taking the analog readings, then you should forego `analogRead()`
and access the ADC directly. This is more involved that typical Arduino
programming, as it involves configuring the ADC at low-level, in “free
running mode”. In this mode the ADC operates in an autonomous way, and
send you an interrupt every time a sample is ready.

I have written a program that does something similar: it samples an
analog input at 9.6 kHz (104 µs per sample) an periodically
sends the reading through the serial port: [sound-meter.ino][]. You can
probably adapt it for driving LEDs instead of the serial port.

[sound-meter.ino]: https://gist.github.com/edgar-bonet/e693799f58a545ca89a2


body:
Alright so I've been trying to update/change the number on the display during a loop, but nothing really happens. It doesnt change/update, the value is always exactly same.

    #include <TM1637Display.h>

    #define led_display 1
    #define led_display_scnd 3

    int analogPin = A0;
    int moisture;
    int percentage;

    int map_low = 686;
    int map_high = 350;

    TM1637Display display(led_display_scnd, led_display);

    void setup() {
      pinMode (led_display, OUTPUT);
      display.setBrightness(1);

      display.showNumberDec(1);
      digitalWrite(led_display, HIGH);
      Serial.begin(9600);

    }

    void loop() {
      display.showNumberDec(5);
      moisture = analogRead(analogPin);
      Serial.print("Raw: ");
      Serial.print(moisture);

      int sensorValue = analogRead(A0);
      percentage = 100-((sensorValue-110)*100L/(1023-110));

      Serial.print(" | Percentage: ");
      Serial.print(percentage);
      Serial.println("%");

      display.showNumberDec(moisture); // updating the value

      delay(2000);
    }

title: TM1637Display is not updating on loop

Answers: 0


body:
1. I created a simple circuit with an `UNO`, `L298N` and `a single motor`.

2. Wrote the following code to test controlling the speed of the motor.

3. Tested motor with `digitalWrite()` function and it works fine.

4. Tested motor with `analogWrite()` function and from `255` down to around `70` motor works at various speeds.

**Q:** But from around 70 and below, the L298N starts to beep and the motor stop spinning. Any thoughts?

    int enr = 9;
    int inr1 = 8;
    int inr2 = 7;

    void setup() {
     pinMode(enr, OUTPUT);
     pinMode(inr1, OUTPUT);
     pinMode(inr2, OUTPUT);
    }

    void loop() {
      analogWrite(enr, 71);
      digitalWrite(inr1, HIGH);
      digitalWrite(inr2, LOW);
    }

title: L298N beeps and malfunctions when receiving certain analogWrite values

Answers: 1

body:
Ok, here is my theory what's happening:

Every motor has an amount of friction at his rotor. You need to pass enough energy to overcome this friction, or the motor will not move. When you use `analogWrite(enr, 71)` or lower, you pass only a small amount of energy to the motor, so that it cannot overcome the friction.

Now you have to understand, what `analogWrite()` really does. It does **not** output an analog voltage. Instead it generates a PWM signal. The voltage changes between HIGH and LOW level (5V and 0V in case of the Uno) at a specific frequency. The relation between HIGH time and LOW time is called duty cycle. That is, what's controlling the motor speed. So instead of supplying different voltages, we turn the motor on and off very fast. Since the rotor has a relatively big inertia (because of it's mass), it cannot react fast enough to follow these pulses. We only give it small pushes very fast. Instead it integrates over all the pulses. If the duty cycle is low (more LOW than HIGH time) only a small amount of energy is passed to the motor.

So, what is the motor doing, when it's got not enough energy to overcome the friction? It will still get little pushes very fast, but cannot actually spin. Instead the passed energy will induce vibrations in the motor, which have the frequency of the PWM signal. These vibrations can then be heard as a continuous beep.

If enough energy is passed to overcome the friction, the rotor spins correctly and does not vibrate, thus you cannot hear a beep.

**What to do now:**

The described principle applies to every motor, so cannot do much about that. You can simply go the easy way and not drive the motor with such low duty cycles. Another cause might be, that your motor likes to get a higher current to give it's full power. The L298N is quite inefficient, so you could change that to a H-bridge driver, that uses MOSFETs instead of bipolar transistors. Also maybe you can increase the voltage, that you use to drive the motor (depending on the not specified motor).

You didn't describe, how you have connected everything, so 2 other points: You cannot drive a motor from a digital pins power (since a digital output pin can only provide 40mA at max, 20mA recommended) and you should also not power a motor through the Arduino, since you might fry the voltage regulator or the protection diode. You can get away with that, when using small motors without any load, but that doesn't scale well. You should always connect the motor circuit directly with the power supply, so that the motors current does not have to flow through the Arduino.


body:
I have been working with my **Arduino UNO** for 2-3 hours and after that it was not possible to load sketchs into the board since it returns a

> "avrdude: stk500_recv(): programmer is not responding" error.

* The internal led "L" of the board is permanently on.

After a little research I guess that the bootloader was corrupted at some point (I still don't understand when and how).

**Q:** Apart from this board I have an **Arduino Duemilanove** board and I would like to know if it is possible to use this Duemilanove board to burn the bootloader in the broken board, is this possible? in afirmative case, how?

Since all the examples over there shows how to do it with the same board and not with a different one.

title: Burn bootloader into Arduino UNO from Arduino Duemilanove

Answers: 1

body: Yes, Nick Gammon has a page on doing that here  https://www.gammon.com.au/bootloader


body:
Last days I have been investigatin schematics of arduino due board. The purpose of proper understanding of schematics in crucial for me, beacuse I indend to build myself my own board with some minor modifications.

I would really want to learn something from it and not just blindly copy stuff that are already done. In schematics there are two things that I do not understand. First is the working principle of erase button (see: erase button). I have my own idea how does it work, but would like to clarify the working principle from someone that know exactly what is the purpose of all the elements that are connected to erase button. Also, why is ERASE_CMD  line connected to Atmega processor?
 Second thing is switching of power supply between external power and both usbs (see: usb switch). Again, would someone please just brifly describe working principle? Here I really do not undertand why is there op amp added?

Thank you in advance.

Erase button:

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

USB switch:
[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/1Wjnx.png
  [2]: https://i.stack.imgur.com/qhzuA.png

PLEASE NOTE: Both pictures are taken from original arduino webpage: https://store.arduino.cc/due  (see: documentation -> schematics)

title: Arduino due erase button and power switching

Answers: 1

body:
The asker posted the same question and received an answer [here][1]
There is discussion regarding the purpose of the Erase switch [here][2]

  [1]: https://forum.arduino.cc/index.php?topic=628347.0
  [2]: https://forum.arduino.cc/index.php?topic=502139.0


body:
So I am trying to work on a mini battle bot project. However, it has been a while since I have worked with my Arduino electronics. So I am going through and learning how to do each thing before putting it all together. So far I have learned how to use the IR remote and got that working. I got my brushless motor with esc working with the Arduino. Now I am trying to get my dc motors working for the wheel component. I am just trying to get one motor running from the motor shield as proof of concept essentially. So here is the run down.

I have 8xAA batteries in  series with each AA running at 1.5 volts for a total of 12 volts. I have verified this with my multimeter. The dc motors need 9-18 volts to run, so 12 should have it running. However, I will probably step that up to 18 volts for maximum power and run 4 dc motors since I am guessing my project will be a little heavy, so I need as much power as possible. I have the 8xAA batteries connected correctly with positive to the positive and negative to negative on the motor shield. I have checked my soldering connection and the pins are not bent and it looks straight and good. I made sure I firmly pressed down to get it onto the Arduino. Motor is connected to m2 as per the code. I don't understand why this isn't working as it should work. I have tried using this form: https://arduino.stackexchange.com/questions/20000/why-is-my-adafruit-motor-shield-not-spinning-my-motors

And that did not solve it. I originally was using a 9 volt battery but that form told me to use more than 9 volts and to use AA batteries, so I did that. I also checked my connections and made sure soldering is good. Here is my code:

    #include <AFMotor.h>

    // DC motor on M2
    AF_DCMotor motor(2);

    void setup() {
      Serial.begin(9600);           // set up Serial library at 9600 bps
      Serial.println("Motor party!");

      // turn on motor #2
      motor.setSpeed(200);
      motor.run(RELEASE);
    }

    int i;

    // Test the DC motor
    void loop() {
      motor.run(FORWARD);
    }

I have connected my motor to the battery directly and motor runs just fine. I have checked the voltage of my battery and it is great, not below the 12 volts and not above 13 volts. I have opened up serial monitor and I do see 'motor party' so I know the code is running. I looked for errors down below and saw none. The port I have checked and it is correct. Motor shield is made by Adafruit. I do have the correct library installed, in fact I just installed it today so I have up to date library. The lights on the Arduino light up and the light indicating power on the motor shield also light up when my AA batteries are plugged in. When I plug it in, lights light up but motor doesn't run. Here are a few pictures.

https://i.stack.imgur.com/cSo3x.jpg

I am have a hard time figuring this out, so if anyone can help me, thanks in advance.

title: Is My Motor Shield Broken?

Answers: 2

body: As noted by markshancock, you are using an older version of the Adrafruit Motor Shield library meant for the version 1 of the board (you have the version 2.3), and according to their forum they are not compatible (they use different communication protocols) use the newer version of the library https://forums.adafruit.com/viewtopic.php?f=31&p=276888

body:
The commands you are using don't match the ones listed for this board.  Here is the [AF Documentation][1] for the Motor Shield Board V2.

Try

    #include <Wire.h>
    #include <Adafruit_MotorShield.h>
    #include "utility/Adafruit_MS_PWMServoDriver.h"

    Adafruit_MotorShield AFMS = Adafruit_MotorShield();
    Adafruit_DCMotor *motor = AFMS.getMotor(2);

    void setup() {
      Serial.begin(9600);           // set up Serial library at 9600 bps
      Serial.println("Motor party!");

      // turn on motor #2
      AFMS.begin();
    }

    int i;

    // Test the DC motor
    void loop() {
      motor->run(FORWARD);
    }

Note: In this library, getMotor() returns creates a pointer; so, you have to use "->" rather and "." to access the motor run() method.

  [1]: https://learn.adafruit.com/adafruit-motor-shield-v2-for-arduino/using-dc-motors


body:
Running on atmega168p, I've got an interesting behavior I can't explain. A global volatile var that's called `pos` over here is not updated as it should. Once I add some code below the assignment, it starts working.

```c
#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>

Encoder myEnc(A2, A3);

void setup() {
  Serial.begin(115200);
  while (!Serial); Serial.println("Started.");
  PCMSK1 |= bit(PCINT10) | bit(PCINT11) | bit(PCINT12);
  PCIFR  |= bit (PCIF1);   // clear any outstanding interrupts
  PCICR |= bit(PCIE1);
}

volatile int pos  = 0;
int oldpos = 0;

void loop() {
  if (oldpos != pos) {
    oldpos = pos;
    Serial.println(pos);
  }
  delay(100);
}

// PCINT10, PCINT11
ISR(PCINT1_vect) {
  pos = myEnc.read();
  //  adding digitalRead(A0)
  // or even Serial.println(pos) updates the var correctly
}
```

Switching from `int` to `byte` doesn't change anything. Encoder library is https://github.com/PaulStoffregen/Encoder. Any clues?

title: global volatile variable not being updated in ISR

Answers: 3

body:
You are using pos outside of the interrupt without turning the interrupt off.  pos is two bytes, so it takes the Arduino more than one cycle to read in that variable no matter how it is handled.  If an interrupt occurs during that time, you get a corrupted value.

You need to have a cli() and then make a copy of pos to another variable and then a sei() and then use that copy in your calculations in loop.

body:
Well, the long awaited answer to this question is simple - the library that I've tried to use in my code was over-optimizing things by going full ASM and interfering with my stuff. Using C version straightened things up.

For anyone getting strange behaviour I recommend taking a quick glance at the lib's code you're using, maybe it's not your fault after all.

body:
<!-- language-all: lang-arduino -->

# How to recognize and fix race conditions in Arduino by using atomic access guards:

> Switching from int to byte doesn't change anything. Encoder library is https://github.com/PaulStoffregen/Encoder. Any clues?

Your code here:

    void loop() {
      if (oldpos != pos) {
        oldpos = pos;
        Serial.println(pos);
      }
      delay(100);
    }

has an unaddressed race condition, which leads to undefined behavior and data corruption. Making `oldpos` into a `uint8_t` or `int8_t`, each of which is 1 byte, instead of `int`, which is 2 bytes, won't fix it, because you need the whole section from `if (oldpos != pos) {` through `Serial.println(pos);` to be atomic so that the value of `pos` you use to enter the `if` block does not get changed by the interrupt while you are in the `if` block. I'll explain more later. This is reminds me of a problem I had a few years back, here: [C++ decrementing an element of a single-byte (volatile) array is not atomic! WHY? (Also: how do I force atomicity in Atmel AVR mcus/Arduino)](https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why).

So, let's walk through a case where making a 2-byte variable into a 1-byte variable WILL solve the problem, first, to ensure we understand why one might think making it a 1-byte variable is the solution.

Let's look at this example. **It has a race condition and undefined behavior. Can you spot it?**

    volatile uint16_t isr_counter = 0;

    void setup()
    {
        // enable the ISR here
    }

    // Any ISR
    ISR()
    {
        my_var++;
    }

    void loop()
    {
        Serial.println(isr_counter); // <== race condition!
    }

The answer is that `isr_counter` is a 2-byte variable, and AVR microcontrollers have 8-bit (1-byte) CPUs, so, it is possible that as `isr_counter` is being read in `loop()` to be printed, 1 of the 2 bytes is read out correctly to be printed, then the ISR fires, changes the variable, and gives control back to the main loop. The 2nd byte, now not what it was supposed to be, is read out, leading to a corrupted variable! Ex: let's assume `isr_counter` was 0xFFFF, or 65535, at the moment it is supposed to be printed, and lets say the low byte is read out correctly as 0xFF, then the ISR fires, the variable is incremented to 0x0000 since it overflows, then the control goes back to the main loop, and the 2nd byte is read out, it is now corrupted. What will be printed would be the contents of the variable containing 0x00FF, or 255, when what *should* have been printed out was 65535, and the next value after that to be printed out would have been 0. And what if the high byte was read out correctly before the low byte? (I'm not sure which order AVR mcus read the bytes), then your corrupted value would be 0xFF00, or 65280, when what *should* have been printed out was 65535 (0xFFFF), and the next value after that to be printed out would have been 0 (0x0000).

So, simply making the variable a `uint8_t` magically solves this race condition **for this one particular case** because 8-bit variables on 8-bit CPUs are read or written atomically, which means "as an atomic, or whole, single, unit, not broken up or corrupted by interrupts or other threads". **All operations which take 1 single CPU instruction cycle are automatically atomic, because they cannot be interrupted.**  For any multi-instruction-cycle code block which we need to be atomic, we must **force it to be atomic by using what I call "atomic access guards".** Reading a 1-byte variable on an 8-bit CPU, or writing a 1-byte variable on an 8-bit CPU, is 1 instruction, so it is naturally atomic. Incrementing or decrementing a 1-byte variable, however, is NOT an atomic operation, since the variable must be read, modified, and written. Reading a 2-or-more-byte varible on an 8-bit CPU, or writing a 2-or-more-byte varible on an 8-bit CPU, is also NOT atomic, since it takes one instruction per byte. This means just reading a 2-byte variable or writing a 2-byte variable can be interrupted by an ISR in the middle of the operation, which leads to data corruption if you do not use atomic access guards!

Now, your case: would making `pos` into a 1-byte variable as `volatile int8_t pos = 0;` solve the race condition? No, not at all. Let's look at your code again, this time imagining that `pos` is an `int8_t` instead of an `int` (which is `int16_t` on AVR Arduino):

    void loop() {
      if (oldpos != pos) {
        oldpos = pos;
        Serial.println(pos);
      }
      delay(100);
    }

Let's walk through a potential scenario: `pos` is 7. `oldpos` is 6. So, `oldpos != pos` is true, and you enter the `if` statement. Now, right as you enter, the ISR fires, `pos` is changed by the ISR to 6 (or to any other number--it's still a race condition and undefined behavior), `oldpos` is now set to 6, which is what it already was, and you have data corruption because _it should have been set to 7!_ Note that when I say this is undefined behavior in this case, I simply mean we cannot predict what will happen. This is buggy code. Code should *always* be predictable. Undefined behavior is a bug! Note also that when talking about "undefined behavior" according to C or C++ standards, we mean "the standard doe not _define_ what will happen", which means your code may act one way on one architecture or with one compiler, and differently on another architecture or with a different compiler. This is not what I am talking about here. Here, when I say "undefined behavior" I don't mean "according to the C or C++ standard", I mean, "according to the rules of logic."

The solution to fix your race condition is to *enforce* atomic access using what I like to call **"atomic access guards"**. On multi-threaded systems, this means to use **locks, mutexes, and semaphores**. On single-threaded systems, such as this, it means to **disable any interrupt which could interfere and cause the race condition** (you can think about interrupts interacting with the main loop as a parallel to one thread interacting with another thread, so it is as though you had a multi-threaded system just by having a single-threaded system + interrupts). For AVR microcontrollers, disabling interrupts to act as atomic access guards is usually done by disabling global (or all) interrupts. BUT, disabling interrupts introduces jitter by delaying the processing of the ISR, so it should be done _for as short of a time period as possible!_ **That means you should just disable interrupts, make copies of volatile variables, and re-enable interrupts.** This is an important point though: sometimes, in the case of using a 1-byte volatile variable, using a *copy* of your variable, which can NOT be changed at any moment by an ISR, also, in and of itself, acts as a form of "atomic access guards" and solves the problem all by itself. I'll post an example of this below.

But: **DANGER DANGER!** It's a "best practice" to always back up the interrupt state, disable interrupts, then restore the interrupt state, rather than just turning interrupts off then back on all the time. Why? Because what if you write a function which sometimes gets called _from within an ISR itself?_ If you enable interrupts inside an ISR, you just enabled _nested interrupts_, which leads to _more race conditions._ If you know exactly what you are doing and you *want* nested interrupts, this is fine! But, chances are one is just making a mistake here and _accidentally_ enabling nested interrupts without even realizing it, leading to really-hard-to-track down data corruption due to nested interrupts. Safety-critical systems can crash and hurt people when this happens, so we can't ever allow unmanaged race conditions.

So, do it like this:

1. Force atomicity in `loop()` by backing up the interrupt state.
1. Make copies of the volatile variables.
1. Then restore the global interrupt state.
1. Use only the copy of the varible in the rest of your code. This (using the copy) is also a form of "atomic access guards" all by itself for later code blocks using the variable because using the copy instead of the volatile variable means that the variable can NOT be changed at any moment by an ISR. This enforces atomicity as well!

Making a copy of the volatile variable and nothing else, while interrupts are disabled, _minimizes time where interrupts are disabled_, making your code the best it can possibly be! It should now look like this:

**1 of 3: THE BEST WAY!:**

    volatile int pos  = 0; // assume this variable is still an `int`, which is 2-bytes

    void loop() {
        uint8_t SREG_bak = SREG; // back up the global interrupt state
        noInterrupts(); // disable interrupts
        // make copies of your volatile variables here
        int pos_copy = pos;
        // restore interrupt state, turning them back ON if they were ON before,
        // or leaving them OFF if they were OFF before.
        SREG = SREG_bak;

        // Now do what you want with the copy, using pos_copy ONLY,
        // to avoid race conditions! (ie: using this copy here enforces
        // this entire block to be naturally atomic now, and by itself
        // is a form of "atomic access guards", as explained above.)
        if (oldpos != pos_copy) {
            oldpos = pos_copy;
            Serial.println(pos_copy);
        }
        delay(100);
    }

Solved!

Let's look at 2 other examples, however, for completeness.

Here, we force the whole `if` statement block to be atomic. This looks correct at first, but has two problems: 1) [a true bug] `Serial.println` will block forever if the outgoing serial buffer is full, as it relies on interrupts to empty it, and if interrupts are off, that will ever happen, and 2) [an undesirable effect leading to performance issues, but *not* a bug] it keeps interrupts off for a longer time period than is necessary. The code above was best: it kept interrupts off the absolute minimum time possible by just making copies of the volatile variables, and it ensured this whole `if` statement block was atomic by simply using the copy there, which automatically acts as an "atomic access guard" by itself and enforces atomicity in the `if` statement block.

**2 of 3: this still has 2 problems: one is a bug, and one is a performance issue but not a bug:**

    volatile int pos  = 0; // assume this variable is still an `int`, which is 2-bytes

    void loop() {
        uint8_t SREG_bak = SREG; // back up the global interrupt state
        noInterrupts(); // disable interrupts

        if (oldpos != pos) {
            oldpos = pos;
            Serial.println(pos);
        }

        // restore interrupt state, turning them back ON if they were ON before,
        // or leaving them OFF if they were OFF before.
        SREG = SREG_bak;

        delay(100);
    }

And lastly, what if the volatile variable was a 1-byte variable? Well, then you could simplify to this, since reading a 1-byte variable is naturally an atomic operation!

**3 of 3: this works too (without bugs and without performance issues), but ONLY if your volatile variable here is 1-byte!:**

    // this variable is now a 1-byte variable, which has naturally atomic read and
    // write operations! (but not increment or decrement)
    volatile int8_t pos  = 0;

    void loop() {
        // Make copies of your volatile variables here.
        // Being a 1-byte variable on an 8-bit (1-byte) CPU architecture, this operation
        // is already naturally atomic, so no need for "atomic access interrupt guards".
        int8_t pos_copy = pos;

        // Now do what you want with the copy, using pos_copy ONLY,
        // to avoid race conditions! (ie: using this copy here enforces
        // this entire block to be naturally atomic now, and by itself
        // is a form of "atomic access guards", as explained above.)
        if (oldpos != pos_copy) {
            oldpos = pos_copy;
            Serial.println(pos_copy);
        }
        delay(100);
    }

For _3 other ways to create atomic access guards in 8-bit AVR-based Arduinos_, see my answer from 2016 here: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why/39693278#39693278.

_Last comment:_ Paul Stoffregen is one of the most-expert in Arduino in our day. I'm sure he makes mistakes, but my default is to trust anything he's written. He's a most-excellent software developer and engineer: one of the absolute best in the entire world. Look for bugs in what he writes, and let him know if you found any, but you have unaddressed race conditions here, so that's what I'd look at first.

# References:
1. My own race condition problem: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why
1. My own race condition solution, demonstrating 3 (or 4, depending on how you look at it) ways to enforce **"atomic access guards"** on AVR-based 8-bit Arduinos: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why/39693278#39693278


body:
I have an arduino uno which turns on a water pump (12V, 3.6W) once every 10 hours for a few minutes (I've followed [this](https://www.instructables.com/id/Automatically-water-your-small-indoor-plant-using-/) tutorial on how to connect the water pump). To turn on the water pump I used a **PN2222A transistor**, and connected the **base** in serial with a **220 ohm** resistor to the **digital pin 9**.
A few minutes after turning on the power on my Arduino UNO the **PN2222A** transistor burned out (lots of smoke coming out of it).

I also used a **1N4007** diode, cathode connected to the positive pin, and anode to the negative pin of the water pump.

The power supply outputs around 12.6V

Maybe the resistor is too low/weak?

I've created a schematic [here](https://www.tinkercad.com/things/93WNCASSUjE), attached it's a snapshot of it.

[![tinkercad schematic][1]][1]

**EDIT1:**
Here is a picture on how I connected my transistor. I've removed from the photo:

 - the input wires (should be top-right of breadboard)
 - wire to arduino digital pin (should be on h-19 on the breadboard)
 - water pump from the breadboard (positive pin: c-2, negative pin: h-2)

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

**EDIT2 (a solution that worked for me):**

It looks like the input to the arduino (arduino and the pump share the same 12V input, but the arduino's goes through a step down converter to 10V) was a bit loose (to be more specific, the negative pin was loose) and randomly, the arduino would shut down and then the pump would start (maybe because the digital pin becomes HIGH, dont know why though) all while the arduino is shut off. That's when the transistor (PN2222A) burned out. I switched to TIP120 with a 1k resistor as @Jot suggested and looks like when the same problem with the power happens, nothing is burning out :)

  [1]: https://i.stack.imgur.com/lzeB8.png
  [2]: https://i.stack.imgur.com/VSxU4.jpg

title: Why does the transistor burn out

Answers: 5

body:
Seems to be a simple pinout issue, I checked the PN2222A and its pins are in EBC order. You probabily reversed it and burned the transistor. Reverse the transistor and the problem will be solved.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/bEAQJ.png)

<!-- End schematic -->

body:
TinkerCAD may have mislead you on the pinout for the transistor

**TinkerCAD**

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

**PN2222A**

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

  [1]: https://i.stack.imgur.com/z6D3Z.jpg
  [2]: https://i.stack.imgur.com/y9RxJ.jpg

body:
Datasheet for the PN2222A indicates it is only good for 150mA Ic for a pulse test, pulse width <= 300 microseconds, 2% duty cycle.

Your water pump, 12V, 3.6W.  With P=IV, or P/V = I, then 3.6W/12V = 0.3A, indicates this transistor is not the correct choice for this application.

body:
By this, does it mean that you still have a problem turning the pump on? Because a PN2222A should handle up to 1A through its collector, as the datasheet states http://www.mouser.com/ds/2/149/PN2222A-371983.pdf
>  That's when the transistor (PN2222A) burned out. I switched to TIP120 with a 1k resistor as @Jot suggested and looks like when the same problem with the power happens, nothing is burning out :)

If you are still having problem turning the pump on, try turning it on manually by moving the jumper that is on the Arduino pin 9 to either GND or 5V, that should indicate if the problem lies on the Arduino pin (GPIO) or on the transistor.

It is also important to check the current needed by the pump, because the datasheet indicates that, to have a current IC = 350 mA -> IB = 35 mA which is close to the maximum of an Arduino pin (40 mA). If the Arduino pin cannot supply enough current to put the transistor in saturation mode, it will either kill the pin or put the transistor in its linear region, meaning it will dissipate a lot of power (Ic*Vce).
> Base-Emitter Saturation Voltage
>
> IC = 150 mA, IB = 15 mA
>
> IC = 500 mA, IB = 50 mA

body:
It looks like the input to the arduino (arduino and the pump share the same 12V input, but the arduino's goes through a step down converter to 10V) was a bit loose (to be more specific, the negative pin was loose) and randomly, the arduino would shut down and then the pump would start (maybe because the digital pin becomes HIGH, dont know why though) all while the arduino is shut off.

That's when the transistor (PN2222A) burned out. I switched to TIP120 with a 1k resistor as @Jot suggested in one of the comments and looks like everything is ifne now (even when the same problem/bug with the power randomly happens)


body:
I am using Arduino Mega 2560 for interfacing devices such as the [Maxim MAX22500E][1] and [TI ADS1241][2].

Now I am requiring more speed for hopefully the same coding, and I am thinking in the Arduino Due (84 MHz Clock) which is enough faster than the Arduino Mega (16MHz Clock) but imposes working with 3.3V, hence using some 3.3V 5V [level conversion][3] for every input and output.

If I want to keep the same "arduino" coding environment, is there another faster 5V processor? Or should I focus in the strategy of interfacing the 5V devices from a 3.3V processor?

  [1]: https://datasheets.maximintegrated.com/en/ds/MAX22500E-MAX22501E.pdf
  [2]: https://www.ti.com/lit/gpn/ADS1241
  [3]: https://next-hack.com/index.php/2017/09/15/how-to-interface-a-5v-output-to-a-3-3v-input/

title: Faster Arduino Mega

Answers: 1

body:
You should begin working with 3.3V. 5V is getting rarer and rarer as far as "real world" applications go.

Many devices that you have been using at 5V will also work at 3.3V (such as the MAX22500E). Running those at 3.3V will mean you don't need logic level translation.

Others, like the ADS1241, have "split power" where you can have different logic voltage (DVDD) and analog voltage (AVDD), so you just run the logic at 3.3V and the analog at 5V so you don't need a logic level translator.

For those few rare devices that have to run at 5V and don't have a 3.3V equivalent, yes you will need to use some logic level shifting.


body:
I am working with an Arduino Due and the [Analog ADXL345][1] through a [module][2] following [this tutorial][3], with the `wire.h` library at Fast Speed (400kHz), the Accelerometer Sampling at 800Hz (for the Maximum Reccomended Limit), and the Serial Monitor at 115200 bps.

The cable is 24AWG solid wire, 6in length, two pairs, for `3.3V`, `GND`, `SCL` and `SDA` pins.

When the accelerometer is starting up, it generates a high pitched noise is generated!. Possibly by the 5V-3.3V regulator or by the accelerometer itself.

Under 400kHz|800Hz, the readings are unstable: by simply touching some open terminals in the Due, the Accelerometers readings toggle between strong oscillations and the correct ones (Figure 1).

[![enter image description here][4]][4]
After some "taps", the oscillations stops and the proper measures can be captured at the expected sampling rate (Figure 2). Note the mean values are modified for plotting only.

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

What should I do to prevent such behavior?, and what is causing that, considering the device is indeed working at the expected speed?

  [1]: https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
  [2]: https://www.openimpulse.com/blog/products-page/product-category/adxl345-digital-3-axis-accelerometer-module/
  [3]: https://howtomechatronics.com/tutorials/arduino/how-to-track-orientation-with-arduino-and-adxl345-accelerometer/
  [4]: https://i.stack.imgur.com/3tOjH.png
  [5]: https://i.stack.imgur.com/yugqb.png

title: Arduino Due ADXL345 Interference

Answers: 0