message:
Run multiple function with different argument/return structure by one function pointer

**Edit:**
I tried a simple code in Arduino IDE which should've done in the first place instead in doing it in a desktop compiler. Because the results are different by experiment. In the desktop C compiler, it's working and bypassing the code without much problems, just one or two warnings.

But in Arduino IDE, it's not acceptable and gives error.

This is the code:

    // functions
    void function1(uint8_t x, uint8_t y){
      int z = x + y;
      Serial.println("function1\n");
      Serial.println(z);
    }
    uint8_t function2(uint8_t x, uint8_t y){
        Serial.println("function2\n");
        return 1;
    }

    void (*fun_ptr)();

    void setup() {
      // put your setup code here, to run once:

      Serial.begin(9600);
      fun_ptr = (void (*)())function2;
      int value;

      value = fun_ptr(1,2);

    }

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

    }

body:
I assume, that the `fun_ptr` points to the different service functions to do some kind of animation other other long running tasks on your display, thus you want to repeatedly call them in a structured way.

What you are currently doing will not really work. When you call a function, you need to provide its arguments. That's the same for a function pointer. You cannot call a function, that demands parameters, without any parameters. While you can still set a function pointer of type `(void (*)(void*)` to a function of type (void (*)(uint8_t)), the compiler warns so, because you still cannot call the function without any parameter. If you are trying to do so, you will still get an error of `too few arguments to function ...`.

I see 2 ways to go from here:

- You could overload your functions, so that a version without any parameters exists. Like this:

        void foo(uint8_t i){Serial.println(i);}
        void foo(){foo(10);}

    With 10 being the value, with which the function should be called, when you provide no parameters. You can of course also use variables or function calls here, to actually get that value for the parameter `i`. Then you can use the pointer to call that function:

        void (* p)(void);
        p = &foo;
        p();

    The assignment of the pointer will choose the version of the function without any parameters out of the overloaded pool of this function, since that matches the type of the pointer. Note, that I removed the `*` from the `void` parameter definition. I don't understand, what that would mean anyway (pointer to void?). The function pointer `p()` can now be called without any parameters, since it points to a function without any parameters.

- You could ditch the function pointer and use a simple switch case statement with a state variable (which holds some identifier for the corresponding function), to call the correct service function. I won't go into detail here, since that is already basically, how an FSM can be programmed in C++, which is covered on this site and on the web numerous times.

If I were you, I probably would go with the first option, though that might also depend on the overall logic, that I currently don't really understand (too few information).


sender: user

sender: assistant

body:
Here's my latest work around:

I was searching for a work around. I got back to copy a method of casting a function pointer.

And changed my data structure of having 2 nested structs to one that contain everything which should serve my project well.

Here's my work:

task_manager.h

    ///////////////////////////////////////////////////////////////////////////
    // enumerations
    typedef enum {NOT_FINISHED,FINISHED,DONE}STATE;
    // variables
    typedef void (*f_ptr)(void *args);

    // structs
    typedef struct __attribute__((__packed__)) THREAD{
        uint8_t tsk_cnts, tsk_cntr;     // task information
        STATE   thrd_st;                  // thread flag states
        f_ptr   *tsk_fptr;
    }THREAD;

main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include "task_manager.h"

    const unsigned char PIC[] = {9, 8, 7, 1, 2};

    void function1(void){printf("function1\n");}
    void function2(uint8_t i){printf("function2\nnumber = %d\n",i);}
    void function3(uint8_t a, uint8_t b, const uint8_t *img){
        printf("function3\na#%d b#%d\narray[0] = %d\n",a,b,*(img+0));}
    uint8_t function4(uint8_t i){printf("function4# return\n"); return i+=1;}

    THREAD thread1;

    uint8_t fn4_ret;

    int main(){

        // set thread main info
        thread1.thrd_st = 0;
        thread1.tsk_cnts = 4;
        thread1.tsk_cntr = 0;

        // allocating memory for tasks
        thread1.tsk_fptr = malloc(4*sizeof(f_ptr));

        // store tasks addresses
        thread1.tsk_fptr[0] = (void(*)())function1;
        thread1.tsk_fptr[1] = (void(*)())function2;
        thread1.tsk_fptr[2] = (void(*)())function3;
        thread1.tsk_fptr[3] = (void(*)())function4;

        // call the functions
        ((void(*)())thread1.tsk_fptr[1])(9);
        ((void(*)())thread1.tsk_fptr[2])(1,2,PIC);
        fn4_ret = ((uint8_t(*)())thread1.tsk_fptr[3])(1);
        printf("\fn4_ret = %d\n",fn4_ret);

        return 0;
    }

