body:
i want to send an array of int to another arduino by serial.

To garantie a better robust during the transmission, i added < and > with endMarker and startMarker.

The receiver wait until the Hardware Serial is open, and read the data from the Software Serial from the sender.

Code for the sender:

    int test[] = {1, 2, 3, 4, 5, 6, 7};

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

    void loop() {
      for (byte i = 0; i < 7; i++) {
        Serial.write("<");
        Serial.write(test[i]);
        Serial.write(">");
        delay(500);
      }
    }

Code for the reader, i edited the code from here: http://forum.arduino.cc/index.php?topic=396450

    // Example 3 - Receive with start- and end-markers

    include <SoftwareSerial.h>

    const byte numChars = 32;
    char receivedChars[numChars];

    boolean newData = false;

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

    void setup() {
        Serial.begin(9600);
        mySerial.begin(9600);
        Serial.println("<Arduino is ready>");
    }

    void loop() {
        recvWithStartEndMarkers();
        showNewData();
    }

    void recvWithStartEndMarkers() {
        static boolean recvInProgress = false;
        static byte ndx = 0;
        char startMarker = '<';
        char endMarker = '>';
        char rc;

        while (Serial.available() > 0 && newData == false) {
            rc = mySerial.read();

            if (recvInProgress == true) {
                if (rc != endMarker) {
                    receivedChars[ndx] = rc;
                    ndx++;
                    if (ndx >= numChars) {
                        ndx = numChars - 1;
                    }
                }
                else {
                    receivedChars[ndx] = '\0'; // terminate the string
                    recvInProgress = false;
                    ndx = 0;
                    newData = true;
                }
            }

            else if (rc == startMarker) {
                recvInProgress = true;
            }
        }
    }

    void showNewData() {
        if (newData == true) {
            Serial.print("This just in ... ");
            Serial.println(receivedChars);
            newData = false;
        }
    }

I don't know if the problem is the serial.write, that send bytes, or i need to use serial.print to send string.

title: array to serial

Answers: 1

body:
You are attempting to use an 8-bit binary protocol to transmit 16 bit values, and then wrapping it in ASCII characters.  There is:

* No way to differentiate the ASCII characters from the 8 bit binary data, and
* No way to fit 16 bits into an 8 bit protocol.

The simplest way is to use `Serial.print` to make the whole protocol ASCII:

    Serial.print("<");
    for (byte i = 0; i < 7; i++) {
      Serial.print(test[i]);
      if (i < 6) {
        Serial.print(",");
      }
    }
    Serial.println(">");

Which would send out:

    <1,2,3,4,5,6,7>


body:
[![enter image description here][1]][1]Im working on a project where I want to connect 32 servos together.
 I got:
-Arduino uno
-2 PCA9685 16-Channel 12-bit PWM/Servo Shield
-power supply 5v 10 A
-All wiring is to the right pins (I have checked that several times)

So I got the 2 PCA9685 16-Channel 12-bit PWM/Servo Shield from Adafruit I connected all the wires as its supposed to be and I connected the shield to an external power supply which is 5V 10A that should be sufficient for it to work but unfortunately servos are not moving at all although the serial monitor is giving numbers I don't know where is the problem coming from.
ps. Im using the Adafruit library
its not even moving one servo (although the servo moves when connected directly to the Arduino.
thank you in advance.

the code I'm using its one of the examples from the library:

    /***************************************************
      This is an example for our Adafruit 16-channel PWM & Servo driver
      Servo test - this will drive 8 servos, one after the other on the
      first 8 pins of the PCA9685

      Pick one up today in the adafruit shop!
      ------> http://www.adafruit.com/products/815

      These drivers use I2C to communicate, 2 pins are required to
      interface.

      Adafruit invests time and resources providing this open source code,
      please support Adafruit and open-source hardware by purchasing
      products from Adafruit!

      Written by Limor Fried/Ladyada for Adafruit Industries.
      BSD license, all text above must be included in any redistribution
     ****************************************************/

    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>

    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    // you can also call it with a different address you want
    //Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
    // you can also call it with a different address and I2C interface
    //Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(&Wire, 0x40);

    // Depending on your servo make, the pulse width min and max may vary, you
    // want these to be as small/large as possible without hitting the hard stop
    // for max range. You'll have to tweak them as necessary to match the servos you
    // have!
    #define SERVOMIN  150 // this is the 'minimum' pulse length count (out of 4096)
    #define SERVOMAX  600 // this is the 'maximum' pulse length count (out of 4096)

    // our servo # counter
    uint8_t servonum = 0;

    void setup() {
      Serial.begin(9600);
      Serial.println("8 channel Servo test!");

      pwm.begin();

      pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

      delay(10);
    }

    // you can use this function if you'd like to set the pulse length in seconds
    // e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
    void setServoPulse(uint8_t n, double pulse) {
      double pulselength;

      pulselength = 1000000;   // 1,000,000 us per second
      pulselength /= 60;   // 60 Hz
      Serial.print(pulselength); Serial.println(" us per period");
      pulselength /= 4096;  // 12 bits of resolution
      Serial.print(pulselength); Serial.println(" us per bit");
      pulse *= 1000000;  // convert to us
      pulse /= pulselength;
      Serial.println(pulse);
      pwm.setPWM(n, 0, pulse);
    }

    void loop() {
      // Drive each servo one at a time
      Serial.println(servonum);
      for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
        pwm.setPWM(servonum, 0, pulselen);
      }

      delay(500);
      for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
        pwm.setPWM(servonum, 0, pulselen);
      }

      delay(500);

      servonum ++;
      if (servonum > 7) servonum = 0;
    }

  [1]: https://i.stack.imgur.com/fXQha.jpg

title: PCA9685 servo shield not working

Answers: 1

body:
You have your SDA and SCL pins connected backwards.

* SDA is A4
* SCL is A5

You have it the other way around.


body:
I currently have limited electronics experience. I am planning to use mains power through relays for climate control, so considering the risk, I would like to check to see if these relays are appropriately connected to receive mains power.

I have two relays. One relay will take 600W (a heater) while the other will have 50W/0.2A (a fan).

The relay module is: https://www.auselectronicsdirect.com.au/assets/files/(ST1080)5V Relay module.pdf
There seems to be a resistor inbuilt into the casing, and according to the packet (but not the PDF) there is inbuilt Back-EMF protection.

My concern is that it may not be protected against inrush, uses screw terminals, and may not be isolated.

Diagram is:
[![enter image description here][1]][1]

Any advice will be appreciated. Once again, I will not run mains power through it until I am sure of it being safe.

  [1]: https://i.stack.imgur.com/FFAKg.png

title: Are these relays connected correctly?

Answers: 1

