text:
Keypad - Speaker - Interference
I am trying to build a system, that plays specific audios (.wav files) from a SD-Card, according to the key combination that has been pressed.
I am using:

4x4 Membrane
4 Ohm Speaker
MicroSD Card Adapter Module
TIP120 Transistor (for amplification)
Arduino NANO clone (https://www.amazon.de/gp/product/B0755XYBG4)

So I broke the project down in various steps:

playing .wav file from the SD Card (works fine)
using keypad (works fine)
combinig both (as you may have guessed: does not work)

Here are the codes I used for every step:
1)
#include "SD.h"
#define SD_ChipSelectPin 4
#include "TMRpcm.h"
#include "SPI.h"

TMRpcm tmrpcm;

void setup() {
  tmrpcm.speakerPin = 9;
  Serial.begin(9600);
  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD fail");
    return;
  }

  tmrpcm.setVolume(5);
  tmrpcm.play("test.wav");
}

void loop() {}

This plays test.wav one time after uploading or resetting.
2)
#include <Keypad.h>

// Definition für das Keypad von Elegoo
const byte ROWS = 4; // vier Zeilen
const byte COLS = 4; // vier Spalten
// Symbole auf den Tasten
const byte rows[ROWS] = {2, 3, 12, 5};//connect to the row pinouts of the keypad
const byte cols[COLS] = {6, 7, 8, 11};//connect to the column pinouts of the keypad

char keys[ROWS][COLS] = { //create 2D arry for keys
  {'D', 'C', 'B', 'A'},
  {'#', '9', '6', '3'},
  {'0', '8', '5', '2'},
  {'*', '7', '4', '1'},
};

// Instanz von Keypad erzeugen, Keymap und Pins übergeben
Keypad customKeypad = Keypad(makeKeymap(keys), rows, cols, ROWS, COLS);

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

void loop() {
  // Gedrückte Taste abfragen
  char customKey = customKeypad.waitForKey();
  Serial.println(customKey);
}

This code prints out every pressed key.
3)
#include <Keypad.h>
#include "SD.h"
#define SD_ChipSelectPin 4
#include "TMRpcm.h"
#include "SPI.h"

TMRpcm tmrpcm;

// Definition für das Keypad von Elegoo
const byte ROWS = 4; // vier Zeilen
const byte COLS = 4; // vier Spalten
// Symbole auf den Tasten
const byte rows[ROWS] = {2, 3, 12, 5};//connect to the row pinouts of the keypad
const byte cols[COLS] = {6, 7, 8, 11};//connect to the column pinouts of the keypad

char keys[ROWS][COLS] = { //create 2D arry for keys
  {'D', 'C', 'B', 'A'},
  {'#', '9', '6', '3'},
  {'0', '8', '5', '2'},
  {'*', '7', '4', '1'},
};

// Instanz von Keypad erzeugen, Keymap und Pins übergeben
Keypad customKeypad = Keypad(makeKeymap(keys), rows, cols, ROWS, COLS);

void setup() {
    tmrpcm.speakerPin = 9;
  Serial.begin(9600);
  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD fail");
    return;
  }
}

void loop() {
  // Gedrückte Taste abfragen
  char customKey = customKeypad.waitForKey();
  Serial.println(customKey);

  if (customKey == 8) {
    tmrpcm.setVolume(5);
    tmrpcm.play("test.wav");
  }
}

This code should play test.wav if key 8 is pressed.
THE PROBLEM
So the problem is not that there is no sound at all, but its just completely distorted. The sound quality never was great but sufficient. Now it sounds like "too much signal" is coming onto the speaker and interferes with the audio. Even if there shouldn't be any audio playing, machine-like sounds are produced by the speaker. By slowly working through the code I managed to find the line that probably causes the problem:
char customKey = customKeypad.waitForKey();
Serial.println(customKey);

If put it in a comment and put
tmrpcm.setVolume(5);
tmrpcm.play("test.wav");

in the setup function the audio is played.
I tried a lot and it doesn't matter where you put the getKey line (or change it to waitForKey()), as long as this line is somewhere in a function the sound is distorted.
Why does this happen? How can i work around it?
Can anybody please help me with this? :)
wiring diagram

Pins 11 and 12 are MISO/MOSI SPI pins, you're using them both for the SD card and the touchpad

Hm ok, so so you have a solution? I am running Out of Pins... Can I use a different wiring? What Others Pins could I use to avoid it?  And what about the Others digital Pins that have an additional SPI purpose? Are they a Problem as well?

