text:
Trouble interfacing PN5180 RFID Module with Arduino Uno
I bought the PN5180 module a few weeks back and I am having quite a bit of trouble interfacing it with my Arduino Uno. The library that I am using is ATrappmann PN5180 Library. The link of which is here https://github.com/ATrappmann/PN5180-Library. I have followed his connections to the letter and have tested each component individually.
The Uno is fine since I have used it extensively for other testing. The Level Shifter is also working fine. The one I am using is similar to this. The jumper wires are also fine. I have tried working with both examples given in the library and the code gets stuck during the looping. I have attached a screenshot here.

I can't seem to figure out where is it going wrong. Is there any way I can use the RC522 Library for setting up the PN5180 reader? I have successfully integrated both RC522 and PN532 NFC readers with Uno but they don't have the required range. I plan on using the reader for localization. It will read the cards and compare it with an array of UID characters to figure out where it is. Any suggestion would be greatly appreciated honestly!
Edit:
Adding the circuit diagram and code so that It is easier to understand

Code:
// NAME: PN5180-Library.ino
//
// DESC: Example usage of the PN5180 library for the PN5180-NFC Module
//       from NXP Semiconductors.
//
// Copyright (c) 2018 by Andreas Trappmann. All rights reserved.
//
// This file is part of the PN5180 library for the Arduino environment.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// BEWARE: SPI with an Arduino to a PN5180 module has to be at a level of 3.3V
// use of logic-level converters from 5V->3.3V is absolutely necessary
// on most Arduinos for all input pins of PN5180!
// If used with an ESP-32, there is no need for a logic-level converter, since
// it operates on 3.3V already.
//
// Arduino <-> Level Converter <-> PN5180 pin mapping:
// 5V             <-->             5V
// 3.3V           <-->             3.3V
// GND            <-->             GND
// 5V      <-> HV
// GND     <-> GND (HV)
//             LV              <-> 3.3V
//             GND (LV)        <-> GND
// SCLK,13 <-> HV1 - LV1       --> SCLK
// MISO,12        <---         <-- MISO
// MOSI,11 <-> HV3 - LV3       --> MOSI
// SS,10   <-> HV4 - LV4       --> NSS (=Not SS -> active LOW)
// BUSY,9         <---             BUSY
// Reset,7 <-> HV2 - LV2       --> RST
//
// ESP-32    <--> PN5180 pin mapping:
// 3.3V      <--> 3.3V
// GND       <--> GND
// SCLK, 18   --> SCLK
// MISO, 19  <--  MISO
// MOSI, 23   --> MOSI
// SS, 16     --> NSS (=Not SS -> active LOW)
// BUSY, 5   <--  BUSY
// Reset, 17  --> RST
//

/*
 * Pins on ICODE2 Reader Writer:
 *
 *   ICODE2   |     PN5180
 * pin  label | pin  I/O  name
 * 1    +5V
 * 2    +3,3V
 * 3    RST     10   I    RESET_N (low active)
 * 4    NSS     1    I    SPI NSS
 * 5    MOSI    3    I    SPI MOSI
 * 6    MISO    5    O    SPI MISO
 * 7    SCK     7    I    SPI Clock
 * 8    BUSY    8    O    Busy Signal
 * 9    GND     9  Supply VSS - Ground
 * 10   GPIO    38   O    GPO1 - Control for external DC/DC
 * 11   IRQ     39   O    IRQ
 * 12   AUX     40   O    AUX1 - Analog/Digital test signal
 * 13   REQ     2?  I/O   AUX2 - Analog test bus or download
 *
 */

//#define WRITE_ENABLED 1

#include <PN5180.h>
#include <PN5180ISO15693.h>

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_NANO)

#define PN5180_NSS  10
#define PN5180_BUSY 9
#define PN5180_RST  7

#elif defined(ARDUINO_ARCH_ESP32)

#define PN5180_NSS  16
#define PN5180_BUSY 5
#define PN5180_RST  17

#else
#error Please define your pinout here!
#endif

PN5180ISO15693 nfc(PN5180_NSS, PN5180_BUSY, PN5180_RST);

void setup() {
  Serial.begin(115200);
  Serial.println(F("=================================="));
  Serial.println(F("Uploaded: " __DATE__ " " __TIME__));
  Serial.println(F("PN5180 ISO15693 Demo Sketch"));

  nfc.begin();

  Serial.println(F("----------------------------------"));
  Serial.println(F("PN5180 Hard-Reset..."));
  nfc.reset();

  Serial.println(F("----------------------------------"));
  Serial.println(F("Reading product version..."));
  uint8_t productVersion[2];
  nfc.readEEprom(PRODUCT_VERSION, productVersion, sizeof(productVersion));
  Serial.print(F("Product version="));
  Serial.print(productVersion[1]);
  Serial.print(".");
  Serial.println(productVersion[0]);

  if (0xff == productVersion[1]) { // if product version 255, the initialization failed
    Serial.println(F("Initialization failed!?"));
    Serial.println(F("Press reset to restart..."));
    Serial.flush();
    exit(-1); // halt
  }

  Serial.println(F("----------------------------------"));
  Serial.println(F("Reading firmware version..."));
  uint8_t firmwareVersion[2];
  nfc.readEEprom(FIRMWARE_VERSION, firmwareVersion, sizeof(firmwareVersion));
  Serial.print(F("Firmware version="));
  Serial.print(firmwareVersion[1]);
  Serial.print(".");
  Serial.println(firmwareVersion[0]);

  Serial.println(F("----------------------------------"));
  Serial.println(F("Reading EEPROM version..."));
  uint8_t eepromVersion[2];
  nfc.readEEprom(EEPROM_VERSION, eepromVersion, sizeof(eepromVersion));
  Serial.print(F("EEPROM version="));
  Serial.print(eepromVersion[1]);
  Serial.print(".");
  Serial.println(eepromVersion[0]);

  /*
  Serial.println(F("----------------------------------"));
  Serial.println(F("Reading IRQ pin config..."));
  uint8_t irqConfig;
  nfc.readEEprom(IRQ_PIN_CONFIG, &irqConfig, 1));
  Serial.print(F("IRQ_PIN_CONFIG=0x"));
  Serial.println(irqConfig, HEX);

  Serial.println(F("----------------------------------"));
  Serial.println(F("Reading IRQ_ENABLE register..."));
  uint32_t irqEnable;
  nfc.readRegister(IRQ_ENABLE, &irqEnable));
  Serial.print(F("IRQ_ENABLE=0x"));
  Serial.println(irqConfig, HEX);
  */

  Serial.println(F("----------------------------------"));
  Serial.println(F("Enable RF field..."));
  nfc.setupRF();
}

uint32_t loopCnt = 0;
bool errorFlag = false;

void loop() {
  if (errorFlag) {
    uint32_t irqStatus = nfc.getIRQStatus();
    showIRQStatus(irqStatus);

    if (0 == (RX_SOF_DET_IRQ_STAT & irqStatus)) { // no card detected
      Serial.println(F("*** No card detected!"));
    }

    nfc.reset();
    nfc.setupRF();

    errorFlag = false;
  }

  Serial.println(F("----------------------------------"));
  Serial.print(F("Loop #"));
  Serial.println(loopCnt++);

/*
  // code for unlocking an ICODE SLIX2 protected tag
  uint8_t password[] = {0x01, 0x02, 0x03, 0x04}; // put your privacy password here
  ISO15693ErrorCode myrc = nfc.unlockICODESLIX2(password);
  if (ISO15693_EC_OK == myrc) {
    Serial.println("unlockICODESLIX2 successful");
  }
*/

  uint8_t uid[8];
  ISO15693ErrorCode rc = nfc.getInventory(uid);
  if (ISO15693_EC_OK != rc) {
    Serial.print(F("Error in getInventory: "));
    Serial.println(nfc.strerror(rc));
    errorFlag = true;
    return;
  }
  Serial.print(F("Inventory successful, UID="));
  for (int i=0; i<8; i++) {
    Serial.print(uid[7-i], HEX); // LSB is first
    if (i < 2) Serial.print(":");
  }
  Serial.println();

  Serial.println(F("----------------------------------"));
  uint8_t blockSize, numBlocks;
  rc = nfc.getSystemInfo(uid, &blockSize, &numBlocks);
  if (ISO15693_EC_OK != rc) {
    Serial.print(F("Error in getSystemInfo: "));
    Serial.println(nfc.strerror(rc));
    errorFlag = true;
    return;
  }
  Serial.print(F("System Info retrieved: blockSize="));
  Serial.print(blockSize);
  Serial.print(F(", numBlocks="));
  Serial.println(numBlocks);

  Serial.println(F("----------------------------------"));
  uint8_t readBuffer[blockSize];
  for (int no=0; no<numBlocks; no++) {
    rc = nfc.readSingleBlock(uid, no, readBuffer, blockSize);
    if (ISO15693_EC_OK != rc) {
      Serial.print(F("Error in readSingleBlock #"));
      Serial.print(no);
      Serial.print(": ");
      Serial.println(nfc.strerror(rc));
      errorFlag = true;
      return;
    }
    Serial.print(F("Read block #"));
    Serial.print(no);
    Serial.print(": ");
    for (int i=0; i<blockSize; i++) {
      if (readBuffer[i] < 16) Serial.print("0");
      Serial.print(readBuffer[i], HEX);
      Serial.print(" ");
    }
    Serial.print(" ");
    for (int i=0; i<blockSize; i++) {
      if (isprint(readBuffer[i])) {
        Serial.print((char)readBuffer[i]);
      }
      else Serial.print(".");
    }
    Serial.println();
  }

#ifdef WRITE_ENABLED
  Serial.println(F("----------------------------------"));
  uint8_t *writeBuffer = malloc(blockSize);
  for (int i=0; i<blockSize; i++) {
    writeBuffer[i] = 0x80 + i;
  }
  for (int no=0; no<numBlocks; no++) {
    rc = nfc.writeSingleBlock(uid, no, writeBuffer, blockSize);
    if (ISO15693_EC_OK == rc) {
      Serial.print(F("Wrote block #"));
      Serial.println(no);
    }
    else {
      Serial.print(F("Error in writeSingleBlock #"));
      Serial.print(no);
      Serial.print(": ");
      Serial.println(nfc.strerror(rc));
      errorFlag = true;
      return;
    }
  }
#endif /* WRITE_ENABLED */

/*
  // code for locking an ICODE SLIX2 protected tag
  ISO15693ErrorCode myrc = nfc.lockICODESLIX2(password);
  if (ISO15693_EC_OK == myrc) {
    Serial.println("lockICODESLIX2 successful");
    delay(5000);
*/
  delay(1000);
}

