# Question
Title: How can I use a LCD I2C and a RTC3231 on a Arduino Pro Mini?
On a small project, I have a DS3231 RTC module and a LCD I2C module that I'm trying to connect on a Arduino Pro Mini board. However, both the RTC and LCD require connecting the `SDA` and `SCL` to the pins `A4` and `A5` respectively.

The libraries do not seem to allow changing the connected pins. Why is that? I have other pins available, like `A6` and `A7`, can those be used?

# Answer
Welcome, I understand where you are coming from, without a background you do not know what to ask. Were were all where you are at one time. I hope this helps. You need to do some studying on the I2C bus, online tutorials will make it easy. You you will find you can connect over 100 devices to it at one time The SCL and SDA lines go from module to module. Note each module has its own address, sometimes they are selectable. Some modules have pull up resistors, others do not. To keep it interesting the pull up resistors are mostly 10K but that is not a constant.

There are loading rules etc to be careful of if you have long wires or maybe more than three units. You need to add pull ups to each of the two lines (example: 4.7K from SCL to +5) or use something in the 3K range for a 3V3 system. The reason is because the bus has both dominant and recessive states where the recessive is high which the resistor provides. The SCL and SDA output/input on the parts have open collector/open drain outputs so they cannot source anything.

Once you have it hooked up you need to run a program called I2C scan or something like that. If you have wired it correctly it will give you the address of the module, you will probably get two or three as there is the RTC, Memory device and possible a temperature sensor.

The #1 rule is the Arduino A Power Supply it is NOT! A small module or two connected to the 5V out is fine but never connect a motor directly to any arduino you will probably fry the Arduino.

I use Vin and supply it with about 8 volts by using either a Buck or Sepic converter from a 12V 2A or larger supply. I do it this way because I get a more stable voltage on the Arduino because of the extra filtering etc built into the analog regulator section. Real nice when using the A/D, keeps things stable. Were here to help, ask questions any time and do not worry is some over eager person decides to vote you down. Read the guidelines etc and you will do great.

You can search online for "Arduino RTC" and find a lot of programs with software.
> 0 votes

---
Tags: lcd, rtc, arduino-mini
---


title: How does erasing the EEPROM work?

text:
# Question
Title: How does erasing the EEPROM work?
The datasheet for the ATmega328P contains this table, which describes bits 4 and 5 of EECR:

| EEPM1 | EEPM0 | Programming Time | Operation |
| --- | --- | --- | --- |
| 0 | 0 | 3.4ms | Erase and write in one operation (atomic operation) |
| 0 | 1 | 1.8ms | Erase only |
| 1 | 0 | 1.8ms | Write only |

I'm currently working on some non-blocking EEPROM-handling code and I'm wondering when and how I should erase the EEPROM.

* What does erasing do? Does it set one byte to 0x0, or the entire EEPROM?
* Should I erase it first whenever I want to write a byte?
    + If not, why is there an option to erase and write separately?
* How do I initiate an erase?

Either the datasheet is rather lacking concerning the EEPROM, or I'm just not finding what I'm looking for. I tried using a search engine, but all results are either about the Arduino EEPROM library or \<avr/eeprom.h\>, both of which use polling instead of interrupts (and are therefore blocking).

# Answer
Your questions are answered in the AVR ATMega328 datasheet.

The procedure for erasing and writing the internal EEPROM is outlined in chapter 7.6 (Register Description).

* The Erase operation erases 1 byte (erasing an EEPROM cell sets it to all 1s, i.e. 0xff).
* The EEPROM address to be erased/programmed is pointed to by the EEARL and EEARH registers. The value to be programmed into that address is set by the EEDR. Reading a value from EEPROM returns the value in the same EEDR register.
* Before writing a new value to the EEPROM, the old value must first be erased. You can do that as two separate actions or one single action. You could also leave the cell deprogrammed (erased) by only erasing it and not programming it again.
* You initiate an erase of the EEPROM address pointed to by EEARH/EEARL, by setting EEPM1 to 1, EEPM0 to 0 and setting EEPE to 1 to start the erase operation. Setting EEPM1 and EEPM0 both to 0 will erase and program a new byte in a single operation.

As for making EEPROM writes non-blocking, you could set a (non-blocking) timer for the duration of the write, erase or erase/write operation. According to the datasheet these operations respectively take 1.8, 1.8 and 3.4 ms. Just make sure your code does not access the EEPROM while these operations are taking place.

You could also (non-blocking) periodically poll the EEPE bit until it is cleared, signalling the operation is finished.

The most elegant way, i.m.o. is to make use of the EERIE flag by setting it to 1, which will enable the ATmega to generate an interrupt when the EEPROM operation is finished.
> 3 votes

# Answer
I switched to FRAM, 32K x 8 can be gotten for just a few $$$, generally less the imported Arduinos. It is as fast as the Arduino can access it, both read and write. You can use I2C or SPI depending on which unit you buy. There are some very nice libraries for it making it easy to use. It is non volatile, ie does not lost information when power fails. It will support in the range of a trillion memory cycles with no delay when writing or reading it so no blocking. Just a few extra processor cycles because of the SPI or I2C overhead. If you have code already written for the External EEPROM it should work as is but it will have an unneeded delay in it.
> -1 votes

---
Tags: atmega328, avr, eeprom
---


# Question
Title: Will many nrf24L01 radio modules running at the same time cause interference?
I am working on a battle bot type of project where their will be 4 transmitters communicating with 4 receivers attached to the robots in the 4 foot x 4 foot playing field. Are their any complications that will arise when trying to run many radio modules at the same time? Like relating to interference or noise? If so, what solutions or work-arounds exist for this problem?

# Answer
> 2 votes
According to HowToMechatronics, the NRF24L01 module can use 125 different channels which gives a possibility to have a network of 125 independently working modems in one place. Each channel can have up to 6 addresses.

I believe that as long as you agree a channel allocation amongst competitors there shouldn’t be problems.

For more information on channel setting see NRF24l01 Channel switching

# Answer
> 0 votes
Welcome Rishikesh, there is a great possibility they will have problems. Because I do not know the environment or what the hardware is configured I cannot properly answer your question without a lot more information. I can suggest Look here for some information: https://forum.arduino.cc/t/nrf24l01-transmission-problem/526158/3 Here is another link that will help: https://devzone.nordicsemi.com/f/nordic-q-a/38005/nrf24l01-communication-is-interfered-by-wifi I hope this helps.

---
Tags: arduino-uno, arduino-nano, communication, nrf24l01+
---


# Question
Title: Where is the digitalPinToInterrupt macro defined
I am new to Arduino, and it's confusing to me how you can just write code in the IDE and use functions or macros such as `#define ISR()` in the avr-libc library without having to include the header file in the Arduino sketch.

I was trying to find where `digitalPinToInterrupt()` is defined, but had no luck. Any idea?

# Answer
Generally, if you want to find identifiers in your Arduino board support, you can run the ctags program on the libc and Arduino core files. ctags is used as part of the build process in its effort to generate C++ declarations for you. So it is generally available to you as an Arduino user. You should find `ctags` or `ctags.exe` in:

> */path/to/arduino15*`/builtin/tools/ctags/`*version-number*`/`

This can be run against your board support in:

> */path/to/arduino15*`/packages/`*vendor*`/hardware/`*architecture*`/`*version-number*`/`

And your standard libraries found under directories in the form of:

> */path/to/arduino15*`/packages/`*vendor*`/tools/`*compiler-tool*`/`*version-number*`/`

If you're wondering what */path/to/arduino15/* would be on your system, it's documented here in terms of where the preferences file is stored. The relevant paths containing and version numbers and architecture names should show in the verify/compile output when verbose mode is turned on in preferences.

## Specific example

On my linux system with reasonably current versions of UNO-related things, my command-line would look like:

```
~/.arduino15/packages/builtin/tools/ctags/5.8-arduino11/ctags \
    -f /tmp/output-file \
    -R \
     ~/.arduino15/packages/arduino/hardware/avr/1.8.3/ \
    ~/.arduino15/packages/arduino/tools/avr-gcc/4.8.1-arduino5/avr/include/

```

The resulting tag file can then `grep`ed or just opened and the following entries can be found, showing the filenames and line numbers to investigate:

```
DigitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/circuitplay32u4/pins_arduino.h   138;"   d
digitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/ethernet/pins_arduino.h  79;"    d
digitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/gemma/pins_arduino.h 64;"    d
digitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/leonardo/pins_arduino.h  160;"   d
digitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/mega/pins_arduino.h  110;"   d
digitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/robot_control/pins_arduino.h 120;"   d
digitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/robot_motor/pins_arduino.h   115;"   d
digitalPinToInterrupt   /home/user/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/standard/pins_arduino.h  79;"    d

```

In the case of an UNO the `standard` variant is the significant declaration.

---

There are different implementations of ctags. The one used by the Arduino support files is Exuberant CTAGS and you may want to read its documentation, to learn how to control the program to display differently to only search for specific identifiers, etc. It is also typically used with editors that have some special support for the resulting tags file, to jump to definitions, like an IDE would.
> 1 votes

# Answer
If you like to tinker with the files. Than platformio is great option to go with. It provides auto completion and much more advance functionality.

You can easy see where some function/mecro is defined, by just right click on the function than click on the "Go to definition" option.

The file that contains the definition will be opened in the new tab. As for your current Macro check the image below
> 0 votes

---
Tags: interrupt, atmega2560
---


title: Garbage in serial monitor

text:
# Question
Title: Garbage in serial monitor
I'm revisiting my Arduino stuff (I want to revive Teleinfo shield to monitor closely my power consumption). I just cannot get the thing to work (Teleinfo Shield \+ Uno Wifi).

When trying to check what's happening this is the kind of Serial Monitor screens that I get.

Any hints on how to solve? It happens with other Uno as well and different versions of IDE.

Thank for any help, the answers I found in different places didn't lead me to a solution.

I tried several baud settings, (same for port and monitor, each time) and sometimes nothing was written, sometimes complete garbage, sometimes as illustrated

