# Question
Title: Request for help condensing code and saving memory
I'm building a final project for a class that involves playing an audio file of a wave shield every time I scan an amiibo with an RFID scanner. I'm a pretty new programmer, so I'm not very familiar with the how to best reduce DRAM usage. As such, I got the following error when I attempted to run my most recent iteration of code:

> Global variables use 2801 bytes (136%) of dynamic memory, leaving -753 bytes for local variables. Maximum is 2048 bytes.

Here is my code:

```
////// WAVE SHIELD HEADERS //////
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
/////////////////////////////////

/////// LCD HEADERS /////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

//////////////////////////////////////////

////////// RFID HEADERS /////////////////
#include <SPI.h>
#include <Adafruit_PN532.h>

#define PN532_IRQ   (6)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield

Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

/////// various declarations /////////
uint8_t GLOBALUID[7];

//////////////////////////// WAVE SHIELD PORTION OF CODE ///////////////////////////////////

SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 100  // button debouncer

// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
  extern int  __bss_end;
  extern int  *__brkval;
  int free_memory;
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
  }
  return free_memory;
}

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

/////// MAIN SETUP /////////

void setup() {
  // set up serial port
  Serial.begin(115200);

  // Set the output pins for the DAC control in the wave shield.
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  // Set button outputs
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);

  // Set random seed for picking amiibo
  randomSeed(analogRead(A2));

  // initialize lcd
  lcd.init();
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);

   if (!card.init()) {
    putstring_nl("Card init. failed!");
    sdErrorCheck();
    while(1);
  }

  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);

// look for a FAT partition
  uint8_t part;
  for (part = 0; part < 5; part++) {
    if (vol.init(card, part))
      break;
  }
  if (part == 5) {
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();
    while(1);
  }

  // tell the user about what was found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?

  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!");
    while(1);
  }
}
//////////// END OF WAVE SHIELD ///////////////

////////////// FUNCTION FOR SELECTING AUDIO FILES ////////////
void playSoundClip(){

  char charUID[7];

  for(int i = 0; i < 7; i++)
    charUID[i] = GLOBALUID[i];

  Serial.println();

/*
      {"Mario",                   { 4, 79, 119, 42, 55, 60, 128 },"MARIO"},     //0
      {"Meta Knight",             { 4, 243, 209, 58, 117, 76, 128},"MK"},       //1
      {"Inkling",                 { 4, 84, 47, 218, 87, 73, 128 },"INK"},       //2
      {"Donkey Kong",             { 4, 244, 122, 98, 249, 61, 128 },"DK"},      //3
      {"Lucas",                   { 4, 7, 52, 202, 178, 73, 129 },"LUCAS"},     //4
      {"Duck Hunt",               { 4, 40, 173, 146, 84, 73, 128 },"DUCKH"},    //5
      {"Ocarina of Time Link",    { 4 163 57 114 221 76 128 },"OOTL"},          //6
      {"Breath of The Wild Link", ( 4 133 61 74 120 76 128 },"BOTWL"},          //7
      {"8-bit Link",              { 4 192 150 130 221 76 128 },"8BITL"},        //8
      {"Toon Link",               { 4, 89, 88, 226, 161, 62, 128 },"TOONL"},    //9
      {"Mr. Game and Watch",      { 4, 134, 32, 154, 85, 73, 128 },"GANDW"},    //10
      {"Falco",                   { 4, 23, 139, 178, 17, 74, 129 },"FALCO"},    //11
      {"King Dedede",             { 4, 108, 188, 242, 232, 73, 128 },"DEDEDE"}, //12
      {"Mewtwo",                  { 4, 241, 126, 202, 87, 73, 128 },"MEWTWO"},  //13
      {"Captain Falcon",          { 4, 11, 204, 178, 124, 72, 129 },"CAPF"},    //14
      {"ROB",                     { 4, 40, 208, 50, 3, 73, 128 },"ROB"},        //15
      {"PAC-MAN",                 { 4, 45, 26, 2, 114, 64, 129 },"PACMAN"},     //16
      {"Cloud",                   { 4, 107, 128, 26, 114, 64, 128 },"CLOUD"},   //17
      {"Ness",                    { 4, 107, 128, 26, 114, 64, 128 },"NESS"},    //18
      {"Ryu",                     { 4, 109, 252, 234, 33, 75, 128 },"RYU"}      //19
*/

  uint8_t amiiboNo = 0;

  if(strcmp(charUID,"479119425560128"))
    amiiboNo = 0; //Mario
  else if(strcmp(charUID,"42432095811776128"))
    amiiboNo = 1; //Meta Knight
  else if(strcmp(charUID,"484472188773128"))
    amiiboNo = 2; //Inkling
  else if(strcmp(charUID,"42441229824961128"))
    amiiboNo = 3;// Donkey Kong
  else if(strcmp(charUID,"475220217873129"))
    amiiboNo = 4;// Lucas
  else if(strcmp(charUID,"4401731468473128"))
    amiiboNo = 5;// Duck Hunt
  else if(strcmp(charUID,"41635711422176128"))
    amiiboNo = 6;// Ocarina of Time Link
  else if(strcmp(charUID,"4133617412076128"))
    amiiboNo = 7;// Breath of The Wild Link
  else if(strcmp(charUID,"419215013022176128"))
    amiiboNo = 8;// 8-bit link
  else if(strcmp(charUID,"4898822616162128"))
    amiiboNo = 9;// toon link
  else if(strcmp(charUID,"4134321548573128"))
    amiiboNo = 10;// Mr. Game and Watch
  else if(strcmp(charUID,"4231391781774129"))
    amiiboNo = 11;// Falco
  else if(strcmp(charUID,"410818824223273128"))
    amiiboNo = 12;// king dedede
  else if(strcmp(charUID,"42411262028773128"))
    amiiboNo = 13;// Mewtwo
  else if(strcmp(charUID,"41120417812472129"))
    amiiboNo = 14;// Captain Falcon
  else if(strcmp(charUID,"44020850373128"))
    amiiboNo = 15;// ROB
  else if(strcmp(charUID,"44526211464129"))
    amiiboNo = 16;// Pacman
  else if(strcmp(charUID,"424913721823376128"))
    amiiboNo = 17;// Cloud
  else if(strcmp(charUID,"41071282611464128"))
    amiiboNo = 18;// Ness
  else if(strcmp(charUID,"41092522343375128"))
    amiiboNo = 19;// Ryu

  Serial.println(amiiboNo);

  uint8_t clipNo = random(3);

  switch(amiiboNo){
    case 0:
      if(clipNo == 0)
        playComplete("MARIO01.WAV");
      else if(clipNo == 1)
        playComplete("MARIO02.WAV");
      else if(clipNo == 2)
        playComplete("MARIO03.WAV");
      break;
    case 1:
      if(clipNo == 0)
        playComplete("MK01.WAV");
      else if(clipNo == 1)
        playComplete("MK02.WAV");
      else if(clipNo == 2)
        playComplete("MK03.WAV");
      break;
    case 2:
      if(clipNo == 0)
        playComplete("INK01.WAV");
      else if(clipNo == 1)
        playComplete("INK02.WAV");
      else if(clipNo == 2)
        playComplete("INK03.WAV");
       break;
    case 3:
      if(clipNo == 0)
        playComplete("DK01.WAV");
      else if(clipNo == 1)
        playComplete("DK02.WAV");
      else if(clipNo == 2)
        playComplete("DK03.WAV");
       break;
    case 4:
      if(clipNo == 0)
        playComplete("LUCAS01.WAV");
      else if(clipNo == 1)
        playComplete("LUCAS02.WAV");
      else if(clipNo == 2)
        playComplete("LUCAS03.WAV");
       break;
    case 5:
      if(clipNo == 0)
        playComplete("DUCKH01.WAV");
      else if(clipNo == 1)
        playComplete("DUCKH02.WAV");
      else if(clipNo == 2)
        playComplete("DUCKH03.WAV");
       break;
    case 6:
      if(clipNo == 0)
        playComplete("OOT01.WAV");
      else if(clipNo == 1)
        playComplete("OOT02.WAV");
      else if(clipNo == 2)
        playComplete("OOT03.WAV");
       break;
    case 7:
      if(clipNo == 0)
        playComplete("BOTWL01.WAV");
      else if(clipNo == 1)
        playComplete("BOTWL02.WAV");
      else if(clipNo == 2)
        playComplete("BOTWL03.WAV");
       break;
    case 8:
      if(clipNo == 0)
        playComplete("8BITL01.WAV");
      else if(clipNo == 1)
        playComplete("8BITL02.WAV");
      else if(clipNo == 2)
        playComplete("8BITL03.WAV");
       break;
    case 9:
      if(clipNo == 0)
        playComplete("TOONL01.WAV");
      else if(clipNo == 1)
        playComplete("TOONL02.WAV");
      else if(clipNo == 2)
        playComplete("TOONL03.WAV");
       break;
    case 10:
      if(clipNo == 0)
        playComplete("GANDW01.WAV");
      else if(clipNo == 1)
        playComplete("GANDW02.WAV");
      else if(clipNo == 2)
        playComplete("GANDW03.WAV");
       break;
    case 11:
      if(clipNo == 0)
        playComplete("FALCO01.WAV");
      else if(clipNo == 1)
        playComplete("FALCO02.WAV");
      else if(clipNo == 2)
        playComplete("FALCO03.WAV");
       break;
    case 12:
      if(clipNo == 0)
        playComplete("DEDEDE01.WAV");
      else if(clipNo == 1)
        playComplete("DEDEDE02.WAV");
      else if(clipNo == 2)
        playComplete("DEDEDE03.WAV");
       break;
    case 13:
      if(clipNo == 0)
        playComplete("MEWTWO01.WAV");
      else if(clipNo == 1)
        playComplete("MEWTWO02.WAV");
      else if(clipNo == 2)
        playComplete("MEWTWO03.WAV");
       break;
    case 14:
      if(clipNo == 0)
        playComplete("CAPF01.WAV");
      else if(clipNo == 1)
        playComplete("CAPF02.WAV");
      else if(clipNo == 2)
        playComplete("CAPF03.WAV");
       break;
    case 15:
      if(clipNo == 0)
        playComplete("ROB01.WAV");
      else if(clipNo == 1)
        playComplete("ROB02.WAV");
      else if(clipNo == 2)
        playComplete("ROB03.WAV");
       break;
    case 16:
      if(clipNo == 0)
        playComplete("PACMAN01.WAV");
      else if(clipNo == 1)
        playComplete("PACMAN02.WAV");
      else if(clipNo == 2)
        playComplete("PACMAN03.WAV");
       break;
    case 17:
      if(clipNo == 0)
        playComplete("CLOUD01.WAV");
      else if(clipNo == 1)
        playComplete("CLOUD02.WAV");
      else if(clipNo == 2)
        playComplete("CLOUD03.WAV");
       break;
    case 18:
      if(clipNo == 0)
        playComplete("NESS01.WAV");
      else if(clipNo == 1)
        playComplete("NESS02.WAV");
      else if(clipNo == 2)
        playComplete("NESS03.WAV");
       break;
    case 19:
      if(clipNo == 0)
        playComplete("RYU01.WAV");
      else if(clipNo == 1)
        playComplete("RYU02.WAV");
      else if(clipNo == 2)
        playComplete("RYU03.WAV");
       break;

    }
}

//////// MAIN LOOP /////////
void loop() {

      lcd.print("Scan an");
      lcd.setCursor(0,1);
      lcd.print("amiibo!");
      delay(3000);

    uint8_t * ID{};

    waitForRFID();

    playSoundClip();

}

//////////////// MORE WAVE SHIELD ///////////////////////

// Plays a full file from beginning to end with no pause.
void playComplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.println(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }

  // ok time to play! start playback
  wave.play();
}

/////////////// END OF WAVE SHIELD //////////////////////

//////////////// RFID FUNCTION /////////////////////////
uint8_t* waitForRFID(){
    nfc.SAMConfig();

  Serial.println("Waiting for an amiibo ...");

  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
  uint8_t uidLength;
  uint8_t testuid[7];
  while(true){
    if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)){

      Serial.print("Hex UID: ");
      nfc.PrintHex(uid, uidLength);
      Serial.print("Octal UID: { ");
      for(int i = 0; i < uidLength; i++){
        Serial.print(uid[i]);
        GLOBALUID[i] = uid[i];
        if (i != uidLength - 1)
          Serial.print(", ");
      }
      Serial.println(" }");

      Serial.print("GLOBALUID: ");
      for(int i = 0; i < 7; i++)
        Serial.print(GLOBALUID[i]);

      Serial.println();
      Serial.println();
    }
    return testuid;
  }

}

//////////////// END OF RFID FUNCTION /////////////////

```

