title: GPS Logger problem

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

    }
  }
}

```

# Answer
SD uses SPI. On the Uno, SPI is on pins 10-13. 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.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: 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.

# Answer
`Serial.print(PIND, BIN);` will write the value in `PIND` to the serial port in Base-2 representation.
> 2 votes

# Answer
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.
> 0 votes

# Answer
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.
> 0 votes

# Answer
```
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

```
> 0 votes

---
Tags: arduino-uno
---


title: Circuit with buzzer not working :(

text:
# Question
Title: Circuit with buzzer not working :(
so I have a circuit with a buzzer and a resistor:

This circuit should be working, but for some reason the buzzer doesn't sound. I pushed the buzzer into the breadboard as hard as I could, I put the + side to positive and the - side to negative but it still doesnt work :(. How can I fix this?

Quick curiosity question: When I was doing electricity in school, the teacher just called the buzzers 'buzzers' but when I started doing arduino I noticed that the arduino community seems to call them 'Piezo buzzers/piezo speakers'. Is there any significance in the word 'Piezo' and should I start referring to them as 'Piezo buzzers' myself?

# Answer
There is two kinds of buzzers - active and passive

1. Passive buzzer means they can be operated by applying just logic high to + and low to ground.

Digitalwrite function will do this job

2. Active buzzers needs pulses to make sound. Sound produced depends on the frequency. Your buzzer might be a passive one. You can make a symphony by applying different frequencies..

'tone' function will help you for this
> 6 votes

# Answer
Try the toneAC library if it is a two pin piezo speaker... It generates weak alternating current, using two arduino pins. Your piezo will last longer. Works like old tone library. Remember to put a 100 ohm resistor in series :)
> 0 votes

# Answer
Buzzer coils get locked if a higher voltage is applied to the terminals - it could be 5-9 V. Once it gets locked it won't work even if you put direct battery to it. The only solution is to first take out your buzzer and give it a reverse voltage that will get the coil out of the lock position, then put 180 Ω resistor and run. It will work and it will never lock again.
> 0 votes

---
Tags: arduino-uno, buzzer
---


# Question
Title: 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.

# Answer
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.
> 3 votes

---
Tags: arduino-uno, usb, raspberrypi
---


# Question
Title: 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 Arduino Nano not visible in Serial Ports (Mac OS) 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.

# Answer
> 1 votes
The Elegoo website has a downloads page which contains the drivers.

1. Using the Raspberry Pi, download the zip file containing the drivers.
2. Unzip the contents to a location of your choice. (Also see here)
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

---
Tags: arduino-nano, python, raspberrypi, ch340
---


title: Using Modbus TCP server on Arduino

text:
# Question
Title: 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()));

}

```

# Answer
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.
> 1 votes

---
Tags: arduino-uno, modbus
---


# Question
Title: Atmega328p - Going low power 1.8V using 4Mhz oscillator - Bootloader flash
I would like to use an **Atmega328p** micro-controller with a 4 Mhz oscillator in order get some **low power consumptions**. I am using an Arduino board to **flash the bootloader** into the Atmega.

**EDIT**

In order to compile the optiboot bootloader I had to install the avr-libc package and clone the repo

```
sudo apt-get install avr-libc
git clone https://github.com/Optiboot/optiboot.git

```

and edited the Makefile in `/optiboot/bootloaders/optiboot/Makefile` by adding a new entry called atmega328\_4

```
HELPTEXT += "target atmega328     - ATmega328p 4Mhz\n"
atmega328_4: TARGET = atmega328
atmega328_4: MCU_TARGET = atmega328p
atmega328_4: CFLAGS += $(COMMON_OPTIONS)
atmega328_4: AVR_FREQ ?= 4000000L
ifndef BIGBOOT
atmega328_4: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
else
# bigboot version is 1k long; starts earlier
atmega328_4: LDSECTIONS  = -Wl,--section-start=.text=0x7c00 -Wl,--section-start=.version=0x7ffe
endif
atmega328_4: $(PROGRAM)_atmega328_4.hex
atmega328_4: $(PROGRAM)_atmega328_4.lst

atmega328_4_isp: atmega328
atmega328_4_isp: TARGET = atmega328
atmega328_4_isp: MCU_TARGET = atmega328p
ifndef BIGBOOT
# 512 byte boot, SPIEN
atmega328_4_isp: HFUSE ?= D9
else
# 1k byte boot, SPIEN
atmega328_4_isp: HFUSE ?= D9
endif
# Low power xtal 46MHz) 16KCK/14CK+65ms
atmega328_4_isp: LFUSE ?= 7D
# 2.7V brownout
atmega328_4_isp: EFUSE ?= FE
atmega328_4_isp: isp

```