The code is the following Teleinfo\_Arduino\_V0\_3E.ino (just added some lines writing to serial to follow progress; and modified `Serial.begin` accordingly and "shortened" to stay within size limits but it's sending wrong characters ate beginning))

```
/*
              Datalogger Téléinfo 2 compteurs sur Arduino

              Compteur 1: consommation
              Compteur 2: production solaire en tarif BASE

              Juin 2011:
              v0.2  * passage automatique à l'heure d'été
                      correctif erreur abo BBR
                      modification ecriture sur SD (utilisation de teleinfoFile.print à la place s'une variable STRING
                      qui plante l'Arduino avec les abonnements BBR
              v0.2a * ajout mode sans puissance apparente pour ancien compteur et calcul de celle-ci pour les logiciels d'analyse
              v0.2b * pour Arduino 1.0 (mise à jour de la RTC et utilisation de la librairie SD livrée avec la 1.0)
              v0.2c * modif type de variable pour éviter d'avoir 2 enregistrements à la même minute (surtout sur des proc + rapide)
              v0.3  * détection automatique du type d'abonnement sur le compteur 1
              v0.3a * Fonction de mise à l'heure par l'usb (interface série) en 1200 bauds 7 bits parité pair
                      Procédure:
                      1- carte débranchée, enlevez la pile de son support (pour réinitialiser l'horloge)
                      2- enlevez le cavalier du shield téléinfo
                      3- configurer votre logiciel émulateur de terminal (termite,Hyperterminale...) en 1200 bauds 7 bits parité pair
                      4- mettre sous tension la carte.
                      -- Le programme détectera le reset de l'horloge et vous demandera de rentrer l'heure et la date. --

              v0.3b * Correction bug calcul PAP compteur 2, enregistrement journalier compteur 2
              v0.3c * Triphasé sur compteur 2
              v0.3d * correction bug retour ligne sur compteur 2 (entête fichier)
              v0.3e * Correction bug si pas de compteur 2
*/

#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>

const char version_logiciel[6] = "V0.3e";

// #define echo_USB            //envoie toutes les trames téléinfo sur l'USB
#define message_systeme_USB  //envoie des messages sur l'USB (init SD, heure au demarrage, et echo des erreures)

//*****************************************************************************************
byte inByte = 0;  // caractère entrant téléinfo
char buffteleinfo[21] = "";
byte bufflen = 0;
byte mem_sauv_minute = 1;
byte mem_sauv_journee = 1;
byte num_abo = 0;
byte type_mono_tri[2] = { 0, 0 };
uint8_t presence_teleinfo = 0;  // si signal teleinfo présent
byte presence_PAP = 0;          // si PAP présent
boolean cpt2_present = true;    // mémorisation de la présence du compteur 2
boolean compteursluOK = false;  // pour autoriser l'écriture de valeur sur la SD
boolean mem_affichage_cpt2_present = true;

int ReceptionOctet = 0;            // variable de stockage des octets reçus par port série
unsigned int ReceptionNombre = 0;  // variable de calcul du nombre reçu par port série
byte reg_horloge = 1;
boolean mem_reg_horloge = false;
const uint8_t val_max[6] = { 24, 59, 59, 31, 12, 99 };

// declarations Teleinfo
unsigned int papp = 0;  // Puissance apparente, VA

uint8_t IINST[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } };  // Intensité Instantanée Phase 1, A  (intensité efficace instantanée) ou 1 phase en monophasé

unsigned long INDEX1 = 0;  // Index option Tempo - Heures Creuses Jours Bleus, Wh
unsigned long INDEX2 = 0;  // Index option Tempo - Heures Pleines Jours Bleus, Wh
unsigned long INDEX3 = 0;  // Index option Tempo - Heures Creuses Jours Blancs, Wh
unsigned long INDEX4 = 0;  // Index option Tempo - Heures Pleines Jours Blancs, Wh
unsigned long INDEX5 = 0;  // Index option Tempo - Heures Creuses Jours Rouges, Wh
unsigned long INDEX6 = 0;  // Index option Tempo - Heures Pleines Jours Rouges, Wh

// compteur 2 (solaire configuré en tarif BASE par ERDF)
unsigned long cpt2index = 0;     // Index option Base compteur production solaire, Wh
unsigned int cpt2puissance = 0;  // Puissance apparente compteur production solaire, VA

#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D

// *************** déclaration carte micro SD ******************
const byte chipSelect = 4;

// *************** déclaration activation compteur 1 ou 2 ******
#define LEC_CPT1 5  // lecture compteur 1
#define LEC_CPT2 6  // lecture compteur 2
//
byte verif_cpt_lu = 0;
//

byte compteur_actif = 1;           // numero du compteur en cours de lecture
byte donnee_ok_cpt[2] = { 0, 0 };  // pour vérifier que les donnees sont bien en memoire avant ecriture dans fichier
byte donnee_ok_cpt_ph[2] = { 0, 0 };

// *************** variables RTC ************************************
byte minute, heure, seconde, jour, mois, jour_semaine;
unsigned int annee;
char date_heure[18];
char mois_jour[7];
byte mem_chg_heure = 0;  //pour pas passer perpetuellement de 3h à 2h du matin le dernier dimanche d'octobre
RTC_DS1307 RTC;

// ************** initialisation *******************************
void setup() {
  // initialisation du port 0-1 lecture Téléinfo
  Serial.begin(1200);
  // parité paire E
  // 7 bits data
  UCSR0C = B00100100;
#ifdef message_systeme_USB
  Serial.print(F("-- Teleinfo USB Arduino "));
  Serial.print(version_logiciel);
  Serial.println(F(" --"));
#endif
  // initialisation des sorties selection compteur
  pinMode(LEC_CPT1, OUTPUT);
  pinMode(LEC_CPT2, OUTPUT);
  digitalWrite(LEC_CPT1, HIGH);
  digitalWrite(LEC_CPT2, LOW);

  // verification de la présence de la microSD et si elle est initialisée:
#ifdef message_systeme_USB
  if (!SD.begin(chipSelect)) {
    Serial.println(F("> Erreur carte, ou carte absente !"));
    return;
  }
  Serial.println(F("> microSD initialisee !"));
#endif

  // initialisation RTC16

  Wire.begin();
  RTC.begin();

  if (!RTC.isrunning()) {
#ifdef message_systeme_USB
    Serial.println(F("RTC non configure !"));
#endif
  }

  DateTime now = RTC.now();  // lecture de l'horloge
  annee = now.year();
  mois = now.month();
  jour = now.day();
  heure = now.hour();
  minute = now.minute();
  jour_semaine = now.dayOfTheWeek();

  format_date_heure();
#ifdef message_systeme_USB
  Serial.println(date_heure);
#endif
}

// ************** boucle principale *******************************

void loop()  // Programme en boucle
{

  if (!(RTC.isrunning()) && (reg_horloge < 7)) {  // si l'horloge n'est pas configurée
    digitalWrite(LEC_CPT1, LOW);

    if (!mem_reg_horloge) {
      switch (reg_horloge) {  // debut de la structure
        case 1:
          Serial.print(F("Entrer Heure: "));
          break;
        case 2:
          Serial.print(F("Entrer Minute: "));
          break;
        case 3:
          Serial.print(F("Entrer Seconde: "));
          break;
        case 4:
          Serial.print(F("Entrer Jour: "));
          break;
        case 5:
          Serial.print(F("Entrer Mois: "));
          break;
        case 6:
          Serial.print(F("Entrer Annee 20xx: "));
          break;
      }
      mem_reg_horloge = true;
    }
    if (Serial.available() > 0) {  // si caractère dans la file d'attente

      Serial.print(F("un nombre a ete recu")); //---- lecture du nombre reçu
      while (Serial.available() > 0) {
        // tant que buffer pas vide pour lire d'une traite tous les caractères reçus
        inByte = Serial.read();         // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
        Serial.println(inByte);
        if (((inByte > 47) && (inByte < 58)) || (inByte == 13)) {
          ReceptionOctet = inByte - 48;  // transforme valeur ASCII en valeur décimale
          if ((ReceptionOctet >= 0) && (ReceptionOctet <= 9)) ReceptionNombre = (ReceptionNombre * 10) + ReceptionOctet;
          // si valeur reçue correspond à un chiffre on calcule nombre
          Serial.print(ReceptionNombre);
          Serial.print(reg_horloge);
        } else
          presence_teleinfo = -1;
      }  // fin while
      if (inByte == 13) {
        if ((ReceptionNombre > val_max[reg_horloge - 1]) || (ReceptionNombre == -1)) {
          Serial.println(F("Erreur horaire"));
          ReceptionNombre = 0;
          mem_reg_horloge = true;
        } else {
          Serial.print("cela bugge");
          switch (reg_horloge) {  // debut de la structure
            case 1:
              heure = ReceptionNombre;
              Serial.print("heure:");
              Serial.println(heure);
            case 2:
              minute = ReceptionNombre;
              break;
            case 3:
              seconde = ReceptionNombre;
              break;
            case 4:
              jour = ReceptionNombre;
              break;
            case 5:
              mois = ReceptionNombre;
              break;
            case 6:
              annee = 2000 + ReceptionNombre;
              break;
          }

          mem_reg_horloge = false;
          ReceptionNombre = 0;
          ++reg_horloge;

          if (reg_horloge > 6) {
            RTCsetTime();
            Serial.println(F("Reglage heure OK - installer le cavalier pour la teleinfo"));
            digitalWrite(LEC_CPT1, HIGH);
          }
        }
      }
    }
  }

  else {

    DateTime now = RTC.now();  // lecture de l'horloge
    minute = now.minute();
    heure = now.hour();
    seconde = now.second();

    if ((heure == 0) && (minute == 0) && (seconde == 0)) {
      annee = now.year();
      mois = now.month();
      jour = now.day();
      jour_semaine = now.dayOfTheWeek();
    }

    // passage à l'heure d'été +1 heure
    // la lib RTC a une fonction: dayOfWeek qui donne le jour de la semaine (la DS1307 se charge de tout !)
    // réponse: 0 -> dimanche, 1 -> lundi etc...
    //
    if ((heure == 2) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 3) && (jour > 24)) {
      heure = 3;
      RTCsetTime();
    }

    // passage à l'heure d'hiver -1 heure
    if ((heure == 3) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 10) && (jour > 24) && (mem_chg_heure == 0)) {
      heure = 2;
      RTCsetTime();
      mem_chg_heure = 1;
    }

    if ((heure == 23) && (minute == 59) && (seconde == 10))  // pour être sur de pas tomber pendant l'enregistrement toutes les minutes
    {
      if ((mem_sauv_journee == 0) && (compteursluOK))  // un seul enregistrement par jour !
      {
        fichier_annee();
        mem_sauv_journee = 1;
        mem_chg_heure = 0;
      }
    } else
      mem_sauv_journee = 0;

    if (seconde == 1) {
      if ((mem_sauv_minute == 0) && (compteursluOK))  // un seul enregistrement par minute !
      {
        enregistre();
        mem_sauv_minute = 1;
      }
    } else
      mem_sauv_minute = 0;

#ifdef message_systeme_USB
    if ((donnee_ok_cpt[1] == B00000111) && (mem_affichage_cpt2_present)) {
      if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 detecte"));
      mem_affichage_cpt2_present = false;
    } else if ((!cpt2_present) && (mem_affichage_cpt2_present)) {
      if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 non present !"));
      mem_affichage_cpt2_present = false;
    }
#endif

    if ((donnee_ok_cpt[0] == verif_cpt_lu) and (cpt2_present)) {
      if ((type_mono_tri[0] == 1) && (donnee_ok_cpt_ph[0] == B10000001)) bascule_compteur();
      else if ((type_mono_tri[0] == 3) && (donnee_ok_cpt_ph[0] == B10000111))
        bascule_compteur();
    } else if ((donnee_ok_cpt[1] == B00000001) or ((compteur_actif == 2) and (!cpt2_present))) {
      if ((type_mono_tri[1] == 1) && (donnee_ok_cpt_ph[1] == B10000001)) bascule_compteur();
      else if ((type_mono_tri[1] == 3) && (donnee_ok_cpt_ph[1] == B10000111))
        bascule_compteur();
      compteursluOK = true;
    }

    if (compteur_actif == 2) {
      if (presence_teleinfo > 200) {
        cpt2_present = false;
        compteursluOK = true;
        bascule_compteur();
      } else
        cpt2_present = true;
    }

    read_teleinfo();
  }
}

///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, uint8_t len) {
  int i;
  char sum = 0;
  for (i = 1; i < (len - 2); i++) sum = sum + buff[i];
  sum = (sum & 0x3F) + 0x20;
  return (sum);
}

///////////////////////////////////////////////////////////////////
// mise en forme Date & heure pour affichage ou enregistrement
///////////////////////////////////////////////////////////////////
void format_mois_jour() {
  sprintf(mois_jour, "%02d,%02d,", mois, jour);
}

// Convert normal decimal numbers to binary coded decimal
static uint8_t bin2bcd(uint8_t val) {
  return val + 6 * (val / 10);
}

///////////////////////////////////////////////////////////////////
// mise à l'heure de la RTC (DS1307)
///////////////////////////////////////////////////////////////////
void RTCsetTime(void) {
  Wire.beginTransmission(104);  // 104 is DS1307 device address (0x68)
  Wire.write(bin2bcd(0));       // start at register 0

  Wire.write(bin2bcd(seconde));       //Send seconds as BCD
  Wire.write(bin2bcd(minute));        //Send minutes as BCD
  Wire.write(bin2bcd(heure));         //Send hours as BCD
  Wire.write(bin2bcd(jour_semaine));  // dow
  Wire.write(bin2bcd(jour));          //Send day as BCD
  Wire.write(bin2bcd(mois));          //Send month as BCD
  Wire.write(bin2bcd(annee % 1000));  //Send year as BCD

  Wire.endTransmission();
}

```

MacBookPro 2018 runnning Monterey

# Answer
> 2 votes
## Parity mismatch

The essence of the seems to be this:

```
Serial.begin(1200);
// parité paire E
// 7 bits data
UCSR0C = B00100100;

```

The code changes the USART to operate with **EVEN** parity and **1** stop bits, or 7E1 for short. The Arduino serial monitor uses the more common NO parity 1 stop bit configuration (8N1). I did a small hello world type test to confirm that the kind of output you're getting on the Serial Monitor is about like expected for this mismatch.

## Resolving

So, you need them to match. You can:

* Either remove/comment out `UCSR0C = B00100100;` to go with the normal 8N1 configuration.
* Or use a serial terminal emulator or other software capable of configuring for the port for even parity and 1 stop bits (7E1).

Incidentally, if you have good cause to use 7E1, the conventional way to do it is `Serial.begin(1200, SERIAL_7E1);` I don't know why they manually manipulated the hardware registers, perhaps the code predates support for this form of `begin()`.

## Serial Monitor Support

The IDE's Serial Monitor is reportedly capable of being configured for something other than 8N1 via `preferences.txt`. ~~I did not get it working, but I also didn't spend that long trying. Perhaps I will again and update this.~~ I think I didn't close all instances of the IDE. I've now verified that the Serial Monitor can be operated in 7E1 making the following changes to the arduino15 directory's `preferences.txt` file:

| Old line reading | New line reading |
| --- | --- |
| `serial.databits=8` | `serial.databits=7` |
| `serial.parity=N` | `serial.parity=E` |

That said, it is *probably a mistake* to have a change like that hidden away where it will cause lots of confusion later when 8N1 is needed. So, a terminal emulator is still probably a better choice if you actually want or need even parity and 1 stop bits. I in fact I'm going to change mine back now, just so this doesn't catch me. I'd use a regular software terminal emulator instead of messing with these, but it's to know that you *can* use Serial Monitor if you're forced to do that for whatever reason.

---
Tags: serial
---


title: Problem with push button

text:
# Question
Title: Problem with push button
I am making a project where if the push button is pressed, the LCD screen will show a message. But with many trial and errors, it doesn't give the right result.

Here is the circuit:

Here is the code:

```
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
#define BUTTON 7
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  pinMode(BUTTON, INPUT);
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 0);
  // print the number of seconds since reset:
  lcd.print("Press Button");
  lcd.setCursor(0,1);
  lcd.print("to make COFFEE");
  if (digitalRead(BUTTON) == HIGH) {
    lcd.clear();
    lcd.print("SENT TO MACHINE");
  }
}

```

# Answer
It looks like you have several issues.

1. The positive and negative supply "rails" on your prototyping board are not connected together internally. You should add a positive jumper wire.
2. You are trying to detect when the button provides a `HIGH` logic level, but there is no possibility of doing so with the current "wiring".

One more thing that could help to determine this, or another possible issue, is a picture of your setup from a different angle so we can see exactly how that button, capacitor, and resistor are connected.

This is the area which would be nice to see from a different angle.
> 1 votes

# Answer
you should implement debouncing because when you press the button with your hand it will bounce and make the signal instable so no High/Low, here's the doc from Arduino:

https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce
> 0 votes

---
Tags: arduino-uno, lcd, button
---


# Question
Title: Noise in RF 434 transmitter and receiver
I'm working on RF transmitter and receiver modules using two Arduino UNOs. I'm getting an additional noise on the receiver side in serial.println. To be more clear about the question. Hre is my transmitter code

```
// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>

// Create Amplitude Shift Keying Object
RH_ASK rf_driver;

void setup()
{
    // Initialize ASK Object
    rf_driver.init();
    Serial.begin(9600);
}

void loop()
{

    const char *msg = "Hello World";
    rf_driver.send((uint8_t *)msg, strlen(msg));
    rf_driver.waitPacketSent();
    Serial.println((char *)msg);
    delay(1000);
}

```

Here is my receiver code

```
// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>

// Create Amplitude Shift Keying Object
RH_ASK rf_driver;

void setup()
{
    // Initialize ASK Object
    rf_driver.init();
    // Setup Serial Monitor
    Serial.begin(9600);
}

void loop()
{
    // Set buffer to size of expected message
    uint8_t buf[11];
    uint8_t buflen = sizeof(buf);
    // Check if received packet is correct size
    if (rf_driver.recv(buf, &buflen))
    {

      // Message received with valid checksum
      Serial.print("Message Received: ");
      Serial.println((char*)buf);
    }
}

```

And here is my Serial monitor in receiver side

So, can somebody help me to sort out this issue

# Answer
You're treating a raw buffer as a string.

In C a string is an array of characters (11 in your case) terminated by a NULL character. You receive 11 bytes into an 11 byte array and then try and print it - without any terminating character - so the output "overruns" into the memory following your array.

You need a buffer of 12 bytes not 11, and you have to make sure that the 12th byte (byte number 11) is zero.

Or use `Serial.write(buf, buflen);` function to write exactly 11 bytes to the serial.
> 1 votes

---
Tags: arduino-uno, communication, rf, serial-data
---


# Question
Title: How to configure 16x2 character LCD to work with 8bit?
I have the LiquidCrystal library installed but all the examples are for 4bit connection, I want to drive the LCD with 8bit.

In LiquidCrystal.cpp file it says;

> When the display powers up, it is configured as follows:
>
> DL = 1; 8-bit interface data

But what's is the function, should it be like this: `LiquidCrystal DL(1);`? where and how should I call `DL = 1;`?

# Answer
> 3 votes
You don't "do" anything to enable 8 bit. As it says *when the device powers up the DL bit in the configuration is already set, enabling 8 bit*.

You just need to wire it for 8 bit and specify all 8 bits of wiring in the constructor.

The manual entry for the constructor shows you what parameters you can specify:

---
Tags: lcd, library
---


# Question
Title: Using Arduino to read and write data to RS232 device
I have a micro turbojet engine (JetCat P100-RX) which is operated through an Electronic Control Unit (ECU).

The ECU has a lot of information about the engine. I want to access that information and also send commands to the ECU to control the engine.

The ECU connects to a Mini I/O device. This connection is shown in the following image:

The details of both the ECU serial connection and the Mini I/O Board are given in this manual page 4. (What I understand here is that the data stream from the Mini Board follows a RS232 protocol.) It looks as shown:

I would like to collect the information from the Tx, Rx and GND pins using the Arduino Uno. How can I do this? The Arduino is connected to my PC through the USB port.

**EDIT1:** What I tried doing:

I connected the Tx, Rx and GND of the Mini Board to pins 10 and 11 of the Arduino and configured 10 and 11 as serial pins and GND to Arduino GND (Rx anf Tx respectively) using SerialSoftware as follows:

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

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

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600); // Set to 9600 as the manual says (link above)
}

