title: Smooth breathing led

text:
# Question
Title: Smooth breathing led
I am trying to make a simple breathing led circuit in which the intensity of the led varies between 0 and 255. I followed the Fade tutorial on the Arduino site, which gives me what I want, but I notice that the change in brightness is much more noticeable when the intensity is at 0.

In other words, the brightness seems to be bouncing back from 0, rather than slowly gliding back up.

I tried mapping the value of the delay to brightness: `del = map(brightness, 0, 255, 10, 1);` but that did not do the job.

The mapping seems to work better when I use 30 instead of 10 as longest delay time: `del = map(brightness, 0, 255, 30, 1);` but I think what I really need is to implement some sort of sinusoidal function to make transitions smoother, but I am really struggling with the math... Any suggestions?

Here is the code:

```
int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 1;    // how many points to fade the LED by
int del;

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }

  // here I map the delay to brightness
  del = map(brightness, 0, 255, 10, 1);

  delay(del);
}

```

# Answer
There's two ways you could algorithmically do what you want, both with different results.

The first is with a sinewave:

```
for (int i = 0; i < 360; i++) {
    analogWrite(5, (sin(i * 0.0174533) + 1) * 127));
    delay(3);
}

```

Basically you work your way 360 degrees around a circle and take one axis (e.g., the vertical one), offset it so that the values are all positive (`sin` gives a value between -1 and +1), then multiply it to fit the full brightness.

This is the smoothest way of fading an LED, but it doesn't respect the different sensitivities your eye has to the different brightnesses (you see more brightness variation when it's dim compared to when it's bright).

The other method is much cruder but does respect those differences in sensitivities. This specific method only gives you 8 brightnesses as opposed to 256, but they are on a *log2* curve:

```
for (int i = 0; i < 9; i++) {
    int v = (1 << i) - 1;
    analogWrite(5, v);
    delay(100);
}
for (int i = 7; i > 0; i--) {
    int v = (1 << i) - 1;
    analogWrite(5, v);
    delay(100);
}

```

The theory of this one is it uses bit-shifting to gradually fill a byte with 1 from the least significant bit upwards.

When `i` is 0, this formula:

```
int v = (i << i) - 1;

```

gives:

```
1 << 0 == 0b00000001
0b00000001 - 1 = 0b00000000

```

If `i` is 4, you get:

```
1 << 4 == 0b00010000
0b00010000 - 1 = 0b00001111

```

So you effectively end up with a set of values:

```
0: 0
1: 1
2: 3
3: 7
4: 15
5: 31
6: 63
7: 127
8: 255

```
> 4 votes

# Answer
The three 255 values for RGB colour space (255^3) is 16,581,375 colours. These include for brightness level. The reason you're experiencing brightness issues is not to due with your arduino board but, with the RGB color space. And by breathing, and i'm guessing here, that you are trying to transition thru RGB:

```
void colorLoop() {

    static int Col1;
    static int Col2;
    static int Col3;

    static int C1;
    static int C2;
    static int C3;

  if ((((Col1 == 0) || (Col1 == 250)) && (((Col2 == 0) || (Col2 == 250)) && ((Col3 == 0) || (Col3 == 250))))) {

  C1 = random(1, 3);
  C2 = random(1, 3);
  C3 = random(1, 3);
  }

  if (((C1 == 1) && (Col1 != 0))) {
      Col1 = (Col1 - 10);
  }
  if (((C2 == 1) && (Col2 != 0))) {
      Col2 = (Col2 - 10);
  }
  if (((C3 == 1) && (Col3 != 0))) {
      Col3 = (Col3 - 10);
  }

  if (((C1 == 2) && (Col1 != 250))) {
      Col1 = (Col1 + 10);
  }
  if (((C2 == 2) && (Col2 != 250))) {
      Col2 = (Col2 + 10);
  }
  if (((C3 == 2) && (Col3 != 250))) {
      Col3 = (Col3 + 10);
  }

if (((Col1 <= 90) && ((Col2 <= 90) && (Col3 <= 90)))) {  //avoid black
   C1 = 2;
   C2 = 2;
   C3 = 2;
 }

    for (uint8_t i = 0; i < LED_COUNT; i++) {
     leds[i] = CRGB(Col1, Col2, Col3);
    }
    delay(100);
    LEDS.show();
  }

```

You may have more success or find it easier to use a HSL or HSV colour space. HSV uses Hue, Saturation and Value instead of RGB. FastLED has optimized it's implementation of HSV to use a 0-255 addressing for Hue (instead of 360), keeping it fast for animations run on microcontrollers:

https://github.com/FastLED/FastLED/wiki/FastLED-HSV-Colors

here is a similar effect using the HSV color spectrum:

```
void rainbow_fade() {

 int ihue = 0; //some microcontrollers use HSV from 0-255 vs the normal 0-360
    ihue++;
    if (ihue > 255) {ihue = 0;}
    for(int i = 0 ; i < LED_COUNT; i++ ) {
     leds[i] = CHSV(ihue, 255, 255);
    }
      LEDS.show();
      delay(100);
  }

```
> 2 votes

# Answer
I thought about making a regular fade, with a logarithmic delay: for an example:

```
val=30*(1-((sqrt(brightness))/(sqrt(255))));
delay(val);

```
> 2 votes

# Answer
I'm not sure that it will work with a normal led. Some 20mA leds are still bright with only 1mA. The programmable RGB 5050 leds (for example the NeoPixels) are easier for a smooth visual brightness change.

The human eye is logarithmic for light brightness. Therefor a 10-based exponent or a less steep natural-based exponent can be used.

This will give a smooth brightness change:

```
y = a * exp (-b * x * x);
// x is incrementing in time.

```

If you really need a very smooth brightness change for a normal led, you might need an extra output with a higher resistor value to the same led, for a higher resolution at low brightness.
> 1 votes

# Answer
1. Use a timer interrupt and in thee Isr change a pwm generator duty cycle. Or
2. Use a timer and set up two compare channels with a fixed offset. In the compare Isr, advance the math points forward and then flip an output pin. You will see the brightness goes up and down, whose speed depends on the offset.

No need for gamma correction.

edit: to demonstrate how the 2nd approach might work, here is a quick example.

It runs off of TIMER0, Output Compare Ch A and Ch B.

TIMER0 is set with a 256x prescaler, free running. Ch A is set to interrupt every LED\_PR ticks, and Ch B is set to interrupt every LED\_PR + LED\_OFFSET ticks. they run the same user interrupt handler -\> to flip a pin attached on LED\_PORT / LED pin.

```
tmr0_init(TMR0_PS256x);                 //initialize tmr0 with a prescaler
tmr0a_setpr(LED_PR);                    //set up output compare ch a period
tmr0a_act(led_flp);                     //install user handler for ch a
tmr0b_setpr(LED_PR + LED_OFFSET);       //set up output compare ch b period, with offset
tmr0b_act(led_flp);                     //install user handler for ch b
ei();

```

and here is how it works in simulation:

the DC will go up then down, then up and then down, ....
> 1 votes

# Answer
Just recently I published a blog post about this very topic at https://thingpulse.com/breathing-leds-cracking-the-algorithm-behind-our-breathing-pattern/

Turns out you get very pleasing results if you use `f(x) = e^sin(x)`. If you bring this down to 0 and have an amplitude of 255 the formula becomes `f(x) = (e^sin(x) - 1/e) * (255/(e - 1/e))`. Finally, you stretch `x` so you get a frequency of 12-20 breaths per minute: `x * PI/2`.

```
#include <math.h>

void setup() {
  pinMode(9, OUTPUT);
}

void loop() {
  float val = (exp(sin(millis()/2000.0 * PI)) - 0.368) * 108.0;
  analogWrite(9, val);
}

```
> 0 votes

---
Tags: led
---


# Question
Title: Why is my SPI clock voltage lower at higher frequencies?
I measured that the SPI-Clock of my Arduino Nano in my project didn't reach near 5V. So I quickly tested with a new one, nothing attached except a (mydaq) scope.

I measured the SPI clock:
2.5 V @ 8 Mhz;
3.6 V @ 4 Mhz;
5 V @ 1 Mhz.

I think the graph looks like that because the low max sample of the mydaq, so I dont worry to much about that. The MISO could reach about 5V but why is the clock voltage lower at higher frequencies? And how to reach 5V?

```
#include <SPI.h>

void setup() {
  SPI.begin();
  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
}

void loop() {
  SPI.transfer(1);
}

```

I also tried SPI mode 2 or 3 @8Mhz, idle state was 4,7 V but Vp-p again only 1,9 V.

# Answer
> 2 votes
This is the second time the Nyquist frequency has come up in the last couple of days.

In order to accurately measure a changing signal, like you are doing, you need to sample at, at least, twice the frequency of the signal. If you don't your samples may give incorrect results because you are sampling partway up or down the curve.

To measure an 8 MHz signal, you therefore need to sample at 16 MHz, which you don't appear to be doing.

# Answer
> 2 votes
According to the MyDAQ specifications the analogue input has a pass-band filter of "DC to 400kHz". That means that at 400kHz the signal will be reduced by -3dB, and anything above that will be reduced even further, and the higher the frequency the more it will be reduced.

Further to that the MyDAQ samples at up to 200ksps, which means it can only capture a maximum frequency component of 100kHz.

The MyDAQ is little more than an educational toy. It's just a glorified sound card and really not worth wasting your time with.

---
Tags: arduino-nano, spi
---


title: Atmega2560 PWM on PH4

text:
# Question
Title: Atmega2560 PWM on PH4
I am trying to convert the following code to output to pin 7 (PH4, OC4B) on an Arduino Mega. The code outputs to pin 6. This code is from a GitHub for the GRBL on the Mega "https://github.com/fra589/grbl-Mega-5X" out of the cpu\_map.h It is clear that PH6 and PH7 are on the same PORTH but I just do not know what bits need changing to get GRBL to output on pin 7.Any help would be welcome.

```
#elif defined (SPINDLE_PWM_ON_D6)

    // Set Timer up to use TIMER4C which is attached to Digital Pin 6 - Ramps Servo 2
    #define SPINDLE_PWM_MAX_VALUE     255.0 // Translates to about 1.9 kHz PWM frequency at 1/8 prescaler
    #ifndef SPINDLE_PWM_MIN_VALUE
      #define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
    #endif
    #define SPINDLE_PWM_OFF_VALUE     0
    #define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)

    //Control Digital Pin 6 which is Servo 2 signal pin on Ramps 1.4 board
    #define SPINDLE_TCCRA_REGISTER    TCCR4A
    #define SPINDLE_TCCRB_REGISTER    TCCR4B
    #define SPINDLE_OCR_REGISTER      OCR4A
    #define SPINDLE_COMB_BIT          COM4A1

    // 1/8 Prescaler, 16-bit Fast PWM mode
    #define SPINDLE_TCCRA_INIT_MASK (1<<WGM41)
    #define SPINDLE_TCCRB_INIT_MASK ((1<<WGM42) | (1<<WGM43) | (1<<CS41))
    #define SPINDLE_OCRA_REGISTER   ICR4 // 8-bit Fast PWM mode requires top reset value stored here.
    #define SPINDLE_OCRA_TOP_VALUE  0xFF // PWM counter reset value. Should be the same as PWM_MAX_VALUE in hex.

    // Define spindle output pins.
    #define SPINDLE_PWM_DDR   DDRH
    #define SPINDLE_PWM_PORT  PORTH
    #define SPINDLE_PWM_BIT   3 // MEGA2560 Digital Pin 6

```

