text:
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);

  }

}

a quick look at the library shows  transfer16 and transfer32 functions

Without fully understanding your problem description, I guess that SPI.transfer() actually will cut off everything after the lowest byte of your data element (because it expects one byte), thus only sending one byte per number. As jsotola wrote, the transfer32() function is meant for tranferring 32 bit numbers. You should use it

I've used bitwise operator to transform 32 bits data to two 16 bits data, and using SPI.transfer16() to do the transfer. I'm sure that the bitwise operator is working (Because I use serial monitor to print the result). But when I connect the Linkit7697 to the oscilloscope, it shows the waveform as I mentioned above.

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.


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

Honestly I don't see much potential for optimziation without touching the libraries. Commenting the switch case gives you that much memory, because the compiler then optimizes out all the wav playing stuff, that is only used in the switch statement. Maybe you should switch to a board with more RAM

I think you can put all the string literals in program space with the string helper, but I don't think, that this will be enough, since you want to get to maybe 75% (the compiler doesn't count all local variables I believe)

The memory usage here clearly comes from the libraries you use. The combination of SD card reader library + LCD + NFC reader seems just too big for an Arduino Uno. I'm unable to build your code, as I can't find the libraries you're using. Are these standard libraries installed trough the library manager?

nitpick: Arduino Uno has an ATmega328, which has SRAM, not DRAM. The phrase "dynamic memory" seems to mean just dynamic in a more generic sense, i.e. volatile memory used at run-time, as opposed to the non-volatile program memory that's mostly static wrt. run-time use. On the other hand, DRAM is a particular way of implementing (volatile) RAM.

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.

I know this originated in the O.P.'s code, and you I know that you know this, but strcmp(_P) returns 0 for "equal".

@timemage: Oops! You are right. I know but I didn't pay attention. I added that to the answer, just to make it more prominent.

As soon as I get the opportunity, I’ll implement these fixes and get back with you on the progress. Thank you for the help!

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.

snprintf() is a good suggestion. It will likely cost more flash than strcpy() and strcat() combined because, even if you only use %02d, the function carries support for a wide range of conversion specifiers. I do think it is a good choice, if you have enough flash (likely the case here), because it makes the code simpler. It's interface, however, may not be very novice-friendly. OTOH, my file_number[1] += clipNo; statement is probably not novice-friendly either. :-/

@EdgarBonet, as a novice, I can attest, I was a bit thrown off by the file_number[1] += clipNo; statement, haha. If you have the time, would you mind explaining what you did there?

Update: It works! After changing the string literals and file names via yours' and @EdgarBonet 's suggestions, my program sits at 84% memory. I'll probably tamper around with it a bit more to eek out some extra features. Thank you both!

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.

I’ve considered getting a Mega; it seems worthwhile. Unfortunately this is a project that’s due in a few days. I may grab it just to satiate my own curiosity though. Thanks for the suggestion.

I generally start with a larger processor such as a Mega and when finished I can put it in a smaller unit. This gives me room for the debugging print statements etc.

So, I borrowed a Mega from my professor and tried it out yesterday. As it turns out, the wave shield I'm using to read audio files and play to a speaker explicitly lists the Mega as a version of Arduino that is NOT supported, for some reason. It really sucks; I wanted to expand the scope of this project significantly, but what can you do?

source: Stack Exchange

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

sort: votes


