# Question
Title: (Arduino Uno) PWM output (and servo plugged on it) becomes unstable if I use 1Wire on another pin
**Unnecessary context but hey I'm guessing you might be interested**

Hi, I want to build a PID temperature regulator with a servo that presses on a silicon pipe to adjust the flux of liquid passing through. The liquid is hot beer that must be cooled very quickly from 100°C to 25°C, and it passes through a heat exchanger where also passes in the other direction a constant flux of cold water. The lesser the flux of beer, the colder it becomes. But it is cumbersome to regulate it by hand and I'd like to automate it, because I (think I) can.

**Overview of the system**

My system is mainly composed of an Arduino Uno, a servo motor (PWM on pin 11), a BS18B20 1Wire temperature probe (on pin 2), and a few buttons. In 'manual' mode I can choose the position of the servo with the buttons and it is very stable.

I also have a buzzer on pin 13 and will add an I2C screen when the core works.

**My problem**

As soon as I start to request the temperature at regular intervals (like every 200 ms), the servo flickers all the time, which is boring, looks bad, and probably will reduce its life expectancy. I think every time I request a temperature something happens on the PWM, like a brief reset or something, and the servo reacts and then gets back to its original position.

The only power I've tested so far is the USB cable from the computer. In case you wonder, the code is here:

```
#include <AceButton.h> // https://github.com/bxparks/AceButton
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Servo.h>

Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards

#define ONE_WIRE_BUS 2 // pin for thermometer

using namespace ace_button;

// The pin number attached to the button.
const int BUTTON_SET_PIN = 12;
const int BUTTON_MORE_PIN = 4;
const int BUTTON_LESS_PIN = 0;

const int BUTTON_MODE2_PIN = 5;
const int BUTTON_MODE3_PIN = 7;

const int LED_PIN = LED_BUILTIN;
const int SERVO_PIN = 11;

const int MODE_THERMOMETER = 1;
const int MODE_REGULATOR = 2;
const int MODE_MANUAL = 3;
int mode;

// LED states. Some microcontrollers wire their built-in LED the reverse.
const int LED_ON = HIGH;
const int LED_OFF = LOW;

// Both buttons automatically use the default System ButtonConfig. The
// alternative is to call the AceButton::init() method in setup() below.
AceButton buttonSet(BUTTON_SET_PIN);
AceButton buttonMore(BUTTON_MORE_PIN);
AceButton buttonLess(BUTTON_LESS_PIN);

ButtonConfig modeConfig;
AceButton buttonMode2(&modeConfig);
AceButton buttonMode3(&modeConfig);

// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// variables for tune
float value = 50;
unsigned long tuneStart;
float max = 175;
float min = 10;

void handleModeEvent(AceButton *, uint8_t, uint8_t);

void handleModeEvent(AceButton *button, uint8_t eventType, uint8_t /* buttonState */) {
  switch (eventType) {
  case AceButton::kEventPressed:
    if (button->getPin() == BUTTON_MODE2_PIN) {
      mode = MODE_REGULATOR;
      printMode();
    }

    if (button->getPin() == BUTTON_MODE3_PIN) {
      mode = MODE_MANUAL;
      printMode();
    }
    break;
  case AceButton::kEventReleased:
    if (button->getPin() == BUTTON_MODE2_PIN) {
      mode = MODE_THERMOMETER;
      printMode();
    }
    if (button->getPin() == BUTTON_MODE3_PIN) {
      mode = MODE_REGULATOR;
      printMode();
    }
    break;
  }
}

void printMode()
{
  Serial.print("Mode ");
  Serial.println(mode);
}

void handleButtonEvent(AceButton *, uint8_t, uint8_t);

void setup() {
  Serial.begin(9600);
  while (!Serial); // Wait until Serial is ready - Leonardo/Micro
  Serial.println(F("Test 3 boutons - la suite en 115200 bps"));
  delay(300);

  // servo
  myservo.attach(11);

  // thermal probe
  sensors.begin();
  sensors.setWaitForConversion(false);
  sensors.setResolution(10);

  Serial.begin(115200);
  while (!Serial); // Wait until Serial is ready - Leonardo/Micro
  Serial.println(F("setup(): begin"));

  // Initialize built-in LED as an output.
  pinMode(LED_PIN, OUTPUT);
  pinMode(SERVO_PIN, OUTPUT);

  // Buttons use the built-in pull up register.
  pinMode(BUTTON_SET_PIN, INPUT_PULLUP);
  pinMode(BUTTON_MORE_PIN, INPUT_PULLUP);
  pinMode(BUTTON_LESS_PIN, INPUT_PULLUP);

  pinMode(BUTTON_MODE2_PIN, INPUT_PULLUP);
  pinMode(BUTTON_MODE3_PIN, INPUT_PULLUP);

  buttonMode2.init(BUTTON_MODE2_PIN);
  buttonMode3.init(BUTTON_MODE3_PIN);

  // Configure the ButtonConfig with the event handler, and enable all higher
  // level events.
  ButtonConfig *buttonConfig = ButtonConfig::getSystemButtonConfig();
  buttonConfig->setEventHandler(handleButtonEvent);
  buttonConfig->setFeature(ButtonConfig::kFeatureClick);
  buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
  buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);

  // Configs for the tune-up and tune-down buttons. Need RepeatPress instead of
  // LongPress.
  modeConfig.setEventHandler(handleModeEvent);
  modeConfig.setFeature(ButtonConfig::kFeatureClick);
  // These suppressions not really necessary but cleaner.
  modeConfig.setFeature(ButtonConfig::kFeatureSuppressAfterClick);

  // Check if the button was pressed while booting
  if (buttonMode3.isPressedRaw()) {
    mode = MODE_MANUAL;
    printMode();
  } else if (buttonMode2.isPressedRaw()) {
    mode = MODE_THERMOMETER;
    printMode();
  } else {
    mode = MODE_REGULATOR;
    printMode();
  }
  Serial.println(F("setup(): ready"));
}

long timer_200 = 0;
long timer_1000 = 0;

void loop() {
  // Should be called every 4-5ms or faster, for the default debouncing time of ~20ms.
  buttonSet.check();
  buttonMore.check();
  buttonLess.check();
  buttonMode2.check();
  buttonMode3.check();

  // every 200 ms
  long now = millis();
  if (now > timer_200 + 200) {
    timer_200 = now; // to reinit timer
    if (mode == MODE_MANUAL) {
      myservo.write(value);
    }
  }

  // every 1s
  if (now > timer_1000 + 1000) {
    timer_1000 = now; // to reinit timer
    // get temperature requested last time
    Serial.print("Temperature for Device is: ");
    Serial.println(sensors.getTempCByIndex(0));
    // and request a new one
    sensors.requestTemperatures(); // Send the command to get temperatures
    if (mode == MODE_THERMOMETER) {}
  }
}

// The event handler for both buttons.
void handleButtonEvent(AceButton *button, uint8_t eventType, uint8_t buttonState) {
  switch (eventType) {

  case AceButton::kEventClicked:
    if (button->getPin() == BUTTON_MORE_PIN) {
      value = value * 1.01;
      if (value > max) {
        value = max;
      }

      Serial.println(value);
    }

    if (button->getPin() == BUTTON_LESS_PIN) {
      value = value * .99;
      if (value < min) {
        value = min;
      }
      Serial.println(value);
    }

    if (button->getPin() == BUTTON_SET_PIN) {
      Serial.println(F("set"));
    }
    break;

  case AceButton::kEventLongPressed:
    if (button->getPin() == BUTTON_SET_PIN) {
      Serial.println(F("set long press"));
    }

    if (button->getPin() == BUTTON_MORE_PIN || button->getPin() == BUTTON_LESS_PIN) {
      tuneStart = millis();
    }
    break;
  case AceButton::kEventRepeatPressed:

    if (button->getPin() == BUTTON_MORE_PIN) {
      tuneUp();
    }

    if (button->getPin() == BUTTON_LESS_PIN) {
      tuneDown();
    }
    break;
  }
}

void tuneUp() {
  unsigned long duration = millis() - tuneStart;
  float ratio = 1 + (0.00001f * 4 * duration);
  value = value * ratio;
  if (value > max) {
    value = max;
  }
  Serial.println(value);
}

void tuneDown() {
  unsigned long duration = millis() - tuneStart;
  float ratio = 1 - (0.00001f * 4 * duration);
  value = value * ratio;
  if (value < min) {
    value = min;
  }
  Serial.println(value);
}

```

It's still quite a prototype.

What could cause this and how can I prevent it?

# Answer
> 1 votes
I suspect the 1Wire libary disables (and enables) interrupts when it sees fit. This will cause servo "hickups" because the servo library uses interrupts.

If I'm right then your best bet is using a servo library that doesn't use interrupts. I always use a hardware PWM library for driving servos, so I have no servo library recommendations to make, but maybe somebody else has.

Also: you are doing a `Serial.begin()` twice, and the variables you use for timing (using `millis()`) should be `unsigned long`, not `long`.

---
Tags: arduino-uno, pwm, 1-wire
---


# Question
Title: Stepper not working properly using L298N
If googled and search here but can't find the same issue. I'm using an Arduino Uno, L298N driver (5v jumper is off - actually just 2 holes where the jumper pins were supposed to be), scavenge stepper motor from a 5 inch drive - TEAC P.no. 14769070-90 (we call it a floppy drive). I used the example from the Arduino IDE that spins the stepper in on direction and then the other.

The stepper motor has a 5 wire ribbon and with an LED test showed that the out side two wires are a pair. I've look at schematics for the 5 wire, I know it's got to do with the uni/bi polar of the motor but I have no idea if I need to connect this middle wire?

I've wired it according to this Maker Guides article

**The issue is that in the clockwise direction it is very weak and it just vibrates in the anti-clockwise direction.**

**How do I go about diagnosing the issue?**