# Answer
> 1 votes
You want to replace pin 6 (PH3, OC4A) with pin 7 (PH4, OC4B). There are three things you have to change. First, the output compare register, which is OCR4A for pin OC4A and OCR4B for pin OC4B. Thus:

```
-#define SPINDLE_OCR_REGISTER      OCR4A
+#define SPINDLE_OCR_REGISTER      OCR4B

```

Then, the configuration bit that enables the output:

```
-#define SPINDLE_COMB_BIT          COM4A1
+#define SPINDLE_COMB_BIT          COM4B1

```

Last, the bit to set in the data direction register, which is 3 for PH3 and 4 for PH4:

```
-#define SPINDLE_PWM_BIT   3 // MEGA2560 Digital Pin 6
+#define SPINDLE_PWM_BIT   4 // MEGA2560 Digital Pin 7

```

Note: as in *diff -u* format, the prefix `-` means “remove this”, the prefix `+` means “add this”.

---
Tags: pwm, atmega2560, port-mapping
---


# Question
Title: Will the arduino uno still work if I replace the onboard 16Mhz crystal with a 12Mhz crystal?
I have recently bought an arduino uno R3 (the type where the atmega328 is surface mount and not removable on a mainly blue PCB); the board has two crystals on it one for the clock for the USB serial and the other for the atmega328 clock. Suppose I have built a fully completed circuit using the arduino (this means the arduino needs not to be further connected to a PC). Will my arduino uno based circuit still work if I simply replace (desolder) the 16Mhz (for the atmega328) crystal with a 12Mhz crystal (soldered in its place)? The circuit doesn't use the serial ports or the the crystal for USB serial. Actually the circuit is simply the blink LED example built into the IDE. I am guessing it will still work but blink slower-but I don't know the answer for sure.

# Answer
Sure the device will work, but all time related peripherals won't behave. The USART will run at the wrong baud rate, the millisecond timer's intervals will be too long, and so on.
> 1 votes

# Answer
Assembling an answer from the comments. Ever-terse *@jsotola* points the OP to page two of the data sheet which *@Dave X* summarizes as saying that yes, the chip will operate at 0 to 16 MHz. There is a caveat though, discussions on the Arduino forum suggest that the reduction in clock speed proposed by OP might interfere with the boot loader. The same discussion provides guidance for compiling for lower speed operation.
> 0 votes

---
Tags: led
---


# Question
Title: How to make Arduino to read 1X4 keypad multiple times?
I want to use 1X4 membrane keypad to enter 3 working parameters for LED string controlled by Arduino mini. Keypad is attached to D2-D5 pins and LED is attached to pin 12. My objective is to set the following parameters: frequency (4 values), duty cycle (4 values), run time 4 (values). I need Arduino to read keypad 3 times so I can enter 3 parameters. "Run time" In the sketch below has not been set. I want to use “while” to force Arduino to read the keys but arduino reads it once. Only first “while” is working in the code and I can set cycle period. Second “while” does not work because the key has been already pressed and Arduino does not read keypad second time. Are there any means to use more than 1 "while" in the code or to use one while to read keypad 3 times?

Thank you.

```
   #define Key1 3 // key 1 attached to pin 3
    #define Key2 2 // key 2 attached to pin 2
    #define Key3 5 // key 3 attached to pin 5
    #define Key4 4 // key 4 attached to pin 4
    float period; // cycle time
    float power; // duty cycle
    float ontime; // ontime  time LED is on
    float rest;  // rest time LED is off
    const int ledPin =  12;      // the number of the LED pin

    void setup()
    {
      pinMode(Key1, INPUT_PULLUP);
      pinMode(Key2, INPUT_PULLUP);
      pinMode(Key3, INPUT_PULLUP);
      pinMode(Key4, INPUT_PULLUP);
      pinMode(ledPin, OUTPUT);
    }
    void loop() {
      digitalWrite(ledPin, LOW);
      while (digitalRead(Key1) == HIGH && digitalRead(Key2) == HIGH && digitalRead(Key3) == HIGH && digitalRead(Key4) == HIGH) {};

      int key1a = digitalRead(Key1);
      int key2a = digitalRead(Key2);
      int key3a = digitalRead(Key3);
      int key4a = digitalRead(Key4);

      if (!key1a) {
        period = 1000;
      }
      if (!key2a) {
        period = 2000;
      }
      if (!key3a) {
        period = 3000;
      }
      if (!key4a) {
        period = 4000;
      }

      while (digitalRead(Key1) == HIGH && digitalRead(Key2) == HIGH && digitalRead(Key3) == HIGH && digitalRead(Key4) == HIGH) {};

      int key1b = digitalRead(Key1);
      int key2b = digitalRead(Key2);
      int key3b = digitalRead(Key3);
      int key4b = digitalRead(Key4  );

      if (!key1b) {
        power = 10;
      }
      if (!key2b) {
        power = 20;
      }
      if (!key3b) {
        power = 50;
      }
      if (!key4b) {
        power = 80;
      }

      ontime = period * power / 100;
      rest = period - ontime;

      digitalWrite(ledPin, HIGH);
      delay(ontime);
      digitalWrite(ledPin, LOW);
      delay(rest);
    }

```

# Answer
> 0 votes
Do something to wait until a key is released before advancing to the next section. It would be wise to structure your program to have only one function that processes key presses, and then call it for each key. (Pass key identification, pin number, into the function.)

---
Tags: keypad
---


# Question
Title: Do you actually NEED external resistors for switch connecting IO pin to ground?
Years ago, I encountered a fairly long debate at AVRfreaks.net about whether or not it's OK to directly connect AVR pins that are configured as inputs with internal pullup enabled directly to ground through a button or switch.

From what I recall, the consensus at the time was that it's not (at least, for switches likely to be *closed* and *conducting* at reset), because at least *some* AVR MCUs weren't absolutely *guaranteed* to have their pins in high-impedance state at reset (at least, not if the chip reset while in brownout state, or something like that).

Thinking back, I'm not sure whether the warnings even applied to the chips **I** was introduced to at the time (ATtiny2313, ATtiny13, and ATmega162)... I just remember that the others on the site were pretty adamant that I was courting disaster, and I took their word for it.

Fast forward ~15 years.

The **current** datasheet for the ATmega2560 (at https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega640-1280-1281-2560-2561-Datasheet-DS40002211A.pdf ) **does** seem to guarantee (on pages 7-9) that the pins used by ports A through L **are** tri-state high-impedance input pins at reset under all conditions, including when the clock is halted (obviously, any pin Arduino's bootloader subsequently makes use of could behave differently if I tried to hijack it for double-duty reading a button/switch... but the Mega2560 has so many pins, there really isn't any *reason* to reuse pins Arduino uses for its own purposes).

Offhand, I can think of three potential remaining concerns:

* If I screw up and accidentally execute code that configures a pin connected directly to ground through a closed switch as a high output, the pin (and probably the whole chip) is likely to go up in smoke. I can deal with this risk.
* If I were powering it with batteries, I might care about the constant power drain wasting battery life. I'm not, and I don't.
* I'm not quite sure whether "OK to connect directly to ground through a *momentary* pushbutton" necessarily equates to "OK to connect directly to ground through a *switch* that might conceivably be closed and continuously conducting current for the life of the circuit.

So... have I missed anything? And **is** #3 a legitimate concern, or is it something that's not worth caring about if you're talking about something like 8 pins connected through a DIP switch?

Illustrative circuit:

`Ground <-- [switch] --> IO pin (configured for input, internal pullup enabled)`

# Answer
> If I screw up and accidentally execute code that configures a pin connected directly to ground through a closed switch as a high output, the pin (and probably the whole chip) is likely to go up in smoke. I can deal with this risk.

In addition to “there is an obvious bug”, there could also be a bug that is only triggered in very rare conditions, or a “cosmic ray” event which causes the processor to mis-execute instructions.

Or, maybe a metal tool or piece of debris fell across two of the processor pins and the other pin *is* an output that's currently high. (This is impossible to protect against in all cases, of course.)

In any of these cases, the hazard is that you're **turning a situation where the device misbehaves temporarily into a situation where the device is permanently damaged.**

Will this happen? Likely not. Is it worth protecting against? Depends on your application, on hard-to-quantify risk probabilities, and how much of a bother it would be to replace the processor.
> 1 votes

# Answer
It is usually better to use a resistor when connecting to either +5V or ground. This protects the uP against software bugs, particularly during a hectic debug effort. Even moving on to the next project while forgetting the existing wiring can be a source of trouble.
> 0 votes

---
Tags: switch, resistor
---


title: reading strings from multiple Arduinos

text:
# Question
Title: reading strings from multiple Arduinos
So I have 5 Nanos all trying to crack a password, the idea is each one has one fifth of the list so they can test 5 at a time, then when it is found, I want it to be displayed on a screen I have, the idea is to connect them all to a hub which would be the arduino uno, the Uno would then take the char was sent, and send it to the screen, it does not know which Arduino will send the char and the idea is to use serial.write but I am open to other options. What is the best way to go about accomplishing this task, is there some way I can have it reading the serial from all 5 Nanos, and can this be done without it being plugged into a computer?

# Answer
> 1 votes
Presumably you will avoid having two Nanos try the same item from the list. Then, only one Nano can find the answer, and only one will try to transmit data at any given time. In such a situation, yes, you could connect all five Nanos to the same serial link:

* Connect the Uno's TX directly to the RX each Nano. They will all receive the data transmitted by the Uno.
* Connect the Uno's RX to the TX of each Nano through this circuit:

simulate this circuit – Schematic created using CircuitLab

As long as at most one Nano tries to `Serial.print()` (or `Serial.write()`) at any given time, the Uno will receive the data just fine, although it will not be able to tell which of the Nanos sent it.

# Answer
> 0 votes
The Nano devices can be wired in a daisy chain. Any character coming in must be immediately sent out. The chain would end where it connects to the Arduino.

---
Tags: arduino-uno, arduino-nano, display, serial-data
---


# Question
Title: How many bits long,at most, is the seed in the randomSeed() function?
I can not find a concrete reference to how many bits long the (input) seed for the randomSeed() function is for Arduino given here

https://www.arduino.cc/reference/en/language/functions/random-numbers/randomseed/

In the above webpage , though it is the official Arduino document for randomSeed(), it does not concretely say if the maximum bit length of the seed is 8,16 or 32 bits.

I think it is 16 bits long (in other words the seed is in the range of integers 0 and 65535). So for example the maximum input to randomSeed would be expressed as randomSeed(65535).

But I do not know for sure if the seed input is 16 bits at most. So my question is the seed used in randomSeed() 16 bit length at most (thus having a maximum value of 65535). 32 bits is comparable to a 32bit windows desktop computers so I think 32 bits is too large for the input seed to randomSeed(). I am also using an Arduino Uno with Arduino IDE version 1.6.7 (if that matters regarding the input bit length of the seed).

# Answer
As stated on the page you link to:

> `seed`: number to initialize the pseudo-random sequence. Allowed data types: `unsigned long`.

Therefore it's 32 bits, since that is what `unsigned long` is.
> 3 votes

---
Tags: led
---


# Question
Title: Power saving configuration of unconnected pins
By default, all Arduino (ATmega328P) pins are configured for input without the internal pull-up enabled. This default seems to come from the AVR microcontroller itself.

When it comes to saving power - is this an optimal configuration for unused (and thus unconnected) pins?

Section 14.2.6 Unconnected Pins of the ATmega328P datasheet (page 88) recommends to configure pull-ups in order to save power:

> If some pins are unused, it is recommended to ensure that these pins have a defined level. Even though most of the digital inputs are disabled in the deep sleep modes as described above, floating inputs should be avoided to reduce current consumption in all other modes where the digital inputs are enabled (Reset, Active mode and Idle mode).

> The simplest method to ensure a defined level of an unused pin, is to enable the internal pull-up. In this case, the pull-up will be disabled during reset. If low power consumption during reset is important, it is recommended to use an external pull-up or pull-down.

So I'm tempted to call something like

```
for (uint8_t i = first_unused_pin; i < 20; ++i)
    pinMode(i, INPUT_PULLUP);

```

during setup.

Although, I don't understand where an increased power-consumption would come from when the INPUT pin is unconnected and no pull-up is active. I mean, since the pull-up is connected to VCC, there definitely is some current flowing, whereas without the pull-up I don't see where current would flow, since the pin is unconnected ...

However, Nick Gammon reports in his extensive article on power saving techniques (Section Configuring pins as inputs/outputs, Sketch D) an *increased* power consumption when 6 unused pins are configured as inputs with internal pull-ups attached:

> All pins as inputs, and LOW (in other words, internal pull-ups disabled): 0.35 µA (same as before).
>
> All pins as inputs, and HIGH (in other words, internal pull-ups enabled): 1.25 µA.

So the datasheet's statements seem to conflict with these results.

Is this an error in the datasheet are am I missing something?

# Answer
Current is consumed when an input pin switches from HIGH to LOW or from LOW to HIGH. An unconnected "floating" input pin can change randomly depending on the local environment (EMI, noise, etc). That is unpredictable. The "it will consume more" is erroneous - it should be "it could consume more". The *could* is important, as I mentioned, it is unpredictable. By pulling up or down it is no longer unpredictable, as you have a defined steady state, and the input pin will not switch randomly.

Yes, you will get some leakage current through the pullup and the low-side MOSFET, but it is a defined predictable amount which you can incorporate into your design. If you want to reduce it then use larger external pullups (or pulldowns) to reduce the leakage current (note: using too large will start to encroach on the "floating" teritory again).

But when you're dealing with such small currents you're usually below the self-discharge equivalent current of your battery anyway, so saving a few nA isn't going to actually make the slightest bit of difference.
> 3 votes

# Answer
> Although, I don't understand where an increased power-consumption would come from when the INPUT pin is unconnected and no pull-up is active.

This part of your question already has 2 answers, so I'll just answer the "power saving part".

The data sheet says "If some pins are unused, it is recommended to ensure that these pins have a defined level.". Configuring them with `pinMode()` to `OUTPUT`, then driving them `LOW` using `digitalWrite()` is perfectly acceptable, and MAY offer the greatest power saving / noise immunity of all.

If you look at "14.3 Alternate Port Functions" on page 89, you get a glimpse of the internal digital logic circuitry. When set to `OUTPUT`, the internal circuits provides a low impedance path to ground to sink current. What ever part of the internal circuitry that was "oscillating due to a floating input pin", causing the extra power consumption, is now connected to ground, or it's input is ignored, or how ever Microchip did it.

When you follow the I/O pin on Figure 14-2, it shows the `INPUT_PULLUP` circuitry at the top of the diagram, followed by the tri-state control lower down, then the `SLEEP` circuitry comprised of an analogue switch OR transmission gate if you prefer, inverter gate and N channel FET. When the Arduino is in some sleep modes, it "disconnects" the pin with the analog switch, and also grounds the Schmitt trigger input at the same time. What would be cool is if you could write "Arduino code" in the IDE to toggle this ON/OFF programmatically.

From the data sheet:

> 14.2.5 Digital Input Enable and Sleep Modes
>
> As shown in Figure 14-2, the digital input signal can be clamped to ground at the input of the Schmitt Trigger. The signal denoted SLEEP in the figure, is set by the MCU Sleep Controller in Power-down mode, Power-save mode, and Standby mode to avoid high power consumption if some input signals are left floating, or have an analog signal level close to VCC/2.

The bottom line is, you don't want unused pins set as `INPUT` (Tri-state (Hi-Z) mode). See "Table 14-1. Port Pin Configurations".
> 1 votes

# Answer
The theory here is that an pin without a pull-up will probably float somewhere around the switching voltage. A bit of noise from the surroundings or whatever might push the pin up or down slightly, which will cause the internal circuitry to "flip" from high to low (or vice versa). All that flipping consumes quite a lot of power. The little tiny trickle from a pull-up resistor is so much smaller than the "flip cost" that it's worth using them.

I should also mention that it's very hard to test for a floating pin's consumption of power. Whenever you test it, you'll find it behaving very nicely, but as soon as you put it into a proper application it'll go crazy and won't work anywhere near your expectation. Putting in pull ups avoids this uncertainty, and lets you work with whatever the power consumption is when they're present.

I don't have the results any longer, but a while back I tried measuring the power consumption of the Arduino in various "idle" modes. The theory and practice did't match up terribly well.

It's possibly worth doing some tests, but IIRC, the lowest power setup was to set all pins as inputs and pull them low. In practice that's a lot of work to arrange, so setting them as inputs and using the internal pull-ups works nearly as well.

What you'll also find is that almost anything else will save far more power than the little trickle in the internal pull-ups. Here are some guides which might help:
> 0 votes

---
Tags: power, atmega328
---


title: Arduino diagrams

text:
# Question
Title: Arduino diagrams
I would like to document some of the experiments I have been doing with the arduino. In many of the internet posts on Arduino projects, they have a similar diagram of the Uno or Mega with breadboards and resistors. Some with more detail than others. I've been looking at many of these articles to see if they mention what drawing package they are using but nobody seems to do so.

I could take one of them and just colour out the wires but I can't get the right shade of grey or green.

1. What diagramming tool can be used for drawing these diagrams?
2. Where can I get hold of a blank Arduino Mega/Uno/Nano template.

# Answer
As Juraj commented, those kinds of pictorial diagram are often made using a program called Fritzing.

You should also try producing a more traditional and useful diagram called a schematic. Fritzing can do that at the same time. There are also free programs that are better. See KiCAD, Eagle, EasyEDA etc.

You might find online emulators like Wokwa to be usefull.

---

Related:

Many of the Rules and guidelines for drawing good schematics also apply to Fritzing's pictorial diagrams.
> 4 votes

---
Tags: documentation
---


# Question
Title: Upload s sketch to a 5v Pro-Micro board as 3.3V by mistake
I have 2 types of Pro-Micro(as shown here), both 5v, micro-usb, which worked as expected, until, accidentally were flashed as 3.3v using the Arduino IDE.

At first I thought that the fact it stoped working right after, has nothing to do with that error, but since again, did the same mistake, I understand that this is no coincidence.

After doing so, boards seemed to be powered on ( leds are ON ), but are not found under `port` in the Arduino IDE.

Are they really can be destroyed by such an error ?

# Answer
> 5 votes
Holding `RST` and `GND` pins after re-connecting USB, showed it on `port` menu. needed another such holding, prior to upload.

All good now.

# Answer
> 2 votes
I had the same issue with a promicro wired in to a button box, before i found out that you need to upload a sketch....I know...I\`m a noob, I was trying to rename my button boxes board to a Sparkfun board but I think i had 3.3v 8mhz selected instead of 5v 16mhz, as a result my board was not detected under comm ports and gave a driver error, given that...with my board at least there is only an 8 second delay in which you have to select the correct comm device and then upload a sketch, I shortened the process by opening IDE and selecting the board type and left IDE with a black sketch, of coarse this does not allow the board to be detected as a usb device but it fixes the comm port issue, instead of using a fiddly wire jumper i just used a small screw driver to jump the gnd and reset contacts and quickly selected the boards comm port in IDE then upload with out a delay, by the time IDE actually recognizes a device you actually have closer to 3-4 seconds to react....but its doable.

---
Tags: arduino-pro-micro
---


# Question
Title: Arduino not rebooting with watchdog enabled
I have a custom board that is switching an inductive load through a 10A@230V ac relay. Due to a poor design, voltage spikes are causing the board to reboot from time to time (brown-out, watchdog and "unknown reason")

The problem here is that from time to time, the microcontroller freezes and no longer executes code (or at least, it seems so), even if the watchdog should be running. I programmed the WDTON and BROWN-OUT fuses, so the watchdog should be always on.

Once the microcontroller is frozen, an external reset makes it work again.

My questions:

Is there any SOFTWARE fix to guarantee that the device never freezes. Am I using the watchdog incorrectly?

I read in the Atmega 328P datasheet about the 4 cycle restriction between the WDE writing and the prescaler bits writing (page 44), but It´s not clear to me if this restriction applies when WDON fuse is programmed. Also, I couldn´t find what the "wdt\_enable (WDTO\_2S);" instruction is doing under the hood.

Is it possible that the watchdog oscillator stops due to a voltage spike?

This is my code (the part to illustrate the watchdog problem)

Hardware: Custom board

microcontroller: ATmega 328P

Brown-out fuse: programmed

WDTON fuse: programmed

```

#include <avr/wdt.h>

#define R0          3 // Relay output 16A @ 230Vac (10A @ 230Vac)
#define R1          4 // Relay output 10A @ 230Vac (10A @ 230Vac)
#define R2          5 // Relay output 10A @ 230Vac (10A @ 230Vac)

byte outputs;

//-------------------------------------------------------------------------

void test() {

#define TEST_SWITCHING_INTERVAL  500

  static unsigned long previousMillisTest;
  static int count;

  unsigned long actualTemp = millis();
  if ((actualTemp - previousMillisTest) >= TEST_SWITCHING_INTERVAL) {
    bitWrite (outputs, 0, !bitRead (outputs, 0)); Serial.print ("R0 = ");    Serial.print (bitRead (outputs, 0));
    bitWrite (outputs, 1, !bitRead (outputs, 1)); Serial.print ("   R1 = "); Serial.print (bitRead (outputs, 1));
    bitWrite (outputs, 2, !bitRead (outputs, 2)); Serial.print ("   R2 = "); Serial.print (bitRead (outputs, 2));
    Serial.print ("   count: "); Serial.print (count++);
    Serial.print ("  millis: "); Serial.println (previousMillisTest);
    previousMillisTest = actualTemp;
  }
  digitalWrite (R0, bitRead (outputs, 0));
  digitalWrite (R1, bitRead (outputs, 1));
  digitalWrite (R2, bitRead (outputs, 2));
}

//-----------------------------------------------------------------------

void setup() {

  uint8_t MCUSR_save;

  MCUSR_save = MCUSR;
  MCUSR = 0;
  wdt_enable (WDTO_2S);

  Serial.begin (9600);

  if      (MCUSR_save & 0x01)  Serial.println ("*********Restarting . Power-on Reset*********");
  else if (MCUSR_save & 0x02)  Serial.println ("*********Restarting . External Reset*********");
  else if (MCUSR_save & 0x04)  Serial.println ("*********Restarting . Brown-out Reset*********");
  else if (MCUSR_save & 0x08)  Serial.println ("*********Restarting . Watchdog Reset*********");
  else if (MCUSR_save & 0x10)  Serial.println ("*********Restarting . JTAG Reset*********");
  else                         Serial.println ("*********Restarting . Unknown reason*********");
  Serial.print ("MCUSR = 0x"); Serial.println (MCUSR_save, HEX);

  initPins();
  initDevice();

  if (DEBUG) showConfig();

  // prevents flooding the RS485 bus if the device is continuously restarting
  delay (100);

  sendFrame (RESTARTED, 0); // sends the "restarted" event through the RS485 port

}