You could probably use pins from A0 to A3 (or to A5 if you don't use I2C) https://electronics.stackexchange.com/questions/67103/can-i-use-the-analog-pins-on-the-arduino-for-my-project-as-digital

Thank you! You were right. Pins 11 and 12 interfered with the other SPI pins i used. I switched to A0 and A2 and now everything works perfectly.


text:
How to get keyboard input to Arduino from the computer its plugged in to?
I have an Arduino Uno connected to my laptop and I need to get keypress info from the laptop's keyboard
with only the Arduino sketch and without any program running on the laptop.
Is there a specific library or some way of doing so?

As you wrote your question: No, you can't do this. How could a sketch running on the Arduino make the computer transfer keyboard input, if there is no program for this running on the computer?

I read this question and commented it earlier today. Did you delete it and ask again with the "no program" addition?

@Juraj, you are correct in your thinking ... i have also seen this same question earlier ... i commented about using Processing ... now the OP apparently wants to use a keyboard on a laptop that is shut down ... lol

@asaf, perhaps you could use a PS2 keyboard that is directly connected to the arduino

@Juraj it has been edited by an 'anonymous user'.

This sounds like a key logger -  which may be innocent, but is probably morally/legally dubious (especially if the owner of the PC is unaware that it is attached).

You can't. It's impossible.
Or not as you have requested it, anyway.
The Arduino can only talk over Serial, so you will have to have some software running on the PC that transfers data (however that data is generated) over serial to the Arduino to process.
The only other option will be to have one of the Arduino boards that is capable of acting as a USB Keyboard device, such as a Leonardo, plus either a PS/2 keyboard or a USB keyboard plus a USB Host shield. Your Arduino the receives the keystrokes from the keyboard, processes them, and sends the result on to the PC.

source: Stack Exchange

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

sort: votes


text:
How to upload already compiled code when no changes were made?
How do I use the Arduino IDE to upload the last compiled code? I don't want to have to wait 2 minutes to upload compiled code when there are no changes. It's a big codebase, where I frequently make one or two small changes and have some issue with my MCU or USB cables. Frequently the controller on my boards are damaged due to some overcurrent issue because of the high-heat nature of 3D printing. Having to wait an extra 2-5 minutes every time I experiment with this is unacceptable.
Obviously, there is a keyboard shortcut to do this that I'm unaware of, because otherwise  this would add hours to development.
Please tell me how I can get the Arduino IDE to just 'upload without compiling' my sketch.

What version of the Arduino IDE are you using? It used to be rubbish, but later versions have better caching of compiled code.  Alternatively UECIDE has far better caching than the Arduino IDE and recompilation is a lot faster because of that.

you can find the compile bin file in your temp folder, then use a different upload tool (or OTA) to send it out.

@Majenko: the link above to UECIDE doesn't seem to point to where it is supposed to point; maybe replace with https://github.com/UECIDE/UECIDE ?

You can upload hex file to your board from command line without Arduino IDE.
To get the hex file, use in Arduino IDE in menu the command "Export compiled binary". It will save the hex file next to the ino file.
I assume your board in printer has AVR MCU. Then you can use avrdude from command line to upload the hex file again and again without any compilation.
The avrdude command on Windows is (if started from the sketch's folder):
%LOCALAPPDATA%\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -C%LOCALAPPDATA%\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -carduino -PCOM11 -b115200 -D -Uflash:w:Blink.ino.hex:i

The command line is for the Blink sketch and for AVC boards package 1.6.21

This is what I have done.  In the arduino IDE settings panel, turn on the "Show verbose output during compile and upload". This way whenever you are doing verify and upload you can see all the command that Arduino has performed. Now after you hit Verify or Upload it, you can copy the last command before the upload, such as
"/Users/fang/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude" "-C/Users/fang/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" -v -V -patmega32u4 -cavr109 "-P/dev/cu.usbmodem21101" -b57600 -D "-Uflash:w:/private/var/folders/xb/4609zdjx4tn3bv_6jh2nym_r0000gn/T/arduino/sketches/7972D54945A751059BF3114D2057C2B6/sketch_aug4c.ino.hex:i"
Now, when you need to upload without compiling again, just paste this line to the Terminal, it'll do the rest for you. Essentially you can see Arduino IDE is just a wrapper around these commands.
Update:
I also found another way which is kinda of different but more effective. If you happen to use Visual Studio Code, you can also try the PlatformIO plugin which can compile and upload code separately, I wrote an article about it here, https://windmaomao.medium.com/use-platformio-to-write-arduino-code-3c957c4e58b5

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


text:
MPU6050 FIFO overflow and freezing problems
I'm using the sensor MPU6050 to control movements of my robotic arm. The code works fine when it is a standalone program but I keep encountering 'FIFO overflow' when the code is compiled into the main program. This is the code that I am using:
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    #include "I2Cdev.h"
    #include "MPU6050_6Axis_MotionApps20.h"
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #endif
    MPU6050 mpu;

    RF24 radio(9, 8);  // CE, CSN

    const byte address[6] = "00001";

    const int AccReadings = 10;
    //Wrist Roll
    int DataX[AccReadings];
    int WRIndex = 0;
    int WRtotal = 0;
    int WRaverage = 0;
    //Wrist Pitch
    int DataY[AccReadings];
    int WPIndex = 0;
    int WPtotal = 0;
    int WPaverage = 0;
    //Shoulder Lift
    int DataY2[AccReadings];
    int SLIndex = 0;
    int SLtotal = 0;
    int SLaverage = 0;
    //Elbow Lift
    int ELaverage = 0;
    //Arm Rotation
    int ARaverage = 0;
    float correct;

    #define OUTPUT_READABLE_YAWPITCHROLL
    #define INTERRUPT_PIN 2
    bool blinkState = false;

    // MPU control/status vars
    bool dmpReady = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
    uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer[64]; // FIFO storage buffer

    // orientation/motion vars
    Quaternion q;           // [w, x, y, z]         quaternion container
    VectorInt16 aa;         // [x, y, z]            accel sensor measurements
    VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
    VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity;    // [x, y, z]            gravity vector
    float euler[3];         // [psi, theta, phi]    Euler angle container
    float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

    struct Sensor_Data
    {
      int WristRoll;
      int WristPitch;
      int ShoulderLift;
      int ElbowLift;
      int ArmRotation;
    };
    Sensor_Data data;

    //Interrupt Detection
    volatile bool mpuInterrupt = false;
    void dmpDataReady()
    {
      mpuInterrupt = true;
    }

    void setup()
    {
      radio.begin();
      radio.openWritingPipe(address);
      radio.setPALevel(RF24_PA_MIN);
      radio.stopListening();

      //Zero-fill Arrays
      for (int i = 0; i < AccReadings; i++)
      {
       DataX[i] = 0;
      }
      for (int j = 0; j < AccReadings; j++)
      {
       DataY[j] = 0;
      }
      for (int k = 0; k < AccReadings; k++)
      {
       DataY2[k] = 0;
      }

      #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        Wire.setClock(400000);
      #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
      #endif

      Serial.begin(115200);
      while (!Serial);

      mpu.initialize();
      pinMode(INTERRUPT_PIN, INPUT);
      devStatus = mpu.dmpInitialize();
      mpu.setXGyroOffset(49);
      mpu.setYGyroOffset(-18);
      mpu.setZGyroOffset(9);
      mpu.setZAccelOffset(4427);

      if (devStatus == 0)
      {
        mpu.setDMPEnabled(true);
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
      }
      else
      {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        // Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
      }
    }

    void loop()
    {
      /*smoothWR();
      movementWR();
      smoothWP();
      movementWP();
      smoothSL();
      movementSL();*/
      ElbowMovement();
      radio.write(&data, sizeof(Sensor_Data));
    }

    void smoothWR()
    {
      WRtotal = WRtotal - DataX[WRIndex];
      DataX[WRIndex] = analogRead(A0);
      WRtotal = WRtotal + DataX[WRIndex];
      WRIndex = WRIndex + 1;

      if (WRIndex >= AccReadings)
      {
        WRIndex = 0;
      }

      WRaverage = WRtotal / AccReadings;
      //Serial.println(WRaverage);
    }

    void movementWR()
    {
      WRaverage = map(WRaverage, 278, 419, 0, 180);
      data.WristRoll = constrain(WRaverage, 0, 180);
      //Serial.println(data.WristRoll);
    }

    void smoothWP()
    {
      WPtotal = WPtotal - DataY[WPIndex];
      DataY[WPIndex] = analogRead(A1);
      WPtotal = WPtotal + DataY[WPIndex];
      WPIndex = WPIndex + 1;

      if (WPIndex >= AccReadings)
      {
        WPIndex = 0;
      }

      WPaverage = WPtotal / AccReadings;
      //Serial.println(WPaverage);
    }

    void movementWP()
    {
      WPaverage = map(WPaverage, 280, 421, 0 , 135);
      data.WristPitch = constrain(WPaverage, 0, 135);
      //Serial.println(data.WristPitch);
    }

    void smoothSL()
    {
      SLtotal = SLtotal - DataY2[SLIndex];
      DataY2[SLIndex] = analogRead(A2);
      SLtotal = SLtotal + DataY2[SLIndex];
      SLIndex = SLIndex + 1;

      if (SLIndex >= AccReadings)
      {
        SLIndex = 0;
      }

      SLaverage = SLtotal / AccReadings;
      //Serial.println(SLaverage);
    }

    void movementSL()
    {
      SLaverage = map(SLaverage, 410, 270, 0 , 180);
      data.ShoulderLift = constrain(SLaverage, 35, 180);
      //Serial.println(data.ShoulderLift);
    }

    void ElbowMovement()
    {
      // if programming failed, don't try to do anything
      if (!dmpReady) return;

      // wait for MPU interrupt or extra packet(s) available
      while (!mpuInterrupt && fifoCount < packetSize)
      {
        if (mpuInterrupt && fifoCount < packetSize)
        {
          // try to get out of the infinite loop
          fifoCount = mpu.getFIFOCount();
        }
      }

      // reset interrupt flag and get INT_STATUS byte
      mpuInterrupt = false;
      mpuIntStatus = mpu.getIntStatus();

      // get current FIFO count
      fifoCount = mpu.getFIFOCount();

      // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024)
      {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        fifoCount = mpu.getFIFOCount();
        Serial.println(F("FIFO overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen frequently)
      }
      else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT))
      {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        // Get Yaw, Pitch and Roll values
    #ifdef OUTPUT_READABLE_YAWPITCHROLL
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

        // Yaw, Pitch, Roll values - Radians to degrees
        ypr[0] = ypr[0] * 180 / M_PI;
        ypr[1] = ypr[1] * 180 / M_PI;
        ypr[2] = ypr[2] * 180 / M_PI;

        // Skip 300 readings (self-calibration process)
        if (int l = 0; l <= 300) {
          correct = ypr[0]; // Yaw starts at random value, so we capture last value after 300 readings
          l++;
        }
        // After 300 readings
        else {
          ypr[0] = ypr[0] - correct; // Set the Yaw to 0 deg - subtract  the last random Yaw value from the currrent value to make the Yaw 0 degrees
          // Map the values of the MPU6050 sensor from -90 to 90 to values suatable for the servo control from 0 to 180
          ELaverage = map(ypr[0], -90, 90, 0, 180);
          data.ElbowLift = constrain(ELaverage, 30, 110);
          ARaverage = map(ypr[1], -90, 90, 0, 180);
          data.ArmRotation = constrain(ARaverage, 0, 180);
          //Serial.println(data.ElbowLift);
          Serial.println(ypr[1]);
        }
    #endif
      }
    }

Is there any ways to get rid of the FIFO overflow? Also When I tried to used Jeff Rowberg's example code MPU6050_DMP6 the program froze after a few seconds. Is there any solution to that?
This is the example code that I am using:
    #include "I2Cdev.h"
    #include "MPU6050_6Axis_MotionApps20.h"
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #endif
    MPU6050 mpu;
    float correct;
    int j = 0;

    #define OUTPUT_READABLE_YAWPITCHROLL
    #define INTERRUPT_PIN 2
    bool blinkState = false;

    // MPU control/status vars
    bool dmpReady = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
    uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer[64]; // FIFO storage buffer

    // orientation/motion vars
    Quaternion q;           // [w, x, y, z]         quaternion container
    VectorInt16 aa;         // [x, y, z]            accel sensor measurements
    VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
    VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity;    // [x, y, z]            gravity vector
    float euler[3];         // [psi, theta, phi]    Euler angle container
    float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

    //Interrupt Detection
    volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady() {
      mpuInterrupt = true;
    }

    void setup()
    {
      #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
      Wire.begin();
      Wire.setClock(400000);
      #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
      Fastwire::setup(400, true);
      #endif
      Serial.begin(38400);
      while (!Serial);

      mpu.initialize();
      pinMode(INTERRUPT_PIN, INPUT);
      devStatus = mpu.dmpInitialize();
      mpu.setXGyroOffset(17);
      mpu.setYGyroOffset(-69);
      mpu.setZGyroOffset(27);
      mpu.setZAccelOffset(1551);

      if (devStatus == 0)
      {
        mpu.setDMPEnabled(true);
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
      }
      else
      {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        // Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
      }
    }

    void loop()
    {
      if (!dmpReady) return;
      if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer))
      {
        #ifdef OUTPUT_READABLE_YAWPITCHROLL
                // display Euler angles in degrees
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                mpu.dmpGetGravity(&gravity, &q);
                mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
                if (j <= 300)
                {
                  correct = ypr[0]; // Yaw starts at random value, so we capture last value after 300 readings
                  j++;
                }
                else
                {
                  ypr[0] = ypr[0] - correct;
                  Serial.print("ypr\t");
                  Serial.print(ypr[0] * 180/M_PI);
                  Serial.print("\t");
                  Serial.print(ypr[1] * 180/M_PI);
                  Serial.print("\t");
                  Serial.println(ypr[2] * 180/M_PI);
                }
        #endif
      }
    }

I have used an MPU6050 successfully in my autonomous robot project for several years now, so I have some knowledge of the subject
If your code is freezing intermittently, it may well be the infamous bug in the Arduino 'Wire' code that causes the I2C receive and/or transmit functions to block under certain conditions.
Take a look at some of my posts on 'Paynter's Palace'.  You'll find there is a long history of intermittent I2C hangup problems with the stock 'Wire' library.  The good news is that this problem was (sorta) fixed.  You can now use the stock 'Wire' library, but you still have to manually enable the watchdog timeout value to get the transmit/receive functions to unblock if they get stuck.
See this post regarding the Wire library bug fix. You will find the following lines in setup():
Wire.setWireTimeout(3000,true);
    wireTimeoutCount = 0;
    Wire.clearWireTimeoutFlag();

These lines set a reasonable timeout value (3000 uSec in my case), reset a local variable (wireTimeoutCount) I used for debug, and reset the new Wire library timeout flag.
Note that you'll need to ensure you are using the latest Wire library code.  If the above 'Wire.setWireTimout(3000, true);' compiles, then you are using the latest library.  If it doesn't, then you'll have to get the latest one.
Hope this helps,
Frank

Thank you Frank. It is working now but when i integrate the codes with NRF24L01 wireless module, the MPU6050 doent seem to work. Do you know what seems to be the problem?


text:
How do I make my motors speed change?
I'm using an Adafruit V1 Motor Shield for coding two 12 volt DC motors. In my code I'm changing the set speed, but the motors still seem to be going the same speed, which is really fast, and I want them to go slow.  What do I change to make my motors speed run the way I want them to run?
Here's my code below:
#include <AFMotor.h>

AF_DCMotor motor1(1);
AF_DCMotor motor2(2);

void setup() {
  Serial.begin(9600); // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  // turn on motor
  motor1.setSpeed(3);
  motor2.setSpeed(5);
}

void loop() {
  uint8_t i;

  //second motor
  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  //1 motor
  Serial.print("tick");

  motor1.run(FORWARD);

  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tack");

  motor1.run(BACKWARD);

  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }
}

delete all of the code inside loop() ... what happens then?

What do I change to make my motors speed run the way I want them to run? ... how is anyone supposed to guess how you want the motors to run?

@jsotola  I mean by like how do i change the speed?

please read my first comment

@jsotola when I delete all of the code inside void loop(), nothing happens.

please add motor1.run(FORWARD);