It compiled with me fine, passed what I want and returned the required data.


body:
It looks to me like you are trying to find the right answer to the wrong
question, typical of an [XY problem][]. In the example you provide in
your own answer, you call the function pointer right after having set
its value. In this case, there is no use to the function pointer, as you
could directly call either `read_chars()` or `write_chars()`.

Obviously, this is just because that example is excessively simplified.
In a more realistic use case, you would set the function pointer in one
part of the code, and call it in a completely different part. Assuming
the functions and the pointer are defined like this:

```c++
void (*fun_ptr)();

void read_chars(uint8_t address) {
    printf("address of array is 0x%.2x\n", address);
}

void write_chars(uint8_t row, uint8_t col, const char *str) {
    printf("[%d, %d]: %s\n", row, col, str);
}
```

One section of the program sets the pointer:

```c++
// Here we learn what action should be performed.
if (should_read()) {
    fun_ptr = (void(*)()) read_chars;
} else {  // should write
    fun_ptr = (void(*)()) write_chars;
}
```

and a different section calls it:

```c++
// Here we have to perform the action.
if (fun_ptr == (void(*)()) read_chars) {
    ((void(*)(uint8_t)) fun_ptr)(1);
} else if (fun_ptr == (void(*)()) write_chars) {
    ((void(*)(uint8_t, uint8_t, const char *)) fun_ptr)(
            1, 1, "messaage0");
}
```

Note that this second section **must** know what function it is calling
in order to pass the correct arguments. Hence the `if...then` test. Note
also that, in order to have valid C++, you must explicitly cast the
function pointer before calling it. This gets very clumsy, and it is a
lot more convenient to store this information (what function should be
called) in an `enum` rather than a function pointer:

```c++
enum {
    CALL_NONE, CALL_READ_CHARS, CALL_WRITE_CHARS
} what_to_call = CALL_NONE;
```

which would be used like this:

```c++
// Here we learn what action should be performed.
if (should_read()) {
    what_to_call = CALL_READ_CHARS;
} else {
    what_to_call = CALL_WRITE_CHARS;
}

// ...

// Here we have to perform the action.
if (what_to_call == CALL_READ_CHARS)
    read_chars(1);
else if (what_to_call == CALL_WRITE_CHARS)
    write_chars(1, 1, "messaage1");
```

That being said, it is often the case that when it is time to perform
the action, the part of the code responsible of doing so does not know
what arguments should be passed, and this information is more readily
available at the time when when learn what action should be performed.
This is a quite common situation, and a standard C idiom in this case is
to give the function a `void *` parameter that it will cast to the
appropriate type in order to retrieve the data it needs. For instance:

```c++
void (*fun_ptr)(void *);
void *fun_ptr_data;

void read_chars(void * data) {
    uint8_t address = * (uint8_t *) data;
    printf("address of array is 0x%.2x\n", address);
}

struct write_chars_data {
    uint8_t row;
    uint8_t col;
    const char *str;
};

void write_chars(void *data) {
    write_chars_data *d = (write_chars_data *) data;
    printf("[%d, %d]: %s\n", d->row, d->col, d->str);
}
```

Note that, since `write_chars()` needs to retrieve multiple parameters
from a single pointer, it uses a pointer to a `struct`.

Now, the part of the code that learns what should be done has the
responsibility of providing the data:

```c++
// Here we learn what action should be performed.
if (should_read()) {
    fun_ptr = read_chars;
    uint8_t *p = new uint8_t;
    *p = 1;
    fun_ptr_data = (void *) p;
} else {  // should write
    fun_ptr = write_chars;
    write_chars_data *p = new write_chars_data;
    p->row = 1;
    p->col = 1;
    p->str = "messaage2";
    fun_ptr_data = (void *) p;
}
```