(I'm on a beginner level with regards to hw. Sw engineer with a Solder iron - very dangerous)

# Answer
> 1 votes
The motor you got is a unipolar stepper motor. The five wires are one end of the four windings inside the motor, plus a common wire that connects all the other poles together.

Bipolar motor offer more torque than unipolar, at the expense of a more difficult control. 6 wires unipolar stepper motors can be converted to bipolar motors just selecting the correct wires. I am not aware of any method to convert a 5 wires unipolar motor to bipolar that does not imply tearing it apart (which is not really a great idea).

The L298 is not really made to drive this kind of motor, it is best suited to drive bipolar motors (can still drive it tho, please read the next paragraph). Good news, driving unipolar steppers is rather simple. You basically have to connect the common wire to you V+ rail and connect the other wires to GND via BJT/MOS. Don't connect them directly to the Arduino! It's the perfect recipe for fried chips. You can either choose to use discrete transistors or arrays like the ULN2003.

If you still want to use the L298 to drive the motor you can exploit the lower transistors of the H-bridge. Connect Vss and the enable pins to 5V, Vs to your positive rail voltage and pin 1, 8, 15 to GND. Then connect each phase to each output and the input to 4 pins to an Arduino/microcontroller. Leave the pins normally on and turn one off in turn (1-\>2-\>3-\>4-\>1...) and your stepper should run! This works because when you leave the pins on, the upper side of the H-bridge is powered on, thus shorting the winding. When you turn one pin off the lower part of the bridge will actually turn on and let the current flow to GND, closing the circuit and powering the winding. Using this kind of circuit you could also omit the freewheeling diodes needed to discharge the windings (as said before, you short them, allowing current to freely circulate).

EDIT/TLDR: Connect the windings to the output of the L298 and the common one to the positive rail. Keep the pins high and turn one sequentially off, you should see the motor move.

# Answer
> 0 votes
Take a look at this video \- it has a great explanation of using a 5-wire stepper motor with an Arduino

---
Tags: arduino-uno, stepper, l298n
---


# Question
Title: Can we generate 20kHz tone with normal buzzer in arduino?
Can normal buzzer be used for generating high frequency audio and if this is possible then can normal microphone module be able to detect the same frequency range(15 kHz - 20 kHz).

Here is the specifications of this buzzer:-

```
Rated Voltage : 6V DC
Operating Voltage : 4 to 8V DC
Rated Current* : ≤30mA
Sound Output at 10cm* : ≥85dB
Resonant Frequency : 2300 ±300Hz
Tone : Continuous
Operating Temperature : -25°C to +80°C
Storage Temperature : -30°C to +85°C
Weight : 2g
*Value applying at rated voltage (DC)

```

# Answer
An arduino is very well capable of producing a 20KHz signal. You can use a PWM signal on one of the PWM pins, generate the signal by alternating a pin high and low with a few microseconds in between or you can use a buzzer with an input signal that can play a continuous tone at a specified frequency. I really can't see if the module you show can generate a tone based on the input.

Detecting a tone, however is somewhat difficult. You need an analog microphone amplifier, an ADC (analog-to-digital-converter) and some processing to detect a frequency in the signal data.

The usual microphone modules that are sold for arduino's are mostly just noise detectors and generate a signal when loud noise is present.
> 2 votes

# Answer
As others have noted, the frequency range of the buzzer is given in the data sheet. This is a mechanical property, like the tone of a bell; you can't change it electrically. So if you really need to generate high frequency audio, you need a different type of device. Something like a speaker whose output is controlled by its input signal. You don't mention what you are planning on using this for, which might make a difference in your options. There are inexpensive piezo tweeters that work in this range, but they typically have very ragged frequency responses. Actually, *most* transducers in this range do, but dynamic types tend to be better, though more expensive and less efficient.

If you want to generate controllable high frequencies with Arduino, you might want to look at my open-source DaqPort sketch. This is intended to be controlled by a computer over USB and includes data acquisition as well as generation, but the oscillator portion can run as a stand-alone. The sketch is included with my Daqarta software, which is free for Arduino use. Daqarta includes the Arduino\_Oscillators mini-app, which is described here: https://www.daqarta.com/dw\_rrss.htm The oscillators are also used by the DaquinOscope mini-app https://www.daqarta.com/dw\_rrss.htm which does simultaneous acquisition, but it uses the computer for display so it's not stand-alone.

Microphones should not be a problem; many inexpensive electrets can handle this range. But we really need to know more about your plans.
> 0 votes

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


# Question
Title: Shift between the carrier frequency of the signal transmitted with arduino and my garage door RC (433 mhz)
I have this 433 mhz transmitter and receiver for arduino.

I want to replay my garage door remote control with this transmitter so I reversed the RC (remote control) signal with RTL-SDR/sdrsharp and audacity. It is not working.

Why is there a shift between the carrier frequency of the signal transmitted with arduino (RH\_ASK library) and my garage door RC ?

How can I change this ?

# Answer
> 2 votes
The reason is that your garage door opening is operating on a different carrier frequency than your transmitter module. The plot you are showing is called a "waterfall" plot and shows the frequency on the "x" axis with time progressing from top-to-bottom.

The garage door remote appears to be centered just above 433.900 MHz while your transmitter is around 434.000 MHz. While that might not seem like a large difference, these things are designed to be receptive in a very narrow band.

So you need to read the specifications of your transmitter module and see if its frequency is adjustable and, if so, adjust it upward to the correct frequency.

# Answer
> 1 votes
Are you certain about what modulation is used by your garage door?
There are relatively strong side bands on 433.800 MHz. While most of the signal is at 433.900 MHz this might be an FSK variant instead of ASK modulated signal. In that case you will not be able to use this transmitter for your task. Usually taking apart your remote and searching for the IC numbers will give you more insight about what is being used. If you find an FCC-ID on your remote, you can try to find information that way as well.

# Answer
> 0 votes
The term "433MHz" refers not to a frequency, but to a *band*. That is, a range of frequencies, officially defined as 433.05MHz to 434.79MHz. You are free to use any frequency within that range you choose for your carrier frequency. The manufacturers of the garage door opener have chosen one frequency, your TX/RX are tuned to another frequency.

If you want to receive the frequency your opener transmits at then you will need a receiver tuned to that exact frequency. If you want your garage door to receive your signals then you will need a transmitter tuned to the correct exact frequency.

You can think of it as a normal radio. "433MHz" is akin to "The FM band". Within that band are a number of stations, all with their own frequency. Your TX/RX pair are tuned to BBC Radio 2, but the garage door is working on Classic FM (replace with two radio stations that mean something to you...)

---
Tags: rf, remote-control
---


# Question
Title: Sound localization using two mics, Arduino Uno on MATLAB
I have been trying to achieve this for a long time using the ITD method and have gone through various articles on the net.

I want to know if its possible to actually achieve sound localization using an Arduino Uno and two MEMS mics with a high gain (https://www.sparkfun.com/products/9868).

I have been trying this on MATLAB using the a=arduino() command and readVoltage command but the main issue I face is that for a particular sound (clapping for instance) the time difference between the two mics is not always the same which results in different direction predictions.

We managed to increase the low resolution of the Arduino by removing unnecessary operations. Now we are able to get an array of size 750 for 10 secs giving a resolution of 0.01 secs. I am not sure if that is enough.

I basically have 3 arrays, one storing the sampling times, and the other two storing the amplitudes of the two analog inputs at that particular time in the first array.

Now I look for a peak in one and then the corresponding near peak in the second one and then compute the time difference. After this I can compute the angle using the speed of sound and the distance between the mics.

Please let me know how I can make this work or where I am going wrong.

# Answer
> 1 votes
Let's assume a microphone distance of 0.5m (which may be just small enough for you). Sound travels with about 300m/s in normal conditions. Let's also say, that you want at least a precision in the angle measurement of 15°.

As stated in the project Mikael linked, it is important that the distance to the sound source is big enough (so that the waves can be seen as planar). Then you have the following situation:

We are interested in the difference in distance, that the waves have to travel to the two microphones. It can be calculated by `delta s = d * sin(alpha)`. With `15°` we get `delta s = 0.13m`. The time difference is calculated by `delta t = delta s/v`, where `v` is the speed of sound. We get `delta t = 0.43ms` which equates to `2.32kHz` sampling frequency. Since we use two microphones that must be sampled sequentially, the sampling frequency must be doubled. In the end we have a sampling frequency of `4.64kHz`. So your sampling time of `0.01s` wouldn't be enough for that.

The largest time difference in this setup (with the sound source in line with the microphones) would be `1.6ms`, so your sampling time would be too big even for this.

Regarding the transmission with a baudrate of say 115200 baud this shouldn't be a problem.

But the actual speed of your setup highly depends on your code, which you haven't shown. Maybe this forum post can help you going further.

# Answer
> 1 votes
You should use the Arduino interrupt function. This will get it to 4 micros. You cannot use delay on Arduino counting in micros that is needed. You can have ca 10 cm between mics doing as follows:

You may use accelerometer instead of mic. Serial read, don't work, too slow. Use ISR..together with Arduino clock is 16 MHz. Gives a error in +- 10 micros. Given that it's possible to get the angle within 0.5 degrees if using Sine/Cosine. But, the trigg appear at different places on the waves sinus, giving you extra errors at low freq.

Don't give up. This works:

1. Attach interrupt (ISR) on 2 pins. Make all variable used in ISR volatile.
2. Use internal clock with micros() to stop at interrupt, flag a variable true if rising/falling/change.
3. Use the time difference from trigs for calculations.
4. Calculations do in loop, not ISR calculate using radians.
5. Don't try to read or write anything while in ISR or before calculations, that mess up the clock!
6. Use 11500 baudrate.
7. If in loop or ISR = true then disable interrupt by state variable.

---
Tags: arduino-uno, arduino-micro, sound
---


title: Library ADC MCP33121

text:
# Question
Title: Library ADC MCP33121
I'm looking for the Library of the ADC MCP33121 for Arduino UNO or functional code, I don't have enough tools for testing so I'd like to get some code already tested. I appreciate any help. Thanks... Josh

# Answer
> 2 votes
You don't really need a library for that chip. You just do a pair of SPI transfers with the CS pin low.

For example:

```
digitalWrite(pinCS, LOW);
uint8_t msb = SPI.transfer(0xFF);
uint8_t lsb = SPI.transfer(0xFF);
digitalWrite(pinCS, HIGH);

uint16_t val = (((uint16_t)msb << 8) | lsb);
val = val >> 2; // For 14 bit devices shift it twice. For 12 bit do it 4 times.

```

---
Tags: library, adc
---


# Question
Title: Arduino Pro micro Serial communication problem with Node MCU
I recently bought an ATmega32U4 based Arduino Pro micro. I am using the **Keyboard library** and interfacing with my PC via USB.

I am trying to create a serial communication between the Arduino Pro micro and a NodeMCU via Rx, Tx pins (0, 1), but it isn't working i.e. not giving any output with the code below on the Pro micro:

```
#include <Keyboard.h>

int incomingByte;
unsigned long lastTime;

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

void loop() {
  if (Serial.available() > 0) {
    lastTime = millis();
    String payload = "";

    while (1) {
      if (millis() - lastTime > 1000)
        break;

      incomingByte = Serial.read();
      Serial.println(incomingByte);
    }
  }

```

On the NodeMCU there is a simple script flashed which only writes on serial some characters in a delayed loop.

When using the **SoftwareSerial library** with the Pro micro, it is working fine i.e. I can read data sent by the NodeMCU on custom Rx, Tx pins (9, 10). I tried this because I thought since Pro micro is communicating with a PC, the original Rx and Tx pins are busy. But after some research I got to know that unlike other Arduino boards like the UNO, the Pro micro doesn't use those for communication over USB.

Although custom serial using **SoftwareSerial library** is working, it is too slow and unreliable i.e. it takes 2-3 seconds to pass a string of length 10. Also its unreliable because on sending bigger length strings, the strings arrive incomplete or sometimes the data gets corrupted (characters shuffle).

Again this is not my main concern, if I can use original Rx, Tx pins as usual on any other Arduino boards, it solves my issue.

This is my circuit diagram:

# Answer
RX and TX pin of Arduino Micro are Serial1. Replace `Serial` in your sketch with `Serial1` to communicate with esp8266 over RX and TX pin.
> 0 votes

---
Tags: serial, nodemcu, arduino-micro, arduino-pro-micro, atmega32u4
---


title: ESP32 Bluetooth SPP Max Speed

text:
# Question
Title: ESP32 Bluetooth SPP Max Speed
I am trying to understand the maximum BT SPP transmission speed that can be achieved using ESP32.

What my project requires is to send 2bytes of data every 200us (5kHz) AND additional 15bytes of data every 50ms(20Hz) via BT.

I am trying to achieve that using BT SPP, however, I could not understand the speed of BluetoothSerial::write AND BluetoothSerial::print.

Based on my testing for 5kHz, the BluetoothSerial::write freezes after 2-3 seconds of connection.

BluetoothSerial::println function doesn't seem to freeze, however, the time taken for the function to complete doesn't seem to be constant. Please refer to the code below on how I measure the time taken for the function to complete.

The picture below shows the time in microseconds each time the function (dataFormat()) takes place. If you look through, there are 2 instances where the time duration is more than an average 0f 80us.

I would like to know, ESP32 BT SPP can achieve such a speed or there is another way I could achieve this.

Thank you for your time and assistance in this matter. I have asked the same question in ESP32 Forum as well here.

```
void dataFormat(record r){
  serialBtPrint_dur = micros();
  char msg[20];
  sprintf(msg,"%04d%05d%05d%05",r.e, r.r, r.p, r.y);
  SerialBT.println(msg);
  serialBtPrint_dur = micros() - serialBtPrint_dur;
  }
}

void loop() {
  char msg[20];
  uint8_t testMsg[20] = "abcdefghijklmnop\n";
  if(!structs.isEmpty()){
    dataset[local_rd_ptr].yawData);
    data::dataFormat(structs.shift());
    Serial.println(serialBtPrint_dur);
  }
}

```

# Answer
This seems more like an overflow issue with something than an actual delay. If you look at the time in the log, it seems you aren't skipping seconds in the log (aka, 19:12:32.234 in two sequential log entries when you claim a delay). I think it's an error of working with larger than 8-bit data sizes. I know this is an old question, but I was looking for info and came upon it and figured I'd ask.
> 1 votes

---
Tags: bluetooth, esp32
---


# Question
Title: Watchdog timer/deep sleep loop for Atmega 328 Pro Mini 5v 16 mhz
I have been struggling to get my Adafruit 5v pro mini to loop in deep sleep mode several times, then awake to perform something then return to the deep sleep mode loop. While it is out of deep sleep mode I want the watchdog timer to be active to protect against system hangups. Although I can get in and out of deep sleep mode easy enough, and I can also use a loop that performs one deep sleep/awake cycle. I want to maximize the power savings by having a prolonged deep sleep period of several minutes. I have read many posts related to this subject, but have not yet found a response works for me. Attached is my code, which loops through the sleep cycle twice, but not if ISR(WDT\_vect) on row 85 calls my hardwareReset() function. If my call to hardwareReset is used, my test loop on rows 25-30 times out as expected, but my waitSleep function no longer loops twice. Can anyone please offer guidance? Many thanks

```
// thanks to KeyChainino for basic code. I added ADC disable to further reduce power from 0.67mA to 0.54mA
//
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
const int ledPin = 13;
const int resetPin = 9;

// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(resetPin, OUTPUT);
  digitalWrite(resetPin,HIGH);
  Serial.begin(9600);
  Serial.println("Resetting..");
  delay(100);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  for(int i=0; i<9; i++){; //set up loop to force timeout of WDT
  delay(1000);
  Serial.print("Loop ");
  Serial.println(i);
  delay(100);
}
  waitSleep(2); //go sleep for x loops of WDT settings (8 sec max per loop)
}

void waitSleep(int sleep_cycles) {
  while (sleep_cycles) {
    goSleep();
    sleep_cycles--;
  }
}

void goSleep() {
  watchdogSetup(); //enable watchDog
  // disable ADC (analog to digital conversion)
  byte old_ADCSRA = ADCSRA;
  ADCSRA = 0;
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();
  //disable watchdog after sleep
  wdt_disable();
  ADCSRA = old_ADCSRA;
}

void watchdogSetup() {

  //WDP3 - WDP2 - WPD1 - WDP0 - time
  // 0      0      0      0      16 ms
  // 0      0      0      1      32 ms
  // 0      0      1      0      64 ms
  // 0      0      1      1      0.125 s
  // 0      1      0      0      0.25 s
  // 0      1      0      1      0.5 s
  // 0      1      1      0      1.0 s
  // 0      1      1      1      2.0 s
  // 1      0      0      0      4.0 s
  // 1      0      0      1      8.0 s

  // Reset the watchdog reset flag
  bitClear(MCUSR, WDRF);

 //The following bit have to be set at the same time otherwise the system doesn't set the right value

 /* Start timed equence */
 //Watchdog Change Enable to clear WD (by setting the WDCE bit) and Enable WD (by setting the WDE bit)
 WDTCSR |= (1 << WDCE) | (1 << WDE);

 //Set new watchdog timeout value to 8 seconds (WDP3 and WDP0 to 1) and enable interrupts instead of reset (WDIE to 1)
 WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0) ;
}
void hardwareReset(){;
  digitalWrite(resetPin,LOW);
}

ISR(WDT_vect) {
  //hardwareReset();
}

```

# Answer
I don't know if this is the best solution, but I found a workaround. In the ISR(WDT\_vect) function I added a while statement where I added a boolean variable set to true when running the basic program, and false when I enter looping deep sleep mode. I'd appreciate if someone out there can provide a better solution, but for now this one works for me. Below is the revised code in case anyone's interested.

```
// thanks to KeyChainino for basic code. I added ADC disable to further reduce power from 0.67mA to 0.54mA
//revised by John Bedford 01/12/2020
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
const int ledPin = 13;
const int resetPin = 9;
volatile boolean wdtInterrupt;    //watchdog timer interrupt flag

// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(resetPin, OUTPUT);
  digitalWrite(resetPin,HIGH);
  Serial.begin(9600);
  Serial.println("Resetting..");
  delay(100);
  watchdogSetup();
}

// the loop function runs over and over again forever
void loop() {
  wdtInterrupt= true;
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  for(int i=0; i<9; i++){; //set up loop to force timeout of WDT
    delay(1500);
    Serial.print("Loop ");
    Serial.println(i);
    delay(100);
  }
  wdt_reset();

  waitSleep(2); //go sleep for x loops of WDT settings (8 sec max per loop)
}

void waitSleep(int sleep_cycles) {
  wdtInterrupt=false;
  while (sleep_cycles) {
    goSleep();
    sleep_cycles--;
  }
}

void goSleep() {
  watchdogSetup(); //enable watchDog
  // disable ADC (analog to digital conversion)
  byte old_ADCSRA = ADCSRA;
  ADCSRA = 0;
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();
  //disable watchdog after sleep
  wdt_disable();
  ADCSRA = old_ADCSRA;
}

void watchdogSetup() {

  //WDP3 - WDP2 - WPD1 - WDP0 - time
  // 0      0      0      0      16 ms
  // 0      0      0      1      32 ms
  // 0      0      1      0      64 ms
  // 0      0      1      1      0.125 s
  // 0      1      0      0      0.25 s
  // 0      1      0      1      0.5 s
  // 0      1      1      0      1.0 s
  // 0      1      1      1      2.0 s
  // 1      0      0      0      4.0 s
  // 1      0      0      1      8.0 s

  // Reset the watchdog reset flag
  bitClear(MCUSR, WDRF);

 //The following bit have to be set at the same time otherwise the system doesn't set the right value

 /* Start timed equence */
 //Watchdog Change Enable to clear WD (by setting the WDCE bit) and Enable WD (by setting the WDE bit)
 WDTCSR |= (1 << WDCE) | (1 << WDE);

 //Set new watchdog timeout value to 8 seconds (WDP3 and WDP0 to 1) and enable interrupts instead of reset (WDIE to 1)
 WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0) ;
}
void hardwareReset(){;
  digitalWrite(resetPin,LOW);
}

ISR(WDT_vect) {
  while (wdtInterrupt){
   hardwareReset();
  }
}

```
> 1 votes

---
Tags: sleep, watchdog
---


title: Arduino Nano, ESP8266-01 communication

text:
# Question
Title: Arduino Nano, ESP8266-01 communication
In my last question I got the suggestion to get a voltage regulator to power my ESP8266, so I went out to buy one and in the end my ESP8266 turned on. Then I started wiring the Tx/Rx pins through the Logic Level Shifter and tried out this piece of code I found online

```
// Basic serial communication with ESP8266
// Uses serial monitor for communication with ESP8266
//
//  Pins
//  Arduino pin 2 (RX) to ESP8266 TX
//  Arduino pin 3 to voltage divider then to ESP8266 RX
//  Connect GND from the Arduiono to GND on the ESP8266
//  Pull ESP8266 CH_PD HIGH
//
// When a command is entered in to the serial monitor on the computer
// the Arduino will relay it to the ESP8266
//

#include <SoftwareSerial.h>
SoftwareSerial ESPserial(2, 3); // RX | TX

void setup()
{
    Serial.begin(115200);     // communication with the host computer
    //while (!Serial)   { ; }

    // Start the software serial for communication with the ESP8266
    ESPserial.begin(115200);

    Serial.println("");
    Serial.println("Remember to to set Both NL & CR in the serial monitor.");
    Serial.println("Ready");
    Serial.println("");
}

void loop()
{
    // listen for communication from the ESP8266 and then write it to the serial monitor
    if ( ESPserial.available() )   {  Serial.write( ESPserial.read() );  }

    // listen for user input and send it to the ESP8266
    if ( Serial.available() )       {  ESPserial.write( Serial.read() );  }
}

```

But I when I tried sending "AT" to the ESP via the Serial Monitor nothing happend.

This is my current wiring, I hope it's not to unclear:

Hopefully someone can help me :)

# Answer
> 0 votes
**Some hardware troubleshooting** -

* Make sure that the 3.3 V power supply to the wifi module is supplying enough current to esp8266 as it consumes much current.
* Make sure that TX from Nano is going to RX of esp8266 via a resistive divider for bringing down 5V out signals from nano to 3.3 V ( to be on safer side)
* At power-on, check if BLUE LED of ESP8266 blinked 2-3 times quickly and went OFF. Check if the RED LED lighted up and stays ON. If it does, your ESP8266 chip is working fine. If the BLUE LED did n't blink or if it stays ON, your firmware may be corrupt and you will need to re-flash the firmware of ESP8266.
* Make sure that the baudrate is correct.

# Answer
> 1 votes
Step 1: Turn On Your ESP8266 Module by Using Arduino Nano 3.3V Dc Output Pin. Remeber sometimes Arduino board is not delivering sufficient voltage to the ESP8266 module. You can use a 3.3 V ( Do not exceed input voltage from 3.3v) regulator ( AMS1117 ) to power this module. A voltage divider circuit is used to drop the Arduino 5V to ESP8266 3.3 V.

Step 2: Here is the schematic Diagram, in my code I used Digital pin 2 as a Tx and D3 as an RX.

Step 3: Open Arduino IDE and Paste the source code in the window just like shown in the picture.

Step 4: You are ready to send At Commands to Your ESP8266 Module. Remember you will see a Garbage value during Serial Communication.

AT – Will give OK on the serial monitor, if Not just unplug vcc Pin of ESP8266 Module for a moment and reconnect again.

Send AT+RST – Command to Restart module / Optional Command

Send AT+GMR – To get the firmware version

Send AT+CWMODE? – Set Module to a Dual Mode Sucha as Standalone + Access Point mode.

Send AT+CWLAP – Command to Search Nearby Wifi Access Point. Find your Wifi Name in the Search Result.

Send AT+CWJAP="Your Wifi Name","Your Wifi Password" – Command to Connect to WIFI.

Send AT+CIFSR – Command to Check Allocated Ip given by your Wifi to your ESP8266 Module/Optional Command.

# Answer
> 1 votes
The problem is the ESP8266-01 as diagrammed is shorting the pins of the header. Remember that the breadboard you are using connects all pins on each side, on a row by row basis. The WiFi module has 8 pins with the pinout shared in other posts. You must "float" the module and wire it to the breadboard with point to point wiring (hope that is clear). Put simply... don't plug the WiFi module into the breadboard. Can't be done. Cheers!

---
Tags: esp8266, arduino-nano
---


title: esp32 Stack canary watchpoint triggered

text:
# Question
Title: esp32 Stack canary watchpoint triggered
I am writing a program for esp32 on Arduino IDE. On some point of execution of code for File reading I am facing this exception,

```
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask)

```

However on reading few forums I found an answer of increasing the depth of the stack for your FreeRTOS task. My question is there any other way to handle this exception other than increasing stack size and avoid the program from crashing ?

# Answer
> 6 votes
The best way to handle this exception is to identify what's using so much space on the stack and rewrite your code to avoid it.

The three most common ways you'd use too much stack space are:

1. large local variables - for instance, declaring a large array as a local variable inside a function, like:

```
#define VERY_LARGE_STRING_LENGTH 8000

void loop() {
  char my_very_large_string[VERY_LARGE_STRING_LENGTH];

  for(i = 0; i < VERY_LARGE_STRING_LENGTH; i++)
    my_very_large_string[i] = ' ';
}

```

Local variables are stored on the stack, so a large array of them will use up a lot of stack space.

2. recursive functions - each time a function recurses it uses stack space. If it recurses deeply enough then it will trample the stack guard and cause this exception. For instance:

```
int count(i) {
  i--;

  if(i > 0) {
    Serial.println(count(i));
  }

  return i;
}

void loop() {
  count(8000);
}

```

Each time a function recurses, its return address and its arguments and local variables are all stored on the stack. If it recurses too many times it will use more storage than is allocated to the stack.

3. mistakes in your code like wild pointers and buffer overruns

```
void loop() {
  char my_bad_string[10];
  char *wild_pointer;

  // buffer overrun
  for(i = 0; i < 8000; i++)
    my_bad_string[i] = ' ';

  // who knows where this will end up pointing
  wild_pointer += rand();
  wild_pointer = ' ';
}

```

when you overrun an array on the stack you'll probably overwrite other variables and corrupt their values. Do it enough and you'll hit the stack guard. Remember that C strings (`char` arrays and pointers) need `n+1` characters to store a string of length `n` because they're terminated with an extra null `'\0'` character.

If you're using recursive functions, look at ways to limit the recursion or use tail recursion which the compiler may be able to optimize to avoid using excessive stack space.

If you're using large variables, think about why and rewrite your code to be able to use smaller variables. For instance, if you're reading a large file, try to process it a line at a time rather than reading the entire file into memory. If you're downloading large JSON from a web server, try using a streaming JSON parser rather than downloading the entire thing and then processing it.

A mistake in your code will be the hardest to figure out, given that it's a mistake. Be careful about pointers and memory allocation. Although memory is allocated from the heap and not the stack, if it's overwritten or reused after it's been freed using it as a pointer can still cause stack corruption. Also be careful to not return pointers to local variables inside functions:

```
int *do_not_do_this() {
  int this_will_not_work_the_way_you_hope = 0;

  return &this_will_not_work_the_way_you_hope;
}

```

can also lead to stack corruption as the space occupied by the variable will no longer be reserved for it and may be used by something else.

---
Tags: esp8266, arduino-ide, c++, esp32, espressif
---


# Question
Title: Arduino to AtTiny change of pin interrupt behaviour?
I have a project which, to save on battery, is put to sleep until an interrupt pin is rising from LOW to HIGH.

This works well on Arduino Nano, however the translation doesn't on the ATTiny.

```
#include <avr/sleep.h>
void setup(){
    pinMode(2,INPUT);
    noInterrupts();
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    attachInterrupt(INT0,wakeUp,RISING);
    //Yadada
    Interrupts();
}
void wakeUp(){
   //Something Something
   sleep_mode();
}

```

Both on the Arduino Nano and the AtTiny, the interrupt Pin 0 is equivalent to Pin 2.

* The Arduino is set to ISP
* I have run the Bootloader (with internal clock as 8MHz if that makes a difference)
* The program loads on the AtTiny45.

Yet, the interrupt pin does not interrupt.

**Does the INT0 act differently on a ATTiny than on the Arduino, and if so, how can I wake up my AtTiny?**

# Answer
After going through a lot of documentation, it seemed best and more efficient to attach the interrupt without functions.

```
EIMSK  |=  (1<< INT0);//Attaches the interrupt
MCUCR  |=  (1<< SM1)  //Power-down mode
         | (1<<ISC01) //The rising edge of INT0
         | (1<<ISC00);// generates an interrupt request

```
> 0 votes

---
Tags: arduino-nano, interrupt, attiny
---


# Question
Title: How to choose a transmit pin in the IRremote library for an Arduino Uno?
I am looking for a way to choose a pin on the Arduino Uno. This pin will be used to send the signal of an IR LED. I am using the **IRremote** library.

e.g.

Below is the IR send demo which uses pulse width modulation pin 3 to send the IR signal. I want to change that pin to any other pin.

Any pointers will make me very happy thanks.

```
/*
 * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
 * An IR LED must be connected to Arduino PWM pin 3.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

IRsend irsend;

void setup()
{
}

void loop() {
    for (int i = 0; i < 3; i++) {
        irsend.sendSony(0xa90, 12);
        delay(40);
    }
    delay(5000); //5 second delay between each signal burst
}

```

# Answer
> 2 votes
As the pin does not appear to be able to be defined when creating an object from the `IRsend` class, it seems as if you will have to modify the IRremote library itself.

I recently had the same problem with the USB Host library, see Change select pin of USB Host library. It *is* annoying when you can't define the pin(s), that a particular library uses, yourself... However, the authors of the library probably have their reasons for doing so.

Looking through the various headers of the library, I found in `boarddefs.h` on lines 134-138:

```
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
// ATmega48, ATmega88, ATmega168, ATmega328
#else
    //#define IR_USE_TIMER1   // tx = pin 9
    #define IR_USE_TIMER2     // tx = pin 3

```

So, the line to change, for the Uno, would seem to be line 138 in boarddefs.h

```
    #define IR_USE_TIMER2     // tx = pin 3

```

However, it is not, as that merely states that for the Arduino Uno `IR_USE_TIMER2` is used...

Looking further down to where the Timers are defined, you will see the section for Timer 2, on line 146. In that section the transmit pin, for a number of versions of the Arduino, is defined as `TIMER_PWM_PIN` on lines 189-197:

```
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
|| defined(__AVR_ATmega164P__)
#   define TIMER_PWM_PIN  14             // MightyCore
#else
#   define TIMER_PWM_PIN  3              // Arduino Duemilanove, Diecimila, LilyPad, etc
#endif                                   // ATmega48, ATmega88, ATmega168, ATmega328

```

You will have to change this line in the library, Line 196 in boarddefs.h:

```
#   define TIMER_PWM_PIN  3              // Arduino Duemilanove, Diecimila, LilyPad, etc

```

You could try changing the `3` so that you can use another pin. It might work. For example to use pin 5, en lieu of pin 3, change the `3` to a `5`, like so:

```
#   define TIMER_PWM_PIN  5              // Arduino Duemilanove, Diecimila, LilyPad, etc

```

**Be careful** not to choose a pin that is used by something else, **AND** I think that the pin will need to be PWM capable.

Note that the definitions that are in `boarddefs.h` used to be in `RemoteInt.h`, in earlier versions of the library. See this comment at the very top:

```
// This file contains all board specific information. It was previously contained within
// IRremoteInt.h

```

So, make sure that you have the latest version of the IRremote library.

---

The above hack should also work for the Mega2560 as is uses the same timer, Timer 2, see lines 68-71:

```
// Arduino Mega
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    //#define IR_USE_TIMER1   // tx = pin 11
    #define IR_USE_TIMER2     // tx = pin 9

```

Other boards are also defined in this file. If you have another type of board, the timer may be different, but the process to find which line to change would be very similar...

# Answer
> 2 votes
I tried to find where the pin is defined and gave up, I ended up swapping to pin9 by commenting out timer2, like this:

```
#define IR_USE_TIMER1   // tx = pin 9
//#define IR_USE_TIMER2     // tx = pin 3

```

Not ideal since I needed 9 also and I will add how annoying this library is that although I only need to receive signals and never send...it still takes up a pin for sending.

ANyway, the posts above helped me at least get my motor shield working, thanks guys.

---
Tags: arduino-uno, pins, ir
---


# Question
Title: Initialising timer interrupt crashes Mega 2560
Below is the entirety of my prototype code, the cycling of pin 13 is what I use to confirm the board is restarting. The board resets continually on this implementation of initialising the interrupt. There is no code implemented for the interrupt, simply initialising the interrupt and specifically enabling the Output Compare Interrupt by setting its bit high is enough to cause the crash. The evidence of the crash is the onboard LED cycling as instructed in the `setup()` routine.

I have tried setting `OCR3A` in one and two operations, I have tried initialising `TIMSK3` and not, I have tried intialising `TCNT3` to zero and non-zero values, and setting the prescaler with the bit shift and the discrete value, nothing seems to work..

What is going on?

```
void FlashLED() {
  digitalWrite(13, !digitalRead(13));
  delay(100);
  digitalWrite(13, !digitalRead(13));
  delay(100);
  digitalWrite(13, !digitalRead(13));
  delay(100);
  digitalWrite(13, !digitalRead(13));
  delay(100);
}

void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  FlashLED();

  // Initialise timer 3 and interrupt
  noInterrupts();
  TCCR3A = 0;
  TCCR3B = 0;
  TIMSK3 = 0;
  TCNT3 = 0;

  // Initialise OCR3A in two operations, as OCR3A = 62500; Serial.print(OCR3A); yields 36 (low byte only)
  unsigned int count = 62500;
  OCR3AH = count >> 8;
  OCR3AL = count;
  TCCR3B |= 1 << WGM32; // CTC Mode
  //TCCR3B |= 4; // Prescaler 256
  TCCR3B |= 1 << CS32; // Prescaler 256

  TIMSK3 |= 1 << OCIE3A; // Output Compare Interrupt Enable
  interrupts();
}

void loop() {
  // put your main code here, to run repeatedly:

}

```

**Update:**

I had also been trying with an empty ISR handler and discounted its effect:

```
ISR(Timer3_COMPA_vect) {

}

```

However, as the astute viewer would notice, the signature is incorrect in its capitalisation. The correct handler is

```
ISR(TIMER3_COMPA_vect) {

}

```

This has resolved the issue.

# Answer
> 1 votes
You have enabled the timer and also its interrupts but you have no interrupt handler. The interrupt has to go somewhere and as it is it's going who-knows-where. Add an ISR and I believe that will resolve your issue.

Yes, the capitalization is important!

---
Tags: interrupt, timers, arduino-setup
---


# Question
Title: How to use a push button & transistor as a kickstarter for power supply?
My goal is to save energy, and I intend to do so by **powering a chip with itself, and cut power whenever unnecessary**. The best image I can have is of a startled monkey who jumps on the branch, screams its profanities while holding to the branch, and when the screams are done, lets go of the branch and falls back on the floor, asleep.

The chip, in my case an ATtiny45, has a program that just makes a specific sound (hopefully more pleasing than an angry monkey's) with a PWM, but would also power an output pin connecting to a transistor acting as a relay between the battery and the power pin.

This is the ideal protocol:

```
(No closed circuit, no power)
Press Button
Battery power goes through to transistor
Transistor allows current from Battery to PWR pin
Software: Chip starts PWM to Speaker and Outputs constantly the Hold Pin
Hold pin powers the transistor and thus the chip for when the button won't be pressed
Software: When Button still pressed, makes Chip Scream louder
Software: Button not pressed anymore makes chip scream softer until it's done screaming
Software: Scream is finished, stops powering the Hold Pin
Transistor isn't powering the chip anymore.

```

I think the idea is plausible, though I can't test it at the moment due to not having NPN transistors (?)

My questions are the following:

* **Truth: Is is possible for a transistor as relay to power a chip on demand?**
* **Risks: Is the power going to be stronger due to the amplifying nature of the transistor? What about the chip, I've read that a chip can maintain its code for 20+ years without power supply. Is this true?**
* **Goals: Is there a better way to save power? Would it be best for the chip to just have sleep enabled?**
* **Name: If this works, is there a better name than the Startled Monkey?**

Thanks again for your help, this community has already taught me a lot!

simulate this circuit – Schematic created using CircuitLab

# Answer
> 1 votes
I think all this effort is unnecessary. The ATTINY45 pulls a *maximum* of 2uA when sleeping...

..and in practice I've found the typical current to be much less.

If, say, you are using AAA batteries for you project then you could sleep for more than 100 years. In practice your batteries will self discharge long before this, so any potential power savings by completely disconnecting the chip are wasted (and remember there is some leakage loss though the transistors that might even be more than the sleep power used by the ATTINY).

Instead connect the batteries directly to the power pins of the ATTINY and connect the button between any IO pin and ground. Activate the internal pullup on the IO pin and then set a pinchange interrupt on that pin to wake the chip when the button is pressed. Now go to sleep and wait for a button press to wake you.

# Answer
> 2 votes
Your idea is sound, but your implementation is flawed.

First, you don't want to bother with "wake" and things like that - when the chip gets power it just starts from scratch - that's your "wake" signal. Your code will just be "Hold it on" and "Make a sound" followed by "Let it switch off".

You only need one IO pin for that - the "Hold it on" signal. The "catch" signal in your schematic is just the chip getting power.

And then there's your schematic. You should really use a P-channel MOSFET to do the switching of the power, not an NPN transistor. An NPN won't work, and a PNP (which would be what you would use for this if you were using a BJT) would impose a voltage drop, which you don't want.

Your circuit would in fact need to look like this:

simulate this circuit – Schematic created using CircuitLab

When idle M1 (P-channel with threshold voltage well below the battery voltage) is turned off by R1 pulling the gate up to the source voltage. Pressing the button pulls the gate below its threshold voltage allowing M1 to turn on. The chip then gets power.

M2 (N-channel with threshold voltage well below the chip voltage) is then activated by the chip by driving the GPIO HIGH to bypass the switch and connect the gate of M1 to GND. R2 keeps M2 turned off while idle.

M2 is needed so that there is no current flow between the battery and the GPIO when the power is turned off. Without it current can flow through R1 into the GPIO, through the ESD protection diodes inside the chip, and potentially break the chip.

Now to help clear up some of your questions:

> Truth: Is is possible for a transistor as relay to power a chip on demand?

Yes, it is.

> Risks: Is the power going to be stronger due to the amplifying nature of the transistor?

No. Amplification, with a BJT, is really a misnomer. It doesn't "amplify" a signal, it takes one small signal and uses that to proportionally control a larger signal. But that's only in the "linear" portion of the curve. When used in "saturation" like this it's more like a switch - power applied to the base turns on the flow of current from collector to emitter.

> What about the chip, I've read that a chip can maintain its code for 20+ years without power supply. Is this true?

Yep. Flash memory typically has a retention time in the order of 10 to 100 years. 20 years is a reasonable ballpark figure.

> Goals: Is there a better way to save power? Would it be best for the chip to just have sleep enabled?

Zero power is the best low power there is. Even in the deepest sleep mode the chip will still draw power. But if you do it right there can be little difference between the current drawn by a sleeping chip and the self-discharge of a battery as it sits idle.

> Name: If this works, is there a better name than the Startled Monkey?

I like the name Startled Monkey. I think I'll use that in future myself.

---
Tags: power, relay, attiny, battery, transistor
---


# Question
Title: Splitting up code in multiple files causing `multiple definition` and `undefined reference` error
I have the following very basic program that reads MPU6050(accelerometer and gyroscope) sensor using the I2C library, and prints the sensor information. This program works as expected.

```
#include <Arduino.h>
#include <MPU6050_6Axis_MotionApps20.h>

inline void printToSerial(bool, bool) __attribute__((always_inline));

MPU6050 imu;
int16_t ax, ay, az, gx, gy, gz;

void setup() {
  imu.initialize();

  imu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  imu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);

  imu.setXAccelOffset(-1451);
  imu.setYAccelOffset(-682);
  imu.setZAccelOffset(1448);
  imu.setXGyroOffset(69);
  imu.setYGyroOffset(-16);
  imu.setZGyroOffset(29);
  Serial.begin(9600);
}

void loop() {
  imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  printToSerial(false, true);
  delay(50);
}

void printToSerial(bool a, bool g){
  if(a){
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.println(az);
  }

  if(g){
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
  }
}

```

But as I want to add more functionality to the main program - I want to move MPU6050 specific code to separate file.

So, I created `Sensor.h` with the following content,

```
#ifndef SENSOR_H
#define SENSOR_H

#include <MPU6050_6Axis_MotionApps20.h>

extern MPU6050 imu;
extern int16_t ax, ay, az, gx, gy, gz;

void sensorInit();
void sensorUpdate();

#endif

```

And placed the implementation in the `Sensor.cpp` file.

```
# include "Sensor.h"

void sensorInit(){
  imu.initialize();

  imu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  imu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);

  imu.setXAccelOffset(-1451);
  imu.setYAccelOffset(-682);
  imu.setZAccelOffset(1448);
  imu.setXGyroOffset(69);
  imu.setYGyroOffset(-16);
  imu.setZGyroOffset(29);
}

void sensorUpdate(){
    imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
}

```

And finally, modified the `main.cpp` file in the following way,

```
#include "Sensor.h"
#include <Arduino.h>

inline void printToSerial(bool, bool) __attribute__((always_inline));

void setup() {
  sensorInit(); // replaced few lines of codes
  Serial.begin(9600);
}

void loop() {
  sensorUpdate(); // replaced few lines of codes
  printToSerial(false, true);
  delay(50);
}

void printToSerial(bool a, bool g){
  if(a){
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.println(az);
  }

  if(g){
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
  }
}

```

But when I try to build the code, I get the following error in the linking step,

```
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpInitialize()'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpPacketAvailable()'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(long*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(long*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(long*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(VectorInt16*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGravity(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetEuler(float*, Quaternion*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpProcessFIFOPacket(unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetFIFOPacketSize()'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetCurrentFIFOPacket(unsigned char*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\libdeps\uno\I2Cdevlib-MPU6050/MPU6050.h:436:7: warning: type 'struct MPU6050' violates one definition rule [-Wodr]
 class MPU6050 {
       ^
.pio\libdeps\uno\I2Cdevlib-MPU6050\MPU6050.h:436:7: note: a different type is defined in another translation unit
 class MPU6050 {
       ^
.pio\libdeps\uno\I2Cdevlib-MPU6050/MPU6050.h:1036:18: note: the first difference of corresponding definitions is field 'dmpPacketBuffer'
         uint8_t *dmpPacketBuffer;
                  ^
.pio\libdeps\uno\I2Cdevlib-MPU6050\MPU6050.h:436:7: note: a type with different number of fields is defined in another translation unit
 class MPU6050 {
       ^
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o: In function `MPU6050::getDeviceID() [clone .constprop.29]':
<artificial>:(.text+0xbba): undefined reference to `imu'
<artificial>:(.text+0xbd0): undefined reference to `imu'
<artificial>:(.text+0xbd4): undefined reference to `imu'
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x10c): undefined reference to `imu'
<artificial>:(.text.startup+0x11c): undefined reference to `imu'
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o:<artificial>:(.text.startup+0x12a): more undefined references to `imu' follow
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x282): undefined reference to `ax'
<artificial>:(.text.startup+0x286): undefined reference to `ax'
<artificial>:(.text.startup+0x28a): undefined reference to `imu'
<artificial>:(.text.startup+0x28e): undefined reference to `imu'
<artificial>:(.text.startup+0x298): undefined reference to `ay'
<artificial>:(.text.startup+0x29c): undefined reference to `ay'
<artificial>:(.text.startup+0x2a0): undefined reference to `imu'
<artificial>:(.text.startup+0x2a4): undefined reference to `imu'
<artificial>:(.text.startup+0x2ae): undefined reference to `az'
<artificial>:(.text.startup+0x2b2): undefined reference to `az'
<artificial>:(.text.startup+0x2b6): undefined reference to `imu'
<artificial>:(.text.startup+0x2ba): undefined reference to `imu'
<artificial>:(.text.startup+0x2c4): undefined reference to `gx'
<artificial>:(.text.startup+0x2c8): undefined reference to `gx'
<artificial>:(.text.startup+0x2cc): undefined reference to `imu'
<artificial>:(.text.startup+0x2d0): undefined reference to `imu'
<artificial>:(.text.startup+0x2da): undefined reference to `gy'
<artificial>:(.text.startup+0x2de): undefined reference to `gy'
<artificial>:(.text.startup+0x2e2): undefined reference to `imu'
<artificial>:(.text.startup+0x2e6): undefined reference to `imu'
<artificial>:(.text.startup+0x2f0): undefined reference to `gz'
<artificial>:(.text.startup+0x2f4): undefined reference to `gz'
<artificial>:(.text.startup+0x30c): undefined reference to `gy'
<artificial>:(.text.startup+0x310): undefined reference to `gy'
<artificial>:(.text.startup+0x328): undefined reference to `gz'
<artificial>:(.text.startup+0x32c): undefined reference to `gz'

```

Main.cpp, Sensor.cpp and Sensor.h files are in the same directory. I am using PlatformIO to build and deploy the code on an Arduino Uno and the platformio.ini file content is the following,

```
[env:uno]
platform = atmelavr
board = uno
framework = arduino
lib_deps = jrowberg/I2Cdevlib-MPU6050@0.0.0-alpha+sha.fbde122cc5

```

I am wondering what is causing the linking errors.

# Answer
> 3 votes
The failing is not with your code. The failing is with the MPU6050\_6Axis\_MotionApps20.h library. It erroneously has code in the header rather than in a separate CPP file.

You have done everything right. The author of that library could do well in taking a leaf out of your book.

To get it working you will have to move the code out of the header file into the .cpp file - or move it to reside inside the class definition and make it `inline`.

---
Tags: programming, linker, platformio
---


# Question
Title: Attiny : Is it possible to analog read on PB1?
I'm trying to read an analog input on the Attiny85 physical pin 6 (PB1, PWM), but analogRead(PB1) always returns 1023. Is it even possible to use analogRead on this pin? I'm fairly new to this so sorry if it's an obvious answer. Thanks!

# Answer
PB1 has no analog input. So no, you can't read analog with it.

For analog you must use any of PB2 through PB5.
> 1 votes

---
Tags: analogread, attiny, attiny85
---


# Question
Title: Why are characters with value above 127 "padded" with 1s to be 16 bits long, while ones with values 0-127 aren't?
I am using the Arduino IDE to run and monitor, with an Arduino Nano clone. This code shows what I mean by the question:

```
char foo = 127;
char bar = 128;
Serial.println(String(foo, BIN));
Serial.println(String(bar, BIN));
foo = 383;
bar = 384;
Serial.println(String(foo, BIN));
Serial.println(String(bar, BIN));

```

prints

```
1111111
1111111110000000
1111111
1111111110000000

```

It still happens if I then cast the elements to `char`, but not if I cast them to `uint8_t`:

```
char foo = 127;
char bar = 128;
Serial.println(String((char)foo, BIN));
Serial.println(String((char)bar, BIN));
Serial.println(String((uint8_t)foo, BIN));
Serial.println(String((uint8_t)bar, BIN));

```

```
1111111
1111111110000000
1111111
10000000

```

It behaves the same if I do some arithmetic as well:

```
char foo = 127;
char bar = 128;
Serial.println(String(foo / 64, BIN));
Serial.println(String(bar / 64, BIN));

```

```
1
1111111111111110

```

Why is this? If I assign a number bigger than 255, but smaller than 384, it behaves like for numbers below 128, but above that, it does it again, so it's obvious that only the least significant 8 bits of the value are stored as expected, but in cases where (n mod 255) \> 127 (so the 8th bit is `1`) they are retrieved from memory together with another 8 bits, which are all `1`s.

**I can live without an answer to the above issue, what I really need to have confirmed is the following:**

If I were to store and retrieve a `uint16_t` as two elements of a `char[]`, it would always be safe (and not undefined behavior) if I did it as follows, right?:

```
uint16_t foo = 34952;
char bar[2];
bar[0] = foo >> 8;
bar[1] = foo;
uint16_t extracted = (uint16_t((uint8_t)bar[0])) << 8 | (uint8_t)bar[1];

```

Thank you in advance for any help you can provide.

# Answer
> 3 votes
On the AVR platform the `char` type happens to be signed, and it can store numbers in the range \[−128, +127\]. Thus, when you write

```
char bar = 128;

```

You are asking to store in `bar` a number that does not fit. It then gets reduced modulo 28 into the value that does fit, namely −128. For the kind of manipulations you are trying to make, I would recommend you use `uint8_t` instead of `char`.

> it would be always safe (and not undefined behavior) if I did it as follows

It is indeed safe, and the casts you use are needed to make it safe.

---
Tags: arduino-nano, string, array
---


# Question
Title: Reading a string from Firebase and storing it as a CString
I have a mobile app (done using MIT App Inventor) storing some values to a Firebase database. App inventor stores all the values as strings (i.e. with quotes, and strings have quotes enclosed within quotes eg. `"\"hello\""`).

I'm using this library to fetch data from Firebase to ESP8266. I'm using `String` var to store the value retrieved and then change it to a CString (trying to store it directly doesn't work) as below:

This doesn't work:

```
Firebase.get(firebaseData, "/SCHEDULE DETAILS/SCHEDULE1/FREQ FR");
Serial.print("node -- schedule1 /FREQ FR -- type: ");
Serial.println(firebaseData.dataType());
char * cstr1 = new char [33];
cstr1 = firebaseData.stringData();
Serial.print(" -- data: ");
Serial.println(cstr1);

```

This works:

```
Firebase.get(firebaseData, "/SCHEDULE DETAILS/SCHEDULE1/WEIGHT");
Serial.print("node -- schedule1/WEIGHT -- type: ");
Serial.println(firebaseData.dataType() ) ;
String dummy = firebaseData.stringData();
Serial.print(" -- data: ");
Serial.print(dummy);
char * cstr = new char [dummy.length()+1];
strcpy (cstr, dummy.c_str());
Serial.print(" -- data int type: ");
Serial.println(atoi(cstr)) ;

```

I have some more nodes to get data from and I've read that lots of `Strings` are a bad practice. While trying to find out more, I saw the source code and `stringData` function itself returns a CString:

I feel like I'm doing one step more than what is required! Any suggestions on how to go about this would be very useful!

**Try1** Based on the answer from @Majenko, I tried this before adding to the library:

```
const char* get_cstring() {
  String str = "will it work" ;
  return str.c_str();
}

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

void loop() {
  const char *new_c = get_cstring();
  int len = strlen(new_c);

  for (int i = 0; i < len; i++) {
    Serial.println(new_c[i]);
    delay(1000);
  }
  Serial.println("----------");
}

```

But how do I access the contents, because it just prints garbage values; `strlen(new_c)` gives 2 (I'm guessing that's the amount of storage needed in bytes!?)

Thanks!

# Answer
> 0 votes
In returning a `String` object the Firebase first generates that `String` object and copies the C string data into it.

If you want to get at the raw C string data you will have to look at adding a new "getter" to the library to return the pointer to that C string data:

I'd write it for you, but since you posted a screenshot of the Firebase function, and the change from that code to the new code is very minor (just change the function name and the return type), I can't copy-and-paste it. And I'm not going to peer at that little image and type it all in again.

Incidentally, internally the Firebase library actually uses `std::string`, which is a better implementation of the same thing that `String` does. `String` was created because the Arduino compiler has no STL, and hence no `std::string`. Either way they both use dynamic allocation.

---
Tags: esp8266, string, iot, c-string
---


title: Why does the LEDs affect Analog Input?

text:
# Question
Title: Why does the LEDs affect Analog Input?
So I'm working for a project to control RGB Led Strip using microphone or sound sensor with `Arduino Nano`. I'm using `5050 RGB Led Strip` around 120 LEDs, and I control them using simple transistor circuit to each channel R, G, and B, then I connect the base of the transistors to the resistors and PWM Outputs of the Arduino. And then I'm using `KY-038 Sound Sensor` (I'm using the Analog Output pin) and connect it to Arduino `A0`.

The problem is when I didn't connect the LEDs, the microphone worked correctly. I processed the analog input, put filter and threshold. When I connected the LEDs, the reading of the `A0` is disturbed by the transition of the LED (for example from 0% PWM to 50% PWM or ON). As the result, my analog read detected it as a voltage swing and recognize it as a sound, and trigger the LEDs, then oscillating without any external sound. If I disconnected the LEDs, it worked correctly, for example I change it to Arduino Built-In LED, it turned on according to the external sound.

Why does this happen? I don't think they share the same timer, and I also use proper Power Supply and Capacitor to provide the enough power.

My project is similar to this project.

# Answer
I think it is because of power consumption.

If the LEDs consume lots of power, the LED on Arduino(typically mini red LED) will be off or faded. So before you connect the LEDs, check the mini red LED which is on Arduino and after connection the LEDs, check ones again. If the red LED is faded or off, the problem must be power consumption.

Connect 12v or 5v to vin to powering the Arduino, and also to LEDs The important thing is you should not connect LEDs to Arduino 5v.
> 1 votes

# Answer
Which model of LED are you using? 5050 is just the form factor. However, I think the problem is related to power consumption. The well-known WS2812B (a.k.a. Neopixel from Adafruit), may consume about 50mA. Considering 120LEDs, you can reach an important level of current (circuit supporting more than 1A should be properly designed). The sudden change of current can easily change introduce noise on the entire circuit. The solution should use an external power supply dedicated for LED, sharing GND with your Arduino.
> 0 votes

---
Tags: sensors, arduino-nano, led, analogread, rgb-led
---


title: How to restart ESP32 on any exception?

text:
# Question
Title: How to restart ESP32 on any exception?
While developing a lot of projects (In Arduino IDE) for ESP32 one common issue I am facing is termination of program execution on unhandled exceptions. There are various exception I get. For example: `stack canary watchpoint triggered (looptask)`, `invoke_abort`, etc. I have no idea how to handle them, hence I prefer to restart the ESP manually.

Is there any way where I can restart the ESP32 automatically on all unhandled or unfortunate exceptions other than handling the exceptions ?

# Answer
> 1 votes
I don't know if I understand your question well, but if what you want to do is reset MCU programmatically, watchdog is good solution. The orther way is connect IO port and reset port by using wire, and send a signal(send LOW or HIGH voltage to reset port) to reset port.

Or use asm code.

---
Tags: c++, esp32, espressif
---


title: Do interrupts block other interrupts?

text:
# Question
Title: Do interrupts block other interrupts?
If I have an interrupt attached to two pins and the handler of the first is still executing when the second interrupt fires, does it:

a) queue the second interrupt,

b) ignore the second interrupt (missing it altogether), or

c) pause processing of the first interrupt to execute the second?

I am writing code that logs the exact time the interrupt occurs. Quite lightweight, but have three pins and am logging the rise and fall of each, so there is the potential for collisions. If a) then the second interrupt timestamp will be late, b) there is no timestamp for the later interrupt or c) the timing of the first and second interrupts will be ambiguous.

b) is the worst case, the other two are manageable.

# Answer
It depends on the architecture.

Assuming AVR (8-bit Arduino) then it will queue the second interrupt until the first is finished.

It works by setting a flag in a register at the moment the interrupt occurs. Then between instructions it checks that flag and executes the associated interrupt routine. If an interrupt is in progress at the time the flag still gets set, but it is unable to check the state of that flag until after the current interrupt is over and normal execution occurs, at which point after the next instruction is completed it checks the interrupt flag statuses and runs the second interrupt routine.
> 3 votes

# Answer
It depends on the specific MCU, not all are exactly the same.

Some have interrupt priority circuitry that you can use. But in general, an ISR can be interrupted by another incoming IRQ, etc. What you often do in an ISR is mask IRQ, handle the IRQ, and then unmask to let any pending IRQs be handled.

This is one reason why long-running ISRs should be avoided!
> 1 votes

---
Tags: interrupt
---


title: Set parameters after compilation

text:
# Question
Title: Set parameters after compilation
I am extremely new to Arduino and have searched for this on the web but have not found it.

My project has 2 files, a .ino file with the sketch and another .h file with the secrets and configuration parameters, such as reading intervals, credentials to connect to WiFi, etc.

Now I need in runtime to be able to connect to the arduino, either by serial or by any other way to be able to set these parameters.

My question is: How can I change the parameters after compiling the sketch? For example, how can I specify the credentials for the Arduino to connect to the client's WiFi, since each client has different credentials?

# Answer
> 4 votes
It is likely 2 features are desired for this project:

1. A way to enter WIFI credentials after the program is running.
2. A way to store the WIFI credentials between power cycles.

The solution for the 2nd requirement is to use non volatile memory. Both problems have been solved before for certain types of Arduinos. Here is a project on GitHub which has solutions for boards using the ESP8266 or ESP32 processors.

# Answer
> 4 votes
You can set parameters, like SSID and password, at run time in several ways. The two most obvious are:

* a small dialog using the serial monitor or an other serial console;
* a web interface served by the Arduino that lets you enter parameters.

The idea of the latter is that, when the Arduino can't connect to an available network (because it is unknown, or because it doesn't have the right credentials stored), it sets itself up as an *access point* with a known SSID, password, and IP address.

You can then (first) connect to the Arduino's access point WiFi network, and then open a HTML page from the Arduino in a webbrowser that lets you enter your WiFi credentials for the "real" WiFi network. This is how the WiFiManager library works (for the ESP8266 and the ESP32).

Once the credentials have been entered, you can store them (permanently) in EEPROM using the EEPROM library or, if the MCU on your Arduino doesn't have EEPROM, using a library that stores in flash, like the FlashStorage library for SAMD21-based Arduinos.

The same mechanisms can be used for other parameters you may want to set at run time.

---
Tags: esp8266, esp32, wifi
---


# Question
Title: Turn on relay for amount of time by continuous input
I have a project having two input status

* first the input is not continuous the output buzzer relay will be on for 10 seconds and then turned off or it can be off directly by push button
* the second state if the input is continuous the output buzzer relay will be on for 10 seconds and then turned off or it can be off directly by push button

I made this code but it does not work can anyone suggest an edit without using millis() because it will crash after 49 days and without using delay function.

Note that the device will work 24 hours / 365 days.

```
const int input1 = 19;
const int input2 = 36;
const int relay1 = 10;
const int relay2 = 21;
const int reset = 40;
const int buzzerreset = 45;
const int buzzerrelay = 46;

int buttonState1 = 0;    //for input1
int buttonState2 = 0;    //for input2
int buttonState3 = 0;    //for pushbutton
int buttonState4 = 0;    //for buzzer reset
int b4 = 0;              //for buzzer reset

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(buzzerrelay, OUTPUT);
  pinMode(input1, INPUT);
  pinMode(input2, INPUT);
  pinMode(reset, INPUT);
  pinMode(buzzerreset, INPUT);

  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(buzzerrelay, LOW);
}