My first guess for what may be taking up the most memory is the switch statement. When I uncomment that, the memory usage jumps from 90% to over 130%. I've tried other ways to get this code to work, like concatenating text, but this is the only way that seemed to work reliably, until I ran out of memory.

I'm also using a lot of libraries to help use the shields and LCD I have attached to the Uno. I couldn't get rid of those libraries without compromising the project.

Other than that, I don't know what to do. If anyone has any suggestions for condensing the code down, I'd really appreciate any advice you have to offer.

Thanks.

# Answer
You have a huge `switch...case` here to decide the name of the file that should be played. This costs a lot of code space, but also data space, because every single literal string in this portion of code gets copied to RAM during initialization.

There is no need to spend all this cost, as the file names have been assigned in a very regular fashion, so you can build the file name *algorithmically*. As a general rule, whenever you find yourself programming by copying, pasting, then applying some predictable modifications to the copies, you are almost certainly doing something wrong. Making repeated copies of the same thing, with predictable changes is what computers are best for. So you have to ask yourself how you can instruct the computer (in this case, the Arduino) to do that for you. Do not do the computer's job yourself!

In this case, the file name is built by gluing three pieces together:

* a prefix that depends on `amiiboNo`
* a two-digit number between `"01"` and `"03"`, depending on `clipNo`
* the constant suffix `".WAV"`

The prefix cannot be computed algorithmically, so you still have to write down all the possible prefixes. You could use a big `switch...case` for this, but it is way more convenient to pick the right prefix from an array indexed by `amiiboNo`:

```
const char *file_prefixes[] = {
    "MARIO", "MK",    "INK",    "DK",    "LUCAS", "DUCKH",  "OOT",
    "BOTWL", "8BITL", "TOONL",  "GANDW", "FALCO", "DEDEDE", "MEWTWO",
    "CAPF",  "ROB",   "PACMAN", "CLOUD", "NESS",  "RYU"
};

```

Then, you declare an array of `char` for holding the file name, and you build that file name by putting together the three pieces listed above. Your whole `switch...case` can then be replaced by this:

```
char filename[13];           // longest file name: 12 characters + NUL
char file_number[3] = "01";  // 2 digits + NUL
file_number[1] += clipNo;    // file_number: "01", "02" or "O3"
strcpy(filename, file_prefixes[amiiboNo]);
strcat(filename, file_number);
strcat(filename, ".WAV");
playComplete(filename);

```

This will already save you a lot of RAM, but probably not enough. I did not see any obvious inefficient use of variables in your program (but I did not look in too much detail), so we will continue to aim at literal strings.

The problem with literal strings is the fact that they get copied from flash to RAM during initialization, and whereas you probably have enough flash, the RAM is in short supply. This is a problem specific to Harvard architectures, as they have separate address spaces for code and data. We can use some AVR-specific tricks to instruct the compiler not to perform this copying. This makes it harder to access the data because C++ does not natively know about address spaces. Fortunately, there are some macros and helper functions that can make it easy in specific cases.

The best know such helper in Arduino world is the `F()` macro. Use it every time you `print()` or `println()` a literal string, as in:

```
Serial.println(F("Waiting for an amiibo ..."));

```

Next, we have to get rid of the very long list of numeric UIDs. For this, we use the `PSTR()` macro and `strcmp_P()` function provided by the avr-libc. Replace every line that looks like

```
if (strcmp(charUID, "479119425560128"))

```

by something like

```
if (strcmp_P(charUID, PSTR("479119425560128")) == 0)

```

Note that the value returned by `strcmp_P()` has to be compared to `0`, as this is what that function, just like `strcmp()`, returns in case of equality. Thanks to timemage for noticing this issue.

Last, we could also keep all the file prefixes in flash, but this would be trickier. For now, I suggest you apply the tricks described here and see whether they are enough to make your program fit.

**Edit**: more on the somewhat obscure statement: `file_number[1] += clipNo;`

In C++, a `char` is an 8-bit number. Depending on the platform, it can be either signed (range: −128…+127) or unsigned (0…255). The name comes from the fact that it is most often used to store the numeric value of an ASCII character. For example, the numeric value 33 means `'!'`, 48 means `'0'`, and 65 means `'A'`.

The definition

```
char file_number[3] = "01";

```

creates a 3-cell array initialized with the following content:

```
             ┌─────┬─────┬─────┐
file_number: │  48 │  49 │   0 │
             └─────┴─────┴─────┘

```

Using the language notation for characters, the contents could also be written as follows:

```
             ┌─────┬─────┬─────┐
file_number: │ '0' │ '1' │ '\0'│
             └─────┴─────┴─────┘

```

The last cell with the ASCII NUL is there to inform library functions such as `strcat()` that this is where the string of characters ends.

The statement

```
file_number[1] += clipNo;

```