//---------------------------------------------------------------------------

void loop() {
  wdt_reset();
  test();
}

```

# Answer
> 3 votes
You can choose to either reset the processor or execute an interrupt routine. Example code:

```
#include <avr/wdt.h>

// watchdog intervals
// sleep bit patterns for WDTCSR
enum
{
  WDT_16_MS  =  0b000000,
  WDT_32_MS  =  0b000001,
  WDT_64_MS  =  0b000010,
  WDT_128_MS =  0b000011,
  WDT_256_MS =  0b000100,
  WDT_512_MS =  0b000101,
  WDT_1_SEC  =  0b000110,
  WDT_2_SEC  =  0b000111,
  WDT_4_SEC  =  0b100000,
  WDT_8_SEC  =  0b100001,
 };  // end of WDT intervals enum

void setup()
  {
  wdt_disable ();
  Serial.begin(115200);
  Serial.println ();
  Serial.println("After reset");
  watchdogSetup(WDT_4_SEC);
  }

volatile bool watchdogFired = false;

ISR(WDT_vect) // Watchdog timer interrupt.
  {
  watchdogFired = true;
  }

void watchdogSetup(byte interval)
  {
  cli(); // disable all interrupts

  // Enter Watchdog Configuration mode:
  WDTCSR = bit (WDCE) | bit (WDE);
  // Set Watchdog settings:
  //  WDTCSR = bit (WDIE) | interval;   // set WDIE, and requested delay - for an INTERRUPT
  WDTCSR = bit (WDE) | interval;    // set WDIE, and requested delay - for a RESET
  wdt_reset(); // reset the WDT timer
  sei();  // enable interrupts again
  }

void loop()
  {

  if (watchdogFired)
    {
    watchdogFired = false;
    Serial.println ("Watchdog fired.");
    }

  // wdt_reset();  // if you want to reset the watchdog

  } // end of loop

```

This example resets the processor, however if you uncomment the line `WDTCSR = bit (WDIE) | interval;` and comment the one below `WDTCSR = bit (WDE) | interval;` then it interrupts instead. You can see that in the example output.

If you want an interrupt then you have to supply an interrupt routine (ISR).

---

Responding to comments:

> But there´s little documentation about how to adequately recover from a reset when the fuse is programmed.

The processor resets, which is what you want, right? You don't need to "recover" from a reset. It's like saying how do you recover from powering it on.

> Do I still need to re-enable the watchdog, even if it should be enabled by the fuse?.

I doubt it. In my code the watchdog keeps firing, even after you get the message the first time (the interrupt one).

However you might want to change the interval to the one you want. And you might want to reset the watchdog (wdt\_reset ()) if things are going OK.

> Also, with the WDTON fuse enabled, the ISR mode is not valid (only the reset mode).

Well, there is not necessarily an ISR for the ISR mode (yet, if ever). The datasheet specifically says that you get the reset mode and not the ISR mode.

It is unclear from the datasheet what the time interval is, with the WDTON fuse programmed.

---
Tags: atmega328, watchdog
---


title: Correct usage of SPI with ISR

text:
# Question
Title: Correct usage of SPI with ISR
My Arduino needs to do:

1. Run ISR as many times as possible/ as fast as possible.
2. Occasionally receive data over I2C.
3. Output data over SPI in ISR.

My question is regarding SPI and ISR. The documentation about SPI I found, was quite poor.

```
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
SPI.usingInterrupt(255);
SPI.begin();

void isr_function()
        SPI.transfer(data);
        pulse_latch();
};

```

Is this the correct use of SPI in my case? Can it be faster?

# Answer
It is actually fairly easy just to use the SPI peripheral without using the arduino libraries. The attached functions could be used to send a number of bytes through the SPI with one call: (Assuming ATMEGA328)

```
#include <avr/io.h>
#include <avr/interrupt.h>

static unsigned char spiCnt, *userBufr;

/* Call this function during setup */
void SpiInit (void)
    {
    PPR &= ~0x04;   // Be sure the SPI has power
    DDRB |= 4;      // Be sure SS signal on PORTB bit 2 is output
    SPCR = 0x50;    // Turn SPI on, maximum CLK rate
    }

/* Call this function to initiate the multi-byte send */
void SpiWrite (void *data, unsigned char bytCnt)
    {
    /* Save the the caller's messsage information */
    userBufr = data;
    spiCnt = bytCnt;

    /* Enable the SPI device, send first byte */
    SPCR |= 0x40;           // Enable SPI
    SPDR = *userBufr++;     // Send the first byte
    SPCR |= 0x80;           // Enable interrupts
    }

/* Call this one to be sure the message is finished */
int SpiIsDone (void)
    {
    /* Non-zero when operation is finished */
    return ( ! (SPCR & 0x80));
    }

/* Stay out of this one */
ISR (SPI_STC_vect)
    {
    /* Check the remaining number of bytes to send */
    if (--spiCnt)
        SPDR = *userBufr++;     // Send the next byte

    /* Operation is finished, shut down SPI */
    else
        SPCR &= ~0x80;  // Disable interrupts for SPI
    }

```
> 1 votes

---
Tags: arduino-nano, interrupt, spi, isr
---


# Question
Title: Why analogRead's value decreases when I decrease the value of resistor?(I use digitalWrite(high) to positive terminal of resistor)
Basically, my circuit contains only 1 resistor(like the basic LED circuit).

I tried to know what is the actual voltage of digitalWrite(High). I don't understand why the value of analogRead does not fix to 1023 but instead decreases when I decrease the value of the resistor. Moreover, the value comes to zero when my resistor value comes to 1 ohm. Really appreciate any helps here.

# Answer
> 0 votes
A digital output pin can only provide a specific current: 20mA max recommended, 40mA absolute max. When you get near and over that these values the voltage will go down, as the internal driver hardware cannot provide enough current to hold the voltage.

With the resistor you are providing a direct current path to ground. For high values of R it doesn't make much different (as the current through the resistor to ground is lower than the max current of the digital pin drivers max current). When you lower R the current through it to ground gets bigger. Thus the digital pin driver has to provide more current to hold the voltage. When it gets too low the driver cannot provide enough current, the voltage will fall.

With R at 1Ohm you are basically shorting the digital output pin to ground as 1Ohm really isn't much resistance. At 5V (which is the output voltage of the Uno) you will get `U/R = 5V / 1 Ohm = 5A` current through it. The driver cannot provide this. In real life the pin driver would most likely be killed by this current draw.

# Answer
> 2 votes
As a complement to chrisl's answer, it is worth noting that the datasheet of the microcontroller (here the ATmega328P), under a section named “Typical characteristics”, has a subsection named “Pin Driver Strength”. This subsection has some typical voltage-vs-current curves showing that:

* the curves are not quite linear, although the non-linearity is small at 5 V supply voltage
* they depend strongly on temperature
* near ambient temperature, the pin behavior is close to an ideal voltage source in series with a 25 Ω resistor.

The curves go only up to 20 mA, as the behavior for higher currents is not characterized.

From this, you can guess the voltage reading you expect. For example, if you use a 470 Ω resistor (which is safe), the output pin resistance and the external resistor make a voltage divider. The expected voltage you read is

(5 V) × (470 Ω) / (470 Ω + 25 Ω) = 4.747 V

---
Tags: arduino-uno, serial, analogread, resistor, digitalwrite
---


title: How to transmit DTMF signal to Arduino

text:
# Question
Title: How to transmit DTMF signal to Arduino
I'm trying to read an incoming DTMF signal through the A0 input pin. I want to do this programmatically and not with the MT8870 module. This library (https://github.com/Adrianotiger/phoneDTMF) is supposed to do just that but I can't figure out how to connect my incoming DTMF signal to Arduino's A0 pin to receive the signal. Basically, my laptop produces the DTMF signal and I want to attach the line out, which is two wires, the positive and ground, to Arduino. None of the configurations I've tried work. I've tried to attach the positive to A0 and the ground to ground, but A0 doesn't seem to be detecting anything. I also don't want to use a microphone on the A0 pin to detect the DTMF. A simple Fritzing type diagram showing how to connect the incoming DTMF signal to A0 would be helpful. Thanks.

# Answer
Your problem is that you think there's a "positive" signal. In audio there isn't a "positive" signal, there is just a signal that swings around 0V.

You have to convert said signal to a "positive" signal by adding a DC offset to it.

The simplest way is with one capacitor and two resistors:

simulate this circuit – Schematic created using CircuitLab

That schematic will remove any DC offset that your laptop may add ("AC couple") and then add a 2.5V DC offset of your own to the signal. The audio signal will then be alternating around 2.5V.

You may need to boost the audio signal's volume with an op-amp (note: do *not* use a "power" amplifier like the LM386, it is not suitable; use an op-amp) to increase the sensitivity of the input. You could do this with a simple inverting amplifier arrangement with the DC offset being injected into the non-inverting input:

simulate this circuit

Here the gain of the amplifier is the ratio between R3 and R4 - in this case a 10:22 ratio (or a 2.2x gain).

From a software point of view you now remove 512 from each analog read value to give you a range of +/-511 for your sampled values. You then probably (maybe with the library you link to) take a block of samples at a defined frequency and perform an FFT analysis to find what dominant frequency components are present.
> 3 votes

---
Tags: arduino-uno, analog
---


title: Arduino pro mini sampling rate

text:
# Question
Title: Arduino pro mini sampling rate
what are the possible sampling rate the user can set in Arduino pro mini using ADCSRA registers. I want to set my desired sampling rate through registers, is it possible?

# Answer
The previous responders are correct; but, maybe some clarification may help. The data conversion rate determined by the ADCSRA register is the conversion rate of the hardware. There is no need to sample data readings faster than conversions are performed. Faster conversions show more jitter than slow ones. Your actual sample rate will usually depend more on the time it takes to run through your loops than on the conversion rate. Arduino library code is usually not the optimum choice for speed.

When you change the conversion rate in the ADCSRA, be sure to avoid clobbering the other bits:

ADCSRA = (ADCSRA & 0xF8) | (newRate & 7);

If you are getting the hang of writing the control registers, you might want to use the ADC's operation complete interrupt to retrieve each reading. That eliminates loop times.
> 1 votes

---
Tags: serial, timers, adc, analog-sampling, registers
---


title: Turn off Timer1 / Timer1 One-shot

text:
# Question
Title: Turn off Timer1 / Timer1 One-shot
A zero detector crossover sends a pulse to the Arduino, it must start counting x time and then a pulse is sent from the Arduino, once the timer reaches time x, it must stop counting and only start counting again when it receives the new pulse of the zero crossing detector, the idea is to do something like this:  What I don't know is how to keep the timer off all the time toff that appears in the image.

# Answer
the way to turn off the Timer is to set the CS12, CS11 and CS10 prescale bits to 0, in this way the CLK signal is disconnected and the timer stops counting, when you want the timer to continue counting, they are set back to 1 the CS12, CS11 and CS10 bits according to the selected prescale.

```
byte savePrescale

savePrescale = TCCR1B & (0b111<<CS10);
...
TCCR1B &= ~(0b111<<CS10); // Stop Timer1 Clock
...
TCCR1B |= savePrescale;  // Restart Timer1 clock.
...