@jsotola Its still the same speed. I have the power supply of 12v hooked up to the Arduino mega, which makes the motor sheild turn on, but is there any chance that it could be that there is to much power going to the motor shield which is causing the motors to spin faster?

are you saying that you are connecting 12 V to something that is not rated for such a voltage?

The arduino mega is 12 volts but the motor shield is 5 volts

hey . so if you have multimeter take it and check for the voltage at the terminals for the motor and the voltage should change according to the speed you have set

It looks like that motor shield can control stepper motors, servos, or variable speed DC motors. Are you using variable speed DC motors? (What model of motors are you using?)


text:
How do I program an LCD screen and do I need an Arduino
I am trying to create a small device with a screen that tells the date and time. I am thinking of using a UCTRONICS 0.96 Inch OLED Module (type that on Amazon). I am very new at coding, and I know more about electrical engineering, so I have a few questions.

Do I need an Arduino that big to power this screen or any screen? I am trying to put this in a compact housing

How do you set up the screen and code it to tell the time and date

Is there a better screen for me to pick that is easier to work with, or is there a screen that comes programmed telling the time and date

Can someone help, please?

"is there a screen that comes programmed telling the time and date" - For that you would just by a simple clock.

OLED screen is really good looking for both indoor and outdoor and I think you have made a good choice.
You need the following things to complete your project easily.