void showIRQStatus(uint32_t irqStatus) {
  Serial.print(F("IRQ-Status 0x"));
  Serial.print(irqStatus, HEX);
  Serial.print(": [ ");
  if (irqStatus & (1<< 0)) Serial.print(F("RQ "));
  if (irqStatus & (1<< 1)) Serial.print(F("TX "));
  if (irqStatus & (1<< 2)) Serial.print(F("IDLE "));
  if (irqStatus & (1<< 3)) Serial.print(F("MODE_DETECTED "));
  if (irqStatus & (1<< 4)) Serial.print(F("CARD_ACTIVATED "));
  if (irqStatus & (1<< 5)) Serial.print(F("STATE_CHANGE "));
  if (irqStatus & (1<< 6)) Serial.print(F("RFOFF_DET "));
  if (irqStatus & (1<< 7)) Serial.print(F("RFON_DET "));
  if (irqStatus & (1<< 8)) Serial.print(F("TX_RFOFF "));
  if (irqStatus & (1<< 9)) Serial.print(F("TX_RFON "));
  if (irqStatus & (1<<10)) Serial.print(F("RF_ACTIVE_ERROR "));
  if (irqStatus & (1<<11)) Serial.print(F("TIMER0 "));
  if (irqStatus & (1<<12)) Serial.print(F("TIMER1 "));
  if (irqStatus & (1<<13)) Serial.print(F("TIMER2 "));
  if (irqStatus & (1<<14)) Serial.print(F("RX_SOF_DET "));
  if (irqStatus & (1<<15)) Serial.print(F("RX_SC_DET "));
  if (irqStatus & (1<<16)) Serial.print(F("TEMPSENS_ERROR "));
  if (irqStatus & (1<<17)) Serial.print(F("GENERAL_ERROR "));
  if (irqStatus & (1<<18)) Serial.print(F("HV_ERROR "));
  if (irqStatus & (1<<19)) Serial.print(F("LPCD "));
  Serial.println("]");
}

Edit 2:
So i tried one of the forks of ATrappmann library. the link is https://github.com/tueddy/PN5180-Library, and the problem of the code stalling at loops have been resolved. But now, the reader won't read any of my cards :(

I have the same problem as you, have you solved it ????.


text:
arduino acclerometer with servo motor
I'm currently working on project to operate three motors while sending accelerometer value to computer via bluetooth module. I want the motor operation and value transmission to work seperatly. But when motors operate, the transmission stops. I used the ArduinoThread library, but since I don't understand all the usage, it still has some kind of delay. Plus, I want two of the motors work first(just once) and the other works after specific time(also just once). But the first setup of two motors and the latter doesn't work. Please check my code and give me some advice. Thank you!
#include <Wire.h>
#include <SoftwareSerial.h>
#include <Servo.h>
#include <Thread.h>

const int MPU_addr=0x68;  // MPU-6050 I2C address
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;

SoftwareSerial BTSerial(3,2);   // TX,RX

Servo servoMini;
Servo servoUp;
Servo servoDown;
int pinMini = 6;
int pinUp = 9;
int pinDown = 10;
int i = 1;
unsigned long tPrev, tNow = 0;

Thread myThread = Thread();

void readAcc(){
  Wire.endTransmission(true);
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers   // 14bit??

  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  //AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  //AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  //GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  //GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  //GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  BTSerial.println(AcX);   // 16bit
  Serial.println(AcX);

  // delay(25);
}

void setup(){
  // I2C
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)

  // serial, bluetooth
  Serial.begin(9600);
  BTSerial.begin(9600);
  Serial.println("CLEARDATA");
  Serial.println("ONLY AcX");

  // servo
  servoMini.attach(pinMini);
  servoUp.attach(pinUp);
  servoDown.attach(pinDown);
  pinMode(pinMini, OUTPUT);
  pinMode(pinUp, OUTPUT);
  pinMode(pinDown, OUTPUT);
  servoMini.write(145);
  servoUp.write(180);
  servoDown.write(0);

  // Thread(MPU-6050)
  myThread.onRun(readAcc);
  myThread.setInterval(20);
}

void loop(){
  while(i == 1){
    tNow = millis();
    myThread.run();

    servoUp.attach(pinUp);
    servoDown.attach(pinDown);
    servoUp.write(60);
    servoDown.write(120);

  if((tNow - tPrev)>= 1000){
    servoMini.attach(pinMini);
    servoMini.write(180);
    i++;
  }
}

  servoMini.detach();
  myThread.run();
}

Your loop() function makes no sense to me. What is your intention with that code?

To read the value from an accellerometer (I²C bus) and process/use these readings to control the servo (bluetooth, probably in opposite direction?)

I think you'll probably have to look at DSP (digital signal processing). Perhaps something like this, but I haven't done this sort of things lately. You can indeed use a thread to read the values and store them in variables, another thread for dsp for delaying the signal, and a third to control the servo.

@Majenko I want two motors which is servoUp and servoDown to move first just once. And after 1seconds, the other motor to move once. So I used while(i ==1). Since need to check the value form the acclerometer, so I used myThread.run() again, but I'm not sure.

@Pieterjan The accelerometer and motor doesn't have meaningful connection. The value from sensor is sent to computer and modified for analysis seperately. I'm going to change the angle that motor moves and velocity of servomotor to check difference in acceleration.

Here's the final form of my project.
I've added motor detach function since it still shivers a bit.
#include <SoftwareSerial.h>
#include <Servo.h>

const int MPU_addr=0x68;  // MPU-6050 I2C address
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;

SoftwareSerial BTSerial(3, 2);  // TX, RX

Servo servoMini;
Servo servoUp;
Servo servoDown;

const byte pinMini = 6;
const byte pinUp = 9;
const byte pinDown = 10;

// Timings for each event.
const unsigned long ACC_INTERVAL = 50;
const unsigned long INTERVAL = 1000;
const unsigned long INTERVAL_FIN = 2000;
const unsigned long GRIPPER_INTERVAL = 2000;
const unsigned long GRIPPER_INTERVAL_FIN= 3000;
const unsigned long LED_INTERVAL = 250;

// Keep track of timestamps for each event.
unsigned long prev_led_timestamp;
unsigned long prev_acc_timestamp;
unsigned long servo_timestamp;
unsigned long servo_timestamp_fin;
unsigned long gripper_timestamp;
unsigned long gripper_timestamp_fin;

// Flags to indicate completion of "just once" events.
bool servo = false;
bool servo_fin = false;
bool gripper = false;
bool gripper_fin = false;

// State of blinking LED.
bool led_state = false;

void readAcc(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers   // 14bit??

  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  //AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  //AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  //GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  //GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  //GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  BTSerial.println(AcX);   // 16bit
  //Serial.println(AcX);
}

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

  // For blink without delay.
  pinMode(LED_BUILTIN, OUTPUT);

  // I2C
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  // servo
  servoMini.attach(pinMini);
  servoUp.attach(pinUp);
  servoDown.attach(pinDown);

  // Perform first move.
  servoMini.write(145);
  servoUp.write(180);
  servoDown.write(0);

  // Initialise all timestamps with the same value with a single call to millis().
  prev_led_timestamp =
  prev_acc_timestamp =
  servo_timestamp = servo_timestamp_fin =
  gripper_timestamp = gripper_timestamp_fin = millis();
}

void loop(){
  unsigned long current_timestamp = millis();

  // TASK 1: Read acc.
  if (current_timestamp - prev_acc_timestamp >= ACC_INTERVAL){
    // Read acc.
    readAcc();
    prev_acc_timestamp += ACC_INTERVAL;
  }

  // TASK 2: Just once.
  if (!servo && current_timestamp - servo_timestamp >= INTERVAL)  {
    //Serial.print("Running just once... ");
    servoUp.attach(pinUp);
    servoDown.attach(pinDown);
    servoUp.write(60);
    servoDown.write(120);
    // retract speed control
    servo = true;
    //Serial.println("Done.");
  }
  if (!servo_fin && current_timestamp - servo_timestamp_fin >= INTERVAL_FIN){
    servoUp.detach();
    servoDown.detach();
    servo_fin = true;
  }

  // TASK 3: Also just once.
  if (!gripper && current_timestamp - gripper_timestamp >= GRIPPER_INTERVAL)  {
    // Perform third move.
    //Serial.print("Running also just once... ");
    servoMini.write(180);
    gripper = true;
    //Serial.println("Done.");
  }
  if (!gripper_fin && current_timestamp - gripper_timestamp_fin >= GRIPPER_INTERVAL_FIN){
    servoMini.detach();
    gripper_fin = true;
  }

  // TASK 4: Blink without delay.
  if (current_timestamp - prev_led_timestamp >= LED_INTERVAL){
    // Toggle LED state.
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    prev_led_timestamp += LED_INTERVAL;
  }
}

I think you want something like Blink Without Delay, but with more tasks.
Here is my interpretation of your description which extends Blink Without Delay by adding three more tasks to:

read the accelerometer
perform "just once"
perform "also just once"

I've added several Serial.print() statements to give a running commentary on what's occurring for debug purposes.
#include <Wire.h>
#include <SoftwareSerial.h>
#include <Servo.h>

SoftwareSerial BTSerial(3, 2);  // TX, RX

Servo servoMini;
Servo servoUp;
Servo servoDown;

const byte pinMini = 6;
const byte pinUp = 9;
const byte pinDown = 10;

// Timings for each event.
const unsigned long READ_ACCELEROMETER_INTERVAL = 50;
const unsigned long JUST_ONCE_INTERVAL = 1000;
const unsigned long ALSO_JUST_ONCE_INTERVAL = 2000;
const unsigned long LED_BLINK_INTERVAL = 200;

// Keep track of timestamps for each event.
unsigned long previous_blink_timestamp;
unsigned long previous_accelerometer_timestamp ;
unsigned long just_once_timestamp;
unsigned long also_just_once_timestamp;

// Flags to indicate completion of "just once" events.
bool just_once = false;
bool also_just_once = false;

// State of blinking LED.
bool led_state = false;

void setup()
{
    Serial.begin(115200);
    Serial.println("\n\nAccelerometer with Servo Test\n");

    // For blink without delay.
    pinMode(LED_BUILTIN, OUTPUT);

    // servo
    servoMini.attach(pinMini);
    servoUp.attach(pinUp);
    servoDown.attach(pinDown);

    // Perform first move.
    servoMini.write(145);
    servoUp.write(180);
    servoDown.write(0);

    // Initialise all timestamps with the same value with a single call to millis().
    previous_blink_timestamp =
    previous_accelerometer_timestamp =
    just_once_timestamp =
    also_just_once_timestamp = millis();
}

void loop()
{
    unsigned long current_timestamp = millis();

    //
    // TASK 1: Read accelerometer.
    //
    if (current_timestamp - previous_accelerometer_timestamp >= READ_ACCELEROMETER_INTERVAL)
    {
        // Read accelerometer.
        Serial.print("Reading accelerometer... ");
        readAcc();
        previous_accelerometer_timestamp += READ_ACCELEROMETER_INTERVAL;
        Serial.println("Done.");
    }

    //
    // TASK 2: Just once.
    //
    if (!just_once && current_timestamp - just_once_timestamp >= JUST_ONCE_INTERVAL)
    {
        // Perform second move.
        Serial.print("Running just once... ");
        servoUp.write(60);
        servoDown.write(120);
        just_once = true;
        Serial.println("Done.");
    }

    //
    // TASK 3: Also just once.
    //
    if (!also_just_once && current_timestamp - also_just_once_timestamp >= ALSO_JUST_ONCE_INTERVAL)
    {
        // Perform third move.
        Serial.print("Running also just once... ");
        servoMini.write(180);
        also_just_once = true;
        Serial.println("Done.");
    }

    //
    // TASK 4: Blink without delay.
    //
    if (current_timestamp - previous_blink_timestamp >= LED_BLINK_INTERVAL)
    {
        // Toggle LED state.
        led_state = !led_state;
        digitalWrite(LED_BUILTIN, led_state);
        previous_blink_timestamp += LED_BLINK_INTERVAL;
    }
}

