message:
Specific values not showing when using a numeric keypad

I have attached a 3x4 keypad to my Arduino Leonardo as an input method. Whenever I press the buttons, the majority of the keys work but specific ones don't. Here's my code, I've set it up to beep a piezo buzzer when it gets a keypress.

    #include <Keypad.h>

    int buzzerPin = 0;
    const byte ROWS = 4; //four rows
    const byte COLS = 3; //three columns
    char keys[ROWS][COLS] = {
        {'1','2','3'},
        {'4','5','6'},
        {'7','8','9'},
        {'*','0','#'}
    };
    byte rowPins[ROWS] = {12, 13, 8, 10}; //connect to the row pinouts of the keypad
    byte colPins[COLS] = {11, 7, 9}; //connect to the column pinouts of the keypad

    Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

    void setup(){
        Serial.begin(9600);
        pinMode(buzzerPin, OUTPUT); //Set buzzerPin as output
        keypad.addEventListener(keypadEvent); //Add an event listener for the KeyPad
    }

    void loop(){
        char key = keypad.getKey();
    }

    void keypadEvent(KeypadEvent eKey) {
            // When the KeyPad will be pressed, the results will appear on the serial monitor.
            switch (keypad.getState()) {
            case PRESSED:
                    Serial.print("Enter: ");
                    Serial.println(eKey);
                    beep(10);
                    delay(10);
                    break;
            }
    }

    void beep(unsigned char delayms) { //creating function
        tone(buzzerPin, 2000); //Setting pin to high
        delay(delayms); //Delaying
        noTone(buzzerPin); //Setting pin to LOW
        delay(delayms); //Delaying
    }

I based my rows/columns off of this pin-out: https://www.jaycar.com.au/12-key-numeric-keypad/p/SP0770,
but I later found out some of the columns had to be swapped :P

Here's a diagram of what's happening:
[![Diagram of working and not working keys][1]][1]

The keys in red do not work.

I wouldn't have posted this on stack exchange but it looks like an oddly specific pattern, and no matter what I changed, it didn't work.

(And yes, that is the exact keypad I bought from Jaycar)

Edit: I forgot to mention that I was using a prototype shield to plug the keypad into, but all pins are confirmed working on that.

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

body:
A row against a row does not work, or a column against a colum.
That means there is a logical explanation. Row #2 is swapped with column #2.
Button 5 does work, because that still has a row against a column (but then the other way around).


sender: user

message:
Connecting 2 arduino on same ground

I'm working project which consist of 2 arduino running a 2 different sketch, However, can i make these 2 ic to run on same power +ve and same ground?

sender: assistant

body: Yes, you can. Just be sure, that you connect both Arduinos in parallel to the power source (both power inputs together to the power output of the source and both grounds together to the ground of the source), so that the current for the second Arduino won't flow through the first Arduino. Also use a power source, that is capable oft providing enough current for your needs.


message:
Using serial.available to return number of bytes

My code:

    char data;
    int numOfBytes;
    void setup() {
        Serial.begin(9600);
    }
    void loop()
    {
        if (Serial.available() > 0)
        {
            int numOfBytes = Serial.available();
            Serial.print("numOfBytes: ");
            Serial.println(numOfBytes);

            data=Serial.read();
            Serial.print("data: ");
            Serial.print(data);
            Serial.print("\n-----------\n");

            delay(500);
        }
    }

I expected that this code returns 5 and then 4,3,2,1.
But it returned: 1,4,3,2,1

Why?

body:
This is because at the first execution only one byte was received. The Serial interface does not send the data in one big packet of 5 bytes, only because you typed five bytes and started the transmission of all with one press in enter. It is sending the bytes one by one, in other words serial (hence the name). The exact transmission time is dependend on many factors (especially, when other technologies are involved, like the USB interface, when you are transmitting over the Arduinos USB to serial converter).

In this case the first byte is sent, followed by a short break, then the other bytes. The Arduino is fast enough in checking the Serial interface to sense this at 9600 baud.


message:
What is the output format of PINxn on atmega328p

I have written this simple code to run on my Arduino:

    #ifndef F_CPU
    #define F_CPU 16000000UL // 16 MHz clock speed
    #endif

    #include <avr/io.h>
    #include <util/delay.h>

    int main(void)
    {
      Serial.begin(9600);
      DDRD = 0x00;
      PORTD = 0x80; //activate pull-up resistor on first pin on port D

      while (1)
      {
        Serial.print(PIND);
      }
      return 0;
    }

