# Question
Title: 16Hertz Uno R3 Board vs Arduino Uno R3 Board
I bought a 16Hertz Uno R3 Board. When I installed the driver and the Arduino IDE, in the IDE\`s menu I saw:

> Tools -\> Board -\> Arduino Uno

was selected by default which is great, but...

> Tools -\> Port -\> COM3(Arduino Mega or Mega 2560)

was selected by default which I think might be some kind of misunderstanding...

When I chose:

> Tools -\> Board -\> Arduino Mega or Mega 2560

On that tools menu appeared new menu "Processor" with two options:

> Tools -\> Processor -\> ATmega2560 (Mega 2560)

which was selected by default and there was another option

> Tools -\> Processor -\> ATmega1280

When I restore Tools -\> Board settings back to "Arduino Uno" the "Processor" menu with the two options disappeared and Tools -\> Port setting did not changed!

If you take my board and look at the Microcontroller there is written:

> ATMEGA328P-PU

Also on that board is written:

> 16HzUNO

I need to know:

1. What does 16Hz mean? Does it mean the clock or frequency of this Microcontroller? I think it does not, if I try to find out details of my Microcontroller on the rs-online site, there is written:

> ATMEGA328P-PU, 8 bit AVR Microcontroller 20MHz 1 kB, 32 kB Flash, 2 kB RAM, I2C 28-Pin PDIP

2. Why was there "COM3(Arduino Mega or Mega 2560)" written on the Port's menu?
3. Is my 16Hz Uno R3 and the Arduino Uno R3 board the same? Which one is better? When one of those is better?
4. Does the standard Arduino Uno R3 board have the same ATMEGA328P-PU Microcontroller?

# Answer
You need to have a look at the Arduino comparison table. This shows that *all* Arduino Uno boards run at 16 MHz. It seems that you have fallen for the marketing on the page for the Uno kit that you provided.

Also, which version of the IDE are you running? You should upgrade to the latest version, which is currently, at the time of writing, version 1.6.1.

To answer your questions in turn:

1. "**16Hz**" is the *brand name* and has nothing whatsoever to do with the speed, which is actually 16 **Mega** Hertz. "Clock" and "Frequency" refer to the same thing. 16 MHz is the clock frequency of the board, and is the speed at which the **ATmega328** runs at. The RS Online link does indeed state 20 MHz, but that is merely the *maximum* speed at which the **ATmega328** can run at. The Uno under clocks it at 16 MHz.
2. The **Ports** menu will show you a number of possible devices, **Arduino Uno** should be one of them (which is the one you should select) and three items below that will be **Arduino Mega or Mega 2560** (which you should ignore, you do not have a Mega board1). Unfortunately the Arduino site only shows the Mac menu, even on the Windows guide

>

which is no help to you, assuming that you are running the Arduino IDE on Windows. You should actually see this in the **Board** menu:

>

and this in the **Port** menu:

>

As you can see, there should be no mention of the microcontroller in the **Port** menu.
3. The 16Hz branded Uno and the Arduino Uno are to all intents and purposes the same and as I state in the first line, the 16 MHz Uno is *exactly* the same as a regular Uno, it is just marketing.
4. Both the 16Hz and the Arduino Uno have a **ATmega328** and the Mega board has a **ATmega2560**. Again, check the Arduino comparison table to see the variety of the boards and their respective microcontrollers.

I hope that answers your questions.

---

1 If you *do* chose the **Arduino Mega or Mega 2560** option, in the **Board** menu, then indeed there will be an additional **Processor** menu. However, this is irrelevant in your case, as you do not have a Mega board, and so you need to chose the Uno in the **Board** menu. If you do so, then the **Processor** menu will disappear, as it is not needed for the Uno.
> 3 votes

# Answer
1. Every Arduino is using a quartz crystal in order to get the frequency needed. ATmega328 can handle up to 20 MHz
2. ??
3. Yes. You can't run the microcontroller by itself. It has an internal oscillator but none is using it. So basically you will have a 16 MHz crystal.
4. Pretty much the Arduino Uno, Nano, Mini and few others have the ATmega328P. Note that the `-PU` `-AU` at the end defines the package. So they're the same.

Arduino Mega, Leonardo, Micro, Due use other chips.
> 2 votes

# Answer
Just a theory for 2:

The text that shows up in the Tools \> Port list after the COMx

eg `Tools -> Port -> COM3(Arduino Mega or Mega 2560)`

is simply what the IDE thinks the board is based on the USB ID (VID/PID) of the board's USB interface chip. For some clones, this is blank because they don't even use the same chip as an authentic Uno. In your case, I would suspect that they have used the USB chip from a Mega board on your Uno board.

So the IDE thinks a Mega is attached because it is seeing a USB chip from a Mega, even though it is an Uno (clone).
> 0 votes

---
Tags: arduino-uno, serial, arduino-mega, atmega328
---


# Question
Title: Timeout error with Arduino Mega and ESP8266 as the wifi module
I am trying to use the ESP8266 as the wifi module based on this tutorial. My connections are as follows:

```
ESP8266 <-----------------> Arduino Mega
VCC     ------------------> 3.3V (converted 5V from Mega to 3.3V using LD33V)
CH_PD   ------------------> 3.3V
GND     ------------------> GND
RX      ------------------> TX1(Pin 18)
TX      ------------------> RX1(Pin 19)

```

I have checked the baud rate by issuing the AT commands at 115200 baudrate and the ESP is responding. Below is my code which I am trying to use:

```
#include "WiFiEsp.h"
#include <PubSubClient.h>

const char* ssid = "MySSID";
const char* password = "MyPassword";
int status = WL_IDLE_STATUS; //wifi radio's status
byte* messageBuff;

//MQTT
const char* mqtt_server = "192.xxx.x.xxx";
//const char* mqtt_topic = "Rpi_Master";
const char* mqtt_username = "username";
const char* mqtt_password = "password";
//client Id
const char* clientID = "A_1";

//Variables for numbers
long randNumber1;
String rn1;
char rn1_char[50];
long randNumber2;
String rn2;
char rn2_char[50];
long randNumber3;
String rn3;
char rn3_char[50];
long randNumber4;
String rn4;
char rn4_char[50];
long randNumber5;
String rn5;
char rn5_char[50];
long randNumber6;
String rn6;
char rn6_char[50];

WiFiEspClient wifiClient;
PubSubClient client(mqtt_server, 1883, wifiClient); //1883 is the listener port for the broker

void callback(char* topic, byte* payload, unsigned int length) {

    Serial.print("Message Received: [");
    Serial.print(topic);
    Serial.println("]");
    Serial.print("Message is:");
    String message = (char *)payload;
    Serial.println(message);

    Serial.println();
    if (!strncmp((char *)payload, "Start", length)) //Start code can be changed to any string value in place of 1
    {
      randomNumberGenerator();
      client.publish("Arduino_A", "OK");
    }

}

void reconnect() {
  //Loop until we are reconnected
  while (!client.connected())
  {
    Serial.print("Attempting MQTT Connection...");
    //Attempt to Connect
    if (client.connect(clientID, mqtt_username, mqtt_password))
    {
      Serial.println("connected");
      //Once connected publish an announcement
      client.publish("Arduino_A", "Please send the pass code to send the values");
      //and resubscribe
      client.subscribe("Rpi_Master"); //This name can be changed
    }
    else
    {
      Serial.print("failed, rc = ");
      Serial.print(client.state());
      Serial.println("Trying again in 5 seconds");
      //Wait for 5 seconds before retrying
      delay(5000);
    }
  }
}

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

  //initilize the ESP module
  WiFi.init(&Serial1);
  Serial.println("Attempting to connect to WPA network");
  status = WiFi.begin(ssid, password);
  //if you are not connected stop here
  if (status != WL_CONNECTED)
  {
    Serial.println("Couldn't get a wifi network");
    while (true);
  }
  //if you are connected, print out the info about the connection
  else
  {
    Serial.println("Connected to the network");
  }
  //client.setServer(server, 1883);
  client.setCallback(callback);
  //Allow the hardware to sort itself
  delay(1500);
  randomSeed(25);
}

void loop() {
  if (!client.connected())
  {
    reconnect();
  }
  //delay(1000);
  client.loop();
  delay(50);
}

void randomNumberGenerator()
{
    randNumber1 = random(10,20);
    Serial.println(randNumber1); // print a random number from 0to 299
    rn1 = String(randNumber1);
    rn1.toCharArray(rn1_char, rn1.length() + 1);
    randNumber2 = random(20, 30);// print a random number from 10 to 19
    Serial.println (randNumber2);
    rn2 = String(randNumber2);
    rn2.toCharArray(rn2_char, rn2.length() + 1);
    randNumber3 = random(30,40);
    Serial.println(randNumber3);
    rn3 = String(randNumber3);
    rn3.toCharArray(rn3_char, rn1.length() + 1);
    randNumber4 = random (40,50);
    Serial.println(randNumber4);
    rn4 = String(randNumber4);
    rn4.toCharArray(rn4_char, rn4.length() + 1);
    randNumber5 = random (50,60);
    Serial.println(randNumber5);
    rn5 = String(randNumber5);
    rn5.toCharArray(rn5_char, rn5.length() + 1);
    randNumber6 = random (60,70);
    Serial.println(randNumber6);
    rn6 = String(randNumber6);
    rn6.toCharArray(rn6_char, rn6.length() + 1);
    client.publish("LC_1", rn1_char);
    client.publish("LC_2", rn2_char);
    client.publish("LC_3", rn3_char);
    client.publish("LC_4", rn4_char);
    client.publish("LC_5", rn5_char);
    client.publish("LC_6", rn6_char);
    client.publish("Arduino_A", "End Transaction");
}