void loop() {
  buttonState1 = digitalRead(input1);
  if (buttonState1 == HIGH) {
    digitalWrite(relay1, HIGH);
    digitalWrite(buzzerrelay, HIGH);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState3 = digitalRead(reset);
  if (buttonState3 == HIGH) {
    digitalWrite(relay1, LOW);
    //digitalWrite(buzzer, LOW);
  } else {
    buttonState4 = digitalRead(buzzerreset);

    if ((buttonState4 == HIGH || buttonState1 == HIGH) && b4 == LOW) {
      digitalWrite(buzzerrelay, LOW);
    }
    // while (digitalRead(input1) == HIGH);
    // digitalWrite(buzzerrelay, LOW);

    (buttonState2 = digitalRead(input2));
    if (buttonState2 == HIGH) {
      digitalWrite(relay2, HIGH);
      digitalWrite(buzzerrelay, HIGH);
      //delay(10000);
      //digitalWrite(buzzer, LOW);
    }

    buttonState3 = digitalRead(reset);
    if (buttonState3 == HIGH) {
      digitalWrite(relay2, LOW);
      //digitalWrite(buzzer, LOW);
    } else {
      buttonState4 = digitalRead(buzzerreset);
      if (buttonState4 == HIGH) {
        digitalWrite(buzzerrelay, LOW);
      }
      //while (digitalRead(input2) == HIGH);
      //digitalWrite(buzzerrelay, LOW);
    }
  }
}

```

# Answer
I would suggest having a `buzzerPlaying` state, an `oldInput` state, and a `buzzerOffTime` (unsigned long millis when you should turn the buzzer off.

Ignore input if `buzzerPlaying == true` and just check the `buzzerOffTime`. When `buzzerOffTime` passes, turn off the buzzer, set `buzzerPlaying` to false, and start checking the input again.

If the `buzzerPlaying == false` and input is high:

1. check `buzzerPlaying`. If it's true, do nothing.
2. If `buzzerPlaying` is false, check `oldInput`. If `oldInput` is high, do nothing (The input has not been reset.) else set buzzerPlaying to true, set oldInput to high, turn on the buzzer, and calculate `buzzerOffTime`.

If the `buzzerPlaying == false` and input is low, set oldInput to low (Once the buzzer has stopped playing and the input has dropped low, start looking for more inputs.)
> 1 votes

# Answer
Whatever the inputs do, when one of them first goes HIGH you want the buzzer to sound, stopping after 10 seconds or a button-press, whichever comes first? Then you need something like this:

```
if any input is HIGH,
   save millis();
   start the buzzer;

   if button is HIGH
      stop the buzzer;
   else if millis() - saved millis() >= 10*1000 millisec),
      stop the buzzer;