Display (which you have already found one
Arduino (why? easy to program, lots of libraries available, and also tutorials)
RTC - Real-time clock - This is another IC (DS1307, for example)

Arduino need not be UNO. You can use ATTiny85 MCU. the programming will be the same as how you program a UNO. ATtiny85 has no builtin I2C, but the libraries are there to emulate I2C to be connected to OLED displays.
If you want to avoid the third option, go with internal timekeeping alone. But, over a week, you will see the time difference (the internal clocks of the MCU are not accurate, so the time will lead or lag over a period of time)
have you thought about a keypad or a single button to give the option to the user to set the time?

This is just a prototype, the end product should be able to connect to your smartphone, so it can just use the wifi and your phone to get the time going. As per the screen, I am not trying to spend $50 on a screen; I would like it to be cheaper; I think I will go with the OLED screen and an Arduino Nano. I will ditch the clock for now, as that's only half of the prototype I am creating.

The screen you reference is an input only device, that is, it accepts output from other sources and presents the information. It is not, per se, a stand-alone computer for processing information in the manner you describe.

Image above courtesy linked Amazon site.
One option you can consider is a device known as Sparkfun Microview.

Image above courtesy to linked Amazon site.
This device is an integrated Arduino with OLED display. That's only half the objective. You'll also have to have a programming interface (referenced on the site) as well as an external input for RTC (real time clock). Rather than provide a link, an Amazon search for "Arduino RTC" returns many options. Kit form (assembly required (minor soldering), fully assembled, with and without battery.
All of the above requires, at a minimum, a power source for the Microview and a breadboard on which to make the connections. One can, of course, design a PCB to consolidate the components.
The programming portion is easily accomplished (relative reference) by researching that aspect via the internet. There are tutorials for the Microview, which by necessity include Arduino programming, as well as supplemental tutorials for the RTC. Sparkfun is known (by me) for providing good online support via these tutorials.
If you decide to travel this route to your goal, you may have Arduino specific questions which would be acceptable to this SE.


text:
How to get the sizeof array of structs
I'm trying to make a use of a relay module,
I want a clear way to configure and control my relay module
I've defined the struct and filled it with some info about id, pin number, title, and relay state
I can't loop with for in the array of controls, because I can't get the sizeof the array right
typedef struct{
  int id;
  int pin;
  String title;
  bool state;
}  SwitchControl;

SwitchControl controls[2] = {
  {1, 22, "Switch 01", 1},
  {2, 23, "Switch 02", 0},
};

for(int i=0; i<sizeof(controls) - 1; i++){
}

thanks

This is really a C++ question more than anything.  In case you're wondering the Arduino source preprocessing has no effect on this.

Try (sizeof(controls)/sizeof(controls[0]) or better (sizeof(controls)/sizeof(SwitchControl))

for (const auto &e: controls) {   or std::size if you happen to have that.   still seems like a C++ question really.

I would code a const right above, eg. MAX_CONTROL, which keeps later code clean and (I think) faster, as C++ doesn't have to calc anything each time it's used.

@dandavis, A constant expression like one involving the division of the result of two sizeof operators will be evaluated at compile time in pretty much any compiler.  Or at least those made after about 1992 or so.

To make it generic, you simply divide the sizeof the array by the sizeof the type:
for(int i=0; i<sizeof(controls)/sizeof(SwitchControl); i++){
}

Then you can later change the items if the array, or the structure and the code will be the same.

A more generic way (usable in future cases) is:
// number of items in an array
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

Now you can use ARRAY_SIZE (the_array) in your code like this:
for(int i=0; i<ARRAY_SIZE (controls); i++){
}

The above works in C as well as C++.

The more C++ way of doing it is to use a template like this:
// number of items in an array
template< typename T, size_t N > size_t ArraySize (T (&) [N]){ return N; }

Now ArraySize(the_array) returns the number of elements in the array:
for(int i=0; i< ArraySize (controls); i++){
}

The "Arduino language" is C++ with some initial pre-processing. For all intents and purposes any tutorial on C++ will help you with Arduino programming (except that the Standard Template Library (STL) is not included by default).

I don't know why you were subtracting 1 in your posted code. Did you not want to iterate through the whole array?

sizeof(controls) returns the size, in bytes, of the entire object which is not what you want.  You want the number of elements.
I'll point out that since you're statically allocating this as:

SwitchControl controls[2]

The size you are looking for is always going to be 2.  So just use 2 in your for loop like:

for(int i=0; i<2; i++)

The number of elements is 2 for now. But the point in using sizeof() with statical allocation is, that you can easily add more elements to the array, without changing all the for loops in your code. It is highly probable, that the shown code of the OP is just a test code, and that the final code might have more elements and the number of elements might change between different iterations of the code. While your suggestion works, it is not a good tip to do so.

I think you're reading a lot more into this question that is currently there.  Yes, you are correct but sometimes you need to walk before you can run.


text:
Does anybodyknow how to program Muscle Sensors v3?
#include <Servo.h>

const int x =  200

//Naming the servosServo
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;

void setup()
{
  Serial.begin(9600);
  servo2.attach(10);
  servo3.attach(11);
  servo4.attach(3);
  servo5.attach(6);
  servo6.attach(5);
}

void loop()
{
  //Printing the EMG data
  Serial.println(analogRead(0));

  if (analogRead(5) > 200)
  {
    servo2.write(180);
    servo3.write(148);
    servo4.write(89);
    servo5.write(180);
    servo6.write(180);
  } else if (analogRead(0) < 200)
  {
    servo2.write(38);
    servo3.write(10);
    servo4.write(0);
    servo5.write(16);
    servo6.write(16);
  }

  delay(100);
}

I don't know if the problem is in the code or in the circuit.

En este web site se habla inglés. ¿Puedes editar tu pregunta y traducirla al inglés?

I'm assuming you're referring to this?

you said nothing about a problem that you are seeing ... remove all of the servo code ... reduce your code to read sensor and print the value to serial monitor


text:
Most precise way to measure linear distance travelled by a wheel
Suppose a bot with wheels is traveling in a a straight line, and we want to measure this linear distance traversed by it as accurately as possible.
One of the ways is to use an optical encoder to measure the angle of rotation of the wheels and get the linear distance traveled.
Another way could be to use the data from accelerometer and get the linear distance traveled.
Which of these two methods would be better? Is there a third method which is more precise than the previous two?

Calculating speed and distance traveled purely by integrating (twice) the input of an accelerometer is complex and will never be very accurate (small measurement errors will add up to large errors). My recommendation would be to use the optical encoder and circumference of the wheels for this as it's much simpler and more accurate.

If you use an accelerometer, you have to integrate twice to arrive at distance travelled. These two integrations will also compound errors and noise, so the result won't be very accurate without many corrections.
If a wheel doesn't slip and is undriven, the results of counting wheel rotations should be fairly accurate when the robot is moving in a straight line.
Dragging a cheap computer mouse behind the robot and reading its output could also work, but I haven't tried that one yet.
The most accurate, if you can set up a flat object that reflects well enough at the destination of the robot, is probably LIDAR. Not cheap, but easy enough to do as long as the robot moves in a straight line.
Another option would be to count wheel rotations, and calibrate with LIDAR (or GPS for very long distances) and use the calibrated wheel rotations in the final version, or use two or more methods and do sensor fusion.

If you measure  one of the free running wheels (with no motor connect to it), it depends on the traction of the wheel, but that could be fairly accurate.
If you move horizontally a simple accellerometer (1 axis) would be great. But if you have a vertical component, then you can not distinct between accelleration and weight force (Einstein). If you use a 3 axes accellerometer, you can compute/extract the robots moving speed (subtract the G component = 9.81 m/s²) and thus the distance. You have to use vector arithmetic in this case.
If the ground has enough "structure" you could use an optical sensor (like optical mice have).
If you have a reference object (e.g. a wall, a book) you could use a LIDAR sensor (https://en.wikipedia.org/wiki/Lidar) to measure the absolute distances at time points and compute the relative distance between these time points.

A comment on the idea of the free-running wheel.  Back in the 1970s  the standard method used by engineers at General Motors was a "fifth wheel" attached to rear of the car.  It was an ordinary bicycle wheel that was free to bounce up and down on a pivoting hitch.  We could look out the rear window and see it bouncing.  But it was always dead-on accurate since it had enough rotational inertia to keep the speed, even though it was airborne much of the time.


text:
Connect 12V 38A battery to SIM800C GSM Module
I have a gsm module that is rated for 12V and 1A. And I also have a drone Battery that is 12V and 38A. Would it hurt the gsm module If I connect it to this high power Battery?
I heard It's voltage that goes through forcefully, but current doesn't force it self through. So would it be safe to connect?

Your picture is of a HP server power supply. What does it have to do with the question?

@StarCat IT'S HAS THE SAME OUTPUT, WHAT'S THE DIFFERENCE?

The difference is: One is a battery, the other is a mains connected power supply. Do you have a datasheet of your battery? Are you sure your battery is 38A and not 38Ah? Because that would be much more useful information than a picture of a random power supply that has nothing to do with your question. Anyway, you can connect your battery and all will be fine (probably) because your SIM module will only use the current it needs.

@StarCat It's Turnigy LiPo pack with current upto 38A
https://youtu.be/EYkd6c6Gqyg?t=308

I really don’t want to watch a Youtube video, but it will probably do the job.

When choosing a battery there are three basic parameters that need to be considered:

Voltage
Capacity
Max. current draw

In your case you have listed the requirement as 12V 1A which means you need 12V and the maximum current need is 1 Amp.  You have said nothing about capacity, which is how much energy is stored in the battery so I assume it's not important here.
Your proposed 12V 38A battery will work just fine since it's still 12V and the 38A is simply the maximum current draw, not the minimum.  The battery will provide up to 38A but will also source less.
Be careful, though.  If you create an accidental short circuit there is a large amount of energy stored in a 38A type battery and it will be discharged very quickly indeed, possibly causing a fire.  Be sure to properly insulate your wires and connections.

I looked up the SIM800C GSM Module, and it seems it requires a Lithium Ion or Lithium polymer battery, and has a built-in charging circuit in it. (It sounds like it uses the battery to manage peak current demands.) Thus you MUST use a rechargeable lithium battery for it. Having a higher current battery should be fine as long as the voltage is correct.


text:
How can I have different routines fire off at different intervals
I'm making an interface that will have a digital clock....once a second..
I'd like to do other things at different intervals but if I delay(1000) then I have to wait that second which is now the minimum other things have to run at.

this has been asked over and over ... study the blinkWithoutDelay example sketch in the arduino IDE and please, do some research ... akso look into FSM (finite state machine)

You can also Google and research "nonblocking cooperative multitasking." I've written about it pretty extensively in my answer here: https://stackoverflow.com/a/50032992/4561887. Start with Blink Without Delay though first to get the gist of the concept.

https://github.com/jandrassy/KitchenTimerClock/blob/master/KitchenTimerClock/KitchenTimerClock.ino

As said in the comments: you should read up on State Machines and have a close look at the Blink Without Delay example.
To get you started with an example closer to what you want to achieve, have a look at the code below; it will count seconds without blocking the loop.
unsigned long int secondsTimerMillis;
int seconds, minutes, hours = 0;
int secondsInterval = 1000; //ms

void setup() {
  Serial.begin(9600);
  // More setup() stuff goes here
  secondsTimerMillis = 0;
}

void loop() {
  if ((millis() - secondsTimerMillis) >= secondsInterval) {
    seconds++;
    secondsTimerMillis = millis();
    Serial.println(seconds);
    // More stuff you want to do every second goes here
  }
  // More loop() stuff goes here
}

This is just the basic mechanism, and it won't be very accurate without some way of adjusting the clock every now and again.
You will also have to add code for checking seconds == 60 and increase minutes / reset seconds when needed; the same goes for hours.
Having/handling other events at other intervals is just more of the same.
Note that using a Real Time Clock as the basis for your timing would make your life programming much easier, and your clock more accurate, but I am assuming you want to do this "by hand".

If you want a clock, your best option is... to buy a clock. Or, more
precisely, an RTC module. Not only will it be way more accurate than
your Arduino, it will also be able to keep the time off battery when
your project is powered off.
If you really want to rely on the (unreliable) timing capabilities of
your Arduino, you may want to try the millis()-based fake RTC provided
by the Adafruit RTClib library: RTC_Millis. Example
usage:
#include <RTClib.h>

RTC_Millis clock;

void setup() {
    Serial.begin(9600);
    clock.begin(DateTime(F(__DATE__), F(__TIME__)));
}

void loop() {
    static DateTime last_time;
    DateTime now = clock.now();
    if (now != last_time) {
        char buffer[] = "hh:mm:ss";
        Serial.println(now.toString(buffer));
        last_time = now;
    }
}

Note the test if (now != last_time), which is equivalent to the test
if (currentMillis - previousMillis >= interval) of the Blink Without
Delay tutorial (the RTC has a resolution of one second). It allows the
code to be non-blocking.
Note also that, if you are willing to measure you clock's drift rate,
you could calibrate-out that drift by using RTC_micros instead,
and calling the adjustDrift() method in setup().


text:
Apply patch to library for custom changes in Arduino IDE
I wish to obtain unix epoch timestamps in millisecond precision. I am using an ESP32 along with DS3231 RTC breakout board from adafruit.
Apparently the Repository is not maintained often but I see a PR which overcomes the rollover for software timer and the developer provided a patch in the comment to use the unix timestamps in ms.
I went to the libraries folder where all the downloaded adafruit repos exist. But when I did  git status it mentions that the library download (from the library manager) is not a git repository.
I wan't to inculcate the changes to the RTClib library by using the patch provided. Should I just change the code directly via the Arduino IDE editor?

Save the patch to a file, put it in the directory holding the library,
open a terminal on that directory and type:
patch -p1 < patchfile

You may have to install the "patch" utility if you don't have it yet. On
a Debian-like OS (I don't know for other OSes):
sudo apt install patch

Well I blundered and cloned a fork from your repo and added the patch to it. Added this updated repo to the IDE. I think I will revert back to your method.


text:
How to receive and process a long string sent over serial?
I want to receive about 5kb of data in Base64 format. The following code does not work. Only a few characters are received, sometimes CPU crashes.
String content = "";
char character;

while (Serial.available()) {
       character = Serial.read();
       content.concat(character);
}

I do not care about ram usage since on ESP32 there is plenty.
How can I get all the data? Example input: https://pastebin.com/wYG5AhHK

I can see no logical cause, other than maybe you want to yield() within your while loop. You can also pre-allocate the space in your string to reduce heap mangling. content.reserve(6000); Better would be to not use String at all but use a large statically allocated character array.

I had to read until delimiter :D
String receive() {
        String content = "";
        content = Serial.readStringUntil('\r');
        return content;
    }

Now it is fine. I will also change String to large char array.

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


text:
How to use ESP8266 Pin D3 / GPIO 0 and D8 / GPIO 15 properly
I am using WeMos D1 Mini Pro to control multiple relays. I found out that during start up the relay connected to pin D3 and D8 would switch between on and off a couple times in a very short interval. I found out that the two pins are related to boot loader configuration.
Question is: Is there any way to prevent the relay from "blinking"? Is there a way to disable the relay output until boot loader finish it's stuff? Because this behavior only occur once every boot up.

GPIO0 comes in HIGH, so keep it HIGH in setup() and after to avoid state changes (use NC if needed). GPIO15 should not get to full HIGH voltage during boot, so connecting the relay via diode or resistor, or using a high-value shunt resistor to divide the current, or using a cap to suck up that "inrush" should be enough to allow switching while preventing boot state toggling.

A 74HC244 can be used to buffer up to 8 outputs and isolate them at will from the ESP8266. It can also be used for inputs as well if you connect gates the other way around. One additional IO line is required to control it.

Thank you for the input. That might work but I am looking more toward a software solution if there is any =)

No, there is no software solution. Any software you install runs after the bootloader, and you can't do anything to the bootloader except select the boot source using the troublesome GPIO pins you have already identified.

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


text:
Arduino receive response from SIM800H to AT+CCLK? command
I've been trying to make a program that interacts with SIM800H trough AT commands. It worked with the String class, but it was full of "memory leaks" and after a few hours it just hanged. Then I tried to write it again with char arrays, but for some reason I couldn't get it to work properly.
Can someone suggest me a correction to my program and also a way to get char by char with loop and Serial.read();? Serial in this case (Arduino Leonardo) is the USB port and Serial1 is the port to the modem.
Here is my code:
const long interval = 2000;
static long currentMillis;

char wherecclk = 0; // To determine where is the + in +CCLK in the char array

char serialdata[256] = ""; // Array to store the chars before parsing

char rtcy1[3]; // Current year  Format: yy\0
char rtcm1[3]; // Current month  Format: mm\0
char rtcd1[3]; // Current day  Format: dd\0
char rtch1[3]; // Current hour  Format: hh\0
char rtcmm1[3]; // Current minute  Format: mm\0
char rtcs1[3]; // Current second  Format: ss\0

int rdpos = 0;

void setup() {
  Serial.begin(9600); // USB to Computer
  Serial1.begin(9600); // UART to Modem
  Serial1.print("ATE0\r"); // Disable echo
}

void loop() {
  wherecclk = 0;
  if (Serial1.available () > 0) { // when something comes on real serial
    strcpy(serialdata, "OK\n\n+CCLK: \"04/01/01,01:35:31+00\"\n\nOK\n"); // This is a real sample of the response coming from the modem emulated

    while (rdpos < 256) { // loop timeout: 256 bytes
      if (serialdata[rdpos] == '+') {
        break; // We have reached the first + char. Stop incrementing it
      }
      rdpos++;
    }

    if (serialdata[rdpos + 1] == 'C' && serialdata[rdpos + 2] == 'C' && serialdata[rdpos + 3] == 'L' && serialdata[rdpos + 4] == 'K') { // If the serial command mathes +CCLK save its position
      wherecclk = rdpos;
    }
    rdpos = 0;

    if (wherecclk != 0) {
      rtcy1[0] = serialdata[wherecclk + 8]; // getting first char with its offset
      rtcy1[1] = serialdata[wherecclk + 9];
      rtcy1[2] = '\0';
      rtcm1[0] = serialdata[wherecclk + 11];
      rtcm1[1] = serialdata[wherecclk + 12];
      rtcm1[2] = '\0';
      rtcd1[0] = serialdata[wherecclk + 14];
      rtcd1[1] = serialdata[wherecclk + 16];
      rtcd1[2] = '\0';
      rtch1[0] = serialdata[wherecclk + 17];
      rtch1[1] = serialdata[wherecclk + 18];
      rtch1[2] = '\0';
      rtcm1[0] = serialdata[wherecclk + 20];
      rtcm1[1] = serialdata[wherecclk + 21];
      rtcm1[2] = '\0';
      rtcs1[0] = serialdata[wherecclk + 23];
      rtcs1[1] = serialdata[wherecclk + 24];
      rtcs1[2] = '\0';
    }
  }

  if (millis() - currentMillis >= interval) { // This is done every second
    Serial1.print("AT+CCLK?\r"); // ask for the time
    // delay(50);
    Serial.println("");
    Serial.println("=====");
    Serial.println(millis());
    Serial.println("YEAR: ");
    Serial.print(rtcy1[0]);
    Serial.println(rtcy1[1]);
    Serial.println("MONTH: ");
    Serial.print(rtcm1[0]);
    Serial.println(rtcm1[1]);
    Serial.println("DAY: ");
    Serial.print(rtcd1[0]);
    Serial.println(rtcd1[1]);
    Serial.println("HOUR: ");
    Serial.print(rtch1[0]);
    Serial.println(rtch1[1]);
    Serial.println("MINUTE: ");
    Serial.print(rtcmm1[0]);
    Serial.println(rtcmm1[1]);
    Serial.println("SECOND: ");
    Serial.print(rtcs1[0]);
    Serial.println(rtcs1[1]);

    currentMillis = millis();
  }
}

Here is the output (a screenshot, because serial monitor doesn't give me full code):

You declare your variables for month and minute differently (rtcm1[3] vs rtcmm1[3]), but you load rtcm1 with month, and then a few lines later, with minutes.

Silly me! I guess I overlooked the typo and thought it's some other error

Here's the final code in case someone needs it:
const long interval = 1000;
static long currentMillis;

char wherecclk = 0; //To determine where is the + in +CCLK in the char array

char serialdata[256] = ""; //Array to store the chars before parsing

char rtcy1[3]; //Current year  Format: yy\0
char rtcm1[3]; //Current month  Format: mm\0
char rtcd1[3]; //Current day  Format: dd\0
char rtch1[3]; //Current hour  Format: hh\0
char rtcmm1[3]; //Current minute  Format: mm\0
char rtcs1[3]; //Current second  Format: ss\0

int rdpos = 0;

int pointingfinger = 0;

void setup() {
  Serial.begin(9600); //USB to Computer
  Serial1.begin(9600); //UART to Modem
  Serial1.print("ATE0\r"); //Disable echo
}

void loop() {
  if (Serial1.available () > 0) { //when something comes on real serial
    rdpos = 0;
    wherecclk = 0;
    if (pointingfinger == 255) {
      pointingfinger = 0;
    }

    serialdata[pointingfinger] = Serial1.read();

    while (rdpos < 256) //loop timeout: 256 bytes
    {
      if (serialdata[rdpos] == '+') {
        break; //We have reached the first + char. Stop incrementing it
      }
      rdpos++;
    }
    if (serialdata[rdpos + 1] == 'C' && serialdata[rdpos + 2] == 'C' && serialdata[rdpos + 3] == 'L' && serialdata[rdpos + 4] == 'K') { //If the serial command mathes +CCLK save its position
      wherecclk = rdpos;
    }

    pointingfinger++;
  }

  if (millis() - currentMillis >= interval) //This is done every second
  {
    pointingfinger = 0;
    //Serial.println("=========");
    //Serial.println(serialdata);
    //Serial.println("=========");
    if (wherecclk != 0) {
      rtcy1[0] = serialdata[wherecclk + 8]; //getting first char with its offset
      rtcy1[1] = serialdata[wherecclk + 9];
      rtcy1[2] = '\0';
      rtcm1[0] = serialdata[wherecclk + 11];
      rtcm1[1] = serialdata[wherecclk + 12];
      rtcm1[2] = '\0';
      rtcd1[0] = serialdata[wherecclk + 14];
      rtcd1[1] = serialdata[wherecclk + 15];
      rtcd1[2] = '\0';
      rtch1[0] = serialdata[wherecclk + 17];
      rtch1[1] = serialdata[wherecclk + 18];
      rtch1[2] = '\0';
      rtcmm1[0] = serialdata[wherecclk + 20];
      rtcmm1[1] = serialdata[wherecclk + 21];
      rtcmm1[2] = '\0';
      rtcs1[0] = serialdata[wherecclk + 23];
      rtcs1[1] = serialdata[wherecclk + 24];
      rtcs1[2] = '\0';
    }
    Serial1.print("AT+CCLK?\r"); //ask for the time
    //delay(50);
    Serial.println("");
    Serial.println("=====");
    Serial.println(millis());

    Serial.println("YEAR: ");
    Serial.print(rtcy1[0]);
    Serial.println(rtcy1[1]);
    Serial.println("MONTH: ");
    Serial.print(rtcm1[0]);
    Serial.println(rtcm1[1]);
    Serial.println("DAY: ");
    Serial.print(rtcd1[0]);
    Serial.println(rtcd1[1]);
    Serial.println("HOUR: ");
    Serial.print(rtch1[0]);
    Serial.println(rtch1[1]);
    Serial.println("MINUTE: ");
    Serial.print(rtcmm1[0]);
    Serial.println(rtcmm1[1]);
    Serial.println("SECOND: ");
    Serial.print(rtcs1[0]);
    Serial.println(rtcs1[1]);

    currentMillis = millis();
  }
}


text:
Connect NodeMCU with USB camera
I am trying to connect a USB camera to my NodeMCU v0.9.

VCC  Red             +5V
D-       White           Data
D+       Green           Data
GND  Black           Ground

I dismantled the USB cable and connected the VCC cable to 5 V and the black ground cable to GND.
Now I have a DATA + and DATA - cable from the USB, which I connected to the D5/D6 GPIOs of the NodeMCU. I can now read the digital signal of the camera.
But I am not quite sure how to process the data cable's signal. I am not familiar with the USB data + / - cable concept.
Any ideas on how I can process the video image ?

You can't. USB is complex, and the video data over it even more complex.

https://www.cnx-software.com/2016/08/08/esp8266-gets-usb-support-thanks-to-espusb-software-stack/

A) that's device mode, not host mode. B) that's low speed which means keyboard and mouse only.

no, but you can get a camera that connects by serial or SPI or i2c

You can't. It's as simple as that. To do it you require:

An MCU or MPU with a USB Host or OTG module built in.
Drivers for that module to enumerate the device
Drivers for the specific device you are connecting
Software to deal with the data provided by the device.

The ESP8266 has none of those.
Sounds to me like you want a Raspberry Pi.


text:
MKR1010 disconnects and reconnects normally until it reaches a point where it never reconnects again
The board does reconnect from time to time, but there are times where it just disconnects and never reconnects again and I can't replicate the error because while I run it with Serial open and turn ON and OFF my WiFis it always reconnects as it should.
#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include <EmonLib.h>

EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
int INTERVAL = 60;
int last_code = 0;

char ssid[] = "MySSID";
char pass[] = "MyPW";

String ID = "Garden_Pump_Sensor";

int sequence = 0;
double kWh = 0.0;

char serverAddress[] = "192.168.1.108";  // server address
int port = 5005;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);

int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  analogReadResolution(9);
  emon1.current(0, 100);
  emon2.current(5, 100);
  emon3.current(6, 100);
  Connecting();
}

void Connecting() {
  int tries = 4;
  while ( (WiFi.status() != WL_CONNECTED && tries > 0) || last_code != 200) {
    Serial.print("Status #1: ");
    Serial.println(WiFi.status());
    WiFi.begin(ssid, pass);
    Serial.print("Status #2: ");
    Serial.println(WiFi.status());
    tries--;
    last_code = 200;
  }

  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void reconnecting() {
  if (WiFi.status() != 3  || (WiFi.RSSI() <= -90) || (WiFi.RSSI() == 0) || last_code != 200) {
    WiFi.end();
    Connecting();
  }
}

void loop() {
  unsigned long delayTime = INTERVAL * 1000;
  unsigned long time_start = millis();

  DataMonitorAndSend();

  unsigned long time_final = millis() - time_start;
  unsigned long delay_value = delayTime - time_final;
  Serial.println(delay_value);
  if (delay_value < 1  || delay_value > delayTime) {
    return;
  } else {
    delay(delay_value);
  }

}

void DataMonitorAndSend() {
  reconnecting();

  Serial.println("making POST request");
  String contentType = "application/json";
  kWh = kWh + getKWH();
  String postData = "{\"ID\": \""+ID+"\",\"seq\": " + String(sequence) + ",\"kWh\": " + String(kWh, 6) + "}";
  Serial.print("data: ");
  Serial.println(postData);

  client.setHttpResponseTimeout(5 * 1000);
  client.post("/receivedata/", contentType, postData);

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  if (statusCode == 200) {
    kWh = 0;
    sequence++;
  }
  last_code = statusCode;
  Serial.print("Response: ");
  Serial.println(response);

}

double getKWH() {
  int LOOPS = 15;
  double kWh_Total = 0.0;
  unsigned long delayTime_kwh = 2 * 1000;
  for (int i = 0; i < LOOPS; i++) {
    unsigned long time_start_kwh = millis();

    double Irms1 = emon1.calcIrms(600);
    if (Irms1 < 0.3) Irms1 = 0;
    double Watt1 = (Irms1 * 230) / 1000;

    double Irms2 = emon2.calcIrms(600);
    if (Irms2 < 0.3) Irms2 = 0;
    double Watt2 = (Irms2 * 230) / 1000;

    double Irms3 = emon3.calcIrms(600);
    if (Irms3 < 0.3) Irms3 = 0;
    double Watt3 = (Irms3 * 230) / 1000;

    kWh_Total = kWh_Total + ((Watt1 + Watt2 + Watt3) / 60);

    unsigned long time_final_kwh = millis() - time_start_kwh;
    unsigned long delay_value_kwh = delayTime_kwh - time_final_kwh;
    if (delay_value_kwh < 0  || delay_value_kwh > delayTime_kwh) {
      delay(0);
    } else {
      delay(delay_value_kwh);
    }

  }

  return kWh_Total / LOOPS;
}

Feel free to ignore the getkWH(), it's code related to power consumption. Also the firmware is up to date and the server is using a static IP.

A quick answer (so take it for what it is worth): If using Windows, I have had different versions of Windows decide on their own a particular network was bad, stop communicating over it and not say a word about it.  Switching to Linux the network problems all became clear and, finally, problems could be easily solved.

Thank you, but for the server, I'm using a raspberry pi / raspbian OS running a simple Flask Server. I have actually this server for other projects and had no issues, I think the issue is that the mkr is not sending /hangs somewhere and not a case of the server not receiving since I sent requests from other sources into it and it works fine.

Since you only send a data every 60s, it is better to only establish a WiFi when you need it, AND only create an instance of HttpClient after that. That's means that it only creating the wifi and client instances when you need it instead of using a global instances. Here is a way I usually do for such an application that I modified based on your sketch, you could give it a try. Please noted that only the  changes that I made are highlighted in my code snippet, please fill-in the rest of your code:
unsigned long INTERVAL = 60000;  // in milliseconds
unsigned long time_start = millis() + INTERVAL;    // noted that I changed this to a global variable and to unsigned long

// WiFiClient wifi;
// HttpClient client = HttpClient(wifi, serverAddress, port);

void Connecting() {
  WiFi.disconnect();
  WiFi.begin(ssid, pass);
  Serial.print("Connecting to ");
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println(" Connected");

  // your code for printing localIP
}

void loop() {

  if (WiFi.status() != WL_CONNECTED)
    connecting();

  // send data when INTERVAL is reached
  if (millis() - time_start > INTERVAL) {
    DataMonitorAndSend();
    time_start = millis();
  }

  yield();

}

void DataMonitorAndSend() {
  // reconnecting();

  WiFiClient wifi;
  HttpClient client = HttpClient(wifi, serverAddress, port);

  // rest of your DataMinitorAndSend() code

  client.end();

}

I found that before using WiFi.begin() to re-connect, one needs to use WiFi.disconnect() first. At least that keeps my set-up reliably re-connecting, when its battery is empty or my router is out for a moment. Also, testing for WL_CONNECTED or 3 only means that one's set-up is connected to the router, but the router not necessarily yet to the internet; in case of a restart of the router after a power outage. On one of my routers, one has to wait 10 seconds, on another 18 seconds.
void connectToWLAN()
{
  // Check if the AirLift FeatherWing's WLAN module works
  if (WiFi.status() == WL_NO_MODULE)
  {
    Serial.println("Connection to AirLift FeatherWing WLAN module failed");

    // If not, indicate there is a WLAN module malfunction
    WiFi.setLEDs(0, 255, 0); // Red

    // And stop forever
    while (true);
  }

  // Return to loop() if already connected to the WLAN router
  if (WiFi.status() == WL_CONNECTED)
  {
    return;
  }

  Serial.println("Trying to connect to WLAN router");

  // Indicate there is no WLAN router connection just yet
  WiFi.setLEDs(192, 255, 0); // Yellow

  do
  {
    // Start connection to WLAN router and print a status value
    WiFi.disconnect();
    delay(1000);

    status = WiFi.begin(WLAN_SSID, WLAN_PASS);
    // WL_IDLE_STATUS     = 0
    // WL_NO_SSID_AVAIL   = 1
    // WL_SCAN_COMPLETED  = 2
    // WL_CONNECTED       = 3
    // WL_CONNECT_FAILED  = 4
    // WL_CONNECTION_LOST = 5
    // WL_DISCONNECTED    = 6
    Serial.println(WiFi.status());
    delay(10000);
  }
  while (status != WL_CONNECTED);

  Serial.println("Connection to WLAN router successful");

  // Indicate that the WLAN router connection was established
  WiFi.setLEDs(255, 0, 0); // Green

  // To better see the status indicating RGB LED's state
  delay(2000);
}


text:
ESP32 changing frequency instead of duty cycle
Using this code on an ESP32 allows varying the duty cycle of the PWM with a fixed 5000 Hz frequency; it is working fine.
How do I vary the frequency and keep the duty cycle at a fixed value?
// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;

void setup(){
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);

  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledChannel);
}

void loop(){
  // increase the LED brightness
  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }

  // decrease the LED brightness
  for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }
}