I saved the file, run the make command and got the following error:

```
userk@norepinephrine:~/development/git/optiboot/optiboot/bootloaders/optiboot$ make atmega328_4
avr-gcc (GCC) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

BAUD RATE CHECK: Desired: 115200, Real: 125000, UBRRL = 3, Difference=8.5%
avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax -mmcu=atmega328p -DF_CPU=4000000L  -DBAUD_RATE=115200 -DLED_START_FLASHES=3           -c -o optiboot.o optiboot.c
optiboot.c:348:6: error: #error BAUD_RATE off by greater than 5%
     #error BAUD_RATE off by greater than 5%
      ^
optiboot.c:359:2: error: #error Unachievable baud rate (too fast) BAUD_RATE
 #error Unachievable baud rate (too fast) BAUD_RATE
  ^
<builtin>: recipe for target 'optiboot.o' failed
make: *** [optiboot.o] Error 1

```

So I changed the -DBAUD\_RATE parameter to 19200 and rerun the make command

```
BAUD_RATE_CMD = -DBAUD_RATE=19200

```

Then 2 new files were created: optiboot\_atmega328\_4.elf and optiboot\_atmega328\_4.hex

Then I copied these files into the arduino configuration folder located at: `/home/userk/.arduino15/packages/arduino/hardware/avr/1.6.21/bootloaders/optiboot`

**TIDE**

I am using a **custom** board configuration file board.txt

```
##############################################################

nz.name=Arduino Noize

nz.vid.0=0x2341
nz.pid.0=0x0043
nz.vid.1=0x2341
nz.pid.1=0x0001
nz.vid.2=0x2A03
nz.pid.2=0x0043
nz.vid.3=0x2341
nz.pid.3=0x0243

nz.upload.tool=avrdude
nz.upload.protocol=arduino
nz.upload.maximum_size=32256
nz.upload.maximum_data_size=2048
nz.upload.speed=19200

nz.bootloader.tool=avrdude
nz.bootloader.low_fuses=0x7D
nz.bootloader.high_fuses=0xD9
nz.bootloader.extended_fuses=0xFE
nz.bootloader.unlock_bits=0x3F
nz.bootloader.lock_bits=0x0F
nz.bootloader.file=optiboot/optiboot_atmega328_4.hex

nz.build.mcu=atmega328p
nz.build.f_cpu=4000000L
nz.build.board=AVR_UNO
nz.build.core=arduino
nz.build.variant=standard

```

**Flashing the Bootloader** I have followed these steps:

* Uploaded the ArduinoISP sketch onto the Arduino UNO board.
* Wired up the Arduino board and microcontroller as shown in the diagram below

* Select "Arduino Noize" from the Tools \> Board menu.
* Select "Arduino as ISP" from Tools \> Programmer Run Tools \> Burn Bootloader

At this point I got a success message from IDE. So the bootloader has been correctly flashed into the Atmega328p

**The Problem**

When I try to upload a sample sketch (blink) using the wiring below I get a **timeout** from the IDE.

I have double checked the connections but the sketch doesn't upload. Do you have any advice?

# Answer
As Gerben notes in the comments, the bootloader has to know how fast the board is running. It uses this to work out the baud rate settings for the serial communication.

If you haven't compiled the bootloader yourself with the right clock settings you will probably find that it is operating at a quarter of the speed you expect it to. Dividing your upload baud rate by four in your board settings may make it work, but you really should compile the bootloader to match the board properly.
> 2 votes

# Answer
As mentioned before, you need to compile the Optiboot bootloader with the correct clock frequency. Here's a guide that shows you how to do that, as well as adding an option to the Arduino IDE menu to select the right clock speed without having to add your own board definition.

Optiboot - ATmega328P at custom frequency
> 2 votes

# Answer
```
nz.bootloader.low_fuses=0x7D
nz.bootloader.high_fuses=0xD9
nz.bootloader.extended_fuses=0xFE

```

Extended fuse byte. bits 2,1,0 determine the brown out level (bits 7-3 not used) 110 = 1.7 to 2.0V, 1.8 typical

Low fuse byte bits 3,2,1 determine the clock source 110 = low power crystal oscillator in 3-8 MHz range.