The part of the code that has to perform the action now is very simple:

```c++
// Here we have to perform the action.
if (fun_ptr)
    fun_ptr(fun_ptr_data);
```

Note that this code snippet doesn't free the allocated memory. You will
have to figure out who will be responsible for that.

This pattern is quite common in libraries, where the client (the user of
the library) wants an action to be performed, but the library is
responsible for performing that action at the right time. The client
would then provide the library a pointer to a function that accomplishes
the action (called a “callback”), together with a generic pointer to the
data needed by the callback. The use of a generic `void *` pointer makes
sense, because the library cannot know what kind of data the callback
will need.

In your case, since you know what kind of data you may need, you could
use a pointer to an `union` instead of a generic pointer:

```c++
union fun_data {
    uint8_t address;  // for read_chars
    struct {          // for write_chars
        uint8_t row;
        uint8_t col;
        const char *str;
    };
};

void (*fun_ptr)(fun_data *);
fun_data *fun_ptr_data;
```

A more idiomatic C++ style would be to pack together the callback
function and its data into a “functor”, i.e. an object that can be
called like a function, and can also store the data it needs. You would
then use inheritance in order to create specific functor types while
calling a generic one.

[XY problem]: https://xyproblem.info/


message:
Timing push button code

I am trying to time how long button is held for. The code seems to work but with two problems:

1) the millis values are being read wrongly. If you hold the button for 1 second, it returns holdTime of about 3000 ms. A quick click returns holdTime of about 1000 ms.

2) Each successive button press adds to the previous millis value so holdTime just gets higher and higher and doesn't measure how long the button has just been pressed for

Any ideas or advice for newbie welcome!

```c++
#include <LiquidCrystal.h>

const int button1Pin = 1;  // pushbutton 1 pin
const int ledPin = 13;     // LED pin

int button1State, button2State;  // variables to hold the pushbutton states
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int startPressed = 0;
int endPressed = 0;
int holdTime = 0;

void setup() {
  // Set up the pushbutton pins to be an input:
  pinMode(button1Pin, INPUT);

  // Set up the LED pin to be an output:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
\
}

void loop() {

  while (digitalRead(button1Pin) == LOW) {}

  button1State = digitalRead(button1Pin);
  startPressed = 0;
  endPressed =0;
  holdTime = 0;

  // if button1 or button 2 are pressed (but not both)
  if (button1State == LOW) {
    digitalWrite(ledPin, LOW);   // turn the LED on
    startPressed = millis();
  } else {
    digitalWrite(ledPin, HIGH);  // turn the LED off
    endPressed = millis();
    holdTime = endPressed - startPressed;
  }
  lcd.print("You pressed for");
  lcd.setCursor(0, 1);
  lcd.print(holdTime);
  lcd.print("ms");
  while (digitalRead(button1Pin) == LOW) {}
  lcd.clear();
  startPressed =0;
  endPressed =0;
  holdTime = 0;
}
```

body:
Your source has several flaws, and one error that generates the output you see. This is the analysis of the error.

In `loop()` you start by waiting for the button pin to get HIGH, following by another read of the pin's state that will most probably return the same, HIGH. _Note: Only if your button bounces with just the right timing, this last read will return LOW._

    while (digitalRead(button1Pin) == LOW) {}
    button1State = digitalRead(button1Pin);

Next you check the pin's state, and let's assume that it is HIGH. Only the `else` part is executed, and it calculates the `holdtime` as the difference of `endPressed` and `startPressed`. The former has the current value of `millis()`, but the latter is 0 as you initialized it.

That's why you're getting always growing values.

**How to solve?**

Think about the `while` loops, do you need them? Remember that `loop()` is already called repeatedly.

You may need a state variable that stores the last pin's state, so you can detect changes.


message:
trigger a function of a Arduino Uno from signal received by LoRa module

I have two sx1278 Lora transceivers where both are connected to two Arduino Uno boards. I want to trigger a function in the Arduino Uno board where receiver side of LoRa connected using the signal received by Lora receiver.

body:
I'm assuming you have read the datasheet for the SX1278.  If not, please refer to it at:

[SX1278 Datasheet][1]