end;

```
> 0 votes

---
Tags: timers, relay, digital, input
---


# Question
Title: What pins to use on a Teensy to get data from multiple peripherals?
I'm using a Teensy to keep records on the location, speed, altitude, and direction of a weather balloon I'm hoping to launch. I have an Adafruit LSM9DS1 and a Ublox NEO-M8N with compass (HMC5833L) so to get all the data from these I need to connect to a total of 6 pins to get the data. I also want to use a Pixhawk radio telemetry unit to send these data to the ground so I can see them in realtime, so that will involve at least 2 more pins I believe.

The Teensy appears to have plenty of IO pins for all of this, but I've noticed that in all the libraries I've installed to try to use with these things, the pins to use aren't explicitly set. The libraries I've played with include the Adafruit LSM9DS1 library, NeoGPS, Pixhawk Arduino link, RadioHead, Grove HMC5833L, and others. I've been able to get some serial data in by using pins 18 and 19, but I can't attach all the periperhals to the same pin.

It feels like I'm missing something very basic here but I haven't been able to figure out how to use these libraries with inputs on different pins. Even when I look into the code of the libraries themselves, I can't find where the pins are being set. Most of the documentation that mentions which pins things use is written for specific Arduino models, like the Uno, and don't mention the Teensy.

What pins do I use if I want to read and write on more than one peripheral from my Teensy? How can I get data on more than just the two "default pins" that these libraries seem to expect?

# Answer
> 1 votes
The first thing to look at when determining which pins to connect a peripheral to is what protocol that peripheral uses - e.g. I2C, SPI, analog voltage via ADC, etc. The Teensy pinout for the version you have (e.g. the 3.2 pinout) lists which pins can function as which protocol functions. For example, pin 19 can act as an analog input (`A5`) or as part of the 0th I2C unit, `SCL0`. Your `LSM9DS1` can use I2C, so you could connect it to that I2C unit. Typically Arduino libraries will default to using the default peripheral type. In Arduino, an I2C bus is called `Wire`, so a library for an I2C device will typically use the `Wire` device. Well-written libraries will also let you pass in your own peripheral, which is how you change the pins. Each library will do this differently.

---
Tags: library, pins, gps, teensy, imu
---


# Question
Title: PubSubClient: Subscription working, but callback never called
I am using an ESP32 (https://heltec.org/project/wifi-kit-32/) with a AM2302 DHT22 and an LDR, talking to mosquitto on a Linux box. Publishing data is working fine, other than the "exceeded timeout, disconnecting" lots of people seem to be having. However, when a message is sent from another client to a topic I am subscribed to, my callback is never called, so I can't consume it.

In my reconnect function, I have

```
    boolean success = mqttClient.subscribe("sensors/basement/led");
    Serial.print("Subscribe returned ");
    Serial.println(success);