void loop() {
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
}

```

My circuit diagram:

**But I don't get any output on the Serial Monitor.**

While reading online I found out that I need some converter. Following these posts, I have bought a MAX3232. Do I need to use that? How do I use that and what changes do I make in my code?

# Answer
That is relatively easy to do. If you have a Mega or another Arduino that has more than one serial port, great. If not, then softwareserial is what you need. For this to work all grounds must be connected.

Softwareserial can only receive on one channel at a time. On the hardware level you should use a high-impedance receiver to monitor both the RX and TX signals. I use a 74HC14 (74C914 is rated at +- 25 V on its input) or similar device. Place a 50 kΩ resistor from the RX to an input on the IC, do the same with the TX to another input on the IC. The input protection diodes of the 74HC will limit the current, at 50 kΩ 50 V gives 1 mA.

Connect the outputs of the IC to inputs of the Arduino. Each input needs to be configured to receive ASYNC input at the correct baud and other parameters. I have done this many times and it works great. I always did it with UARTs, not software. Note the 74HC device inverts the signal as is normal with RS232. There are various modules available for the Arduino that have a USART, UART or similar serial device on them.
> -1 votes

---
Tags: arduino-uno, serial, softwareserial, rs232
---


title: AsyncWebServer giving wdt reset

text:
# Question
Title: AsyncWebServer giving wdt reset
I am using 3 Esp32 modules. One being master and other two being nodes. Nodes are connecting to the master's AP. Master is connected with GSM module to execute the web api. Master esp is having a Async Webserver which takes the http requests from the nodes and executes the appropriate web api. This web api returns the result and finally this result is sent back to the node as the response to the http request.

While running this code, Randomly on any request i face wdt reset.

Hence my question is, how should i handle the wdt resets and keep my program running softly.

```
E (32706) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (32706) task_wdt: - async_tcp (CPU 0/1)
E (32706) task_wdt: Tasks currently running:
E (32706) task_wdt: CPU 0: IDLE0
E (32706) task_wdt: CPU 1: async_tcp
E (32706) task_wdt: Aborting.
abort() was called at PC 0x400e1cc3 on core 0
Backtrace: 0x4008c434:0x3ffbe170 0x4008c665:0x3ffbe190 0x400e1cc3:0x3ffbe1b0 0x40084771:0x3ffbe1d0 0x4016aaf3:0x3ffbc0d0 0x400e307a:0x3ffbc0f0 0x4008a361:0x3ffbc110 0x40088b7d:0x3ffbc130