```
> 3 votes

# Answer
You can initiate a "One shot" timer at each zero-crossing.

The trick @Gerben mentioned in turn off Timer1 / Timer1 One-shot eventually links to code at https://github.com/bigjosh/TimerShot which does the one-shot functionality on Timer2 by idling the timer at TCNT2=0 with OCR2A=0, and using the TCNT2 space above 0 to operate an adjustable oneshot on OC2B.

This trick can be adapted to Timer1:

```
// The one shot pulses are output on Digital pin OC1B (Arduino Uno D10, Mega D12, Nano D3)
// Modified by Dave Forrest 2020-01-11 for Timer 1
// Based on Josh Levine's Nov 23, 2015 work at https://github.com/bigjosh/TimerShot/blob/master/TimerShot.ino

#define OSP_SET_WIDTH(cycles) (OCR1B = 0xffff-(cycles-1))

// Setup the one-shot pulse generator and initialize with a pulse width that is (cycles) clock counts long

void osp_setup(uint16_t cycles) {

  TCCR1B =  0;      // Halt counter by setting clock select bits to 0 (No clock source).
              // This keeps anything from happeneing while we get set up

  TCNT1 = 0x00;     // Start counting at bottom.
  OCR1A = 0;      // Set TOP to 0. This effectively keeps us from counting because the counter just keeps reseting back to 0.
          // We break out of this by manually setting the TCNT higher than 0, in which case it will count all the way up to MAX and then overflow back to 0 and get locked up again.
  OSP_SET_WIDTH(cycles);    // This also makes new OCR values get loaded from the buffer on every clock cycle.

  TCCR1A = 0b11<<COM1B0  | 0b11<<WGM10;  // OC1B=Set on Match, clear on BOTTOM. Mode 15 Fast PWM.
  TCCR1B = (0b11<<WGM12)| (0b001<<CS10); // Start counting now. WGM 15=0b1111  to select Fast PWM mode

  //DDRB |= _BV(2);     // Set pin to output (Note that OC1B = GPIO port PB2 = Arduino Uno Digital Pin 10)
  DDRB |= _BV(6);     // Set pin to output (Note that OC1B = GPIO port PB6 = Arduino Mega Digital Pin 12)
  //DDRD |= _BV(3);     // Set pin to output (Note that OC1B = GPIO port PD3 = Arduino Nano Digital Pin 3)
}

// Setup the one-shot pulse generator

void osp_setup() {
  osp_setup(1);
}

// Fire a one-shot pulse. Use the most recently set width.

#define OSP_FIRE() (TCNT1 = OCR1B - 1)

// Test there is currently a pulse still in progress

#define OSP_INPROGRESS() (TCNT1>0)

// Fire a one-shot pulse with the specified width.
// Order of operations in calculating m must avoid overflow of the uint16_t.
// TCNT2 starts one count lower than the match value becuase the chip will block any compare on the cycle after setting a TCNT.

#define OSP_SET_AND_FIRE(cycles) {uint16_t m=0xffff-(cycles-1); OCR1B=m;TCNT1 =m-1;}

void setup()
{
  osp_setup();

}

void loop()
{
  // Step though 0-11 cycle long pulses for demo purposes
  for (uint8_t o = 0; o < 101; o++) {
    OSP_SET_AND_FIRE(o);
    while (OSP_INPROGRESS());         // This just shows how you would wait if necessary - not necessary in this application.
    //_delay_us(1);      // Wait to let the audience clap
  }
}

```

This code produced pulses with a resolution of 62.5ns, which is on the edge of what my test equipment can measure. Here's a 6.25us, 100 cycle pulse next to a 1 cycle pulse:

With Timer1's 16 bit range and the /1 prescaler you can do pulses from 62.5ns to 4us. With the /1024 prescaler, (`TCCR1B|=(0b101 <<CS10);`) it can do 64us up to 4.194sec. With /256 prescaler, (`TCCR1B|=(0b100 <<CS10);`) it can do 16us up to 1.05sec.

For a one shot triggered on a zero-crossing, you might try something like this with the above

```
void loop()
{
  ...
  int t1_us = 1000000UL/60 /8 ; // 1/8th of a 60Hz cycle

  if(needOneShot){  // Set needOneShot with an interrupt or sensor or something
    OSP_SET_AND_FIRE(t1_us/16);  // 16us ticks with the /256 prescaler
     needOneShot = false;
  }
  ...
}

```
> 1 votes

---
Tags: timers
---


# Question
Title: Arduino nano standalone - pcb to be manufactured
Using EasyEDA I've designed a standalone Arduino nano and plan to have a small PCB manufactured by jlcpcb. I've used the Nano's user manual as a reference for the PCB; within this scope I've used the same microcontroller (ATMEGA168-20AU) and kept close to the original design.

The circuit is modestly basic and will use a blank target ATMEGA168 placed by jlcpcb - my question is - From a programmer Arduino, do I flash the bootloader and program the target micro through the ICSP (left hand side) or is something else required for bootloader plus program? Is the circuit schematic sufficient to work? (could be opening a can of worms here in asking that)

Thanks

# Answer
> 3 votes
You program the chip through ICSP, yes. Whether or not you include a bootloader is optional - you don't need a bootloader to program through ICSP, that is only for if you want to program through the UART pins and a USB to UART adapter.

Your circuit doesn't appear to include any "bypass" capacitors. These are small capacitors (usually 100nF) placed close to each power (VCC) pin on all chips. These are not optional and are required for the proper running of the chip.

---
Tags: arduino-nano
---


title: how to change a const char*

text:
# Question
Title: how to change a const char*
At the top of my arduino sketch, I have the following :

```
// softAp
const char *softApSsid = "abcdefg";
const char *softApPassword = "123456";

```

Those are the DEFAULT ssid and password to connect to the soft AP. The soft AP is start in the setup() such as :

```
WiFi.softAP(softApSsid, softApPassword);

```

according to the github repo, that function indeed requires "const char\*" as parameters (source: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp#L97)

Further in my sketch, I want to let the user edit the ssid and password. I wrote a function that reads the first byte of the eeprom. If it equals 255, we use the default credentials, if it equals to 1, it means the user set custom credentials, so we will use those to spawn the soft AP.

I wrote this :

```
void getSoftApAuth() {
  bool isDefaultSoftApAuth = 255 == EEPROM.read(0);

  if (! isDefaultSoftApAuth) {
    softApSsid = "";
    softApPassword = "";

    int i = 1;
    while ('\0' != EEPROM.read(i)) {
      softApSsid += char(EEPROM.read(i));
      i++;
    }

    i = 65;
    while ('\0' != EEPROM.read(i)) {
      softApPassword += char(EEPROM.read(i));
      i++;
    }
  }
}

void setSoftApAuth(const char* ssid, const char* passphrase) {
  EEPROM.write(0, 1);

  // ssid
  int positionOfSsid = 1;
  int lengthOfSsid = strlen(ssid);
  for (int i = 0; i < lengthOfSsid; i++) {
    EEPROM.write(positionOfSsid + i, ssid[i]);
  }
  EEPROM.write(positionOfSsid + lengthOfSsid, '\0');

  // passphrase
  int positionOfPassphrase = 65;
  int lengthOfPassphrase = strlen(passphrase);
  for (int i = 0; i < lengthOfPassphrase; i++) {
    EEPROM.write(positionOfPassphrase + i, passphrase[i]);
  }
  EEPROM.write(positionOfPassphrase + lengthOfPassphrase, '\0');

  if (EEPROM.commit()) {
    Serial.println("Successful EEPROM write");
  } else {
    Serial.println("Failed EEPROM write");
  }
}

void resetSoftApAuth() {
  EEPROM.write(0, 255);

  if (EEPROM.commit()) {
    Serial.println("Successful EEPROM reset");
  } else {
    Serial.println("Failed EEPROM reset");
  }
}

```

this does compile but crashes and throws exceptions when I run the chip. I believe the issue is in getSoftApAuth() where i try to concatenate the string such as `softApSsid += char(EEPROM.read(i));`. I print the value of softApSsid in the Serial Monitor and it outputs garbage. I replaced everything with "String" type, and this time it outputs correct username/password stored in the eeprom, but it wont start the soft AP, I believe because I am now trying to pass String instead of const char\* to the `WiFi.softAP()` function as I said earlier (it starts the soft AP with factory default SSID like ESP-AABBCCDDEE appending the MAC address and without any password).

So, basically, how can I modify my `softApSsid` down in my code, while i declared it at the top as a `const char*`, knowing it feeds a function that takes (exclusively?) a `const char*` (WiFi.softAP())

Or is there an other approach / design pattern to achieve this? That is to say: having default credentials hard-coded, but allowing the user to define custom credentials (and storing/retrieving them from the eeprom).

Thanks. Please be indulgent as I am mostly a webdev and not yet comfortable with the strongly typed languages (let alone pointers / references ...)

# Answer
> 7 votes
> that function indeed requires "const char\*" as parameters

There seems to be a misunderstanding here. The method signature is:

```
bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* psk,
    int channel, int ssid_hidden, int max_connection);

```

Within this signature, the word `const` means the method makes the promise not to modify the `ssid` nor the `psk` strings. If you were implementing the method, you would indeed be *required* to honor the constness of these strings. As a user of the method, however, you are perfectly allowed to provide a modifiable string. You are not bound by any constness requirement. And indeed, you have to use modifiable strings if you want your user to be able to change them.

The simplest way to handle this situation is:

```
char softApSsid[MAX_SSID_LENGTH] = "abcdefg";
char softApPassword[MAX_PWD_LENGTH] = "123456";

```

Note that you have to allocate enough room to store the longest strings you may need. Whereas 8 bytes would be enough to store `"abcdefg"`, it may not suffice for other ssids.

Also note that C strings cannot be grown with the `+=` operator. They are just arrays of characters and should be written to as such:

```
i = 0;
do {
    char c = EEPROM.read(1+i);
    softApSsid[i++] = c;
} while (c != '\0');

```

---

**Edit**: answering this comment:

> Some research on SO also suggested the following:
> `const char *password = myString.c_str();`
> where `myString` is of `String` type.

Indeed. The `c_str()` method of the `String` class lets you directly access the C string buried within a `String` object, if you promise not to modify it (hence the `const`). Growing a `String` is easy, as the `+=` operator takes care of handling the memory.

I would, however, advice against any unnecessary use of the `String` class, as it involves lots of heap memory allocation, especially if you build a string one character at a time with `+=`. This is not really friendly to your device's memory. See The Evils of Arduino Strings for details.

# Answer
> 0 votes
Always remember that a variable that is defined as a char array will not automatically grow if you concatenate something to it. Its size is fixed. When you used String, that did fix that problem. You can use the c\_str() function of String to access the string itself. String operations will change that string, perhaps even allocating it at a different address. It might be wise just to define fixed sized char arrays for passing to the WIFI functions. I'd have to look inside the WIFI library to determine if the strings are copied for use internally. Make those fixed sizes large enough to take some editing, but do protect from over-filling by the editor.

---
Tags: esp8266, wifi
---


title: 'PinStatus' does not name a type

text:
# Question
Title: 'PinStatus' does not name a type
I bought an "off-brand" ESP32 board. I can upload blinky without a problem using platformio with the following `platformio.ini` file:

```
[env:humidious]
platform = espressif32
board = nodemcu-32s
framework = arduino

```

However, as soon as I add `lib_deps = grafana/PrometheusArduino@^0.3.0` the compiler throws the following errors:

```
In file included from .pio/libdeps/humidious/WiFiNINA/src/WiFiStorage.h:23:0,
                 from .pio/libdeps/humidious/WiFiNINA/src/WiFi.h:38,
                 from .pio/libdeps/humidious/PromLokiTransport/src/clients/ESP32Client.h:7,
                 from .pio/libdeps/humidious/PromLokiTransport/src/PromLokiTransport.h:8,
                 from .pio/libdeps/humidious/PrometheusArduino/src/PromClient.h:4,
                 from .pio/libdeps/humidious/PrometheusArduino/src/PrometheusArduino.h:5,
                 from src/main.cpp:4:
.pio/libdeps/humidious/WiFiNINA/src/utility/wifi_drv.h:293:12: error: 'PinStatus' does not name a type
     static PinStatus digitalRead(uint8_t pin);

```

It was suggested on another thread that the board was out of date, but updating this didn't help.

Adding `typedef int PinStatus` before `#include <PrometheusArduino.h>` didn't help either.

# Answer
What Majeko said was correct. PIO was using WifiNINA instead of the ESP32's WiFi library. To solve this, I added `lib_ignore = WiFiNINA` to `platformio.ini` and `#include <WiFi.h>` before including the prometheus libraries in `main.ino`.

I tested this by pointing PrometheusArduino at my desktop with this example:

```
$ ncat -l 9090
POST /api/prom/push HTTP/1.1
Host: 192.168.0.45
Content-Type: application/x-protobuf
Content-Encoding: snappy
User-Agent: prom-arduino/0.2.2
Content-Length: 209

F

%
__name__uptime_milliseconds_total

job
esp32-test

hostD   @/@%@<@@/

heap_free_bytes
0

foobar
        0xA6..(0xA/

```
> 2 votes

# Answer
The problem here is that PlatformIO is picking up the wrong WiFi library. It has decided that the WiFi.h provided by WiFiNINA is the correct one to use, rather than the WiFi.h provided by the ESP32's bundled WiFi library.

You could try removing all traces of the WiFiNINA library from your PlatformIO installation, or maybe you need to manually specify which WiFi library should be used to preempt the autoselection routine.

I don't know how you do that in PlatformIO.
> 1 votes

---
Tags: esp32
---


# Question
Title: How can I get a Faster boot with the Adafruit Feather SAMD21?
The Adafruit Feather SAMD21 takes about two seconds from power being supplied to when setup() starts running. How can I shorten that time so that setup() will run sooner? I measure this time using a power supply and others appear to measure similar times with their eyeballs.

I understand that 328 microcontrollers can be made to boot quicker (almost instantly from a human perspective) using different bootloaders for example, but I haven't found one for the M0 SAMD21 nor another method.

The code isn't relevant because the blink example shows the same timeframe, but here's another example:

```
//no libraries, global variables, nothing.
setup(){
digitalWrite(LED_BUILTIN, HIGH);
}

loop(){
}

```

# Answer
After consulting the datasheet for the SAMD21, I verified that the processor starts immediately once the internal clocks are stable. This happens quickly. The reset vector directs execution to the Arduino bootloader, which certainly spins while waiting for the Arduino programmer to connect. If that does not happen during that delay, the bootloader jumps to the resident application. The delay with no activity is how the bootloader determines that you want to start the application. You can eliminate that by programming the processor using a hardware programmer/debugger, and getting rid of the Arduino bootloader.

The hardware programmers also allow source level breakpoint debugging. You just have to learn to use a decent IDE programming environment. A good prgrammer will cost you around $160.
> 1 votes

---
Tags: adafruit, bootloader, feather
---


title: How to convert byte *payload to String

text:
# Question
Title: How to convert byte *payload to String
I would like to convert a `byte *payload` to a `String`, because I want to compare the content of `payload` to another `String`.

```
void mqttCallbackHandler(char *topic, byte *payload, unsigned int length) {
  String payloadstr = ???
  ...
}

```

# Answer
> 8 votes
Depending on what is setting the message on the topic, `payload` may, or may not be, a NULL-terminated string. This is why they provide the `length` parameter.

You could consider comparing the data with `memcmp()` which is like `strcmp()` but doesn't look for a NULL termination - instead it takes a length parameter. This is good if you may have NULL bytes in your payload.

An alternative is `strncmp()` which both looks for a NULL termination and also limits the length using a `length` parameter. Better for payloads you know are strings, but you aren't sure if they have NULL termination or not.

Here is a callback (for PubSubClient on ESP8266) I have in one of my projects which uses `strncmp()`:

```
void callback(char *topic, byte *payload, unsigned int length) {
    if (!strcmp(topic, SUBTOPIC)) {
        if (!strncmp((char *)payload, "on", length)) {
            digitalWrite(POWERPIN, HIGH);
            powerState = true;
            client.publish(PUBTOPIC, "on", true);
        } else if (!strncmp((char *)payload, "off", length)) {
            digitalWrite(POWERPIN, LOW);
            powerState = false;
            client.publish(PUBTOPIC, "off", true);
        }
    }
}

```

Simply casting your payload to `(char *)` is enough for the functions to take it as a string, and the `length` parameter will prevent looking past the end of the payload if there is no NULL termination.

It's not perfect - a single byte payload of `o` will falsely match the first `on`, but if that is a critical problem I am sure you can find a way to work around it by checking what `length` equals.

# Answer
> 3 votes
This is an old post but probably somebody can use this info:

```
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
  String topicStr = topic;
  String recv_payload = String(( char *) payload);

  Serial.println( "mqtt_callback - message arrived - topic [" + topicStr +
                  "] payload [" + recv_payload + "]" );
}

```

# Answer
> 2 votes
Consider simply using the returned pointer.

Payload is a pointer of type byte. You can compare each byte in a string to the byte the pointer is pointing at. Then increment the pointer to the next byte and repeat the process. You don't need to allocate more memory for new string.

If a type string is necessary. For example, if you were using a complex library method which requires a string to be passed to it, you could copy what the returned pointer is pointing at byte by byte into a locally defined string.

# Answer
> 2 votes
For comparing a byte array to a String object, you could convert the byte array to another String object, but this involves dynamically allocating memory for a whole copy of the string. This is memory unfriendly, and preferably avoided on small microcontrollers.

The cheapest way to achieve what you want is to compare them as character arrays :

```
if (strcmp((char *) payload, theReferenceString.c_str()) == 0) {
    // the strings are equal
}

```

`strcmp()` is a standard C function that does the byte by byte comparison, exactly as suggested by st2000.

# Answer
> 0 votes
Marco's answer worked for me, but worked better with:

```
payload[length] = 0;
String recv_payload = String(( char *) payload);

```

Therefore, the full code would be:

```
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
  String topicStr = topic;
  payload[length] = 0;
  String recv_payload = String(( char *) payload);

  Serial.println( "mqtt_callback - message arrived - topic [" + topicStr +
                  "] payload [" + recv_payload + "]" );
}

```

---
Tags: esp8266, c
---


# Question
Title: 'D1' was not declared in this scope; did you mean 'y1'?
Even though i am mentioning everything in the beginning then too m getting out of scope error. Code Reference :- https://noisycarlos.com/project/how-to-turn-your-computer-on-and-off-remotely/ I dont know what wwrong here. I am using ESP8266 module. Please help.

```
#include <ESP8266WiFi.h>

    const char* ssid = <YOUR WIFI NAME>;
    const char* password = <YOUR WIFI PASSWORD>;
    const char ON = '+',
     OFF = '-',
     SLEEP = '/',
     AUTO = 'A';

    const int pinPowerLightOut = D1,
     pinPowerLightIn = D5,
     pinPowerButton = D6,
     pinResetButton = D7,

     buttonPressTime = 250;

    char currentStatus = OFF;
    char lightStatus = AUTO;

    unsigned long autoDisconnectTime = 0,
     powerButtonReleaseTime = 0;

    WiFiServer wifiServer(80);
    WiFiClient client;

    unsigned long lastOn = 0,
     lastOff = 0;

    void changeStatusTo(char newStatus)
    {
     if(newStatus != currentStatus)
     {
     Serial.print("Status changed to ");
     Serial.println(newStatus);

     }
     currentStatus = newStatus;
    }

    void recordLightStatusChange(bool lightIn)
    {
     if(lightIn)
     lastOn = millis();
     else
     lastOff = millis();

    if(lightStatus == AUTO);
     digitalWrite(pinPowerLightOut, lightIn);

    }
    void statusChange()
    {
     bool currentLightStatus = !digitalRead(pinPowerLightIn);

    if(lastOn != 0 && lastOff != 0)
     {
     if((millis() < lastOn + 4000) && (millis() < lastOff + 4000))
     {
     changeStatusTo(SLEEP);
     recordLightStatusChange(currentLightStatus);
     return;
     }
     }

    if(currentLightStatus)
     changeStatusTo(ON);
     else
     changeStatusTo(OFF);

     recordLightStatusChange(currentLightStatus);
    }

    void Print(String toPrint)
    {
     client.print(toPrint);
     Serial.print(toPrint);
    }
    void Println(String toPrint)
    {
     client.println(toPrint);
     Serial.println(toPrint);
    }

    void processCommand(String command)
    {
     Serial.print(F("Received command "));
     Serial.println(command);

    if(command.equalsIgnoreCase(F("status")))
     {
     Print("Status: ");
     if(currentStatus == ON)
     Println("On");
     else if(currentStatus == OFF)
     Println("Off");
     else if(currentStatus == SLEEP)
     Println("Sleeping");
     }
     else if(command.equalsIgnoreCase(F("on")))
     {
     if(currentStatus != ON)
     {
     Println("Power Button Pressed (powering on)");
     pressPowerButton(buttonPressTime);
     }
     else
     Println("Machine is already on (button not pressed)");

    }
     else if(command.equalsIgnoreCase(F("off")))
     {
     if(currentStatus == ON)
     {
     Println("Power Button Pressed (powering off)");
     pressPowerButton(buttonPressTime);
     }
     else
     Println("Machine is already off (button not pressed)");

    }
     else if(command.equalsIgnoreCase(F("reset")))
     {
     unsigned long releaseTime = millis() + 500;
     digitalWrite(pinResetButton, HIGH);
     while(millis() < releaseTime)
     {}
     digitalWrite(pinResetButton, LOW);

    Println("Reset Button Pressed");
     }
     else if(command.equalsIgnoreCase(F("force off")))
     {
     if(currentStatus != OFF)
     {
     Print("Holding Power Button for 10 seconds...");
     pressPowerButton(10000);
     }
     }
     else if(command.equalsIgnoreCase(F("pressPwr")))
     {
     digitalWrite(pinPowerButton, HIGH);
     Println("Power Button Pressed");
     }
     else if(command.equalsIgnoreCase(F("releasePwr")))
     {
     digitalWrite(pinPowerButton, LOW);
     Println("Power Button Released");
     }
     else if(command.equalsIgnoreCase(F("light on")))
     {
     setLightStatus(ON);
     }
     else if(command.equalsIgnoreCase(F("light off")))
     {
     setLightStatus(OFF);
     }
     else if(command.equalsIgnoreCase(F("light auto")))
     {
     setLightStatus(AUTO);
     }
    }

    void setLightStatus(char newStatus)
    {
     if(newStatus == ON)
     {
     digitalWrite(pinPowerLightOut, HIGH);
     Println("Light On");
     return;
     }

     if(newStatus == OFF)
     {
     digitalWrite(pinPowerLightOut, LOW);
     Println("Light Off");
     return;
     }

     if(newStatus == AUTO)
     {
     Println("Light Set to Auto");
     setLightStatus(currentStatus);
     }

    }

    void pressPowerButton(int duration)
    {
     powerButtonReleaseTime = millis() + (duration);
     digitalWrite(pinPowerButton, HIGH);
    }

    void runRoutineChecks()
    {
     checkIfPowerNeedsToRelease();

    if((millis() > lastOn + 4000) && (millis() > lastOff + 4000))
     statusChange();
    }

    void checkIfPowerNeedsToRelease()
    {
     if(powerButtonReleaseTime != 0)
     {
     if(millis() >= powerButtonReleaseTime)
     {
     digitalWrite(pinPowerButton, LOW);
     powerButtonReleaseTime = 0;
     Println("Power Button Released");
     }
     }
    }

    /////////////----------------------------------------------------------------------------

    void setup() {
     Serial.begin(115200);
     pinMode(pinPowerLightIn, INPUT_PULLUP);
     pinMode(pinPowerLightOut, OUTPUT);
     pinMode(pinPowerButton, OUTPUT);
     pinMode(pinResetButton, OUTPUT);

     attachInterrupt(digitalPinToInterrupt(pinPowerLightIn), statusChange, CHANGE);

     WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED)
     {
     delay(1000);
     Serial.println("Connecting..");
     }

    Serial.print("Connected to WiFi. IP:");
     Serial.println(WiFi.localIP());

     wifiServer.begin();
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////

    void loop()
    {

     runRoutineChecks();

     client = wifiServer.available();
     if (client)
     {
     while (client.connected())
     {
     String comm = "";
     while (client.available()>0)
     {
     char c = client.read();

    autoDisconnectTime = millis() + 60000;

     if(c == ';')
     {
     processCommand(comm);
     comm = "";
     }
     else
     {
     comm.concat(c);
     }
     }
     runRoutineChecks();
     if(autoDisconnectTime > 1000 && millis() > autoDisconnectTime)
     {
     Serial.println("Client timeout");
     client.stop();
     }
     }
     client.stop();
     Serial.println("Client disconnected");
     autoDisconnectTime = 0;
     }
    }

```