So those settings look okay.
> 1 votes

---
Tags: arduino-uno, arduino-ide, atmega328, bootloader, oscillator-clock
---


title: array to serial

text:
# Question
Title: 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.

# Answer
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>

```
> 1 votes

---
Tags: serial, softwareserial, array
---


title: PCA9685 servo shield not working

text:
# Question
Title: PCA9685 servo shield not working
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;
}

```

# Answer
> 2 votes
You have your SDA and SCL pins connected backwards.

* SDA is A4
* SCL is A5

You have it the other way around.

---
Tags: arduino-uno, servo, shields
---


# Question
Title: 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:

It seems weird to me.

A quick Google search gets me to this 2013 post by Tom Carpenter. 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?

# Answer
> 14 votes
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.

# Answer
> 3 votes
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`.

# Answer
> 3 votes
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, 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 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.

---
Tags: serial, performance
---


# Question
Title: 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?

# Answer
2S LiPo with 5V UBEC 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.
> 1 votes

# Answer
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.
> 1 votes

---
Tags: power, battery, arduino-motor-shield
---


# Question
Title: 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`.

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

```
> 2 votes

---
Tags: arduino-mega, code-review, atmega2560, calibration
---


title: Ping a sensor for error checking

text:
# Question
Title: 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.

# Answer
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 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.
> 1 votes

# Answer
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.
> 0 votes

---
Tags: sensors, temperature-sensor
---


# Question
Title: 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;
 }
}

```

# Answer
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).
> 2 votes

# Answer
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.
> 1 votes

---
Tags: programming, c++
---


title: Are these relays connected correctly?

text:
# Question
Title: 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%20Relay%20module.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:

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

# Answer
> 0 votes
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)?

---
Tags: arduino-uno, power, relay
---


# Question
Title: How to pass non-static class member to callback?
I am using the 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()'
> 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()'
> 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?

# Answer
> 7 votes
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)

---
Tags: esp8266, c++
---


title: Watchdog Timer for atmega 128

text:
# Question
Title: 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 ?

# Answer
> 1 votes
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.

---
Tags: arduino-mega, timers
---


# Question
Title: 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:

}

```

# Answer
> 1 votes
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).

---
Tags: arduino-uno, frequency, speaker
---


# Question
Title: 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 )?

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.

# Answer
> 1 votes
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.

---
Tags: serial, arduino-mega, lcd, library
---


# Question
Title: 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

# Answer
> 3 votes
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

# Answer
> 0 votes
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).

# Answer
> 0 votes
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.

---
Tags: arduino-uno
---


# Question
Title: (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.

# Answer
> 0 votes
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.

---
Tags: arduino-uno
---


# Question
Title: Trying to use Tap Detection solution using ADXL345 with Arduino
I am using ADXL345 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.

# Answer
> 1 votes
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?

---
Tags: arduino-uno, sensors, code-review, accelerometer
---


title: Arduino OBD connection

text:
# Question
Title: 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

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

```
> 0 votes

---
Tags: arduino-nano
---


# Question
Title: 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?

# Answer
> 4 votes
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

simulate this circuit – Schematic created using CircuitLab

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.

---
Tags: battery
---


title: Help with clearing memory

text:
# Question
Title: 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);
  }
}

```

# Answer
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.
> 0 votes

---
Tags: programming
---


# Question
Title: How do I change the Console colour of Arduino IDE?
Leading on from the question Can I change font Color and/or Type for IDE 1.5.6r2?, in 1.6.0, or 1.6.11 it does not seem to be possible to change `console.color` or `console.error.color`. To be precise, you can change the settings in the `preferences.txt`2 file, but they appear to be ignored when the IDE is restarted. Have these become hard coded? I see from the preference.txt example file that

```
# Some colors have been hardcoded into the source in app/ in order to ensure
# consistency with the images distributed and stored with the application.
# They have been commented out below so that users who install an old
# version of the software will not get incorrect colors left-over from this
# config file.

```

However, the settings to which I refer are not commented out, and so would led me to believe that they can be changed. Orange text on black is just horrific to read.

For example:

```
console.error.color=#FFF000
console.color=#FFCCCC