I simply set my D port as an input and read the value in a loop. The output of PIND is 253. What is this number representing? is it in decimals? where can I see a list of these? How can I see a binary repression of the PIN output (8 bits of them). I don not want to use bit shifting.

body: `Serial.print(PIND, BIN);` will write the value in `PIND` to the serial port in Base-2 representation.


body:
From the Atmega 323p datasheet: "Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn", which is probably not what you meant to do. To read the current state of register D, you need to read PORTD, or

    Serial.print(PORTD);

in your example.

Update:

> ... what is PIND used for ...

PINx is called the Port x Input Pins Address and a note under it says "Writing to the pin register provides toggle functionality for IO" and refers us to the general pin-driver circuit schematic (Section 41.2 in my copy of the datasheet). That section tells us that "Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn." That is the only reference to this register I could find.

Note that the PORTx registers are bi-directional; the same register is used for reading or setting the states of the port's bits.

> Also i'm not Writing a logic one to PINxn anywhere, i'm just reading
> it

The datasheet doesn't mention what is read from the port, at least nowhere that I found, despite that the PINx register is described as Read/Write, so your guess is as good as mine! ¯\\_(ツ)_/¯
But to read a port's data, you need to read its PORTx register.

Update 2:

> 6 & 7map to the crystal pins and are not usable

They are usable. You can use them for I/O or for an external crystal, but not both. The "why?" is properly the domain of Atmel's engineers but I'll take a stab at it and say that many more functions could be put on the chip than there is space for physical pins on the package. Since pin count is at a premium, functions have to be doubled up on the same pins; you get to choose what you need. SPI, PWM, or I/O on DIP B2&3; Reset and I/O on C6; Timer-counter 1 input, I/O, & PWM on D5, for a few examples. Nearly every pin has several possible uses (power and grounds being the notable exceptions). For my uses, I dedicate the Crystal, Reset, and UART pins to those functions, but I could imagine systems that might need to reassign any of them.


body:
The Serial port is at pin 0 and 1.
PORTD is for pin 0,1,2,3,4,5,6,7. That's the problem, you mess with the pins of the Serial port.

Note: When a crystal/resonator/clock is used, those pins are disconnected from PORTB. That means you may use PORTB and read and write 8 bits to it, the crystal will keep on running.


body:
    byte valueB = PINB; // reads the value of portB, D14-D19, into the variable valueB

If you then

    Serial.print (valueB,BIN);

you will see the value of D19 to D14 in binary, or 0s & 1s. I don't think leading zero's are shown, so that can be a little confusing.

    Serial.print (valueB);

will show the same value in decimal.
253 = 0b11111101   0b indicates base 2 (binary) format.  0x is used fof hexidecimal format (0x00 to 0xFF for 0 to 255).

If you are using the IDE and have not changed the fuses from the Uno/Nano board type, the IDE is expecting a crystal or resonator on PB7 & PB6, so reading them will return a nonsense result, so you might as well mask them off before printing.

    valueB = valueB & 0b00111111;

If the other pins do not have their internal pullup resistors turned on, or external pullup or pulldown resistors are not used, the pins are 'floating' and their low input current means that any external charge can easily change their reading - so valueB = PINB; will have erratic results.

If a port has been set to outputs, then all pins can be written to at once:

    PORTB = 0b0011111111;  // set D19 to D14 high for example


message:
Can I use a camera sensor from a not functioning smartphone in Arduino or Raspberry pi?

I want to use the OmniVision_OV16860 camera sensor from a not functioning Moto G4 plus phone to capture pictures using Arduino or Raspberry Pi.

Is it possible to do that? If yes, explain the whole process.

body:
> Is it possible to ... use the OmniVision_OV16860 camera sensor (on an)
> Arduino?

It is doubtful as bare image sensors usually require specialized software drivers to be of any use. Also, a common Arduino does not have the power to do image processing.  Only the few Arduino's built with unusually powerful processors could handle image processing.  But, at this level, expect little support as most do not do image processing on the Arduino platform.


message:
GPS Logger problem