accesses the second element of the array (array indexing starts at 0) and increments its numeric value by the amount of `clipNo`. For example, if `clipNo` is 1, then the value in the middle cell will be changed from 49 (i.e. `'1`') to 50 (i.e. `'2'`). This relies on the fact that ASCII digits have consecutive numeric values, which would also be expected from any sane character encoding.
> 11 votes

# Answer
As a minor addendum to Edgar Bonet's excellent answer, you could simplify your code further and save even more memory by renaming your files.

In particular, instead of storing a list of character names indexed by Amiibo number and using those as the filename prefix, why not use the Amiibo numbers directly? That is, instead of your files being named

> `MARIO01.WAV`, `MARIO02.WAV`, `MARIO03.WAV`, `MK01.WAV`, `MK02.WAV`, `MK02.WAV`, etc.

you could just name them e.g.

> `AMI01_01.WAV`, `AMI01_02.WAV`, `AMI01_03.WAV`, `AMI02_01.WAV`, `AMI02_02.WAV`, `AMI02_03.WAV`, etc.

and construct the name in your code e.g. like this:

```
char filename[13];
int len = snprintf(filename, sizeof(filename), "AMI%02d_%02d.WAV", amiiboNo + 1, clipNo + 1);
if (len < 0 || len >= sizeof(filename)) {
  // TODO: handle error or insufficient buffer size here
}

```

The main advantage here is that you'll save memory by not having to store the list of character names. The tradeoff, of course, is that your filenames will now be a lot less descriptive.

You could probably optimize this a bit more by manipulating the bytes of the filename directly like Edgar does. But personally I'd suggest starting with the generic `snprintf` based solution and only switching to direct byte manipulation if it's still too much. At least I'd assume that the `snprintf` implementation in the standard library is probably going to be fairly well optimized for a low footprint. Of course I could be wrong.
> 4 votes

# Answer
Just a SWAG try switching from a UNO to a MEGA the code should work once the decelerations are fixed. What the compiler is not telling you is how much memory is actually used. You have the Heap and Stack etc.
> 1 votes

---
Tags: arduino-uno, lcd, rfid, memory-usage
---


# Question
Title: Sending multiple data with SPI interface monitored by an Osciloscope
I have multiple 32-bit data stored in an array, and I want to sequentially send them by SPI interface. I want to check that my code is correctly sending data by SPI interface, so I upload the code and connect my Linkit7697 to an oscilloscope. The expecting waveform is like this:

But it turns out to be like this:

It seems that all data are composited together in every 32 bits. What's wrong? Any idea?

Here is my code:

```
#include <SPI.h>

#define SPI_MOSI (11)
#define SPI_MISO (12)
#define SPI_CS (10)
#define SPI_CLK (13)

uint32_t test[]={
  0xF0000000,   //11110000000000000000000000000000
  0x00F00000,   //00000000111100000000000000000000
  0x0000F000,   //00000000000000001111000000000000
  0x0000000F    //00000000000000000000000000001111
  };

int i = 0;

void setup() {
  digitalWrite(SPI_CS,HIGH); //Set slave select to high, linkit7697 is Master
  SPI.begin();
  SPI.beginTransaction(SPISettings(20000000,MSBFIRST,SPI_MODE0 ));

}

void loop() {

  for (i = 0; i < 4; i++){
    digitalWrite(SPI_CS,LOW);
    SPI.transfer(&test[i],4);
    digitalWrite(SPI_CS, HIGH);

  }

}

```

# Answer
> ```
> SPI.transfer(&test[i],4);
>
> ```

The `SPI.transfer()` transmit one byte each time and therefore expecting a pointer to a byte (i.e. uint8\_t) while you are passing in an address of an `uint32_t`. What you need to do is to cast the address of `uint32_t` into a pointer of `uint8_t` before passing it into the `SPI.transfer`.

```
uint8_t *ptr = (uint8_t *) &test;

SPI.beginTransaction(SPISettings(20000000,MSBFIRST,SPI_MODE0 ));
digitalWrite(SPI_CS,LOW);
for (i = 0; i < sizeof(test); i++) {
  SPI.transfer(*ptr++, 4);
}
digitalWrite(SPI_CS, HIGH);
SPI.endTransaction();

```

Please also note that Arduino is a little endian machine, so if you have a data as `0x41424344`, the first byte get transmitted will be `0x44`.

One more thing, it is always good to call `SPI.endTransaction()`, it free up the SPI bus to allow other SPI devices to use the data bus.
> 1 votes

---
Tags: spi
---


title: Program Nano Every using UPDI port

text:
# Question
Title: Program Nano Every using UPDI port
I have and Arduino Nano and an Arduino Nano Every. I'm doing some experiments and trying to program the Nano Every from the Nano, using the UPDI port.

I'm using tutorials like this one that does the same thing but instead of Arduino Nano Every he wants to program an ATtiny.

What I did so far:

**1. Transform Arduino Nano into a UPDI programer:**

1.1 Clone jtag2updi and open `jtag2updi.ino`. Connect Arduino Nano through USB to my computer and compile and upload jtag2updi with Arduino IDE just like any other sketch.

1.2 Connect a capacitor of 10uF between RST and GND pins of Arduino Nano

1.3 Install MegaCoreX into Arduino IDE.

**2. Program Arduino Nano Every from a UPDI:**

2.1 Connect UPDI pin from Arduino Nano Every to pin D6 of Arduino Nano with a 4.7k resistor. Connect 5V and GND of both boards.

2.2 In Arduino IDE open the Blink example and chose from the `Tools` menu the following configuration:

2.3 Compile and upload sketch.

**Error:**

And the problem is that it gives this error:

```
Arduino: 1.8.12 (Mac OS X), Board: "ATmega4809, Nano Every, Reset, BOD 2.6V, Internal 20 MHz, No bootloader"

/Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
/Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
Using board '4809' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
Using core 'coreX-corefiles' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
Detecting libraries used...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /dev/null
Generating function prototypes...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
/Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o
Compiling libraries...
Compiling core...
Using precompiled core: /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a
Linking everything together...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -Wl,--section-start=.text=0x0 -mmcu=atmega4809 -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/../arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a -L/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -lm
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.eep
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -R .eeprom /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex
chmod +x /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh
/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objdump "--disassemble --source --line-numbers --demangle --section=.text" /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.lst
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-size -A /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf
Sketch uses 814 bytes (1%) of program storage space. Maximum is 49152 bytes.
Global variables use 4 bytes (0%) of dynamic memory, leaving 6140 bytes for local variables. Maximum is 6144 bytes.
Forcing reset using 1200bps open/close on port /dev/cu.usbserial-1440
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf -v -patmega4809 -cjtag2updi -P/dev/cu.usbserial-1440 -e -Uflash:w:/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex:i -Ufuse0:w:0x00:m -Ufuse1:w:0x54:m -Ufuse2:w:0x02:m -Ufuse4:w:0x00:m -Ufuse5:w:0xC9:m -Ufuse6:w:0x06:m -Ufuse7:w:0x00:m -Ufuse8:w:0x00:m -Ulock:w:0xC5:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf"
         User configuration file is "/Users/miguelwon/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-1440
         Using Programmer              : jtag2updi
JTAG ICE mkII sign-on message:
Communications protocol version: 1
M_MCU:
  boot-loader FW version:        1
  firmware version:              6.00
  hardware version:              1
S_MCU:
  boot-loader FW version:        1
  firmware version:              6.00
  hardware version:              1
Serial number:                   00:00:00:00:00:00
Device ID:                       JTAGICE mkII
         AVR Part                      : ATmega4809
         Chip Erase delay              : 0 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 0
         StabDelay                     : 0
         CmdexeDelay                   : 0
         SyncLoops                     : 0
         ByteDelay                     : 0
         PollIndex                     : 0
         PollValue                     : 0x00
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           prodsig        0     0     0    0 no         61   61      0     0     0 0x00 0x00
           fuses          0     0     0    0 no          9    0      0     0     0 0x00 0x00
           fuse0          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse1          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse2          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse4          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse5          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse6          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse7          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse8          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           lock           0     0     0    0 no          1    0      0     0     0 0x00 0x00
           data           0     0     0    0 no          0    0      0     0     0 0x00 0x00
           usersig        0     0     0    0 no         64   64      0     0     0 0x00 0x00
           flash          0     0     0    0 no      49152  128      0     0     0 0x00 0x00
           eeprom         0     0     0    0 no        256   64      0     0     0 0x00 0x00

         Programmer Type : JTAGMKII_PDI
         Description     : JTAGv2 to UPDI bridge
         M_MCU hardware version: 1
         M_MCU firmware version: 6.00
         S_MCU hardware version: 1
         S_MCU firmware version: 6.00
         Serial number:          00:00:00:00:00:00
         Vtarget         : 5.0 V

avrdude: jtagmkII_set_devdescr(): bad response to set device descriptor command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_initialize(): Cannot locate "flash" and "boot" memories in description
avrdude: AVR device initialized and ready to accept instructions

Reading | avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_read_byte(): bad response to read memory command: RSP_NO_TARGET_POWER
avr_read(): error reading address 0x0000
    read operation not supported for memory "signature"
avrdude: error reading signature data for part "ATmega4809", rc=-2
avrdude: error reading signature data, rc=-2
avrdude: jtagmkII_program_disable(): bad response to leave progmode command: RSP_NO_TARGET_POWER

avrdude done.  Thank you.

the selected serial port
 does not exist or your board is not connected

```

# Answer
> 2 votes
I'm not sure if you ever solved this issue but for me this error was occurring because the ATmega4809 chip was not powered on. By adjusting the wiring I managed to get rid of the "RSP\_NO\_TARGET\_POWER" error.

So I would suggest double checking wiring and then use the "Upload using programmer" (in "Sketch" tool-bar menu) to upload as suggested by Juraj.

---
Tags: programming, arduino-nano, sketch
---


# Question
Title: Arduino UNO With On / Off Module Switch + Battery Advice
*So I have the following connected and the programming works fine when connect by USB*

**The Parts**

* 1 Arduino UNO
* 1 Laser Module (KEYS)
* 1 Rocker Switch Module (Standard 3 PIN)
* 2 Variation Motors (KEYS)
* 1 Speaker Module (BIG SPEAKER MODULE)
* 2 Push Button Modules (Standard 3 PIN)
* 1 SD Card Reader Module (Generic)
* 1 3V 1800 amh Battery

**The Problem 1** *I want to make an On/Off Switch but it doesn't work.*

Battery Powers The Arduino Like This: (WORKS)

https://postimg.cc/JHmTwFKc

Battery Powers The Arduino Like This: (NOT WORKING)

https://postimg.cc/V0RKzFVy

PROBLEM 1: Why doesn't this work when it does for the Nano I have here:

https://postimg.cc/SnXHfwPJ

*Secondly Here are some pictures of the setup I have*

Battery - Rocker

https://postimg.cc/KK6qfjMW

Rocker - Arduino

https://postimg.cc/hXH6y2FM

https://postimg.cc/4HJrvnCg

Wide View Of Project

https://postimg.cc/3WY5Qfkc

**The Problem 2** *I need advice on what size battery to use the project for 1-2 hours I think I need (5v,7v,9v) but would like some help with which would be best suited or any suggestions you have*

**What I think it is but need help**

1. The Wiring is wrong (but I have tested it all and its working fine)
2. The Rocker Module is passing 3V to the UNO (Not enough Power)
3. The Battery is not powerful enough (I need a bigger battery)
4. NOOB Problems as its my first project

**What I need help with**

1. What battery to use?
2. Making the On/Off switch work

Thanks for the HELP!!!

**BONUS** Here is the code used:

```
    #include <pcmConfig.h>
    #include <pcmRF.h>
    #include <TMRpcm.h>

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

    //SD card pin
    #define SD_ChipSelectPin 10
    //soundplayer object
    TMRpcm tmrpcm;

    int led = 13;
    //pin numbers
    int buttonpin = 3;
    int lazerpin = 4;
    int buttonpin2 = 5;
    int motorPin = 6;
    int motorPin2 = 7;

    //other values
    int t = 0;
    int val;
    int val2;
    int ammoUsed = 0;
    int prestate = 0;
    int prestate2 = 1;
    int canReload = 0;

    void setup()
    {
      //pin modes
      pinMode(led, OUTPUT);
      pinMode(lazerpin, OUTPUT);
      pinMode(buttonpin, INPUT);
      pinMode(buttonpin2, INPUT);
      pinMode(motorPin, OUTPUT);
      pinMode(motorPin2, OUTPUT);

      Serial.begin(9600);
      if (!SD.begin(SD_ChipSelectPin))
      {
        return;
      }
      else {
        //setup sound
        tmrpcm.speakerPin = 9;
        tmrpcm.quality(1);
        tmrpcm.setVolume(5);
        //play setup sound (user knows the gun is ready)
        playSound(0);
        tmrpcm.disable();
        tmrpcm.stopPlayback();
      }
    }

    //method to call sounds depending on the input
    void playSound(int t) {
      tmrpcm.disable();
      tmrpcm.stopPlayback();

      if (t == 0) {
        tmrpcm.setVolume(5);
        tmrpcm.play("0.wav");
        delay(2980); //time of clip
      }
      else if (t == 1) {
        tmrpcm.setVolume(6);
        tmrpcm.play("1.wav");
        delay(660); //time of clip
      }
      else if (t == 2) {
        tmrpcm.setVolume(5);
        tmrpcm.play("2.wav");
        delay(950); //time of clip
      }
      else if (t == 3) {
        tmrpcm.setVolume(6);
        tmrpcm.play("3.wav");
        delay(620); //time of clip
      }
      else if (t == 4) {
        tmrpcm.setVolume(5);
        tmrpcm.play("4.wav");
        delay(660); //time of clip
      }

      tmrpcm.disable();
      tmrpcm.stopPlayback();

      return;
    }
    void loop()
    {
      val = digitalRead(buttonpin); // check the state of the button
      val2 = digitalRead(buttonpin2); // check the state of the button

      //reload gun
      if (val2 == HIGH && prestate2 == 0 && canReload == 1)
      {
        //reset ammo and play sound with vibrate
        ammoUsed = 0;
        canReload = 0;
        digitalWrite(motorPin, HIGH); //vibrate
        digitalWrite(motorPin2, HIGH); //vibrate
        playSound(3);
        digitalWrite(motorPin, LOW);  //stop vibrating
        digitalWrite(motorPin2, LOW);  //stop vibrating
        prestate2 = 1;

      }
      else if (val2 == LOW)
      {
        //reload let go
        prestate2 = 0;
      }

      //Shooting the gun 1-4 normal. 5 is louder and longer.
      if (val == LOW) // if button is pressed, turn LED on
      {
        digitalWrite(lazerpin, LOW);
        digitalWrite(led, LOW);
        prestate = 0;
      }
      else if (val == HIGH && prestate == 0)
      {
        if (ammoUsed != 5)
        {
          ammoUsed ++;

          if (ammoUsed > 0) {
            canReload = 1;
          }
          else {
            canReload = 0;
          }

          //turn on lazer and virbate
          digitalWrite(lazerpin, HIGH);
          digitalWrite(led, HIGH);
          digitalWrite(motorPin, HIGH); //vibrate
          digitalWrite(motorPin2, HIGH); //vibrate

          //play sound
          if (ammoUsed == 5) {
            playSound(2);
          }
          else {
            playSound(1);
          }
          //after sound lazer and vibrate turn off
          digitalWrite(motorPin, LOW);  //stop vibrating
          digitalWrite(motorPin2, LOW);  //stop vibrating
          digitalWrite(lazerpin, LOW);
          digitalWrite(led, LOW);

          prestate = 1;
        }
        else {
          //no ammo just vibrate and play sound with no lazer
          digitalWrite(motorPin, HIGH); //vibrate
          digitalWrite(motorPin2, HIGH); //vibrate
          playSound(4);
          canReload = 1;
          digitalWrite(motorPin, LOW);  //stop vibrating
          digitalWrite(motorPin2, LOW);  //stop vibrating
          prestate = 1;

        }
      }

    }

```

# Answer
> 1 votes
So here is the deal (I Kinda Solved It) so I took apart a 9V battery pack with a flip switch in it..... soldered some wired to it and now it works perfectly...... haha

but I would still like the know the reason why the rocker switch module doesn't work.

the only thing I can think of is the Voltage or Amp passed from the Switch Module isn't enough to power the board (as I tried 3 different rocker switches and all acted the same)

Thanks for the help

---
Tags: arduino-uno, button, battery, switch
---


# Question
Title: Writing to partially reserved registers of sensors
I'm trying to change the range of a gyroscope I'm using and there is the following guideline:

> it is recommended to mask out (logical and with zero) reserved bits of registers which are partially marked as reserved.

I tried reading about bit masking with the bitwise operators and I feel I understand it for trying to read only certain bits, but not for writing.

For example, how would I write to the following register, masking out the 2 bits which are reserved?

# Answer
> 2 votes
You always write a whole byte when you set the register. You only need to "mask out" those bits if there's a danger that you may inadvertently set them to 1, for instance through some value over flow from other bits when combining values together to form that byte.

If you're not doing that then there's nothing to mask out. For instance if you just want to set a specific set of bits then just set that value - `0b00101001` is going to be `0b00101001` whether you mask it or not.

If you decide you *really* want to mask a value, for instance if you are writing a library and you have no control over what an end user may decide to pass to a function, then `&` (or `&=`) is your friend:

```
uint8_t val = 0x55; // 0b01010101 in binary
val &= 0b00111111; // or 0x3F if you want to use HEX
// val is now 0x15 since bit 6 has been "masked" to 0.

```

---
Tags: sensors, bit, registers
---


title: how fast does loop() run in Arduino

text:
# Question
Title: how fast does loop() run in Arduino
Hi I am using `Arduino Nano` to gamify my experience on Unity3D. I know that `Update()` in Unity3D runs every frame per second but I because I'm not an electronics guy I don't know how `loop()` function runs on Arduino.

Does it depends on number of CPU cycles(or micro processor chip in case of Arduino) or what? Please explain. I facing some lags in my game. I can fix them only if know how is loop() function running on Arduino

There ain't a lot of information about `loop()` in arduino documentation

# Answer
Loop runs as long as loop needs to run.

Instructions in a CPU run sequentially. The more instructions there are the longer it takes to run.

The more code you put in loop the longer loop will run.

There are two ways to know how long each iteration of loop will take:

1. Profiling: Actively time each iteration of loop, though be warned, the act of timing will affect the amount of time taken.
2. Cycle counting. Compile the source into assembly and total up the number of clock cycles needed for all the instructions (including calls to functions). Arduous for small loops, a gargantuan task for anything else.

Also note that many external factors can affect how long loop() takes to run - such as serial communication speed, etc.
> 11 votes

# Answer
the instructions between the end of loop() and the next run of it are a ret, jmp and a call.

You can consider the main function to be effectively:

```
void main(){

    init();
    while(1) loop();

}

```

Though in reality there is some setup done before `init()` to make `millis()` and such work.
> 3 votes

# Answer
A look at main.cpp (for avr code in my installation) in file:

```
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp

```

shows that the Arduino runs loop() alternately with serialEventRun() in an infinite loop:

```
int main(void)
{
    init();
    initVariant();
 #if defined(USBCON)
    USBDevice.attach();
#endif

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }

    return 0;
}

```

Inspection of HardwareSerial.cpp shows that serialEventRun() simply calls serialEvent(), if you have defined it in your sketch.

This means that you can write your own infinite loop within loop() perfectly safely, unless you have written serialEvent() code and are expecting it to run regularly.

This begs the question: if serialEvent() is called sequentially with loop(), will serialEvent() be called if loop() never returns? In other words, is serialEvent() interrupt-driven as well as being called when loop() returns? A quick test -see below- shows that it is **not** interrupt-driven, so the previous paragraph is true.

```
/*
  Serial Event Checker

  A sketch to see if serialEvent() is interrupt-driven.
  Will serialEvent() be called if loop() never returns?

  This code is based on Tom Igoe's SerialEvent example.

  On (at least) Arduino Uno we find that serialEvent() simply runs
  sequentially with loop().  When loop() never returns serialEvent()
  is never called.

  NOTE: The serialEvent() feature is not available on the Leonardo, Micro, or
  other ATmega32U4 based boards.

  R Symonds-Tayler 2018-02-01

  This example code is in the public domain.

*/

String inputString = "";         // a String to hold incoming data

void setup() {
  // initialize serial:
  Serial.begin(115200);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

// comment out this definition to allow loop() to return
#define INFINITE_LOOP

void loop() {
#ifdef INFINITE_LOOP
    while(1);
#endif

}

/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      Serial.print("Got: '");
      Serial.print(inputString);
      Serial.println("'");
      // clear the string:
      inputString = "";
    }
  }
}

```

This means that serialEvent() code might just as well go into your main loop() within a:

```
if(serial.available()){
   // your code here...
}

```

block.
> 2 votes

# Answer
It depends on what's in the loop. From a few clock cycles to infinite hang.
> 1 votes

# Answer
try looking up arduino functions micros() and delayMicroseconds() If you might need your loop to wait longer than 16000 microseconds then also look up the other delay() function which does milliseconds.

By the way, the internal clock is very slightly off and varies with room temperature, so don't rely on it staying synchronised to your other device without a handshake.
> 1 votes

# Answer
In this article bri\_huang made a nice experiment using an oscilloscope and simple write functions.

He calculated the speed of the loop to be 117 kHz even though the microcontroller has a 16 MHz clock.

https://learn.sparkfun.com/blog/1687
> 0 votes

---
Tags: programming, arduino-nano, c
---


title: Delay coding not working as expected

text:
# Question
Title: Delay coding not working as expected
***Added second attempt at bottom of code, Please check it, works with out lag time but never turns Vacuum off?*** This project is pretty well explained in the code description. My main problem is I need a delay for **ditialWrite(vacPin,LOW);**. With this part included the stepper doesn't react a quickly as before 2/3 sec lag, & the ACS712 current sensor does not read at all in the console screen. I have tried different operatives, statements, and relocating the code in different spots with no luck!
I think this has a simple fix, but it has alluded me!. Hope this is clear enough, any help would be appreciated.

```
/*This version works as is **EXCEPT** the Delay vac 4 sec has to be turned off. See ########### area for Problem.
/*Auto Blast gate project:  for dust collection in wood shop.
  Arduino Nano
  ACS712 current sensor
  DRV8825 stepper driver
  Nema 17 stepper
  Each tool will be monitor by a current sensor and when that analog port exceeds a given threshold
  1. Rotate the stepper to a predetermined position to align ports for that tool.
  2. After the gate is align a digital pin will drive relay to turn on Vacuum system.
      Vacuum will stay on as long as sensor exceed the threshold while tool is running.
      **When tool stops vacuum will continue for 4 seconds to clear remaining dust.**
  3. If the same tool is used next, the Stepper will remain in it's current position.
      But the vacuum system should still operate the same.
  4.  currently using buttons to simulate tools and also one ACS712 for testing  */

// defines pins numbers
const int stepPin = 3;
const int dirPin  = 2;
const int enPin  = 8;
const int vacPin = 4; //simulate Vacuum relay

int ca = 0;  //currentAngle
int na = 0;  //angle
int stepPerAngle = 5 / 9; // full step = 1.8 or could have used "*1.8"
int   numstep;
int analogValue = 0;

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

  // Sets the 3 pins as Outputs
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enPin, OUTPUT);
  pinMode(vacPin, OUTPUT); //Just added this for vac

  //set values for 2 outputs
  digitalWrite(enPin, LOW);
  digitalWrite(dirPin, HIGH);
  digitalWrite(vacPin, LOW); //just add this for vac

}

void loop() {
  int n;
 analogValue = 0;

  // Assign button degrees
  if      ( analogRead(A0) > 600) {
    analogValue = (analogRead(A0));
    Serial.print("AO = ");
    Serial.println(analogValue);
    na = 0;

  }
  else if ( analogRead(A1) > 600) {
    analogValue = (analogRead(A1));
    Serial.print("A1 = ");
    Serial.println(analogValue);
    na = 45;
  }

  else if ( analogRead(A2) > 600) {
    analogValue = (analogRead(A2));
    Serial.print("A2 = ");
    Serial.println(analogValue);
    na = 225;
  }

  else if ( analogRead(A3) > 600) {   //=tool on
  analogValue = (analogRead(A3));
    Serial.print("A3 = ");
    Serial.println(analogValue);
    na = 270;

  }

 /*###########################################################
 **this is where I need help.  The first if statement works as it should.
 when those 2 condition are met the vacPin goes high.** */

  if(analogValue > 600 && ca==na) {
    digitalWrite(vacPin, HIGH);
  }

/* **this part is not working correctly.  If the delay is remove it works as the "else if" statment reads.
  I need the delay so when a tool is stopped, the vacuum continues for a few secounds to clear remaining saw dust** */

else if (analogValue < 600) {
   delay (4000); **/*  with this on:
             the stepper does not start as quickly as before,
             the analog will not read the ACS712 sensor at all,  only the buttons*/**
    digitalWrite(vacPin, LOW);
  }

//################################################################################

  if ( ca != na ) {

  //2nd SCENARIO
  if (na - ca > 0 && na - ca <= 180)
    { digitalWrite(dirPin, HIGH);
      n = ((na - ca) * 5 / 9);
      numstep = n;
      ca = na;

    }

    //3rd SCENARIO
    else if (ca - na > 0 && ca - na > 180)
    { digitalWrite(dirPin, HIGH);
      n = ((na + 360 - ca) * 5 / 9);
      numstep = n;
      ca = na;
    }

    // 4th SCENARIO
    else if (na - ca < 0 && na - ca <= 180)
    { digitalWrite(dirPin, LOW);
      n = ((ca - na) * 5 / 9);
      numstep = n;
      ca = na;
    }

    //5th SCENARIO
    else if (na - ca > 0 && na - ca > 180)
    { digitalWrite(dirPin, LOW);
      n = ((ca + 360 - na) * 5 / 9);
      numstep = n;
      ca = na;
  }

    for (int x = 0; x < numstep; x++) {

      digitalWrite(stepPin, HIGH);
      delayMicroseconds(1000);  //speed
      digitalWrite(stepPin, LOW);
      delayMicroseconds(1000);

    }

    delay(200);
  }

}

```

#################################################

```
if(analogValue > 600 && ca==na) {
    digitalWrite(vacPin, HIGH);
  }

/* this part is not working correctly.  If the delay is remove it works as the "else if" statment reads.
  I need the delay so when a tool is stopped, the vacuum continues for a few secounds to clear remaining saw dust */

// another variation to the section in question
else if (analogValue < 600 && vacPin==HIGH) {
   delay (4000);
/*  written this way it works but never turn Vacuum off?*/
    digitalWrite(vacPin, LOW);
  }

```

# Answer
It's not exactly clear what you're trying to do, but I think you want to start the vac and start the stepper, then 4 seconds later stop the vac. The 4 second delay forces the rest of your code to wait (doing nothing) during the 4 seconds.

Look at the Arduino IDE example program, BlinkWithoutDelay. The technique used there is what you need to use instead of delays, to allow your program to manage multiple things at once. This technique is called non-blocking; any time part of your program waits for something to happen blocks the code from doing anything else until that 'something' completes.

Search for non-blocking programming to read more. There are plenty of articles on the web, including in Arduino Stack Exchange that discuss that.

Update (following your 2021-05-05, 20:48Z update):

Here is an answer I wrote to similar question in which I wrote about non-blocking programming in more detail. The short answer is that you can't use delay() when you need to monitor or control several things simultaneously. *Delays keep anything else from happening until they expire* which is what is keeping your stepper from advancing as you intended. You need to do something like:

```
if the tool is running,
  ; // do nothing
else,
  save the time;    // this is the tool-stopped time
  move the stepper; // I assume the stepper completes in < 4s
end

if the tool is stopped and the vac is running,
  if (current_time - saved_time) >= 4000,
    stop the vac;
  end;
end;
// and let loop() keep running

```

Notice that this *never waits* for the tool or the fan. It just checks quickly and often, whether something needs to be done; if so, it does it; and in any case it continues on.

Because this is in your loop function, this code runs over and over again, so eventually, when 4 seconds has passed (in the case of the vac), the vac will get stopped, but meanwhile, the stepper has been able to run and any other small tasks needing doing will have an opportunity. The important point is, your code *never hangs around waiting* for anything to happen; it just very rapidly checks everything that could need to be {started, stopped, accelerated, ...}, if/when something is ready to be done, it does it, but it moves on immediately, in either case.
> 3 votes

# Answer
I don’t know where to start but, this worked **PERFECTLY!** I need to work on stepper speed and ramp Length to smooth out, or jumpers on the DRV8825 expansion bd. Other than that, I want to understand the library! I went to the readme and it explained the thing it can do, but I don’t know how to utilize on my own. I noticed your name and written by are the same! Am I talking to a person or a company? Thanks again Thanks for everyone else that help as well and I need to study some of those solutions as well!

**MicroBahner** May 8 This would be my suggestion with MobaTools:

/\*This version works as is **EXCEPT** the Delay vac 4 sec has to be turned off. See ########### area for Problem. Auto Blast gate project: for dust collection in wood shop. Arduino Nano ACS712 current sensor DRV8825 stepper driver Nema 17 stepper Each tool will be monitor by a current sensor and when that analog port exceeds a given threshold

1. Rotate the stepper to a predetermined position to align ports for that tool.
2. After the gate is align a digital pin will drive relay to turn on Vacuum system. Vacuum will stay on as long as sensor exceed the threshold while tool is running. **When tool stops vacuum will continue for 4 seconds to clear remaining dust.**
3. If the same tool is used next, the Stepper will remain in it's current position. But the vacuum system should still operate the same.
4. currently using buttons to simulate tools and also one ACS712 for testing \*/ // suggestion with MobaTools for driving the stepper and timer fuction #include \<MobaTools.h\>

// defines pins numbers const int stepPin = 3; const int dirPin = 2; const int enPin = 8; const int vacPin = 4; //simulate Vacuum relay

const int stepPer360Degree = 200; // Number of steps for one revolution ( adjust to your needs ) MoToStepper stepper ( stepPer360Degree, STEPDIR ); MoToTimer vacTimer; // for delayed switch off const long runOnTime = 4000;

int na = 0; //angle

int analogValue = 0;

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

// Setup the stepper stepper.attach( stepPin, dirPin ); stepper.setSpeedSteps( 1000, 20 ); // sets Speed and ramplength stepper.attachEnable( enPin, 100, LOW ); // Disable after 100ms. enabled is LOW

pinMode(vacPin, OUTPUT); //Just added this for vac

//set values for 2 outputs digitalWrite(vacPin, LOW); //just add this for vac

}