text:
Blink LED with different on off times just once with millis
So Im having trouble trying to figure this out. My project needs a valve to stay shut and when an event is triggered, 3 seconds into that event the valve opens for 2 seconds, then remain shut till it's triggered again. I was just treating it like an LED in the code. I was trying to code it to jump from one if-statement to the next with the appropriate delays but it doesn't work the way i thought it would. Any help would be great. Thanks
//the event does ventGo0 = true;

 if(((millis() - previousVenting) > offoffDuration)&&(ventGo0==true)){
        previousVenting1 = millis();
        ventGo1=true;
        ventGo0=false;
       }

     if(((millis() - previousVenting1) > onDuration)&&(ventGo1==true)){
       digitalWrite(ventPin, HIGH);
       previousVenting2 = millis();
       ventGo2=true;
       ventGo1=false;
     }

       if(((millis() - previousVenting2) > offDuration)&&(ventGo2==true)){
         digitalWrite(ventPin, LOW);
         ventGo2=false;
       }

      ```

just a note ... if (ventGo1==true) is same as if (ventGo1)

You could use two millis() based timers.
// Sketch uses 1066 bytes (3%) of program storage space.
// Global variables use 27 bytes (1%) of dynamic memory.
// Arduino Uno, IDE 1.8.9
class MillisTimer{

  private:

    unsigned long m_timeInMilliSeconds;
    unsigned long m_previousMillis;
    byte m_timerActive;

  public:

    MillisTimer(unsigned long timeInMilliSeconds):
      m_timeInMilliSeconds(timeInMilliSeconds){
      m_timerActive = 0;
      m_previousMillis = 0;
    }

    bool Update(){
      if(m_timerActive && (millis() - m_previousMillis >= m_timeInMilliSeconds)){
        m_previousMillis += m_timeInMilliSeconds;
        return 1;
      }
      else{
        return 0;
      }
    }

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

    void ReStart(){
      m_timerActive = 1;
      m_previousMillis = millis();
    }

    byte IsActive(){
      return m_timerActive;
    }

};

// Make copies of the object to work with.
MillisTimer TwoSecondTimer(2000);
MillisTimer ThreeSecondTimer(3000);

void setup(){

  // Call this function when an event is triggered.
  ThreeSecondTimer.ReStart();

  // Timer status indicator.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

}

void loop(){

  // Call the update function as fast as possible.
  if(ThreeSecondTimer.Update()){
    digitalWrite(LED_BUILTIN, HIGH);
    ThreeSecondTimer.Stop();
    TwoSecondTimer.ReStart();
  }

  // Call the update function as fast as possible.
  if(TwoSecondTimer.Update() && !ThreeSecondTimer.IsActive()){
    digitalWrite(LED_BUILTIN, LOW);
    TwoSecondTimer.Stop();
  }

}

Great thanks Ve7jro. I put your code in my project and it works great, just what I needed. When the arduino is booted up for the first time, it does tigger the the led or in my case the valve. Is there a way to stop that from happening? Thanks

@Jason8899 _ If you update your question with the complete "sketch", I'll take a look at it for you. Keep in mind that, ThreeSecondTimer.ReStart(); in setup() starts the timer immediately, so you should remove it from setup() and add it to your code, the "event driven" part of your code.

I found the issue, thanks again.

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


text:
U-blox Neo-6M GPS module and RX LED of Arduino aren't blinking
I started recently working with a uBlox Neo 6M GPS module.
Connection between Arduino and GPS module....
Vcc pin --> 3.3V ,
Tx pin --> D2,
Rx pin --> D3,
Gnd --> Gnd

I tried with this code:
#include <SoftwareSerial.h>
// Choose two Arduino pins to use for software serial
int RXPin = 2;
int TXPin = 3;
//Default baud of NEO-6M is 9600
int GPSBaud = 9600;
// Create a software serial port called "gpsSerial"
SoftwareSerial gpsSerial(RXPin, TXPin);
void setup()
{
  // Start the Arduino hardware serial port at 9600 baud
  Serial.begin(9600);
  // Start the software serial port at the GPS's default baud
  gpsSerial.begin(GPSBaud);
}
void loop()
{
  // Displays information when new sentence is available.
  while (gpsSerial.available() > 0)
    Serial.write(gpsSerial.read());
}

About 2-3 hours, I was working with it.. But I do not get the GPS LED to blink, as well as my Arduino's RX LED. In serial monitor I didn't get any data. Is my gps module destroyed??

Are you indoor or outdoor?

your code is missing the part that sends data from the Serial to gpsSerial ... the NEO-6M gets no data

Are you sure your module will run on 3.3v ?  Some modules need 5v to run while some work on 3.3v.  Also, what Arduino board do you have ?  Most have 5v logic level pins. You must ensure that the logic level matches between module and arduino.


text:
Unknown text printing on Serial Monitor
I want to use the Serial Monitor for some debugging, but it prints something else.
Edit-
This only happens if  I use the attachInterrupt() function
I tried another program that does not use interrupts and there it works.
My code:-

/*
YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
volatile int flow_frequency; // Measures flow sensor pulses
unsigned int l_hour; // Calculated litres/hour
unsigned char flowsensor = 13; // Sensor Input
unsigned long currentTime;
unsigned long cloopTime;
void flow () // Interrupt function
{
   flow_frequency++;
}
void setup()
{
   pinMode(flowsensor, INPUT_PULLUP);
   Serial.begin(9600);
   attachInterrupt(0, flow, RISING); // Setup Interrupt
   sei(); // Enable interrupts
   currentTime = millis();
   cloopTime = currentTime;
}
void loop ()
{
   currentTime = millis();
   // Every second, calculate and print litres/hour
   if(currentTime >= (cloopTime + 1000))
   {
      cloopTime = currentTime; // Updates cloopTime
      // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
      l_hour = (flow_frequency * 60 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
      flow_frequency = 0; // Reset Counter
      Serial.print(l_hour, DEC); // Print litres/hour
      Serial.println(" Lhour");
   }
}

Data from Serial Monitor:-
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
⸮⸮⸮⸮⸮⸮ISR not in IRAM!

User exception (panic/abort/assert)
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Abort called

>>>stack>>>

ctx: cont
sp: 3ffffef0 end: 3fffffc0 offset: 0000
3ffffef0:  feefeffe feefeffe feefeffe 00000100
3fffff00:  000000fe 00000000 00000000 00000000
3fffff10:  00000000 00000000 00000000 00ff0000
3fffff20:  5ffffe00 5ffffe00 3ffef0a4 00000000
3fffff30:  00000001 00000000 3ffee34c 40201e72
3fffff40:  40100402 40202e51 ffffffff 40201e84
3fffff50:  feefeffe 00000001 3ffee34c 40202399
3fffff60:  00000000 00000001 3ffee324 4020129c
3fffff70:  00000000 feefeffe feefeffe 3ffee38c
3fffff80:  3fffdad0 00000000 3ffee34c 40202448
3fffff90:  3fffdad0 00000000 3ffee34c 40201079
3fffffa0:  feefeffe feefeffe feefeffe 40201a80
3fffffb0:  feefeffe feefeffe 3ffe84e4 40100cfd
<<<stack<<<

Why is this happening?
Hardware-ESP8266 based NodeMCU

As the error says: your ISR is not in IRAM.

@Majenko What is that supposed to mean?

An ESP8266 ISR needs the ICACHE_RAM_ATTR prefix to force it to stay resident in IRAM (so it does not need to be run from SPI flash when an interrupt occurs). Your ISR definition should be: ICACHE_RAM_ATTR void flow () { .... For an explanation: See here. Also see this StackOverflow answer.

I’m voting to close this question because it is not a real Question

Please look at the edit


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

I don't really understand, what you mean. But the Uno runs on 5V, so the maximum voltage on its pins imposed by it is 5V.

I see. I'm too new to arduino.

https://majenko.co.uk/blog/what-exactly-gpio-pin

I'll read the article.

Maybe using a voltmeter?

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.

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.

EMF (Electromotive Force)? That’s a rather odd term to use in this instance. Just voltage will do.

5V is not the EMF or Voltage of an Arduino Uno. It is the EMF or Voltage the microcontroller of the Arduino Uno (ATmega328) should be supplied with. If a digital pin is set to be high, it will have a voltage slightly under the supply voltage, depending of the amount of current that is drawn from that pin.

Oh,I see. I edited the answer.


text:
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):

And what happens, if you take the average over a longer time and show that? Because thats, what a multimeter does. My multimeter seems to average over about 500ms. Also you would need to take the min and max values before averaging to get the amplitude, since otherwise taking the average of the wave directly would mostly cancel out. Please show the code and the wiring of your project.

How is the ESP32 connected to the output of the amplifier? What kind of signal is this?

@chrisl, I just added diagram and code. I will now try your suggestion of getting the average

@StarCat, I hope the newly diagram helps with the questions. Otherwise I'll try to clarify further

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

Thanks, very good points.

You only take a measurement every 100ms:

This I fixed by taking a larger sample and getting the average.

The amplifier can output voltages up to it's supply voltage, so 5V:

I can regulate this with a volume knob in the LM386 module

I'm not sure if it is good to connect a speaker and the ESP in parallel:

This is the only way I've found to get readings that make sense. If the speaker is not there I get high values that don't reflect anything from the actual input.

I am wondering about why it works only with the speaker connected and how can I get rid of it as I don't really need a speaker on my setup

Mhh, the amplifier most likely acts like a current source and will raise the voltage, until the needed current flows or the limit is reached. So the problem is the type of amplifier. With a different amplifier you should be able to ditch the speaker. Though - as I wrote - I'm really no expert in that field.

@AlejandroCamus Taking samples and calculating the average to find the amplitude is meaningless. Imagine a single cycle of a pure sine wave. Think about sampling at regular points along that waveform. What will the average be? Now reduce the amplitude but keep the offset the same and do it again. What will the result be? You see the average has no relation to the amplitude - it only gives you the "DC offset" of the waveform. Instead you need to take lots of samples and find the MAX and MIN values over that period. The difference between the two values is the amplitude.

@Majenko Actually I think the OP gets satisfying results, because he tries to use the speaker ground as ground for the Arduino. Most likely the amplifier outputs a symmetrical wave around the speaker ground. But the ADC doesn't measure the negative voltages, thus the OP actually only measures one half wave. The average still doesn't give the real amplitude, but that still might be sufficient for the OPs application. At least that is my theory whats happening.

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 ++;
}

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


text:
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?

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.

Thank you for the detailed and informative answer. In your example, do you mean bit 7 and bit 8 are masked out?

6 and 7. You start counting bits from 0.

Thank you again :)


text:
RFID and Keypad Based Door Lock Using Arduino
I'm new to the Arduino world and I have a question. I found this project to do but I need your help, I want instead of this servomotor to put an electromagnetic door lock, could you help me with the changes in the scheme and code to understand this process? Thank you very much! I leave the diagram and the code here.

#include <deprecated.h>
#include <MFRC522.h>
#include <MFRC522Extended.h>
#include <require_cpp11.h>

// Include required libraries
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <SPI.h>
// Create instances
LiquidCrystal_I2C lcd(0x27, 16, 2);
MFRC522 mfrc522(10, 9); // MFRC522 mfrc522(SS_PIN, RST_PIN)
Servo sg90;
// Initialize Pins for led's, servo and buzzer
// Blue LED is connected to 5V
constexpr uint8_t greenLed = 7;
constexpr uint8_t redLed = 6;
constexpr uint8_t servoPin = 8;
constexpr uint8_t buzzerPin = 5;
char initial_password[4] = {'1', '2', '3', '4'};  // Variable to store initial password
String tagUID = "19 7F 30 C2";  // String to store UID of tag. Change it with your tag's UID
char password[4];   // Variable to store users password
boolean RFIDMode = true; // boolean to change modes
char key_pressed = 0; // Variable to store incoming keys
uint8_t i = 0;  // Variable used for counter
// defining how many rows and columns our keypad have
const byte rows = 4;
const byte columns = 4;
// Keypad pin map
char hexaKeys[rows][columns] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
// Initializing pins for keypad
byte row_pins[rows] = {A0, A1, A2, A3};
byte column_pins[columns] = {2, 1, 0};
// Create instance for keypad
Keypad keypad_key = Keypad( makeKeymap(hexaKeys), row_pins, column_pins, rows, columns);
void setup() {
  // Arduino Pin configuration
  pinMode(buzzerPin, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  sg90.attach(servoPin);  //Declare pin 8 for servo
  sg90.write(0); // Set initial position at 90 degrees
  lcd.begin();   // LCD screen
  lcd.backlight();
  SPI.begin();      // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  lcd.clear(); // Clear LCD screen
}
void loop() {
  // System will first look for mode
  if (RFIDMode == true) {
    lcd.setCursor(0, 0);
    lcd.print("   Door Lock");
    lcd.setCursor(0, 1);
    lcd.print(" Scan Your Tag ");
    // Look for new cards
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
      return;
    }
    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial()) {
      return;
    }
    //Reading from the card
    String tag = "";
    for (byte j = 0; j < mfrc522.uid.size; j++)
    {
      tag.concat(String(mfrc522.uid.uidByte[j] < 0x10 ? " 0" : " "));
      tag.concat(String(mfrc522.uid.uidByte[j], HEX));
    }
    tag.toUpperCase();
    //Checking the card
    if (tag.substring(1) == tagUID)
    {
      // If UID of tag is matched.
      lcd.clear();
      lcd.print("Tag Matched");
      digitalWrite(greenLed, HIGH);
      delay(3000);
      digitalWrite(greenLed, LOW);
      lcd.clear();
      lcd.print("Enter Password:");
      lcd.setCursor(0, 1);
      RFIDMode = false; // Make RFID mode false
    }
    else
    {
      // If UID of tag is not matched.
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Wrong Tag Shown");
      lcd.setCursor(0, 1);
      lcd.print("Access Denied");
      digitalWrite(buzzerPin, HIGH);
      digitalWrite(redLed, HIGH);
      delay(3000);
      digitalWrite(buzzerPin, LOW);
      digitalWrite(redLed, LOW);
      lcd.clear();
    }
  }
  // If RFID mode is false, it will look for keys from keypad
  if (RFIDMode == false) {
    key_pressed = keypad_key.getKey(); // Storing keys
    if (key_pressed)
    {
      password[i++] = key_pressed; // Storing in password variable
      lcd.print("*");
    }
    if (i == 4) // If 4 keys are completed
    {
      delay(200);
      if (!(strncmp(password, initial_password, 4))) // If password is matched
      {
        lcd.clear();
        lcd.print("Pass Accepted");
        sg90.write(90); // Door Opened
        digitalWrite(greenLed, HIGH);
        delay(3000);
        digitalWrite(greenLed, LOW);
        sg90.write(0); // Door Closed
        lcd.clear();
        i = 0;
        RFIDMode = true; // Make RFID mode true
      }
      else    // If password is not matched
      {
        lcd.clear();
        lcd.print("Wrong Password");
        digitalWrite(buzzerPin, HIGH);
        digitalWrite(redLed, HIGH);
        delay(3000);
        digitalWrite(buzzerPin, LOW);
        digitalWrite(redLed, LOW);
        lcd.clear();
        i = 0;
        RFIDMode = true;  // Make RFID mode true
      }
    }
  }
}

First: Please tell us, what electromagnetic doorlock you exactly have. A link to the product would be fine. Second: What exactly don't you understand in that code? Even without understanding the whole code you might get good results when playing with it a bit. The servo part is everything with sg90. You can then replace these parts with your door lock code.


text:
Send button only works when pressed immediately after
I am new to Arduino and I am trying to create a Morse code based "chat".
I can submit a message in Morse code using the send button (the one on the right,) and when I press the button on the left and the whole decoded message should appear on the screen. However, this is not happening unless I press the send button immediately after introducing the Morse code. Can anyone help me out? I tried changing the delay period, but nothing seems to make it send how it should.
As I said, I am a beginner, so please go easy on me.
This is my code:
/* String tone = "-... ..- -. .- ";

  Morse code - Receiver

  modified on 14 Apr 2019
  by Saeed Hosseini @ Electropeak
  https://electropeak.com/learn

*/
#include <LiquidCrystal.h>
// Create an LCD object. Parameters: (RS, E, D4, D5, D6, D7):
LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7);
String code = "";
int len = 0;
char ch;
int ok;
char new_char;
int i1=0;
int i2=1;
const int but_send=8;
const int but = 12;
const int led = 13;
String a="";
unsigned long pres_len = 0, rel_time, pres_time = 0, old_time_len = 0, old_pres = 0, space = 0;
int state = 0;
int unit_delay = 250;
int min_delay = 10;
int buttonState = 0;

char MakeString()
{
  if (pres_len < (unit_delay*3) && pres_len > 50)
  {
    return '.';                        //if button press less than 0.6sec, it is a dot
  }
  else if (pres_len > (unit_delay*3))
  {
    return '-';                        //if button press more than 0.6sec, it is a dash
  }
}

void Morse_decod()
{
  static String morse[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
                             "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
                             ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "!"
                            };
  int i = 0;
  while (morse[i] != "!")
  {
    if (morse[i] == code)
    {
      Serial.print(char('A' + i));
      a=a+char('A' + i);
      //lcd.print(char('A' + i));
      Serial.print(" ");
      if(i2>=2)
      {
        i1++;
        i2=0;
      }
      else
      {i2++;
      }
      break;
    }
    i++;
  }
  if (morse[i] == "!")
  {
    Serial.println("");
    Serial.println("This code is not exist!");
  }

  code = "";
}
void sendText()
{
  Serial.println(digitalRead(but_send));
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  //if (digitalRead(but_send) == HIGH) {
    // turn LED on:
     //gitalWrite(led, HIGH);
  if(ok==1){
    Serial.println(a);}
  ok=0;

    //}
  //else {
    // turn LED off:
    //Serial.println("NIMIC");
  //}
 delay(200);
}
void setup() {
  Serial.begin(9600);
  pinMode(but, INPUT_PULLUP);
  pinMode(but_send, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  lcd.setCursor(i1, 12);
  lcd.begin(16, 2);

}
void loop() {
label:
  while (digitalRead(but) == HIGH) {}
  old_pres = rel_time;
  pres_time = millis();
  digitalWrite(led, HIGH);
  while (digitalRead(but) == LOW) {}
  rel_time = millis();
  digitalWrite(led, LOW);
  pres_len = rel_time - pres_time;
  space = pres_time - old_pres;
  if (pres_len > min_delay)
  {
    code += MakeString();
  }
  while ((millis() - rel_time) < (unit_delay * 3))
  {

    if (digitalRead(but) == LOW)
    {
      goto label;

    }

  }

  Morse_decod();
    delay(1000);
  if (digitalRead(but_send) == LOW)
  {
    ok=1;
    //Serial.println("A intrat aici");
    sendText();
    //delay(100);

  }

 //Serial.println(digitalRead(but_send));

}

This is what should happen all the time, not only after pressing the send button very fast:

If needed, I can send a link from my tinkercad simulation.

tavis’ answer nailed down your problem: your program is completely
unresponsive when it is blocked in the first while loop of the
loop() function. Here I will try to give you some hints on how to
avoid this situation, but first some general comments:

if (pres_len < (unit_delay*3) && pres_len > 50)

The threshold should be unit_delay*2, maybe with a longer
unit_delay. In Morse, a dot is one unit, and a dash is three units. If
you have to set a threshold, it should be somewhere in the middle.
Otherwise, a perfectly valid dash of 2.99 units would be mistaken
for a dot.
Also, a function returning anything but void should always return a
value. What is this function supposed to return if press_len is
smaller or equal than 50? And if it is exactly equal to
unit_delay*3? The best way to make sure you did not forget any case is
to have an else at the end that returns a default value in case no
condition matches:
else
    return '?';  // we could not understand

In this particular case, it seems to me like you already did the
debounce prior to calling the function, so it could be simplified to
char getSymbol()
{
    if (pres_len < 2 * unit_delay)
        return '.';
    else
        return '-';
}

Note that giving functions meaningful names is an important step in
making the code easy to understand and reason about.

if(i2>=2)
{
  i1++;
  i2=0;
}
else
{i2++;
}

All this serves no useful purpose, as you do not use i1 or i2 after
setup(). Removing useless stuff is also important for the clarity of
the code.

Serial.println("This code is not exist!");

It should say “I cannot understand this code!”, but it may well exist.
Now, to the core of the issue. If you want the program to be responsive,
you should embrace non-blocking programming. This means getting rid of
delay() (see Blink Without Delay) and getting rid of blocking
loops, like the two while loops at the top of loop(). A very useful
approach is to program your system as a finite state machine.
Please, take the time to read and digest these two resources.
Next, as an example, I can point you to a Morse decoder of mine that is
based on the finite state machine concept. You do not have have to look
at my code, which may be too low level for your taste, but look at the
documentation of the program internals. It explains how the state
machines are built and interact with one another. Below is a state
diagram taken from that documentation. It shows the state machine that
takes the debounced “rise” and “fall” events as inputs, and generates
“dot”, “dash”, “end-of-char” and “end-of-word” symbols as outputs:

It looks like the line : while (digitalRead(but) == HIGH) {} will capture the processor in a loop until "but" is pressed.  So if you press the send button immediately after using "but" it might see that you pressed "send", but if you let the program loop get back to while (digitalRead(but) == HIGH) {}, then nothing can happen until "but" is pressed again.

Both tavis and Edgar Bonet have hit the nail on the head, and Edgar has provided you with an excellent tutorial.
You are unlikely to get this to work properly in the Tinkercad browser simulator because it runs at different speeds depending on the complexity of the code it is running. And the complexity varies when you press buttons, which throws the timing out as the Morse button is pressed.
However, I managed to get it roughly working in Tinkercad as follows.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte MORSE_BUTTON_PIN = 6;
const byte SEND_BUTTON_PIN = 7;
const byte MORSE_LED_PIN = 8;

const unsigned long DEBOUNCE_DELAY_ms = 50;
const unsigned long MORSE_UNIT_1 = 500;  // milliseconds.
const unsigned long MORSE_UNIT_2 = 2 * MORSE_UNIT_1;  // milliseconds.
const unsigned long MORSE_UNIT_5 = 5 * MORSE_UNIT_1;  // milliseconds.

const String MORSE_CODES[] =
{
  ".-", "-...", "-.-.", "-..", ".",
  "..-.", "--.", "....", "..", ".---",
  "-.-", ".-..", "--", "-.", "---",
  ".--.", "--.-", ".-.", "...", "-",
  "..-", "...-", ".--", "-..-", "-.--",
  "--.."
};

String symbol;
String message;

Debouncer morse_button(MORSE_BUTTON_PIN, DEBOUNCE_DELAY_ms);
Debouncer send_button(SEND_BUTTON_PIN, DEBOUNCE_DELAY_ms);

void setup()
{
  Serial.begin(115200);
  pinMode(MORSE_BUTTON_PIN, INPUT);
  pinMode(SEND_BUTTON_PIN, INPUT);
  pinMode(MORSE_LED_PIN, OUTPUT);
  // Set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Hello, world!");
}

void loop()
{
  static unsigned long press_begin_time = 0;
  static unsigned long release_begin_time = 0;
  static bool measure_the_gap = false;

  morse_button.Update();
  send_button.Update();

  if (morse_button.Fall())
  {
    // Remember when the morse button was pressed and
    // switch on the LED.
    int timestamp = millis();
    digitalWrite(MORSE_LED_PIN, HIGH);
    press_begin_time = timestamp;
  }

  if (morse_button.Rise())
  {
    // Remember when the morse button was released and
    // switch off the LED.
    int timestamp = millis();
    digitalWrite(MORSE_LED_PIN, LOW);
    release_begin_time = timestamp;
    int pressed_time = timestamp - press_begin_time;
    if (pressed_time > MORSE_UNIT_2)
    {
      // Dash.
      //Serial.print("-");
      symbol += "-";
    }
    else
    {
      // Dot.
      //Serial.print(".");
      symbol += ".";
    }
    measure_the_gap = symbol.length() > 0;
  }

  if (measure_the_gap)
  {
    unsigned long timestamp = millis();
    //Serial.println("Measuring the gap.");
    if (((timestamp - release_begin_time) > MORSE_UNIT_2))
    {
      // A long gap between presses signifies the end of a symbol.
      //Serial.println("Long gap");
      //Serial.println(symbol);
      measure_the_gap = false;
      message += DecodeSymbol(symbol);
      symbol = "";
    }
  }

  if (send_button.Fall())
  {
    // Print the Morse string.
    //Serial.println(message);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print(message);
    message = "";
  }

  // Delay for Tinkercad simulator.
  // Not needed for real hardware.
  delay(10);
}

char DecodeSymbol(String& symbol)
{
  //Serial.print(symbol);
  //Serial.print(": ");
  char ch = '?';
  for (int i = 0; i < 26; i++)
  {
    if (symbol == MORSE_CODES[i])
    {
      ch = 'A' + i;
      break;
    }
  }
  //Serial.println(ch);
  return ch;
}

For debouncing the buttons, I used this debouncer that I've put on GitHub. For Tinkercad, you will need to copy and paste that debouncer code (the debouncer.h file followed by the debouncer.cpp file) into the top of the Tnkercad code file because Tinkercad doesn't allow you to include your own code files.

+1, but note that: 1. timestamp and pressed_time should be unsigned long in order to avoid rollover issues, but then these variables are not really needed. 2. symbol.length() > 0 is always evaluated right after adding a character to symbol, and in this context it is always true.


text:
Delay function not working with ESP32
For whatever reason the delay function is not working (it is not delaying at all) with my ESP32 development board. Has anyone come across a similar issue before? It's not working with other sketches, in either the loop or set up functions. A sample sketch:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <BleMouse.h>

// mouse object
BleMouse ble("test", "me");

/** I2C pins **/
#define I2C_SDA 33
#define I2C_SCL 32

// I2C object
TwoWire wire_custom = TwoWire(0);

// Sensor object
Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28, &wire_custom);

/**************************************************************************/
function definitions
...

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

  Serial.begin(115200);

  ble.begin();

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

  // updating range
  bno.setMode(Adafruit_BNO055::OPERATION_MODE_CONFIG);
  delay(1000);
  write_register (0x28, 0x0A, 0b00111010);
  bno.setMode(Adafruit_BNO055::OPERATION_MODE_NDOF);
  delay(10000);
  byte result = read_register (0x28, 0x0A, 1);
  Serial.print(result);
  Serial.print("\n");
  Serial.print("\n");
}

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

  sensor_data (x_placeholder, y_placeholder);

  transform_sensor_data (x_placeholder, y_placeholder, x, y);

  if (ble.isConnected()) {
    ble.move(x, y);
  }
}

What does "not working" mean? Not delaying at all? Delaying forever? Too short a delay? Too long a delay? And what makes you believe that delay() is at fault?

how do you know that the delay function does not work? ... you do not have any debugging code that would verify that

Sorry I didn't clarify it is not delaying at all regardless of what amount I set it to.

How would you know? The loop() in the above code doesn't use a delay, and has no output either.

The output is the last function which moves the mouse, and that begins immediately after uploading the code. So there is no delay between uploading the code and when the loop function starts running.

Gotta be something to do with that register you set, or the setcrystal thing or one of those libraries.  To prove it, just upload a dead simple delay sketch and see if it works then.

Yeah will have to do it, I'm actually sorry I posted this question without considering it fully yesterday. It was quite a stressful day with this as the cherry on top.


text:
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?

From what I can see, your code expects an SPI display but your display has an I2C pinout. You should either use I2C in your code or convert your OLED display to SPI (some displays allow that with relatively simple modifications). Otherwise, it's probably not going to work.

@StarCat It is common for chinese displays to use SCK and SDA for "4 wire" serial's Clock and Data (SPI SCK and MOSI). The presence of DC attests to that.

@Majenko, you’re probably right (and I might have seen these confusingly labeled displays myself) but the display in question is from Adafruit which I kind of hold to a higher standard. The documentation should make it clear.

If it's SSD1306 then that's what the documentation calls them.

@Tyler Wallentine: why don't you give us the Adafruit product number of this display? @ Majenko: the SSD1306 can be 'programmed' to any of 5 different interfaces/protocols: I2C, 6800 parallel, 8080 parallel, 3 wire serial and 4 wire serial (datasheet: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf).

DC selects between Data and Commands.
CS is the Chip Select
SDA is the Serial DAta.
SCL is the Serial CLock.

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 - Master Out Slave In.  Some microcontrollers also call this SDO - Serial Data Out, where it's "out from the master's perspective".


text:
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!

Typically you would want to use the BT module by connecting it to a separate UART.  But since the UNO has only 1 UART you can't do this.  You CAN use SoftwareSerial however, which lets you use make a software based UART on normal digital IO pins.  Apparently it is possible to program over bluetooth though. https://create.arduino.cc/projecthub/mansurkamsur/upload-sketch-arduino-over-bluetooth-using-android-f1ce55

hmm, I don't actually know what a UART is; does this mean that I am unable to alter the state of pins? what about serial and sending code

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.

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.

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.

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.

so sorry for the late response, this helps tremendously and I totally have a better understanding of this. I was actually getting hung up on that serial problem you mentioned, and the explanation that the bluetooth module is a bluetooth-serial bridge, instead of the USB-serial bridge that the Atmega32u4 does; this really helped. from what I understand, it seems like you're saying it would be a good idea to do everything through one method (sending code, altering binary data, etc) to prevent corrupting data by sending through both USB and bluetooth, right?


text:
Two servos for robot (head & chest) movement at different speeds at once
I have an Arduino Uno and two Hi-tec servos (HS-40 & 5055 digital) that I'm using for a basic robot build. I'm trying to have one servo(HS-40) turn the head back and forth (left to right) slightly faster than the other servo (HS-5055) controlling the upper torso.
I would like to have each servo working at the same time but not at the same speed without waiting for one servo to complete its movement.
I tried a sketch with a delay of 45-50 which seems to work fine for the movement speed and 0-75 degrees is ideal for the head travel and 0-65 degrees for the torso travel. I would like to have this movement to be repeated continuously so the robot mimics like it is looking side to side or left to right naturally.
Please help as I tried many sketches but can't find one that works like this. I tried modifying other code but can't get them work. Any help will be greatly appreciated.
How do modify this code so just the second servo runs at 40 which will slow down just enough? Also this is not my code, but it's one that seems to be close to what I'm trying to do.
#include <Servo.h>

Servo servo1;
Servo servo2;

int i = 0;

void setup() {
  servo1.attach(8);
  servo2.attach(9);
}

void loop() {
  for (i = 0; i < 70; i++) {
    servo1.write(i);
    servo2.write(i);
    delay(50);
  }
  for (i = 70; i > 0; i--) {
    servo1.write(i);
    servo2.write(i);
    delay(50);
  }
}

Please post some code that you are using.  Without a starting point it is difficult to offer any help.   But do a google search for "blink without delay" for an approach that might work.

Here is the code. Can a "Delay" command be added to the second servo to slow it down to 40? #include <Servo.h>
Servo servo1;
Servo servo2;
int i = 0;
void setup() {
servo1.attach(8);
servo2.attach(9);
}
void loop() {
for (i = 0; i < 70; i++) {
servo1.write(i);
servo2.write(i);
delay(50);
}
for (i = 70; i > 0; i--) {
servo1.write(i);
servo2.write(i);
delay(50);
}
}

change the line to servo1.write(2*i);

Heres a little sketch you can try.  It uses timing to accomplish the different servo speeds.  It won't give you the exact servo travel each loop but it sounds like you might not mind if it randomly is off by a few degrees each loop.
#include <Servo.h>
Servo servo1;
Servo servo2;
int i = 0;
void setup() {
  Serial.begin(9600);
  servo1.attach(8);
  servo2.attach(9);
}

int sweep_time = 3500; // 70 * 50ms = 3500

int head_degrees = 75; // sweep degrees for the head to move
int body_degrees = 65; // sweep degrees for the body to move

int millis_per_head_move = sweep_time / head_degrees;
int millis_per_body_move = sweep_time / body_degrees;

void loop() {
  int i = 0; int j = 0;
  unsigned long now_millis = 0;
  unsigned long start_sweep = millis(); // mark the time when we start the first sweep

  while ( millis() - start_sweep < sweep_time ) {  // keep moving first sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0 ) servo1.write(i++);
    if (now_millis % millis_per_body_move == 0 ) servo2.write(j++);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);

  start_sweep = millis();  // mark the time when we start the second/back sweep
  while ( millis() - start_sweep < sweep_time ) {  // keep moving second sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0) servo1.write(i--);
    if (now_millis % millis_per_body_move == 0) servo2.write(j--);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);
}

Thank you so much for this. I was getting some jittering with the previous code as the head swept back but I think I need to add some weight for ballast to the head & torso to help stabilize them. This code seems to minimize some of the jittering. I did test it with some added weight and it seems to be better now. Hopefully, once I get this project done I'll post a link where you can see it in action.  Again, thanks for all the help!  Much appreciated.

Happy that it works! If my answer solved the issue then please mark it as the accepted answer.

You do that by clicking the check mark by someone's answer.

Thanks for the answer from @tavis
Here is the simulation of their code and it answers your questions aptly.

The code (same as above, except the sweep time change)
#include <Servo.h>
Servo servo1;
Servo servo2;
int i = 0;
void setup() {
  Serial.begin(9600);
  servo1.attach(8);
  servo2.attach(9);
}

int sweep_time = 1000; // 70 * 50ms = 3500

int head_degrees = 75; // sweep degrees for the head to move
int body_degrees = 65; // sweep degrees for the body to move

int millis_per_head_move = sweep_time / head_degrees;
int millis_per_body_move = sweep_time / body_degrees;

void loop() {
  int i = 0; int j = 0;
  unsigned long now_millis = 0;
  unsigned long start_sweep = millis(); // mark the time when we start the first sweep

  while ( millis() - start_sweep < sweep_time ) {  // keep moving first sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0 ) servo1.write(i++);
    if (now_millis % millis_per_body_move == 0 ) servo2.write(j++);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);

  start_sweep = millis();  // mark the time when we start the second/back sweep
  while ( millis() - start_sweep < sweep_time ) {  // keep moving second sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0) servo1.write(i--);
    if (now_millis % millis_per_body_move == 0) servo2.write(j--);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);
}

Link to the simulation:
https://wokwi.com/arduino/projects/303847722463527490
Here is another example with three Servo motors running at three different sweep times:
https://wokwi.com/arduino/projects/299552195816194570


text:
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,

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

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

It will be very much help full if you can share a schematic for the same including the level shifter to be used. And I am using  an Arduino Mega

Look for example here. Though you only need this, if you want to connect Arduino TX to sensor RX (for sending data to the sensor). You don't write, if you really need that

Thanks , I want to connect Tx(ard)->Rx(sens) , may be in future as I can send commands to the sensor for changing the output modes .

More correctly: RS232 is the protocol (standard) and an UART (universal asynchronous receiver/transmitter) is a type of integrated circuit (IC - chip) that is designed to work a.o. according to that protocol.


text:
Arduino does not boot when SPI lines are loaded
i connected an Arduino Nano to an external SPI Flash using THIS tutorial (russian) and the SPIMemory library. While accessing the Flash works well, i have encountered the following issue:
The Problem: When the SPI MISO line is pulled high by the flash while the Arduino boots, it does not start, for example because it was rebooted while accessing the flash. I have to power down the Flash before it boots again. But even then, it takes unusually long to boot.
I know that the Atmega328p allows reprogramming via SPI, but to my knowledge this should not cause this behavior since the SPI lines do not change (starting the programming mode would require a command to be sent immediately after restart). Is there any way to prevent this behavior? (Except disabling SPI programming via fuse bits, this would be my last choice)
EDIT
Programming the Arduino via ISP does work, however i added some series resistors to the flash to prevent accidentally driving the SPI lines from multiple sources.
The problem seems to come from the MISO line, when it is pulled to VCC the Arduino does not start. This is not mentioned in the data sheets anywhere and i am not sure how to prevent this (sketch below to show the wiring).

Is it possible for you to burn the bootloader/flash a sketch via ISP? If you erase the bootloader you can find out if thats where it hangs.

@SimSon I made a few tests, i will add the results to the post, too: writing via ISP does work, however i added some series resistors to the flash to prevent multiple drivers on the same line. Writing the firmware without bootloader greatly speeds up the startup of the arduino, but does not prevent it from freezing when the SPI lines are pulled by the flash. The MISO line seems to be the main problem, when it is pulled to VCC the Arduino does not start.

how do you actually know that it "freezes"? If it still happens without a bootloader, then it looks like it's caused by your sketch. you might also want to include a wiring diagram

@SimSon i edited the program so that it enables the status led of the nano right at the beginning. The LED remains dark until i pull the MISO line from the nano, then it immediately lights up

I honestly can't imagine why a sketch like that would hang in this scenario. But I'm confident that my answer can solve the issue.
My guess is that the following happens:
The flash is selected (CS pulled low by atmega) at the moment at which the reset happens. At this moment, the master will stop generating a clock signal and CS will be floating.
Thus, the flash will not be deselected reliably due to the floating CS and MISO will remain in the state it was before the reset occured (HIGH if it was transmitting a logic 1, LOW for 0). Basically, the SPI communication of the flash will be stuck with MISO being actively pulled to logic high or low.
IDK why this causes the sketch to freeze, but if you add a pullup resistor to the flash's CS, it should be deactivated by default (and also after a reset of the atmega as pins will be inputs/floating by default). As a result, the flash can not actively pull MISO and should therefore barely affect the atmega at all.
I suggest you add the mentioned pullup and see if that makes any difference. If it doesn't I'm going to delete this answer, but it was a bit too long for a comment ;).
Edit: I also just saw that you are missing the pullup resistor on the reset pin. That could well be the actual problem.

Thank you, this actually works! I've also added a weak pull down on the MISO line to be sure, but this does not seem to be really necessary.

@Sabulanis I just saw that you also don't have a pullup on the reset pin. That could have been the problem behind it


text:
Problem with ESP32 bluetooth
I am trying to connect ESP32 via bluetooth classic to my PC to transfer some data from a sensor.
As a first step, I am simply trying to send some random data over bluetooth serial. The code is at follows:
#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

int myData[8];
BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  Serial.println("Opening Serial Connection on COM4");
  SerialBT.begin("ESP32"); //Bluetooth device name
  SerialBT.println("Opening Serial Bluetooth Connection on COM6");

}

void loop() {

  for(int i = 0; i < 8; i++)
  {
    myData[i] = random(0,500);
  }
  if(Serial.available())
    {

     for(int i = 0; i < 8; i++)
  {
    SerialBT.write(myData[i]);
  }

    }
    delay(20);
}

In Windows bluetooth settings, I have paired the ESP32 with windows and connected it. I have set up incoming and outgoing COM ports for bluetooth where incoming port is  COM6 and outgoing port is COM5.
However, when I open arduino serial monitor for COM6, it is empty and no data is being printed. I am using arduino IDE. Furthermore, on COM4, there is nothing printed despite the Serial.println("Opening Serial Connection on COM4"); command which I think should work regardless of bluetooth.
I have tried everything I can think of. I would be grateful if anyone can help me solve this problem as I have been stuck for days


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

You can try the I2C_Anything library by Nick Gammon

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


text:
Delay function executes too quickly
I'm making a hydroponics system that collects data and sends it to the user through a SIM module. The problem is that while I want it to happen only once every 15 minutes and for the pump to operate for 30 seconds only, yet the device seems to do everything 10 times as quickly, if not even faster. Is there any way to fix this without multiplying everything by 10?
#include <SoftwareSerial.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <GravityTDS.h>
#include <Servo.h>

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

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

char msg;
char call;

void setup()
{

  dht.begin();

  sensors.begin();

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

  myservo.attach(PUMPPIN);
}

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

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

  sensors.requestTemperatures();

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+************\"\r"); // Replace x with mobile number
  mySerial.print(h);// The SMS text you want to send
  mySerial.print("% humidity, ");
  mySerial.print(t);
  mySerial.print(" degrees Celsius air temperature, ");
  mySerial.print(sensors.getTempCByIndex(0));
  mySerial.print(" degrees Celsius water temperature, ");
  mySerial.print(tdsValue,0);
  mySerial.print(" ppm");

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

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

}```