body:
Yes, your relays are hooked up the right way. I'm using the same modukes to drive a fan 75W and a HPS-Lamp with 400W. As long as you drive the heater with AC voltage, you're in the specs (different than stated in previous comments).
But the humidity sensor (a DHT11/22) isn't, as far as I remember its pinout...
And could you explain what the Transistor is for (if it is a transistor, I'm curious what you want to achieve with this wiring)?


body:
I am using [ADXL345][1] sensor connecting with Arduino via I2C interface, I am able to test the data at tri-axial axis but as there are some other features also, which I am going to try with Tap detection method as I didn't use TAP THRESH register and instead of that I am using the registers (in decimal) of Tap latency - 33, Tap Duration - 34, Tap Window - 35.

For which I just started with raw code,

    #include <Wire.h>

    // ADXL345 I2C address is 0x53(83)
    #define Addr 0x53

    void setup()
    {
      // Initialise I2C communication as MASTER
      Wire.begin();
      // Initialise serial communication, set baud rate = 9600
      Serial.begin(9600);

      // Start I2C Transmission
      Wire.beginTransmission(Addr);
      // Select bandwidth rate register
      Wire.write(0x2C);
      // Normal mode, Output data rate = 100 Hz
      Wire.write(0x0A);
      // Stop I2C transmission
      Wire.endTransmission();

      // Start I2C Transmission
      Wire.beginTransmission(Addr);
      // Select power control register
      Wire.write(0x2D);
      // Auto-sleep disable
      Wire.write(0x08);
      // Stop I2C transmission
      Wire.endTransmission();

      // Start I2C Transmission
      Wire.beginTransmission(Addr);
      // Select data format register
      Wire.write(0x31);
      // Self test disabled, 4-wire interface, Full resolution, Range = +/-2g
      Wire.write(0x08);
      // Stop I2C transmission
      Wire.endTransmission();
      delay(300);
     }

     void loop()
     {
       unsigned int data[3];
       for(int i = 0; i < 3; i++)
       {
        // Start I2C Transmission
        Wire.beginTransmission(Addr);
        // Select data register
        Wire.write((33 + i));
        // Stop I2C transmission
        Wire.endTransmission();

        // Request 1 byte of data
        Wire.requestFrom(Addr, 1);

        //Read Three Bytes
        if(Wire.available() == 1)
        {
          data[i] = Wire.read();
        }
     }
       int TAP_DUR = data[1];
       int TAP_LAT = data[2];
       int TAP_WIN = data[3];

       Serial.print("TAP DURATION: ");
       Serial.println(TAP_DUR);
       Serial.print("TAP Latency: ");
       Serial.println(TAP_LAT);
       Serial.print("Tap Window : ");
       Serial.println(TAP_WIN);
       delay(3000);
       }

which is not working properly, and giving the result like this

    TAP DURATION: 0
    TAP Latency: 0
    Tap Window : 22272
    TAP DURATION: 0
    TAP Latency: 0
    Tap Window : 22272
    TAP DURATION: 0
    TAP Latency: 0
    Tap Window : 22272

The main aim is to test the no of tap count and duration between single tap and double tap rather than using any library I need to work with the code I have been making.

Suggestion and bits of advice to make it work will be welcome.

  [1]: https://store.ncd.io/product/adxl345-3-axis-accelerometer-13-bit-i2c-mini-module/

title: Trying to use Tap Detection solution using ADXL345 with Arduino

Answers: 1

body:
the arrays are indexed from 0 but you assign to TAP_ variables array values indexed 1,2,3.

Are you sure the sensor is wired ok? Did it work with a library example?


body:
Help me to choose a power source for the below project:

 - 4x DC Motors (3V~6V DC each with ~170mA),
 - 1x Micro Servo Motor (4.8V~6V),
 - 1x Ultrasonic sensor
 - 1x Bluetooth sensor

It is basically an RC car. The project runs on Arduino UNO and it uses Motor Shield (1.2) to power up those five motors. The motor shield does support external power supply. Shall I go for that, or Arduino can power up the entire system altogether?

title: Choosing a proper power source for for basic RC car with 4 motors

Answers: 2

body:
[2S LiPo](https://hobbyking.com/en_us/batteries-chargers/batteries/lipo.html?config=52) with [5V UBEC](https://hobbyking.com/en_us/power-systems/power-distribution/vr-ube-bec-sbec.html) is what you want.  Hit your favourite RC model seller for those.  I use HobbyKing (as the links show).

The capacity choice of the LiPo depends on

* How much power your motors etc need, and
* How long you want it to run for

You could also go for 3S or 4S to get more power if your chosen UBEC supports the voltage.

body:
Many [fake] Arduino UNO boards on the market have an AMS1117 regulator for external power supply from 7.5v to 12v. note that it's a linear regulator and it "wastes" the excess power as heat and compared to the very demanding components you have (about 1 amps) it's obviously not an option. so no. you can't use "External" supply of Arduino to power them all.

it's best to use separate supplies for each board. or you may Use a 5V Battery Kit and connect it to 5V pin on either shields.


body:
I trying to loop over a function in arduino to get values for 2000 times, and then divide it by 2000 to get an average offset:

    int16_t x_offset = 0;
    int16_t y_offset = 0;
    int16_t z_offset = 0;

And inside `setup()`:

    for(int i=0; i<2000;i++)
      {
        GetXYZ(x_offset, y_offset, z_offset);
        x_offset += x_offset;
        y_offset += y_offset;
        z_offset += z_offset;
        Serial.println(x_offset);
        delay(3);
      }
      x_offset /= 2000;
      y_offset /= 2000;
      z_offset /= 2000;
      Serial.println(x_offset);Serial.println("...");Serial.println(y_offset);Serial.println("...");
    Serial.println(z_offset);Serial.println("...");

Here is the GetXYZ() function:

    void GetXYZ( int16_t &x, int16_t &y, int16_t &z) {
      // Get the gyro values
      Wire.beginTransmission(MPU);
      Wire.write(0x43);     // first register of gyro values
      Wire.endTransmission(false);

      Wire.requestFrom(MPU,6);
      x = Wire.read() << 8 | Wire.read();
      y = Wire.read() << 8 | Wire.read();
      z = Wire.read() << 8 | Wire.read();
    }

The values printed in the serial of `x_offset`, `y_offset` and `z_offset` are always `0`.

title: Arduino loop over a function is always displaying 0 as final values

Answers: 1

body:
There's a couple of things wrong here:

1. You are just getting the last read value doubled:

    x_offset += x_offset;

However `x_offset` is always replaced with the lates reading.  You're not summing anything.

2. To get anything other than 0 out of dividing an integer by 2000 the value stored in the integer would have to be > 2000. But since you can only store a maximum of 32767 in your int16_t variables, even if you didn't have the problem in point 1, the variables would overflow and the results would be meaningless.

You need to:

* Use a second variable per axis to store your total
* Ensure that it is big enough to store the maximum reading × 2000.  I'd suggest a `long` or `int32_t`.

For instance:

    int16_t x_offset = 0;
    int16_t y_offset = 0;
    int16_t z_offset = 0;
    int32_t x_total = 0;
    int32_t y_total = 0;
    int32_t z_total = 0;

And inside setup():

    for(int i=0; i<2000;i++)
      {
        GetXYZ(x_offset, y_offset, z_offset);
        x_total += x_offset;
        y_total += y_offset;
        z_total += z_offset;
        Serial.println(x_offset);
        delay(3);
      }
      x_total /= 2000;
      y_total /= 2000;
      z_total /= 2000;
      Serial.println(x_total);Serial.println("...");Serial.println(y_total);Serial.println("...");
    Serial.println(z_total);Serial.println("...");


body:
I have an application that is being controlled by an Arduino. At one point in the process, it needs to determine the level of vacuum in a chamber and adjust it to within a range of values.

I can control the vacuum pumps easily enough, but it is hard to find a vacuum sensor for the Arduino. I need a sensor that can be reasonably accurate down to roughly 28 inches mercury and would connect by a tube. I can't put the sensor directly into the chamber.

Does anyone know of an Arduino sensor that would work? If not, could someone suggest a sensor component that may work with an Arduino. I would prefer to not have to engineer a solution from the sensor component up but I can if I need to.

title: Vacuum pressure sensor for Arduino

Answers: 1

body:
Industrial pressure/vacuum sensors are sturdy and rigid. They have extra protection, for example to use it submersible. The manufacturer often make them for certain voltages (for example 24v) and with different outputs (0..5v output, or 5-20ma output, and so on).
There are cheap versions of those sensors. They are between 5 and 20 dollars on Ebay and Aliexpress.
The manufacturers do not tell which sensor they use inside, and it can be hard to find a sensor that is exactly the one that you need.

The bare sensor is often a piezoresistive sensor in a wheatstone bride configuration. The output voltage span of those sensors is very low and not suitable to connect directly to an arduino board.
The advantage can be that they do not have a operating voltage. Only a maximum voltage.

The ideal pressure/vacuum sensor has a temperature compensation and a gain and a output span that is near 5v. You find most of them at nxp.com.
Luckely they have also a vacuum sensor with a large range, for example the MPXV6115V.

Those sensors are ratiometric. Power them with the arduino 5v and use the arduino 5v as analog reference (that is the Arduino default setting). When the 5v changes, the resulting measured pressure does not change and is still accurate.

Never solder something to the unused pins. Those pins can be connected to something inside.

There are a few ways to calculate the pressure. One way is to use the formula from the datasheet, the other way is to map the output voltage span to the pressure span and correct for the offset of the output voltage.


body: Is it possible to ping a sensor, like DHT22 or 18B20, to check for connection. I want to do an error check in `void setup()` and make sure all sensors are connected properly.

title: Ping a sensor for error checking

Answers: 2

body:
There isn't one answer for all sensors. Some may implement a self-check; if not, an operator could provide a specific environment at startup, which setup() would test for. Otherwise, about all you can do is a sanity-check on the output.

DS18b20 - the Dallas/Maxim one-wire digital thermometer, for example, has a specific value immediately after reset; you could check for that before commanding a measurement. Or simply take a sample and make sure it "makes sense". The specific tests available depend on what a given sensor implements.

body:
There is no simple "yes" or "no" answer to this.

You need to check the datasheets and libraries for your chosen devices and see what is available.  Many libraries will have `begin()` function, which may, or may not, return whether the device is working.

Many may just lock up waiting for communication, and there's not a lot you can do with that short of reprogramming the library to work differently.

Some (especially analog sensors) will return values from their reading functions that are far outside a tolerable range that you could assume indicated a malfunction.

For I2C based sensors you could use a variant of the [I2CScanner](https://playground.arduino.cc/Main/I2cScanner) sketch to look at what addresses are in use before attempting to use the sensors themselves.

Other protocols may have a similar system you can use to examine what is on the bus.


body:
Good day.

I am new in Arduino so please bear with me. I need to know if Pins other than Pin 0 and 1 can be used as a serial connection. I have 3 devices that needs to be connected to Arduino via USB, but when I saw the specification of Arduino, it only implicate that only pins 0 and 1 is used for serial rx/tx. So is it possible to connect the other 2 usb connector via pin 2 to pin 5

Thank you very much for your answer

title: Arduino pin 3 to 7 used in serial data transfering

Answers: 3

body:
pins 0,1 are rx/tx for the hardware UART peripheral. Arduino (I assume UNO/Nano) have just one hardware UART.

there is a software library which makes use of any 2 pin to simulate hardware UART pin behavior for additional software UARTs (this is called bit banging). these "software" UARTs are not as fast as hardware ones and can't be relied on for fast baudrates (speeds). but for 9600kbps, they're good.
keep in mind, that despite they are easy to implement and versatile, they use CPU time when communicating and if you are using interrupts in your code, data flow will be affected.

https://www.arduino.cc/en/Reference/SoftwareSerial

body: If you need your Arduino to be a USB slave for additional serial interfaces, then you can connect FTDI Basics to hardware serial ports (such as on Mega) or to software serial ports (such as on Mega).

body: Try to avoid the SoftwareSerial library, it’s very unreliable, that I can tell you from experience. In exchange try AltSoftSerial or NeoSWSerial, far better.


body:
I am using the [arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets/) library in my own Arduino library. I'm having trouble with trying to assign a class member as the websocket library `onEvent` callback function.

MyClass.cpp:

    #include <WebSocketsClient.h>
    #include "Arduino.h"
    #include "MyClass.h"

    void MyClass::connect(String host, int port) {
      webSocket.begin(host, port, "/");
      webSocket.setReconnectInterval(5000);

      // tried all these variations
      // webSocket.onEvent(incomingEventHandler);
      // webSocket.onEvent(MyClass::incomingEventHandler);
      webSocket.onEvent(this->incomingEventHandler);
    }

    void MyClass::loop() {
      webSocket.loop();
    }

    void MyClass::incomingEventHandler(WStype_t type, uint8_t *payload, size_t length) {
      // do stuff with incoming data
      // need to access other member functions and class variables
    }

MyClass.h:

    #ifndef MyClass_h
    #define MyClass_h

    #include <WebSocketsClient.h>
    #include "Arduino.h"

    class MyClass {
      public:
        void connect(String host, int port);
        void loop();
        void incomingEventHandler(WStype_t type, uint8_t *payload, size_t length);
      private:
        WebSocketsClient webSocket;
    };

    #endif

The error returned is:

> sketch/MyClass.cpp: In member function 'void MyClass::connect(String,
> int)': MyClass.cpp:14:47: error: no matching function for call to
> 'WebSocketsClient::onEvent(<unresolved overloaded function type>)'
> webSocket.onEvent(this->incomingEventHandler);

---

From what I understand it seems like I need to create a pointer to the class member, I have tried a few different ways, this one seemed the most promising, but still failed:

    typedef void (MyClass::*MyClassMemFn)(WStype_t type, uint8_t *payload, size_t length);

    void MyClass::connect(String host, int port) {
      webSocket.begin(host, port, "/");
      webSocket.setReconnectInterval(5000);

      MyClassMemFn onEventCallback = &MyClass::incomingEventHandler;
      webSocket.onEvent(MyClassMemFn onEventCallback);
    }

The above returns this error:

> sketch/MyClass.cpp: In member function 'void MyClass::connect(String,
> int)': MyClass.cpp:15:34: error: expected primary-expression before
> 'onEventCallback'    webSocket.onEvent(MyClassMemFn onEventCallback);

---

I have also tried to use `std::bind`:

    void MyClass::connect(String host, int port) {
      webSocket.begin(host, port, "/");
      webSocket.setReconnectInterval(5000);

      webSocket.onEvent(std::bind(&MyClass::incomingEventHandler, this));
    }

Error:

> sketch/MyClass.cpp: In member function 'void MyClass::connect(String,
> int)': MyClass.cpp:12:47: error: no matching function for call to
> 'WebSocketsClient::onEvent(<unresolved overloaded function type>)'
> webSocket.onEvent(this->incomingEventHandler);

---

If I move the `incomingEventHandler` function outside the class definition, it works as expected, however then I can't call other class members or access class properties in the same scope.

In arduino c++ how can I pass non-static class member properties as a callback? Is there a better way to approach this?

title: How to pass non-static class member to callback?

Answers: 1

body:
Yes, a callback can be a member function. The error in your `std::bind` call is that while you do bind the first hidden `this` paramater to an object instance, in this case `this` object, you must also use placeholders for all your other function parameters.

Since you declared

    void incomingEventHandler(WStype_t type, uint8_t *payload, size_t length)