void loop() { analogValue = 0;

// Assign button degrees if ( analogRead(A0) \> 600) { analogValue = (analogRead(A0)); Serial.print("AO = "); Serial.println(analogValue); na = 0;

} else if ( analogRead(A1) \> 600) { analogValue = (analogRead(A1)); Serial.print("A1 = "); Serial.println(analogValue); na = 45; }

else if ( analogRead(A2) \> 600) { analogValue = (analogRead(A2)); Serial.print("A2 = "); Serial.println(analogValue); na = 225; }

else if ( analogRead(A3) \> 600) { //=tool on analogValue = (analogRead(A3)); Serial.print("A3 = "); Serial.println(analogValue); na = 270;

}

// position stepper if needed if ( stepper.read() != na ) stepper.write( na );

// start vac if tool is on and stepper is in position if (analogValue \> 600 && !stepper.moving()) { digitalWrite(vacPin, HIGH); }

if ( vacTimer.expired() ) { // switch off vac if timer expires Serial.println( "Vac = off"); digitalWrite(vacPin, LOW); }

if (analogValue \< 600 && digitalRead( vacPin ) && !vacTimer.running()) { // start timer to switch off vac after time Serial.println( " start vac run-on-time" ); vacTimer.setTime( runOnTime ); }

} If you want to give it a try, the library can be installed by means of the library manager ( enter mobatools in the search field )
> 1 votes

---
Tags: programming, arduino-nano
---


# Question
Title: Adafruit OLED 7-pin display - Abbreviations
I can't remember for the life of me how exactly I set up this screen in previous models, partially because the references I'm using in my code have different names from the pins on the Adafruit display.

My code identifies the following digital pins for the following display pins:

```
OLED_MOSI = 12
OLED_CLK = 11
OLED_DC = 10
OLED_CS = 8
OLED_RESET = 9

```

My Arduino is then attached from the following pins to those labelled on the OLED display as:

```
12 -> SDA
11 -> SCK
10 -> DC
8 -> CS
9 -> RES
5V -> VDD
GND -> GND

```

In other words, I am interpreting the following as being equivalent:

```
RES = RESET
SCK = SCK
MOSI = SDA

```

Is there anything within the information I've provided that is wrong or may cause the screen to malfunction?

# Answer
* `DC` selects between `D`ata and `C`ommands.
* `CS` is the `C`hip `S`elect
* `SDA` is the `S`erial `DA`ta.
* `SCL` is the `S`erial `CL`ock.

These four together form what the documentation calls the "4-wire serial interface". It's not quite like SPI, owing to the presence of the `DC` pin (which is why it doesn't use SPI terminology), but close enough that SPI can be used to communicate with it.