```

My Code Snippet is given below,

**Master**

```
HttpClient http(gsmClient, "www.mydummyserver.com", 80);
AsyncWebServer server(80);

const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";
IPAddress ip(192,168,5,2);
IPAddress gateway(192,168,5,1);
IPAddress subnet(255,255,255,0);
const char* PARAM_MESSAGE = "message";

void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}

void setup() {

  Serial.begin(115200);
  WiFi.mode(WIFI_AP);
  delay(100);
  WiFi.softAPConfig(ip, gateway, subnet);
  WiFi.softAP(ssid, password);

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(200, "text/plain", "Hello, world");
    });

 server.on("/myApi", HTTP_POST, [] (AsyncWebServerRequest *request) {

        String message;
        if (request->hasParam(PARAM_MESSAGE)) {
            message = request->getParam(PARAM_MESSAGE)->value();
        } else {
            message = "No message sent";
        }

        http.setTimeout(20000);
        String postData = "Param1=abcd&Param2=pqrs";
        http.beginRequest();
        http.post("http://www.mydummyserver.com/testapi.php");
        http.sendHeader("Content-Type", "application/x-www-form-urlencoded");
        http.sendHeader("Content-Length", postData.length());
        http.beginBody();
        http.print(postData);
        http.endRequest();
        int statusCode = http.responseStatusCode();
        String response = http.responseBody();

        Serial.print("Status code: ");
        Serial.println(statusCode);
        Serial.print("Response: ");
        Serial.println(response);
        request->send(200, "text/plain", "Response: " + message);

    });

 server.onNotFound(notFound);

    server.begin();

}

void loop() {

}

```

**Node**

```
HTTPClient httpClient;

void setup() {

  Serial.begin(115200);

  WiFi.begin("ESP32-Access-Point", "123456789");

  Serial.print("WiFi ");

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(10);

  }

  Serial.println("connected:" + WiFi.SSID());

}

void executeApi() {

  Serial.println("Executing Api...");

  httpClient.setTimeout(20000);
  httpClient.begin("http://192.168.5.2/myApi");
  httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
  String contentStr = "Param1=abcd&Param2=pqrs";

  int httpResponseCode = httpClient.POST(contentStr);

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

  httpClient.end();

}

String cmd = "";
void loop() {

  if (Serial.available() > 0) {

    cmd = (Serial.readStringUntil('\n'));

    if (cmd.length() > 0) {

      if (cmd == "api") {
        executeApi();

      }

    }

  }

}

```

For sulutions i have tried following things,

a. I tried to write this into the loop() function.

```
 while(true){
   delay(1);
 }

```

b. Tried disabling the wdt

```
disableCore0WDT()
disableCore1WDT()

```

but none of these giving good results.

# Answer
The following recommendations, as you aren't providing enough relevant info:

* Install ESP-exception decoder and analyse your backtrace - Post it here so we can see in detail what caused the wdt
* AsyncWebServer tends to cause this behavior if a response takes too long; a well placed `yield()` sometimes helps to prevent this behavior - to analyse you need ESP-exeption decoder
* As `loop()` is running on core1 some/no process (idle) on core0 can cause the behavior. You can look up "task assignment to cores" on how to manually distribute the tasks (or send a `yield()` timed to core0 to reset the wdt)
* Placing time-outs in combination with sleep/deep sleep (although you don't seem to use them) are also causes for wdt resets
* A hackey trick is to set `CONFIG_ASYNC_TCP_USE_WDT 0`, but it is OK for testing

If you look into async\_tcp for the possible culprit you see one line `xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 * 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);`

Here is an example of how I use it to prevent wdt resets. Place in `setup()`:

```
disableCore0WDT();
disableCore1WDT();
disableLoopWDT(); // You forgot this one !

```

and because of this routine in the async\_tcp lib:

```
static void _async_service_task(void *pvParameters) {
  lwip_event_packet_t * packet = NULL;
  for (;;) {
    if (_get_async_event(&packet)) {
      #if CONFIG_ASYNC_TCP_USE_WDT
      if (esp_task_wdt_add(NULL) != ESP_OK) {
        log_e("Failed to add async task to WDT");
      }
      #endif
      _handle_async_event(packet);
      #if CONFIG_ASYNC_TCP_USE_WDT
      if (esp_task_wdt_delete(NULL) != ESP_OK) {
        log_e("Failed to remove loop task from WDT");
      }
      #endif
    }
  }
  vTaskDelete(NULL);
  _async_service_task_handle = NULL;
}

I set the `CONFIG_ASYNC_TCP_USE_WDT 0` and it works so far.

```
> 1 votes

# Answer
## **Short answer**

**increase the size of the \_async\_queue in AsyncTCP.cpp**

```
_async_queue = xQueueCreate(32, sizeof(lwip_event_packet_t *));

```

**from 32 to 64 or even higher if you can spare the space**

## **Detailed (but possibly incorrect) explanation:**

After looking at the OS calls, I found that in AsyncTCP.cpp

The event queue is created as:

```
_async_queue = xQueueCreate(32, sizeof(lwip_event_packet_t *));

```

Later the items are added with a Timeout of portMAX\_DELAY, for example:

```
static inline bool _send_async_event(lwip_event_packet_t ** e){
    return _async_queue && xQueueSend(_async_queue, e, portMAX_DELAY) == pdPASS;
}