Hm. Right, sorry

Use ledcWriteTone ?

Why remove points on the question? changing the frequency will be helpful if you are working with a stepper motor for example.

If you want to change the pwm frequency during runtime there is a function ledc_set_freq() for this purpose. I'm not sure if your duty cycle will remain valid, but I guess it does as long as the resolution does not change. You will have to try that on your own and eventually implement a compensation.

I tried using ledc_set_freq but the issue is that if do it very quickly then is not set it anymore. If I do this on a normal arduino using pwm library i can change pin frequency each 50ms and is fine.


text:
Connect 5V relay to ESP32 WROVER B board
I need to use a ESP32 WROVER B based MCU board with a standard (cheap) one-channel 5 V relay (e.g. to switch on a mains-power appliance).
Attempted removal of excess solder around the headers permanently disabled the 5 V power output line from the board (to power a relay or other modules), but other pins functional/board boots up correctly.
So at present, there is only a 3.3 V power source and 3.3 V GPIO pins (and others such as for external microphone and speaker).
I assume it is safe to connect a 3.3 V GPIO from the MCU to IN and external 5 V power source to VCC ad GND of the relay and connect the grounds of the MCU and relay together to complete the circuit.
The relay only needs to switch the appliance on when triggered (for example a lamp) and switch off when triggered again. I have a 3.3 ↔ 5 V bidirectional level shifter, but don't think it is suitable here (unless it can be incorporated directly). An alternative maybe is to use an Arduino Uno to connect with the relay, itself triggered by the ESP32 and more complex circuitry (bearing in mind the ESP32's GPIO is 3.3 V and the Arduino's is 5 V).