```

and it does return 1 which I believe is success (usually success is zero but I don't think that's the case here). I also see the subscription in my mosquitto logs, which are currently cranked up to debug.

```
1610417274: New client connected from XXX.XXX.XXX.XXX as Basement1 (c1, k15, u'XXXXXXXXX').
1610417274: Sending CONNACK to Basement1 (0, 0)
1610417275: Received SUBSCRIBE from Basement1
1610417275:     sensors/basement/led (QoS 0)
1610417275: Basement1 0 sensors/basement/led
1610417275: Sending SUBACK to Basement1

```

When I send data to sensors/basement/led from the other client (mqttdash), the server receives it, and sends it to mqttdash, as well as Basement1, which is my ESP32:

```
It's definitely sending the message to the ESP32:
1610417546: mqttdash-3785c5ce 0 sensors/basement/led
1610417546: Sending SUBACK to mqttdash-3785c5ce
1610417578: Received PUBLISH from mqttdash-3785c5ce (d0, q0, r0, m0, 'sensors/basement/led', ... (1 bytes))
1610417578: Sending PUBLISH to Basement1 (d0, q0, r0, m0, 'sensors/basement/led', ... (1 bytes))
1610417578: Sending PUBLISH to mqttdash-3785c5ce (d0, q0, r0, m0, 'sensors/basement/led', ... (1 bytes))