```

Currently am using this code to send 6 random values whenever there is a request being sent from the broker over MQTT. I intend to replace this code once the error issue is resolved. The code works fine and the ESP connects to the broker (Raspberry Pi in my case) initially. However after some time I keep getting Timeout Error and the ESP8266 keeps diconnecting from the server.

I read in other forums that ESP8266 will not be handle high baudrates such as 115200 and should be set to 9600. Could this be a reason for the timeout error? Please let me know what changes I need to rectify this issue. Thanks a lot for your time in advance. Attached the screenshot of the error.

# Answer
The old WiFiEsp by Bruno Poltaruri library can't do much with larger data received. The AT firmware sends all the data at once and the serial RX buffer overflows. It works better with 9600 baud which slows down the AT firmware.

It is hard to receive more data over network with AT firmware without UART hardware flow control and Arduino AVR boards don't have flow control and simple esp8266 modules don't have the flow control pins exposed.

My new WiFiEspAT library uses the new passive receive mode implemented in AT firmware 1.7.0 (SDK 3). The new passive receive mode of the AT firmware is not supported for UDP and secure connection (SSL) yet. For this reason in the new library UDP received message size is limited to configured buffer size and secure connection (SSL, https) is not supported.

With my new library over hardware serial high baud rates can be used. For Arduino Mega 500000 baud works good. For example a WebServer serving web files from SD card requires high baud rate to be able to serve multiple files one after other fast enough.
> 1 votes

---
Tags: arduino-mega, esp8266, wifi, shields
---


title: Input current for L293D shield

text:
# Question
Title: Input current for L293D shield
I am a newbie in arduino working on a bot with L293D shield. But I have a question as what would be the input current to drive all 4 dc motors and 2 servo motors. I can see that it can supply 0.6Amp current for the four motors.

I am considering the amount of electrons flowing in per unit time is equal to the electrons flowing out of the circuit, as an simplistic aprach. So practically the input current should be greater than or equal to 2.4Amp.

As I have 6 motors in total so I was thinking about making a 12V 3Amp DC supply for a better performance. Should I do it like that? will it damage the board or shield?

# Answer
> 1 votes
Here the proper answer:

The vast majority of devices are constant-voltage devices. They need a constant operating voltage to work correctly. Microcontrollers are such devices. When operating, they will try to draw as much current from the power source, as they need, but not more. Much like a simple resistor with an applied voltage will draw a specific amount of current (calculable with Ohm's law), complex devices like microcontrolelrs have something like an overall impedance/resistance, that is depending on their specific operation. So also here the device only draws as much current, as it needs. (I wrote about an overall impedance to emphasize the fundamental principle. No one would really specify an overall impedance for such a device, because this would only be a value calculated by the voltage and current needed, not a real resistance.)

This means, that burning parts are not due to the power supply supplying more amps. They get burnt, because something draw too much power trough them.

Let's look at some examples:

1. Imagine, that you create a short between 5V and ground on your Uno. A short means, that a high current can flow, since the resistance is very low. Now you are drawing a high current from your 5V pin to the ground pin. The Arduino's 5V pin is connected to a voltage regulator (for if you use Vin) and over a diode to USB. Both parts are only rated for a maximum current (depending on the version of the board between 200mA and 1A). The high current, that you draw, will flow through one of these parts, depending on your input source. This part will get fried, because a way to high current will flow through it, just because you **draw** the current.
2. A strong motor, that needs more current, than the board is rated for, would result in a similar problem like the short circuit. Indeed every device, that needs more current, than the board is rated for, might result in frying the mentioned parts.

But what happens, if you draw more power from the power supply itself, than it is rated for? The power supply electronic is similar to the Arduino board. When you draw too much current from the power supply, some parts of it might get fried and stop working. Thus, you should not try to draw more current from it, than it can provide. Often power supplies have a protection circuit, that will either lower or directly cut the voltage, if too much current is drawn. This is for the safety of the supply and should not be used for current limiting your own application normally.

So, you should always calculate, what current you expect to need, and then take a power supply, that can provide more current than that. You should consider a significant headroom, so that you can add more parts, if you want to extent your project. For example, if I calculate 2A for my project, I would use a power supply in the range of 3A.

---

Addition:

Above I wrote about constant-voltage devices. There are also constant-current devices, for example LEDs. An LED has a specific constant forward voltage. Under that voltage it will not conduct current. Over that voltage, the current rises exponentially. The voltage over the LED will always stay the same, as it was designed. This is the reason, why you need to add a current limiting resistor to a LED. But in the vast of devices, LEDs (or in fact every diode) is an exception.

---
Tags: arduino-uno, l293d
---


# Question
Title: Initalizing library object in own library
**EDIT: @Juraj fixed the Issue, changes at the end of the post**

I am developing an application to program OneWire ID Chips. I am using the OneWire library (https://github.com/PaulStoffregen/OneWire) and built my own Library for the DS28EC20 Chip on top of it.

It is working but it's not very elegant. I have issues initalizing the OneWire object in my own library. At the moment it is only working with a fixed pin declared in my own library.

I want to call a function in my code which initalizes the OneWire library aswell as my own library for the DS28EC20.

I am not using the Arduino IDE, I am using Platform.io for VSCode because it's more powerful.

It would be awesome if someone could help me, because I need to use multiple ID Chips in my application.

Because of unkown reasons I need to pass a variable to the constructor of the DS28EC20. Calling the OneWire library in there does not work...

*I excluded the other functions in the DS28EC20.cpp file, I think they are not necessary rn*

Thank you very much in advance! \- pitchbent

main.cpp:

```
#include <Arduino.h>
#include <OneWire.h>
#include <DS28EC20.h>

uint8_t scratchpad[32];                                                   // Array for scratchpad
uint16_t location;                                                        //Memory location to store scratchpad in
//uint8_t memory[32];
bool status;                                                              // Status of the crc check

DS28EC20 One(5);

void setup() {

  pinMode(13,OUTPUT);
  Serial.begin(115200);                                                   //begin serial connection 0
  location = 0x460;                                                       //Memory location

  for (uint8_t i = 0; i < 32; i++)                                        //filling array for scratchpad
  {
    scratchpad[i]=0x22;
  }
  Serial.println(scratchpad[2]);

  status = One.write_scratchpad(scratchpad,32,location);                  //write scratchpad
  Serial.println("Status:");                                              //print status
  Serial.println(status);

  // put your setup code here, to run once:
}

void loop() {

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

```

DS28EC20.cpp:

```
#include "Arduino.h"
#include "OneWire.h"
#include "DS28EC20.h"

OneWire Wire(31);

DS28EC20::DS28EC20(uint8_t)
{

}
bool DS28EC20::write_scratchpad(uint8_t *data, uint8_t leng, uint_fast16_t adress)
{
  Serial.println("123");
  uint8_t TA1;                                                            // Var for adress Bytes
  uint8_t TA2;
  uint8_t crc_rec[6];                                                     // Array for recieved CRC Bytes
  uint8_t crc_array[leng+3];                                              // Array for calculation of CRC value

  TA1 = (adress & 0xFF);                                                  // calculation of TA1 & TA2
  TA2 = ((adress >> 8) & 0xFF);
 crc_array[0]=WRITE_SCRATCHPAD;                                            // The CRC sum is computed out of the command aswell as the adress byteys
  crc_array[1]=TA1;                                                         //
  crc_array[2]=TA2;

  for (int i = 0; i < leng; i++)                                            // write data into crc array
  {
    crc_array[i+3]=data[i];
  }
 Wire.reset();                                                             // Reset
  Wire.write(SKIP_ROM);                                                     // Skip ROM
  Wire.write(WRITE_SCRATCHPAD);                                             // write Scratchpad

  Wire.write(TA1);                                                          // send adress bytes
  Wire.write(TA2);

  for(int i=0;i<leng; i++)                                                  // write data
  {
    Wire.write(data[i]);
  }

  Wire.read_bytes(crc_rec,6);                                               // safe CRC values sent from chip

  delay(10);
 Wire.reset();                                                             // Reset
if(Wire.check_crc16(crc_array,leng+3,&crc_rec[0]))                        // CRC Check
  {
    return true;
  }
  else
  {
    return false;
  }

}

```

DS28EC20.h

```
/*
Library for DS28EC20, built on top of OneWire.h lib
*/

#ifndef DS28EC20_h
#define DS28EC20_h

#include "Arduino.h"
#include "OneWire.h"
#include "DS28EC20.h"

#define WRITE_SCRATCHPAD 0xF                                              // commands für DS28EC20
#define READ_SCRATCHPAD 0xAA
#define COPY_SCRATCHPAD 0x55
#define READ_MEMORY 0xF0
#define EXTENDED_READ_MEMORY 0xA5

#define READ_ROM 0x33
#define MATCH_ROM 0x55
#define SEARCH_ROM 0xF0
#define SKIP_ROM 0xCC
#define RESUME 0xA5

class DS28EC20
{
    public:
     DS28EC20(uint8_t); // Constructor, add DS28EC20 to "pin"
     bool write_scratchpad(uint8_t *data, uint8_t leng, uint_fast16_t adress);
     bool write_memory(uint16_t adress);
     void read_memory(uint16_t adress,uint8_t *data, uint8_t leng);

     private:

};

```

**Fix:**

In main.cpp call Object with corresponding pin:

```
DS28EC20 One(31);

```

In DS28EC20.cpp add

```
OneWire Wire;

```

after includes, change the constructor aswell:

```
DS28EC20::DS28EC20(uint8_t pin)
{
  Wire.begin(pin);
}

```

In DS28EC20.h you need to change the class to:

```
class DS28EC20
{
    public:

     DS28EC20(uint8_t pin); // Constructor, add DS28EC20 to "pin"
     bool write_scratchpad(uint8_t *data, uint8_t leng, uint_fast16_t adress);
     bool write_memory(uint16_t adress);
     void read_memory(uint16_t adress,uint8_t *data, uint8_t leng);

     private:
     OneWire Wire;

};

```

# Answer
Use the constructor without parameter `OneWire wire;` and call `wire.begin(pin);` to set the pin.

And to use more sensors on different pins, make the OneWire instance member of the DS28EC20 class.
> 0 votes

---
Tags: library, eeprom
---


title: ultrasonic sencor give wrong distances

text:
# Question
Title: ultrasonic sencor give wrong distances
. I used the inbuilt basic example of measuring the distance to test my ultrasonic sensor. the object is kept at 10 - 15 cm. form the ultrasonic sensor but still the readings show 135 cm only

```
#include <Ultrasonic.h>
int trigPin = 5;
int echoPin = 6;
#include <Servo.h>   //servo library
Servo servo;
int servoPin = 7;
long duration, dist, average;
long aver[3];   //array for average

void setup() {
    Serial.begin(9600);
    servo.attach(servoPin);
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    servo.write(0);         //close cap on power on
    delay(100);
    servo.detach();
}

void measure() {
 digitalWrite(100,HIGH);
digitalWrite(trigPin, LOW);
delayMicroseconds(100);
digitalWrite(trigPin, HIGH);
delayMicroseconds(150);
digitalWrite(trigPin, LOW);
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
dist = (duration/2.0) / 29.1;    //obtain distance
}
void loop() {
  for (int i=0;i<=2;i++) {   //average distance
    measure();
   aver[i]=dist;
    delay(100);              //delay between measurements
  }
 dist=(aver[0]+aver[1]+aver[2])/3;

if ( dist<15 ) {
//Change distance as per your need
 servo.attach(servoPin);
  delay(1);
 servo.write(0);
 delay(2500);
 servo.write(100);
 delay(500);
 servo.detach();
}
Serial.print(dist);
}

```

---

```
#include <Ultrasonic.h>
int trigPin = 5;
int echoPin = 6;
#include <Servo.h>   //servo library
Servo servo;
int servoPin = 7;
long duration, dist, average;
long aver[3];   //array for average

void setup() {
    Serial.begin(9600);
    servo.attach(servoPin);
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    servo.write(0);         //close cap on power on
    delay(100);
    servo.detach();
}

void measure() {
    digitalWrite(100,HIGH);
    digitalWrite(trigPin, LOW);
    delayMicroseconds(100);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(150);
    digitalWrite(trigPin, LOW);
    pinMode(echoPin, INPUT);
    duration = pulseIn(echoPin, HIGH);
    dist = (duration/2.0) / 29.1;    //obtain distance
}

void loop() {
  for (int i=0;i<=2;i++) {   //average distance
    measure();
   aver[i]=dist;
    delay(100);              //delay between measurements
  }
  dist=(aver[0]+aver[1]+aver[2])/3;

  if ( dist<15 ) {
    //Change distance as per your need
    servo.attach(servoPin);
    delay(1);
    servo.write(0);
    delay(2500);
    servo.write(100);
    delay(500);
    servo.detach();
  }
  Serial.print(dist);
}

```

# Answer
> 1 votes
You have a lot of redundant code:

1. include Ultrasonic.h is unnecessary.
2. servo.attach and servo.detach without reusing pin is unnecessary
3. The ultrasonic code is not correct. It should be:

```
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // measure duration of pulse from ECHO pin
    duration_us = pulseIn(echoPin, HIGH);

    // calculate the distance
    distance_cm = 0.017 * duration_us;

```

Refer to the Ultrasonic sensor tutorial and Servo motor tutorial

---
Tags: arduino-uno
---


# Question
Title: PCINT0, PCINT1, PCINT2, etc. on ATtiny45/85
According to the datasheet:

we could think that, if we want to have a pin change interrupt for 3 pins, we have to create multiple instances:

```
ISR(PCINT0_vect){
   ...
}

ISR(PCINT1_vect){
   ...
}

ISR(PCINT2_vect){
   ...
}

void setup(){
  GIMSK = 0b00100000;
  PCMSK = 0b00000111;
}

```

However, this does not work, and I read here and here that we have to define **just one** interrupt function:

```
ISR(PCINT0_vect){
   if (digitalRead(0) == LOW)
     ...
   if (digitalRead(1) == LOW)
     ...
   if (digitalRead(2) == LOW)
     ...
}

```

Why is that so? What is `PCINT1, 2, 3`, ... made for then in this pinout schematics, if we don't have to use it?

# Answer
> 3 votes
You are confusing Pin Change Interrupt *pins* with Pin Change Interrupt *vectors*. The two are very different.

Many Pin Change Interrupt *pins* are associated with just one Pin Change Interrupt *vector*.

You use the *pin* number (the value shown in the pinout) to decide if you want that pin to respond or not. You use the *vector* to respond any of the pins that are assigned to that vector.

In the ATTiny chips, since there are so few Pin Change Interrupt *pins* (8 or less) you only need one Pin Change Interrupt *vector* to handle them.

You can know if "PCINT4" corresponds to a *pin* or a *vector* by the context. If you see it on a pin then it is a pin. If you see it in code with `_vect` after it then it's a vector.

# Answer
> 4 votes
That is simply the difference between an external interrupt INTx and a pin change interrupt PCINT. The first is an interrupt for a single pin. The second is an interrupt for a complete group of pins. Normally this group is a complete port. As the Attiny85 only has one port, this is the case here. So the whole group is only 1 single interrupt source. Thus it only has one interrupt vector named `PCINT0_vect`.

A pin change interrupt triggers, when any of the pins under it's supervision changes. You can remove pins from it's supervision by masking them with the `PCMSK` register.

So the interrupt vector `PCINT_vect` will be triggered by every change on any of the pins, that are not masked out. It is up to you to check, which one changed it's level.

---

On bigger microcontrollers, there are more pins and mostly also most of them are connected to a pin change interrupt. Here mostly every complete port is connected to a single pin change interrupt. Thus the corresponding registers are additionally marked with a number (`PCINT0_vect` as the interrupt vector for the first port, ...)

# Answer
> 1 votes
You can enable/disable Pin Change INTerrupts for individual pins using the Pin Change Mask Register `PCMSK`.

The names on the pins map the bit in `PCMSK` to the physical pin.

You find more information in section 9.3.4 on p. 52 in the ATtiny85 Data Sheet

---
Tags: interrupt, attiny
---


# Question
Title: Mega ADK connecting to PS3 Controller - OSC did not start error
I have a project that I am working on that uses a PS3 controller to connect to an Arduino Mega 2560 ADK (built-in USB). I have been trying to test the controller/arduino connection and I cannot get past the "OSC did not start" error via serial monitor.

I started a new thread because all of the threads I read were based on the Mega 2560 plus the USB shield, not the ADK. Theoretically, there should be no difference, but rather safe than sorry.

Here is my hardware: Arduino Mega 2560 ADK - Controller TrendNet TWB-106UB - USB dongle PS3 Move Navigation Controller (only 1)

Libraries: USB\_Host\_Shield USB\_Host\_Shield\_Library\_2.0

Sketch: https://gitlab.com/darren-blum/SHADOW

However, for the sake of testing, I have tried the straight example sketches from the USB Host libraries. I have tried the PS3USB and the PS3BT examples. It does not matter what sketch I try, I cannot get past the "OSC did not start".

The code that triggers this error is:

```
if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }

```

I am not sure what I am missing. Here is one of the example sketches in its entirety:

```
#include <PS3BT.h>
#include <usbhub.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

USB Usb;
//USBHub Hub1(&Usb); // Some dongles have a hub inside

BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
/* You can create the instance of the class in two ways */
PS3BT PS3(&Btd); // This will just create the instance
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57); // This will also     store the bluetooth address - this can be obtained from the dongle when running     the sketch

bool printTemperature, printAngle;

void setup() {
  Serial.begin(115200);
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}
void loop() {
  Usb.Task();

  if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
    if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
      Serial.print(F("\r\nLeftHatX: "));
      Serial.print(PS3.getAnalogHat(LeftHatX));
      Serial.print(F("\tLeftHatY: "));
      Serial.print(PS3.getAnalogHat(LeftHatY));
      if (PS3.PS3Connected) { // The Navigation controller only have one     joystick
        Serial.print(F("\tRightHatX: "));
        Serial.print(PS3.getAnalogHat(RightHatX));
        Serial.print(F("\tRightHatY: "));
        Serial.print(PS3.getAnalogHat(RightHatY));
      }
    }

    // Analog button values can be read from almost all buttons
    if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
      Serial.print(F("\r\nL2: "));
      Serial.print(PS3.getAnalogButton(L2));
      if (PS3.PS3Connected) {
        Serial.print(F("\tR2: "));
        Serial.print(PS3.getAnalogButton(R2));
      }
    }

    if (PS3.getButtonClick(PS)) {
      Serial.print(F("\r\nPS"));
      PS3.disconnect();
    }
    else {
      if (PS3.getButtonClick(TRIANGLE)) {
        Serial.print(F("\r\nTraingle"));
        PS3.setRumbleOn(RumbleLow);
      }
      if (PS3.getButtonClick(CIRCLE)) {
        Serial.print(F("\r\nCircle"));
        PS3.setRumbleOn(RumbleHigh);
      }
      if (PS3.getButtonClick(CROSS))
        Serial.print(F("\r\nCross"));
      if (PS3.getButtonClick(SQUARE))
        Serial.print(F("\r\nSquare"));

      if (PS3.getButtonClick(UP)) {
        Serial.print(F("\r\nUp"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED4);
        }
      }
      if (PS3.getButtonClick(RIGHT)) {
        Serial.print(F("\r\nRight"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED1);
        }
      }
      if (PS3.getButtonClick(DOWN)) {
        Serial.print(F("\r\nDown"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED2);
        }
      }
      if (PS3.getButtonClick(LEFT)) {
        Serial.print(F("\r\nLeft"));
    if (PS3.PS3Connected) {
      PS3.setLedOff();
      PS3.setLedOn(LED3);
    }
  }

  if (PS3.getButtonClick(L1))
    Serial.print(F("\r\nL1"));
  if (PS3.getButtonClick(L3))
    Serial.print(F("\r\nL3"));
  if (PS3.getButtonClick(R1))
    Serial.print(F("\r\nR1"));
  if (PS3.getButtonClick(R3))
    Serial.print(F("\r\nR3"));

  if (PS3.getButtonClick(SELECT)) {
    Serial.print(F("\r\nSelect - "));
    PS3.printStatusString();
  }
  if (PS3.getButtonClick(START)) {
    Serial.print(F("\r\nStart"));
    printAngle = !printAngle;
  }
}
#if 0 // Set this to 1 in order to see the angle of the controller
    if (printAngle) {
      Serial.print(F("\r\nPitch: "));
      Serial.print(PS3.getAngle(Pitch));
      Serial.print(F("\tRoll: "));
      Serial.print(PS3.getAngle(Roll));
    }
#endif
  }
#if 0 // Set this to 1 in order to enable support for the Playstation Move controller
  else if (PS3.PS3MoveConnected) {
    if (PS3.getAnalogButton(T)) {
      Serial.print(F("\r\nT: "));
      Serial.print(PS3.getAnalogButton(T));
    }
    if (PS3.getButtonClick(PS)) {
      Serial.print(F("\r\nPS"));
      PS3.disconnect();
    }
    else {
      if (PS3.getButtonClick(SELECT)) {
        Serial.print(F("\r\nSelect"));
        printTemperature = !printTemperature;
      }
      if (PS3.getButtonClick(START)) {
        Serial.print(F("\r\nStart"));
        printAngle = !printAngle;
      }
      if (PS3.getButtonClick(TRIANGLE)) {
        Serial.print(F("\r\nTriangle"));
        PS3.moveSetBulb(Red);
      }
      if (PS3.getButtonClick(CIRCLE)) {
        Serial.print(F("\r\nCircle"));
        PS3.moveSetBulb(Green);
      }
      if (PS3.getButtonClick(SQUARE)) {
        Serial.print(F("\r\nSquare"));
        PS3.moveSetBulb(Blue);
      }
      if (PS3.getButtonClick(CROSS)) {
        Serial.print(F("\r\nCross"));
        PS3.moveSetBulb(Yellow);
  }
  if (PS3.getButtonClick(MOVE)) {
    PS3.moveSetBulb(Off);
    Serial.print(F("\r\nMove"));
    Serial.print(F(" - "));
    PS3.printStatusString();
  }
}
if (printAngle) {
  Serial.print(F("\r\nPitch: "));
  Serial.print(PS3.getAngle(Pitch));
  Serial.print(F("\tRoll: "));
  Serial.print(PS3.getAngle(Roll));
}
else if (printTemperature) {
  Serial.print(F("\r\nTemperature: "));
  Serial.print(PS3.getTemperature());
}
  }
#endif
}