I have some problems with my GPS Logger. U use Arduino Uno, NEO - 6M, SD card.
Problem is in function void loop. I enter inside, but stuck on the "while loop", don't even get inside this loop. Here is code I use:

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

    #define SD_CS 4
    #define FILE_BASE_NAME "Trac"

    TinyGPS gps;
    SoftwareSerial serial(10, 11);

    File myFile;

    const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
    char fileName[] = FILE_BASE_NAME "00.csv";

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

      Serial.println("SD card initialization...");
      if(!SD.begin(SD_CS))
      {
        Serial.println("Failed! Check card");
        //while(1);
      }
      Serial.println("Initialization done");

      while (SD.exists(fileName)){
        if (fileName[BASE_NAME_SIZE + 1] != '9')
        {
          fileName[BASE_NAME_SIZE + 1]++;
        }
        else if (fileName[BASE_NAME_SIZE] != '9')
        {
          fileName[BASE_NAME_SIZE + 1] = '0';
          fileName[BASE_NAME_SIZE]++;
        }
        else{
          Serial.println("Can't create file name");
          //return;
        }
      }

      myFile = SD.open(fileName, FILE_WRITE);
      if (!myFile) {
        Serial.println("open failed");
        //return;
      }
      Serial.print("opened: ");
      Serial.println(fileName);
    }

    void loop(){
      while (serial.available())
      {
        int c = serial.read();
        if (gps.encode(c))
        {
          long lat, lon;
          unsigned long fix_age;
          gps.get_position(&lat, &lon, &fix_age);
          Serial.print("Latitude:");Serial.println(lat);
          Serial.print("Longitude:");Serial.println(lon);
          myFile = SD.open(fileName, FILE_WRITE);
          myFile.print(lat);
          myFile.print(", ");
          myFile.print(lon);
          myFile.println("");
          myFile.close();
        }
      }
    }

If I use this code, it gives me the lat ad lon:

    #include <SoftwareSerial.h>
    #include <TinyGPS.h>

    TinyGPS gps;
    SoftwareSerial nss(10, 11);

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

    void loop()
    {
      while (nss.available())
      {
        int c = nss.read();
        if (gps.encode(c))
        {
          long lat, lon;
          unsigned long fix_age;
          gps.get_position(&lat, &lon, &fix_age);

          Serial.print("Szerokosc:");Serial.println(lat);
          Serial.print("Dlugosc:");Serial.println(lon);

        }
      }
    }