Wow! It's exactly what I wanted. I've never thought of using boolean type. Thank you very much! By the way, Can I ask you why you add the led blinking at the end?

@JohnCho, the LED blinking is not essential, but it's useful for debugging purposes to show that the MCU hasn't frozen - known as a heartbeat signal or sign of life signal. Plus I was building upon the Blink Without Delay example to show how to add concurrent non-blocking tasks.

Thank you! Now I have better understand of concurrent tasks. Sorry for late comment, by the way.

source: Stack Exchange

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

sort: votes


text:
Relay not triggering from loop function. Variable "volume" not updating after encoder is turned to value?
I am reading a value from an encoder "volume knob" and I have a function called void fn_on were I am having sum int to zero and counting until it reaches the set value of volume. I tried posting to serial but my sum counter does not work. I want my relay to run "volume" number of times until sum > volume in my function "fn_on" I believe I am not storing or updating my volume correctly. Thank you for taking the time to look through this.
#include <LiquidCrystal_I2C.h>
#include <Rotary.h>
#include <LCD_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);

/* Rotary Encoder - Polling Example

The circuit:
  encoder pin A to Arduino pin 2
  encoder pin B to Arduino pin 3
  encoder ground pin to ground (GND)
*/
#define PINA 2
#define PINB 3
#define RelayPin 8

const char PUSHB = 5;
bool pressed = false;
long volume = 0; // this may not set the volumue

Rotary r = Rotary(2, 3);

void setup()
{
    Serial.begin(115200); // setup Pin modes
    pinMode(PUSHB, INPUT);
    r.begin(true);
    lcd.init();
    lcd.backlight();
    lcd.setCursor(0, 3);
    lcd.print(volume);
    digitalWrite(PINA, HIGH); // enable pull-ups
    digitalWrite(PINB, HIGH);
    // digitalWrite (PUSHB, HIGH);
    pinMode(RelayPin, OUTPUT); // Relay Pin ini
}

void loop()
{
    bool currentState = digitalRead(PUSHB);

    if (currentState == pressed)
    {
        Serial.println("Pressed");

        while (digitalRead(PUSHB) == pressed)
        {
            // do nothing
        }
    }

    unsigned char result = r.process();

    if (result)
    {
        // Serial.println(result == DIR_CW ? "Right" : "Left");
        if (result == DIR_CCW)
        {
            volume = volume - 1000; // change ++ to mulpes of 1000
            Serial.println(volume);
            lcd.setCursor(0, 3);
            lcd.print(volume);
            lcd.print("                                ");

            int sum = 0;
            for (sum = 1; sum < volume; sum++ && currentState = true)
            {
                lcd.setCursor(0, 2);
                lcd.print(sum);
                digitalWrite(RelayPin, LOW); // run test
                delay(3000);
                digitalWrite(RelayPin, HIGH); // run test
                delay(3000);
                digitalWrite(RelayPin, LOW); // run test
                delay(3000);
            }
        }
        else
        {
            volume = volume + 1000; // change volume++ to mulpes of 1000
            // initialize display_menu to 1st line
            lcd.setCursor(0, 3);
            lcd.print(volume);
            lcd.print("                                 ");
        }
    }
}

Where are you calling fn_on() in your code? And do you know you have two variables called “sum”: one as a const int in your global scope and one as an int within the fn_on() function?

your code is quite messy ... please fix the indentation so that the code is easier to read and easier to understand

I changed some of the logic
Okay I am trying to read a value from a rotary encoder, the value that I am reading is "volume (cycles)". I want to dial the encoder to a number and set it with a push button and run a relay N number of cycles. I am using a "for loop" to run my relay once the push button is pressed and when volume is greater than one

Does the LCD display the correct volume? What do you get if you serial print the volume? The whole relay thing isn't relevant until that part works correctly

I believe the issue is that you're setting your encoder pins high with digitalWrite().  Those pins need to be configured as inputs for the interrupts to work correctly.  This will be handled by the encoder library when you call r.begin(true).  In fact, true in that call tells the library to enable the pullups for you.
Removing those lines should fix your issue.

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


text:
Using String instead of C string, yet another attempt to touch a loaded issue
I've been reading a lot over the years why we should not use the notorious String class and how heap fragmentation is bad practice and not professional and we should never use it in our programs or we'll never enter the C hall of fame and get to be called programmers.
Fine, I get it, C string is pro, String is people toying with Arduino, but having read all that I still don't understand:

Where is the risk? If I use String and my heap gets fragmented, and there's still enough memory for the program to run for months without crashing, why should I not use String if it makes my work so much easier? Just because it's a bad habit is a very lame answer.

Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky? Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

And really, what is potential harm, in practical terms not theoretically, what are the limits, does anyone know when a program will crash?

Happy coding!

I totally agree. I use String all the time and in all the ways I know I shouldn't and my gadgets never have any problems.  So, in practice, I don't see the harm in using String and I'll keep using them.

if your device crashes after several months, isn't that a problem?

Interesting to see this discussion, because if you speak to infosec people they will tell you that C string handling is one of the profession's great disasters.

Whether or not String is actively harmful depends on context. The problem is that ignorant (in the technical sense) usage of String can easily lead to difficult-to-diagnose problems: those least likely to understand how to diagnose the issues are the most likely to have the issues.

@pjc50 Indeed, but the issues faced by devs with a few K of memory are different than those faced by the majority of programmers.

You can create just as much mess on the heap allocating your own string memory with malloc() and free() as you can by using a string class. Especially considering that the code of the string class itself was probably written by someone who knows more about software development than you do.

If it works, great, use it! If it turns out to be a problem, switch away from it. Organize your code in a way that this is easily doable. Don't prematurely optimize. That being said, on limited platforms (embedded), using C strings from the start might be a good idea.

It's not that String itself is evil, it's more that it's very easy to abuse it and cause heap fragmentation. Used judiciously it's fine and a useful tool. Used in "bad" ways and you open the door to random crashes.
By "bad" ways I mean excessive (and not needed) data duplication and heap reallocation. The biggest pitfalls are:

Using .concat() or "adding" strings together with +
Passing String objects to functions by value instead of by reference

Basically anything where a new string is created and the old one thrown away leaves holes in the heap.
Those holes (fragmentation) themselves aren't a problem - the problem is the very tiny amount of RAM the typical low-end Arduino (i.e., ATMega328P based) has. When you have wasted space in your heap in the form of holes it's more and more likely that you will end up having the top of your heap meet the bottom of your stack, and that is when problems arise.
For transient operations String is fine. By "transient" I mean operations where all the data is discarded at the end. All temporary and source strings are destroyed and all the memory is returned to the pool, thus leaving no holes in the heap.
Also on microcontrollers with far more memory than a little Arduino UNO (such as ESP32, etc) heap fragmentation ceases to really be a problem. By the time the heap grows big enough to be noticeable any holes have got big enough that they start to get filled again.

Comments are not for extended discussion; this conversation has been moved to chat.

(Outsider here, checking this out from the hot network questions) Returning String objects from functions by value instead of by reference Does the Arduino environment use C++, or C? In C++, copy-elision on return is now guaranteed, so I don't think this should be an issue.

The short answer is that fragmentation crashes are infrequent because they require very specific conditions to arise—and that's the problem.
Imagine you have a crash that occurs once every few days and can't figure out why. It never happens while testing and doesn't seem to be caused by anything specific.
Then it turns out that your code is printing numbers to a string, usually 4 digits but sometimes 2 or 3. And it turns out that very specific sequences of the lengths of strings being allocated and deallocated trigger a crash. But there's no good way to analyse or predict the problem because it hinges on absolutely everything that's happened since boot. If there was a 3- instead of 4-digit number 8 hours ago, that completely changes what would need to happen now to trigger a crash.
While answering this question I tried to come up with some code that would leave memory very fragmented. It was very difficult. Memory fragmentation is very sensitive to what happens, in what order. Basically it's a highly chaotic system.
This is reminiscent of problems related to multithreading, where running a simple program multiple times can easily give different results. Problems like this are really, really frustrating to identify and diagnose. A lot of people have felt the pain and that is why there is such stigma about String.
To answer your questions:

why should I not use String if it makes my work so much easier?

As long as you understand the pitfalls and how to avoid them, sometimes Strings are the best tool for the job.
The main goal of avoiding String is to prevent severe heap fragmentation. There are other ways to do that, though:

Don't store lots of heap-allocated objects on a long-term basis. If you only have 3 global String variables then it's probably fine to allocate 100 small strings if you delete them before doing anything else
If you have to store many heap-allocated objects long-term, try not to allocate them during a period of a lot of heap allocations, deallocations, and resizings (such as during a loop when a string is being built). You want to avoid these long-term objects being given "random" positions through memory.

If you want to use String in an application where reliable long-term operation is important, you really have to be thorough in understanding your memory usage patterns and why they are unlikely to trigger a problem.
I should add that each String adds several bytes of memory overhead, both for the string descriptor and for the invisible bookkeeping that the malloc() implementation does. They are also slower to access than char []s.

Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky?

This is difficult because of how sensitive things are to tiny differences in allocation history. There are a few simple analyses you can do, though.
If you have n heap-allocated objects, you have n+1 fragments (although some fragments may be zero size.) The average fragment size will be ≤ the amount of free space divided by n+1. For example if you have 19 allocated objects and 2000 bytes of remaining space, your average fragment size will be 100 bytes. Mathematically this implies that at least one fragment is ≥ this size, and therefore you are guaranteed to be able to allocate anything smaller than 100 bytes. Keep in mind though that every allocated object consumes a few bytes of invisible bookkeeping data used by the runtime's implementation of malloc(), and there may be other hidden things floating around in the system, like some objects allocated by libraries. Also remember that on Arduino, SRAM is shared by stack and heap.
Now let's say you have 8KB of heap space and you allocate a lot of stuff, then deallocate a lot of stuff, leaving exactly 3 small objects allocated. This will divide your heap into 4 regions. The average size will be just under 2KB and so no matter how unlucky you are, one or more of the regions will be at least that size. So you should be able to allocate one large object of around 2KB, or, allocate hundreds of small objects, or allocate one object and keep resizing it anywhere up to 2KB. If you then free everything except for 3 small objects, you will be back in the same situation: you are guaranteed a region of at least 2KB.
There are two noteworthy conclusions:

If the maximum number of items that will ever be allocated at a time is n, and their maximum size is s, and your heap size is at least (2n+1) × (s+4), you will never have a fragmentation problem. (3 is an architecture-dependent fudge factor to cover malloc bookkeeping and padding issues.)
If there are "checkpoints" in your code where only a few objects are allocated, this makes it easier to reason about what can happen between these checkpoints.

Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

Not for Arduino that I know of. The problem is, a program susceptible to severe fragmentation may only display signs for short periods once every few days or something.
The easiest technique you can use is to consume say 30% of your memory with malloc() at the start of your program to put more heap pressure on it, and see if it still works. This isn't guaranteed to bring the problems out of the woodwork, but it greatly boosts the chances that you will see something.
You can also write a function to try to allocate the largest objects possible over and over, slowly reducing the size, and see to what extent you are prevented from allocating large objects but can allocate small ones. I was going to post one but I decided it would be of limited benefit.
If you really want to see what is going on with your heap you can look at the source of your malloc() implementation and inspect its data structures from within your program. In this case it seems to be as simple as putting this at the start of your code
struct __freelist {
  size_t sz;
  struct __freelist *nx;
};
extern struct __freelist *__flp;

and then you can traverse the contents of the freelist using __flp.

I'd like to answer your question without discussing the more technical side. This has been admirably covered by my learned colleagues in their own answers. I am going to address the cost-benefit side of using String.
Certainly, in the short term, it is almost certainly faster and easier to use String than to allocate buffers of characters, keeping track of how full they are, appending to the end of them, and so on.
For example, to read serial input, this is easy:
String inputBuffer;

void loop()
  {
  while (Serial.available () > 0)
    inputBuffer += Serial.read ();

  if (inputBuffer == "something")
    doSomething ();
  }  // end of loop

This, by the way, is the very sort of code that is likely to cause heap fragmentation and a crash. :)
So, you may well save an hour or two of coding by using the String class. So far, so good. You are ahead.
Then you start testing. Things go well for a while, but then after your code runs for an hour it mysteriously crashes, or probably, hangs. Your device stops doing what it is supposed to do, and you start looking for bugs. There is nothing obviously wrong, so you spend quite a bit of time trying to solve the issue. Heap fragmentation doesn't jump out and slap you in the face like, say, forgetting to add one variable to another.
So you look over the code, maybe post a question on Stack Exchange, maybe ask friends, maybe ask your teacher (where appropriate). Soon enough, time is mounting. You spend an hour debugging, two hours, four hours, and soon you have spent eight hours on it. Now you have wasted all the benefit you got from using the "easy" String class. Not only that, you are way behind, compared to allocating a fixed-size buffer and managing putting data into it yourself.
Sooner or later you identify that heap fragmentation is the culprit, and have to rewrite it. In other words, you eventually have to stop using the String class. So the whole episode has been a waste of time.
Certainly this won't always happen, and for the occasional use of fixed-length String objects, there won't be an issue. But if you look at the conditions mentioned in the other answers, you can see that it is easier, in fact, to "just don't use String" than to use them in very careful ways, and hope that your project doesn't break today, tomorrow, next week, or after three months "in the field".

why should I not use String if it makes my work so much easier?

Certainly you should, if it makes your work easier, and if it doesn't crash.

does anyone know when a program will crash?

No, probably not. If you are "lucky" it will crash soon after you start it, and you will at least know you have a problem. If you are unlucky your fish feeder will stop feeding your fish two weeks into your holiday and they will die.

As you mentioned, amazing answers given here and your adds to that so thanks everyone for taking the time.

I'm not an Arduino programmer, but I am a C programmer.  And the problem of string types in C -- or, rather, the absence of a first-class string type in C -- is an old but important one.
The fundamental problem is this.  In C, you can say things like
int a, b, c, d, f();
a = b + c;
d = f();

And you can say things like
float q, r, s, t();
q = r / s + t();

But you can not say
string x, y, z();
x = y + z();

C has no first-class string type.  In pure C, if you want to manipulate strings, you have to use some combination of char [] arrays and char * pointers.  You have to remember to allocate enough memory to hold the strings you're working with today.  In many cases you can't assign strings; you may have to call strcpy or the like.  In most cases you can't directly compare strings; you usually have to call strcmp or the like.  This can all be a real nuisance, and if you get the details wrong, you get strange bugs and crashes.
So, especially if you're a beginning or casual programmer, It Would Be Nice if C had a true, first-class string type.  (And of course C++ does have such a type.)
But there's a very good reason that plain C doesn't have such a type.  Manipulating strings is just plain harder than manipulating ints or floats.  The reason it's harder is precisely because they're variable-length, and potentially rather large.  Under C's low-level philosophy, the best person to make good tradeoffs when it comes to deciding how to handle a particular program's strings is that program's author, not the compiler or library writer.
You can write a decently good, decently efficient, high-level, first-class string type.  But, it's never going to be as efficient, for every problem, as handcrafted char [] and char ** code would be.  Also, if there are a bunch of rules for how to use a first-class string type efficiently, avoiding fragmentation and the like, those rules are probably going to end up being almost as complicated as the rules for using char [] and char * correctly -- but the whole point of introducing the first-class string type was so that programmers wouldn't have to worry about those low-level details all the time!  It's really rather a pretty pickle.
So when someone says, "you shouldn't use that high-level string type, it's wasteful and inefficient", the question to ask is, is it unacceptably wasteful or inefficient?
Once upon a time, people said we shouldn't use compiled languages, since they're wasteful and inefficient.  Those people thought we should all write everything in assembly language.  (And there are still a few people who say this.)  Most of the time, though, we've discovered that compiled code is adequately efficient, and its other advantages more than make up for any slight lingering inefficiencies.
And the question for C strings versus Strings is almost perfectly equivalent.  If your program is making significant use of strings, expending a large fraction of its time or a large fraction of the available memory towards them, the inefficiencies of Strings might well be unacceptable.  If there are relatively few strings, however, the convenience to the programmer of using a high-level String type (along with the absence of bugs) might be well worth it, and the costs might be inconsequential.
But there's no one right answer to the question of "Do or don't use Strings", because it's a subjective question, and different people under different circumstances will legitimately come to different conclusions.

C wouldn't need to add much to allow programmers to implement things that are much closer to be usable as first-class types.  If it included static const compound literals, and offered a strong recommendation that such literals should be omitted if their addresses are taken and directly used as the second operand of a ?: operator whose first operand is always zero, or the third operand of one whose first operand is never zero, better string types could be easier to use than C strings.

Mega point is: don't use String (or anything else that uses the heap) inside interrupts - even with objects created outside the interrupt. the underlying memory allocation functions cannot deal with it and you've got a good chance something will go boom.
As for the rest, so much of this is dependant on implementation
Nick's answer with the input buffer yes will crash, he never clears it! (j/k)
But even if he did after matching with something, i.e.
      if (inputBuffer == "something") {
            inputBuffer="";
            doSomething ();
      }

after we've hit this there will be no more (possible) fragmenting to do with this code, as the implementation for String on the copy (or a concatenation) there does not reallocate the memory buffer unless it is too small. So as we go round this whole loop after the first time, no heap allocations will happen.
We could also remove any reallocations during the initial building of the 'something' string in the inputBuffer by allocating enough space right at the beginning of the code with
    inputBuffer.reserve(9);

where 9 is the length of the string 'something' (reserve will add an extra byte on the buffer for the string terminator)
You can also use this to reserve space for doing multiple concatenations . Anything above 1 concat / += will save time because of not multiply reallocating space, plus stop the fragmentation.
    int newSize=a.length()+b.length()+c.length();
    a.reserve(newSize); // only memory realloc happens here
    a.concat(b);
    a.concat(c);

Similarly you could create a much bigger buffer to briefly handle something you're not sure the size of (say, reserve 512 bytes) but beware! because of the point above (.reserve() does not reallocate the buffer unless the requested size is larger) you are stuck with that buffer until the string object is destroyed by going out of scope or being explicitly deleted. Global objects are stuck with it. So if you need a global object that could get bigger or smaller, make it a pointer to a String then use new/delete as required.
Also we need to consider object lifetime. Even if you use a bunch of String objects in a function, if they are all destroyed at the end, and you haven't created any other heap objects within that function, when you have left and all the Strings are auto destroyed there should be no impact on the heap, it should return to its previous state as the memory is reclaimed
If you are creating String objects on the heap (via new) though it does compound any fragmentation problems you may have in your code anyway as you end up with 2 heap items, the String wrapper object and the data itself. If you're just using a local or global variable the wrapper won't be in the heap, either in global memory or on the stack.

As you already got good answers to most of your questions, I will try
to cover here only this one:

Is it possible to quantify the fragmentation and get a feel of what's  safe and when it becomes risky?

A quick Web search for “Arduino free memory” finds a few code snippets
that can be used to measure, at run time, the amount of free memory:

Available Memory, in the Arduino Playground, only works on AVR. It
measures  the total amount of available RAM, including the holes in
the heap.

Measuring Memory Usage, an Adafruit tutorial, shows some portable
(AVR and ARM) code that measures the available RAM between the heap
and the stack. This does not include the holes in the heap.

If you compare the AVR versions of these two code snippets, you can see
the difference is in the freeListSize() function of the Playground
version. This function returns the total memory residing in heap holes,
which could be a measure of the heap fragmentation.
The function is AVR-specific, but then AVR is where heap fragmentation
is most worrisome.


text:
Battery voltage measurement with voltage divider
I am using the following circuit to measure the Li-ion 3.7V battery capacity.

Figure 1 – Schematic for 3.7 V batteries.
This setup works fine for the 3.7V batteries.
To be able to measure 9V batteries, I modified the circuit with a voltage divider so that the Arduino sees max 5v at the analog input. However Arduino reports 0V. I have measured the output of voltage divider with a DMM and it shows 5V. I wonder why doesn't Arduino report the correct voltage. Could you please help me fix it?

Figure 2 – Modified schematic for 9 V batteries which doesn't work.
My code:
#include "LCD5110_Graph.h"
LCD5110 myGLCD(5, 6, 7, 9, 8); // Setup Nokia 5110 Screen SCLK/CLK=5, DIN/MOSI/DATA=6, DC/CS=7, RST=9 Chip Select/CE/SCE=8,
extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];

#define gatePin 10
#define highPin A0
#define lowPin A1

boolean finished = false;
int printStart = 0;
int interval = 5000; // Interval (ms) between measurements

float mAh = 0.0;
float shuntRes = 1.0; // In Ohms – Shunt resistor resistance
float voltRef = 4.71; // Reference voltage
float current = 0.0;
float battVolt = 0.0;
float shuntVolt = 0.0;
float battLow = 2.9;

unsigned long previousMillis = 0;
unsigned long millisPassed = 0;