```

However, my callback is never called. Here is the setup of the callback:

```
WiFiClient espClient;
PubSubClient mqttClient(espClient);
...
void setupMQTT()
{
    mqttClient.setServer(MQTT_HOST, MQTT_PORT);
    mqttClient.setCallback(mqttSubHandler);
    mqttConnect();
}
...
void mqttSubHandler(char *topic, byte *message, unsigned int length)
{
    Serial.print("Message arrived on topic: '");
    Serial.print(topic);
    Serial.print("'. Message: ");
    String messageTemp;

    for (int i = 0; i < length; i++)
    {
        Serial.print((char)message[i]);
        messageTemp += (char)message[i];
    }
    Serial.println();
...

```

Full code at https://github.com/djsegfault/arduino/blob/master/basement\_monitor/basement\_monitor.ino

Does anyone know why the callback is not being called? Thanks in advance.

# Answer
> 2 votes
nknolleary, the owner of the library, correctly identified the problem: You need to call mqttClient.loop() in you main loop. Without that, you are never giving the client a chance to check for any incoming messages.

---
Tags: esp32, mqtt
---


title: Switch case (millis()) UPDATED

text:
# Question
Title: Switch case (millis()) UPDATED
I want to create a sketch that counts the days from the moment the "project" start and send and osc message every two days (or more) for 3 weeks. So:

```
day zero : osc message -> 0
day two. : osc message -> 1
day four : osc message -> 2

```

etc.

I'm trying to create a state machine to send the messages when the millis reaches a certain time it should print message and so on for the other times. I'm giving a small example:

I went with @jsotola's suggestion and tried out the BlinkWithoutDelay approach. It seemingly works because I get serial prints around the correct millis() they are printed in 4fold or 3fold the messages.

EDITED CODE:

```
int daytwo = 25920; // for testing purposes other numbers then the actual millis()
int dayfour = 44400;

void loop() {
  unsigned long currentMillis = millis();   // store current time

  if (currentMillis == daytwo) {
    Serial.println("daytwo");
  }

  if (currentMillis == dayfour) {
    Serial.println("dayfour");
  }
}

```

Serial output:

```
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.926 -> daytwo
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour

```

# Answer
The following code is not very "clean" but easy to understand. Use a variable to hold the day, you have already printed and check in which interval you are. If you change the 2 day interval print a message and set the actDay variable to the number of the day you have already printed; to avoid repprinting it again.

```
int daytwo = 25920;
int dayfour = 44400;

int actDay = -1;

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis < daytwo)
  {
    if ( actDay != 0 )
    {
      actDay = 0;
      Serial.println("dayzero");
    }
  }
  else if (currentMillis < dayfour )
  {
    if ( actDay != 2 )
    {
      actDay = 2;
      Serial.println("daytwo");
    }
  }
  else
  {
    if ( actDay != 4 )
    {
      actDay = 4;
      Serial.println("dayfour");
    }
  }
}