Assuming a relay module: check if it is OK to drive it with 3.3 V logic when it is on a 5 V power supply, or show the specs for us to look at.
Driving a relay module with 3.3 V logic is unlikely to harm the ESP32, but it may not drive the relay properly if the relay module expects 5 V logic.
Generally, I would even prefer using an external power supply rather than the 5 V pin on a microcontroller board to power a relay module.
As long as you connect everything as you describe, it should work just fine (if the relay module accepts 3.3 V logic).

These "digital relay" modules are available in 3.3V and 5V versions. Simply buy one of the 3V models. Here is one, for example: https://www.dfrobot.com/product-1572.html


text:
DFplayer, Play sound when pin is high
I have a code here, from DFmini player. I have a tactile switch. when I press it on and release it will play a sound. My question is that when I press the tactile but not release it so I want it still play the same sound.
But while the tactile switch is pressed down it keeps repeating the same sound. I want it to play just for once while the tactile button is still pressed down.
//#include <SoftwareSerial.h>   //If we use other pins than D0 adn D1 for TX and RX for the music player
#include <DFMiniMp3.h>          //Downlaod here: https://electronoobs.com/eng_arduino_DFPlayer_Mini_Mp3_by_Makuna.php

int sw1 = 3;
int sw2 = 4;
int sw3 = 5;
int sw4 = 6;
int sw5 = 7;
int sw6 = 8;
class Mp3Notify
{
public:
  static void OnError(uint16_t errorCode)
  {
    // see DfMp3_Error for code meaning
    Serial.println();
    Serial.print("Com Error ");
    Serial.println(errorCode);
  }

  static void OnPlayFinished(uint16_t globalTrack)
  {
    Serial.println();
    Serial.print("Play finished for #");
    Serial.println(globalTrack);
  }

  static void OnCardOnline(uint16_t code)
  {
    Serial.println();
    Serial.print("Card online ");
    Serial.println(code);
  }

  static void OnCardInserted(uint16_t code)
  {
    Serial.println();
    Serial.print("Card inserted ");
    Serial.println(code);
  }

  static void OnCardRemoved(uint16_t code)
  {
    Serial.println();
    Serial.print("Card removed ");
    Serial.println(code);
  }
};

DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial);   //Create the UART connection to the module

void setup()
{
  //3 push buttons with pullups
  pinMode(sw1,INPUT);                        //Define each button as input with pullup
  pinMode(sw2,INPUT);
  pinMode(sw3,INPUT);
  pinMode(sw4,INPUT);
  pinMode(sw5,INPUT);
  pinMode(sw6,INPUT);
  digitalWrite (sw1, HIGH); //12 Votls supply set to off state
  digitalWrite (sw2, HIGH); //5 Votls supply set to off state
  digitalWrite (sw3, HIGH); //3 Votls supply set to off state
  digitalWrite (sw4, HIGH); //Ajustable Votls supply set to off state
  digitalWrite (sw5, HIGH); //3 Votls supply set to off state
  digitalWrite (sw6, HIGH); //Ajustable Votls supply set to off state
  Serial.begin(9600);
  mp3.begin();                                      //Start communication with the DFplayer module
  uint16_t volume = mp3.getVolume();                //Get actual volume
  mp3.setVolume(30);                                //Set new volum (max is 30)
  uint16_t count = mp3.getTotalTrackCount();        //Get the total tracks on the SD card in case we want to sue this later...
}

//just a fucntion that we use to create delays in "ms"
//without using the delay() function
void waitMilliseconds(uint16_t msWait)
{
  uint32_t start = millis();

  while ((millis() - start) < msWait)
  {
    // calling mp3.loop() periodically allows for notifications
    // to be handled without interrupts
    mp3.loop();
    delay(1);
  }
}

void loop()
{
  if(!digitalRead(sw1))
  {
      mp3.playMp3FolderTrack(1);  // Play audio track 0001
      waitMilliseconds(1000);     // 1s of delay
  }

  if(!digitalRead(sw2))
  {
      mp3.playMp3FolderTrack(2);  // Play audio track 0002
      waitMilliseconds(1000);     // 1s of delay
  }

  if(!digitalRead(sw3))
  {
      mp3.playMp3FolderTrack(3);  // Play audio track 0003
      waitMilliseconds(1000);     // 1s of delay;
  }

  if(!digitalRead(sw4))
  {
      mp3.playMp3FolderTrack(4);  // Play audio track 0001
      waitMilliseconds(1000);     // 1s of delay
  }

  if(!digitalRead(sw5))
  {
      mp3.playMp3FolderTrack(5);  // Play audio track 0002
      waitMilliseconds(1000);     // 1s of delay
  }

  if(!digitalRead(sw6))
  {
      mp3.playMp3FolderTrack(6);  // Play audio track 0003
      waitMilliseconds(1000);     // 1s of delay;
  }

}//end of void

Does this answer your question? DFplayer, Play sound based on pressed button

same as your last question ... you have code that does something when you press a button ... you have no code that executes when you release a button ... you also have no code that does anything when the track ends, except for printing a message ... check the messages in the serial monitor

@jsotola, on this line   if(!digitalRead(sw4)), I have to tell the code if the button is held down so do the function. if released don't do. i tried else and break but it doesn't work. don't know what to use to tell the software .

Currently you are checking, if the button is currently pressed. Thus the code inside the if statement will execute as long, as the button is pressed. You want to check for the transition. Have a look at the Bounce2 library, which makes it way easier to check buttons. Then you have if(button.fell()) to check, if the button pin fell (for the press transition), or if(button.rose()) to check, if the button pin rose (for the release transition).

@chrisl, Thanks, the Bounce2 Library was useful and help a lot.