body: SD uses SPI. [On the Uno, SPI is on pins 10-13](https://www.arduino.cc/en/Reference/SPI). You are also using pins 10 and 11 for software serial. That won't work. You need to use pins other than 10 and 11 for software serial.


message:
Install Arduino IDE in Raspberry Pi 3 model B

I am trying to install Arduino IDE in my Raspberry Pi model 3 but it is unable to locate file path.

I use the following steps

    sudo apt-get update && sudo apt-get install arduino

and in result I found this

    pi@raspberrypi:~ $ sudo apt-get update && sudo apt-get install arduino
    Hit:1 http://archive.raspberrypi.org/debian stretch InRelease
    Ign:2 http://repository.pi4j.com wheezy InRelease
    Hit:3 http://repository.pi4j.com wheezy Release
    Reading package lists... Done
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    E: Unable to locate package arduino

I am searching for a solution but not able to understand what's the problem here.

Any ideas to make it work will be helpful.

body:
Visit https://www.arduino.cc/en/Main/Software in your browser, and click the Linux ARM link under ‘Download the IDE’.

    cd Downloads/
    tar -xf arduino-1.8.3-linuxarm.tar.xz

Extract the file to your /opt directory, then open a Terminal and run the install.sh script to install.

    sudo mv arduino-1.8.3 /opt
    sudo /opt/arduino-1.8.3/install.sh

You will find Arduino IDE under Menu > Programming. Open the app to start programming your Arduino board.

Hope this helps.


message:
How to connect an Elegoo Nano to a Raspberry Pi and program it?

I own an several Elegoo Nanos and a Raspberry Pi. I would like to connect an Elegoo Nano to the Pi and upload nanpy onto the board and control it's GPIO pins.

I have plugged the nano into the Pi and it is not recognised by the pi. I believe it is something to do with the drivers required for the nano to work. I feel this is similar to this post https://arduino.stackexchange.com/questions/34775/arduino-nano-not-visible-in-serial-ports-mac-os#answer-34781 as I have tried and failed at connecting it to my Mac.

Any help at getting the Elegoo Nano read by the Arduino IDE on my Raspberry Pi so I can program onto it would be greatly appreciated.

body:
The Elegoo website has a [downloads page][1] which contains the drivers.

1. Using the Raspberry Pi, [download the zip file containing the drivers][2].
2. [Unzip the contents][3] to a location of your choice. ([Also see here][4])
3. Change to the directory containing the Linux driver source files (ie `CH341SER_LINUX`).
4. In the terminal type `make`. Let it compile the driver.
5. In the terminal type `make load`.

Done

  [1]: https://www.elegoo.com/download/
  [2]: http://www.elegoo.com/tutorial/Elegoo CH340 Driver 2018.6.19.zip
  [3]: https://askubuntu.com/q/86849
  [4]: https://unix.stackexchange.com/q/6596


message:
Using Modbus TCP server on Arduino

I have a scd30 sensor wired to an Arduino Uno. The scd30 works on the I2C protocol. I am able to read data live on the serial monitor on the Arduino IDE. I have an ethernet shield on my Arduino. I would like the Arduino to communicate with a field agent which will upload the data to the internet.

I have tried numerous modbus TCP libraries and dont seem to be getting anywhere. I can connect my arduino to the field agent but whenever it sends data I get a 0x02 exception code - Illegal data address. This is the library I'm using https://github.com/andresarmento/modbus-arduino/tree/master/libraries/ModbusIP/examples

I believe the right way to go about it is through holding registers but im not sure how to do this when using I2C. The connection is fine, the problem is the format. Any help is appreciated thanks.

    /*
      Reading CO2, humidity and temperature from the SCD30
      This example prints the current CO2 level, relative humidity, and temperature in C.
    */
    #include <SPI.h>
    #include <Ethernet.h>
    #include <Modbus.h>
    #include <ModbusIP.h>
    #include <Wire.h>
    #include <Streaming.h>
    #include "SparkFun_SCD30_Arduino_Library.h"

    SCD30 airSensor;
    //Modbus Registers Offsets (0-9999)
    const int SENSOR_ISTS = 100;
    //ModbusIP object
    ModbusIP mb;
    long ts;

    void setup()
    {
      Wire.begin();
      Serial.begin(9600);
      Serial.println("SCD30 Example");

     // The media access control (ethernet hardware) address for the shield
        byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
        // The IP address for the shield
        byte ip[] = { 000 , 00,0, 00  };
        byte gateway[] = { 0, 0, 0, 0 };
        byte subnet[] = { 255, 255, 255, 0 };
        //Config Modbus IP
        mb.config(mac, ip,gateway,subnet);
        // Add SWITCH_ISTS register - Use addIsts() for digital inputs
        mb.addHreg(SENSOR_ISTS);
      airSensor.begin(); //This will cause readings to occur every two seconds

    }

    void loop()
    {

    mb.task();
       mb.Hreg(SENSOR_ISTS, digitalRead(airSensor.getTemperature()));

    }

body:
The ModbusIP library expects from you that you supply the value of the register. The AirSensor library gives you that value.

Set the register value to Hreg:

    mb.Hreg(SENSOR_ISTS, airSensor.getTemperature());

I tested your sketch without the sensor library and it is working. Client was my java test client I use to test access to Modbus TCP registers of my photovoltaic system.

Make sure that the client calls "0x03 - Read Holding Registers" and test address 100 and 101 because some modbus clients offsets are 1-based.


message:
Why is Serial.Write that slower when writing x+1 characters than when it is writing x characters?

Using `Serial.Write()` in a time sensitive application. I realize that the number of characters being written not only had an impact on the time spent writing in the buffer, but actually had a bigger impact than expected.

Consider the following sketch, which measures the time it takes to write NB_CHARS characters, using `Serial.Write()`. I sampled 1000 times in order to get a more reliable measure.

    #define NB_CHARS 100

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

      uint8_t chars[NB_CHARS];
      for (int i=0; i<NB_CHARS; i++)
      {
        chars[i] = 66;
      }

      unsigned long time1, time2;
      unsigned long totalTime = 0;

      delay(100);

      for (int i=0; i<1000; i++)
      {
        time1 = micros();
        Serial.write(chars, NB_CHARS);
        time2 = micros();
        totalTime += time2 - time1;

        delay(10);
        Serial.println("");
        delay(10);
      }

      float meanTime = (float)totalTime / 1000.0f;
      Serial.print("meanTime = ");
      Serial.println(meanTime);
    }

    void loop()
    {

    }

Here are some results for different NB_CHARS values:

    NB_CHARS: Time (microseconds)
    1: 12
    2: 18
    3: 24
    [...]
    99: 2912
    100: 2997
    101: 3082
    [...]
    199: 11412
    200: 11497
    201: 11582