The ERROR :-

```
NODEMCU:2:30: error: 'D1' was not declared in this scope; did you mean 'y1'?
    2 | const int pinPowerLightOut = D1,
      |                              ^~
      |                              y1
C:\Users\wahid\Documents\Arduino\NODEMCU\NODEMCU.ino: In function 'void statusChange()':
NODEMCU:61:42: error: 'pinPowerLightIn' was not declared in this scope; did you mean 'pinPowerLightOut'?
   61 |   bool currentLightStatus = !digitalRead(pinPowerLightIn);
      |                                          ^~~~~~~
      |                                          pinPowerLightOut
C:\Users\wahid\Documents\Arduino\NODEMCU\NODEMCU.ino: In function 'void processCommand(String)':
NODEMCU:118:24: error: 'buttonPressTime' was not declared in this scope
  118 |       pressPowerButton(buttonPressTime);
      |                        ^~~~~~~
NODEMCU:130:24: error: 'buttonPressTime' was not declared in this scope
  130 |       pressPowerButton(buttonPressTime);
      |                        ^~~~~~~
NODEMCU:140:18: error: 'pinResetButton' was not declared in this scope
  140 |     digitalWrite(pinResetButton, HIGH);
      |                  ^~~~~~
NODEMCU:158:18: error: 'pinPowerButton' was not declared in this scope; did you mean 'pressPowerButton'?
  158 |     digitalWrite(pinPowerButton, HIGH);
      |                  ^~~~~~
      |                  pressPowerButton
NODEMCU:163:18: error: 'pinPowerButton' was not declared in this scope; did you mean 'pressPowerButton'?
  163 |     digitalWrite(pinPowerButton, LOW);
      |                  ^~~~~~
      |                  pressPowerButton
C:\Users\wahid\Documents\Arduino\NODEMCU\NODEMCU.ino: In function 'void pressPowerButton(int)':
NODEMCU:212:16: error: 'pinPowerButton' was not declared in this scope; did you mean 'pressPowerButton'?
  212 |   digitalWrite(pinPowerButton, HIGH);
      |                ^~~~~~
      |                pressPowerButton
C:\Users\wahid\Documents\Arduino\NODEMCU\NODEMCU.ino: In function 'void checkIfPowerNeedsToRelease()':
NODEMCU:232:20: error: 'pinPowerButton' was not declared in this scope; did you mean 'pressPowerButton'?
  232 |       digitalWrite(pinPowerButton, LOW);
      |                    ^~~~~~
      |                    pressPowerButton
C:\Users\wahid\Documents\Arduino\NODEMCU\NODEMCU.ino: In function 'void setup()':
NODEMCU:246:11: error: 'pinPowerLightIn' was not declared in this scope; did you mean 'pinPowerLightOut'?
  246 |   pinMode(pinPowerLightIn, INPUT_PULLUP);
      |           ^~~~~~~
      |           pinPowerLightOut
NODEMCU:248:11: error: 'pinPowerButton' was not declared in this scope; did you mean 'pressPowerButton'?
  248 |   pinMode(pinPowerButton, OUTPUT);
      |           ^~~~~~
      |           pressPowerButton
NODEMCU:249:11: error: 'pinResetButton' was not declared in this scope
  249 |   pinMode(pinResetButton, OUTPUT);
      |           ^~~~~~
exit status 1
'D1' was not declared in this scope; did you mean 'y1'?

```

# Answer
> 0 votes
Only for some esp8266 dev boards Dx pins are defined. The constants map esp module pin numbers to board's pin numbers (for example on most of them D1 is io 4).

**If you have a dev board with Dx labels on the PCB, then select the right board in Tools menu.**

For plain esp8266 module use pin numbers in code. If the author of the code had a Wemos D1 mini or a NodeMci dev board, use the Dx definitions in the header file to map the Dx pins to esp8266 pins.

Note that on esp8266 not all pins are general purpose IO. Some have limited usage, so use the same esp8266 pins as the author of the code.

---
Tags: arduino-uno, esp8266
---


# Question
Title: How to limit backlight LED current in 16x2 LCD
I'm getting the error "**Current through backlight led is 23.7 kA, while maximum is 20.0 mA**". What am I doing wrong?

```
#include <LiquidCrystal.h>

LiquidCrystal lcd(1, 2, 4, 5, 6, 7);

void setup()
{
  lcd.begin(16,2);
}

void loop()
{
  lcd.print("Arduino");
  delay(3000);
}

```

# Answer
> 3 votes
The two pins on the LCD which are marked "LED" are directly connected to the backlight LED. If you drive an LED over its forward voltage the current is rising exponential in relation to the voltage. Thus every LED needs a current limiting circuit, like a simple resistor in series. Otherwise the current through the LED will be so high, that it gets fried.

So to solve the problem you should place a resistor in series with the backlight LED (so for example between Vcc and the positive LED pin). The needed resistor value depends on the LED. The error message states 20mA max (just like a digital output pin on an Arduino), thus a value above R = U/I = 5V/20mA = 250 Ohm will be enough to hold the current below the maximum. To have a safety margin I would start with like 300 Ohm (depending on whats available).

# Answer
> 1 votes
You need to limit the current going to the backlight LED by putting a resistor in series with the LED.

Currently you have the LED wired to 5V and Ground with nothing to limit the current. This will result in the LED failing from over-current.

You will want to install a 330 ohm resistor in series with the LED, like illustrated in the image below. (Note the data lines are not shown to make the circuit simpler.)

---
Tags: arduino-uno, lcd
---


title: Breathing LEDs on single PWM pin?

text:
# Question
Title: Breathing LEDs on single PWM pin?
I'm doing a project which is essentially a lighted cube, that communicates status through different colors, where I get this ides \[it\]\[1\] (having code). So when the light goes below a certain level it turns a certain color, when temp goes above a certain level it turns another color, etc. I'm figuring I'll probably need anywhere from 2 to 4 LEDs per color to get a nice intensity, and the colors would breathe, which is pretty easy with PWM on the arduino.

What I'm thinking is that I'm going to leave all the colors in phase. So that the intensity ramp on red is the same as yellow, is the same as green, etc. That would require only a single PWM output and most importantly, a single section in the code, which would make writing easier.

The solution I've come up with is to have the PWM pin drive a MOSFET, and give it the modulation, and the MOSFET would repeat the "breathing" pulse to all the LEDs. Then each color gets switched on or off through a transistor by other pins on the arduino that simply go high or low.

I figure an IRF630, which has an insanely high drain current for this purpose should be more than enough for whatever I might plug into it. And for the switching of each color, maybe an N2222, 4 LEDs will go at about 80 mA max anyway.

So, why not just drive each color from a PWM output? Any thoughts on the circuit? Sound like it could work?

\[1\]: https://www.kynix.com/Blog/Arduino-Complete-Guide-for-Beginners-with-Examples.html Code Source

# Answer
From your description I think you are wanting this arrangement:

simulate this circuit – Schematic created using CircuitLab

There is no logical problem with that arrangement. However you must watch the total current being provided by each GPIO pin. You must not go above 40mA peak, and you should not go above 25mA sustained.

It may be better to provide the 5V to the LEDs through a P-channel MOSFET per bank to allow for higher current:

simulate this circuit

Note that here the operation of the GPIO is reversed: the gate of the P-channel MOSFET must be pulled LOW to turn it on.
> 1 votes

---
Tags: arduino-uno, led, pwm
---


# Question
Title: How to execute programs based on received bluetooth value - wake-up-light (ESP32)
I'm trying to execute programs on my arduino based on values received via bluetooth. Although I've experimented a lot, I'm unable to get the code to work.

I have build a simple android app with three buttons that sends either value "11", "21" or "31" to the arduino over bluetooth, which should trigger the code to operate a DIY wake-up-light (ESP32 + NeoPixels). Can anyone tell me what I'm doing wrong? Thanks in advance!

```
#include "BluetoothSerial.h"
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

// init Class:
BluetoothSerial ESP_BT;

#define LED_PIN    5
#define LED_COUNT 7

Adafruit_NeoPixel matrix = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  matrix.begin();
  matrix.show(); // Initialize all pixels to 'off'

  Serial.begin(19200);
  ESP_BT.begin("Wake_Up_Light"); //Name of Bluetooth interface
}

int led_pin_1 = 5;
int incoming;

void loop() {

// ------------ call wakeup program or gotosleep program ----------------
  if (ESP_BT.available())
  {
    incoming = ESP_BT.read(); //Read what we receive

    int rnumber = incoming;

    switch (rnumber) {
      case 1:
        Serial.print("11"); //----- Activate wake-up light after 6 hours -----
          6hours();
          wakeup();
          ledsoff();
        break;

      case 2:
        Serial.print("21"); //----- Activate go-to-sleep mode -----
          gotosleep();
        break;

      case 3:
        Serial.print("31"); //----- Activate powernap mode -----
          gotosleep();
          wakeupdelay();
          wakeup();
          ledsoff();
        break;
      }
  }
}

void wakeup() {

    uint16_t i, j;

  for (j = 1; j < 10; j++) {
    for (i = 0; i <LED_COUNT; i++) {
      matrix.setBrightness(255);
      matrix.setPixelColor(i, 3, j, j);
    }
    matrix.show();
    delay(18000); //-------- 180.000ms (3 minutes) / 10 steps = 18.000 ---------
  }
}

void gotosleep() {

    uint16_t i, j;
  for (j = 10; j > 0; j--) {
    for (i = 0; i <LED_COUNT; i++) {
      matrix.setBrightness(255);
      matrix.setPixelColor(i, 3, j, j);
    }
    matrix.show();
    delay(16363); // ---- 180000ms (3 minutes) / 11 steps = 16363 --------
  }
  matrix.setBrightness(0);
  delay(40000); // ---- 40 seconds delay
  }

void wakeupdelay() {
  delay(1200000);
}

void ledsoff() {
    matrix.setBrightness(0);
}

void 6hours() {
  delay(21600000)
}

```