On page 69 you will see a couple of tables regarding the functions possible on the digital I/O (i.e. DIO) pins:

[![SX1278 DIO Pin Functions][2]][2]

I'm not clear what exactly you are looking for or which mode you are operating in (you have provided almost no information about your project) but all the information you might need is available on these DIO pins.

You can connect the appropriate pin or pins to some of the edge sensitive lines on your Arduino and define and enable an INTERRUPT in your code.  So when the event you are waiting for happens, an interrupt will occur, you can go and read the data and do whatever with it.

  [1]: https://semtech.my.salesforce.com/sfc/p/#E0000000JelG/a/2R0000001Rc1/QnUuV9TviODKUgt_rpBlPz.EZA_PNK7Rpi8HA5..Sbo
  [2]: https://i.stack.imgur.com/F3VY0.png


message:
Code is not running, servo does not even spin

I am trying to run a program which works as follows:

An LDR is integrated in a box. A block is placed on top. This box can be rotated by a servo. The program is supposed to make the box turn until the block slides and lifts off from the LDR.

At that point the servo angle is stored and used to calculate the friction coefficient.

Finally, the answer to this calculation is printed on an LCD and the program repeats by first returning the box to the original state. The entire programs runs on an Arduino and an Arduino Lotus. Why doesn't the servo rotate?

```c++
//servo
#include <Servo.h>

Servo myservo;
int previous_angle = 0;
int angle = 0;

//lightsensor
int lightsensor = 0;
int LIGHT = 800;
int DARK = 940;

//LED screen
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

void setup() {
  Serial.begin(9600);
  myservo.attach(6);

  pinMode(lightsensor, INPUT);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  delay(100);
}

void loop() {
  int i = previous_angle;
  int lightStatus = analogRead(lightsensor);

  if (lightStatus >= DARK) {
    delay(300);

    while (int i = previous_angle) {
      i<=90;
      i = i+1;
      myservo.write(i);
      delay(45);
    };
  } else if (lightStatus < DARK) {
    for (int i = previous_angle; i>0;) {
      delay(300);
      int angle = tan(i);
      display.clearDisplay();
      display.setTextSize(1.5);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println(angle);
      display.display();
      delay(300);

      myservo.write(0);
      delay(45);
    };
  }
}
```

body:
For starters: this bit is a strange mixture of `for` and `while` syntax:

```c++
while (int i = previous_angle) {
  i <= 90;
  i = i + 1;
  myservo.write(i);
  delay(45);
};
```

It will compile, but probably not do what you want it to do. It should probably be:

```c++
for (int i=previous_angle; i<=90; i=i+1) {
  myservo.write(i);
  delay(45);
}
```

Also, `previous_angle` is never changed in your code after initialisation; it is always 0.

That also means that the `for` loop below will not do what you want (and that loop also doesn't increment `i` anywhere):

```c++
for (int i = previous_angle; i>0;)
```

There may be more; make the suggested changes first and see what happens.


message:
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][1]

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

  [1]: https://www.makerguides.com/l298n-stepper-motor-arduino-tutorial/

body:
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.


body:
Take a look at [this video][1] - it has a great explanation of using a 5-wire stepper motor with an Arduino

  [1]: https://www.youtube.com/watch?v=0BW-mboT-xo