In SPI the pin that sends data from the Arduino to the slave is known as the `MOSI` \- `M`aster `O`ut `S`lave `I`n. Some microcontrollers also call this `SDO` \- `S`erial `D`ata `O`ut, where it's "out from the master's perspective".
> 0 votes

---
Tags: adafruit, display, oled
---


# Question
Title: Struggling to understand how Bluetooth serial is related to USB on Arduino
I've recently acquired a Bluetooth module to attach to my Arduino Uno, but I'm trying to draw parallels to the standard method of communication that I'm familiar with, which seems to be just directly reading or writing to sensors through methods like digitalRead and digitalWrite, respectively. Additionally however, it seems like it's also possible to connect to a serial console, through the `Serial` class. These make sense, and I've used both individually (serial console viewed by the built-in Serial window in Arduino IDE, and serial write done through `Serial.print/println()`).

However, in the Bluetooth module I purchased (HW-10), there are pinouts that connect to the TX/RX ports, which I've currently left unconnected since I'm not using the Bluetooth module or any other serial module. My question is, once I connect these, does this completely replace the connection through USB that is currently used to interface with the Uno?

If so, I had a set of specific functionalities in mind for whether these would be "replaced" by connecting the module through the 4 pinouts (TX, RX, VCC, GND):

**1. Serial:** Can I write and access the serial monitor through the IDE by connecting to 9600 baud, both in code and in the Serial Monitor