Can you please verify the problem with the blink example, while nothing is connected to the Arduino? Just to narrow down the problem more. Maybe the fuses of your Mega are configured the wrong way. If the same problem happens with the blink sketch you could try using another Arduino to burn the bootloader via ISP. That also sets the fuses.

I wouldn't use delay with so long values. Check the current time using millis() instead. This will also allow you to keep the board responding (i.e. to button presses).

An unrecommended method it to change long SECOND = 1000; to long SECOND = 10000;

@Gil, how should it work?

Each "SECOND" will be 10X longer. Remember when you are in delay the computer can do nothing else.

@Gil, are you serious? do you understand the cause of the problem in the question?

He stated things are happening about 10X what he wanted, he asked for the easiest way and did not want to change the code which would be the best. I also stated that was unrecommended. What did I miss, he originally stated he did not want to change his code, this was the simplest way I saw at the time.  What did I miss?

you missed that 15*MINUTE is calculated as int and overflows so the result is a much shorter delay


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

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.


text:
avrdude: stk500_recv(): programmer is not responding Arduino LCD_I2C Upload problem ( port not found and ...)
i have problem to upload the LCD I2c Example program to Arduino UNo. the code are shown below:
//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Hello, world!");
  lcd.setCursor(2,1);
  lcd.print("Ywrobot Arduino!");
   lcd.setCursor(0,2);
  lcd.print("Arduino LCM IIC 2004");
   lcd.setCursor(2,3);
  lcd.print("Power By Ec-yuan!");
}

void loop()
{
}

the schematic is like the below photo:

but i get this error:
Sketch uses 3382 bytes (10%) of program storage space. Maximum is 32256 bytes.
Global variables use 327 bytes (15%) of dynamic memory, leaving 1721 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

Thank.

try uploading some other sketch ... you will find that it is not problem to upload the LCD I2c Example program, it is problem uploading any program

Thanks @chrisl, the avrdude: stk500_getsync(): not in sync: resp=0x00," aka Some Dude Named Avr Won't Let Me Upload My Program helped me, the problem was solved by changing the USB Cable and removing the I2C pins from the Arduino Pins ( SCL & SDA Pins : A4 and A5).

@jsotola, the Problem was only with upload the LCD I2c Example program, and solved by the above solution (  changing the USB Cable and removing the I2C pins from the Arduino Pins )

@sosa are you saying that other programs would load correctly without changing the USB cable and removing I2C pins?

@jsotola, if i have not removed the SCL and SCA pints, Yes.