```

but I still get white/orange(red?) text for the output and error messages respectively.

I am making the edits while the Arduino IDE is not running.

---

1 In 1.6.3 the ignored `console.color` etc. lines appear to have been removed from the `preferences.txt` file.

2 `C:\Users\username\AppData\Roaming\Arduino15\preferences.txt`

# Answer
It turns out that the `theme.txt` configuration file is *not* located alongside the `preferences.txt` file, but alongside/under the Arduino application's `.jar` files. Thus, for the current version (1.6.3):

* on OS X, `.../Arduino-1.6.3.app/Contents/Java/lib/theme/theme.txt`
* on Win7, `C:\Program Files\Arduino\lib\theme\theme.txt`
* on Linux, `.../arduino-1.6.3/lib/theme/theme.txt`
* on Windows 10, when installed as an App, C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE\_1.8.10.0\_x86\__mdqgnx93n4wtt\lib\theme\theme.txt, however it does not seem possible to edit it - it can be opened in notepad++ but a save fails.

See an associated Github issue, IDE Background and print color options needed, for a little more discussion.
> 10 votes

# Answer
Download the Dark Theme of Jeff Thompson from Github: jeffThompson/DarkArduinoTheme

Screenshot:
> 2 votes

---
Tags: arduino-ide
---


# Question
Title: 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

# Answer
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.
> 0 votes

---
Tags: sensors
---


# Question
Title: NRF24L01+ PA not working with Arduino Mega (works with Nano)
**Full disclosure**: I'm a newbie.

I've got an Arduino Nano and a Mega, and a pair of NRF24L01+ PA modules (exactly these: http://www.elektrotedarik.com/Images/Urun/11122013173429.jpeg)

I'm trying to get them to work. I am on this tutorial with the RF24 library: https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

On Arduino Nano, it works perfect. I wire everything as told, and set up my radio:

```
const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN);
fdevopen( &my_putc, 0);
radio.begin();
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipe);

```

When I call `radio.printDetails();` I get a nice output in serial monitor:

```
STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1    � = 0xe8e8f0f0e1 0xc2c2c2c2c2
RX_ADDR_P2-5    � = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xe8e8f0f0e1
RX_PW_P0-6  � = 0x20 0x00 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR   � = 0x03
RF_CH        = 0x4c
RF_SETUP    � = 0x27
CONFIG       = 0x0c
DYNPD/FEATURE   � = 0x00 0x00
Data Rate    = 250KBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_HIGH

```

Everything as expected. If I remove a wire (for testing), it displays all zeroes, when I plug it back, it displays right again, so I assume that it's in working condition. I then try the same with Mega, but even after re-checking the wiring after 4 times, it's not working. Here's what I get with the same code:

```
STATUS       = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1    � = 0x0000000000 0x0000000000
RX_ADDR_P2-5    � = 0x00 0x00 0x00 0x00
TX_ADDR      = 0x0000000000
RX_PW_P0-6  � = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA        = 0x00
EN_RXADDR   � = 0x00
RF_CH        = 0x00
RF_SETUP    � = 0x00
CONFIG       = 0x00
DYNPD/FEATURE   � = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01
CRC Length   = Disabled
PA Power     = PA_MIN

```

Tried many times, no avail. Then I've came upon several threads talking about the different pins. Changed the pins to match Mega's MOSI, MISO, SCK, CE, CSN pins, no avail. I've tried exact same configuration with people who say that it's working, no avail. Then I've stumbled upon that Mega ironically can't supply enough current from the 3V3 pin (while Nano perfectly can) and it can't power the NRF24L01+ PA. I've tried drawing 3V from my power supply (my power supply has either 3 or 4.5 volts, I can't risk burning my transceiver with 4.5 volts). It still doesn't work, and it became extremely hot in seconds (the one attached to my nano doesn't heat up at all). I immediately turned it off, thought that I've burned something, swapped with the Nano's transceiver, and it (fortunatelly) works. So there's no problem with the NRF24L01+ PAs. Why would it not work with Mega (I've also tried the lowest power setting too), and why would it get extremely hot when attached to an external power supply? What else can I do?

**UPDATE:** I've added a 470uF decoupling capacitor to the receiving end (the one attached to Mega), it seems to be worse.

A very interesting observation: If I touch the receiver when it's not working, it starts receiving the signal excellently. If I let it go, signal is lost again.

**UPDATE 2:** Nevermind the last "when I touch..." update, it appears to be related to wiring (haven't soldered them yet, just using jumper wires)

**UPDATE 3:** My initial assumption is correct, something happens when I touch the cables. Something more weird is going on. I soldered my module on a prototype board, and my module sometimes works even without CE pin plugged in. When I touch the cable, it transmits, and stops. Here, TX pin lighting up means it's receiving the signal (I'm writing data to serial). It receives the data (and yeah, the correct data) when I touch the CE pin's cable:

How on Earth is this possible? Does the CE pin/cable (and myself) act as an antenna? Makes no sense.

**UPDATE 4:** If I plug that pin to 5V, the whole receiver starts working absolutely perfectly, with no errors/drops at all. But I can't get it: why? And would it overheat/short something?

# Answer
> 2 votes
I have a NRF24L01 - not that exact model, mine looks like this:

Pin-outs:

I hooked it up to my Mega2560 like this:

```
NRF24L01     Mega2560
----------   ----------------

  VCC         3.3V pin
  Gnd         Gnd
  CSN         D10
  CE          D9
  MOSI        D51 - (MOSI)
  SCK         D52 - (SCK)
  IRQ         N/C
  MISO        D50 - (MISO)