void setup()
{
    Serial.begin(9600);
    Serial.println("Battery Capacity Checker v1.1");
    Serial.println("battVolt current mAh");

    pinMode(gatePin, OUTPUT);
    digitalWrite(gatePin, LOW);

    myGLCD.InitLCD(); // initialize LCD with default contrast of 70
    myGLCD.setContrast(68);
    myGLCD.setFont(SmallFont); // Set default font size. tinyFont 4×6, smallFont 6×8, mediumNumber 12×16, bigNumbers 14×24
    myGLCD.clrScr();

    myGLCD.print("Battery", CENTER, 0);
    myGLCD.print("Check", CENTER, 12);
    myGLCD.print("Please Wait", CENTER, 24);
    myGLCD.print("AdamWelch.Uk", 8, 40);
    myGLCD.update();
    delay(2000);
    myGLCD.clrScr();
}

void loop()
{
    battVolt = analogRead(highPin) * voltRef / 1024.0;
    shuntVolt = analogRead(lowPin) * voltRef / 1024.0;

    if (battVolt >= battLow && finished == false)
    {
        digitalWrite(gatePin, HIGH);
        millisPassed = millis() – previousMillis;
        current = (battVolt – shuntVolt) / shuntRes;
        mAh = mAh + (current * 1000.0) * (millisPassed / 3600000.0);
        previousMillis = millis();

        myGLCD.clrScr();
        myGLCD.print("Discharge", CENTER, 0);
        myGLCD.print("Voltage:", 0, 10);
        myGLCD.printNumF(battVolt, 2, 50, 10);
        myGLCD.print("v", 77, 10);
        myGLCD.print("Current:", 0, 20);
        myGLCD.printNumF(current, 2, 50, 20);
        myGLCD.print("a", 77, 20);
        myGLCD.printNumI(mAh, 30, 30);
        myGLCD.print("mAh", 65, 30);
        myGLCD.print("Running", CENTER, 40);
        myGLCD.update();

        Serial.print(battVolt);
        Serial.print("\t");
        Serial.print(current);
        Serial.print("\t");
        Serial.println(mAh);

        delay(interval);
    }
    if (battVolt < battLow)
    {
        digitalWrite(gatePin, LOW);

        finished = true;

        if (mAh < 10)
        {
            printStart = 40;
        }
        else if (mAh < 100)
        {
            printStart = 30;
        }
        else if (mAh < 1000)
        {
            printStart = 24;
        }
        else if (mAh < 10000)
        {
            printStart = 14;
        }
        else
        {
            printStart = 0;
        }

        myGLCD.clrScr();
        myGLCD.print("Discharge", CENTER, 0);
        myGLCD.print("Voltage:", 0, 10);
        myGLCD.printNumF(battVolt, 2, 50, 10);
        myGLCD.print("v", 77, 10);
        myGLCD.setFont(MediumNumbers);
        myGLCD.printNumI(mAh, printStart, 21);
        myGLCD.setFont(SmallFont);
        myGLCD.print("mAh", 65, 30);
        myGLCD.print("Complete", CENTER, 40);
        myGLCD.update();

        delay(interval * 2);
    }
}

Circuit with modifications

Figure 3 – Schematic for 9 V batteries.

Why such tiny resistor values?

Sorry it wasn't the correct schematic. I have updated the post with the correct one. I suppose you were referring to the voltage divider resistors?

Actually, ignore that - I was looking at the resistors wrong. The small ones are current sense and load, not the battery divider.

A load of 4.3ohm on a 9volt battery draws 2amps???

Yes that's indeed high so I am planning to use Rload = 10 ohm. My 9V nominal Li-ion battery has max voltage of 8V so with a total 11 ohm resistance the current will be limited around 819 mA. Since the resistors can take upto 10 W so it should be fine .

The problem comes because you are powering your load through the voltage divider you use for reading your battery voltage.
You cannot do high-side current reading like that with a voltage higher than the ADC voltage. Instead you need to do the current sensing before your voltage divider and then divide that result down again.
Your circuit should look more like:

simulate this circuit – Schematic created using CircuitLab

Thanks for the explanation. I have uploaded a new schematic and I hope I have incorporated your suggestion correctly. Can you please have a look? :)


text:
Multiple I2C devices connected to one Arduino Uno?
Is it possible to connect more than one I2C device to an Arduino Uno? I know that the SCL and SDA pins are on analog pins A4 and A5 respectively, but there are also two pins labeled SCL and SDA located next to the AREF pin on the other side of the board. Does that mean I can connect multiple devices to the same board and, if so, how?
For context, I'm currently working on creating a robotic arm that matches its movements to the movements of my arm (I believe this is called a telepresence robot). To do so, I wanted to use a couple of IMUs (specifically the MPU-6050) to record the movements of my wrist and shoulder. Using the TinyMPU6050 library by Gabriel Milan, I've already been able to establish communication with one IMU, but I'm struggling with the second one. I'm already communicating with the arm via the Uno's SPI interface so I can't use that to communicate with a second IMU, although I know it's possible.
I know that similar questions have been asked before, but none of the questions I could find had the exact answers that I needed, so I thought I would ask anyway. This code that I currently have works for one IMU, but I don't know where to begin to add a second one (if it's even possible). Any help that I can get would be greatly appreciated. Cheers!
#include <TinyMPU6050.h>

MPU6050 IMU_1(Wire);

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

  //initializing and calibrating `IMU_1`
  IMU_1.Initialize();
  Serial.println("Calibrating...");
  IMU_1.Calibrate();
  Serial.println("Calibrated");

  while (!Serial) {
    //empty while loop
  }
}

void loop() {
  IMU_1.execute();
  Serial.println();
  Serial.print("X angle = ");
  Serial.println(IMU_1.GetAngX());
  Serial.print("Y angle = ");
  Serial.println(IMU_1.GetAngY());
  Serial.print("Z angle = ");
  Serial.println(IMU_1.GetAngZ());

  delay(1000);
}

I2C is a multi-drop bus. That means that one set of I2C pins are designed to have multiple devices on it as long as each device has a unique address.
On an Uno the discrete I2C pins and the A4/A5 I2C pins are the same pins. The discrete pins are an attempt to provide a cross-platform standard location for the I2C signals for shields.

So, since I don't have a way of connecting multiple devices to the A4/A5 pins, does that mean that I can connect one IMU to the A4/A5 pins and one to the discrete pins and have it still function as long as I give them different addresses? Thanks for your help!

Yep. Except you don't normally "give" I2C devices addresses (unless you're making them yourself) - you usually are able to select between a couple of addresses using special pins on the I2C devices. If you can't select different addresses then you have the option of an "I2C multiplexer" to select between them.

Adding on to Majenko, you might find A1, A2, A3 on your I2C device, usually these are not connected, by soldering them (individually) you can change the address of your device, which you can then change in your code


text:
How do I recreate the Pong game with two pots and the map function?
I am working on a project for my brothers and anyone else who is interested in playing some LED Pong. I was just stuck on the software part. I don't really know what to do. But, I have an idea: I want to use the map() function to make my life easier, however, I am not sure how to use the map function with the Dot Matrix. All help would be appreciated. All of the stuff came in this kit.
Here is the test code:
#include <LedControl.h>

int DIN = 2;
int CS =  3;
int CLK = 4;

const int playerOnePin = A0;
const int playerTwoPin = A1;

int playerOneValue;
int playerOneValue2;
int playerTwoValue;
int playerTwoValue2;

LedControl lc = LedControl(DIN, CLK, CS, 0);

void setup() {

  lc.shutdown(0, false);      //The MAX72XX is in power-saving mode on startup
  lc.setIntensity(0, 15);      // Set the brightness to maximum value
  lc.clearDisplay(0);          // and clear the display

  pinMode(playerOnePin, INPUT);
  pinMode(playerTwoPin, INPUT);

}

void loop() {

  byte a[8] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  printByte(a);

}

void printByte(byte character []) {

  int i = 0;
  for (i = 0; i < 8; i++)
  {
    lc.setRow(0, i, character[i]);
  }
}

void readPot() {

  playerOneValue = analogRead(A0);

  playerOneValue2 = map(playerOneValue, 0, 1023, 0, 180);
}

Here is the other code:
#include <LedControl.h>

int DIN = 2;
int CS =  3;
int CLK = 4;

byte displayImage[8] =     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// considering a 2d co-ordinate system with origin (0,0) at bottom left corner
int ballX = 3; //X position
int ballY = 7; //Y position - top
int speedX = 0; // no X movement, can be -1, 0 or 1
int speedY = -1; // downward Y movement, can be -1, 0 or 1
int paddleX = 4; // X position of center of paddle - can be 1 to 6. Paddle width is 3
int score = 0;

LedControl lc = LedControl(DIN, CLK, CS, 0);

void setup() {
  pinMode (A0, INPUT);
  pinMode (A1, INPUT);
  lc.shutdown(0, false);      // Keep MAX72XX awake
  lc.setIntensity(0, 15);     // Set the brightness to maximum value
  lc.clearDisplay(0);         // and clear the display
}

void loop() {
  // update ball position
  ballX = ballX + speedX;
  ballY = ballY + speedY;

  // check for ball interaction with walls
  if (ballX == 0 || ballX == 7) {
    speedX = speedX * -1; // bouncing off walls in horizontal direction
  }

  // bouncing off ceiling
  if (ballY == 7) {
    speedY = speedY * -1; // bouncing off the ceiling
  }

  // bouncing off the paddle
  if (ballY == 0 && ballX >= (paddleX - 1) && ballX <= (paddleX + 1)) {
    speedY = speedY * -1;
    score++;    // player earns a point
  }

  // going past the paddle
  if (ballY == 0 && ballX < (paddleX - 1) && ballX > (paddleX + 1)) {
    // going past the paddle - player is out
    Serial.println(); Serial.print("Score: "); Serial.println(score);
    for (int i = 0; i < 8; i++) {
      displayImage[i] = 0x00;
    }
    displayImage[3] = 0xFF; displayImage[4] = 0xFF; // show a line
    renderByte(displayImage);
    while (1); // Freeze
  }
  // clearing the image variable
  for (int i = 0; i < 8; i++) {
    displayImage[i] = 0x00;
  }

  // generating new image
  addPixel(ballX, ballY); // adding the ball position to image
  addPixel(paddleX - 1, 0); addPixel(paddleX, 0); addPixel(paddleX + 1, 0);
  // adding paddle position to image
  renderByte(displayImage); // show the generated image

  // handling paddle control
  if (analogRead(A0) && paddleX > 0) {
    paddleX = paddleX - 1; // move paddle left
  }

  if (analogRead(A1) && paddleX < 7) {
    paddleX = paddleX + 1; // move paddle right
  }

  delay(200);
}

void addPixel(int xVal, int yVal) {
  int newRowval = 2 ^ (7 - xVal);
  int rowVal = displayImage[7 - yVal];
  displayImage[7 - yVal] = rowVal || newRowval;  // inserting a 1 at the required pixel
}

void renderByte(byte image [])
{
  int i = 0;
  for (i = 0; i < 8; i++)
  {
    lc.setRow(0, i, image[i]);
  }
}

Here is the picture of the wiring and the schematic:

Your ball will either go straight or diagonally at 45° ?

Yes, the ball will go straight, I don't know about  the diagonally part, but it won't move the paddle.