# Answer
Thanks for the replies. I've taken another aproach and was able to get the code to work. I'll post it here. Not yet 100% finished, but mostly doing what I wanted.

```
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "BluetoothSerial.h"
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN    5
#define LED_COUNT 7

Adafruit_NeoPixel matrix = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

String  Recvd;
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial ESP_BT;
void printDeviceAddress() {

const uint8_t* point = esp_bt_dev_get_address();

for (int i = 0; i < 6; i++) {
   char str[3];
   sprintf(str, "%02X", (int)point[i]);
   Serial.print(str);
   if (i < 5){
   Serial.print(":");}
}
Serial.println();
}

void setup()
{
Recvd = "";

Serial.begin(19200);

  ESP_BT.begin("Wake_Up_Light");
  Serial.println("Address:");
  printDeviceAddress();

}

int led_pin_1 = 5;
int incoming;

void loop()
{
matrix.setBrightness(0);
matrix.show();
    if (ESP_BT.available()) {
      Recvd = (ESP_BT.read());
      Serial.println("Received value:");
      Serial.println(Recvd);
      if (Recvd == "11") {
        Serial.println("Running wake-up>6hr mode");
        sixhours();
        wakeup();
        ledsoff();

      }
      if (Recvd == "21") {
        Serial.println("Running go-to-sleep mode");
        gotosleep();

      }
      if (Recvd == "31") {
        Serial.println("Running powernap mode");
        gotosleep();
        wakeupdelay();
        wakeup();
        ledsoff();

      }

    }

}

void wakeup() {

    uint16_t i, j;

  for (j = 1; j < 10; j++) {
    for (i = 0; i <LED_COUNT; i++) {
      matrix.setBrightness(255);
      matrix.setPixelColor(i, 3, j, j);
    }
    matrix.show();
    delay(18000); //-------- 180.000ms (3 minutes) / 10 steps = 18.000 ---------
  }
}

void gotosleep() {

    uint16_t i, j;
  for (j = 10; j > 0; j--) {
    for (i = 0; i <LED_COUNT; i++) {
      matrix.setBrightness(255);
      matrix.setPixelColor(i, 3, j, j);
    }
    matrix.show();
    delay(16363); // ---- 180000ms (3 minutes) / 11 steps = 16363 --------
  }
  matrix.setBrightness(0);
  delay(40000); // ---- 40 seconds delay
  }

void wakeupdelay() {
  delay(1200000); // (20 minutes)
}

void ledsoff() {
    matrix.setBrightness(0);
}

void sixhours() {
  delay(21600000); // (6 hours)
}

```
> 1 votes

---
Tags: esp32, bluetooth
---


# Question
Title: How to allow cross-domain requests on ESP8266WebServer
I am using a Raspberry Pi running Chrome (handling the user interface) and connecting via ajax to an Arduino D1 compatible using the IP address as follows:

```
    $.ajax({
        type: "GET",
        url: "http://10.1.1.100/myfunc?id=5",
        error:  function(jqXHR, exception, response) {
                console.log(exception, response);

        etc...

```

I recently started getting this error (wonder why it didn't happen for the last two years):

```
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://10.1.1.100/myfunc?n=1. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

```

I tried various things including setting the browser (Chrome) to `--disable-web-security` and various suggestions, here and here (and many more) but I can't seem to get it to work. Currently, I have:

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
ESP8266WebServer server(80);

void handleRoot() {
  server.send(200, "text/plain", "Root of WebServer!");
}

void setup() {
IPAddress ip(10.1.1.100);
IPAddress gateway(10.1.1.1);
IPAddress subnet(...);
WiFi.begin(ssid, password);
WiFi.config(ip, gateway, subnet);
  // put your setup code here, to run once:
  WiFi.begin(ssid, password);
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  server.on("/", handleRoot);

  server.on("/myfunc", [](){
    String message = "";
    message += "URI: ";
    message += server.uri();
    message += "\nMethod: ";
    message += (server.method() == HTTP_GET)?"GET":"POST";
    message += "\nArguments: ";
    message += server.args();
    message += "\n";
    for (uint8_t i=0; i<server.args(); i++){
      message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
    }
      String num = server.arg(0);

    server.send(200, "text/plain", message);
 });
  server.on("/myfunc", HTTP_OPTIONS, []() {
    server.sendHeader("Access-Control-Allow-Origin","*")
    server.send(204);
 });

  server.onNotFound(handleNotFound);
  server.begin();
}

void loop() {
  delay(1000);
  ...
  server.handleClient();
}

void handleNotFound(){
  String message = "Error!";
  server.send(404, "text/plain", message);
}

```

So what am I doing wrong? Also, one complication that might crop up later is that the domain from where I am calling this in ajax is https and from what I understand https and http are not compatible with cross-domain requests.

Any help is appreciated!

# Answer
> 10 votes
Add the CORS header to every response, not only for 'preflight' OPTIONS request. The OPTIONS support is optional, but the response returning the 'shared resource' must contain the CORS header

`"Access-Control-Allow-Origin: *"`

EDIT: since 2020, the library has `server.enableCORS(true);`

# Answer
> 4 votes
just add this line before every response:

`server.sendHeader("Access-Control-Allow-Origin", "*");`

# Answer
> 4 votes
```
server.enableCORS(true);

```

The server will add the response `Access-Control-Allow-Origin=*` header

---
Tags: esp8266, wifi, web-server, raspberrypi
---


# Question
Title: Mega 2560 with Adafruit Music Maker and TFT - Pin reroute
I'm building a custom headunit for my motorcycle using the Arduino platform. I wanted to try it as the modular nature of the board and shields looked very versatile. While there does seem to be plenty of documentation on how to use a single shield on a board, there seems to be very scant documentation on how to use multiple shields on a single board.

I tested the Adafruit Music Maker and the TFT separately. My code for each works as expected. However, when I stack them, I run into the issue of how to call each shield to perform it's task.

The issue is the shield pinouts. The MM uses the ICSP to communicate with the board so all I need are:

* MCS pin - set to pin D7
* DCS pin - set to pin D6
* CCS pin - set to pin D4
* DREQ pin - set to pin D3 (also a Mega interrupt pin)

By itself, the MM shield works correctly using these pins, but in order for the TFT to work, the TFT needs pins D2 to D9 to send LCD data. That means I need to reroute D3,4,6, & 7 for the MM so the signals to the TFT are not interfering on those pins.

I noticed those pins have corresponding hole-throughs on the board.

Can I use these hole-throughs to redirect the pins to other digital pins on the Mega?

# Answer
> 1 votes
Yes, you can. However you will need to isolate them from the existing pins.

If you flip the shield over you should see a set of bridged solder jumpers:

You will need to take a small, sharp, craft knife (or something similar) and cut the little track that joins the pads together. If the time ever comes that you want to "undo" that cutting you can just bridge the pads with solder.

---
Tags: arduino-mega, adafruit, tft
---


# Question
Title: How to install Adafruit motorshield library in arduino-cli
I need to install this library using the arduino-cli software. I don't know what name to use for the library. Using

```
arduino-cli lib install <library_name>

```

I have tried `Adafruit_MotorShield`, `Adafruit_MotorShield_V2`, and other random combinations and in all cases it cannot found it. In the library manager of the graphical interface it is this one:

# Answer
As pointed out by Juraj♦ in the comments, the name to use can be found in the `library.properties` file. There we find `name=Adafruit Motor Shield V2 Library` so the command to install the library is:

```
arduino-cli lib install Adafruit\ Motor\ Shield\ V2\ Library

```

Note the white spaces are escaped.
> 1 votes

---
Tags: library, adafruit, arduino-cli
---


title: RF Keyfob single button code

text:
# Question
Title: RF Keyfob single button code
I'm making a project where a 2 channel RF keyfob (433Mhz) controls an led using arduino nano. As for the hardware everything works and I have tested it with the example decoder code and it works fine. Library I'm using is the RCSwitch.h for receiving.

I have modified the library example code a bit to suit my project. What I'm basically trying to achieve is make an led turn on when I press button A on the keyfob and after a while if I press button A again then the led must turn off. However with my current code, what happens is pressing button A makes the led turn on and pressing button A again does nothing, but if I press button B then the led turns off. So where did I go wrong?

Here is my code

```
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();
int LED = LED_BUILTIN;
boolean statusled = LOW;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
}

void loop() {
  if (mySwitch.available())
  {
    Serial.print(mySwitch.getReceivedValue());
    unsigned long int num = mySwitch.getReceivedValue();
    Serial.print(num);

    if (num == 16130609){
    mySwitch.disableReceive();

      if (statusled == LOW)
      statusled = HIGH;
    }
    else
    {
      statusled = LOW;
    }

    digitalWrite(LED, statusled);
    unsigned long time_now = millis();
    int ck = 500;
    while(millis() <time_now + ck)
    {;}

    mySwitch.resetAvailable();
    mySwitch.enableReceive(0);
  }
}

```

16130609 is the value I get from decoding button A

16130610 is the value from button B

# Answer
Look again at your logic here:

```
if (num == 16130609){
    mySwitch.disableReceive();

    if (statusled == LOW) statusled = HIGH;
}
else
{
    statusled = LOW;
}

```

When you press A you will get `num` with the value `16130609`. In the if you turn the LED on, if it is off currently. But you never turn it off there. You will always get in this if statement when pressing A. You don't turn the LED off there, so it doesn't turn off when you press A. When you press B you get another value for `num`. Thus the else clause will get executed, turning the LED off.

So the code is doing exactly, what you told it to do.

**Solution:** Since you want to toggle the LED on press of A, you should just toggle the value of `statusled` in there, instead of explicitly setting it. That would look like this:

```
if (num == 16130609){
    mySwitch.disableReceive();

    statusled = !statusled;
}

```

I removed the else clause, since you don't want button B to do anything.
> 1 votes

---
Tags: programming, arduino-nano, wireless, rf
---


# Question
Title: Why map Arduino pins 2 and 3 to Rx and Tx instead of using the build in Rx and Tx pins?
In many examples I see the following:

```
#include <SoftwareSerial.h>

const byte rxPin = 2;
const byte txPin = 3;

// set up a new serial object
SoftwareSerial mySerial (rxPin, txPin);

```

what is the benefit of mapping pins 2 and 3 like this? Why not just use the built in RX (pin 0) and TX (pin 1) pins? I'm using a standard Arduino Uno.

# Answer
SoftwareSerial lets you add an additional serial port using "bit banging" to read/write to the port. This lets you connect up another serial device (eg. GPS, RFID reader, MIDI device, LCD) to this extra port, and still use the hardware serial interface (pins 0 and 1) via the USB port to send messages and/or debugging to the connected PC.

---

> Is there any special wiring needed to send messages to the connected PC? Or is it enough that they just not be in use?

Pins 0 and 1 are connected to the Atmega16U2 USB interface chip. If it gets what looks like serial data it will forward it to the PC.
> 2 votes

# Answer
Nick Gammon indicated Pins 0 (RX) and 1 (TX) are already connected to the USB-Serial 16U2 chip. Correct. Although the transmit pin, pin 1, can drive multiple devices / serial ports, the receive pin, pin 0, is being driven by the 16U2 chip. See: https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf Trying to use this would result in tying two outputs together (never good unless the outputs are configured for open collector/open drain). I've seen many shields that try to use pins 2 and 3 for a serial port. (Not a good idea for a serial peripheral...)
> 1 votes

---
Tags: arduino-uno, serial, softwareserial
---