message:
(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:

```c++
#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?

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


message:
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.
[![enter image description here][1]][1]

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.

[![enter image description here][2]][2]

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 ?

  [1]: https://i.stack.imgur.com/IoaFF.jpg
  [2]: https://i.stack.imgur.com/mhp78.jpg

body:
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.


body:
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.


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


message:
Not able to build program with arduino program under clion

I'm pretty new to arduino and I just downloaded clion and installed the arduino plugin so I have an IDE that I'm used to. Here is my code:

    #include <Arduino.h>

    // Time between a switch indicating not full and the time a valve is opened
    #define SWITCH_DELAY 5000

    #define PIN_SWITCH 2
    #define PIN_GREEN 3
    #define PIN_YELLOW 4

    #define INT16 int
    #define UINT16 unsigned int
    #define UINT32 unsigned long

    DelayChecker    degassingChecker(PIN_SWITCH, PIN_GREEN);

    void setup() {
        pinMode(PIN_SWITCH, INPUT);
        pinMode(PIN_GREEN, OUTPUT);
        pinMode(PIN_YELLOW, OUTPUT);

        Serial.begin(9600);
        Serial.print("UINT16: " + sizeof(UINT16));
        Serial.print("UINT32: " + sizeof(UINT32));
    }

    void loop() {
        UINT32 now = millis();

        degassingChecker.check(now);
    }

    public class DelayChecker {
        private:
            UINT32 delayExpires = 0;
            UINT16 switchId = 0;
            UINT16 solenoidId = 0;
            bool solenoidOn = false;

        public:
            DelayChecker(const unsigned int sw, const unsigned int sol) {
                switchId = sw;
                solenoidId = sol;
            }

            void check(const UINT32 now) {
                if (delayExpires == 0) {
                    INT16 switchState = digitalRead(switchId);
                    if (switchState == LOW) {
                        delayExpires = millis() + SWITCH_DELAY;
                        digitalWrite(PIN_YELLOW, HIGH);
                    }
                }
                else {
                    if (now >= delayExpires) {
                        INT16 switchState = digitalRead(switchId);
                        if (switchState == LOW) {
                            if (!solenoidOn) {
                                digitalWrite(solenoidId, HIGH);
                                solenoidOn = true;
                            }
                        }
                        else {
                            if (solenoidOn) {
                                digitalWrite(solenoidId, LOW);
                                solenoidOn = false;
                            }
                        }
                    }
                }
            }
    };

I hit the run button and get the following.

    ====================[ Build | untitled1 | Debug ]===============================
    /opt/clion/bin/cmake/linux/bin/cmake --build /home/thomas/CLionProjects/untitled1/cmake-build-debug --target untitled1 -- -j 12
    [  7%] Building C object CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/wiring_pulse.c.obj
    [  7%] Building CXX object CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/new.cpp.obj
    [ 10%] Building C object CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/wiring_shift.c.obj
    /opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/new.cpp:29:46: error: expected initializer before 'noexcept'
     void * operator new(size_t size, void * ptr) noexcept {
                                                  ^~~~~~~~
    gmake[3]: *** [CMakeFiles/uno_CORE.dir/build.make:317: CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/new.cpp.obj] Error 1
    gmake[3]: *** Waiting for unfinished jobs....
    gmake[2]: *** [CMakeFiles/Makefile2:99: CMakeFiles/uno_CORE.dir/all] Error 2
    gmake[1]: *** [CMakeFiles/Makefile2:133: CMakeFiles/untitled1.dir/rule] Error 2
    gmake: *** [Makefile:151: untitled1] Error 2

It looks like an error in the libraries. Has anyone seen anything like this?

body:
I found a github issue fixing this error : https://github.com/vsch/CLionArduinoPlugin/issues/36

It worked for me


message:
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)
```
[![Buzzer][1]][1][![microphone-module][2]][2]

  [1]: https://i.stack.imgur.com/HnMRS.png
  [2]: https://i.stack.imgur.com/1J5De.png

body:
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.


body:
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.


message:
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:

```c++
#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:

[![Circuit][1]][1]

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

body: 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.


message:
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

body:
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:

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


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

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


message:
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 ?

body:
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.


message:
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 ?

body:
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][1] 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.

  [1]: https://en.wikipedia.org/wiki/Tail_call


message:
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!

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/lE3m3.png)

<!-- End schematic -->

body:
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:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/TCKv3.png)

<!-- End schematic -->

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.


body:
I think all this effort is unnecessary. The ATTINY45 pulls a *maximum* of 2uA when sleeping...

[![enter image description here][1]][1]

..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][2]. 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.

  [1]: https://i.stack.imgur.com/PZOrd.png
  [2]: https://frinklang.org/fsp/frink.fsp?fromVal=(2600 milliamp hours) / (2 microamp)&toVal=years#calc


message:
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.

body:
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!


message:
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.

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


message:
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!

body:
PB1 has no analog input. So no, you can't read analog with it.

For analog you must use any of PB2 through PB5.


message:
Configure Trinket M0 as I2C peripheral

I am trying to use I2C to communicate between my XBee3 (controller) and an adafruit trinket m0 (peripheral). I'm pretty confident I have the modules connected properly (trinket SCL/pin 2 to xbee SCL/pin DIO1 & trinket SDA/pin 0 to xbee SDA/pin DIO11, and both grounds are connected). Here is my arduino code on the trinket:
```
#include <Wire.h>

void setup()
{
Wire.begin(72); // join i2c bus
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
Serial.print("Waiting for data...");
}

void loop()
{
delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
(void)howMany; // avoid compiler warning about unused parameter

while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
```
and here is my code on the XBee:
```
from machine import I2C

# Instantiate an I2C peripheral.
i2c = I2C(1)
slave_addr = 72
i2c.writeto(slave_addr, b'123', False)
```
Additionally, when I run an i2c.scan() on the xbee with an ISM330DHCX connected to the xbee's I2C, the address pops right up. But when I use the exact same code with the xbee connected to the trinket m0, the xbee cannot find any devices. (Code pasted below)
```
from machine import I2C

# Instantiate an I2C peripheral.
i2c = I2C(1)

# Scan for I2C slaves connected to the interface and print their address.
for address in i2c.scan():
    print("- I2C device found at address: %s" % hex(address))
```
Does anyone have any ideas what I'm doing wrong with configuring the trinket m0 to be an i2c peripheral? Thank you!

body:
I have two Adafruit Trinket M0 arduino boards running on my bench right now talking to each other over I2C. The trick is that you need to install a pull-up resistor between SDA and +3V, and another one between SCL and +3V. Typically it is the peripheral boards that come with those but when you talk between two microcontrollers which are often used as the master controller themselves they are open drain or not powerful enough to drive the bus. Any resistor between 4.7k and 10k ohms should do.

see the following reference doc:

https://docs.particle.io/cards/firmware/wire-i2c/pull-up-resistors-i2c/

From the other direction if you have many peripheral boards that all include their own pull up resistors, the combined resistance on the bus may low enough leak enough current to raise "low" state above 0.4v, at which point communication may have errors.

Or if the wires are too long or there are too many devices without enough pull up resistance (thus too much inherent capacitance) it will take too long for the data lines to reach the "high" state, and you will have to slow down the clock rate or add a signal booster like the LTC4311 (e.g. Adafruit product #4756) to get stable results.


message:
Arduino Mega 2560 + BLE HM-10 - I cannot execute AT commands

I have an Arduino Mega 2560 and a HM10 Bluetooth module ([this one][1])

I have connected the Bluetooth according to the manufacturer's specifications:
VCC -> 5v
GND -> GND

TXD and RXD of the Bluetooth, I have tried to put them in pins of Arduino, in Serial1, in Serial2, in Serial3, with the same result.

The code I use for my tests is this:

    #define BTserial Serial1

    int LED_BOARD = 13;
    int LED_RED = 2;
    int LED_GREEN = 3;

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

        pinMode(LED_BOARD,OUTPUT);
        pinMode(LED_RED,OUTPUT);
        pinMode(LED_GREEN,OUTPUT);
    }

    void loop() {
        if (Serial1.available()) {
            dato = Serial1.readStringUntil('\n');

            Serial.println("DATA RECEIVED: [" + String(dato) + "]");

            if (dato.equals("1")) {
                digitalWrite(LED_BOARD, HIGH);
            }
            if (dato.equals("0")) {
                digitalWrite(LED_BOARD, LOW);
            }

            if (dato.equals("RED_ON")) {
                digitalWrite(LED_RED, HIGH);
            }
            if (dato.equals("RED_OFF")) {
                digitalWrite(LED_RED, LOW);
            }

            if (dato.equals("GREEN_ON")) {
                digitalWrite(LED_GREEN, HIGH);
            }
            if (dato.equals("GREEN_OFF")) {
                digitalWrite(LED_GREEN, LOW);
            }
        }
    }

I have an Android phone, and I use the Arduino Bluetooth Controller (HM-10 Module) app.

- I send the text 1, and the led of the Arduino board (pin 13) turns on.
- I send the text 0, and the led of the Arduino board (pin 13) turns off.
- I send RED_ON, and the led of my breadboard, connected to pin 2, turns on
- I send RED_OFF, and the led of my breadboard, connected to pin 2, turns off
- I send GREEN_ON, and the led of my breadboard, connected to pin 3, turns on
- I send GREEN_OFF, and the led of my breadboard, connected to pin 3, turns off

So the Bluetooth works.

My problem is trying to see the list of Bluetooth commands (AT+HELP command).

I have a method that is responsible for sending AT+HELP to bluetooth, but I have no response.

This is the method, which I run in the main:

    String str_ii = "";
    int ii_0 = 0;
    void ble_help(){
        Serial.println("ble_help");

        BTserial.println("AT+HELP"); // list all AT+ commands
        while (true){ // loop to print all AT+ commands
            char in_char = BTserial.read();
            if (int(in_char)==-1 or int(in_char)==42){
                continue;
            }
            str_ii+=in_char;
            if (in_char=='\n'){
                if (str_ii==String('\r')+String('\n')){
                    if (ii_0 == 0){
                        ii_0 = 1;
                        continue;
                    }
                    break; // break after more than 1 empty carriage return and newline
                }
                Serial.print(str_ii);
                str_ii = "";
            }
        }
    }

When executing this method, in application Arduino Bluetooth Controller (HM-10 Module) app i see the text AT+HELP, but there is no reaction / response from the bluetooh. Neither in the Arduino Bluetooth Controller (HM-10 Module) application nor in the Arduino serial monitor

What am I doing wrong?

Thank you.

  [1]: https://www.amazon.es/gp/product/B06WGZB2N4/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1

body:
First thing first you can see all AT commands available from the data sheet available from [datasheet][1]

Second to get strings from Serial to BTserial you can just use `c = Serial.readStringUntil('\n');` like here

    #define BT_RX           0
    #define BT_TX           1
    #define BT_Serial       Serial1
    #define BT_Timeout      100

    String c, c2;

    void setup() {
      BT_Serial.setTX(BT_TX);
      BT_Serial.setRX(BT_RX);
      BT_Serial.begin(9600);//baudrate
      BT_Serial.setTimeout(BT_Timeout); //set bluetooth read/write timeout

      Serial.begin(9600);
      Serial.setTimeout(100);
      delay(100);
    }

    void loop()
    {
      if (Serial.available()) {
        c = Serial.readStringUntil('\n');
        Serial.println(c);
        BT_Transmit_AT(c);
      }
      if (BT_Serial.available()) {
        c2 = BT_Serial.readStringUntil('\n');
        Serial.println(c2);
      }
      delay(20);
    }

    void BT_Transmit_AT(String data) { //send AT commands
      unsigned long current_time = millis();
      while (BT_Serial.available() > 0) {
        if (millis() - current_time > 100){ //timer to get out incase not receiving anything
          Serial.println("Timeout");
          break;
        }
      }
      BT_Serial.print(data);
    }

And lastly you need to make sure your HM-10 is genuine/has genuine firmware installed or it's a clone. Check if it respond to "AT" with "OK" at all. If it does then it's genuine and you can continue. If it doesn't then you need to flash genuine firmware onto it, then upgrade from there if you. [Here][2] is a good tutorial on flashing the genuine firmware onto the module.

After that you can follow a tutorial [here][3] on upgrading the firmware from an older genuine firmware. You can get the latest genuine firmware from the [Manufacture's website][4].

  [1]: http://jnhuamao.cn/bluetooth40_en.zip
  [2]: https://circuitdigest.com/microcontroller-projects/how-to-flash-the-firmware-on-cloned-hm-10-ble-module-using-arduino-uno
  [3]: https://techienoise.blogspot.com/2016/02/upgrading-firmware-to-hm-10-cc2541-ble.html
  [4]: http://jnhuamao.cn/download_rom_en.asp?id=1


message:
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][1] 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:

```c++
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:

```c++
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:

[![enter image description here][2]][2]

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:

```c++
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!

  [1]: https://github.com/mobizt/Firebase-ESP8266
  [2]: https://i.stack.imgur.com/fOL8c.png

body:
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.


message:
how to clear heap memory in esp32?

I am using Free RTOS on esp32 in my program.
However at some point of time when I execute xTaskCreate() it returns -1 , which error is  could_not_allocate_required_memory. In my program, each time i pring getFreeHeap() it is reduced by 2000 approximately and is never cleared or reset, when it is not sufficient or below 2000 xTaskCreate returns -1.

After reading a lot of forums I could not find a way to clear the memory to create a task, can anyone guide me achieving this ?

**code snippet**

```cpp
void createTsk(){
  SerialDebug.print("available Heap size: ");
  SerialDebug.println(ESP.getFreeHeap());

  BaseType_t xBy = xTaskCreate(taskPriorityOne, "TaskOne", 20240, NULL, 1, &thOne);
  SerialDebug.println("Return Val : ");
  SerialDebug.println(xBy);
}

void taskPriorityOne(void *paramter)
{
   SerialDebug.println("Prio 1 task Initiated");
   threadTask(priorityOneQue, "task1", thOne);
}

void threadTask(QueueHandle_t priorityQue, String taskName, TaskHandle_t th)
{
  xQueueReceive(priorityQue, &taskdataholder, portMAX_DELAY);
  ongoingProcess = taskdataholder;
  furtherExecutionHttp(taskdataholder, fnm, taskName, th);
}

void furtherExecutionHttp(DataHolder *taskdataholder, String fnm, String
taskName, TaskHandle_t th)
{
   String response = httpRequest(taskdataholder->protocol, taskdataholder-
   >host, taskdataholder->port, taskdataholder->url, taskdataholder->body,
   fnm);

  delay(10);

  free(taskdataholder);
  SerialDebug.println("Releasing memory..\n");

  vTaskDelete(th);
}
```

body:
You probably don't want to "clear" the heap, assuming you mean either deallocating or zeroing all memory that you've allocated from the heap.

If you simply return all memory to the heap when you run out, your code may have pointers to that memory remaining when that memory gets allocated to another use, meaning some data will likely get over-written. Or, if you clear the heap (by zeroing it) you will be over-writing data already stored there, and possibly still be unable to allocate more memory if the allocator doesn't "know" that you meant to return it.

Instead, your code should free each memory allocation as soon as it is no longer useful, and make sure its pointer to that memory won't be used again. One way to protect re-use of dead pointers is 1) zero them when you deallocate the memory they point to; and 2) always test for a valid pointer (non-zero) before you try to use it.


body:
The heap memory in ESP32 cannot be cleared explicitly. The heap memory is used to store dynamically allocated objects, and when an object is no longer needed, it is automatically deallocated by the garbage collector.

You can free up some heap memory by deleting unused objects. In your code, you create a new object called **taskdataholder** in the **furtherExecutionHttp()** function. This object is allocated on the heap and will only be deallocated once the function returns. If you want to free up this memory, you can call the **free()** function before the function returns.


message:
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:
```c++
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`:
```c++
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:
```c++
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?:
```c++
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.

body:
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

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


message:
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.

```c++
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);
    }
  }
}
```

body:
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;


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


message:
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.

body:
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.


message:
Checking if Arduino board works or is damaged

I have an Arduino Uno and Mega, but when I connect them to a computer with the USB they came with, there is no green light near the reset button that illuminates.

On the Uno board the pin 13 continuously flashes with red light while on the Mega board the R17 and R18 both illuminate red light but no flashing.

How do I know if the boards work or are damaged?

body:
Did you try to connect to the computer and upload a blank sketch or a blink sketch...
If the program complies and uploads successfully it is alive.
But you will have to check IO, ADC and other features separately.


message:
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?

body:
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][1]. Both problems have been solved before for certain types of Arduinos.  [Here is a project on GitHub][2] which has solutions for boards using the [ESP8266][3] or [ESP32][4] processors.

  [1]: https://en.wikipedia.org/wiki/Non-volatile_memory
  [2]: https://github.com/tzapu/WiFiManager
  [3]: https://en.wikipedia.org/wiki/ESP8266
  [4]: https://en.wikipedia.org/wiki/ESP32


body:
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][1] works (for the ESP8266 and the ESP32).

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

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

  [1]: https://github.com/tzapu/WiFiManager
  [2]: https://www.arduino.cc/en/Reference/EEPROM
  [3]: https://github.com/cmaglie/FlashStorage