```
> 1 votes

# Answer
```
int day = 0;
unsigned long prevMillis = 0;
const unsigned long MILLIS_PER_DAY = 86400000UL;

void setup()
{
  prevMillis = millis();
}

void loop() {
  if( millis() - prevMillis > MILLIS_PER_DAY )
  {
    // one whole day has passed
    day++;
    prevMillis += MILLIS_PER_DAY;

    // do the things you want to do at the beginning of a new day
    if( day==2 ) {
      Serial.println("daytwo");
    }
    else if (day == 4) {
      Serial.println("dayfour");
    }
  }
}

```

This is a more generic version. It checks if `24*60*60*1000` milliseconds have past since the last time the day rolled over. When this occurs, it will increment the current day and update `prevMillis` to have the value of millis() when the day started.

This also has the advantage that is will only run your "daily code" once.

And will also run, when some other task takes a long time. I your old code, you might miss the exact moment millis() is the value you are looking for, if some other code takes more than 1 ms.
> 0 votes

---
Tags: esp8266, arduino-ide
---


# Question
Title: Using Leonardo as keyboard: add wake and sleep functions
I want to use a Leonardo with USB chip to emit some commands via USB port to a digital piano computer (running Windows 7) for various functions. I've gotten the Leonardo to emit page up and page down functions using a simple project I found on the web. What I need now is the following set of functions: left arrow, right arrow, F11, wake, and sleep. What I need help with is:

* where is the complete list of functions available with keyboard.press?
* are wake and sleep among those available?
* if they aren't, what header file could be modified to include them?

Thank you for any suggestions.

# Answer
It turns out there is a library that can be added to compile the media and system functions for USB keyboard connection into the Leonardo, as well as other Arduino modules. It is available through 'tools','library manager'; it is HID-project by NicoHood. There is an example program called "system example" at github to test it for for wake and sleep. It works perfectly. I expect it'll work for the other functions too.
> 1 votes

---
Tags: arduino-leonardo, keyboard
---


# Question
Title: Using same GPIO pins to control multiple stepper drives
I have an Arduino Mega 2560 and I want to control four 23-frame steppers same speed/direction for a conveyor application. I want these to be synchronized exactly as possible for smooth operation.

* Can four TB6600 drivers be daisy chained to the same Arduino GPIO pins?
* Is there a limit to how many number of drivers I can daisy chain?
* I'm wondering about current draw from the 5 volt Arduino GPIO, spread out over many drivers.

Thanks for your help!
Bob

# Answer
Those devices use opto-isolated inputs. To all intents and purposes they look just like an LED with a resistor in series.

The built-in resistor looks like it sets the current to "between 8mA and 15mA" and typically 10mA, though it's impossible to say what it *actually* is. So we'll take the worst-case scenario of 15mA.

The Arduino has an absolute maximum of 40mA, and a recommended maximum of 25mA from each IO pin, with a maximum of 200mA in total through all pins.

That means you ideally can't really have more than one TB6600 per IO pin, but you could get away with 2 per pin, certainly no more.

To run lots in parallel you would need a separate set of drivers that can "fan out" the low-current signal to either a single high current signal or a parallel set of low-current signals.

It looks like you provide 5V to one pin of each input (the anode of the opto-isolator) and sink the current through the other pin (the cathode of the opto-isolator) to ground through your IO pins. That means you could use a single large N-channel MOSFET to sink all of the cathodes in parallel and invert your IO logic in software.
> 2 votes

---
Tags: arduino-mega, pins, stepper-motor
---