First figure out the min and max values that paddleX can have.  I assume if the paddle is two dots wide then its min,max will be 0,6   Then figure out the min and max of your pot, typically 0,1023 for a a 10 bit adc.  Now to map your pot value to paddleX value you'd use the command :
paddleX = map(analogRead(A0),0,1023,0,6);

here is the map documentation : https://www.arduino.cc/reference/en/language/functions/math/map/

For an evenly spaced mapping paddleX = map(analogRead(A0),0,1024,0,7); would provide better results. ( Integer division truncates )

Yes, the paddle is two dots wide.

I don't really know what to do from there.


text:
How does the FireBeetle ESP32 regulate to 3.3v? (schematic provided)
The FireBeetle ESP32 advertises an input voltage of 3.3v-5v, with an operating voltage of 3.3v.
I tested this with an 18650 lithium-ion battery and can confirm this is true. For 3.3V < Vbat < 4.2V, there is a consistent ~3.295 volts at the 3V3 pin. For Vbat < 3.3V, 3V3 drops slightly under Vbat (approx. -.02V).
I found this odd because the onboard RT9080-33GJ5 regulator has a dropout of about 0.2V to 0.3V, so theoretically the output voltage should drop off steeply for Vbat < 3.6V.
Looking at the schematic, I was unable to figure out exactly how this board is able to regulate to 3.3 volts with essentially no dropout. Is it using some sort of buck converter that isn't mentioned in the schematic, or some other clever circuit?
Any help understanding would be much appreciated!

your question is off-topic here

Answered my own question - I didn't realize that dropout voltage essentially goes to 0 for this regulator when current consumption is low. Pretty neat for low current applications with the ESP32.


text:
Arduino Motor Control at a Specific Time
Hello. Currently I'm working on creating an automatic dog food dispenser. I'm using a Arduino Uno R3, an L298N stepper driver, a DS1307 RTC breakout board, a Nema 17 stepper motor, and a breadboard to disperse the power to each board. I'm using a 9V battery to power it temporarily. I've tested motor control without it being determined by the current time and it works perfectly however when I have the motor run at a specific time (4:45 and 6:45 in the code) the motor doesn't move. How can I move the motor at these specific times?
#include <RTClib.h>
#include <Stepper.h>
#include <SoftwareSerial.h>

RTC_DS1307 rtc;

Stepper myStepper(200 , 9 , 10 , 11 , 12);

void setup() {
  Serial.begin(9600);
  rtc.adjust(DateTime(2021 , 7 , 14 , 4 , 44 , 0));
  myStepper.setSpeed(20);
}

void loop() {

  DateTime now = rtc.now();

  if ((now.hour() == 4 and now.minute() == 45) or (now.hour() == 6 and now.minute() == 45)) {
      Serial.println("testing");
      myStepper.step(10000);
      delay(1000);

}

}

You are pushing the limit of the L298N, probably will exceed it. A typical stepper motor like a NEMA 17 is probably rated at voltage of about 2.8 Volts and a maximum current of 1.68 Amps. This basically means if you hook it up to 2.8 Volts it will draw 1.68 Amps. If you try to run it at a higher voltage it will draw more current and get excessively hot. Driver Model: L298N has a Motor Supply Current (Maximum): 2A, Logic Voltage: 5V, Driver Voltage: 5-35V. The motor was rated at about 2.8V, powering it with more will very quickly exceed your bridge capacity. The Arduino will give you 5V and 3.3V but using either to power your motor will probably destroy the Arduino. The Arduino a power supply it is NOT! I suggest you use a seperate power supply for the motor. If you power the Arduino via Vin and use a buck converter from the 12V it should work fine.

Could I run a 9V battery into a breadboard and have both the motor and arduino using the same power supply?

@Carter If you mean those standard 9V block batteries, then no. They barely provide enough current for the Arduino itself, let alone any motor.

I’m new at this but looks to me like your rtc is uses i2c comms.  I don’t see that you’ve included wire.h or issued the wire.begin to initiate communication between the rtc and arduino.  See other rtc examples and good luck!

I'm new at this also and I found a few examples (all of which using an lcd screen) using wire.h but thought they were linked to the lcd. Its good to know that my guess was incorrect. Thanks for your help!

No problem.  Will be curious if that solves the issue.  Thanks.

The I2C communication is probalby already done by the RTC library. Thus there is no need for Wire in the main sketch

@chrisl. You would think, but RTClib shows wire as a dependency.

@Vince The point is that RTClib already #includes Wire.h. You only need to include libraries where they are used. Since Wire is not called in the main sketch, it doesn't need to be included there. Wire is called in the RTClib library, so that it included it at the start of its implementation.

Adding #include <Wire.h> and wire.begin(); worked

@Carter Glad it worked! Thanks for the update.


text:
Incorrect values arriving from Arduino to RPi over serial communication
I am trying to write four values relating to energy (current, power, energy, and peak demand) via a SoftwareSerial connection from my Arduino UNO to my Raspberry Pi 4.  However, two things are occurring:

All of the values should be different, but they are printing to the RPi terminal as if they're identical.

It seems as if the values I'm writing are merging together(?), creating a nonsense value.  For example, if the values that I'm sending are 0.24, 28, 0.05, and 71, they appear in the RPI terminal looking like this:

Current:  54543878
Power:  54543878
Energy:  54543878
Peak Power:  54543878
This is a snip of my Arduino code that writes to the Bluetooth serial connection (uses HC-06):
  bluetoothSerial.write(RMSCurrent);
  bluetoothSerial.write(RMSPower);
  bluetoothSerial.write(kilos);
  bluetoothSerial.write(peakPower);

This is a snip of the Python script that receives it:
while 1:
try:
    received_data = bluetoothSocket.recv(1024)
    RMSCurrent = int.from_bytes(received_data,byteorder='big')
    RMSPower = int.from_bytes(received_data,byteorder='big')
    kilos = int.from_bytes(received_data,byteorder='big')
    peakPower = int.from_bytes(received_data,byteorder='big')

    print("Current (A): %d" % RMSCurrent)
    print("Power (W): %d" % RMSPower)
    print("Energy (kWh): %d" % kilos)
    print("Peak Demand: %d" % peakPower)

except KeyboardInterrupt:
    print("keyboard interrupt detected")
    break
bluetoothSocket.close()

Does anyone have any ideas of what is going on?  Two of my values are floats and two are integers.  I've tried to fix this for the past 12 hours, but to no avail.

printing to the RPi terminal as if they're identical ... why are you surprised? ... it appears that you are setting all four to the same value .... print the value of received_data instead

@jsotola I get a hex ASCII code when received_data is printed.  I guess I'm just not sure how to parse the values I want from that and assign them to the four different variables.

0.24 is not an int. You python code expects ints only (and reads the first bytes of received_data four times).

You will save yourself a lot of headaches by sending the data in ASCII
instead of binary:
bluetoothSerial.print("RMSCurrent: ");
bluetoothSerial.println(RMSCurrent);