BOUNCE 2
Basically, the mechanical part of buttons and switches vibrate slightly when closed or opened causing multiple undesired false states (similar to noise). This library filters out these undesired state changes. More about debouncing:
John Errington's Experiments with an Arduino : Using digital inputs: Switch bounce and solutions to it
Wikipedia article : http://en.wikipedia.org/wiki/Debounce#Contact_bounce
See the bottom of this page for a basic usage example and the "examples" folder for more.
The library is composed of three classes:
Debouncer : The code that does the actual debouncing. Only advanced users should play with this class.
Bounce : This is the general use library. It links the Debouncer to a hardware pin on your board.
Button : A special version of Bounce for buttons that are pressed.
https://github.com/thomasfredericks/Bounce2


text:
Can we have 2 HC12 on a single Arduino (1 to receive and other to transmit)?
I'm working on a project and I need to send 2 datas and receive them at the same time.
My question is: Is it possible to have 2 Arduinos both have 2 HC12 (total 4), because I want each Arduino to send and receive data at the same time.
It's hard for me to have 4 Arduinos.

You may have to provide a link to this HC12 thing you have.  If you're trying to use a particular library with them you should mention that library also.

Why do you want 2 HC-12s? I thought, that they are already working duplex

It would be good to know what is meant by "two datas".  Two connections? Two items? etc.

i'm using the arduino for a motor in an RC plane (1 arduino in the sky the other is on the ground), i want to control it's speed from the ground by an HC12 (send from ground and recive in the sky)  the other is to send me back number of rotations of the motor (sends from sky and receive from ground) so total 4 HC12 and 2 arduinos

@chrisl The HC-12 is actually half duplex but with a small buffer. For true full duplex you need two pairs of modules.

how can i know if mine is half or full duplex

Yes you can - one on Serial pins 0/1 and the other using SoftwareSerial on any other pins. Note that the one on SoftwareSerial will interfere with the one on Serial as it disables interrupts while sending or receiving.
It may be better to use an Arduino which has multiple hardware serial ports. Maybe one of the Teensy boards would be better for your needs.
Alternatively if (and I am not familiar with the modules enough to know if this is right or not) they operate as a transparent serial bridge then you could connect one module to the TX pin for transmission and the other to the RX pin for reception - reading from serial receives from one, and writing to serial transmits through the other.
Also note that you will have to ensure that both pairs of modules are running on different channels to prevent interference between them.

thank you so much, this is really helpful! can i know if you have any codes that may be helpful

@shamsaalb No. As I say I'm not familiar with the modules. However they look like a transparent serial bridge, so whatever you Serial.print from one end will appear at the other end.

Yes, you just need to connect your TX pin on the RX pin of one HC-12, and your RX pin on the TX pin of the other HC-12, and use separate channels for both HC-12. And then you do the same thing on the otherside, but you need of course, to reverse the channels - Et voila.
However, you might need to take precautions (distancing / shielding) to avoid your emitting HC-12 to parasite the channel of the nearby receiver.
By the way, it seems that one should refrain as much as possible to use SoftwareSerial, which is not robust enough for high speed and seems to cause data distortion.


text:
How to add the previous value to current value from sensor
const byte interruptPin = 4;
void ICACHE_RAM_ATTR count();
void setup() {
  Serial.begin(115200);

  // Set up our digital pin as an interrupt
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), count, RISING);
}

void loop() {

}

void count() {
  volatile float rainrate = 3;
  volatile float rate;
  volatile float total;

  rate = rainrate * 0.1;
  Serial.println(rate);

Every time it tips, it returns 0.3.  How do I add the previous value(0.3) to a new tip, to make it 0.6, and save it into a variable.
Thanks!

hello, no it should be like, if it becomes 0.6 from 0.3, the next tip will be 0.9 and so on.

It may be just me, but I have no idea what you mean by "tip".  Not that it matters, I think you have an effective answer to your question anyway.

Btw, you can make the volatile variables global, by putting them above void Setup.
To put the total (new) value, use:
total += <sensorValue>;

where <sensorValue> is a call to get the sensorValue (or the value that has the sensor value stored in it), but I cannot see that in your sketch.
total += 0.3;

is the same as writing:
total = total + 0.3;

The value right of the '='sign is copied (assigned) to the left part of the '=' sign.

Hello, its working. but I think there's somethings wrong with my code because it outputs as double value. when I tip my tipping bucket reed switch, it outputs as 0.3, 0.6 then stop, next tip will be 0.9, 1.20.

An Arduino does not make a difference between double or float. I'm not sure what you mean it stops at 0.6. The variable total should be increased every time it is (what you call) 'tipping'.

@Giddsec I suspect you are suffering from "button bounce" - google "arduino debounce" for help.

Got it all working, thank you very much! :)

You're welcome; if it helped you, please upvote the answer, if the answer gave the best response, accept it (by using the check mark next to the question). Success with your project.

Why bother doing that arithmetic at every tip, when you could just count tips, and multiply the count by 0.3 whenever a result is needed?
tips += 1;                    // each time the bucket tips.
and
Serial.println(0.3 * tips);   // each time you want a result

Just to add context to this answer: floating point arithmetics can be orders of magnitude slower than integer arithmetics on FPU-less devices (like many Arduinos).


text:
Memory allocation on Arduino Due never returns NULL
I'm working on a project that uses quite a bit of RAM to store and analyze data that is sent from the PC. The program heavily relies on malloc/free, which normally works just fine. However, if the data set gets to big - which I can't tell beforehand - the Arduino just dies. Some analysis found that it has to do with memory management. Running a simple sketch which just does
void loop() {
  int SIZE_TO_TEST = (1024 * 10);
  int* mem = (int*)malloc(SIZE_TO_TEST);
  if (mem == nullptr)
  {
    // This never happens
    Serial.print("Allocation failed\r\n");
    return;
  }
  Serial.print("Allocation succeeded\r\n");
  Serial.print((int)mem, HEX); // this always prints 0x200712E0, regardless of the size
  Serial.println();
  for (int i = 0; i < SIZE_TO_TEST / 4; i++)
  {
    mem[i] = i;
  }

  for (int i = 0; i < SIZE_TO_TEST / 4; i++)
  {
    if (mem[i] != i)
    {
      // You better get a new board if this happens
      Serial.print("HARDWARE ERROR: Memory broken\r\n");
    }
  }
  free(mem);
}

works fine and repeatedly prints "Allocation succeeded". When I start increasing the SIZE_TO_TEST, the CPU crashes when the value is over the effective memory size of 96k. The weird thing is, that even when the value is 1000k (far beyond what the uP actually has), the pointer returned by malloc() is still the same memory address, not NULL, as one would expect. The crash also does not occur if the allocated memory is not used (if the two for loops are commented out), so I suspect the actual crash occurs because the program tries to write to memory that is not actually there.
How do I find out that the memory is exhausted? Why does malloc() never return NULL?
(Note: I know about the problems of memory fragmentation with small micro controllers, but I can work around that issue)

Just seen: The problem is also discussed here: https://forum.arduino.cc/index.php?topic=381203.0. No solution given, though.

The Arduino software is open source.  I'm sure a solution could be found.

I can give you an answer as to why it's failing.  But I can't tell you precisely what you should do about it.

Based on @timemage's answer, I'd suggest opening a bug report on Arduino and also on Newlibc.

On the ArduinoCore-sam project maybe.  I don't believe it's really Newlib's problem at all.

Why
This is a partial answer, for now, mostly with regard to:

Why does malloc() never return NULL?

So, the Due appears to use Newlib as its libc implementation; that is the systems C (standard and some non-standard) runtime that includes malloc(), or the greater part of malloc() anyway.  The Newlib malloc() relies on an  sbrk() function which is implemented by the specific system, the Due in this case.
This name and basic idea comes out of Unix; you can read about the interplay between malloc and sbrk some without it having to be in connection with Newlib or the Due specifically.  In short, sbrk extends the area that malloc has to work with and malloc divides that area into requested chunks.  Here is Newlib's documentation for sbrk and a sample implementation.
The Due (SAM) core for Arduino implements sbrk as:
extern caddr_t _sbrk ( int incr )
{
    static unsigned char *heap = NULL ;
    unsigned char *prev_heap ;

    if ( heap == NULL )
    {
        heap = (unsigned char *)&_end ;
    }
    prev_heap = heap;

    heap += incr ;

    return (caddr_t) prev_heap ;
}

This is a kind of degenerate implementation of _sbrk that just blindly says, "You want more memory, sure here you go" without limit.  If you look at the sample sbrk implementation for Newlib, you'll see it just calls abort() instead of a proper failure that would result in malloc returning NULL, which is admittedly not great, but at least it's not pretending that everything is fine.
There should be a condition somewhere in this code that check so see if there's any more space to be had and sets errno = ENOMEM and effectively does return -1 if there is not.
I modified this code to allow me to set a variable from the sketch that could force the next call to _sbrk to fail as described above.  And sure enough, on the next call to malloc() it returned NULL because _sbrk had indicated failure.
So the _sbrk implementation provided by the Due/sam core should be changed so that malloc fails when appropriate.  That said, I'm not precisely sure how that should be done.  So I'm going to hold off on making specific recommendations about it.  Maybe I look into it more I'll come back and update this with something more useful, addressing your other question of:

How do I find out that the memory is exhausted?

In rough terms though, the answer going to be that you modify that function so it returns -1 with ENOMEM under the right conditions.

How
This is the previously mentioned update with some details on the how:

How do I find out that the memory is exhausted?

So I've made something to give you an idea what the condition would look like.  I'm not strictly recommending you use it; for one thing it's barely been tested.
From the ATSAM3X8E's family datasheet:

SRAM0 is accessible over the system Cortex-M3 bus at address 0x2000 0000
and SRAM1 at address 0x2008 0000. The user can see the SRAM as
contiguous thanks to mirror effect, giving 0x2007 0000 - 0x2008 7FFF
for SAM3X/A8

The stack pointer starts near the top of memory 0x2008 7FFF and grows
downward.  The _end symbol marks the end of the mutable static storage
duration variables or the beginning of the heap.  Somewhere closer to
0x2007 0000; the fewer of these variables the closer.
On this system, which has a fairly common layout, the heap grows up with positive increments to sbrk as the stack pointer grows down with stack frames (local variables, return addresses etc).  So, "the end" of memory happens when the heap would otherwise allocate over the stack or the stack runs into the heap as your pushing things onto it.
So a typical thing to do is to check to see whether or not the sbrk's argument would cause the edge of the heap to get "too close" to the stack.
In the the /.arduino15/packages/arduino/hardware/sam/1.6.12/cores/arduino/syscalls_sam3.c, I've include some extra headers:
#include <errno.h>
#include <stdlib.h>