**2. Pins:** Do these connections also allow me to write and read signals from all of the pins, including analog and digital

**3. Sending code:** Can I still send code through Bluetooth without needing a USB connection?

Apologies if this question seems really obvious or specific, I'm confused as I've read a bunch of wording saying that the Bluetooth module uses a "serial connection", when I only understood serial functionality as being a method of outputting text, not controlling the Arduino. Thanks in advance for help!

# Answer
> I don't actually know what a UART is

UART (Universal Asynchronous Receiver Transmitter) is the technical term for the communication interface, which is called `Serial` in Arduino speak. It's often called UART, because that is more precise, since there are many different communication protocols, which also work serially (meaning transferring data bits one after another in contrast to parallel, where multiple bits are transferred simultaneously), like I2C, SPI or USB. All serial protocols, but totally different from the Arduino `Serial` interface. Yes, this is a bit confusing. I guess the Arduino term `Serial` was coined to make the learning curve less steep for beginners (hiding complexity can also make things confusing unfortunately).

So UART is the same as the Arduino `Serial` interface.

> once I connect these, does this completely replace the connection through USB that is currently used to interface with the Uno?

Here it is good to know, how the USB communication works on the Uno. The microcontroller on the Uno (Atmega328p) does not have a native USB interface. So it cannot speak to USB itself. For that there is an extra microcontroller on the board (I think an Atmega32u4). This controller has a native USB interface and it acts as a USB to `Serial` bridge (it creates a virtual serial interface on the PC and translate between that and its physical `Serial`/UART interface). The Atmega328p (which you program with your code) has it's RX and TX pins connected to the RX and TX pins on the Atmega32u4, which can then translate between the `Serial`/UART protocol and the USB protocol. Thus the Atmega328p doesn't know anything about USB. I just talks via `Serial`/UART to the Atmega32u4. In fact it also doesn't know anything about bluetooth. Most bluetooth modules for Arduino are also just bluetooth-`Serial` bridges

Now you need to know, that `Serial`/UART is made for one-to-one connections. With multiple devices you can get problems, when multiple devices try to send data at the same time. I this case (BT module RX to Arduino TX and vice versa) you would get garbled data, if you try to simultaneously send data from bluetooth and USB to the Arduino. The signals would overlap on the Arduinos RX pin, corrupting the data.

That means, that you don't want to send from both interfaces. In fact it is the easiest way to just use one `Serial`/UART interface for only one device. If you leave the Serial Monitor (or any other Serial communication program) closed on the PC, the PC will not interfere with the communication. Though you need to disconnect the bluetooth module, when you write your program to the Arduino, since this is done via `Serial` and you don't want it to meddle with the data.

So in result the bluetooth module will not "replace" the connection through USB. It will be added and it is your duty to prevent data corruption.

> 1. Serial: Can I write and access the serial monitor through the IDE by connecting to 9600 baud, both in code and in the Serial Monitor

Yes. You don't need to use 9600 baud necessarily. The only requirement is, that you use the same baud number in both sketch and Serial Monitor. That number just represents the speed, that the data is send in. Both sender and receiver need to agree on the same communication speed, or the receiver will not be able to read the data. Imagine someone talking to you, but talking twice the speed with that you are able to understand the words. You will not be able to understand much, because the speaker is just too fast. Either you would need to change your hearing/understanding speed or the sender needs to change it's speaking speed, to make the two match.

9600 baud is just one of the standard baudrates, though one of the lower ones. If you need it to be faster (maybe because you are sending much data in fast succession), you might want to use a higher baudrate.

> 2. Pins: Do these connections also allow me to write and read signals from all of the pins, including analog and digital

That is up to you. `Serial`/UART is just a communication interface. How it is used is up to you. You already have seen, that it is often used to output text for a user to read over the `Serial` interface, often used as a way to debug the code by sending specific text at specific places in the code. Since that connection works in both ways, you can also program the Arduino to receive commands over `Serial`/UART and then act upon them.

Here the overlaying communication protocol comes in. `Serial`/UART just transmits a series of bytes over its two lines. It doesn't care, what these bytes mean. It can be text (for example encoded via the ASCII standard, as the Serial Monitor does), or it can be just some binary data. Also there is no concept of "messages". There are only individual bytes and you don't have control over when exactly they are sent. So to make meaningful use of `Serial`/UART you need to use an extra communication protocol on top of `Serial`/UART, that the receiver understands.

When you send text to the Serial Monitor you are the receiver. Thus you would send text (because you can understand text) and a natural way for humans to distinguish individual messages is to use a delimiter character. In normal text that can be a period, though in this field going to a new line has somewhat evolved to the standard (so the delimiter character is the newline character `'\n'`). If you read the delimiter character (either yourself on the Serial Monitor, or the Arduino in your program), that marks the end of the message. You can also use that text based approach in your Arduino program (and I would say that is the easiest way). Though you don't need to. You could also use any binary protocol on it (or even invent your own protocol).

I would suggest you look at the examples in the Arduino IDE, that involve `Serial` and maybe try some tutorials on the web. There are many of them available.

> 3. Sending code: Can I still send code through Bluetooth without needing a USB connection?

You don't need an USB connection for `Serial`/UART to work. In fact the Atmega328p, which you program on the Uno, doesn't care about the USB connection at all. It only knows `Serial`/UART.

---

I hope that gave you a good overview over that topic. When you understand these core concepts you will be able to understand the tutorials and examples on the internet.
> 3 votes

---
Tags: arduino-uno, serial
---


# Question
Title: Arduino Mega reading from external sensor Issue
I have one external sensor and I want it to be connected with Arduino. The sensor came up with a usb cable and the pin out diagram is also given in the data sheet .

When I simply connect the the cabe which came along the sensor (E322968) with no Arduino board involved, but through Arduino IDE and setting baud rate to 115200 I am able to see the output in serial monitor of the Arduino .

I want to capture this data to some variables for further manipulation. In the data sheet the pinout is specified as

Please help me get the data to Arduino variable .

What I tried is connected,

1. the RX1 or Arduino mega to the TX1 of the sensor (pin2) and
2. from Arduino VCC(5v) to VCC of the sensor :: pin(1)
3. ground to gnd of sensor, (pin5)

# Answer
> the RX1 or Arduino mega to the TX1 of the sensor (pin2) and