It seems that at first, each new character adds around 6 microseconds of delay, but afterward it becomes 85 microseconds. I tested every values from 1 to 100 to find where it changes and it seems to be right after 70:

[![Serial.Write() delay as a function of number of chars][1]][1]

It seems weird to me.

A quick Google search gets me to [this 2013 post by Tom Carpenter][2]. I am not sure how true this is or if it is still relevant.

> Part of the trouble is that the Hardware Serial library is so
> incredibly inefficient (I don't think they could have made it less
> efficient if they tried!). After each byte is sent, there is an
> interrupt called which spends a lifetime loading the next byte into
> the buffer to send. The write function also wastes lots of time doing
> calculations as to where to put a character in a ring buffer.
>
> [...]

Why is there such a "long" delay for each character and is there a way to make it faster?

What happens after 70 characters that slows it down even further?

  [1]: https://i.stack.imgur.com/pnFDb.png
  [2]: https://forum.arduino.cc/index.php?topic=196328.msg1448997#msg1448997

body:
The Arduino core has a 64 byte transmission buffer.  Characters are sent out of that buffer by the hardware.

When you blast lots of characters out of serial the first 64 just get put into that buffer - almost instantly.

Once that buffer is full your sketch blocks until the hardware has sent a character to make room.

Since it's sending right from the moment you place the first character into the buffer you get a little more than 64 bytes worth of buffering time (64 + the number that have been sent by the time the buffer fills).

From that point on you are entirely at the mercy of the baud rate you have chosen.

To get more predictable throughput (and maximise the speed) you should bypass the Ardiuno core and manipulate the UART registers directly.


body:
Majenko already gave the right answer: as soon as the buffer is full, everything falls apart (for a time sensitive application).

It is possible to enlarge the serial buffer for your project. However, in the future, with a new Arduino version, you might have forgotten that you have changed a library and the project does no longer work that well.

I want to point out that you can use the usb serial port that is inside some microcontrollers and processors. That is not a real serial uart with a baudrate and a clock, but a usb CDC device.
A atmega32u4 and the arm m0+ have such a usb CDC serial port.
The arduino leonardo, micro and pro micro use the atmega32u4.
The arduino zero, m0, mkr series use the arm m0+ processor.

What about these numbers:

    NB_CHARS: Time (microsec)
    1: 6.93
    2: 7.60
    3: 8.06
    [...]
    99: 153
    100: 154
    101: 152
    [...]
    199: 1685
    200: 1624
    201: 1705

That is with a arm m0+ processor. I used the same sketch as you, but I changed the `Serial` to `SerialUSB`.


body:
Your "long" delay is not too long at all.

If you measure the throughput of the right part, you have about 30 characters sent in 2500 microseconds. This means the rate is roughly (30 * 8 * 1,000,000) / 2500, which is 96,000 bits/sec.

It's a bit less than 115,200 you specified, but serial protocols use [service bits][1], so in fact you'd have to replace 8 with 10. This gives 120,000 baud which is within measurement error.

The left part is actually much faster than you required, but as @Majenko correctly noticed, this is thanks to buffering. Apparently, you can [increase the buffer size][2] up to 256 bytes. If you need consistency instead of maximum speed, you may decrease the buffer size instead.

Finally, you should test performance in a realistic scenario. In your example you just keep sending data in a loop; obviously you soon fill up the buffer and run into port speed limit. However, in real life your loop would probably read some input, do some calculations, then send the result. In this case, you'd be using the buffer more effectively.

  [1]: https://electronics.stackexchange.com/questions/282346/difference-between-bit-rate-and-baud-rate-and-its-origins
  [2]: https://internetofhomethings.com/homethings/?p=927


message:
array to serial

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.

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>


message:
PCA9685 servo shield not working

[![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

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

* SDA is A4
* SCL is A5

You have it the other way around.


message:
Are these relays connected correctly?

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

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


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

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/

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?


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

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?

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.


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

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

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("...");


message:
Vacuum pressure sensor for Arduino

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.

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.


message:
Ping a sensor for error checking

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.

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.


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

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

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.


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

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?

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


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

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.

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.


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

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

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


message:
Watchdog Timer for atmega 128

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 ?

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.


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

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:

    }

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


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

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.

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.


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

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

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.


message:
Arduino OBD connection

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

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("     ");
      }
    }


message:
Help with clearing memory

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

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.


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

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?

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.


message:
My Arduino IDE stuck on uploading

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

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?


message:
Blynk app, DotStar bluetooth control code help

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

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