```

Since (at least when using the AsyncWebserver), both the queueing and the dequeuing are done on the same task (async\_tcp), as soon as there are 32 events in the queue the moment the next event is to be added, the task will block indefinitely, causing the TWDT to be triggered.

So the solution might be to have the event queueing/dequeueing done in different tasks (maybe intended, since it already is an os queue) or increase the queue size to a value that will not be reached. Since the queue items are not that large, I just increased it to 256 to be on the safe side.

**I am not sure if this explanation is correct, since I can't find the code where async\_tcp feeds or kicks the watchdog during normal operation. So if someone knows how it works and could tell me, it would be greatly appreciated.**
> 0 votes

---
Tags: esp32, http, reset, espressif, watchdog
---


# Question
Title: Connect an MPX10DP Pressure Sensor to an Arduino Mega 2560
I'm literally new to using Arduino, i am trying to build a Pitot Tube to measure airspeed using an MPX10DP differential pressure sensor and i am working with an Arduino Mega 2560.

Honestly, i have studied some tutorials of people building a Pitot Tube but the pressure sensors they use are not available in my region, the only pressure that i could afford is the MPX10DP but i am not sure of how to connect it to my arduino and make it get values.

Can someone help me or guide me a bit?

# Answer
> 1 votes
That part was originally introduced by Motorola many years ago. It is a silicon strain gauge in a bridge configuration. You need an external amplifier as it only has maybe 50 mVdc output depending on your circuit. It is a relative output voltage depending on how you excite it. The one you have is a differential unit, they also made absolute and gauge units as well. There were many application notes published on the MPX family of pressure transducers. You may have to look in the Motorola archives to find them. The voltage will be either + or - from your reference point depending on what the differential pressure is. They are not temperature compensated so you need to design that into your circuit as well.

---
Tags: arduino-mega, sensors, pressure
---


# Question
Title: Battery charger board with status interface
There are of course a lot of different battery charging boards, which can be used with the Arduino, most being TP4056 based. There are also a few battery charged boards with an on-board display showing the charge status and there are of course also a lot of programmable battery charger controllers (ICs) with status and control interfaces.

But is there any board available, not just the 'raw' IC, using a charging controller with a status interface, which allows access to the status interface from pins on the board? I can't seem to find anything.

For a battery powered Arduino project I am planning, it could at least be very convenient if I could query the battery charging status from software.

# Answer
I know it's been asked quite long time ago, but still. This is how would have I done the same, with the existing TP4056:

1. use an electric key in a form of mosfet transistor, controlled by digital output pin to disconnect your battery from the charging board once in a while (like every 5-10 minutes or so, depending on your project power drain) for a very short period of time to do the measurement below.
2. while the battery is disconnected, use an analog input pin of arduino with resistor-based voltage divider to see what's your battery voltage. Google for "measure voltage with arduino alone" for schemas and code, it's pretty straightforward.

For obvious reasons, you cannot do this measurement while having your charging board connected to battery, because you'll be getting voltage from the charger, and not from your battery. This is why we disconnected battery from the charging circuit in step 1.

3. Knowing

* current voltage you just get from your battery
* what is the voltage should be on your battery when it's fully charged
* the voltage you allow it to discharge to ... you can calculate percentages

4. digitalWrite to that pin to enable mosfet to connect your battery back to charging circuit
> 2 votes

# Answer
You might consider a coulomb counter IC, it is designed to give you the state of charge of the battery. There is a module labeled "LTC4150 Coulomb Counter" that will do exactly what you want.
> 0 votes

---
Tags: charging
---


# Question
Title: ESP32 not detecting PN532 module running in SPI mode
I am trying to get the Pn532 module working on the esp32, first I tried to get it working with i2c and had some "success"(it worked, but as soon as I had another i2c device, in my case a display, 90% of the time it refused to work) and after some research, it's mentioned in the github repo the module doesnt work with multiple devices attached on the i2c bus. Now I am trying to get it working trough spi, but it doesn't get detected. Code: **readMirafe example from the Adafruit Pn532 Library, but I modified the pins from line 42-45**

```
/**************************************************************************/
/*!
    @file     readMifare.pde
    @author   Adafruit Industries
    @license  BSD (see license.txt)
    This example will wait for any ISO14443A card or tag, and
    depending on the size of the UID will attempt to read from it.

    If the card has a 4-byte UID it is probably a Mifare
    Classic card, and the following steps are taken:

    - Authenticate block 4 (the first block of Sector 1) using
      the default KEYA of 0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
    - If authentication succeeds, we can then read any of the
      4 blocks in that sector (though only block 4 is read here)

    If the card has a 7-byte UID it is probably a Mifare
    Ultralight card, and the 4 byte pages can be read directly.
    Page 4 is read by default since this is the first 'general-
    purpose' page on the tags.
This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
This library works with the Adafruit NFC breakout
  ----> https://www.adafruit.com/products/364

Check out the links above for our tutorials and wiring diagrams
These chips use SPI or I2C to communicate.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
*/
/**************************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout with SPI, define the pins for SPI communication.
#define PN532_SCK  (18)
#define PN532_MISO (19)
#define PN532_MOSI (23)
#define PN532_SS   (27)

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield

// Uncomment just _one_ line below depending on how your breakout or shield
// is connected to the Arduino:

// Use this line for a breakout with a software SPI connection (recommended):
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

// Use this line for a breakout with a hardware SPI connection.  Note that
// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
// hardware SPI SCK, MOSI, and MISO pins.  On an Arduino Uno these are
// SCK = 13, MOSI = 11, MISO = 12.  The SS line can be any digital IO pin.
//Adafruit_PN532 nfc(PN532_SS);

// Or use this line for a breakout or shield with an I2C connection:
//Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10); // for Leonardo/Micro/Zero

  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an ISO14443A Card ...");
}

void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");

    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ...
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");

      // Now we need to try to authenticate it for read/write access
      // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

      // Start with block 4 (the first block of sector 1) since sector 0
      // contains the manufacturer data and it's probably better just
      // to leave it alone unless you know what you're doing
      success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);

      if (success)
      {
        Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
        uint8_t data[16];

        // If you want to write something to block 4 to test with, uncomment
        // the following line and this text should be read back in a minute
        //memcpy(data, (const uint8_t[]){ 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0 }, sizeof data);
        // success = nfc.mifareclassic_WriteDataBlock (4, data);

        // Try to read the contents of block 4
        success = nfc.mifareclassic_ReadDataBlock(4, data);

        if (success)
        {
          // Data seems to have been read ... spit it out
          Serial.println("Reading Block 4:");
          nfc.PrintHexChar(data, 16);
          Serial.println("");

          // Wait a bit before reading the card again
          delay(1000);
        }
        else
        {
          Serial.println("Ooops ... unable to read the requested block.  Try another key?");
        }
      }
      else
      {
        Serial.println("Ooops ... authentication failed: Try another key?");
      }
    }

    if (uidLength == 7)
    {
      // We probably have a Mifare Ultralight card ...
      Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");

      // Try to read the first general-purpose user page (#4)
      Serial.println("Reading page 4");
      uint8_t data[32];
      success = nfc.mifareultralight_ReadPage (4, data);
      if (success)
      {
        // Data seems to have been read ... spit it out
        nfc.PrintHexChar(data, 4);
        Serial.println("");

        // Wait a bit before reading the card again
        delay(1000);
      }
      else
      {
        Serial.println("Ooops ... unable to read the requested page!?");
      }
    }
  }
}

```

My wiring is the following

```
(PN523 Module->esp32):
SCK  -> D18;
MSO  -> D19;
MOSI -> D23;
SS   -> D27

```

And yes, the board is in SPI mode(the dip switch). Thank you!

# Answer
> 0 votes
Got it working by running the module in VSPI and modifying the library a bit: https://github.com/adafruit/Adafruit-PN532/issues/80#issuecomment-649915457

# Answer
> 0 votes
There is a switch on your PN5322 by default it is set to 0, 0. Switch to the mode of communication you are using.

---
Tags: esp32
---


# Question
Title: Why am I reading only zeroes from PORTB?
I am using a custom Arduino Nano compatible board with an Atmel 328P. I am externally changing the values applied to several pins on PORTB. I expect to be able to read the values of these pins (low or high) but I always read zeroes. However, the pin change interrupt is called. What do I need to do to read values from PORTB?

Supply voltage is 5 volts. Pin applied high voltage is 3.3 volts.

With the below code, when I change the voltage applied to a pin, LED1 flashes but LED2 does not.

```
#include <avr/interrupt.h>

#define LED1_PORT                           (PORTD)
#define LED1_PIN_bm                         (_BV(4))         //D1, white

#define LED2_PORT                           (PORTD)
#define LED2_PIN_bm                         (_BV(3))         //D2, red

volatile bool g_bValueChanged = 0;

void setup()
{
  DDRB = 0;                     //set all as inputs
  PCMSK0 = 0xfb;                //exclude 1 pin because of noise
  PCICR |= (1 << PCIE0);        //enable pin change interrupt 0 (for pins PB0..7)

  sei();
}

uint8_t g_valuePrevious = 0;

void loop()
{
  if (g_bValueChanged)
  {
    g_bValueChanged = false;

    LED1_PORT |= LED1_PIN_bm;
    delay(40);
    LED1_PORT &= ~LED1_PIN_bm;
    delay(40);
  }

  uint8_t value = PORTB;
  if (value != g_valuePrevious)
  {
    g_valuePrevious = value;

    LED2_PORT |= LED2_PIN_bm;
    delay(40);
    LED2_PORT &= ~LED2_PIN_bm;
    delay(40);
  }
}

ISR(PCINT0_vect)
{
    g_bValueChanged = true;
}

```

# Answer
The `PORTB` register is initialized by the hardware to zero. You never write to this register, so it always stays zero.

Maybe you are mixing up `PORTB` and `PINB`:

* `PORTB` is the port **output** register, controlled by you
* `PINB` is the port **input** register, for which the bits corresponding to input pins are controlled by whatever drives those pins from the outside.
> 4 votes

---
Tags: atmega328, pins
---


# Question
Title: Teensy 4.1 / 4.0 When to use FlexPWM vs QuadTimer pins to strobe LEDs
I want to strobe 3 LEDs (at independent frequencies and duty cycles) via mosfets with a duty cycle of 0.05%-1% at a frequency range of 24-100 hz. I would like to hold 1% or better accuracy for both duty cycle and frequency.

The Teensy 4.x seems perfect with its amazing PWM frequency and resolution controls, and generous number of independent PWM timers.

1. For the purposes of my application, should I use pins with FlexPWM or QuadTimer? Does it matter?
2. I see that the numbering convention is X.Y, is there any functional significance when X numbers are in common (IE FlexPWM 1.0 and FLexPWM 1.1)?

See "Frequency" section of this page

# Answer
> 1 votes
I had cross-posted, and Paul Stoffregen answered in the Teensy Forum. Pasting Paul's great answer here for posterity:

> 1: Really doesn't matter for 0.05% accuracy.
>
> 2:See "PWM Frequency" on this page.
>
> The 3 pins identified as "FlexPWM1.0" (1, 44, 45) will always run at the same frequency. If you want different PWM frequency, you would need to choose pins from different groups.
>
> More detail on how the hardware actually works can be found in the reference manual. But usually that ends of being far too much information. The timers are packed with a mind boggling number of advanced features, which makes a steep learning curve if you want to dive into how the hardware really works.
>
> Most applications work fine by simply using analogWrite, analogWriteResolution and analogWriteFrequency. Everything you've said sounds like a pretty simple application that can be done easily with these 3 functions. You're only looking for 9 bit resolution from hardware than is natively 15 or 16 bits. Just use the easy functions do the low-level work for you.

---
Tags: pwm, timers, hardware, teensy
---


# Question
Title: USB serial port no longer detected after successful upload
I successfully uploaded a sketch to my Arduino Micro using the USB serial port but if I try to change the sketch that port is not available. The sketch I uploaded on the Micro runs fine when I plug in the USB cable. The ports shown are /dev/cu.Bluetooth-Incoming-Port and /dev/cu.wlan-debug. If I plug in a different chip the port is there. What would cause it to disappear for the Micro?

# Answer
> 1 votes
Problem fixed by following suggestion from namakada81 "Open an empty arduino sketch, select the pro micro and no port, click upload and as soon as the ide says "uploading" reset the arduino

---
Tags: serial, arduino-micro
---


title: Stopwatch stop/start button and reset

text:
# Question
Title: Stopwatch stop/start button and reset
i am trying to make a stop watch with a stop/start button and a reset button

i have made this

```
#include "RTClib.h"
//Setup the Real Time Clock, DS3231
RTC_DS3231 rtc;

const byte SQWinput = 2;  // Must be External Interrupt

volatile uint32_t  MillisecondsAtStartOfSecond = 0;

 unsigned long secondss=0 ;
 unsigned long minutess=0 ;

 unsigned long  hourss =0;
 unsigned long ms;

boolean passed_second=true;
boolean start=true;

const byte ledPin = 13;

const byte startButton = 7;

const byte resetButton = 3;
// Instantiate another Bounce object

const char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// The SQW pin, when set to 1 Hz mode, has a falling edge at the beginning of every second.
void SQWFallingISR()
{
  MillisecondsAtStartOfSecond = millis();
}

void setup ()
{
  Serial.begin(9600); // Set Serial Monitor to 115200
  delay(200);

  pinMode(7, INPUT);
  digitalWrite(7, HIGH);
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);

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

  if (rtc.lostPower())
  {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2022, 4, 03, 21, 14, 0));
  }

  // Configure SQW pin on the DS3231 to output a 1Hz squarewave
  rtc.writeSqwPinMode(DS3231_SquareWave1Hz);

  // Get MillisecondsAtStartOfSecond on the falling edge of SQW.
  attachInterrupt(digitalPinToInterrupt(SQWinput), SQWFallingISR, FALLING);
}

void loop ()
{
  DateTime now = rtc.now();

    ms = millis();

  noInterrupts();
  // How long since the second started?

  ms -= MillisecondsAtStartOfSecond;
  interrupts();

  if(digitalRead(7) != HIGH)   //START BUTTON
{    displayTime (now, ms);
     Serial.println("stopwatch  ");

  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
}

 if(digitalRead(3) != HIGH)   //RESET BUTTON
{
     Serial.println("stopwatch  ");

  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.println(0);
  ms=0;
}
 // displayTime (now, ms);
  /*Serial.println("stopwatch  ");

  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
  Serial.println("*********************************");
  Serial.println("Clock & Date  ");*/

  }

void displayTime(DateTime &now, unsigned long ms)
{
  ms = ms % 1000;  // Ignore full seconds

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  if (now.minute() < 10)
    Serial.print('0');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  if (now.second() < 10)
    Serial.print('0');
  Serial.print(now.second(), DEC);
 // Serial.println();
  Serial.print(':');
  if (ms < 100)
    Serial.print('0');
  if (ms < 10)
    Serial.print('0');
  Serial.print(ms, DEC);
  Serial.println();
  Serial.println("*********************************");

  if(ms>998) {
      secondss++;

  }
    if(secondss>59) {
     secondss=0;
      minutess++;

    }
    if(minutess>59) {
     minutess=0;
      hourss++;}

    }

```

but it is not working properly

the time is not incrementing after ms reaches 999

what is causing this?

# Answer
This code is quite confusing, as you are using both `millis()` and an RTC as time sources.

Your problem may come from here:

```
ms -= MillisecondsAtStartOfSecond;

```

If the internal clock of your Arduino is a bit off, it may happen that an RTC second is only 999 milliseconds from `millis()`. If that happens, then `ms` will never hit 999, and will instead go straight from 998 to 0.

Or maybe it's here:

```
ms = ms % 1000;  // Ignore full seconds
// ...
if (ms > 998) {
    secondss++;
}

```

If you sketch is busy (maybe it is communicating with the RTC), it may not run this code precisely at millisecond 999. And 999 is the only value of `ms` that can possibly increment `secondss`.

For a stopwatch, you don't really need the RTC data. You can implement it entirely on the basis of `millis()`, and that would simplify things:

```
bool stop_watch_running;
uint32_t stop_watch_last_update;
uint16_t stop_watch_ms;
uint8_t stop_watch_s;
uint8_t stop_watch_min;
uint8_t stop_watch_h;

void stop_watch_reset() {
    stop_watch_running = false;
    stop_watch_ms = 0;
    stop_watch_s = 0;
    stop_watch_min = 0;
    stop_watch_h = 0;
}