You must bind as

    webSocket.onEvent(std::bind(&MyClass::incomingEventHandler, this,  std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

Note that this `webSocket.onEvent` call only works if you are on a non-AVR platform, because the library defines

    void WebSocketsClient::onEvent(WebSocketClientEvent cbEvent) {
        _cbEvent = cbEvent;
    }

with

    #ifdef __AVR__
            typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length);
    #else
            typedef std::function<void (WStype_t type, uint8_t * payload, size_t length)> WebSocketClientEvent;
    #endif

i.e., it is a raw function pointer in `__AVR__` but a `std::function` on non-AVR platforms -- `std::bind` will give you a `std::function`. Since you're on an ESP8266, this should work fine.

Refer to https://en.cppreference.com/w/cpp/utility/functional/bind (and maybe [my old question](https://stackoverflow.com/questions/50413872/c17-cannot-use-stdbind-to-produce-a-stdfunction))


body:
I am trying to implement code for the YX5300 MP3 player into my Arduino Uno project. I have broken down the original code example to all I need - basically just one trigger to cycle play one folder. This **does** work in that it starts playing when I push the button connected to pin 7 (it also displays the send command on the serial monitor):

  #include <SoftwareSerial.h>

 #define ARDUINO_RX 5  //should connect to TX of the Serial MP3 Player module
 #define ARDUINO_TX 6  //connect to RX of the module

 SoftwareSerial mp3(ARDUINO_RX, ARDUINO_TX);

 static int8_t Send_buf[8] = {0}; // Buffer for Send commands.  // BETTER LOCALLY

 String sbyte2hex(uint8_t b);

 const byte playPin = 7;
 byte playButton = 0;

 /************ Command byte *************************/

 #define CMD_SLEEP_MODE    0X0A
 #define CMD_WAKE_UP       0X0B
 #define CMD_SEL_DEV       0X09
 #define CMD_PLAY          0X0D
 #define CMD_STOP_PLAY     0X16  // Stop playing continuously.
 #define CMD_FOLDER_CYCLE  0X17
 #define CMD_SET_DAC       0X1A
 #define DAC_ON            0X00
 #define DAC_OFF           0X01
 #define DEV_TF            0X02

 /*********************************************************************/

 void setup()
 {
   Serial.begin(9600);
   mp3.begin(9600);
   delay(500);

   sendCommand(CMD_SEL_DEV, 0, DEV_TF);
   delay(500);

   pinMode(playPin, INPUT);
 }

 void loop()
 {

   playButton = digitalRead(playPin);
   if (playButton == HIGH) {
  sendCommand(CMD_FOLDER_CYCLE, 1, 0);
   }
 }

 /********************************************************************************/
 /*Function: Send command to the MP3                                             */
 /*Parameter: byte command                                                       */
 /*Parameter: byte dat1 parameter for the command                                */
 /*Parameter: byte dat2 parameter for the command                                */

 void sendCommand(byte command){
   sendCommand(command, 0, 0);
 }

 void sendCommand(byte command, byte dat1, byte dat2){
   delay(20);
   Send_buf[0] = 0x7E;    //
   Send_buf[1] = 0xFF;    //
   Send_buf[2] = 0x06;    // Len
   Send_buf[3] = command; //
   Send_buf[4] = 0x01;    // 0x00 NO, 0x01 feedback
   Send_buf[5] = dat1;    // datah
   Send_buf[6] = dat2;    // datal
   Send_buf[7] = 0xEF;    //
   Serial.print("Sending: ");
   for (uint8_t i = 0; i < 8; i++)
   {
  mp3.write(Send_buf[i]) ;
  Serial.print(sbyte2hex(Send_buf[i]));
   }
   Serial.println();
 }

 /********************************************************************************/
 /*Function: sbyte2hex. Returns a byte data in HEX format.                       */
 /*Parameter:- uint8_t b. Byte to convert to HEX.                                */
 /*Return: String                                                                */

 String sbyte2hex(uint8_t b)
 {
   String shex;

   shex = "0X";

   if (b < 16) shex += "0";
   shex += String(b, HEX);
   shex += " ";
   return shex;
 }

 /********************************************************************************/
 /*Function: shex2int. Returns a int from an HEX string.                         */
 /*Parameter: s. char *s to convert to HEX.                                      */
 /*Parameter: n. char *s' length.                                                */
 /*Return: int                                                                   */

 int shex2int(char *s, int n){
   int r = 0;
   for (int i=0; i<n; i++){
   if(s[i]>='0' && s[i]<='9'){
    r *= 16;
    r +=s[i]-'0';
   }else if(s[i]>='A' && s[i]<='F'){
    r *= 16;
    r += (s[i] - 'A') + 10;
   }
   }
   return r;
 }

This, however, does not work. The wiring is exactly the same. It **does** display the play command being sent to the YX5300. But the module does **not** start playing. As far as I am aware, I am using the exact same code for the player. I do not understand why the player won't start playing even though it receives the appropriate command:

 /************ init mp3-player ***************/
 #include <SoftwareSerial.h>

 #define ARDUINO_RX 5  //should connect to TX of the Serial MP3 Player module
 #define ARDUINO_TX 6  //connect to RX of the module

 SoftwareSerial mp3(ARDUINO_RX, ARDUINO_TX);
 static int8_t Send_buf[8] = {0}; // Buffer for Send commands.  // BETTER LOCALLY
 String sbyte2hex(uint8_t b);

 #define CMD_SLEEP_MODE    0X0A
 #define CMD_WAKE_UP       0X0B
 #define CMD_SEL_DEV       0X09
 #define CMD_PLAY          0X0D
 #define CMD_STOP_PLAY     0X16  // Stop playing continuously.
 #define CMD_FOLDER_CYCLE  0X17
 #define CMD_SET_DAC       0X1A
 #define DAC_ON            0X00
 #define DAC_OFF           0X01
 #define DEV_TF            0X02

 /**************** init the real time clock ***************/
 #include <Rtc_Pcf8563.h>
 Rtc_Pcf8563 rtc;

 /**************** setup pins & buttons ***************/
 const byte led = 9; // Pin LED is connected to
 const byte sixAmPin = 4; // Pin for set-alarm-to-6am-button
 const byte sevenAmPin = 5; // Pin for set-alarm-to-7am-button
 const byte eightAmPin = 6; // Pin for set-alarm-to-8am-button
 const byte stopPin = 7; // Pin for stop button
 const byte timeResetPin; // Pin for reset-clock-to-9am-button (useful e.g. after battery failure)
 const byte playPin = 8; // Pin for play-music-button

 byte sixAmButton = 0; // State of 6am-set-button
 byte sevenAmButton = 0; // State of 7am-set-button
 byte eightAmButton = 0; // State of 8am-set-button
 byte stopButton = 0; // State of stopButton
 byte timeResetButton = 0; // State of time-set-button
 byte playButton = 0; // State of play-music-button

 byte brightness = 0; // LED brightness
 bool wakeupMode = false;
 unsigned long prevStepTime = millis();
 unsigned long time;

 /*************** Changeable variables here **************/
 byte setHour = 19;
 byte setMin = 29;
 byte fadeDuration = 1; // Duration of fade in minutes (default: 30)
 byte afterBurn = 1; // Keep light on after alarm for this many minutes (default: 30)
 /********************************************************/

 unsigned long keepLight = afterBurn * 60000UL; // Calculate time to keep LED on after fade (in ms)
 int fadeStepLength = fadeDuration * 6000 / 255; // Calculate step duration for increasing LED brightness (in ms) (default: fadeDuration * 60000 / 255)

 void wakeup();
 void readButtons();

 /********** debug class ************/
 unsigned long int prevDebugTime = 0;
 void debug() {
   unsigned long debugTime = millis();
   if ( debugTime > prevDebugTime + 500 ) {
  Serial.print("Brightness = ");
  Serial.println(brightness);
  Serial.print("Time = ");
  Serial.println(time);
  Serial.print("stopButton = ");
  Serial.println(stopButton);
  Serial.print("playButton = ");
  Serial.println(playButton);
  Serial.print("Time = ");
  Serial.println(rtc.formatTime());
  Serial.println();
  prevDebugTime = millis();
   }
 }
 /************************************/

 void setup() {
   Serial.begin(9600);
   mp3.begin(9600);
   delay(500);

   sendCommand(CMD_SEL_DEV, 0, DEV_TF);
   delay(500);

   // declare LED pin to be an output:
   pinMode(led, OUTPUT);

   // declare button pins as inputs:
   pinMode(stopPin, INPUT);
   pinMode(sixAmPin, INPUT);
   pinMode(sevenAmPin, INPUT);
   pinMode(eightAmPin, INPUT);
   pinMode(timeResetPin, INPUT);
   pinMode(playPin, INPUT);
 }

 void loop() {

   // If it is wake-up time and wakeupMode is on, trigger alarm and reset trigger; else turn on wakeupMode
   if ( rtc.getHour() == setHour && rtc.getMinute() == setMin ) {
  if (wakeupMode) {
    wakeup();
    wakeupMode = false;
  }
  else {
    wakeupMode = true;
  }
   }

   // Check for button input
   readButtons();

   // update LED in case stopButton was pressed
   analogWrite(led, brightness);

   // Todo: Setup power saving methods

   debug();
 }

 void wakeup() {
   // If wake-up-mode is true and brightness < 255, add +1 to brightness every 7 seconds (256 steps)
   while (wakeupMode == true) {
  //update clock
  time = millis();

  // If current time is wakeup-time, increase LED brightness slowly over the course of 30 minutes
  if (brightness < 255 ) {
    // Delay brightening in steps. Do only if interval has passed.
    if (time > prevStepTime + fadeStepLength) {
   brightness ++;
   prevStepTime = millis(); // Resets counter to restart interval
    }
  }
  // Turn off light and exit wakupMode x minutes after max brightness
  else if (brightness == 255 && time > prevStepTime + keepLight) {
    brightness = 0;
    wakeupMode = false; // Exit wakeupMode loop
  }

  // Check for input from buttons
  // readButtons(); //uncomment after testing

  //debug();

  // Set LED brightness accordingly
  analogWrite(led, brightness);
   }
 }

 void readButtons() {
   // Always run this:
   // Check if alarm gets set to 6, 7 or 8am
   sixAmButton = digitalRead(sixAmPin);
   if (sixAmButton == HIGH) {
  setHour = 6;
   }
   sevenAmButton = digitalRead(sevenAmPin);
   if (sevenAmButton == HIGH) {
  setHour = 7;
   }
   eightAmButton = digitalRead(eightAmPin);
   if (eightAmButton == HIGH) {
  setHour = 8;
   }

   // If stopButton is pressed, turn off LED and reset alarm
   stopButton = digitalRead(stopPin);
   if (stopButton == HIGH) {
  wakeupMode = true; //change to false after testing (default: false)
  // brightness = 0; // uncomment after testing
  wakeup(); // for testing purposes
  //sendCommand(CMD_STOP_PLAY); // uncomment after testing
   }

   // Todo: If timeResetButton is pressed, reset clock to 9am
   if (timeResetButton == HIGH) {
  rtc.setTime(9, 0, 0);
   }

   // Todo: If Play music button is pressed, start playing music
   playButton = digitalRead(playPin);
   if (playButton == HIGH) {
  sendCommand(CMD_FOLDER_CYCLE, 1, 0);
   }

 }

 /********************************************************************************/
 /*Function: Send command to the MP3                                             */
 /*Parameter: byte command                                                       */
 /*Parameter: byte dat1 parameter for the command                                */
 /*Parameter: byte dat2 parameter for the command                                */

 void sendCommand(byte command){
   sendCommand(command, 0, 0);
 }

 void sendCommand(byte command, byte dat1, byte dat2){
   delay(20);
   Send_buf[0] = 0x7E;    //
   Send_buf[1] = 0xFF;    //
   Send_buf[2] = 0x06;    // Len
   Send_buf[3] = command; //
   Send_buf[4] = 0x01;    // 0x00 NO, 0x01 feedback
   Send_buf[5] = dat1;    // datah
   Send_buf[6] = dat2;    // datal
   Send_buf[7] = 0xEF;    //
   Serial.print("Sending: ");
   for (uint8_t i = 0; i < 8; i++)
   {
  mp3.write(Send_buf[i]) ;
  Serial.print(sbyte2hex(Send_buf[i]));
   }
   Serial.println();
 }

 /********************************************************************************/
 /*Function: sbyte2hex. Returns a byte data in HEX format.                       */
 /*Parameter:- uint8_t b. Byte to convert to HEX.                                */
 /*Return: String                                                                */

 String sbyte2hex(uint8_t b)
 {
   String shex;

   shex = "0X";

   if (b < 16) shex += "0";
   shex += String(b, HEX);
   shex += " ";
   return shex;
 }

 /********************************************************************************/
 /*Function: shex2int. Returns a int from an HEX string.                         */
 /*Parameter: s. char *s to convert to HEX.                                      */
 /*Parameter: n. char *s' length.                                                */
 /*Return: int                                                                   */

 int shex2int(char *s, int n){
   int r = 0;
   for (int i=0; i<n; i++){
   if(s[i]>='0' && s[i]<='9'){
    r *= 16;
    r +=s[i]-'0';
   }else if(s[i]>='A' && s[i]<='F'){
    r *= 16;
    r += (s[i] - 'A') + 10;
   }
   }
   return r;
 }

Just for some background: This is my code for a light alarm which, instead of playing a sound, will turn on an LED gradually, simulating a sunrise. I features multiple buttons to set the alarm time, stop the alarm (and, later, the music) and to start playing music.

Any hints on overall code architecture are also welcome (this is my first Arduino project, I hadn't written a single line of code for ten years prior to this). But my main concern is finding out where the bug is. My second concern is how to learn how to find out where the bug is.

title: (YX5300 MP3 player) Why is this code not working?

Answers: 1

body: You use pins 5 and 6 for SoftwareSerial and as INPUT for sevenAmPin and eightAmPin. SoftwareSerial can't work if you set the TX pin as INPUT. I assume you didn't wire the buttons to this pins yet.


body:
If I use this function without `&` before `change_x` (in function parameter), `change_x` never changes to false and it keeps on printing forever. Why do I need `&`?

    void some_function(bool &change_x, int pin_x) {
     if (change_x == true) {
     delay(time_delay);
     if (digitalRead(pocket_pin_1) == HIGH) {
      Serial.print("State 1");
      }

     else {
      Serial.println("state 2");
     }
     change_x = false;
     }
    }

title: What is the purpose of '&' while passing bool as a function parameter

Answers: 2

body:
As always in C++ the argument is passed by value by default (just like in plain old C). By using '&' you can pass it by reference. Therefore you are not copying the value of the variable into the method but the original variable with the possibility to mutate it inside the function and it will reflect the changes outside the function.

Perhaps you can paste more of your code so we see how the variable is passed into the function. For instance calling `some_function(true, 3)` won't be useful.

But anyway this is not an Arduino specific question and belongs to stackoverflow.

body:
If you have a boolean b you normally assign it to true or false. If you pass in a function a boolean (or integer, char and most other simple types), a copy is made. So if you change it in the function, when the function returns, the copy is destroyed and the original value is kept.

However, you do not want a copy, so you need a reference (pointer) to that boolean. That is where the & is for. So bool &change is not a boolean, but a reference to a boolean. Whenever you change that reference, the original value of the boolean is changed, which is what you want.

Note, this is a C++ feature, it does not exist in C (there you use pointers instead: bool* change).


body: I am using atmega 128 for a smart vehicle tracker. I am trying to use watchdog timer for this controller.But problem is that I have found the maximum watchdog reset time is 2 seconds. I need watchdog reset time 8 seconds. Now what can I do ?

title: Watchdog Timer for atmega 128

Answers: 1

body:
There is no way you can make the Watchdog timer longer on Atmega 128. It is max 1.8 sec if you set all 3 bits of Timer Prescaler.

For Atmega 328 the max watchdog time is 8 sec and longer time can be achieved using  watchdog interrupt and count up (or down) until you want a reset and then force the reset by setting the shortest watchdog timer.

Atmega 128 doesn't support watchdog interrupt, so the trick with interrupt can't be used.


body:
What else should I add to this code to increase the volume..??

    #include "talkie.h"

    Talkie voice;
    const int8_t speech[] PROGMEM=
    {0x00,0x00,0x00,0x08,0xd8,0x39,0x54,0x00,0xa7,0xa6,0x32,0xe0,
    0x04,0x46,0x55,0x28,0xde,0x53,0xaa,0xa9,0x42,0xe9,0x69,0x95,
    0xbb,0x4f,0x4c,0xa5,0xe7,0x51,0x15,0x5e,0x31,0x94,0x91,0x49,
    0xee,0xa8,0xc5,0x50,0x45,0x2a,0xb9,0x13,0x02,0x43,0xad,0xb9,
    0xf7,0x9d,0x0b,0x76,0x35,0x17,0x31,0xb7,0x46,0xd8,0x35,0x96,
    0x69,0xdf,0xb8,0x60,0xd3,0x54,0xc0,0x31,0x97,0xa2,0x14,0xf0,
    0x27,0xa3,0x02,0xfe,0xbb,0x52,0xc0,0x3f,0x3b,0x0a,0x38,0x79,
    0x42,0x00,0xbb,0xb4,0x2b,0x60,0x06,0x43,0xd7,0x65,0x4e,0xde,
    0xe9,0xa5,0x52,0x1f,0x94,0x56,0x58,0x84,0x2c,0x7d,0x34,0x9e,
    0xe6,0x15,0xb0,0x0d,0xd1,0x87,0x8b,0x77,0xc8,0xd4,0x87,0x58,
    0x4e,0x5e,0x11,0x52,0x1f,0x7c,0x17,0x78,0x95,0x0c,0xbd,0x77,
    0xdd,0x60,0x55,0xc1,0x75,0xce,0x6c,0x13,0xd7,0x04,0xd7,0x05,
    0x91,0xc3,0xec,0x33,0x44,0x67,0x79,0x0c,0x53,0x34,0x02,0x04,
    0xec,0xe4,0xcc,0x80,0x9d,0x53,0x10,0x30,0x05,0x13,0x69,0x3a,
    0x26,0xce,0xb4,0xd4,0xaa,0xc9,0x48,0xa3,0xc2,0x1a,0xa4,0x2e,
    0xb0,0xa8,0x76,0xab,0xe0,0x3a,0xab,0xb2,0xda,0x24,0x02,0x1a,
    0x89,0x9e,0x74,0x33,0x07,0x80,0x80,0x95,0xcd,0x19,0x30,0x9d,
    0x85,0x00,0xba,0xf6,0x14,0x25,0x0f,0x9d,0x6a,0x5e,0xc1,0x95,
    0x22,0x75,0x48,0x46,0x88,0x54,0xba,0x10,0xa1,0xd9,0x25,0x53,
    0xe9,0x62,0xb8,0x77,0x95,0x0c,0xa5,0x4e,0x69,0x39,0x16,0x31,
    0x94,0xaa,0xba,0xe5,0x48,0x2c,0x57,0xda,0x26,0xda,0x23,0x0d,
    0x5d,0xe5,0x1b,0x7b,0x8f,0x34,0x72,0x75,0x28,0x14,0xd5,0xd2,
    0xd0,0x34,0xa9,0xa1,0xe5,0x48,0x43,0xd5,0xa6,0x8a,0x96,0x23,
    0x09,0x55,0x97,0x2a,0xa9,0xad,0xc4,0x52,0x5d,0x0e,0xaa,0xbc,
    0xd2,0x58,0xf4,0xd5,0xa9,0x41,0x46,0x1c,0xf2,0x0f,0xc3,0x2a,
    0xc2,0x8d,0xc9,0x3f,0x93,0x99,0x12,0x26,0x46,0xc0,0xca,0xa2,
    0x00,0x00,0x00,0x0f};
    const int ProxSensor=2;
    int inputVal=0;

    void setup() {
      pinMode(13,OUTPUT);
      pinMode(7,OUTPUT);
      pinMode(8,OUTPUT);
      pinMode(ProxSensor,INPUT);
      Serial.begin(9600);
      // put your setup code here, to run once:
    }

    void loop() {
      if(digitalRead(ProxSensor)==HIGH)
      {
        digitalWrite(13,HIGH);
      }
      else
      {
        digitalWrite(13,LOW);
      }
      inputVal=digitalRead(ProxSensor);
      Serial.println(inputVal);
      if(inputVal==0)
      {
        digitalWrite(7,HIGH);
        //digitalWrite(8,HIGH);
       // voice.say(speech);
        //delay(3500);
        //exit();
      }
      else
      {
        digitalWrite(7,LOW);
        //digitalWrite(8,LOW);
      }
      if(inputVal==0)
      {
        voice.say(speech);
        delay(2500);
        //exit();
      }

      // put your main code here, to run repeatedly:

    }

title: How to increase the volume in speaker using talkie library in arduino uno...?

Answers: 1

body:
Your sample values (that is, the `speech[]` array) range from `0x00` to `0xfe`, using 99.6% of the total range of possible values.

Thus, there is no software solution to increase the volume, as you are only 1 bit away from the maximum output level (`0xff` is the max, and one less is `0xfe`).

This requires a hardware solution. One easy way is to use a commercial audio amplifier or a powered speaker (a speaker with a built-in amplifier).


body:
Right now I have an object:

    class Dog
    {
      public:
        Dog(uint8_t I2c, Stream& feedback);
        void Speak();
      private:
        uint8_t _I2c;
        Stream& _output;
    };

    Dog::Dog(uint8_t I2c, Stream& feedback):_output(feedback),_I2c(I2c){}

    Dog::Speak(){
    _output.println("Hi There.");
    }

That is currently constructed in my sketch via:

`Dog Dug([I2cPort], Serial);`

How can I modify my class so that to be compatible with taking either a Serial object or an LCD display (using [Adafruit's RGB LCD library](https://github.com/adafruit/Adafruit-RGB-LCD-Shield-Library) )?

Eg:

    Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
    Dog Dug([I2cPort], Serial);
    Dog Sam([I2cPort], lcd);

Additional info:

The LCD in question is mostly used as a UI display in its own library this library refreshes the display every 1.5 sec. As information from `speak();` and the UI have similar priority, it is acceptable if one instantly overwrites the other.

I am open to solutions that involve modifying the construction of `Dog` the only requirement is that I need to be able to indicate `print("[something]");` in the Dog.cpp

I'm interested in asking this question on the Arduino SE as I believe there are differences in how you would approach this if the problem was on a traditional computer.

title: How to Create a reference to an External Print object

Answers: 1

body:
If your class is only writing to the stream you probably want to have your class take a Print object instead of a Stream object.

The Adafruit library inherits from Print.


body:
I'm doing a program that starts the measuring process, using an HX711 when the door lock magnetic sensor spits and, when ends the measuring process when the door lock magnetic sensor joins.

    if (analogRead(A0) > 50){
        scale.power_up();
        lcd.setCursor(0, 4);
        lcd.print("Peso: ");
        lcd.print(scale.get_units(), 3);
        Serial.print(scale.get_units(), 3);
        lcd.print(" kg");
        Serial.print("\t");

        myRTC.updateTime();
        Serial.print(myRTC.dayofmonth);
        Serial.print("/");
        Serial.print(myRTC.month);
        Serial.print("/");
        Serial.print(myRTC.year);
        Serial.print("  ");
        Serial.print(myRTC.hours);
        Serial.print(":");
        Serial.print(myRTC.minutes);
        Serial.println("");
        delay(3250);
        digitalWrite(pinR1, LOW);
        lcd.clear();
        lcd.setCursor(0, 1);
        delay(2000);

        if( analogRead(A0) < 50){
        lcd.print("   Peso Registado   ");
        delay(3500);
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print(" O planeta agradece ");
        lcd.setCursor(0, 2);
        lcd.print("    a sua ajuda!    ");
        delay(3000);
        lcd.clear();
        }

        lcd.print("------TI-Trash------");
        lcd.setCursor(0, 1);
        myRTC.updateTime();
        lcd.print("   ");
        lcd.print(myRTC.dayofmonth);
        lcd.print("/");
        lcd.print(myRTC.month);
        lcd.print("/");
        lcd.print(myRTC.year);
        lcd.print("  ");
        lcd.print(myRTC.hours);
        lcd.print(":");
        lcd.print(myRTC.minutes);
        lcd.setCursor(0, 4);
        lcd.print("LOADING...");
        delay(2500);
        lcd.setCursor(0, 4);
        lcd.print(">APROXIME SEU CARTAO");
        }
     }

The problem is that I don't know how can I control the end of the measuring process because the process ends after a few seconds.

How can I controll the end of the measuring process

title: end measure process of HX711 with Door Lock magnetic sensor

Answers: 1

body: You need a variable for the state of the door. If state of the door is `closed` and the sensor shows that the door is open that is the moment where the you update the state of the door to `open` and start to measure. When the door state is `open` and the sensor shows that it is closed that is the moment when you change the state of the door to `closed` and stop measure.


body:
I am using this code on a arduino nano and works fine.

    #include <LiquidCrystal.h>

    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);           // select the pins used on the LCD panel

    #include <OBD2UART.h>

    COBD obd;

    void setup()
    {

      // start communication with OBD-II UART adapter
      obd.begin();
      lcd.begin(16, 2);
      // initiate OBD-II connection until success
      while (!obd.init());
    }

    void loop()
    {
      int value;
      obd.readPID(PID_RPM, value);
      int value2;
      obd.readPID(PID_COOLANT_TEMP, value2);
      lcd.setCursor(0,0);
      lcd.print("RPM = ");
      lcd.print(value);
      lcd.print("     ");
      lcd.setCursor(0,1);
      lcd.print("ECT = ");
      lcd.print(value2);
      lcd.print("     ");
        }

But if OBD is not connected, then it's get stuck in the setup.
What I want to do is to go over setup even if obd is not connected, and try connect to OBD meanwhile...something like display "Connecting..." on first row and count something on second...

Thank you in advance

title: Arduino OBD connection

Answers: 1

body:
The `while()` loop in `setup()` is what gets hung up. Instead of calling `odb.init()` until it returns `true`, just call it once just to get it initiated, then call/check in `loop()` and react accordingly:

    void setup()
    {
      // start communication with OBD-II UART adapter
      obd.begin();
      lcd.begin(16, 2);
      // initiate OBD-II connection once
      obd.init()
    }

    void loop()
    {
      static int error_count;
      if (!obd.init()) {
        // Not connected
        lcd.setCursor(0,0);
        lcd.print("Connecting");
        lcd.setCursor(0,1);
        lcd.print("Count: ");
        lcd.print(error_count);
        error_count++;`
      } else {
        int value;
        int value2;

        obd.readPID(PID_RPM, value);
        obd.readPID(PID_COOLANT_TEMP, value2);
        lcd.setCursor(0,0);
        lcd.print("RPM = ");
        lcd.print(value);
        lcd.print("     ");
        lcd.setCursor(0,1);
        lcd.print("ECT = ");
        lcd.print(value2);
        lcd.print("     ");
      }
    }


body:
I got the following code from Github, and have been playing with it for the last couple months.  The loop ALWAYS begins with the same LED as long as you do a complete reset to the board or power it up.  If I press the start button (I added) after running the loop previously, a different LED typically will fire.  I want to have the same led to start every loop, ALL the time (reset, power up, AND start button).

My current breadboard setup is an Arduino Mega, using a 4x4 matrix for the buttons and the LEDS to some digital outs.  I currently am using 6 LEDS but plan to expand to several more when I get everything working where I want it.

A quick rundown of how this functions...  At power up the LCD read out says Kyndras reaction timer.  If the start button is pressed a countdown begins and the first led lights up (LED 2), when the corresponding button is pressed another led lights until that corresponding button is pressed, etc.  The game runs for 30 seconds, at the end of the game your score is shown.  At that point you can simply press start to do it again.  My current issue is, I want LED "2" to be the first one to fire when the next game starts.  I know there is something retaining memory, because when you watch the last light power on a second before the timer ends, it lights the same light for a fraction of a second on the next game.

I suspect (old_butn = 0;) is my issue.  I have tried moving it all over the sketch and tried changing the digit after it, but I haven't had much luck.

I'm hoping someone can point me in the right direction.

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <Keypad.h>
    #include <Utility.h>
    #include "tones.h" // file music, lies in the folder firmware

    #define GAMETIME 30000
    #define LAMP 6
    #define RES_KEY 15
    #define BUZZER_PIN 19
    #define BLINK 40

    LiquidCrystal_I2C lcd(0x3F, 20, 4);

    const byte ROWS = 4;
    const byte COLS = 4;
    char hexaKeys[ROWS][COLS] = {
      {'<', '8', '4', '0'},
      {'=', '9', '5', '1'},
      {'>', ':', '6', '2'},
      {'?', ';', '7', '3'}
    };

    byte colPins[ROWS] = {39, 37, 35, 33};
    byte rowPins[COLS] = {41, 43, 45, 47};
    boolean lamp_on[6];
    boolean steps = true, go_game = true;
    int lamp_pin[15] = {2, 3, 4, 5, 6, 7};
    unsigned long startTime [12] = { 0, 0, 0, 0 };
    unsigned long duration [12] ;
    const int buttonPin = 14;
    const int startPin = 8;
    long last_pressed = 0;
    long nowMillis = 0;
    long toSec = 0;
    long gameStart = 0;
    long toBlink = 0;
    int score = 0;
    int dlay = 1000;
    int butn = 0;
    int old_butn = 100;
    char customKey;

    int melody[] = { NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 };
    int noteDurations[] = { 4, 8, 8, 4, 4, 4, 4, 4 };

    Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
    //=====================================
    void(* resetFunc) (void) = 0;
    //=====================================
    void setup()
    {
      randomSeed(analogRead(0));
      pinMode(BUZZER_PIN, OUTPUT);
      pinMode(LED_BUILTIN, OUTPUT);
      pinMode(startPin, OUTPUT);
      tone(BUZZER_PIN, 5000, 500);
      foreach (lamp_pin, LAMP, pinMode, OUTPUT);
      foreach (lamp_pin, LAMP, digitalWrite, HIGH);
      foreach (lamp_pin, LAMP, digitalWrite, LOW);
      delay(500);
      lcd.init();
      lcd.backlight();
      lcd.setCursor(4, 0);
      lcd.print("ver 3.5");
      lcd.setCursor(0, 2);
      lcd.print("KYNDRAS REACTION");
      lcd.setCursor(6, 3);
      lcd.print("GAME");
    }
    //=====================================
    void loop()
    {
      //******* allows a reset at anytime within the loop
      customKey = customKeypad.getKey();
      if (customKey - 48 == RES_KEY) {
        go_game = true;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("RESTART!");
        delay(500);
        resetFunc();
      }
      //******* shit gets real
      if (digitalRead(startPin) == HIGH)
      {
        foreach (lamp_pin, LAMP, digitalWrite, LOW);//makes all leds go LOW after randomBlink

        countDown();
        //-------
        gameStart = millis();
        nowMillis = gameStart;
        score = 0;
        steps = true;
        go_game = true; //this line allows you to start w/o reset
        while ((nowMillis - gameStart < GAMETIME) and (go_game)) {
          nowMillis = millis();
          //**********
          if (nowMillis - toSec > 1000) {
            lcd_print();
            toSec = nowMillis;
          }
          //**********
          if (nowMillis - toBlink > BLINK) {
            if (lamp_on[old_butn]) {
              sw_led_off(old_butn);
            }
            else {
              sw_led_on(old_butn);
            }
            toBlink = nowMillis;
          }
          //**********
          if (steps) {
            while (old_butn == butn) {
              butn = random(LAMP);
            }
            sw_led_off(old_butn);
            old_butn = butn;
            sw_led_on(butn);
            steps = false;
          }
          //**********
          customKey = customKeypad.getKey();
          if (customKey) Serial.println((int)customKey);
          if (customKey - 48 == butn) {
            sw_led_off(customKey - 48);
            score++;
            steps = true;
            lcd_print();
          } else if (customKey - 48 == RES_KEY) {
            gameStart = millis();
            foreach (lamp_pin, LAMP, digitalWrite, LOW);
            score = 0;
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("RESTART!");
            delay(500);
            resetFunc();
          }
        }
        if (go_game) game_over(); // the game is over
        go_game = false;
          }
      //******** random blink

      for (int i = 0; i < 6; i++)
      {
        randomBlink(i);
      }
    }

    //=====================================
    void lcd_print() {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("TIME:");
      int time = GAMETIME / 1000 - (nowMillis - gameStart) / 1000;
      lcd.print(time);
      if (time < 11) {
        tone(BUZZER_PIN, 3500 + time * 300, 150);
      }
      lcd.setCursor(11, 0);
      lcd.print("BTN:");
      lcd.print(customKey);
      lcd.setCursor(0, 2);
      lcd.print("SCORE:");
      lcd.print(score);
    }
    //=====================================
    void game_over() {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("   END");
      lcd.setCursor(0, 2);
      lcd.print("     SCORE: ");
      lcd.print(score);
      foreach (lamp_pin, LAMP, digitalWrite, HIGH);//all lamps light for 2sec at end of game
      delay (2000);
      for (int thisNote = 0; thisNote < 8; thisNote++) {
        int noteDuration = 1000 / noteDurations[thisNote];
        tone(BUZZER_PIN, melody[thisNote], noteDuration);
        int pauseBetweenNotes = noteDuration * 1.30;
        delay(pauseBetweenNotes);
        noTone(BUZZER_PIN);
      }
    }
    //=====================================
    void sw_led_on(int num) {
      digitalWrite(lamp_pin[num], 1);
      lamp_on[num] = 1;
    }
    //=====================================
    void sw_led_off(int num) {
      digitalWrite(lamp_pin[num], 0);
      lamp_on[num] = 0;
    }
    //=====================================
    void randomBlink(int pin)
    {
      if (millis() - startTime[pin] >= duration[pin])
      {
        digitalWrite(lamp_pin[pin], !digitalRead(lamp_pin[pin]));
        duration[pin] = random(150, 1500);  //smallest and longest ON/OFF times.
        startTime[pin] = millis();
      }
    }
    //=======================================
    void countDown() {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("   GET READY");
      delay(500);
      lcd.setCursor(0, 2);
      lcd.print("   START IN 3...");
      tone(BUZZER_PIN, 4000, 200);
      delay(500);
      lcd.setCursor(0, 2);
      lcd.print("   START IN 2...");
      tone(BUZZER_PIN, 4500, 200);
      delay(500);
      lcd.setCursor(0, 2);
      lcd.print("   START IN 1...");
      tone(BUZZER_PIN, 5000, 200);
      delay(500);
      lcd.clear();
      lcd.setCursor(0, 1);
      lcd.print("  GO!");
      delay(250);
      for (int i = 0; i < 5; i++) {
        int frequency = 4000 + i * 300;
        tone(BUZZER_PIN, frequency, 150);
        delay(130);
      }
    }

title: Help with clearing memory

Answers: 1

body:
The variables ``butn`` and ``old_butn`` are set to 0 and 100 before the game starts.  It's not clear to me what these value represents.  But re-assigning the variables back to 0 and 100 whenever the game restarts or resets should fix it.

Maybe at the end of the function ``game_over()``.  However it should probably also be done before the call to ``resetFunc()`` - whatever that does, its definition is not included.


body: I want to display a 3.7V battery's remaining life time on LCD screen using arduino. Like a laptop does. 1h 23m remaining or others. Do I need any kind of module to measure the thing? Can anyone tell the method please?

title: How can I calculate remaining battery life time with arduino

Answers: 1

body:
you may use ADC(analogRead) to measure Li-Ion Cell voltage. unlike Ni-Cd or Ni-Mh batteries, a Li-Ion Cell Voltage is a good measure for battery status. the discharge cycle of an usual Li-Ion cell Starts at 4.2v(full charged, better avoid that!) which quickly comes down to 3.7v. it remains about 3.7 volts most of the cycle and at the end, comes down again to about 2v which battery protector circuit cuts battery off circuit.

but if the Arduino itself is powered from li-ion battery, it can't measure the battery voltage as the ADC Reference is the current varying cell voltage itself. in this case you need to set VREF of Arduino to a lower internal constant reference(1.1v):

https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/

and implement a voltage divider

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/sDG8C.png)

<!-- End schematic -->

now you can measure cell voltage compared to a fixed reference. a full battery of 4.2 will be read in ADC as about 1000 (4.2* (1/1+3.3) * 1024). 3.7 should be read about 880 and 2.2v (if the Arduino is still ON!) will be read 500 in ADC unit.


body:
So for a while I get some Arduino IDE problem which I can't solve. When I try to upload any kind of code to my Arduino, Arduino IDE just stay at "Uploading". I tried to use another Arduino but I get the same problem. I used Pro Mini, Nano and Uno but it's the same. Then I decided to upload my code from another PC but I get the same problem and so I can't find where the problem is.

Is the problem in all my Arduinos or in my computers?

Note:
The code which I was uploading, was from Arduino examples.

I am using Windows 10 Pro x64 and in my console I get this error:

     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x57

title: My Arduino IDE stuck on uploading

Answers: 2

body:
To solve this problem, you should google the error message "avrdude: stk500_recv()".  The web shows countless records where this error comes up.  The message indicates that the serial communication has malfunctioned, but incorrect driver or serial port is not the only way this can happen.

During upload, (1) Have you tried to reset the arduino, (2) ensure that the RX/TX pins are not in use?

body:
You tried different PCs and different Arduinos, so the only constant is the Code and the USB cable I guess:

1. Try another USB cable
2. Try to upload another code

Do you have the same problem with any code you try to upload?


body:
This is my setup:

 - Arduino Mega;
 - HM-10 bluetooth module (bought off ebay, so not sure if genuine but works);
 - Adafruit Dotstar addressable LED strip;
 - iOS Blynk app;

Hardware-wise, everything is connected and working properly.

My ultimate goal is to implement this LED strip on my car in the headlights.

At this point though, I want to have everything working off the Blynk app with 3 on/off switch buttons, linked to 3 virtual pins and not consider any code priority for the lights.

I have 3 light "shows" for the strip, which are in their own void functions.

These are:

 - Daytime runing lights: DRL();
 - Signal turn indicator: STI();
 - Police display: POL();

This is my first serious project so consider me a first time coder.
Each switch button should be linked to each light show and turn the strip on and off.

What I want more specifically: when I press the DRL switch, DRL should stay on. Only turn off when switch is pressed again. This works fine.

The STI I want to loop. but when I push the switch, it goes through the function only once. This is what I don't understand, as the `Blynk.run()` is in the void loop function, and the state of the virtual pin hasn't changed.

It's the same for the police lights, it goes through the sequence only once, but i want it looped.

So my question is: How can I loop the STI and POL functions in my code?

I have tried with a while function but i can't get out of it by reading the the virtual pin within the function.

Here is the entire code:

I am aware that the code might be messy, any input is appreciated.
<!-- language-all: lang-cpp -->

    #define BLYNK_PRINT Serial
    #include <SPI.h>
    #include <BlynkSimpleSerialBLE.h>

    #include <Adafruit_DotStar.h>
    #define NUMPIXELS 72

    #include <SoftwareSerial.h>

    Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DOTSTAR_BRG);

    // You should get Auth Token in the Blynk App.
    // Go to the Project Settings (nut icon).
    char auth[] = "***";

    uint32_t amber = 0x020600;
    uint32_t white = 0x020202;
    uint32_t red = 0x000200;
    uint32_t blue = 0x000002;
    //SoftwareSerial SerialBLE(10, 11); // RX, TX

    BLYNK_WRITE(V1)
    {
      int pinValue1 = param.asInt(); // assigning incoming value from pin V1     to a variable

      if (pinValue1 == 1) {
        Serial.print("Daytime running lights: ON ");
        Serial.println(pinValue1); //showing the actual virtual pin status 0/1
        DRL();
      }
      else {
        Serial.print("Daytime running lights: OFF ");
        Serial.println(pinValue1); //showing the actual virtual pin status 0/1
        OFF();
        Serial.print("off ok"); // this just helps me check where the code has   progressed
      }
    }

    BLYNK_WRITE(V2)
    {
      int pinValue2 = param.asInt(); // assigning incoming value from pin V2 to    a variable

      if (pinValue2 == 1) {
        Serial.print("Dynamic turn indicator: ON ");
        Serial.println(pinValue2);  //showing the actual virtual pin status 0/1
        STI();
      }
      else {
        Serial.print("Dynamic turn indicator: OFF ");
        Serial.println(pinValue2);  //showing the actual virtual pin status 0/1
        OFF();
        Serial.print("off ok"); // this just helps me check where the code has  progressed
      }
    }

    BLYNK_WRITE(V3)
    {
      int pinValue3 = param.asInt(); // assigning incoming value from pin V3 to a variable

      if (pinValue3 == 1) {
        Serial.print("Police Lights: ON ");
        Serial.println(pinValue3);
        POL();
      }
      else {
        Serial.print("Police Lights: OFF ");
        Serial.println(pinValue3);
        OFF();
        Serial.print("off ok"); // this just helps me check where the code has progressed
      }
    }

    void setup()
    {
      Serial.begin(9600);
      Serial1.begin(9600);
      Blynk.begin(Serial1, auth);
      Serial.println("Waiting for connections...");

      strip.begin();  //initializes the strip
      strip.show();  //turn off LEDs within NUMPIXELS
    }

    void OFF() {
      for (int i; i <= 72; i++) { //turn off strip
        strip.setPixelColor(i, 0);
        strip.show();
      }
    }

    void DRL() {
      for (int i = 0; i <= 72; i++) {
        strip.setPixelColor(i, white);
        strip.show();
        delay(4);
      }
    }

    void STI() {
      //turn on dinamic indicator
      for (int i = 0; i <= 72; i++) {
        strip.setPixelColor(i, amber);
        strip.show();
        delay(2);
      }

      //turn off dinamic indicator
      for (int i; i <= 72; i++) {
        strip.setPixelColor(i, 0);
      }
      delay (200);  //on condition delay
      strip.show();
      delay (500);  //off condition delay
    }

    void POL() {

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, red);
        strip.show();
      }
      delay(30);

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(30);

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, red);
        strip.show();
      }
      delay(30);

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(30);

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, red);
        strip.show();
      }
      delay(30);

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(30);

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, red);
        strip.show();
      }
      delay(30);

      for (int i = 0; i <= 36; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(100);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, blue);
        strip.show();
      }
      delay(30);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(30);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, blue);
        strip.show();
      }
      delay(30);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(30);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, blue);
        strip.show();
      }
      delay(30);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(30);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, blue);
        strip.show();
      }
      delay(30);

      for (int i = 37; i <= 72; i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
      delay(100);
    }

    void loop()
    {
      Blynk.run();
    }

title: Blynk app, DotStar bluetooth control code help

Answers: 1

body:
The way the `BLYNK_WRITE` functions works is that they are called every time device gets an update of Virtual Pin value from the app. Now if you want to run something on a timer, or in a loop there is a function called `BlynkTimer`. You write your own function that you want to be looped and use this feature to define how often it should repeat. You can control execution by setting a boolean flag in the `BLYNK_WRITE` function and checking it in the loop, or by running the `enable()` and `disable()` methods of the timer. So, you can do something like this (without libraries, just an example):

    BlynkTimer timer; // create timer

    void myTimer()
    {
        // toggle an LED
        static bool state;
        digitalWrite(13, state);
        state = !state;
    }

    void setup()
    {
      Blynk.begin(details); // blynk start
      timer.setInterval(1000L, myTimer); // repeat the timer once a second
      pinMode(13, OUTPUT); // LED pin as output
    }

    void loop()
    {
      Blynk.run(); // Runs all Blynk stuff
      timer.run(); // runs BlynkTimer
    }

You can read more about it in the [docs][1].

  [1]: https://docs.blynk.io/en/blynk.edgent-firmware-api/blynk-timer


body:
Note: Before i explain my issue i would like to note that I am a beginner in electronics. Please pay attention to that when providing solutions and explanations. Thank you.

I have succeeded at making an auto ranging Ohmmeter it is still ofcours experimental there for I would like to get some opinions and perhaps solutions to some of the issues I’m facing
How it works:

It is based on a simple voltage divider. After experimenting it seems that a voltage drop across the unknown resistor in a certain range (this case [3.135V, 0.99V] with a voltage source equal to 3.3V) gives the most precise results compared to other values.

This Ohmmeter has a very useful feature and that is auto ranging, it changes the range automatically when the voltage drop values are not in the previously mentioned interval ([3.135V, 0.99V]).
The accompanied image shows how the device works.

If the value of Rx is too small compared to (R1+R2+R3) the Arduino switches the analog reading from A0 to A1 if the problem still accurse the Arduino will change again to A2 meaning it is now measuring not the value of Rx but (Rx+R1+R2) in series after that the Arduino is programmed to do the subtraction accordingly.

This device presents some noticeable inconvenients  that need to be eliminated:

 1. It depends on experimental values, so it is not certain if it’ll
    function properly in different conditions.

 2. For accurate (still not exact) measurements the value of Rx has to be greater than R1
 3. It provides acceptable measurements compared to the actual value with an error that is not too big (less than 1% relative error) the precision was obtained by the use of some of the arduino functions (such as voltage reference) also I have chosen the voltage source to be 3.3V instead of 5V to reduce noise, now if one wishes to use a different microcontroller other than arduino will it still be possible to obtain the same precision.

I would like to know your professional opinion regarding these inconvenients and if you may solutions for them, I have accompanied the code for better understanding.
Thank you
===================================================================

    #include <ResponsiveAnalogRead.h>
    ResponsiveAnalogRead analogPin0(A0, true);
    ResponsiveAnalogRead analogPin1(A1, true);
    ResponsiveAnalogRead analogPin2(A2, true);

    int raw1= 0,raw2=0,raw3=0;
    int Vin= 3.3;
    float Vout1= 0,Vout2=0,Vout3=0;

    float R1= 10000,R2=100000,R3=1000000;
    float Rx= 0;
    float buffer= 0;

    void setup()
    {
      analogReference(EXTERNAL);

    Serial.begin(9600);
    }

    void loop()
    {
      analogPin0.update();
      analogPin1.update();
      analogPin2.update();
    raw1=analogPin0.getValue();
    buffer= raw1 * Vin;
    Vout1= (buffer)/1024.0;
    if(Vout1<=3.135&&Vout1>=0.99) //firstif
    {

    buffer= (Vin/Vout1) -1;
    Rx= (R1+R2+R3) * buffer;
    Serial.print("Vout1: ");
    Serial.println(Vout1);
    Serial.print("Rx: ");
    Serial.println(Rx);
    delay(1000);
    }
       else //else1 of first if
       {

       raw2=analogPin1.getValue();
       buffer= raw2 * Vin;
       Vout2= (buffer)/1024.0;
          if(Vout2<=3.135&&Vout2>=0.99) //second if of first else
          {
          buffer= (Vin/Vout2) -1;
          Rx= (R2+R3) * buffer;
          Rx=Rx-R1;
          Serial.print("Vout2: ");
          Serial.println(Vout2);
          Serial.print("Rx: ");
          Serial.println(Rx);
          delay(1000);
          }
          else
          {
          raw3=analogPin2.getValue();
          buffer= raw3 * Vin;
          Vout3= (buffer)/1024.0;
              if(Vout3<=3.135&&Vout3>=0.99)
              {
              buffer= (Vin/Vout3) -1;
              Rx= R3 * buffer;
              Rx=Rx-(R1+R2);
              Serial.print("Vout3: ");
              Serial.println(Vout3);
              Serial.print("Rx: ");
              Serial.println(Rx);
              delay(1000);
              }
           }
       }
    }

======================================================
[![Circuit][1]][1]

to jot here are the results as i have previously explained the ohmmeter worked pretty well at the beginning but when i turned it off Then back on the value measured changed, the error got much bigger i tried changing the caliber aka R1 from 220 to 100 but the results were the same, the error was still big
thank you

[![first measurment ][2]][2]

[![after][3]][3]

  [1]: https://i.stack.imgur.com/4S4s8.png
  [2]: https://i.stack.imgur.com/8xJ4L.png
  [3]: https://i.stack.imgur.com/6CgRr.png

title: Autoranging ohmmeter

Answers: 2

body:
As you probably already know, the standard setup for measuring a
resistance with an Arduino is to put the unknown resistor in series with
a known one between 5V and GND, and measure the voltage at the point
in-between them:

         5V
         │
         R₁
     A0 ─┤
         R
         │
        GND

where R is the unknown resistor and R1 is the known
reference. The resistance is then computed as:

    const float R1 = ...;  // reference resistance

    int reading = analogRead(A0);
    float R = (float) reading / (1024 - reading) * R1;

First, it is worth noting that the reference voltage does not appear in
this calculation. You could, of course, do the calculation in terms of
voltage, but you should then notice that the reference voltage can be
simplified away. This is not surprising if you realize than the ADC of
the Arduino does not actually measure a voltage: it rather measures a
voltage _ratio_: the ratio of the input voltage to the reference
voltage. This ratio can then be easily related to the resistance ratio
R/R1. What all this implies is that you should not expect to
get better accuracy by using a 3.3 V reference rather than
5 V. Any inaccuracy in the voltage reference is irrelevant to the
measurement of the resistance.

Next, when measuring a physical quantity, you are almost always
interested in the _relative_ rather than the _absolute_ accuracy. From
the equation above, it can be easily shown that you get the best
relative resolution when the reading is near the middle of the ADC
range:

    raw reading    │   64 │  128 │  256 │  512 │  768 │  896 │  960
    ───────────────┼──────┼──────┼──────┼──────┼──────┼──────┼──────
    resolution (%) │ 1.67 │ 0.89 │ 0.52 │ 0.39 │ 0.52 │ 0.89 │ 1.67

This is consistent with your observations, and it means that the
reference resistor should ideally have a value that is of the same order
as the unknown resistor.

Now, for the autoranging, I would advise you against putting all your
reference resistors in series. With this setup, you always have the same
voltage across the unknown resistor, irrespective of what range you
choose. Reading a different input does not help. You may find out that
the voltage between R1 and R2 gives a better
reading (closer to mid-range), and you get a better accuracy on the
measurement of R+R1. However, when you subtract R1
you are immediately degrade the _relative_ accuracy of the result. In
the end you cannot really improve the accuracy this way.

What I suggest is to put the reference resistors in parallel instead of
in series, and power each one from an analog pin:

         A1  A2  A3
         │   │   │
         R₁  R₂  R₃
     A0 ─┼───┴───┴── ...
         R
         │
        GND

You then use these analog pins in digital mode: all of then in `INPUT`
mode, except one which is set to `OUTPUT` `HIGH`. You can try all of
them in turn and select whichever gives a result closer to mid-range. Or
you can implement a smarter algorithm that finds the optimal one without
trying them all.

There is something to be aware of with this setup: the pins have an
output resistance that is about 25 Ω, which ends up being in series
with the corresponding reference resistors. You can account for that by
adjusting, in your code, the values of those references. But then that
output resistance is not very well known, and can vary with temperature.
This should only be an issue when you are in the low ranges though. You
can mitigate this problem by measuring the voltage at the pin that is
currently pulling up, and replacing `1024` in the equation for R by that
reading. That's why I suggest to use analog instead of digital pins.

Finally, there are a couple of limitations that you should be aware of
when measuring resistances with the Arduino ADC. At the low end of the
resistance range, you cannot use a reference resistor with a very low
value, because you have to make sure you do not pull more than about
20 mA from the pin that pulls up. Your smallest reference may then
end up being somewhere around 220 Ω, and you will loose significant
accuracy when you try to measure anything below 50 Ω. At the upper
end of the range, you should be aware that the ADC is meant to measure
voltage sources with an output resistance no larger than 10 kΩ,
otherwise you risk cross-talk between the ADC channels. Then your higher
reference should probably be 10 kΩ, and any measurement above
50 kΩ will give poor accuracy. Going past these limitations would
require extra electronics, like a good-quality op-amp to “condition” the
signal into something that the ADC can reliably measure.

body:
The answer by @EdgarBonet seems to be a very nice solution for the lowered output voltage of a pin, when a low resistor value is used.

A arduino uno pin can output 20mA without problem, even up to 40mA if needed. So a safe value to measure low resistor values is 220 ohm, which could result in a maximum of 23mA.

Analog input A1 is used both as digital output to power the circuit and also as a analog input to measure how much the voltage has dropped.

This is a quick test:

    // Using the idea in the answer by Edgar Bonet
    //
    // Allow that the voltage of a digital output is
    // lowered by the low resistor value,
    // to calculate the unknown resistor.
    //
    // With two resistors in series.
    // A1 - 220 ohm - A0 - 10 ohm - GND
    //
    // The circuit is a voltage divider.
    // A1 powers the voltage divider.
    // A0 measures the output.

    #define R1 220
    #define N_SAMPLES 10

    void setup() {
      Serial.begin(9600);
      pinMode(A1,OUTPUT);
      digitalWrite(A1, HIGH);
    }

    void loop() {

      // Pin A1 is already set as a digital output and set HIGH.
      // Using analogRead(A1) is to measure the real output
      // voltage. There is a voltage drop, because of the current.
      float Vin = averageRead(A1);
      Serial.print("Vin=");
      Serial.print(Vin);

      float Vout = averageRead(A0);
      Serial.print(" Vout=");
      Serial.print(Vout);

      if(Vin > 0.0 && Vout < Vin) {
        float Vt = Vout / Vin;
        float Rx = (Vt * R1) / (1 - Vt);
        Serial.print(" Rx=");
        Serial.println(Rx);
      }

      delay(500);
    }

    float averageRead(int analogPin) {
      int total = 0;
      for(int i=0; i<N_SAMPLES; i++) {
        total += analogRead(analogPin);
      }
      return float(total) / N_SAMPLES;
    }

That is very nice. It is no problem when the unknown resistor is 10 ohm.

Because of the low resistor values, I did not add delays. With high resistor values, some delay is needed before measuring the analog values.

The next step is to find the best value by finding the value that is the most in the middle, as Edgar Bonet has explained in his answer.

    // Autoranging by finding the value that is most in the middle.
    // Using the answer by Edgar Bonet

    #define N_SAMPLES 10          // the number of samples to average, maximum 30

    // Four resistors to power the circuit (one at a time).
    // A1 has a resistor of 220 ohm, A2 has 3k3, A3 47k, and A4 750k
    // The other leg of the resistors are all connected to A0.
    // The unknown resistor Rx is at pin A0 and GND.
    const float R[4] = {220.0, 3300.0, 47000.0, 750000.0};
    const int pinR[4] = {A1, A2, A3, A4};
    const unsigned long wait[4] = {1, 2, 4, 10};  // delay, values guessed.
    const int pinMeasure = A0;

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

    void loop() {
      float Vin[4];    // Vin is the pin that powers the circuit
      float Vout[4];   // Vout is the voltage over the unknown resistor

      for(int i=0; i<4; i++) {
        // Power the circuit with this resistor
        pinMode(pinR[i], OUTPUT);
        digitalWrite(pinR[i], HIGH);

        // Vin is the pin that powers the circuit.
        // This is always low impedance, no need to wait.
        Vin[i]  = averageRead(pinR[i]);

        // Extra delay to wait for the voltage to become steady,
        // before reading the analog data.
        // Might be needed for the higest resistor values
        // Perhaps there is a cable to the unknown resistor
        // that has capacitance.
        delay(wait[i]);

        // The first 'analogread()' sets the multiplexer.
        // For a high impedance circuit, the first
        // 'analogread()' might be less acurate.
        // Read it a few times, and throw it away.
        averageRead(pinMeasure);

        // Everything is settled by now.
        // Read the analog input for real.
        Vout[i] = averageRead(pinMeasure);

        pinMode(pinR[i], INPUT);  // Make this pin high impedance
      }

      // Find the value for Vout that is the most in the middle.
      // For an Arduino Uno, the middle ADC value is 512.
      float diff = 2000.0; // set to value higher than possible as default
      int best = 0;        // index of the best resistor

      for(int i=0; i<4; i++) {
        float d = fabs(512.0 - Vout[i]); // difference for this resistor
        if(d < diff) {                   // closer to the middle?
          diff = d;                      // remember new difference
          best = i;                      // remember index best resistor
        }
      }

      if(Vin[best] <= 0.0) {
        Serial.println("Something wrong with the circuit");
      }
      else if(Vout[best] >= Vin[best]) {
        Serial.println("Rx not connected");
      }
      else {
        float Vt = Vout[best] / Vin[best];     // temporary precalculation
        float Rx = (Vt * R[best]) / (1 - Vt);  // calculate unknown resistor

        Serial.print(" Rx=");
        Serial.print(Rx);
        Serial.print(" ohm (with resistor ");
        Serial.print(R[best]);
        Serial.print(")");
        Serial.println();
      }

      delay(250);
    }

    float averageRead(int analogPin) {
      int total = 0;
      for(int i=0; i<N_SAMPLES; i++) {
        total += analogRead(analogPin);
      }
      total += N_SAMPLES / 2;  // see www.gammon.com.au/adc
      return(float(total) / float(N_SAMPLES));
    }

I would like to add a capacitor from A0 to GND (parallel with the unknown resistor) to reduce noise. This capacitor should be 1nF or less. The delay in the code is large enough to wait for the voltage to settle with 1nF.

The increase of the resistors by 15 times is a large step. That makes it less accurate, but the arduino uno has only 6 analog inputs. By using 5 resistors with an increase of 6 times is better.
4 resistors 15x : 220, 3k3, 47k, 750k
5 resistors 6x  : 220, 1k2, 8k2, 47k, 270k

There are a few ways to do more:

 - When two resistors result in a output that is close to the middle, it is possible to average the results.
 - When the 5 resistors are used, it is for example possible to lower the value of the 8k2 resistor. When all higher values are turned on, the resulting resistor value becomes 6k8 instead of 8k2.
 - For high resistor values, the output voltage of a pin is not lowered, and digital outputs can be used as well.

An protection resistor for A0 might be needed. I think that a value of 470 ohm or 1k should be fine.

**Many thanks to @EdgarBonet**, I used his answer and added the average and the delay.

----------
Update November 2018

@RekaiaDraoui

When using a breadboard, there can be contacts which are not perfect. That can cause a lot of troubles.

Are you using a circuit as this:

[![Autoranging with reading the powering voltages][1]][1]

  [1]: https://i.stack.imgur.com/EfSb8.png


body:
I followed the instructions of this post: [Storing an array of function pointers][1].
To show my problem I shorted my code extremely but the problem is still there.

My classes are defined as followes:
<!-- language-all: lang-cpp -->

 class MyBaseClass
 {
 public:
   MyBaseClass(String functionName);
   String functionName();
 private:
   String _functionName;
 };

 class MyDerivedClassA : public MyBaseClass
 {
 public:
   MyDerivedClassA(String functionName);
 };

 class MyDerivedClassB : public MyBaseClass
 {
 public:
   MyDerivedClassB(String functionName);
 };

 MyBaseClass::MyBaseClass(String functionName) {
   _functionName = functionName;
 }

 String MyBaseClass::functionName(){
   return _functionName;
 }

 MyDerivedClassA::MyDerivedClassA(String functionName) : MyBaseClass(functionName) {}

 MyDerivedClassB::MyDerivedClassB(String functionName) : MyBaseClass(functionName) {}

The test method is this:

 void test(){
   MyBaseClass *_elements[1000];
   int _elementCount = 0;

   for (int i = 0; i < 2; i++){
  if (i == 0){
    MyDerivedClassA tmp("MyDerivedClassA");

    _elements[_elementCount] = (MyBaseClass *)&tmp;
    Serial.println( _elements[_elementCount]->functionName() );

  } else if (i == 1){
    MyDerivedClassB tmp("MyDerivedClassB");

    _elements[_elementCount] = (MyBaseClass *)&tmp;
    Serial.println( _elements[_elementCount]->functionName() );

  }

  Serial.println( _elements[_elementCount]->functionName() );

  _elementCount++;
   }

   Serial.println("count: " + String(_elementCount));
   for (int i = 0; i < _elementCount; i++) {
  Serial.println("loop: " + String(i));
  Serial.println( _elements[i]->functionName() );
   }
 }

When the code is running I get the following at the serial monitor:

 MyDerivedClassA

 MyDerivedClassB

 count: 2
 loop: 0

 loop: 1

I dont understand, why the first call of "_elements[_elementCount]->functionName()" inside the first loop returns the correct value and the second only an empty string. Inside the second loop it again returns an empty string. I think it's the same problem like inside the first loop.

And there is the problem, that my NodeMCU crashes if the code is executed.

This is the output while it carshes:

 Soft WDT reset

 ctx: cont
 sp: 3ffffd20 end: 3fffffd0 offset: 01b0

 >>>stack>>>
    ...
 <<<stack<<<

  ets Jan  8 2013,rst cause:2, boot mode:(1,7)

  ets Jan  8 2013,rst cause:4, boot mode:(1,7)

 wdt reset

Where is my problem?

  [1]: https://arduino.stackexchange.com/questions/26184/storing-an-array-of-function-pointers

title: Storing an array of objects

Answers: 0


body:
I am fearly new to Arduino and FastLED. I found a nice Sketch which fits almost perfectly to my needs.

Just one Problem:

I dont want the Sketch to effect ALL LEDs in one color.
I want some LEDs in Red (ex. LEDs 0-4) Some in green and others in blue.

They could all have the same effect and timing, but it would be really neat if I could make them out of sync a little bit.

But having the possibility to make different LEDs different colored would be great. Here is the "Pulse" or "Breath" Sketch I want to use.

<!-- language-all: lang-cpp -->

        #include <FastLED.h>

        #define NUM_LEDS 37
        #define DATA_PIN 11
        #define CLK_PIN 13

        CRGB leds[NUM_LEDS];

        int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.
        int brightness = 0;

        void setup()
        {
          FastLED.addLeds<APA102, DATA_PIN, CLK_PIN, BGR>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
          FastLED.setBrightness(50);
        }

        void loop()
        {
           for(int i = 0; i < NUM_LEDS; i++ )
           {
           leds[i].setRGB(0,255,250);  // Set Color HERE!!!
           leds[i].fadeLightBy(brightness);
          }
          FastLED.show();
          brightness = brightness + fadeAmount;
          // reverse the direction of the fading at the ends of the fade:
          if(brightness == 0 || brightness == 255)
          {
            fadeAmount = -fadeAmount ;
          }
          delay(80);  // This delay sets speed of the fade. I usually do from 5-75 but you can always go higher.
        }

title: FastLED - How to Control specific LEDs

Answers: 1

body:
The colors of the LEDs in your sketch are set in this loop:

    for(int i = 0; i < NUM_LEDS; i++ )
    {
        leds[i].setRGB(0,255,250);  // Set Color HERE!!!
        leds[i].fadeLightBy(brightness);
    }

You loop over all LEDs and set them to a specific color and brightness. The changes will be send to the LEDs, when you call `FastLED.show()` afterwards. There is nobody, that prevents you from setting a different color for each LED or to only chnage the value for some of the LEDs.

For example, to light the first 5 LEDs in red, the next 10 in green and leaving the rest as they were before, you can use this code (Just exchange it with your `for` loop):

    for(int i=0;i<5;i++){
        leds[i].setRGB(255,0,0);
        leds[i].fadeLightBy(brightness);
    }
    for(int i=5;i<15;i++){
        leds[i].setRGB(0,255,0);
        leds[i].fadeLightBy(brightness);
    }
    FastLED.show();

The principle is, that you have an array with color values. Each value consists of 3 smaller values for red, green and blue (RGB)(The color results from the distribution between red, green and blue; the brightness results from the overall level of red, green and blue). And each value of the array is bound to an LED (First value to first LED, second value to second LED,...). You can change the color values in the array as you like. And when you want the LEDs to show the current values in the array, you send them out by using `FastLED.show()`. This means you have to call this function everytime, that you want LEDs to change. You don't have to change every value in the array for this to work.

If you would like to build an asynchronous change of colors, you can ditch the `delay(80)` and use non-blocking code like in the `BlinkWithoutDelay` example of the Arduino IDE. There you use the `millis()` function as a clock (it returns the milliseconds since the Arduinos startup). You take a timestamp at the beginning and compare the difference between it and the current time:

    unsigned long timestamp=0;
    unsigned long interval=80; //interval of 80 milliseconds

    void loop(){
        unsigned long current_time=millis();
        if(current_time - timestamp > interval){
            // do something here, like setting LED colors
            timestamp = current_time;
            // don't forget FastLED.show(), to output the colors
        }
    }

You can use multiple of these timestamps with if-statements, one for each segment you want to change in a different frequency.


body:
I would like to turn on and off the output of two pins on my arduino independently from each other. However, so far all my attempts have failed.

My current idea is to save the status (which I chose to be 0 as 'low' and 'high' as 1) of each of the pins in an integer array and then change the status of the pin depending of the entry in the variable. However, the entries in the variable are always set back to 0 and I do not know why this is happening.

This is my arduino code

    const byte numChars = 32;
    byte receivedChars[numChars];
    boolean newData = false;
    const int num_of_pins=2;
    int output_pins[num_of_pins]={22,26};
    int status_pins[num_of_pins]={0,0};

    void setup() {
        int ii=0;
        Serial.begin(9600);
        for(ii=0; ii<num_of_pins; ii++){
            pinMode(output_pins[ii],OUTPUT);
        }

    }

    void loop() {
        recvWithStartEndMarkers();
        chooseFunction();
    }

    void chooseFunction(){
      if (receivedChars[0]==0){
        shutter();
        }
    }

    void shutter(){
            // get number of pin
            int pin_number_rcvd;
            int ii;
            int pin_status_rcvd;
            pin_number_rcvd=receivedChars[1];
            pin_status_rcvd=receivedChars[2];
            //check all status of pins and turn on and off
            for (ii=0; ii<num_of_pins; ii++){
              if (pin_number_rcvd==output_pins[ii]){
                status_pins[ii]=pin_status_rcvd;
              }
              if (status_pins[ii]==0){
                digitalWrite(output_pins[ii],LOW);
              }
              if (status_pins[ii]==1){
                digitalWrite(output_pins[ii],HIGH);
              }
            }
    }

    void recvWithStartEndMarkers() {
        static boolean recvInProgress = false;
        static byte ndx = 0;
        byte startMarker = 8;
        byte endMarker = 9;
        byte rc;

        while (Serial.available() > 0 && newData == false) {
            rc = Serial.read();

            if (recvInProgress == true) {
                if (rc != endMarker) {
                    receivedChars[ndx] = rc;
                    ndx++;
                    if (ndx >= numChars) {
                        ndx = numChars - 1;
                    }
                }
                else {
                    receivedChars[ndx] = '\0'; // terminate the string
                    recvInProgress = false;
                    ndx = 0;
                    newData = true;
                }
            }

            else if (rc == startMarker) {
                recvInProgress = true;
            }
        }
    }

I use pyserial to send the input data to the arduino. my python code:

    import serial
    import time, struct, sys
    ser=serial.Serial('COM17', 9600, timeout=10)
    time.sleep(2)
    ser.reset_input_buffer()
    ser.reset_output_buffer()
    pin_number= int(sys.argv[1])
    high_or_low=int(sys.argv[2])

    ser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9))

I am using an ArduinoDue together with the arduino IDE.

title: Output set to 'low' when new variable in buffer

Answers: 1

body:
Your problem is in one tricky option for arduino's com connection. When you reopen COM port where arduino is connected your arduino resets automatically.

**Here's workaround from arduino.cc:**
>**DisablingAutoResetOnSerialConnection**

>The simple way that doesn't require
> any permanent modifying of your hardware or software configuration
> changes:
>
> Stick a 120 ohm resistor in the headers between 5v and reset (you can
> find these on the isp connector too). 120 is hard to find so just
> combine resistors. Don't go below 110 ohms or above 124 ohms, and
> don't do this with an isp programmer attached. You can just pull out
> the resistor when you want auto-reset back.

http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection

Or you can just modify you script to be able to start over without reopening it.
For example use a loop there and some exit command to end that loop:

    try:
        while True:
            do_something()
    except KeyboardInterrupt:
        pass

https://stackoverflow.com/questions/13180941/how-to-kill-a-while-loop-with-a-keystroke
Replace `do_something()` with this part of your code:

    ser.reset_input_buffer()
    ser.reset_output_buffer()
    pin_number= int(sys.argv[1])
    high_or_low=int(sys.argv[2])

    ser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9))

I hope I was clear enough.


body:
[![enter image description here][1]][1]Hello guys, this is my code and I am basically doing if-else statement.

    int led = D2;
    int but = D1;

    void setup() {
      pinMode(led, OUTPUT);
      pinMode(but, INPUT);

    }

    void loop() {
      if (digitalRead(but) == HIGH){
        digitalWrite(led, HIGH);
      }else{
        digitalWrite(led, LOW);
      }

    }

I have also attached the photo so that you can diagnose the situation.

The led show only glow if the button is pressed. But the led keeps glowing for longer time and I don't know why.
I think there is current leak somewhere in the circuit or the internal processing is slow.
Please help me guys.[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/KGobn.jpg
  [2]: https://i.stack.imgur.com/IrNac.jpg

title: NodeMCU ESP8266 button wiring problem

Answers: 1

body:
Your button and pull-up configuration is not correct, so when the button is not being pressed, the pin D1 is floating, being pulled neither HIGH nor LOW.

Instead, use a pull-up resistor as shown. When the button is not pressed, D1 is connected to GND through a resistor. When the button is pressed, the 3.3V source has a direct path to D1.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/lANP1.png)

<!-- End schematic -->