And put the following as a replacement _sbrk():
size_t __malloc_margin = 4 * (size_t)1024;
extern caddr_t _sbrk (int incr) {
    static const unsigned char *       heap      = (unsigned char *)&_end ;
    /****/ const unsigned char * const prev_heap = heap;

    if (incr > 0) {
        // Extra checks for stack growing

        if (incr >= 96 * (size_t)1024) {
            // The Due only has 96K of ram,
            // so any request for 96K or greater
            // is a failure out of the gate.
            errno = ENOMEM;
            return (caddr_t)-1;
        }

        unsigned char *stack_ptr;

        asm volatile(
            "mov %[sp_out], sp"
            : [sp_out] "=r" (stack_ptr)
            :
        );

        if (stack_ptr < heap) {
            // We're already in real trouble.
            abort();
        }

        if (stack_ptr - heap  <  incr + __malloc_margin) {
            // Not enough memory considering safety margin.
            errno = ENOMEM;
            return (caddr_t)-1;
        }
    }

    heap      += incr ;
    return (caddr_t) prev_heap ;
}

__malloc_margin was used as a variable name just because it's the name that avr-libc uses for the same purpose, namely to tune the minimum distance between the stack and heap during an allocation that the break to increase.  By the way, you can see this same kind of check happen in avr-libc's implementation of malloc (which also takes sbrk's role.)  Why is __malloc_margin 4K ?  No really scientific reason.  It's about 4% of memory, so it's not large, and it's not completely inconceivable to me that someone would try to put local variable(s) approaching 4k in a stack frame on a system that has 96kb total memory.  4K may not be an appropriate default though; more thought should go into that.  Having it in a variable like this allows it to be tuned at runtime; usually there would be a header that provides an extern declaration for it.
I may add more later to explain, but it short if the break is being increased, this sbrk looks to see if the new break would get within __malloc_margin of the stack pointer on a request, an if it would it returns the -1 value and errno = ENOMEM to cause malloc to behave correctly from the user's perspective.
Before anyone bothers to mention: Yes, I know you can take the address of a local to get a stack pointer value.  Yes, the check to see if the single allocation is larger than 96K is probably unnecessary.  Yup, it has Due specific stuff in it even though it's not strictly a Due; there are probably identifiers that could be used instead.  It should probably abort() if sbrk tries to go below 0 sized heap.  It's just a somewhat working illustration of what should be in _sbrk().  More thought and at least one change should be put into it before general use.
Regarding abort()
It occurs to me in some cases abort() may be an appropriate way to handle this.  If you believe that you can characterize the system (or the sketch if you like) at runtime so well that malloc() failing can be regarded as a major oversight, then calling abort() in sbrk() could make sense.  Or at least providing the option to do that.
In the comments you asked:

What does abort() exactly [do] on the Due?

Well, Newlib documentation says:

Before terminating your program, abort raises the exception SIGABRT
(using ‘raise(SIGABRT)’).

and then further down:

Supporting OS subroutines required: _exit and optionally, write.

The SIGABRT and _exit parts are more or less standard behaviour.  So it will call your signal handler for SIGABRT if you have one.
So then what does _exit do?  It loops forever.
I called abort() in a sketch and dumped the following via an arm version of the binutils objdump with -dS command-line options.
Here's the relevant abort() code:
00081b98 <abort>:
   81b98:   b508        push    {r3, lr}
   81b9a:   2006        movs    r0, #6
   81b9c:   f000 fb5c   bl  82258 <raise>
   81ba0:   2001        movs    r0, #1
   81ba2:   f7fe fec5   bl  80930 <_exit>
   81ba6:   bf00        nop

bl <raise> would in turn call your signal handler.  and bl <_exit> calls exit which displays as:
00080930 <_exit>:

extern void _exit( int status )
{
   80930:   e7fe        b.n 80930 <_exit>

00080932 <_kill>:

    for ( ; ; ) ;
}

It appears the optimizer has combined some things here, but essentially _exit has an instruction that jumps (branches) to itself, equivelent to for(;;);.
I half-expected the abort(); code to disable interrupts before calling _exit().  If you do plan on abort() in your _sbrk() that might be something to think about.  You may also want to provide a global flag that can be inspected from SIGABRT that allows the signal handler to do something diagnostically appropriate specifically for _sbrk() failures.
Perhaps sbrk should set a flag in a no-init data section and then set the watchdog timer and let it expire (or provide the SIGABRT handler with the information to do that).  Lots of things to consider.

Can you tell me in which file that implementation of _sbrk is to be found? Looks like a good analysis. Maybe my idea below might help with the missing condition?

It's linked to in the answer "Arduino implements sbrk".  That is syscalls_sam3.c  I'm about to update with some additional information though.

There's some more for you. I'm sure it'll get updated again to correct mistakes if nothing else.

Nice, I'll try this next. Pretty close to what I've been investigating as a workaround. What does abort() exactly on the Due?

I've updated the answer to address what abort() is does on the Due and a little of how that might interact with a replacement  _sbrk().

I think I found a workaround. It relies on the fact that on simple program architectures such as the one used on most microcontrollers, the heap grows upwards while the stack grows backwards.
const int MIN_FREE_STACK = 512;

void* mallocEx(int size)
{
  void* stackPtr = alloca(4); // This returns a pointer to the current bottom of the stack
  PrintAddress("StackPtr ", stackPtr);
  void* ptr = malloc(size);
  PrintAddress("NewInstance ", ptr);
  if ((byte*)ptr + size > ((byte*)stackPtr - MIN_FREE_STACK))
  {
    free(ptr); // This memory location is not really valid
    return nullptr;
  }
  return ptr;
}

The method checks, on each attempt to allocate memory, whether the newly allocated block would reach into the call stack (+ some safety margin). If so, the pointer is freed again and null is returned.
I tried with this a bit more demanding test, and it seems to work as expected (allocates a bunch of blocks until it fails at around 91k, then restarts)

void ValidateMemoryManager()
{
  const int oneK = 1024;
  const int maxMemToTest = 100; // the arduino due has 96k of memory
  void* ptrs[maxMemToTest];
  int idx = 0;
  int totalAllocsSucceeded = 0;
  while (idx < maxMemToTest)
  {
    void* mem = mallocEx(oneK);
    ptrs[idx] = mem;
    if (mem == nullptr)
    {
      break;
    }
    idx++;
  }

  // Happens in simulation
  if (idx == maxMemToTest)
  {
    idx--;
  }

  totalAllocsSucceeded = idx;
  while (idx >= 0)
  {
    free(ptrs[idx]);
    idx--;
  }

   Serial.print("Total usable memory: ");
   Serial.print(totalAllocsSucceeded * oneK, DEC);
   Serial.println();
}

Your answers deserves more love.  I'd considered using alloca() too because it seems like it would resist some unpredictable outcomes from the optimizer.  In the end in I decided to put a tiny chunk of inline assembly in there, but I'm still not sure it is the right choice; alloca might make more sense.  I haven't been through the rest of it to yet thuroughly, but I think I see what you're doing, and if I understand correctly this works almost identically as a non-invasive way of detecting the out-of-memory condition.

@timemage I didn't test this yet, but one point which doesn't work (at least not ouf of the box) with my approach is also correctly supporting new/delete. Could get a bit more complex, because they're not supposed to return null on failure, but throw exceptions. And these are not enabled by default on arduinos.

Right.  It now that I think about I used the term "invasive" with respect to the core.  With respect to your sketch it is.   There are no-throw versions of new and delete, but your point more or less stands.  You would have to replace their implementations to use your custom malloc.  Or alternately use your custom malloc function and then, use a placement-new and explicit destructor call.  If you wanted to go a bit off the rails with it you could define smart pointers that do nothing but that.  Fixing sbrk() is probably better.

@timemage Just tested it: With your fix, new returns null if there's not enough memory left. Seems they got that part right, after all.


text:
Using same GPIO pins to control multiple stepper drives
I have an Arduino Mega 2560 and I want to control four 23-frame steppers same speed/direction for a conveyor application. I want these to be synchronized exactly as possible for smooth operation.

Can four TB6600 drivers be daisy chained to the same Arduino GPIO pins?

Is there a limit to how many number of drivers I can daisy chain?

I'm wondering about current draw from the 5 volt Arduino GPIO, spread out over many drivers.

Thanks for your help!
Bob

daisy chain means connected in series, not connected in parallel ... https://irepo.primecp.com/2016/05/280836/Daisy-Chain-Flower-Crown_Large600_ID-1656864.jpg

Those devices use opto-isolated inputs. To all intents and purposes they look just like an LED with a resistor in series.
The built-in resistor looks like it sets the current to "between 8mA and 15mA" and typically 10mA, though it's impossible to say what it actually is.  So we'll take the worst-case scenario of 15mA.
The Arduino has an absolute maximum of 40mA, and a recommended maximum of 25mA from each IO pin, with a maximum of 200mA in total through all pins.
That means you ideally can't really have more than one TB6600 per IO pin, but you could get away with 2 per pin, certainly no more.
To run lots in parallel you would need a separate set of drivers that can "fan out" the low-current signal to either a single high current signal or a parallel set of low-current signals.
It looks like you provide 5V to one pin of each input (the anode of the opto-isolator) and sink the current through the other pin (the cathode of the opto-isolator) to ground through your IO pins. That means you could use a single large N-channel MOSFET to sink all of the cathodes in parallel and invert your IO logic in software.

So the MOSFET is acting like a relay keeping the IO signal intact (not too much draw on Arduino) while being able to sink the sum total of all tb6600 drivers involved?

@RobertBorn Correct, but also as an inverter, so a HIGH would turn on instead of a LOW as you would normally use for that device.

Please forgive me .. I'm more of a high power electrical guy. Actually I get into way too many kinds of projects :)
In order to not have to mess with my control SW and elegant GUI I paid a college kid to build for me .. could I simply reverse the common to the tb6600 inputs from +5V to ground?
I still need to study the connection of the MOSFET.
Another thought .. I've used these opto-isolated signal boards before. But maybe they are not high speed enough to handle the PWM signal?

@BobB You could use two N-channel mosfets, one as an inverter (as in an RTL inverter) or maybe a P-channel MOSFET to switch the 5V signal, sure. Or add an actual inverter chip to the outputs (74HC00 gives 6 inverters in one chip). There's lots of things you could do.