void stop_watch_start() {
    stop_watch_last_update = millis();
    stop_watch_running = true;
}

// Call this periodically.
void stop_watch_update() {
    if (!stop_watch_running)
        return;
    uint32_t now = millis();
    stop_watch_ms += now - stop_watch_last_update;
    stop_watch_last_update = now;
    while (stop_watch_ms >= 1000) {
        stop_watch_ms -= 1000;
        stop_watch_s++;
        if (stop_watch_s >= 60) {
            stop_watch_s = 0;
            stop_watch_min++;
            if (stop_watch_min >= 60) {
                stop_watch_min = 0;
                stop_watch_h++;
            }
        }
    }
}

void stop_watch_stop() {
    stop_watch_update();
    stop_watch_running = false;
}

```

If you know a bit about C++ classes, you may want to turn this into a class, and replace the `stop_watch_` prefix with `StopWatch::`.
> 4 votes

---
Tags: arduino-uno, interrupt, timers
---


title: MPU6050 does not give output

text:
# Question
Title: MPU6050 does not give output
I need help getting my MPU 6050 to actually give me data. As of right now, my program is only reading 0s from the gyroscope and when I move it, the values all go to -1 and the program just stops until I close and reopen the serial monitor. I know this question has been asked multiple times before, but I've already looked at each of those questions and tried all of the fixes listed there, but not a single one has worked. The I2C scanner does find the sensor at 0x68, but that's only thing that works. These are all brand new boards that I got a couple days ago.

I've tried every library and every example sketch I could find. I've switched to 2 new boards. I've even tried looking at the datasheet for the MPU 6050 and reading/writing the registers directly and still I'm getting no results. The serial monitor either stays blank, shows only 0s or -1s, or just gives me garbage values that change randomly. Please help me.

I've wired the sensor like this (I'm currently on an Arduino Uno):

VCC ==\> 5V
GND ==\> GND
SCL ==\> A5
SDA ==\> A4
AD0 ==\> digital 13 (set to LOW)

And the code I'm using is this:

```
#include <Wire.h>

const int addressPin = 13;

int gyroX, gyroY, gyroZ;

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

  //designating pins as I/O
  pinMode(addressPin, OUTPUT);

  //setting IMU address to 0x68 (LOW)
  digitalWrite(addressPin, LOW);

  initializeSensor();
}

void loop() {
  readGyro();

  Serial.print(gyroX);
  Serial.print("    ");
  Serial.print(gyroY);
  Serial.print("    ");
  Serial.println(gyroZ);
}

void initializeSensor() {
  //performing full device reset, disables temperature sensor, disables SLEEP mode
  Wire.beginTransmission(0x68);

  Wire.write(0x6B);
  Wire.write(0b10001000);

  Wire.endTransmission();

  //writing to gyro config register
  Wire.beginTransmission(0x68);

  Wire.write(0x1B);
  Wire.write(0b00001000);

  Wire.endTransmission();
}

void readGyro() {
  //requesting data from gyro data registers
  Wire.beginTransmission(0x68);

  Wire.write(0x43);

  Wire.endTransmission();

  Wire.requestFrom(0x68, 6);

  gyroX = Wire.read()<<8|Wire.read();
  gyroY = Wire.read()<<8|Wire.read();
  gyroZ = Wire.read()<<8|Wire.read();
}

```

P.S. I few weeks ago I posted a question about I2C devices and in it, I said I had managed to successfully read data from the sensor, but I found out later those were garbage numbers. :(

# Answer
From the MPU-6000/MPU-6050 Register Map and Descriptions:

* Section 4.28, Register 107 – Power Management 1 PWR\_MGMT\_1, pages 40 to 41:

> Note:
> When using SPI interface, user should use DEVICE\_RESET (register 107) as well as SIGNAL\_PATH\_RESET (register 104) to ensure the reset is performed properly. The sequence used should be:
>
> 1. Set DEVICE\_RESET = 1 (register PWR\_MGMT\_1)
>     2. Wait 100ms
>     3. Set GYRO\_RESET = ACCEL\_RESET = TEMP\_RESET = 1 (register SIGNAL\_PATH\_RESET)
>     4. Wait 100ms
* Section 4.26, Register 104 – Signal Path Reset SIGNAL\_PATH\_RESET, page 37:

> Note: This register does not clear the sensor registers. The reset initializes the serial interface as well.
* Section 3, Register Map, page 8:

> The reset value is 0x00 for all registers other than the registers below.
>
> + Register 107: 0x40.
>     + Register 117: 0x68.

This means that the PWR\_MGMT\_1 register defaults to sleep mode after a reset so it needs to be rewritten to disable sleep mode after commanding a reset.

```
void initializeSensor()
{
  //
  // Perfrom full reset as per MPU-6000/MPU-6050 Register Map and Descriptions, Section 4.28, pages 40 to 41.
  //

  // performing full device reset, disables temperature sensor, disables SLEEP mode
  Wire.beginTransmission(0x68);  // Device address.
  Wire.write(0x6B);              // PWR_MGMT_1 register.
  Wire.write(0b10001000);        // DEVICE_RESET, TEMP_DIS.
  Wire.endTransmission();
  delay(100);                    // Wait for reset to complete.

  Wire.beginTransmission(0x68);  // Device address.
  Wire.write(0x68);              // SIGNAL_PATH_RESET register.
  Wire.write(0b00000111);        // GYRO_RESET, ACCEL_RESET, TEMP_RESET.
  Wire.endTransmission();
  delay(100);                    // Wait for reset to complete.

  // Disable SLEEP mode because the reset re-enables it. Section 3, PWR_MGMT_1 register, page 8.
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b00001000);               // SLEEP = 0, TEMP_DIS = 1.
  Wire.endTransmission();
}

```

In the following code I've:

1. Modified `readGyro()` to implement 3 states (Request, Wait, and Read) and return `true` when 6 bytes have been read from the MPU-6050.
2. Added Blink Without Delay to `loop()` to see whether the MCU freezes which requires changing the ADO pin from pin 13 (the built-in led) to another pin, i.e. pin 12.
3. Added several `Serial.print()` statements for debugging to see where things go wrong.
4. Tweaked the code in response to comments.

```
#include <Wire.h>

const byte IMUAddress = 0x68;   // Added for readability and maintainability.
const byte addressPin = 12;     // Changed from 13 to 12 because 13 is built-in LED.

int gyroX, gyroY, gyroZ;

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  Serial.println(F("\n\nMPU-6050 Test\n"));

  // Designating pins as I/O.
  pinMode(addressPin, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);  // Added LED for heartbeat signal.

  // Setting IMU address to 0x68 (LOW).
  digitalWrite(addressPin, IMUAddress & 1);  // Added bit mask of bit 0.

  initializeSensor();
}

void loop()
{
  //
  // TASK 1: Blink without delay to indicate that MCU hasn't frozen.
  //
  const unsigned int INTERVAL = 250;
  unsigned long current_timestamp = millis();
  static unsigned long previous_timestamp = current_timestamp;
  static bool led_state = false;
  if (current_timestamp - previous_timestamp >= INTERVAL)
  {
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    previous_timestamp += INTERVAL;
  }

  //
  // TASK 2: Read gyro.
  //
  if (readGyro())
  {
    Serial.print(gyroX);
    Serial.print(F("    "));
    Serial.print(gyroY);
    Serial.print(F("    "));
    Serial.println(gyroZ);
  }
}

void initializeSensor()
{
  //
  // Perform full reset as per MPU-6000/MPU-6050 Register Map and Descriptions, Section 4.28, pages 40 to 41.
  //

  Serial.print(F("Performing full reset of MPU-6050..."));

  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b10001000);               // DEVICE_RESET, TEMP_DIS.
  Wire.endTransmission();
  delay(100);                           // Wait for reset to complete.

  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x68);                     // SIGNAL_PATH_RESET register.
  Wire.write(0b00000111);               // GYRO_RESET, ACCEL_RESET, TEMP_RESET.
  Wire.endTransmission();
  delay(100);                           // Wait for reset to complete.

  Serial.println(F(" Done."));

  // Disable SLEEP mode because the reset re-enables it. Section 3, PWR_MGMT_1 register, page 8.
  Serial.print(F("Disabling sleep mode of MPU-6050..."));
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b00001000);               // SLEEP = 0, TEMP_DIS = 1.
  Wire.endTransmission();
  Serial.println(F(" Done."));

  //
  // Writing to gyro config register.
  //
  Serial.print(F("Configuring gyro of MPU-6050..."));
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x1B);                     // GYRO_CONFIG register.
  Wire.write(0b00001000);               // +/-500 deg/s.
  Wire.endTransmission();
  Serial.println(F(" Done."));
}

typedef enum State
{
  Request,
  Wait,
  Read
};

bool readGyro()
{
  static State state = State::Request;

  switch (state)
  {
    case State::Request:
      // Request data from gyro data registers.
      Serial.print(F("Requesting data from gyro..."));
      Wire.beginTransmission(IMUAddress);   // Device address.
      Wire.write(0x43);                     // GYRO_XOUT_H register.
      Wire.endTransmission(false);          // Restart connection, i.e. keep alive.
      Wire.requestFrom(IMUAddress, 6);      // GYRO_XOUT_H, GYRO_XOUT_L, GYRO_YOUT_H, GYRO_YOUT_L, GYRO_ZOUT_H, GYRO_ZOUT_L.
      Serial.println(F(" Done."));
      state = State::Wait;
      Serial.print(F("Waiting for data from gyro..."));
      break;

    case State::Wait:
      // Wait for data to arrive into buffer.
      if(Wire.available() < 6)
      {
        //Serial.print(F("."));
        Serial.print(F(" "));
        Serial.print(Wire.available());  // Added to show bytes received.
      }
      else
      {
        Serial.print(F(" "));
        Serial.print(Wire.available());  // Added to show bytes received.
        Serial.println(F(" Done."));
        state = State::Read;
      }
      break;

    case State::Read:
      // Read data from gyro registers.
      Serial.print(F("Reading gyro data..."));
      gyroX = Wire.read() << 8 | Wire.read();
      gyroY = Wire.read() << 8 | Wire.read();
      gyroZ = Wire.read() << 8 | Wire.read();
      Serial.println(F(" Done."));
      state = State::Request;
      return true;  // Indicate data was received.
      break;
  }

  return false;  // Indicate no data received yet.
}