```

# Answer
Idiot me. I thought Mega 2560 = ADK. It does not. Once I corrected my board from the Mega 2560 to the ADK, the USB port worked.
> 1 votes

---
Tags: arduino-mega, usb
---


# Question
Title: Is it possible to run two small motors off an Arduino and have the motors move separately based on a random number generator?
I am a 2nd year design engineering student working on a design project where we are tasked with automating the movement of a rainfall simulator. One of our design ideas consists of two small motors running perpendicular to each other with the movements based on a random number generator. I was told that this would be fairly easy if we used a Siemens Program Logic Controller, but we have a very limited budget so I thought I would check out other options.

I am not familiar with the Arduino or much of anything to do with programming so I thought it would be beneficial to ask for advice from some people who know what they are doing. I attached an initial sketch of the idea and a picture of the rainfall simulator to hopefully clarify what I am hoping to accomplish. The most the device can move from its rested state is only 0.5".

Is this a path worth working towards? Or is this not the proper choice of equipment?

Any advice would be greatly appreciated!

Thanks,

Nick

# Answer
> 0 votes
Leaving your mechanical equipment uncommented \*), an Arduino itself cannot drive 7.4V 1A Stepper Motors. An Arduino itself cannot drive any motor. You need a sufficient power supply and motor driver electronics. And there's a vast amount of different devices to choose from.

But then, the answer to "is it possible (random, two motors, moving independently)" is **yes**.

\*) Well, regarding "uncommented" : 200 lbs is quite heavy to simulate/produce a few raindrops. Small motors won't move such gear as in your pic.

---
Tags: arduino-uno, programming
---


# Question
Title: Determine if Arduino is rapidly pulsed on and off several times
Greetings fellow humans!

I've set myself the task of ascertaining whether an Arduino has been rapidly power cycled to force it into a setup state, a feature common with many IoT devices. So I essentially need to keep a count - of, say, three - prior on/off cycles. I could look at a custom bootloader that stores a power-on count in EEPROM then check if the attempts are \>= 3 once the sketch is running (resetting the count), but I'm concerned that the EEPROM data could become corrupted during the cycle, or the the power cycle would be so rapid for even a bootloader to complete the count at all.

So, I figure I need another solution: an external counter, powered by the Arduino, that increments each time the Arduino receives power, but doesn't rely on the Arduino getting so far as running anything of consequence to keep count.

Could some kind soul point me in the direction of a discrete counter solution that would fit the task? The simpler (fewer discrete components) the better.

Thanks!

SOLVED: less-than-discrete but fully functional solution adopted; noted in comments. Thanks for the feedback.

# Answer
> 0 votes
Normally you wouldn't.

How I would implement it is:

1. Have the MCU monitor the incoming power
2. Provide a large-ish reservoir of power (capacitor) to run the MCU for a short time
3. Isolate the incoming power monitoring from the reservoir with a diode

When the power is removed the MCU runs off the stored power in the capacitor. The MCU then sees that the power is removed (by 1 above) and maybe reduces its power by turning off as much as it can to prolong the runtime. If the power is re-applied before the reservoir runs out then it enters the setup state. If the reservoir runs out, then not much really happens.

For example:

simulate this circuit – Schematic created using CircuitLab

The size of the capacitor will determine the runtime. You may also choose to replace the capacitor with an "LC PI" filter to give more runtime but at the cost of space:

simulate this circuit

---
Tags: power
---


# Question
Title: WS2812 Stair lighting - not all LEDS lighting up
I'm doing a Arduino based stair light project and have a little problem with the code. I have used Simon Jowett's code from the instructable website which after a couple of tweaks works perfect. Apart from the final section, the waterfall effect. The original project used 117 WS2812 LED's I'm using 188. When the white LED's trigger running up or down the stairs they work fine on all 188, the breathe LED's light up on the first and last LED too. But the waterfall effect stops at LED 117. Can anyone see if there is somewhere else that I need to change the amount of LED's in the code apart from here Adafruit\_NeoPixel strip = Adafruit\_NeoPixel(***188***, PIN, NEO\_GRB + NEO\_KHZ800);? Thanks

```
// "Bling" up your Staircase By Simon Jowett November 2014
// Thanks to the Neopxel Library by Adafruit