```

I used the RF24 library. Then I hit a number of issues.

For one thing, the "Getting Started" sketch doesn't seem to work too well, even between two Unos, for reasons I haven't worked out.

However the "pingpair" sketch worked OK between two Unos. But **not** when one device was moved to the Mega2560! I tried various things including a separate power supply, and moving the CSN/CE pins around, but to no avail.

Then I had a look at Vcc/Gnd using the scope:

That's over half a volt of ripple! I soldered on a 0.1 µF capacitor between Vcc and Gnd on the NRF24L01 and the problems went away. Using the pingpair sketch I now have:

```
Now sending 56...ok...Got response 56, round-trip delay: 23
Now sending 1080...ok...Got response 1080, round-trip delay: 21
Now sending 2103...ok...Got response 2103, round-trip delay: 21
Now sending 3126...ok...Got response 3126, round-trip delay: 21
Now sending 4148...ok...Got response 4148, round-trip delay: 22
Now sending 5171...ok...Got response 5171, round-trip delay: 22
Now sending 6194...ok...Got response 6194, round-trip delay: 22
Now sending 7217...ok...Got response 7217, round-trip delay: 22
Now sending 8240...ok...Got response 8240, round-trip delay: 21
Now sending 9263...ok...Got response 9263, round-trip delay: 21
Now sending 10286...ok...Got response 10286, round-trip delay: 21

```

So, my suggestion is a decoupling capacitor on the NRF24L01.

---

### Extra

I still had some weird issues where the above results actually came from a NRF24L01 **without** the aerial. The one with the aerial had much more marginal results.

These are the results **with** the aerial:

```
Now sending 181378...ok...Failed, response timed out.
Now sending 182581...ok...Failed, response timed out.
Now sending 183784...failed.
Failed, response timed out.
Now sending 185047...failed.
Failed, response timed out.
Now sending 186309...ok...Got response 186309, round-trip delay: 26
Now sending 187336...ok...Got response 187336, round-trip delay: 22
Now sending 188359...ok...Failed, response timed out.
Now sending 189561...ok...Got response 189561, round-trip delay: 22

```

Still, I think it is worth trying the decoupling capacitor.

---

> and why would it get extremely hot when attached to an external power supply?

Did you have the grounds connected?

# Answer
> 0 votes
An old thread.
But I want to share my fix when hooking nRF24 with MEGA. I forgot the website where I got the solution.

It is simply adding a `pinMode(x, OUTPUT)` in the `setup`, where `x` is the CSN pin you choose.

I believe the issue is only on pin 53 only on MEGA.
However, add this in all my sketches with or without MEGA just for precaution.

---
Tags: arduino-mega, nrf24l01+
---


# Question
Title: 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:

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.

# Answer
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).
> 0 votes

---
Tags: library, arduino-leonardo
---


title: FastLED - How to Control specific LEDs

text:
# Question
Title: FastLED - How to Control specific LEDs
I am fearly new to Arduino and FastLED. I found a nice Sketch which fits almost perfectly to my needs.

Just one Problem:

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

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

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

```
    #include <FastLED.h>

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

    CRGB leds[NUM_LEDS];

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

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

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

```

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

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

```

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

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

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

```

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

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

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

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

```

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

---
Tags: led
---


title: NodeMCU ESP8266 button wiring problem

text:
# Question
Title: NodeMCU ESP8266 button wiring problem
Hello guys, this is my code and I am basically doing if-else statement.

```
int led = D2;
int but = D1;

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

}

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

}

```

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

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

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

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

simulate this circuit – Schematic created using CircuitLab
> 2 votes

---
Tags: nodemcu
---