```

**Update based upon RowanP's answer**

While concentrating on the software issues I missed a crucial piece of information from the other datasheet (MPU-6000/MPU-6050 Product Specification), i.e. the electrical characteristics in Sections 6.3 and 6.4 on pages 14 and 15 showing a Vdd range of 2.375 V to 3.46 V:

**6.4 Electrical Specifications, Continued**

This will require level shifters on the signals between the 3.3 V MPU-6050 and the 5 V Arduino.
> 3 votes

# Answer
A while ago while figuring out I2C difficulties of my own I did some research and listed out all the failure modes and test techniques I could think of regarding I2C. See I2C protocol doesn't work properly. I routinely go through the list now to tick off the things I need to check to get a new I2C connection working, usually it's something simple (fingers crossed). Do you have access to an oscilloscpe?

(Edit) This old post seems to describe a similar problem (only getting zeros) MPU6050 doesn't work. The consensus there was that the **3.3V MPU6050 had been connected to a 5V UNO, frying the MPU6050 chip**. That sounds very like your situation.
> 3 votes

# Answer
I used 5 V from my Arduino to power the MPU6050, and it was fine. Check out: https://www.instructables.com/How-to-Make-a-Robot-Car-Drive-Straight-and-Turn-Ex/, which has very similar code.

Also, I typically avoid pin 13, since it performs some special additional function, unlike pin 2 to 12.
> 2 votes

---
Tags: arduino-uno, i2c, mpu6050
---


title: I2C protocol doesn't work properly

text:
# Question
Title: I2C protocol doesn't work properly
I am trying to make I2C Communication between NodeMCU and arduino Uno boards. However it is not working properly. It makes communication for once time when i uploaded code.

**Master Device Code(NodeMCU 1.0)**

```
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Wire.h>

HTTPClient client;

StaticJsonDocument <200> doc;

const char* ssid = "MY_SSID";
const char* pass = "MY_PASSWORD";

void setup() {
  Serial.begin(9600);
  Wire.begin(D1,D2);
  WiFi.begin(ssid,pass);
  while(WiFi.status() != WL_CONNECTED) {;}
}

void loop() {

  const char* cd = getCode();
  if(cd==nullptr) {
    Serial.println("Problem Occurred.");
    delay(10000);
    return;
  }
  //Bad code is starting...
  //Basically, sending 24 bytes of data for a Wire Transmission

  int n = strlen(cd);
  int rem = n%24; //remainder
  int quo = (n-rem)/24; //quotient

  while(quo!=0) {
    char sel[24];

    for(int i =0;i<24;i++) {
      sel[i] = cd[((((n-rem)/24)-quo)*24)+i];
    }

    Wire.beginTransmission(8);
    Wire.write(sel);
    Wire.endTransmission();
    quo-=1;
  }

  char sel[rem];

  for(int i =0;i<rem;i++) {
    sel[i] = cd[n-rem+i];
  }

  if(rem>0) {
     Wire.beginTransmission(8);
     Wire.write(sel);
     Wire.endTransmission();
  }
  //Bad code finished!

  //this is also not working.
  Wire.requestFrom(8,3);

  while(Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }

  delay(15000);
}

//get code from server.
const char* getCode() {
  client.begin("http://...");

  int res = client.GET();

  if(res<0) {
    return 0;
  }

  String root = client.getString();
  deserializeJson(doc,root);
  const char* code = doc["Liste"][0]["code"];
  return code;
}

```

**Slave Device Code(Arduino Uno)**

```
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin(8);
  Wire.onReceive(received);
  Wire.onRequest(requested);
}

void loop() {delay(200);}

void received(int bytes) {

  while (Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }

}

void requested() {
  Wire.write("abc");
}

```

**Circuit:**

D1-SDA

D2-SCL

GND-GND

# Answer
> 3 votes
You may need to do some additional research. I'm debugging some I2C problems myself at the moment. Happy to share what my research has turned up:

**Guiding Ideas - What could break?**

1. *Physical Layer*

1. Unintentionally switched connections (SDA\<\>SCL)
    2. Incorrect Pins selected on Microcontroller
    3. Pull-up Resistors
        1. Too many
            * Devices often have pull-ups installed by default. Only one set is needed per bus. Rule of parallel resistors applies to calculate effective resistance.
        2. Too big (too high resistance)
        3. Too small (too low resistance)
    4. Voltage Conversion / Mismatched devices
    5. Spikes or noise on SDA, SCL or Vcc
    6. Parasitic Capacitance
        1. wire / trace design
        2. bus too long
2. *Protocol Layer*

1. Bus Addresses incorrect / collisions
    2. No ACK received from slave (ref. TI article "Troubleshooting I2C Bus Protocol" below)
        1. Timing
        2. Missing / Unexpected SCL pulses
        3. Incomplete 8 bit block
        4. Missing Bytes
        5. False slave address
        6. Unsuccessful address change
    3. NACK signal meaning ambiguity
    4. Clock speed mismatch (should be running at the speed of the slowest slave on the bus)
    5. Blocked bus (i.e., a device has reset or dropped during transmission putting the bus into an invalid state. There is no timeout.)
    6. Multimastering (too many masters on bus?) - if more than one all must support multi-master mode
    7. Clock stretching (a slave is holding the clock low)
    8. What part of the message is missing? Is the initial ACK from the slave received?
3. *Code Layer*

1. For boards with multiple I2C ports, correctly passing the desired port to the relevant library.
    2. Use of interrupts causing timing problems
    3. Use of blocking code structures causing timing problems

**Testing Methods**

* Bus Pinging / Bus Scan (like Arduino Multi-speed scanner https://forum.arduino.cc/index.php?topic=197360)
* Connect additional devices to the bus and see which combinations work to identify the failing item
* Multimeter checks
    + Stable Vcc?
    + Common Ground?
    + (Open Drain) pull-up resistance from SDA & SCL to Vcc
* Test devices like Bus Pirate
* Oscilloscope Analysis / Decode (references below)
* Sifting out which device is causing the problem. (See Hackaday article) Put different-value resistors on the output of all chips on the bus. The low voltage values will be slightly different for each chip, allowing you to see on a scope which chip is talking at any given time, and diagnose when they’re talking over each other.
* install I2C multiplexor to seperate bus into a single connector for each device (i.e., from bus to star topology) (e.g., PCA9544A)

**References**

*I2C General*

*I2C Debug Advice*

*Oscilloscope Analysis of I2C*

# Answer
> 1 votes
A few of my tips:

1. if Arduino is powered using VIN port, the battery must STRICTLY between 7 to 12 volts, otherwise the Arduino board is unstable. Serial communication typically require good board stability
2. A capacitor (100 to 500uF) across the 5V (or 3.3V) and GND port helps to give I2C device a consistent voltage level, which is essential

---
Tags: arduino-uno, i2c, nodemcu, wire-library
---


title: Servo not moving with PIR motion sensor

text:
# Question
Title: Servo not moving with PIR motion sensor
I am working on this code to turn a servo when the PIR motion sensor detects no motion, but it is not working. Some symptoms include:

1. Servo is turning extremely slowly
2. PIR is not turning the servo
3. Servo is turning to incorrect angles

I have tried test programs, and when I type in the serial monitor, the servo turns (slowly and inaccurately) (I coded the serial monitor to do this). I have input from the PIR sensor but it is constantly high, even after waiting 2 minutes for it to initialize. My code and schematic are shown below.

My code:

```
#include <Servo.h>
Servo servo;

void setup() {
  // put your setup code here, to run once:
  servo.attach(13);
  pinMode(2, INPUT);
  Serial.begin(9600);
  Serial.println("Please wait");
  delay(60000);
}