#include <Adafruit_NeoPixel.h>
//#define LDRSensor 1
#define PIN 3

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(188, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// Set up Variables
 unsigned long timeOut=60000; // timestamp to remember when the PIR was triggered.
 int downUp = 0;              // variable to rememer the direction of travel up or down the stairs
 int alarmPinTop = 5;        // PIR at the top of the stairs
 int alarmPinBottom =7;      // PIR at the bottom of the stairs
 int alarmValueTop = LOW;    // Variable to hold the PIR status
 int alarmValueBottom = LOW; // Variable to hold the PIR status
 int ledPin = 13;           // LED on the arduino board flashes when PIR activated
 int LDRSensor = A0;        // Light dependant resistor
 int LDRValue = 0;          // Variable to hold the LDR value
 int colourArray[350];      // An array to hold RGB values
 int change = 1;            // used in 'breathing' the LED's
 int breathe = 0;           // used in 'breathing' the LED's

void setup() {
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
   Serial.begin (9600);  // only requred for debugging
   pinMode(ledPin, OUTPUT);  // initilise the onboard pin 13 LED as an indicator
   pinMode(alarmPinTop, INPUT_PULLUP);     // for PIR at top of stairs initialise the input pin and use the internal restistor
   pinMode(alarmPinBottom, INPUT_PULLUP);  // for PIR at bottom of stairs initialise the input pin and use the internal restistor
   delay (100); // it takes the sensor 2 seconds to scan the area around it before it can
   //detect infrared presence.
   for (int i=0 ;i < 350; i++)  { // initilise the colourArray to zero
   colourArray[i]=0;
   }
}

void loop() {

  LDRValue = analogRead(LDRSensor);
  Serial.println(LDRValue);

  if (timeOut+57000 < millis()) {        // idle state - 'breathe' the top and bottom LED to show program is looping

     breathe = breathe + change;
     strip.setPixelColor(0,0,0,breathe);
     strip.setPixelColor(187,0,0,breathe);
     strip.show();
     if (breathe == 100 || breathe == 0) change = -change;      // breathe the LED from 0 = off to 100 = fairly bright
     if (breathe == 100 || breathe == 0) delay (300);           // Pause at beginning and end of each breath
     delay(25);
  }

  if (LDRValue > 1010) {        // only switch on LED's at night when LDR senses low light conditions - you may have to change the number for your circumstances!

    alarmValueTop = digitalRead(alarmPinTop);        // Constantly poll the PIR at the top of the stairs
    alarmValueBottom = digitalRead(alarmPinBottom);  // Constantly poll the PIR at the bottom of the stairs

    if (alarmValueTop == HIGH && downUp != 2)  {      // the 2nd term allows timeOut to be contantly reset if one lingers at the top of the stairs before decending but will not allow the bottom PIR to reset timeOut as you decend past it.
      timeOut=millis();  // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 1;
      topdown();         // lights up the strip from top down
    }

    if (alarmValueBottom == HIGH && downUp != 1)  {    // the 2nd term allows timeOut to be contantly reset if one lingers at the bottom of the stairs before decending but will not allow the top PIR to reset timeOut as you decend past it.
      timeOut=millis();    // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 2;
      bottomup();         // lights up the strip from bottom up
    }
    if (timeOut+10000 < millis() && timeOut+15000 < millis()) {    //switch off LED's in the direction of travel.
       if (downUp == 1) {
          colourWipeDown(strip.Color(0, 0, 0), 50); // Off
       }
       if (downUp == 2)  {
        colourWipeUp(strip.Color(0, 0, 0), 50);   // Off
       }
      downUp = 0;
      //   for (int i=0 ;i < 350; i++)  {          // Depending on your preference you may want to include this loop to clear out the colourArray
      //    colourArray[i]=0;
      // }
    }

    if (timeOut+15000 < millis() && timeOut+54999 > millis()) waterfall();    // Waterfall effect to play between these times after a PIR trigger.

    if (timeOut+55000 < millis() && timeOut+56999 > millis()) fade();   // Fade/switch off LED's
  }
}

 void topdown() {
    Serial.println ("detected top");                // Helpful debug message
    colourWipeDown(strip.Color(50, 50, 30), 10);    // Warm White
    for(int i=0; i<3; i++) {                        // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
 }

 void bottomup() {
    Serial.println ("detected bottom");          // Helpful debug message
    colourWipeUp(strip.Color(50, 50, 30), 10);   // Warm White
    for(int i=0; i<3; i++) {                     // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
  }

 // Fill the dots one after the other with a color
 void colourWipeDown(uint32_t c, uint8_t wait) {
   for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Fill the dots one after the other with a color
 void colourWipeUp(uint32_t c, uint8_t wait) {
   for(uint16_t i=strip.numPixels(); i < -1; i--) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Play the Waterfall effect
 void waterfall(){
    for(int i= 347; i>-1; i--) {            // Shift the RGB colours down in the colourArray[]
        colourArray[i+3]=colourArray[i];
        }
      colourArray[0] = random(0,20);        // Genearate the red component of the 1st LED at the top of the stairs
      colourArray[1] = random(0,40);        // Genearate the green component of the 1st LED at the top of the stairs
      colourArray[2] = random(10,70);       // Genearate the blue component of the 1st LED at the top of the stairs

      for (int k=0; k<351; k=k+3)   {       // Set and send the colours to the strip
       uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
       strip.setPixelColor(((k+3)/3)-1,c);
       }

      strip.show();      // and display the result
      delay(35);         // delay to simulate running water
 }

 // Play the LED fade out
 void fade(){
 for (int j = 0; j <70; j++) {
   for(int i=350; i>-1; i--) {
     colourArray[i]=colourArray[i]-1;      // reduce intensity of light by 1
     if (colourArray[i] <= 0 ) colourArray[i] = 0;
   }
   for (int k=0; k<351; k=k+3)   {
     uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
     strip.setPixelColor(((k+3)/3)-1,c);
   }
  strip.show();
  delay(60);
  }
 breathe = 0;
 change = 1;
 }

```

# Answer
This line in the code:

```
 int colourArray[350];      // An array to hold RGB values

```

...contains 3 values for each LED. But 350 / 3 is 116.67. This value should likely have been 117 * 3 = 351 for the original code. And for the posted code using 188 LEDs this likely should be 188 * 3 = 546.

This same problem of indexing into the colourArray repeats several more times in the code where the array is cleared out, assigned random values and used to control the LEDs. Normally, well written code uses "#define" directive to set such values once at the beginning of the code allowing the compiler to make adjustments when compiling / uploading the Arduino sketch.

The "#define" used for Arduino sketches is the same as used in C programming. (As Arduino sketches are actually C programs.) Normally, defines are found at the top of a file. Defines are a way of substituting an meaningful name for something a bit hard to understand at first. We can even use a bit of math to keep errors down as the compiler will solve it for us before uploading the code:

```
#define LED_NUMBER_OF (3*188)

```

Later in the code we can use the define:

```
int colourArray[LED_NUMBER_OF];      // An array to hold RGB values

```

Still later in the code we can use the define again:

```
for (int i=0 ;i < LED_NUMBER_OF; i++)  { // initilise the colourArray to zero
  colourArray[i]=0;
}

```
> 1 votes

# Answer
I've just tried the edited code but now the LED's won't work at all?? I'm sure its something I've done wrong.

```
#include <Adafruit_NeoPixel.h>

#define PIN 3

#define LED_NUMBER_OF (3*188)

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(188, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// Set up Variables
 unsigned long timeOut=60000; // timestamp to remember when the PIR was triggered.
 int downUp = 0;              // variable to rememer the direction of travel up or down the stairs
 int alarmPinTop = 5;        // PIR at the top of the stairs
 int alarmPinBottom =7;      // PIR at the bottom of the stairs
 int alarmValueTop = LOW;    // Variable to hold the PIR status
 int alarmValueBottom = LOW; // Variable to hold the PIR status
 int ledPin = 13;           // LED on the arduino board flashes when PIR activated
 int LDRSensor = A0;        // Light dependant resistor
 int LDRValue = 0;          // Variable to hold the LDR value
 int colourArray[LED_NUMBER_OF];      // An array to hold RGB values
 int change = 1;            // used in 'breathing' the LED's
 int breathe = 0;           // used in 'breathing' the LED's

void setup() {
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
   Serial.begin (9600);  // only requred for debugging
   pinMode(ledPin, OUTPUT);  // initilise the onboard pin 13 LED as an indicator
   pinMode(alarmPinTop, INPUT_PULLUP);     // for PIR at top of stairs initialise the input pin and use the internal restistor
   pinMode(alarmPinBottom, INPUT_PULLUP);  // for PIR at bottom of stairs initialise the input pin and use the internal restistor
   delay (100); // it takes the sensor 2 seconds to scan the area around it before it can
   //detect infrared presence.
   for (int i=0 ;i < LED_NUMBER_OF; i++)  { // initilise the colourArray to zero
   colourArray[i]=0;
   }
}

void loop() {

  LDRValue = analogRead(LDRSensor);
  Serial.println(LDRValue);

  if (timeOut+57000 < millis()) {        // idle state - 'breathe' the top and bottom LED to show program is looping

     breathe = breathe + change;
     strip.setPixelColor(0,0,0,breathe);
     strip.setPixelColor(187,0,0,breathe);
     strip.show();
     if (breathe == 100 || breathe == 0) change = -change;      // breathe the LED from 0 = off to 100 = fairly bright
     if (breathe == 100 || breathe == 0) delay (300);           // Pause at beginning and end of each breath
     delay(25);
  }

  if (LDRValue > 1010) {        // only switch on LED's at night when LDR senses low light conditions - you may have to change the number for your circumstances!

    alarmValueTop = digitalRead(alarmPinTop);        // Constantly poll the PIR at the top of the stairs
    alarmValueBottom = digitalRead(alarmPinBottom);  // Constantly poll the PIR at the bottom of the stairs

    if (alarmValueTop == HIGH && downUp != 2)  {      // the 2nd term allows timeOut to be contantly reset if one lingers at the top of the stairs before decending but will not allow the bottom PIR to reset timeOut as you decend past it.
      timeOut=millis();  // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 1;
      topdown();         // lights up the strip from top down
    }

    if (alarmValueBottom == HIGH && downUp != 1)  {    // the 2nd term allows timeOut to be contantly reset if one lingers at the bottom of the stairs before decending but will not allow the top PIR to reset timeOut as you decend past it.
      timeOut=millis();    // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 2;
      bottomup();         // lights up the strip from bottom up
    }
    if (timeOut+10000 < millis() && timeOut+15000 < millis()) {    //switch off LED's in the direction of travel.
       if (downUp == 1) {
          colourWipeDown(strip.Color(0, 0, 0), 50); // Off
       }
       if (downUp == 2)  {
        colourWipeUp(strip.Color(0, 0, 0), 50);   // Off
       }
      downUp = 0;
      //   for (int i=0 ;i < 350; i++)  {          // Depending on your preference you may want to include this loop to clear out the colourArray
      //    colourArray[i]=0;
      // }
    }

    if (timeOut+15000 < millis() && timeOut+54999 > millis()) waterfall();    // Waterfall effect to play between these times after a PIR trigger.

    if (timeOut+55000 < millis() && timeOut+56999 > millis()) fade();   // Fade/switch off LED's
  }
}

 void topdown() {
    Serial.println ("detected top");                // Helpful debug message
    colourWipeDown(strip.Color(50, 50, 30), 10);    // Warm White
    for(int i=0; i<3; i++) {                        // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
 }

 void bottomup() {
    Serial.println ("detected bottom");          // Helpful debug message
    colourWipeUp(strip.Color(50, 50, 30), 10);   // Warm White
    for(int i=0; i<3; i++) {                     // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
  }

 // Fill the dots one after the other with a color
 void colourWipeDown(uint32_t c, uint8_t wait) {
   for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Fill the dots one after the other with a color
 void colourWipeUp(uint32_t c, uint8_t wait) {
   for(uint16_t i=strip.numPixels(); i < -1; i--) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Play the Waterfall effect
 void waterfall(){
    for(int i= 350; i>-1; i--) {            // Shift the RGB colours down in the colourArray[]
        colourArray[i+3]=colourArray[i];
        }
      colourArray[0] = random(0,20);        // Genearate the red component of the 1st LED at the top of the stairs
      colourArray[1] = random(0,40);        // Genearate the green component of the 1st LED at the top of the stairs
      colourArray[2] = random(10,70);       // Genearate the blue component of the 1st LED at the top of the stairs

      for (int k=0; k<350; k=k+3)   {       // Set and send the colours to the strip
       uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
       strip.setPixelColor(((k+3)/3)-1,c);
       }

      strip.show();      // and display the result
      delay(35);         // delay to simulate running water
 }

 // Play the LED fade out
 void fade(){
 for (int j = 0; j <70; j++) {
   for(int i=350; i>-1; i--) {
     colourArray[i]=colourArray[i]-1;      // reduce intensity of light by 1
     if (colourArray[i] <= 0 ) colourArray[i] = 0;
   }
   for (int k=0; k<351; k=k+3)   {
     uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
     strip.setPixelColor(((k+3)/3)-1,c);
   }
  strip.show();
  delay(60);
  }
 breathe = 0;
 change = 1;
 }
~~~~~~

```
> 0 votes

---
Tags: programming
---


# Question
Title: Need function to convert bool array to int- why doesnt this work?
Hey I wrote this function to convert an bool array to int: (Math Lob included):

```
bool b_array[5];

int convertToInt(start_index,stop_index){
    int run=0;
    int result=0;
    for(int id=start_index;id<=stop_index;id++){
        result+=b_array[id] * pow(2.0,run);
        run++;
    }
    return result;
}

```

but it doesnt this work?

Thanks and kind regards Nic

# Answer
Assuming little-endian bools (least significant bool first), you should use simple bit-shifting, not floating point power calculations:

```
for(int id=start_index;id<=stop_index;id++){
    result |= b_array[id] ? (1 << run) : 0;
    run++;
}

```

The *ternary* operation (`b_array[id] ? (1 << run) : 0`) means:

* If `b_array[id]` is true, then
    + Or `result` with 1 left-shifted `run` times and store in `result`
* otherwise
    + Or `result` with 0 and store the result (no-operation).
> 2 votes

---
Tags: convert
---


# Question
Title: Disable interrupts when doing critical things?
I've got a few functions like this that log, or do more critical things like get/save configuration variables.

```
/**
   Write weather data to csv
   commit: datetime,minHumidity,maxHumidity,minTemperature,maxTemperature,rainfall,irrigationRan
*/
void writeWeatherData() {
  noInterrupts();
  DBG_OUTPUT.println(F("[WEATHER DATA] Attempting to save weather data..."));
  bool writeHeader = SPIFFS.exists("/weather_data.csv") ? false : true;
  File file = SPIFFS.open("/weather_data.csv", "a");
  if (!file) {
    addPrintError("[WEATHER DATA] There was an error opening weather_data.csv for writing.");
    interrupts();
    return;
  }
  String data = "";
  if (writeHeader) {
    data += "datetime,minHumidity,maxHumidity,minTemperature,maxTemperature,rainfall,irrigationRan\r\n";
  }
  DateTime now = rtc.now();
  char buf[] = "MM/DD/YY hh:mm:ss";
  String t = now.toString(buf);
  float rainfall = getRainfall();
  data += t + "," + minHumidity + "," + maxHumidity + "," + minTemperature + "," + maxTemperature + "," + rainfall + "," + irrigationRan + "\r\n";
  if (file.print(data)) {
    DBG_OUTPUT.println(F("[WEATHER DATA] File was written."));
  } else {
    addPrintError("[WEATHER DATA] File write failed.");
  }
  file.close();
  DBG_OUTPUT.println(F("[WEATHER DATA] Task completed."));
  interrupts();
}

```

I surround code with `noInterrupts` and `interrupts` however I am not sure if it is required. Assume that an interrupt is triggered at the exact moment when the above function is saving something, what exactly happens if I didn't have `noInterrupts` .etc.?

# Answer
> 3 votes
Interrupts happen all the time and code works just fine without locking them out. It doesn't matter if it's at the exact moment that a function is saving something - a properly written interrupt handler will save any necessary state so that whatever was interrupted can continue without problems. If it doesn't, the software will crash hard.

You should lock out interrupts as little as possible. Interrupts are used for critical timing functions and for network and other communications. Locking them out will cause these functions to be unreliable and may disrupt network connections.

The only time you should disable interrupts is when a data structure that an interrupt handler needs to use is in an inconsistent state. If an interrupt handler needs to use a shared data structure, disable interrupts before beginning to modify it outside of the interrupt handler, and re-enable them when you're done. Make sure it's as brief as possible.

Interrupt handlers should do as little as possible. They definitely should not call SPIFFS, should not call the real time clock, should not allocate or instantiate objects and should not do i/o operations. And you should not be disabling interrupts around calls to SPIFFS in hopes of making it safe for your interrupt handler to also call SPIFFS.

Take this as an example: suppose you want to use SPIFFS in both an interrupt handler and outside the interrupt handler. So you think you'll be clever and disable interrupts before you call SPIFFS outside the interrupt handler. Do you know exactly how SPIFFS works? Do you know whether SPIFFS uses any other functions that you might need to disable interrupts for in other parts of your code so that the interrupt handler won't disrupt them? Do you know for certain that SPIFFS doesn't allocate memory temporarily? Imagine that it does - now you also need to find every place in your code that might allocate memory and lock out interrupts around it, too. And maybe SPIFFS doesn't allocate memory - but do you know that SPIFFS in the future will never allocate memory?

You can't make assumptions about exactly how modules that you call are implemented, or how they'll be implemented in the future.

Unless you seriously know what you're doing, on microcontrollers like Arduinos, the ESP8266 and the ESP32, the best thing an interrupt handler can do is just set a flag to indicate that the interrupt occurred, and let code in the `loop()` check for the flag. The flag should most likely just be a simple Boolean variable declared as volatile so that the C compiler is aware that its value may suddenly change:

```
volatile boolean interrupt_flag = false;

```

It's safe to set that `interrupt_flag` to `true` inside the interrupt handler and it's safe to check the value in `loop()`, reset it to `false` and do whatever work was needed. Don't do more than this unless you know what you're doing.

# Answer
> 2 votes
John Romkey provided you an *excellent* answer. I am adding this just to provide another perspective, hopefully complementary.

Interrupts are meant to handle the most time-critical tasks. Those tasks that cannot wait for the next `loop()` iteration, such as counting a pulse from an encoder, or getting a byte out of the UART receive buffer. If you delay them too much, they may miss their deadline, resulting in unreliable operation of the whole program (counter missing pulses, UART missing bytes...).

Sometimes you have a piece of code that cannot afford being interrupted. Maybe it is extremely time-critical, like the generation in software of a pulse that is exactly 0.5 µs wide. More commonly it will be reading data from memory that is being modified by an interrupt handler, and you don't want that data to be modified in the middle of the read operation. Such pieces of code are called *critical sections*, and you keep them safe in between `noInterrupts()` and `interrupts()`. If an interrupt request fires while the program is running a critical section, the request is put on hold and serviced only when the critical section is done. This adds some **latency** to the interrupt which, if excessive, can lead to the interrupt missing its deadline. This is the reason critical sections should be kept as short as possible.

You have been told that interrupt handlers should be kept as short as possible, but I am not sure you know *why* it is so. The fundamental reason is that *interrupt handlers are themselves critical sections*. While a handler is running, other interrupts are blocked. On some architectures (notably *not* AVR, I don't know about the ESP), only interrupts of lower priority are blocked, but it is still an issue. The rationale for keeping those handlers short applies equally to *any* critical section.

Now, just to provide an example of the sort of bad things that can happen if you block interrupts unnecessarily, consider this piece of code:

```
noInterrupts();
Serial.println("Inside critical section.");
interrupts();

```

What this does is put the string `"Inside critical section."` in a software buffer. Not a huge task you may say. Actually pushing the bytes out to the UART is the job of an interrupt handler, triggered by the UART when it is ready to accept a new byte. But then what happens if there is not enough free space in the buffer for the string? In this case, `Serial.println()` waits in a busy loop. It waits for the interrupt to move bytes out of the buffer and make space for the new string. But wait, we have just disabled interrupts... See the problem? This is the reason it is generally advised to never `Serial.print()` inside an interrupt handler. The same applies to any critical section.

**Edit**: As Juraj points out in a comment, the `HardwareSerial` code now implements a workaround against this problem: if it detects it has to wait with interrupts disabled, it takes care of calling the interrupt handler itself. This is a (relatively) late addition to the `HardwareSerial` code. Their authors presumably witnessed too many beginners doing debug prints from interrupt handlers and being bitten by this issue. Note that it is a workaround, not a solution: it will often make the critical section last for an unreasonably long time.

I wouldn't rely on similar APIs, or even on other cores, systematically implementing this kind of safeguards though: some library authors just trust the user to not do silly things.

---
Tags: esp8266, interrupt
---


# Question
Title: What pins can be used for chip select (CS, CC) on the Arduino nano every?
I’ve checked the nano’s tech specs but I can’t seem to find any information regarding it. I’ve tried setting it to pin 26 (digital output)

# Answer
> 2 votes
The following answer assumes the Arduino is the master.

You can use any pin for that (at least any GPIO pin).

Multiple SPI devices can be connected to a SPI peripheral on an Arduino (in principle).

Every SPI device should have their own CS/CC pin, and is mandatory when you use multiple SPI devices.

For this reason, there is no single pin the SPI can define for being used as CS/CC pin. However, it should give a GND or VCC value, thus a CS/CC pin should typically be configured as a digital input pin (as master) for each slave. (See remark of KIIV too); as slave the CS/CC pin should be a digital output pin.

For the other pins (MOSI, MISO, CLK), the Arduino uses a fixed set of pins because all SPI devices will be connected to these pins.

So the CS pin is configurable, and the other spi pins are fixed.

---
Tags: arduino-nano, spi, sd-card
---


# Question
Title: integer overflow in expression [-Woverflow] - TinyCircuit
I have a tiny circuit Bluetooth shield and I was testing out the sample code that was provided by tinycircuit. However, when I tried uploading the sample code into the board, I kept having the following error. How can I solve this error?

this is the piece of code where there error seems to be happening.

```
#define  ADV_INTERVAL_MIN_MS  50
#define  ADV_INTERVAL_MAX_MS  100

void setConnectable(void)
{
  tBleStatus ret;

  const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME, 'B', 'l', 'u', 'e', 'N', 'R', 'G'};

  hci_le_set_scan_resp_data(0, NULL);
  PRINTF("General Discoverable Mode.\n");

  ret = aci_gap_set_discoverable(ADV_IND,
                                 (ADV_INTERVAL_MIN_MS * 1000) / 625, (ADV_INTERVAL_MAX_MS * 1000) / 625,
                                 STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
                                 sizeof(local_name), local_name, 0, NULL, 0, 0);

  if (ret != BLE_STATUS_SUCCESS)
    PRINTF("%d\n", (uint8_t)ret);

}

```

# Answer
> 1 votes
You can specify the type of a number using suffixes such as `L`, `LL`, `UL` and such. If you don't specify the type this way, all integers that are small enough to fit in an `int` will be of type `int`. When you write

```
ADV_INTERVAL_MIN_MS * 1000

```

it gets expanded by the preprocessor to

```
50 * 1000

```

Since both arguments are of type `int`, the compiler will use this type to compute the result. However, the result is 50,000, and on 16-bit systems the largest number that can fit in an `int` is 32,767, thus the overflow.

As suggested by Majenko, the simple solution is to add the `L` suffix (for `long`) to either operand. The compiler will then do the arithmetics using the `long` data type.

---
Tags: bluetooth
---


title: DFPlayer for Writing to SD Card

text:
# Question
Title: DFPlayer for Writing to SD Card
Can you use the DFPlayer to write to the SD card? Link for DFPlayer: https://www.dfrobot.com/wiki/index.php/DFPlayer\_Mini\_SKU:DFR0299

Here's the goal of my project. I have a button that, when pressed, should a- play a song off an SD card that is hooked up to the DFPlayer and b- should log "button is pressed" to the SD card. Unfortunately, the DFPlayer library doesn't seem to have any functions for this, and I wasn't sure how to see whether the DFPlayer has the functionality to support writing onto an SD card. Are there modules that are Read-only for SD cards? If so, is the DFPlayer one of them?

PS - I'm using an Arduino Uno, Thank you so much for your help! I am a complete novice for SD cards, so any help you give would be very much appreciated!

# Answer
Unfortunately the DFPlayer cant write that data to the SD card. The Arduino has some non volatile memory of its own built in though. Theres 1K of EEPROM for the UNO. Notes on how to use it here: https://www.arduino.cc/en/Reference/EEPROM If you can get what you need to done in 1K and its not important to your project that you be able to unplug the SD card and put it in another reader, then perhaps thats a nice, simple solution...
> 2 votes

---
Tags: arduino-uno, library, sd-card, audio, sd
---


# Question
Title: Arduino Mega resets when DFPlayer speaker plugged into amp!
I have a MP3 DFPlayer Mini connected to a Mega2560. I'm using serial to control it. The Mega is powering/grounding the DFPlayer, and USB is powering the Mega. If I plug a small speaker directly to the DFPlayer speaker pins, I hear the audio as expected. Tracks play correctly, at the proper volume, etc.

I also have a 20w audio amplifier (MAX9744, and 20w speaker ofc), powered separately by a 12v DC wall plug. If I plug an iPod into that via the stereo jack, I hear nice loud audio, as expected. Everything is fine.

For months, I have had the DFPlayer speaker pins supplying audio into the headphone jack on the amplifier. It has been working perfectly. Until recently...

Now, for some reason, the Mega2560 instantly resets, and will continue to reset every couple of seconds *while the speakers are plugged in to the amplifier*. As soon as the line in stereo jack is removed from the amplifier, the Mega works again.

This has me completely stumped. This setup has previously been working perfectly, for several months. The amplifier is clearly affecting the Mega somehow (via the DFPlayer!), even when no audio is actively playing. But I'm stuffed if I can figure out where the problem is!

I appreciate any ideas and suggestions you may have.

# Answer
> 2 votes
For externally amplified speakers, you should be feeding the DAC and GND pins to the amp's inputs. Those DAC pins provide a signal that varies by a small number of volts and is shifted so that they're always positive. This is in the range expected by small headphones (ear buds) and line level inputs to audio components like an amplifier.

The speaker pins on the DF Player mini are pre-amplified (a little tiny bit) to directly drive a very small speaker (like 2 Watts at 8 Ohms). They are a differential signal that includes both positive and negative voltages (relative to GND). Note that the two speaker outputs (SPK+ and SPK-) are not left and right, but two sides of a differential signal. Based on the schematic on page 11 of the datasheet (Chinese), it's a mono output made from mixing the outputs of the left and right DACs.

I could see how you might have gotten away with sending those to the amp, since the pre-amped speaker outputs are low power, and a good amp probably has input protection.

I don't know enough about electronics to know why it's failing now when it seemed to be working before. It could be sensitive to the amplifier's gain or a ground loop between the power sources, but I'm just shooting in the dark. Somehow, I suspect the DF Player Mini struggled to provide enough current to your amp, and since the DF Player Mini was powered from your Arduino, the Arduino essentially browned out, triggering a reset.

# Answer
> 0 votes
As Adrian McCarthy pointed out, you don't want to be running the speaker outputs into an amp like that. Use a DAC pin and Ground. As to why its stopped working - I've had trouble powering an arduino plus dfplayer from USB. The combination can quite easily draw more current than USB is designed to give. It's a bit fuzzy because not all USB supplies work exactly to proper spec. and exactly how much current you need can depend on factors as unpredictable as how much bass there is in your piece of music. If definitely nothing at all has changed in your setup, I would check in case you've got a joint going bad and shorting in the connection from the dfplayer to the amp...

---
Tags: arduino-mega
---


# Question
Title: DFPlayer Noise: Researched, Tried, and Bep Bep Bep Bep Bep
Spent an entire day researching and attempting to fix the DFPlayer noise problem. The amp works as expected, so it is not the problem. I have made a video to help you better understand the sound produced: https://www.youtube.com/watch?v=uK2kkR0XjFs&feature=youtu.be

This is the amp/speaker used: https://sites.google.com/site/wayneholder/chiptunes

The amp with speaker works as expected using another similar mp3 player like from a computer or possibly a phone.

Here we get the bep bep bep bep bep... as the amp/speaker has its own battery power.

Here I made everything as one power source. Bep bep bep bep bep...

I think I exhausted my research and made the following attempts:

```
> -Electrolytic Capacitor at the power terminals
> -Electrolytic Capacitor parallel with ceramic capacitor from negative terminal to VCC in DFPlayer
> -Diode from positive terminal to VCC in DFPlayer
> -Battery Power source; USB power source; Power Supply power source; 5V USB plug regulator power source
> -1k Resistor from TX RX; Rx Tx
> -1-10k resistor from Rx Tx
> -1k between channel to GND
> -Separate power source for each the Arduino, amp, and DFPlayer
> -Tried multiple DFPlayers

```

Keep note that the amp/speaker works well. The files are the same both on the computer and in the SD card.

Here is my code:

```
#include <DFRobotDFPlayerMini.h>

/***************************************************
DFPlayer - A Mini MP3 Player For Arduino
 <https://www.dfrobot.com/index.php?route=product/product&product_id=1121>

 ***************************************************
 This example shows the basic function of library for DFPlayer.

 Created 2016-12-07
 By [Angelo qiao](Angelo.qiao@dfrobot.com)

 GNU Lesser General Public License.
 See <http://www.gnu.org/licenses/> for details.
 All above must be included in any redistribution
 ****************************************************/

/***********Notice and Trouble shooting***************
 1.Connection and Diagram can be found here
 <https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299#Connection_Diagram>
 2.This code is tested on Arduino Uno, Leonardo, Mega boards.
 ****************************************************/

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
int counter = 0;
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

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

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(15);  //Set volume value. From 0 to 30
  delay(1000);
myDFPlayer.enableDAC();  //Enable On-chip DAC
}

void loop()
{
  static unsigned long timer = millis();
  if(millis() - timer > 1000 && counter == 0)
  {
   myDFPlayer.play(1);
   Serial.println(F("Music Started"));
   delay(1000);
   Serial.println(F("1 second later..."));
   delay(6000);
   Serial.println(F("7 seconds later..."));
   delay(1000);
   counter =1;
  }

delay(7000);

  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
  }
}

void printDetail(uint8_t type, int value){
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

```

# Answer
The "bep bep bep" you are hearing is power supply noise introduced by the SD card. Every time the SD card reads the power supply dips and the ground raises. This is because these boards have really terrible grounding in their design. There is no coherent ground plane, and the analog audio sections and noisy digital sections both share the same ground with no isolation or filtering between them.

To reduce the impedance of the ground plane you must connect both the GND pins together, and do it with a short wire. Better would be to modify the board itself and solder a wire directly between the two ground pins.

There are also strategic ground points around the place you could also solder directly to one of those ground pins - such as the ground side of the SD card's decoupling capacitors, and the GND pin of the SD card itself (if your soldering skills are up to it - those pins are pretty fine pitch).

The whole issue stems from trying to fit too much into too small a space. The board really should have been made as a 4-layer board with a (near) solid ground and power plane to reduce the power impedance. Better decoupling and filtering on the SD card's power pin (such as a "PI" filter with two capacitors and a ferrite bead, or two capacitors and a small resistor) would have been a big benefit as well.
> 2 votes

# Answer
Thanks for all the investigative work.

Throwing in my 2 cents :

I was also experiencing random cutoffs and wierd noises. I was using the Servo class in combination with the DFPlayer on an Arduino UNO board. It turns our that the Servo class uses the timers that are related to pin 9 and 10. When attaching a servo, signals will be outputted on those ports. So don't hook up your DFPlayer or anything else on those ports. Probably because the Servo class was sending all kinds of data over the serial connection to the DFPlayer, the module would stop playing and start making a lot of random noise for the remaining duration of the mp3.

Other things that I came across and might help other people : The DFPlayer needs MP3's of a certain length. MP3's of just 1~2 seconds don't play. +5 seconds seems to be fine. Any fancy MP3 encoding also prevents the MP3s from playing. The led will light up but no sound will be outputted.

Depending on the library used for the DFPlayer, the filenames and folder names do matter. The mp3's have to be in the MP3 folder and be named like 0001.mp3, 0002.mp3

According to 1 of the many datasheets out there, the DFPlayer requires 3.3v levels for the RX and TX port, regardless of the operating voltage. So do put those 1K resistors there. It won't hurt the module.

Motors and servo's do cause a lot of noise on the power source if you run the board off the 5v USB port. Even small motors can generate spikes of +2A when turned on.

Signals from other cables and devices can also interfere with the serial connection so ideally use shielded wires for the TX/RX cables.

According to the SD card specs of some manufacturers, power usage for an SD card can go up to 100mA. The module itself can produce 3W output so that would also add up to 600mA @ 5V. And add something like 150mA for the microcontroller onboard. So even a standard 5v@500mA USB port won't have enough power to drive just the Arduino and DFPlayer in some cases.

Someone took a look at the clicks and plops on pause or power on/off : http://work-now-dammit.blogspot.com/2016/08/dfplayer-mp3-module-power-onoff-clicks.html Remove the 0-ohm resistor next to the 8002 amp. Connect pin 1 of the 8002 amp to the BUSY pin (16) of the module.
> 2 votes

# Answer
I found that noise was due to three issues,

* Forgetting to ground BOTH GND pins on the DFPlayer chip
* Forgetting to put 1k resistors in the Tx and Rx lines
* Power fluctuations

**Power is the big issue**. When I powered my Arduino with a 9v 2A supply all the noise went away. Switching to USB power (5v) caused the noise to return.
> 1 votes

# Answer
**My Problem & Solution:** I recently attempted to control the DFPlayer with an Arduino Pro Mini and also experienced loud pulsing noises during playback (along with the music file). The pulsing could be seen on a scope on one of the speaker leads. Unloading the speaker did not help, using different power supplies did not help. Also, with regard to tying the two DFPlayer GND pins together, that's not necessary on my board since they are already connected together via the metal shell of the micro SD connector.

However, I noticed that when I attempted to re-program the Mini (or even when I pressed the reset button), there was a short period of time when the pulsing stopped and the music file played as it should. In my case the problem was the data line from the Mini to the Rx pin on the DFPlayer (there was no connection to the Tx pin). I verified this by starting playback (with the pulsing noise) and then disconnecting the Rx connection. That stopped the pulsing and the music file played as expected.

The software solution was to force the transmit pin on the Mini (I'm using soft serial) to a LOW state immediately after sending the Play command. Works fine now.

Update: I had previously connected the Mini serial output directly to the DFPlayer Rx pin without a 1K limiting resistor. Now, with the resistor in place I no longer get the pulsing noise during playback and there is no longer a need to pull the control line low.
> 1 votes

# Answer
I had the same problem. It was solved with a separate power supply to the DFPlayer. I also grounded both sides of the player but that alone was insufficient.
> 0 votes

# Answer
I've had loads of crazy little issues like this with the dfplayer and tried lots of solutions with very inconsistent results. Sometimes a technique like extra grounding or a resistor to the tx/rx pins will work the magic and then on making another copy of the circuit, the problem is inexplicably back! Here's a important clue that I haven't seen anywhere on forums yet, so I wanted to add it into the mix. Though the dfplayer is claimed to work from 3.3V to 5V, I've found it is *much* better behaved at 3.3V! Running it at 5V gives me odd noise and stability problems that vanish at 3.3V. You can get very cheap and efficient 3.3V regulators that are no bother to use. Try running it at the lower voltage and see if those issues clear up!
> 0 votes

---
Tags: audio
---


# Question
Title: ESP8266 stops working when I use 2x static const char(PROGMEM)
\*Sdk version: 2.2.2-dev(5ab15d1) \*Core Version: 2\_6\_1

This is the error returned:

```
Exception 3: LoadStoreError: Processor internal physical address or data error during load or store PC: 0x4000bf64 EXCVADDR: 0x4024e963
Decoding stack results
0x4020175d: HTML1(String) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266/WString.h line 128
0x40238c26: umm_info(void*, int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc/umm_info.c line 164
0x40100278: millis() at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_wiring.cpp line 188
0x40238c26: umm_info(void*, int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc/umm_info.c line 164
0x4020af74: String::copy(char const*, unsigned int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\WString.cpp line 214
0x40201a3c:

```

Code:

```
static const char HTML1[] PROGMEM = R"=====(
<!DOCTYPE HTML><html><head>
<meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
)=====";

static const char HTML2[] PROGMEM = R"=====(
<button type='button' onclick='sendData(2)'>Test2</button>
)=====";

String html_return = HTML1;
html_return += "<button type='button' onclick='sendData(1)'>Test</button>";
Serial.println("Before Second Const Char");
html_return += HTML2; //<< ESP stops working here

```

# Answer
See Guide to PROGMEM on ESP8266 and Arduino IDE.

Since you put your char array into `PROGMEM`, special functions must be used to load it from flash into RAM; so to load it into a `String` object, the `FlashHelper` class must be used. You can simply use the macro `FPSTR(progmem_ptr)`.

```
#include <Arduino.h>

void setup() {
    Serial.begin(115200);
    Serial.println("\nStart firmware");

    static const char HTML1[] PROGMEM = R"=====(
    <!DOCTYPE HTML><html><head>
    <meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
    )=====";

    static const char HTML2[] PROGMEM = R"=====(
    <button type='button' onclick='sendData(2)'>Test2</button>
    )=====";

    String html_return = HTML1;
    html_return += "<button type='button' onclick='sendData(1)'>Test</button>";
    Serial.println("Before Second Const Char");
    //html_return += HTML2; //crashes
    html_return += FPSTR(HTML2); //works
    Serial.println("Result");
    Serial.println(html_return);
}

void loop() {

}

```

Outputs

```
Start firmware
Before Second Const Char
Result

        <!DOCTYPE HTML><html><head>
        <meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
        <button type='button' onclick='sendData(1)'>Test</button>
        <button type='button' onclick='sendData(2)'>Test2</button>

```
> 1 votes

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


# Question
Title: Connecting Bluetooth module to Arduino Uno without RX/TX pins
Can I connect a Bluetooth module to usual digital pins, other than D0/D1 (RX/TX) pins as the shield is already using the D0 and D1 pins?

My Bluetooth module is an HC-05 MODULE.

# Answer
> 1 votes
Classic Arduinos use pins 0 and 1 for serial communication to the host computer, so it is problematic to connect a bluetooth module there anyway - it can be done, but basically means that programming the board and communicating with it by serial will not work (at least not reliably) until the interfering bluetooth module is removed or disabled. For these boards you need to use a software serial instance to talk to the module, and you can put it on most any digital pins.

ATmega32u4 boards like the Leonardo do not have debug/programming on pins 0 and 1 but do have a hardware UART there, so those would be the best choice for a bluetooth module, but you can still use software serial.

The Arduino Mega has additional hardware serial pins that would be good choices, but you can use software serial.

Various ARM based boards with Arduino ports typically have additional hardware serial pins which you should use. Software serial may or may not be an option on these (it's not that an implementation cannot exist, but that software serial is generally disadvantageous, so when a chip has more hardware UARTs that particular function may not be ported).

# Answer
> 1 votes
you can define pin and can use after defining int RX=any pin TX=any pin

---
Tags: bluetooth, pins
---


# Question
Title: How to Use Function Code 6 Modbus RTU library
I'm trying to communicate with a temperature controller using Modbus RTU. I used this Arduino library.

I was able to read PV(current temperature value) using below code. It uses Function code 4.

I want to set SV value(Set Value) using **Function code 6**

I replaced `telegram.u8fct = 0x04;` to `telegram.u8fct = 0x06;` and `telegram.u16RegAdd = 0x03E8;` to relevant address for SV. But, I couldn't get success.

How can I implement Function Code 6 in this library ?

Code for read PV as below. Its working properly.

```
    #include <ModbusRtu.h>

    // data array for modbus network sharing
    uint16_t au16data[16];
    uint8_t u8state;

    /**
        Modbus object declaration
        u8id : node id = 0 for master, = 1..247 for slave
        u8serno : serial port (use 0 for Serial)
        u8txenpin : 0 for RS-232 and USB-FTDI
                     or any pin number > 1 for RS-485
    */
    //TRANSMISSION CONTROL PIN - 8
    //HADWARE SERIAL NUMBER - 2
    Modbus master(0, 2, 8); // this is master and RS-232 or USB-FTDI

    /*
       This is an structe which contains a query to an slave device
    */
    modbus_t telegram;

    unsigned long u32wait;

    void setup() {
      Serial.begin(9600);
      master.begin(9600); // baud-rate at 9600
      master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
      u32wait = millis() + 1000;
      u8state = 0;
    }

    void loop() {
      switch ( u8state ) {
        case 0:
          if (millis() > u32wait) u8state++; // wait state
          break;
        case 1:
          telegram.u8id = 0x01; // slave address
          telegram.u8fct = 0x04; // function code (this one is registers read)
          telegram.u16RegAdd = 0x03E8; // start address in slave [CHANNEL 1 PV]
          telegram.u16CoilsNo = 0x01; // number of elements (coils or registers) to read
          telegram.au16reg = au16data; // pointer to a memory array in the Arduino

          master.query( telegram ); // send query (only once)
          u8state++;
          break;
        case 2:
          master.poll(); // check incoming messages
          if (master.getState() == COM_IDLE) {
            u8state = 0;
            u32wait = millis() + 100;
            Serial.println(au16data[0]);//PRINT TEMPARATURE VALUE
          }
          break;
      }
    }

```

# Answer
> 0 votes
I managed to change SV value.

According to the library, when using function code 6, It get sending data(temperature value) from `au16regs[0]`as below piece of code of library file. Need to setup that value before requesting.

(ModbusRtu.h - line number 601)

```
case MB_FC_WRITE_REGISTER: //if cunction code 6
    au8Buffer[ NB_HI ]      = highByte(au16regs[0]);
    au8Buffer[ NB_LO ]      = lowByte(au16regs[0]);

```

---
Tags: arduino-mega, library, modbus
---


# Question
Title: Adafruit_LSM303 tilt compensated compass
I am having troubles with tilt compensating my compass.

I am using the LSM303DLHC accelerometer/compass in combination together with the Adafruit\_LSM303\_U.h.

I was able to get my compass to the right direction withthis little snippet:

```
  float heading = (atan2(event.magnetic.y,event.magnetic.x) * 180) / Pi;

```

I also was able to get my roll and tilt angle with converting my X and Y of my accelerometer to angles:

```
   headingNew = asin(eventA.acceleration.x/10);
   float tilt = headingNew*180/PI/90*100;
   headingNew = asin(eventA.acceleration.y/10);
   float roll = headingNew*180/PI/90*100;

```

Now I need to compensate my angle to get a new x and y for inside my heading calculation but the problem is that I can't seem to get the right functions. Online I found the functions below from a large tutorial about the sensor but this gives me completely wrong values.

```
    //Xh = event.magnetic.x*cos(tilt)+event.magnetic.z*sin(tilt);
    //Yh = event.magnetic.x*sin(roll)*sin(tilt)+event.magnetic.y*cos(roll)-event.magnetic.z*sin(roll)*cos(tilt);

```

or in the code itself:

```
   Xh = event.magnetic.x*(eventA.acceleration.z/10)+event.magnetic.z*(eventA.acceleration.x/10);
   Yh = event.magnetic.x*(eventA.acceleration.y/10)*(eventA.acceleration.x/10)+event.magnetic.y*(eventA.acceleration.z/10)-event.magnetic.z*(eventA.acceleration.y/10)*(eventA.acceleration.z/10);

```

I actually get the right angle on a flat surface. But it is even more inaccurate at an angle as the normal heading. Does anybody have any experience with this sensor? Already a big thanks for the help.

# Answer
Via this Youtube movie I found a different library and made this code:

```
#include <SPI.h>
#include <Wire.h>
#include <LSM303.h>
const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
#define STMPE_CS 8
#define TFT_CS 10
#define TFT_DC 9

int last_dx, last_dy, dx, dy;
LSM303 compass;
void setup(){
Serial.begin(9600);
Serial.println("meters Test"); Serial.println("");
Wire.begin();
compass.init();
compass.enableDefault();

compass.m_min = (LSM303::vector<int16_t>){-602, -704, -511}; //values from
cailbration.
compass.m_max = (LSM303::vector<int16_t>){+557, +436, +529}; //values from
cailbration.
last_dx = centreX;
last_dy = centreY;
}
void loop() {
compass.read();
double angle;
float heading = compass.heading();

angle= heading; //use heading from compass
dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
last_dx = dx;
last_dy = dy;
Serial.print("angle:"); Serial.println(angle);
Serial.println("tilt:"); Serial.println(compass.a.x);
delay(25);
}

```

Now everything works. Sometimes you just need to choose your battles.
> 1 votes

# Answer
The `sin()` and `cos()` functions expect their arguments to be in *radians*. If you feed them with anything else, be it degrees, percent slope, or whatever, expect the result to be just crap.

---

**Edit**: The OP changed the question, invalidating my answer. So here comes a new answer...

You have mistaken `eventA.acceleration.y` for `cos(tilt)`, `eventA.acceleration.x` for `sin(tilt)`, and so on. *They are not the same*. You may think they are the same up to some multiplicative factor, and that's right. However, the factor doesn't cancel out as soon as you do computations like `sin(roll)*sin(tilt)`. Don't rush your math: if you want to transform known-good formulas to more practical ones, check every step of the transformation carefully.
> 3 votes

---
Tags: accelerometer, magnetometer
---


title: Debouncing Switch Issue

text:
# Question
Title: Debouncing Switch Issue
I’m trying to use a LDR to monitor the light levels and if the LDR is covered and the button is pressed, the LED should switch on. I’m in the process of adding debouching but every time I run the code, the it goes in the if (val \> 421) part the led is on, but the button hasn’t been pressed and the code stops.

I’m suspecting it may be a logic issue with the states. I’m using the millis function for the debouncing so the code should ignore the first 200ms of when the button is pressed. I just help in regard to the debouncing so when the LDR is covered and the switch is pressed , the LED should turn on.

The code is shown below:

```
const int buttonPin = 8;
const int ldrPin = 0;
const int LEDPin = 13;

boolean buttonState = 0;
boolean NEWbuttonState = 0;
boolean LEDState = 0;
int bounce_time = 200;
unsigned long my_time;

boolean on;

int val = 0;

void showValue(float myval)
{
  Serial.print(myval);
  Serial.print(" lightstatus ");
  Serial.println(LEDState);
}

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(LEDPin, INPUT_PULLUP);
  on = false;
  analogReference(DEFAULT);
  pinMode(ldrPin, INPUT);
  Serial.begin(9600);
  my_time = millis();
}

void loop()
{

  val = analogRead(ldrPin);

  NEWbuttonState = digitalRead(buttonPin);

  if ((millis() - my_time) > bounce_time)
  {
    digitalWrite(LEDPin, LOW);

    if (buttonState != NEWbuttonState)
    {
      buttonState = NEWbuttonState;

      //if button is pressed
      if (NEWbuttonState == 1 && LEDState == 0)
      {
        buttonState = NEWbuttonState;

        if (val > 421)
        {
          my_time = millis();

          digitalWrite(LEDPin, 1);
          LEDState = 1;
          showValue(val);
          Serial.print("button press");
        }

        if (val < 420)
        {
          my_time = millis();

          digitalWrite(LEDPin, 0);
          LEDState = 0;
          showValue(val);
        }
        buttonState = 1;
      }
      else
      {
        if (NEWbuttonState == 0)
        {
          buttonState = 0;

        }
      }
    }
  }
}

```

# Answer
> 0 votes
Bouncing of a mechanical switch happens in very few milliseconds, faster than you can see a led shine.

So, for your task, you don't need any debouncing.

The description or your task lacks what should happen "if not". I assume the led should shine while both button is pressed and ldr is covered. If either button is not pressed, or ldr is lit, the led should remain off.

This one is too simple:

```
void loop() {
  bool ldrDark = analogRead(A0) < MAX_LDRBRIGHT;
  digitalWrite(led, ldrDark && digitalRead(buttonPin));
}

```

To add a delay (led goes on only when button is pressed some time) is easy as well.

```
const byte LED = LED_BUILTIN; // 13 on UNO

const byte BUTTON = 8;  // Button connects to GND
const byte PRESSED = LOW; // due to INPUT_PULLUP
const int DELAY = 300; // ms
bool btnState; // true = HIGH when presse

const byte LDR = A0; // LDR to 5V, Resistor to GND : Low values when dark
const int MIN_LDRBRIGHT= 420; // depends on resistor and LDR

void setup() {
   pinMode (LED, OUTPUT);
   pinMode (BUTTON, INPUT_PULLUP);
}

void loop() {
  static unsigned long lastOpen;
  if (digitalRead(BUTTON) == PRESSED) {
    if (millis() - lastOpen > DELAY)
      btnState = HIGH;
    else btnState = LOW;
  } else {
      lastOpen = millis(); // to remember last moment button was released
      btnState = LOW;
  }

  bool ldrDark = analogRead(A0) < MIN_LDRBRIGHT;

  digitalWrite(LED, ldrDark && btnState);
}

```

---
Tags: led, debounce
---