Of course, you will then have to parse the data stream on the Python
side.
If you really want to send binary data, then be aware that the write()
method you are using is intended for sending single bytes. Every number
you write() is converted to an integer (truncated if it's a float),
reduced modulo 256 to the range [0, 255], then sent as a single
byte. You can loose quite a bit of information in this process.
To send a binary object larger than a byte, you have to use an overload
of write() that takes both a pointer (the address of the object) and a
number of bytes to send. For example:
bluetoothSerial.write((uint8_t *) &RMSCurrent, sizeof RMSCurrent);

But then, you have to be aware that some numeric types do not have the
same binary representation on the Arduino and on the Pi. For instance:

an int is 2 bytes on the Arduino and 4 bytes on the Pi
a double is 4 bytes on the Arduino and 8 bytes on the Pi

I recommend you only use fixed-size integer types (uint16_t and such)
and float.
Also, be aware that the Arduino is little-endian, like the Pi, and
unlike what your Python code currently assumes.
Oh, and the serial link does not have a notion of data packets. If there
happens to be some leftover crap in the serial buffer when you start
your Python program, it will get out of sync with the Arduino, and you
will only read garbage. There are ways around this problem (search for
“packet framing”) but they add quite a bit of complexity.
As I said, you will save yourself a lot of headaches by sending the data
in ASCII instead of binary.


text:
Decoding of data received using the WL-101 433 MHz radio module
Good afternoon! This question is still relevant to me. I use the receiver module in conjunction with arduino. I want to use my own transfer protocol and now I need to accept it. I tried to use various libraries, but all without success. I need to somehow select a sequence of pulses and then determine their values (zero or one) by the duration of the pulses.
But first, I need to determine the beginning of the signal from the preamble (12 pulses at the beginning). I wrote a program that draws a graph where you can see the entire sequence.
Is it possible to define this preamble without using libraries, for example, to make a cycle that will measure the length of the pulses, and there are 12 times the duration of the pulses will be the same, then this is the preamble, followed by digital data.
#define IN_PIN 2
void setup()
{
  Serial.begin(115200);
}

void loop()
{
  bool s = digitalRead(IN_PIN);
  Serial.println(s);
}

it is not possible to guess what is wrong ... we do not know what you connected, how you connected it, and what code you ran

I am trying to plot a graph and see the low and high levels there, which I transmit with my transmitter. To do this, I use the program to read data from the analog port of the arduino, to which the 433 MHz receiver module is connected.
However, nothing is accepted.

It is not working because of:
SPEED
Consider the frequency of the 433Mhz device vs. the speed of the serial monitor. The device sends signals with pulse width in the range of tens of microseconds while the serial monitor can't display that fast.
Your code should analyze the signals, clean the noise (the output of the device is very noisy) and figure out the protocol. All that is done by dedicated libraries such as rc-switch which is very extensive and robust compared to just reading a pin and plotting the output.
DIGITAL
The recover device is outputting a digital pulse which based on it's pulse width changes one can figure out the sequence of numbers sent by the remote control. Each such ASK protocol has it's timing characteristics which you should follow in order to decode the code.
If you want to experiment with that vs. using a ready made library you should start with a code similar to the example below.
void setup() {
  Serial.begin(6000000);
  attachInterrupt(digitalPinToInterrupt(1), handleInterrupt, CHANGE);
}

void loop() {
}

void handleInterrupt() {
  bool s = digitalRead(1);
  Serial.println(s);
}

Just pay attention to the timing issue, this code will show a lot of data but not necessarily (almost for sure) not all the data, but you can avoid the serial print and use the data for analysis.

Thank you. But unfortunately I can't get absolutely anything with your code.
I tried to figure out the library, but I didn't get any data. As I understand it, the library works strictly according to a certain protocol, and the pulses that I send, it takes for noise, maybe.

Also the module you are using is limited to ASK so if you are sending anything else it will not be detected. As for code sample, not that it's listening on interrupt pin 1 (PA23_TC4-W1 on MKR 1010 WIFI), check with your Arduino what pin number it should be showing in order to work and transmit from a compatible device or remote control.

Как то мне здесь помог человек при решении подобной задачи, он поделился кодом, который из частот уровня лишь частоту 1 кГц и уже на ней сигнал анализировался. Это было Гомодинное обнаружение.
Сейчас я не знаю заранее точной частоты, которую нужно построить, пробовал использовать код, на обнаружение 1 кГц, но он не обнаруживает мой сигнал.
Мне нравится этот код тем, что он позволяет установить АЦП ардуино в режиме прямого преобразования, то есть обрабатывать сигнал очень быстро.
Подскажите, как можно оставить этот режим работы АЦП, но убрать выделение сигнала 1 кГц?

@Edgar Bonet, I used your code to detect a 1 kHz harmonic signal.
Tell me how I can use it to detect a rectangular pulse with a duration of 640 μs?


text:
Arduino Uno Esp8266 AT commands
I am trying to send AT commands to esp-01 through serial monitor I have uploaded a blank sketch to Arduino , whatever command I send to ESP I get reply ERROR.
After reconnecting esp-01 I got some garbage vales then ready.
Can anyone help me what I am doing wrong.
This is what I got on serial monitor

These are the connections I am using, I tried to use voltage divider but after using voltage divider, Esp's blue led turned on and nothing happened so I used just used the resistors in series between TX and TX of both devices

This is the voltage divider circuit I was using(that didn't worked)

Please upload your code so it can be examined against the results you are getting.

did you set line ends in Serial Monitor to "Both"?

you want a voltage divider on receiver pin of esp8266. the RX pin of the board is TX pin of the USB chip (because the USB chip is connected to ATmega RX to TX)

The hardware serial, pins 1 and 2, are used by the Arduino to communicate to the USB adapter to your computer.  When you connect another device to them, it interferes with the communication between your computer and the Arduino.
The solution is to connect the ESP-01 to another set of pins and use the SoftwareSerial library to create a second serial port for it.  The code then needs to listen on both serial ports and move data between them.
Also, you need to use the voltage divider or you risk burning out the input pin.  To make the voltage divider, connect the Arduino output to the top of the divider and the ESP-01 to the middle.  You appear to have those reversed in your schematic.

here the USB chip of Uno is connected to the esp8266 and the ATmega is inactive

The paragraph about the voltage divider regarding Rx is relevant though:To make the voltage divider, connect the Arduino RX0 to the top of the divider and the ESP-01 RXD to the middle. You appear to have those reversed in your schematic.

Sometime when I connect CH-PD to 3.3v, SP flash IC starts getting hotter and nothing works can you tell me what causing that ?


text:
Not getting any signal from myoware EMG muscle sensor. The signal LED (Red LED) on the sensor is always ON
This is my first time using EMG Sensor.
I'm trying to read EMG signals from Myoware Muscle Sensor.
When I use analogRead to read analog value, the value is almost same. There is not much change in the analog value.
EMG Sensor I'm using: Myoware Muscle sensor from Advancer Technologies.
Arduino Board: Arduino Mega.
When Sensor is turned ON, the Signal LED (Red LED) on the emg sensor is always ON. (I don't know if it is supposed to be always ON or not )
I have tried placing emg sensor on both forearm and biceps, but no change in the analog value.
I really dont know what is wrong here.
This is the code:
void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A5);
  //float millivolt = (sensorValue/1023)*5;

  Serial.print("Sensor Value: ");
  Serial.println(sensorValue);
  delay(1);
}

You are performing integer division in (sensorValue/1023)*5; this will result in 0 for any sensorValue less than 1023.  It would help to know what values were coming out of analogRead(A5)

I am getting values in the range 676 to 680 at all time. I'm not using the milliVolt value. For now I just want to  get analog values depending on the muscle contraction.

Eventually, forcing to float, ... change to :  float millivolt = (sensorValue/1023.0 ) * 5.0 ; ?

Yes I will. But for that I have to get the correct analog reading first.

I see this board ... https://learn.sparkfun.com/tutorials/myoware-muscle-sensor-kit/all but it is not the "same" ? I did not find your board.

Yes I'm using this board

Are you sure that the board in the picture above is "complete" ? It seems that it is only the MyoWare Cable board ? How did you wire the two boards ? https://cdn.sparkfun.com/assets/learn_tutorials/4/9/1/MyowareCable_ShieldStackedMuscleSensor.jpg ?

Sorry I missed to say that, When I designed the circuit in Fritzing, there was no myoware sensor board. Only cable board was available. So I choose it. Actually I'm using only the myoware sensor board.


text:
i want to combine below two codes
*****1st code
int sensoroutput = 3; // the analog pin connected to the sensor
int sensorinput = A0;
int THRESHOLD = 100;

void setup()
{
    pinMode(3, OUTPUT);
    pinMode(A0, INPUT);   // this function is used to declare gsm connected pin as output
}

void loop()
{
    int value = analogRead(sensorinput);  // function to read analog voltage from sensor
    if (value >= THRESHOLD)                    // function to check voltage level from sensor
    {
        digitalWrite(3, HIGH);
        delay(100);
    }
    else
        digitalWrite(3, LOW);
}

2nd code****
#include <SoftwareSerial.h>

SoftwareSerial sim800l(0, 1); // RX,TX for Arduino and for the module it's TXD RXD, they should be inverted

#define button1 7 //Button pin, on the other pin it's wired with GND

bool button_State; //Button state

void setup()
{
    pinMode(button1, INPUT_PULLUP); //The button is always on HIGH level, when pressed it goes LOW
    sim800l.begin(9600);   //Module baude rate, this is on max, it depends on the version
    Serial.begin(9600);
    delay(1000);
}

void loop()
{
    button_State = digitalRead(button1);   //We are constantly reading the button State

    if (button_State == LOW) {            //And if it's pressed
        Serial.println("Button pressed");   //Shows this message on the serial monitor
        delay(200);                         //Small delay to avoid detecting the button press many times

        SendSMS();                          //And this function is called
    }

    if (sim800l.available()) {            //Displays on the serial monitor if there's a communication from the module
        Serial.write(sim800l.read());
    }
}

void SendSMS()
{
    Serial.println("Sending SMS...");               //Show this message on serial monitor
    sim800l.print("AT+CMGF=1\r");                   //Set the module to SMS mode
    delay(100);
    sim800l.print("AT+CMGS=\"+918707578617\"\r");  //Your phone number don't forget to include your country code, example +212123456789"
    delay(500);
    sim800l.print("SIM800l is working");       //This is the text to send to the phone number, don't make it too long or you have to modify the SoftwareSerial buffer
    delay(500);
    sim800l.print((char)26);// (required according to the datasheet)
    delay(500);
    sim800l.println();
    Serial.println("Text Sent.");
    delay(500);

}

So... what's stopping you combining those two codes?

what is your question? ... this is a Q&A site ... a specific, answerable question is required


text:
Why no brackets after Interrupt routine inside attachInterrupt
I'm just curious as to why there are no brackets at the end of the ISR when attaching and assigning the interrupt command?
 attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
 ...
 void blink() {
    state = !state;
 }

In, attachInterrupt, I would have expected "blink" to be written as "blink()", with the brackets, not just the name of the function, sort of like how you would normally call the function blink() from your loop or setup functions (or elsewhere). So, what's going on here, and are there other scenarios where you might use a function without the brackets after it?

Who on earth would want to close this? It is a good question.

Moderators can see the users who voted to close this question.

It is right, that you are putting brackets after the function name if you are calling it. But with attachInterrupt() you just want to give it the information, which function to call in case of an interrupt. With the brackets the compiler would think you want the function to be executed and the result/return value being given as parameter to attachInterrupt(). But the execution here should only happen in case of an interrupt. The attachInterrupt() function/the corresponding ISR need to know, what to call in case of an interrupt. Just the information/address of the function.
Maybe you have already heard of pointers. That are variables that hold the address of a different variable. They are pointing somewhere else in the memory. blink (without the brackets) is basically a function pointer. Leaving the brackets away tells the compiler, that you want the address of the function, not executing it. You are providing the function parameter by reference this way, providing the address, not the value.
If you like/need you can use that principle yourself by defining your own function pointer variable. For example this
void (*myCallbackFunction)(int);

which is a function, that takes an int as parameter and returns nothing (void). You can then set the function pointer and call it as a normal function
void blinkXTimes(int times){
    for(int i=0;i<times;i++){
        digitalWrite(pin, HIGH);
        delay(500);
        digitalWrite(pin, LOW);
        delay(500);
    }
}

void setup(){
    pinMode(pin, OUTPUT);
    myCallbackFunction = blinkXTimes;

void loop(){
    myCallbackFunction(3);
    delay(5000);
}

We are calling myCallbackFunction(), but it is a function pointer, that points to blinkXTimes(), so that will be executed.

So, what's going on here, and are there other scenarios where you might use a function without the brackets after it?

The above principle is super useful for writing libraries with user callback functions. Another example (besides attachInterrupt()) is the Wire library. There the receive and request interrupts need to interact with the library user to deliver to or request data from him. For this the Wire library lets you set your own callback functions. Refer to the examples of that library.
Another application would be building a Finite State Machine with a function pointer (basically calling different functions on each loop iteration depending on the state, which is represented by the function pointer).
That are the two big application I know of. The first one is more common. Though function pointers are just a tool. They can be used for many things.

This was phenomenally helpful!!!

Just nit-picking, but giving a pointer as an argument for a pointer parameter is still passing by value. In C++ there is just one way to pass by reference: If you have a reference parameter like void f(TYPE & p);.

Unfortunately a lot of these terms are overloaded. The C standard used the term "referenced type" for T in the T * construction, but C++ doesn't use this term there.  However, the application of unary * operator to a pointer is still literally called "dereferencing" a pointer in C++.  Admittedly, that terminology for use as passing-by-way-of-pointer-value is more confusing in C++ than it was/(still is) in C. But, it is commonly used and understood in context, even by C++ programmers, if otherwise imprecise. For anyone that hasn't encountered this usage yet, well, now you have.


text:
Arduino Multiplexer Input voltage per pin not decoupled
I am very new to electronics (software engineer background).
I want to send an analog signal (5V) to one/many input wires. The input wires are connected to a 16 channel mutiplexer.
My arduino then reads all of the 16 channels.
Right now the issue is: If I connect only one pin to the 5V output of the arduino many other of the multiplexer input pins also read high voltage values even tho only one pin is actually connected.
I am pretty sure this issue is a duplicate - please point me to the right direction.
I have read about decoupling (if that is the case - please explain it for newbies without background).

It is not clear at all what you are doing. Please show a schematic of exactly what you have connected on the multiplexer (including power, ground, selectors), and what/where you are measuring.

Please show a schematic or a picture of your setup. What multiplexer are you using? Also understand that an unconnected input has an undefined value and might read high or low or even oscillate between them. It’s much better to connect an unused input to either ground or Vcc to give it a defined value and not have it pick up noise.

As I understand it you have a multiplexer with one of the inputs connected to 5 volts and the rest are open. What you are reading is leakage in the IC and associated wiring. There are many reasons they tell us not to leave inputs open, you just found one. This is especially problematic with CMOS devices because of there extremely high impedance. The first thing the TI publication
SCBA004D–July 1994–Revised September 2016 tells you is power consumption is
becoming a major issue in today’s market. However, when designing systems using CMOS and BiCMOS devices, one must understand the characteristics of these families and the way inputs and outputs behave in systems. It is very important for the designer to follow all rules and restrictions that the manufacturer requires, as well as to design within the data-sheet specifications. Because data sheets do not cover the input behavior of a device in detail, this application report explains the input characteristics of CMOS and BiCMOS families in general. It also explains ways to deal with issues when designing with families in which floating inputs are a concern. Understanding the behavior of these inputs results in more robust
designs and better reliability.


text:
Arduino Nano not recognized by Mabook Pro M1
I am new to Arduino and I have ran into an issue. When I first tried to plug the arduino nano (after market, from ebay) into my computer (Macbook pro M1), nothing happened. Then I downloaded the cp210xVCP Driver. After that, when I plugged in the nano, the /dev/cu.usbserial- 1110 appeared. But when I try to get board info noting happens. It's like the computer recognize there is something, but does not know what. I believe Arduino is not fully compatible for M1 macbooks, but is there something I can do to fix this?

Have you tried uploading a sketch now your board is detected by the OS?

My Arduino clones don't give any Board Info either, so this might be not related to just M1 Macbooks...

Majenko and Python Schlange have the right of it I think. This is a common and well documented phenomenon. Check out the comments on the Arduino forum by the arduino team which explain PIDS and VIDS on USB equipment and why the clones appear differently. It shouldn’t (all going according to plan) make a difference other than the board information not being present as you’ve noted. That’s why Majenko is suggesting you go ahead and upload a sketch. The Blink example sketch is frequently used for this as a first board test when you receive something new.
See also USB FT232 driver on M1 mini for more information about checking USB ports on the Mac.


text:
Problem with first two samples of serial data received by RPi
I'm trying to receive a string from an Arduino to a Raspberry Pi via a Bluetooth socket connection (RFCOMM).  I'm using an HC-06 Bluetooth module, an Arduino UNO R3, and an RPi 4 Model B.  For the most part, everything is working well --except the first two data samples.  This is what my output generally looks like when I view it from the RPi terminal:
0.
06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64

Is there any way I can get the first two lines to show the data properly?  This data is a singular string and I chose my buffer to be 32 bits, so I don't think buffer size is the issue.  I had to add time.delay(4) in my Py script or else every sample of the data would look messed up.  I've tried adjusting the time delay relentlessly, but I can't seem to get the first two samples to display correctly.  Below is a bit of my Python code:
while 1:
try:
        received_data = bluetoothSocket.recv(24)
        formatted_data = received_data.decode("utf-8")
        print("Received Data: ", formatted_data)
        time.sleep(4)

except KeyboardInterrupt:
        print("keyboard interrupt detected")
        break
bluetoothSocket.close()

why do you say that it is a problem with first two samples? ... it looks like a problem with just one line

@jsotola You're correct.  It's just the first sample being split into two lines.

It could be some previous data being buffered by the HC-06 which finally gets to come through once the rfcomm port is opened. Nothing much you can do about that unless you create a bidirectional protocol to instigate the communication only once the port is opened and the receiving program is ready to receive.

@Majenko Is there any way on the receiving Py script that I can have the socket "hold on" to the incoming string until a certain event happens?  I heard there may be a way to do this so that when "\n" is reached, everything will be released from the socket.

@phosphorescent I don't know - that's Python. I don't use Python. Personally I would have the Arduino do nothing at all until your Python program requests data to be sent. That way there can be no buffering issues. Also yes, you should read data up to the \n and use that as the delimiting factor of your communication instead of assuming 24 bytes.

Simple fix: send a boilerplate first instead of jumping right to data. Something like --BEGIN--\n that you can easily strip out in python.

You might want to try sending the data in a packet delimited by unique characters, e.g. { and }, similar to the JSON format.
The NMEA GPS standard uses $ and '\n' to delimit messages.
Here is an Arduino non-blocking C++ algorithm which builds upon Majenko's readline() example to read a packet. It returns true when incoming data has been accumulated into a valid packet. It should be fairly straightforward to convert it to Python.
void setup()
{
    Serial.begin(115200);
    Serial.println(F("\n\nSerial Packet Test\n"));
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
    const static unsigned int INTERVAL = 200;
    static unsigned long previous_timestamp = millis();
    unsigned long current_timestamp = millis();
    static bool led_state = false;

    if (current_timestamp - previous_timestamp >= INTERVAL)
    {
        led_state = !led_state;
        digitalWrite(LED_BUILTIN, led_state);
        previous_timestamp += INTERVAL;
    }

    static char packet[100];

    if (ReadPacket(Serial, packet, sizeof(packet)))
    {
        Serial.print(F("Received packet >"));
        Serial.print(packet);
        Serial.println(F("<"));
    }
}

bool ReadPacket(Stream& stream, char *const packet, const unsigned int SIZE)
{
    const char FIRST = '{';
    const char LAST = '}';
    static bool read_until_last = false;
    static unsigned int i = 0;
    char ch;

    if (stream.available())
    {
        ch = stream.read();

        if (ch == FIRST)
        {
            Serial.println(F("Received FIRST."));
            i = 0;
            packet[0] = ch;
            read_until_last = true;
            return false;
        }
        if (read_until_last)
        {
            i++;
            if (i > SIZE - 2)
            {
                Serial.println(F("Buffer overrun. Resetting to look for next packet."));
                i = 0;
                read_until_last = false;
                return false;
            }
            if (ch == LAST)
            {
                Serial.println(F("Received LAST."));
                packet[i++] = ch;
                packet[i] = 0;
                read_until_last = false;
                return true;
            }
            else
            {
                Serial.print(F("Received char >"));
                Serial.print(ch);
                Serial.println("<");
                packet[i] = ch;
                return false;
            }
        }
    }
    return false;
}

I don't know what the time.sleep(4) statement fixes, but you could try moving the  to the top of the loop instead of the bottom, so it precedes the first read. At the bottom of the loop, it's first execution comes after the first read.


text:
Can I pass data from an Arduino Nano to a Websocket Server via USB?
I have an Arduino Nano, and a local Java WebSocket server (ws://localhost:8888) run by a .jar file on my computer.
I'm wondering if it's possible to send data (text, numbers etc.) from the Arduino Nano to the WebSocket server via USB cable (USB-A to USB Mini, one that normally powers the Nano).
If so, what do I need to do it?
A quick Google for WebSocket Arduino libraries reveals:
Websockets and Arduino Websocket Fast, but looking at the examples, the former uses Ethernet.h and the latter uses Wifi.h, and I'm unsure if my board is compatible with that without other modules.

I don't know the possibilities you have in WebSocket, but the ordinary way to communicate with an Arduino (when it does not have a Wifi or Ethernet HAT) is via Serial. You can use basically any serial communication library to send strings from/to the Arduino.

I figured as much, I'm trying the SerialPort library and facing an issue, see here: https://github.com/serialport/node-serialport/issues/2297

You fail to describe what error you get and what doesn't work.

It's in the title of the issue, and mentioned again in the issue

I ended up using Python to bridge Serial to WebSocket. I wanted flexibility in sending from WebSocket back to Serial too, so I didn't try a prepackaged solution like https://github.com/RandomStudio/serial-to-websocket

it is what RaulG recommended some days ago. it would be nice to accept his answer and not to write a new one

As @Majenko already said the ATmega328 uses a serial connection to communicate. Another chip on the board translates the serial data to USB-Format and the other way around. This enables your computer to interact with the main chip on the Nano (ATmega328).
To solve your problem you might try using something like this simple serial-to-websocket node-server that listenes to data coming in from a serial port and sends it out over WebSocket.

No, you can't. The Arduino has a serial connection, not a network connection. If the Java program is of your own devising you would need to rewrite it to use serial instead of (or as well as) WebSockets. Either that or write a separate piece of software for your computer to go between the Arduino's serial connection and the WebSockets interface.


text:
CH340K - Unknown USB Device (Device Descriptor Request failed)
I have a Arduino Nano clone working fine with the CH340 drivers. It has a CH340C on it.
I made a custom PCB. CH340 chips are hard to come by these days, so I opted for the CH340K, From the datasheet, seems like it should work similar to the CH340C and CH340G that are quite common.
My PCB has a footprint for both the CH340K and CH340C/CH340G (Yes, I'm aware I'm missing the load capacitors for the CH340G). CH340C/N/K/E and CH340B have built-in clocks without external crystal oscillator. So no need for a crystal.
After soldering on the CH340K and USB port, I plugged the device in, and I'm getting an error in Windows 10 Device Manager:

Unknown USB Device (Device Descriptor Request failed)
Windows has stopped this device because it has reported problems.
(Code 43)
The USB set address request failed.

I've uninstalled and reinstalled the CH340 drivers several times. Tried to force the driver onto the device in device manager, and it didn't let me.
There's no short to ground or vcc.
Any help to get this recognized would be great! thanks!
CH340K Pinout

PCB

i think that i remember that the driver has inf and ini  files associated with it ... they are text files ... some editing may be required ... google CH340K inf

What is "the CH340 drivers"? When I google this, I get 967000 results.

Schematic? PCB design? Without those we can't help you

A failure to read the device descriptor generally means that there is a hardware fault. It's not getting as far as even knowing that there is a real USB device attached, let alone working out which driver might fit the bill. You either have a fault in your design, a fault in your PCB layout or a fault in your soldering.

Common problems include: * Accidentally swapping D+ and D-, * Shorting one of the data lines somewhere, * Incorrect crystal, * Incorrect crystal load capacitors, * Incorrect crystal layout (all three latter ones causing the wrong clock speed to be generated)

Thanks all. I added some details to the post. Finding issues with CH340 K is impossible with all the other pages about the more ubiquitous C and G cluttering up search results.

That all looks ok to me except one thing: you have no decoupling capacitor on the V3 pin. The datasheet stipulates this as needing 100nF on it.

Also, the DP trace is very close to the edge of your board. Have you confirmed continuity of that trace? You should leave at least 0.5mm gutter around the edge of your board to allow for tearing during routing or v-grooving.

If I remember correctly, the official Windows driver does not support the latest revisions of the CH340. Can you tell us the error code that is shown in the device manager?

I checked the board, the traces are fine. Just updated post with the Windows error specifics. Maybe I should contact the manufacturer and see if there's an updated driver? I'm not expecting much support from them as the cheap manufacturer they are.

Majenko, was the 100nf capacitor for the win! Thought I didn't need it since I wasn't going to be using the LDO output for anything else on the board. Want to make the official answer?

I’m experiencing the same issue, did you fixed it with the decoupling capacitor?
I tried to install it but no luck so far…

Needed a 100nf capacitor on the v3 pin, per Majenko's suggestion, and per datasheet.
I thought this was only needed if you were going to use the 3.3v output for other purposes. I was wrong!
Same requirement for the CH340C!

on you Pcb the Footprint is not correct!
UD+ is on GND, UD- is on UD+ and GND is on UD- . The CH340K has a differnt Footprint.

did you read the other answer by OP?

Pin 0 is the exposed pad.