void ifMos() {
  if (digitalRead(2) == HIGH) {
    int USER = 270;
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  int USER = Serial.parseInt();
  servo.write(USER);
  Serial.println(USER);
  ifMos();
  delay(10000);
}

```

# Answer
> firget about the servo for now ... write the simplest code that lights an LED when motion is detected – -jsotola

It worked! Thank you so much. All I had to do was add the servo library, write to the servo and upload it. Only 21 lines of code! Final code:

```
#include <Servo.h>
Servo servo;

void setup() {
  // put your setup code here, to run once:
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  servo.attach(13);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(digitalRead(2) == HIGH) {
    digitalWrite(3, HIGH);
    servo.write(270);
  }
  else {
    digitalWrite(3, LOW);
    servo.write(0);
  }
}

```

Thank you to everyone. This was my first time posting on stack exchange, and it was a huge success. Thank you again!
> 1 votes

---
Tags: arduino-mega, servo
---


title: pointing to array of chars

text:
# Question
Title: pointing to array of chars
I'm trying to pass a list of files (located in sketch) to be read using a library I write. List can have different filenames and vary in number of files.

How to pass a this array to my library?

for example:

`char *parameterFiles[3] = {"/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"};`

**EDIT\_1**

To explain more clearly what are my needs: Let's say that my library has a class name `myIOT2`. That class holds an array that contains a list of all filenames (what shown here is not all class). Those names are different from one use of the library to the other, and it might not have all 4 files ( can be also 0 files stored ).

I wish to have the flexibilty not to hard code exact filename in advance, but to pass that array as part of my sketch, as show prior to EDIT\_1.

```
class myIOT2
{
public:
const char *parameter_filenames[4] = {nullptr, nullptr, nullptr, nullptr};

};

```

# Answer
You have to pass both a pointer to the list, and the length of the list as an extra argument. The signature of the function may be something like:

```
void processFiles(const char *fileList[], int fileCount);

```

Note that `const char *fileList[]` is just a fancy way of writing `const char **fileList`. I find the former more readable, but that is completely subjective.

Here is a small test code showing this in action:

```
void processFiles(const char *fileList[], int fileCount)
{
    for (int i = 0; i < fileCount; ++i) {
        Serial.print("Processing file ");
        Serial.println(fileList[i]);
    }
}

const char *parameterFiles[3] = {
    "/myIOT_param.json",
    "/myIOT2_topics.json",
    "/sketch_param.json"
};

void setup() {
    Serial.begin(9600);
    processFiles(parameterFiles, 3);
}

void loop() {}

```

Alternatively, you may put a “sentinel” at the end of the list: a null pointer that signifies that the list ends there:

```
void processFiles(const char *fileList[])
{
    for (const char **p = fileList; *p; ++p) {
        Serial.print("Processing file ");
        Serial.println(*p);
    }
}

const char *parameterFiles[] = {
    "/myIOT_param.json",
    "/myIOT2_topics.json",
    "/sketch_param.json",
    nullptr
};

void setup() {
    Serial.begin(9600);
    processFiles(parameterFiles);
}

void loop() {}

```

---

**Edit**: Answering to EDIT\_1.

> \[My library's\] class holds an array that contains a list of all filenames

First of all, you have to decide who is responsible for storing those file names: the library or its client. When you write:

```
const char *parameterFiles[3] = {
    "/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"
};

```

you are creating 4 arrays: an array of 3 pointers named `parameterFiles`, and three arrays of characters holding the file names. Note that those 3 arrays are *anonymous*: they are not array variables. If the client code tries to pass this `parameterFiles` to your library, the array identifier will decay to a pointer, and your library will receive that pointer. What should it do with it?

1. The library could just keep a copy of the pointer. The client is then responsible for ensuring that it remains valid for as long as the library may need it. This practically implies that `parameterFiles` should be a global variable, and should not be modified once given to the library.
2. The library could make a copy of the array. Then the client is freed from this responsibility. However, it is still responsible for ensuring that the pointers that were copied from the array remain valid, i.e. that the file names stay in the same place in memory.
3. The library could copy the file names themselves. Then the client doesn't have any responsibility about keeping pointers valid.

If you choose option 2 or 3, the library will have to hold one or more arrays. You will then have to choose whether you allocate them statically, or dynamically with `new`. Dynamic allocation is more efficient when the arrays can vary greatly in length, but it can raise issues of memory fragmentation in RAM-constrained devices.

I cannot tell you which option is best: it depends on your use case. In any case, whatever you choose, you should document it: the user of the library should know whether they are responsible for keeping any pointers valid.

In the following, I will assume option 2 with static allocation. This is consistent with the code snippets in your question. Also, if the client provides the file names as string literals, then pointers to these strings remain always valid.

Here is a toy implementation of the `myIOT2` class, where the list of file names is copied by the constructor into the class:

```
class myIOT2 : public Printable
{
public:
    static const int maxFileCount = 4;

    myIOT2(const char *fileList[], int count) {
        if (count > maxFileCount)
            count = maxFileCount;  // discard extra files
        fileCount = count;
        for (int i = 0; i < fileCount; i++)
            filenames[i] = fileList[i];
    }

    size_t printTo(Print& p) const {
        size_t count = p.print(F("myIOT2["));
        for (int i = 0; i < fileCount; i++) {
            count += p.print('"');
            count += p.print(filenames[i]);
            count += p.print('"');
            if (i < fileCount - 1)
                count += p.print(", ");
        }
        count += p.print(']');
        return count;
    }

private:
    const char *filenames[maxFileCount];
    int fileCount;
};

```

Note that, the array of file names being statically allocated, there is a hard maximum on the number of files that can be stored. I made the class `Printable` only for debugging convenience.

And here is an example of this class in use:

```
const int fileCount = 3;

const char *parameterFiles[fileCount] = {
    "/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"
};

myIOT2 iot(parameterFiles, fileCount);

void setup() {
    Serial.begin(9600);
    Serial.println(iot);
}

void loop() {}

```

This test sketch prints:

```
myIOT2["/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"]

```
> 4 votes

---
Tags: array, char
---


# Question
Title: My HC-05 Bluetooth Module is not working
I have been trying to use the **HC-05 Module** with my **Arduino Uno** to control a LED, which can be turned on and off by my phone. Everything is fine when i input the values from the serial monitor. The problem **only occurs when I use my phone**. I am using a bluetooth terminal for HC-05 and it shows it connected. The **bluetooth module is conected** as its blinking slows down when I use the app.

Here's the code:

```
#define ledPin 8
int state = 0;

void setup() {
 pinMode(ledPin, OUTPUT);
 digitalWrite(ledPin, LOW);
 Serial.begin(38400); /
}

void loop() {
 if(Serial.available() > 0){ // Checks whether data is comming from the serial port
 state = Serial.read();
 }
 if (state == '0') {
 digitalWrite(ledPin, LOW);
 Serial.println("LED: OFF");
 state = 0;
 }
 else if (state == '1') {
 digitalWrite(ledPin, HIGH);
 Serial.println("LED: ON");;
 state = 0;
 }
}

```

Here's the serial monitor output;

Appreciate the Help!

# Answer
Few Points that you might want to Look into.

1. Where exactly are you connecting Bluetooth Module with Uno. Make sure you are connecting it with Rx and Tx Pin Only.
2. First make Simple Program to send some data on Serial Say "Hello World" at every 1second and make sure your Bluetooth is connected to Hardware Serial Pins only. If you receive data on phone then you are good to receive as well If not then Try below points.
3. Make sure your HC-05 Baudrate is correct. If you are not sure then try some others as well like 9600, 115200 etc.
4. Make sure Rx and Tx pins are connect with correct pins of HC-05. If you know your Baudrate then try swapping Rx Tx and it should response to you.
> 3 votes

# Answer
When switching from serial monitor to phone, did you change how the Arduino board was powered? If you power Arduino board via VIN port, then voltage across VIN and GND needs to be STRICTLY between 7 to 12 volts, otherwise the Arduino board is unstable (even if the board is on).

More tips and supporting information can be found on Step 3 of: https://www.instructables.com/How-to-Connect-HC-05-to-Windows-1011-Mac-Apple-Com/
> 0 votes

---
Tags: arduino-uno, bluetooth, hc-05
---


# Question
Title: Arduino and RF24 library: communication stops after short amount of time
I am using two Arduino Unos, NRF24L01+ transceivers, and a few components as per this site on which I am following the second tutorial on this page: Arduino Wireless Communication – NRF24L01 Tutorial.

I am using the exact code from the page as well - and have set everything up as per the diagrams, however everything stops working after a short amount of time. Usually between 15 and 30 seconds, everything stays powered but it seems like the transceivers stop communicating. A reset of the *Transmitting* board (the one with the potentiometer) will fix the problem until it again stops 15 or 30 seconds later.

Any idea what might be going on?

# Answer
> 1 votes
Your question does not provide much information to go on. Setting up as given in the tutorial is a good start, but does not guarantee that there will be no problems. It can still either be a problem due to hardware or firmware.

Firmware problems:

* The radio data may be getting corrupted after some time, which shows up as a failed radio transaction
* You inadvertently change the register settings of the radio

Hardware problems:

* There is noise interference on the radio channel you are using due to the urban environment (wifi, etc). Does the system work any better on a different channel?
* The radio drains too much power and browns out, then will revert to default settings on the IC rather than the ones set by your Arduino sketch.

# Answer
> 1 votes
There are few possible reasons:

First: If you soldered a capacitor it's capacity may bee too big , then if brownout appear radio module will not recover from it because of your big sized capacitor.

Second: it could be wrong config. use RF24\_PA\_LOW, RF24\_PA\_HIGH and RF24\_PA\_MAX but not MIN because it is not correctly supported by all RF24 modules.

Third: it could be brownout which is causing arduino board to fail (not the radio module). Then use alternative power source for radio module. But don't forget to leave ground cable of radio module connected to arduino (for data).

# Answer
> 0 votes
I had the same problem and so far I have not been able to find the reason why this happens.

Anyways my temporary solution was to make arduino go to sleep and wake up. The moment the board goes to sleep and reboots everything works great again.

Execute this code every now and then

```
#include <avr/wdt.h>

....

// enable the watchdog timer. This will wake up the board after 120ms
wdt_enable(WDTO_120MS);

// go to deep sleep
if (true)
{
  SMCR |= (1 << 2); // power down mode
  SMCR |= 1;        // enable sleep;
  __asm__ __volatile__("sleep");
}

```

I know this is not a solution but it is better than nothing like in my case.

## Edit (Solution that worked for me)

For some reason if I remove the millis() function the code keeps working.

```
    unsigned int end = millis() + 2500;
    for(int i=0; i<2000; i++) // New code
    // while (millis() < end)  // Old code stops working after 2 minutes ....
    {

```

I perform a task for 2.5 seconds that is why I was using the millis function...

# Answer
> 0 votes
I had a similar issue. I got my NRF24L01+ working for an entire day, but then it suddenly broke and I could not fix it. From my online research, there seem to be a lot of reliability issues with NRF24L01+. Eventually, I implemented my plan Z: switch NRF24L01+ for a HC-05 bluetooth module (which is really easy!!), check out: https://www.instructables.com/How-to-Connect-HC-05-to-Windows-1011-Mac-Apple-Com/ If you continue to trouble, I suggest just use HC-05, which would save you a lot headache and time.

However, the UART on HC-05 transmits data a lot slower than the SPI on NRF24L01, but I did not need the speed, so the switch was a great decision for me.

---
Tags: nrf24l01+
---


# Question
Title: Arduino Uno Analog pot values are not smooth
I have tired Arduino smoothing example but mine analog value are not staying constant even when I don't rotate the potentiometer. I am mapping the values from 0 -\> 1024 to 0-\> 100. I have tried exponential filter also but the result is same.

Values change 2 to 3 point mostly. Any idea how can I make the readings much more smooth.

# Answer
There will always be noise in the output an Analog to Digital Converter (ADC).

> An ADC converts a continuous-time and continuous-amplitude analog signal to a discrete-time and discrete-amplitude digital signal. The conversion involves quantization of the input, so it necessarily introduces a small amount of error or noise.

All one can do is mitigate the noise. Consider cleaning up your power supply. Make sure your voltage reference is well filtered. Inspect these power rails with an oscilloscope if one is available. Also consider keeping all wiring as short as possible and avoid using Bread Boards as they tend to introduce noise in sensitive circuits.

When using exponential averaging consider the equation / code can be modified easily to accommodate very noisy signals at the sacrifice of responsiveness. If the application can tolerate the delay, the decay of historical samples can be lowered such that what most consider noise can be filtered out. One can do this by picking very small values for alpha in the following equation found on wikipedia.org:
> 3 votes

---
Tags: arduino-uno, analogread
---


title: What does the .ino file extension mean

text:
# Question
Title: What does the .ino file extension mean
**What does the `.ino` file extension mean?**

We have `.cpp` meaning C++, `.py` meaning Python, `.exe` meaning executable and so-on.They're obvious. The `.pde` file type that sketches previously used, I think, comes from *processing development environment* (the arduino IDE being based\* on / inspired by processing). But what does `.ino` mean?

There's plenty that explains what such files are, but nothing explains what those three letters mean, if anything.

<sub>* source wikipedia</sub>

# Answer
> 3 votes
> Ardu***ino***

That's all there is to say about that really.

---

As commented in the source code

> The file extension for sketches has changed from .pde to .ino, to avoid conflicts with the Processing software ("ino" are the last three letters in "Arduino").

# Answer
> 3 votes
"Arduino" is an Italian word, and "ino" is the suffix which lends itself well to a filename extension.

From Google Translate of Italian ino:

> ino
>
> 1. Suffisso alterativo di aggettivi e sostantivi; nei primi ha valore diminutivo-vezzeggiativo, talvolta con sfumatura ironica ( biondino, carino ), oppure significa appartenenza etnica ( alessandrino, cadorino ), collegamento con materie ( argentino, salino ); nei secondi, oltre ad avere valore diminutivo-vezzeggiativo ( gattino, pensierino ), indica pure un mestiere ( ciabattino, tamburino ), uno strumento o arnese o apparecchio ( cerino, lavandino ); in alcuni casi è applicato a verbi ( imbianchino, accendino ).
> 2. In chimica organica, suffisso che nella nomenclatura ufficiale indica gli idrocarburi acetilenici, cioè gli alchini ( etino ).

> 1. Alterative suffix of adjectives and nouns; in the former it has a diminutive-pet name, sometimes with an ironic tinge (blond, cute), or it means ethnic affiliation (Alexandrian, Cadore), connection with materials (Argentine, saline); in the latter, in addition to having a diminutive-pet name (kitten, little thought), it also indicates a trade (cobbler, drummer), an instrument or tool or apparatus (match, sink); in some cases it is applied to verbs (painter, lighter).
> 2. In organic chemistry, suffix that in the official nomenclature indicates acetylenic hydrocarbons, i.e. alkynes (ethin).

---
Tags: ino
---