That will not work. These pins are for RS232, which uses the same communication protocol (UART) as the Arduino, but it uses different voltage levels. But fortunately your sensor has also RX and TX pins at TTL level (Transistor-Transistor-Logic). You want to connect these to the Arduino.

One thing to keep in mind: The sensor logic seems to work at 3.3V (voltage on the RX and TX lines). If you also want to send data to the sensor, you may need to step down the 5V of the Uno to the 3.3V of the sensor on its RX line (since 5V might damage the sensor). You can use a simple voltage divider with 2 resistors or a proper level shifter (which uses transistors) (voltage dividers limit the communication speed, though 115200baud should not be a problem).
> 1 votes

---
Tags: serial, arduino-mega, softwareserial, uart
---


# Question
Title: What is a faster alternative to parseInt()?
I'm making an LED spectrum analyzer with an Arduino Due and my PC. The audio processing is done on the PC, and then sent to the Arduino. The exact data sent is a 'coordinate', or more specifically, a number representing a particular band, and another number representing the maximum amplitude of that band. There are 11 bands. Each coordinate has a x and a y value, separated by a comma, and then sent on a new line.

This is my code as of now:

```
void loop() {
  if (Serial.available()) {
    xCoord = Serial.parseInt();
    yCoord = Serial.parseInt();
    if (xCoord != 0) {
      int r, g, b;
      for (int i = 0; i < 8; i++) {
        int fromCoordToIndex = ((xCoord - 1) * 8) + i;
        //
        //do some calculations for the color
        //
        strip.setPixelColor(fromCoordToIndex, strip.Color(r, g, b));
        strip.show();
      }
    }
  }
}

```

The problem is `parseInt` seems to be very very slow (it's not the timeout issue, it's set to 1). From what I can see, it seems to be skipping some data, so every now and then a band gets missed out. The only way I can fix this is to insert a delay between each coordinate being sent. I found that 40 ms works ok, but remember there are 11 bands, so that means about half a second to refresh the whole board, which feels like a slide show...

I've tried inputting individual characters and then using `toInt`, I've tried `parseInt` obviously, I've tried native USB (it's a Due), and I've tried fiddling with baud rates. None seems to have had any effect.

# Answer
> 2 votes
The annoying thing about `parseInt()` is not its speed, it's the fact that it relies on a timeout. If the timeout is too long, it slows you down. If it's too short, it may induce errors.

A safer way to parse the sort of messages you are using is to buffer all the incoming characters until you find a carriage return, then parse the whole line. For example:

```
// Just echo the messages with a different separator.
void parse(char *buffer)
{
    char *s = strtok(buffer, ",");
    int x = atoi(s);
    s = strtok(NULL, ",");
    int y = atoi(s);
    Serial.print(x);
    Serial.print(':');
    Serial.println(y);
}

void loop()
{
    static char buffer[BUFFER_SZ];
    static size_t lg = 0;
    while (Serial.available()) {
        char c = Serial.read();
        if (c == '\r') {        // carriage return
            buffer[lg] = '\0';  // terminate the string
            parse(buffer);
            lg = 0;             // get ready for next message
        }
        else if (lg < BUFFER_SZ - 1) {
            buffer[lg++] = c;
        }
    }
}

```

Note that you should add some error checking when you call `strtok()`.

# Answer
> 1 votes
```
#include <SoftwareSerial>
SoftwareSerial s1(5,6);

void setup {
s1.begin(9600);
s1.setTimeout(50); //sets the timeout of parseint() to 50ms

}

```

Please note that lowering the timeout too much can cause errors, i would not go below 10.

# Answer
> 0 votes
> Premature optimization is the root of all evil (or at least most of it) in programming. Donald Knuth.

I don't know how fast/slow parseInt() is. Neither do you. You have to time it first.

OK. Maybe it's really slow, but is it the slowest part of your code? Slow compared to what?

Is `parseInt` what you need? `parseInt` doesn't convert negative values and it can time-out (but still return zero ... Duh!).

If you read the whole line as a String and then parse the values, you avoid the time-out problem and you can also verify that the data is correct.

This sketch show how to process your data:

```
void setup() {
  Serial.begin(9600);
  while(!Serial);

  String lines[] = {
    "1,1",
    "10,20",
    "11,1000",
  };
  int channel;
  int value;

  for (int i=0; i < 3; i++) {
    sscanf(lines[i].c_str(), "%d,%d", &channel, &value);
    Serial.print("channel="); Serial.print(channel);
    Serial.print(" value="); Serial.println(value);
  }
}

void loop() {
}

```

Well, I'm using `sscanf`, that's slower than `parseInt` for sure, but it get the job done. I doubt you (or me) can do it better, and there more useful thing to do with our time.

Edit:

I profiled

```
sscanf("0001,0001", "%d,%d", &channel, &value);

```

with an Arduino UNO and it took 147us to convert a single par of values.

# Answer
> 0 votes
Instead of using parseint, send the data for the 11 bands in a very specific form to the Arduino so the Arduino can 'parse' it very easily.

Maybe instead of sending text, send 33 bytes for RGB (3) times 11 bands are the levels (0-255) of the consecutive channels. Than there is no conversion needed (except for reading the bytes).

# Answer
> 0 votes
Your data has 11 channels and a single value for each channel. The values will be presented in graphic format, so it fits in the range 0-255 without degrading the presentation. You always can scale your readings to your display's resolution.

You then send these 11 values in binary form. One byte per channel plus one byte to separate one data set from another. You don't need to send the channel number, just the values.

At the Arduino end you read 12 bytes and then loop thru it converting the bytes to ints.

```
#define CHANNELS 11

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

  while(!Serial);
}

void loop()
{
  char packet[CHANNELS + 1];
  int values[CHANNELS];

  // Read 12 bytes (11 bytes of data + 1 byte delimiter)
  int nBytes = Serial.readBytes(packet, sizeof(CHANNELS + 1));

  if(nBytes == CHANNELS + 1) {
    // Convert bytes to ints;
    for(int i=0; i<CHANNELS; i++) {
      values[i] = packet[i];
    }
  } else {
     // Error.
     }

  // Here you display your graph.
}

```

This code doesn't have any error-detection. For that you can add an extra byte with the checksum of the whole dataset.

# Answer
> 0 votes
I seem to have fixed it by lowering the baud rate from 115200 to 9600. This answer inspired the change. Apparently, the higher the baud the faster the information is sent, but the higher the likelihood of an error, and the lower the baud rate, the slower it is sent, but the more reliable it is.

---
Tags: serial, c++, arduino-due, time
---


# Question
Title: Inaccurate voltage readings on an esp32 as opposed to multimeter
I am working on detecting the amplitude of a signal coming from a guitar pickup. I am using an esp32 and an LM386 module for amplifying the signal.

I get quite stable readings with a multimeter, but the readings on the Arduino IDE show peaks and also peaks come when no signal should be there.

Here is a link for short videos of both the esp32 readings and the multimeter:

https://drive.google.com/drive/folders/1gpvkN\_sz627jG0TNPpUps82105EB89OF?usp=sharing

Thanks!

EDIT (Adding simple code being used) :

```
int ampedVoltagePin = 12;

void setup() {
  pinMode(ampedVoltagePin, INPUT);
  Serial.begin(9600);
}

void loop() {
  Serial.println(analogRead(ampedVoltagePin));
  delay(100);
}

```

EDIT (Adding diagram):

# Answer
> 4 votes
I see multiple problems with your setup:

* You only take a measurement every 100ms. That measurement takes the voltage during a very short time span. But the lowest string on a guitar in standard tuning has 82.41Hz (E2). You are measuring at 10Hz. According to the Nyquist–Shannon sampling theorem you need to measure at at least twice the frequency of your lowest frequency to measure. Otherwise your measured data will not have any real meaning and will not represent the input wave. So you need to measure at least with 165Hz.
* The amplifier can output voltages up to it's supply voltage, so 5V. You connect the output directly to the ESP32, which is a 3.3V device. That can damage the pin, that you are using.
* Currently you are trying to measure the signal directly. But you wrote, that you want to have the amplitude. Currently you would need to calculate that in code (for example by taking the min and max value over a time range greater than one period of the lowest frequency, so at least 12ms (1/82.4Hz)). A multimeter most likely will do that in hardware with analog electronics.
* I'm not sure if it is good to connect a speaker and the ESP in parallel. As a speaker is basically an inductor moving in a magnetic field, you might get backwards voltage induced by it. That might be harmful to the ESP. Others here might know more about that.
* You connect the Arduino ground to speaker ground. But that is most likely not the same as the amplifiers ground. Most likely the amplifier drives the speaker symmetrically, so also with negative voltages in reference to the speaker ground. That can damage the ADC of the Arduino. Also it's unclear, how good that ground actually is. That pin is not meant for grounding a microcontroller. Driving a speaker is different from measuring the voltage with an Arduino, so you would need different amplifiers to do it.

I'm not an expert in the field of analog electronics, but I guess you could use a diode to get one half-wave and then feeding it into a low pass filter. The resulting voltage is relatively steady (depending on the cut-off frequency of the filter) and can then be measured by the ESP. I'm sure, that this will only give you a rough measurement of the amplitude, but enough for typical applications like amplitude visualization. For really precise measurements you most likely need to use a more complex electronics setup to work against the non-linearities of the parts (especially the diode).

# Answer
> 0 votes
I managed to get accurate readings by following @chrisl's suggestion in the comment.

Instead of trying to get values at given points I am now averaging 500 values and the readings are as expected.

New code:

```
int ampedVoltagePin = 12;
int counter = 0;
int sumOfVoltages = 0;
int sampleSize = 500;
int average;

void setup() {
  pinMode(ampedVoltagePin, INPUT);
  Serial.begin(9600);
}

void loop() {

  sumOfVoltages += analogRead(ampedVoltagePin);

  if (counter > sampleSize -2) {
    average = sumOfVoltages/sampleSize;
    Serial.println(average);
    sumOfVoltages = 0;
    counter = 0;
  }

  counter ++;
}

```

# Answer
> 0 votes
Yes, you do need to sample at a rate at least 2x the highest harmonic you want to consider. But that's not your biggest problem.

The LM386 is normally used with an output capacitor. The chip specs say it is "self balancing", which means its output sits at half the supply voltage when there is no signal present, then swings up and down from that. The inductance of the speaker is not the issue here, it's that it has a very low DC resistance (8 ohms, typically) and you are putting it across a 2.5V DC source (the LM386 output). This not good for the amp, and it's terrible for the speaker since it is outside its normal centered operating point.

So use a big electrolytic capacitor between the LM386 and the speaker. The data sheet shows 250 uFd, but that's not critical. Note that the + pin of the capacitor must connect to the LM386 output. But the Arduino input must connect to the amp directly, as you are doing now, and you must subtract +2.5V from every reading to get an AC waveform. You can then handle that as you wish, such as by taking the absolute value and filtering (averaging with a time constant).

---
Tags: esp32, analogread
---


title: Sending a struct over i2c

text:
# Question
Title: Sending a struct over i2c
How would you send a struct from an i2c slave when requested by an i2c master?

**Slave Struct Respdonder Sketch (Seeeduino Xiao)**

```
#include <Wire.h>

struct TransmitData
{
  int a;
  int b;
  int c;
  int d;
  float e;
  float f;
  float g;
  float h;
};

TransmitData data;

void setup()
{
  Serial.begin(9600);
  Wire.begin(2);
  Wire.onRequest(requestEvent);

  data.a = 1;
  data.b = 2;
  data.c = 3;
  data.d = 4;
  data.e = 5.1;
  data.f = 6.1;
  data.g = 7.1;
  data.h = 8.1;
}

void loop()
{
  delay(100);
}

void requestEvent()
{
  Serial.print("sending ("); Serial.print(sizeof data); Serial.println(" bytes)");
  Wire.write((byte *)&data, sizeof data);
}

```

**Master Struct Requester/Reciever Sketch (Arduino MEGA)**

```
#include <Wire.h>

struct TransmitData
{
  int32_t a;
  int32_t b;
  int32_t c;
  int32_t d;
  float e;
  float f;
  float g;
  float h;
};

TransmitData data;

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

void loop() {
  Serial.print("requesting ("); Serial.print(sizeof data); Serial.print(" bytes)... ");
  if (Wire.requestFrom(2, sizeof data)) {
    Wire.readBytes((byte*) &data, sizeof data);
    Serial.println("done");

    Serial.println(data.a);
    Serial.println(data.b);
    Serial.println(data.c);
    Serial.println(data.d);
    Serial.println(data.e);
    Serial.println(data.f);
    Serial.println(data.g);
    Serial.println(data.h);
  }
  else {
    Serial.println("could not connect");
  }
  delay(500);
}

```

The serial output on the slave device is:

```
sending (32 bytes)

```

The serial output on the master device is:

```
requesting (24 bytes)... done
1
0
2
0
0.00
0.00
5.10
6.10

```

# Answer
> 2 votes
`int` isn't guaranteed to be the same size across platforms. Use fixed width integer types instead.

https://en.cppreference.com/w/cpp/types/integer

```
struct TransmitData
{
  int32_t a;
  int32_t b;
  int32_t c;
  int32_t d;
  float e;
  float f;
  float g;
  float h;
};

```

---
Tags: i2c
---


title: Code For Lighting RGB Led

text:
# Question
Title: Code For Lighting RGB Led
I am doing this simple introductory exercise to light an RGB Led, but I am confused about the code in the exercise. The following is the code:

```
/* Adafruit Arduino - Lesson 3. RGB LED
*/

int redPin = 11;
int greenPin = 10;
int bluePin = 9;

 //uncomment this line if using a Common Anode LED //#define
 COMMON_ANODE

void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);   }

void loop() {
  setColor(255, 0, 0);  // red
  delay(1000);
  setColor(0, 255, 0);  // green
  delay(1000);
  setColor(0, 0, 255); // blue
  delay(1000);
  setColor(255, 255, 0);  // yellow
  delay(1000);
  setColor(80, 0, 80);  // purple
  delay(1000);
  setColor(0, 255, 255);  // aqua
  delay(1000); }

void setColor(int red, int green, int blue) {
#ifdef COMMON_ANODE
     red = 255 - red;
     green = 255 - green;
     blue = 255 - blue;
#endif
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);   }

```

In this code, why were they able to carry out setColor before expanding upon what it means later through `void setColor(int red, int green, int blue)`? Should that portion of the code come earlier or does it matter? Also I don't quite understand how the definition of the colors red, green, and blue were defined towards the bottom. I know what 255 would indicate maximum brightness, but why do you have to subtract the color from 255? Any help would be much appreciated.

# Answer
> 1 votes
> why were they able to carry out setColor before expanding upon what it means later

You are correct in C that is the case. However the Arduino IDE adds "function prototypes" to the top of your code automatically. That means you no longer have to abide by the "define before use" of C and C++.

> I know what 255 would indicate maximum brightness, but why do you have to subtract the color from 255?

This is for if your LED is "common anode" instead of "common cathode". With a common anode LED you write a LOW to turn it on and a HIGH to turn it off - this is the exact opposite of a common cathode.

So to set the brightness of a common anode LED you need to use the opposite value, and since PWM goes from 0-255 the opposite is 255-0: 255 is off, and 0 is fully on.

---
Tags: led, rgb-led
---


title: Control laser diode from digital pin

text:
# Question
Title: Control laser diode from digital pin
I have a 200mw laser module that came with a 3v 1A power supply. I want to control it from a digital pin on an arduino uno.

Can I use a simple voltage divider like this or is there some consideration to current I'd need to take into account? The laser module was quite expensive so I'm hesitant to try it out.

simulate this circuit – Schematic created using CircuitLab

# Answer
> 2 votes
Your solution does not work, mainly because GPIOs are not intended to source current higher than a few mA. If you want the laser diode to emit a reasonable amount of power, you need to drive it with a transistor. A MOSFET-based low-side-switch would probably be the easiest solution. But note that you still need to limit the current, e.g. by using a series resistor.

Even better would be to use a constant current driver (you can use any led driver with appropriate rating).

If the power supply that came with the laser diode is a constant current source, it might be possible to switch its output directly (without resistor), but that depends on how it behaves when it is open-circuited.

---
Tags: arduino-uno
---


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

In sum my questions are:

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

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

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

---
Tags: power, switch, transistor, mosfet
---


# Question
Title: How to connect an Output to a Pullup Input of another arduino
:tldr; Could problems occur if one connects a HIGH Output of one arduino to a PULLUP\_INPUT of another while using differed power sources?

Hi I'm building some devices for a LARP Dungeon (think Escape room).

For that we have interfaces, riddles and switches(triggers). Interfaces provide access to sound/light/DMX sytems for riddles. Riddles check conditions and send state information to the interfaces.

To keep things simple, states are boolean (like riddle is solved, a critical mistake has been made,..)

I would like to use PULLUP\_INPUTs on the receiving end so I can use simple switches to GND as controls. In some cases a switch might be connected directly to an interface. Mostly there is a riddle in-between. In those cases an OUTPUT of the riddle's Arduino will be connected to the PULLUP\_INPUT of the Interface's Arduino. There will be multiple riddle Arduinos connected to one or even multiple Interfaces. Due to cable length, differed power sources etc. the potential to GND of the involved Arduinos might be differed. So I assume this difference will flow over the pullup resistor of the interfaces into their 5V. The internal PULLUP is ~20kOhms so current should not be a problem but can the voltage, which might be a little higher than the one of the input, cause problems?

Or would it be better to set the Output of a riddle Arduino to INPUT while the signal line should be HIGH so it gets a high impedance? Switching between: OUTPUT:LOW while active and INPUT while inactive.

# Answer
> 1 votes
Connecting any signal that is within the voltage range of the receiving Arduino is safe. So if you use Arduino UNOs or similar with a 5V operating level, you can connect any signal between 0 and 5V to an input. It does not matter whether the input is in pull-up-mode or not. So connecting an output to an input of another Arduino (or even of the same Arduino) is safe. In addition to the signal values, you do need to connect the ground of both Arduinos.

The only thing you must *not* do is connect two outputs together (because if one of them is high and the other is low, you have a shortcut that will potentially fry one or both of the boards). And you would need to be careful if you used different types of Arduinos, like a Uno and a Due, because they run at different voltage levels.

---
Tags: pins, communication, button, voltage-level
---


# Question
Title: Where can I know voltage between GND(ground) and each port of UNO R3?
Currently I'm new to arduino uno r3.

Where can I find each voltage between each port and GND(ground)?

Or can the voltage be changed?

I don't want to break my led bulbs since large difference of 2 potentials

# Answer
You can measure each one at the output of the port (where you plug a connecting-wire to the port). Measure from that wire to ground with your DVM. It should be either 0v or 5v, depending on whether the port is set LOW or HIGH. (Or it could be pulsing from 0v - 5v - 0v - ... , if it is one of the PWM ports and the port has been set to provide a PWM output.) If the pin is in INPUT mode (and not INPUT\_PULLUP), you're likely to read noise picked up by the connection between the pin and the meter, as an INPUT pin will be in high-impedance mode - no voltage will be asserted by the MCU, so the connection will behave almost like an un-connected wire, e.g., an antenna.
> 0 votes

# Answer
5\[V\] is ideal EMF(electromotive force) of arduino UNO R3.

Since I stated "**ideal**" ,the actual EMF be slightly lower than 5\[V\].

In this instance , EMF can be assumed as voltage between GND and port of UNO R3 as ports are connected only by a wire.
> 0 votes

---
Tags: arduino-uno, voltage
---