body:
I've got a NodeMCU V1 and a MAX31865 with a PT100 attached.  When using the example arduino code, it seems to log out the correct values but with an RTD Low Threshold error like so:

    RTD value: 8068
    Ratio = 0.24621582
    Resistance = 105.87280273
    Temperature = 15.09
    Fault 0x40
    RTD Low Threshold

The loop will continue for a few iterations and then throw an exception, before resuming logging out of the values above

The exception reads:

    --------------- CUT HERE FOR EXCEPTION DECODER ---------------

    Soft WDT reset

    >>>stack>>>

    ctx: sys
    sp: 3fffed00 end: 3fffffb0 offset: 01a0
    3fffeea0:  38fe9521 00000000 3ffe8938 00000030
    3fffeeb0:  401015ea 3ffe88f4 004ae1cb 40233b68
    etc etc etc

The code is as follows.

    #include <Adafruit_MAX31865.h>

    // Use software SPI: CS, DI, DO, CLK
    Adafruit_MAX31865 thermo = Adafruit_MAX31865(D4,D1,D2,D3);
    //Adafruit_MAX31865 thermo = Adafruit_MAX31865(D4);

    #define RREF      430.0
    #define RNOMINAL  100.0

    void setup() {
      Serial.begin(9600);
      Serial.print("Adafruit MAX31865 PT100 Sensor Test!");
      thermo.begin(MAX31865_3WIRE);  // set to 2WIRE or 4WIRE as necessary
    }

    void loop() {
      uint16_t rtd = thermo.readRTD();
      Serial.print("RTD value: "); Serial.println(rtd);
      float ratio = rtd;
      ratio /= 32768;
      Serial.print("Ratio = "); Serial.println(ratio,8);
      Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
      Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

      // Check and print any faults
      uint8_t fault = thermo.readFault();
      if (fault) {
        Serial.print("Fault 0x"); Serial.println(fault, HEX);
        if (fault & MAX31865_FAULT_HIGHTHRESH) {
          Serial.println("RTD High Threshold");
        }
        if (fault & MAX31865_FAULT_LOWTHRESH) {
          Serial.println("RTD Low Threshold");
        }
        if (fault & MAX31865_FAULT_REFINLOW) {
          Serial.println("REFIN- > 0.85 x Bias");
        }
        if (fault & MAX31865_FAULT_REFINHIGH) {
          Serial.println("REFIN- < 0.85 x Bias - FORCE- open");
        }
        if (fault & MAX31865_FAULT_RTDINLOW) {
          Serial.println("RTDIN- < 0.85 x Bias - FORCE- open");
        }
        if (fault & MAX31865_FAULT_OVUV) {
          Serial.println("Under/Over voltage");
        }
        thermo.clearFault();
      }
      Serial.println();
      delay(10000);
    }

<!-- 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/3SaWK.png)

<!-- End schematic -->

title: MAX31865 & NodeMCU RTD Low Threshold and Exception

Answers: 0


body:
I am trying to make a Bluetooth controlled robot and have troubles with the Bluetooth modules. I used  3 HC-06 Bluetooth module. All of them have different problems.

- I could not find the 1st HC-06 under the list of Bluetooth devices in the settings.
- The 2nd HC-06 could be paired with the phone but I could not send the message on the Bluetooth terminal app (The error message from the app is below).
- The 3rd HC-06 could be paired and I could send a message but the message was not registered on the Arduino nor on serial monitor. On the Bluetooth terminal app, the message was received but not replied.

What could be the problem? I'm pretty sure my connections are correct as I have checked them and they used to work.

[![This is the error on the second HC-06][1]][1]

  [1]: https://i.stack.imgur.com/rijTb.jpg

title: Various Bluetooth HC-06 modules erratic in different ways

Answers: 0


body:
I am making a shutter for my camera using a Arduino and an optocoupler.

I understand most of most parts, but unsure about the resistor because I don't have the correct size. 5V will be coming from the Arduino, and the [4N35][1] will need 1.3V 10mA. This leads to a 380Ω resistor.

Now I only have 100Ω, 220Ω, 330Ω, and 1kΩ resistors. I have read I shouldn't use anything lower than 380Ω and only use higher but 1kΩ seem a little too high haha.

Just looking for some pointers please.

  [1]: https://www.vishay.com/docs/81181/4n35.pdf

title: Resistor - Correct value for optocoupler, but dont have that size

Answers: 2

body:
1kΩ will be just fine. But if you want lower you could take two 1kΩ and place them in parallel - that will give you 500Ω.

BTW - 1kΩ will give you ((5-1.3)/1000=) 3.7mA through the diode of the optocoupler, and 500Ω will give you ((5-1.3)/500=) 7.4mA.

body: And 330 will give you just over 11mA, I'd go with that


body:
My sketch contains 2 `.h` files. one defines

on 1st `.h` file:

    #define JSON_SIZE_IOT 400
    #define JSON_SIZE_SKETCH 300
    StaticJsonDocument<JSON_SIZE_IOT> paramJSON;
    StaticJsonDocument<JSON_SIZE_SKETCH> sketchJSON;

and other need to define `paramJSON` and `sketchJSON` as `extern`

on 2nd `.h` file:

    extern JsonDocument paramJSON;
    extern JsonDocument paramJSON;

but I get this error:

    error: conflicting declaration 'ArduinoJson6172_91::StaticJsonDocument<400u> paramJSON'
     StaticJsonDocument<JSON_SIZE_IOT> paramJSON;

....

    : previous declaration as 'ArduinoJson6172_91::JsonDocument paramJSON'
     extern JsonDocument paramJSON;

title: ArduinoJSON define as extern

Answers: 1

body:
For an `extern` the whole definition has to match the "master" definition.

So if you have:

```c++
StaticJsonDocument<JSON_SIZE_IOT> paramJSON;
```

then you `extern` has to be:

```c++
extern StaticJsonDocument<JSON_SIZE_IOT> paramJSON;
```

Of course you have to make sure your `JSON_SIZE_IOT` is the same for both - so it's best if that comes from a common source.

This is known as *explicit instantiation declaration* and you can read more about it in the [Class template C++ reference](https://en.cppreference.com/w/cpp/language/class_template).


body:
I want to add zero before the float number like this:

    010.0

The code I'm using is this:

    if(value < 10){
      lcd.print(F("0"));
    }

    lcd.print(value);

But when the value is exactly 10, it adds the zero anyway:

    0010.0

I tried something like this but haven't had any luck:

    if(value < 10 && value != 10){
      lcd.print(F("0"));
    }

* How can I solve this issue?

**- EDIT:**

    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x3B, 16, 2);

    #define turnOff 3
    #define turnOn 2
    #define gateStatus 8
    #define btn 4

    float ADC0, current, ADC1, voltage, ADC2, temp, watt;
    int8_t state, btnState, btnPushed, btnToggle, lcdClear;
    uint32_t deBounce = 0;

    void setup() {
      analogReference(EXTERNAL);
      pinMode(turnOff, OUTPUT);
      pinMode(turnOn, OUTPUT);
      pinMode(gateStatus, INPUT);
      pinMode(btn, INPUT_PULLUP);
      pinMode(13, OUTPUT);
      lcd.begin();
    }

    void loop() {
      digitalWrite(13, LOW);
      state = digitalRead(gateStatus);
      btnState = digitalRead(btn);

      if (!btnState) {
        if (millis() - deBounce > 200) {
          btnPushed = 1;
          deBounce = millis();
        }
      }
      if (btnPushed && btnState) {
        btnToggle = 1;
      }
      if (btnToggle && state) {
        digitalWrite(turnOn, HIGH);
        delay(5);
        digitalWrite(turnOn, LOW);
        btnToggle = 0;
        btnPushed = 0;
      }
      if (btnToggle && !state) {
        digitalWrite(turnOff, HIGH);
        delay(5);
        digitalWrite(turnOff, LOW);
        btnToggle = 0;
        btnPushed = 0;
      }

      for (int i = 0; i < 500; ++i) {
        ADC0 += analogRead(A0);
      }
      ADC0 /= 500;
      current = ADC0 * (2.5 / 1023.0);
      current = current / 0.211;

      for (int i = 0; i < 500; ++i) {
        ADC1 += analogRead(A1);
      }
      ADC1 /= 500;
      voltage = ADC1 * (2.5 / 1023.0);
      voltage = voltage * 20.2;

      for (int i = 0; i < 100; ++i) {
        ADC2 += analogRead(A2);
      }
      ADC2 /= 100;
      temp = ADC2 * (2.5 / 1023.0);
      temp = temp * 100.5;

      watt = voltage * current;

      lcd.setCursor(0, 0);
      if(voltage < 10){
        lcd.print(F("0"));
      }
      lcd.print(voltage);
      lcd.setCursor(5, 0);
      lcd.print(F(" V"));

      lcd.setCursor(9, 0);
      if(temp < 10){
        lcd.print(F("0"));
      }
      lcd.print(temp, 1);
      lcd.print((char)223);
      lcd.print(F(" C"));

      if (state) {
        lcd.setCursor(0, 1);
        lcd.print(F("   OUTPUT OFF   "));
        lcdClear = 1;
      }

      else {
        if (lcdClear) {
          lcd.clear();
          lcdClear = 0;
        }
        lcd.setCursor(0, 1);
        if (current < 10) {
          lcd.print(F("0"));
        }
        lcd.print(current);
        lcd.setCursor(5, 1);
        lcd.print(F(" A"));

        lcd.setCursor(9, 1);
        if (watt < 10) {
          lcd.print(F("0"));
        }
        if (watt < 100) {
          lcd.print(F("0"));
        }
        lcd.print(watt, 1);
        lcd.setCursor(14, 1);
        lcd.print(F(" W"));
      }
    }

title: Adding zero padding to decimal values

Answers: 1

body:
This looks like a rounding problem. If the number you want to print lies
within the open interval (9.95, 10), the condition `value < 10` is true,
as the number is strictly less than 10. Obviously, `value != 10` is also
true. Yet, `lcd.print(x, 1)` will round the number to the closest
multiple of 0.1, which in this case is 10.

I see no better solution than handling the rounding yourself. I would
use integers for the comparison, as they avoid all rounding issues:

```c++
// Print a float to the LCD in 2.1 format (xx.x), left padded with a
// zero if needed. Assume x < 100.
void printPadded(float x)
{
    // Left pad.
    int i = round(x * 10);
    if (i < 100) lcd.write('0');

    // Print the rounded value.
    lcd.print(i * 0.1, 1);
}
```


body:
Or is it 5 V only?

https://www.st.com/en/automotive-analog-and-power/l9823.html

I see in the data sheet it says under Absolute Maximum:
> Supply Voltage:  VDD -0.3 V to 7 V

Then, under Electrical Characteristics:
> 4.5 V < VDD < 5.5 V; unless otherwise specified.

Is the Electrical Characteristics section just listing values for an example voltage of 5 V, or does the chip need 5 V to work properly?

title: Will the L9823 work at 3.3 V with Wemos boards?

Answers: 2

body: No. The undervoltage puts it in reset at 3.95V per the ST data sheet. It is a  5v only part with a wide tolerance on VCC. It was designed many years ago as an automotive part. It is a very nice part and performs well.

body:
The *Absolute Maximum* section in a datasheet describes what will damage a component, or shorten its life span; it does not state the acceptable range of values that will make the component work as expected. It is not a design guideline.

You can deduce from these Absolute Maximum data that a Vdd of 3.3 V will not damage the IC, but not that it will work well at that voltage.

In this case, the datasheet says that all Electrical Characteristics *are specified at* a Vdd of about 5 V. This by itself does not necessarily mean the IC won't work at lower voltages, but it is a hint.

But, further on in the Electrical Characteristics, it is stated that the IC could reset at any Vdd between 2.5 V and 3.95 V, so the IC will very probably not work reliably at 3.3V.


body:
Summary: The green TWI/I2C port on my Braccio shield I2C port hasn't worked for me so far. Looking for advice or information please.

Detail:
I'm using the [Arduino (Tinkerkit) Braccio robot arm][1] for self education. It comes with a Uno based [Braccio Shield][2]. Tinkerkit no longer seems to be in business and documentation is a bit scarce. The shield uses KF2510 style connectors for servos (orange), inputs (white), serial (yellow) and importantly for my question a TWI/I2C port (green).
[![Braccio Shield][3]][3]

The green four pin TWI/I2C connector provides GND, +5V, SDA (A4), SCL (A5). However the SDA and SCL connections are [reported][4] to not be direct, but that "a very tiny chip (located next to the I4 connector) buffers between the green connector and the Arduino pins SDA and SCL" . A photo of the chip described is below.
[![Close-up of buffer chip][5]][5]

Contrary to the reports of a "buffer" studying the [schematic][6] shows a level shifter [PCA9306TI][7] and two sets of 10K pullup resistors (R7,R8 and R11,R12) on the bus on both sides of the chip. VREF2 on the outboard side of the chip has a R9 220K resistor to +5V.

[![Schematic snippet][8]][8]

The other side of my I2C connection was an Arduino Pro-mini 5V. I was never able to get it working using the green port described, but it works fine directly hooked into SCL and SDA bypassing the level shifter.

My questions (sorry for the long lead up) are:

 1. Has the green TWI port been level shifted to expect ~3V? (Only really came to this conclusion writing this all up clearly).
 2. If I want to change the green TWI port to 5V I2C can I replace R9 220K with a zero ohm jumper?
 3. The 10K pullups (R7,R8 and R11,R12) seem larger than anticipated (I had anticipated about 4.7K for 5v or about 2.4 for 3V)? Can they be removed and left open if I have a single set of pullups elsewhere on the bus? Or better suggestions?

Thanks!

**Update 2021/01/30**

Well my I2C debugging skills are improving researching this! As a test bed I set up a clean working I2C bus with two MCU's running the Arduino Example Master/Writer Slave/Receiver sketches by Nicholas Zambetti. I tested the I2C signal on the oscilloscope to make sure it was clean. All good. To that test bed I connected the Braccio shield (5V, GND, SCL, SDA). Connecting the Braccio shield changes the I2C signal in interesting ways, with partial strength (runt) pulses, and round shoulder slow rises. Connecting via the green TWI port seems to accentuate the runt pulse aspect. Also interesting the oscillscope was still able to decode the signal. Still working on figuring this out.

Pic 1. First test - SCA and SCL connected via pin headers in top left of shield picture above.
[![First test][9]][9]
Pic 2. Second test - SCA and SCL connected via green TWI port
[![Second test][10]][10]
Pic 3. Clean Signal (no Braccio Shield connection)
[![Clean signal][11]][11]

  [1]: http://www.farnell.com/datasheets/2575116.pdf?_ga=2.151369337.1936105882.1517985527-654667508.1508905608
  [2]: https://www.arduino.cc/en/Guide/Braccio#braccio-shield
  [3]: https://i.stack.imgur.com/qapkL.png
  [4]: https://forum.arduino.cc/index.php?topic=502485.0
  [5]: https://i.stack.imgur.com/eGPq1.jpg
  [6]: https://content.arduino.cc/assets/Braccio-Shield-V1.pdf
  [7]: https://www.ti.com/product/PCA9306?utm_source=google&utm_medium=cpc&utm_campaign=asc-null-null-GPN_EN-cpc-pf-google-sa&utm_content=PCA9306&ds_k=PCA9306 Datasheet&DCM=yes&gclid=Cj0KCQiA6Or_BRC_ARIsAPzuer-9r3SFKEpBST426P58NfAV52irQPhw6Vol82yxK1wqjSYw1QZpDWAaAthyEALw_wcB&gclsrc=aw.ds
  [8]: https://i.stack.imgur.com/Uz21Q.png
  [9]: https://i.stack.imgur.com/CDQfJ.png
  [10]: https://i.stack.imgur.com/vlKPI.png
  [11]: https://i.stack.imgur.com/Rh0mD.png

title: Problems with green TWI (I2C) port on Arduino Braccio Shield

Answers: 1

body:
I fear we have a colloring issue. Your green is my blue ;-).

I have looked into the data sheet of the level shifter IC and TI only describes scenarios with a higher voltage on the right side and a lower voltage on the left side. Also the allowed voltage translations do not contain 5V to 5V. So I would say in equal voltage scenario the Level shifter may not work.

Answers

* Q1: The TWI port is always used with 5V (not ~3V). The Arduino that is supposed to use the shield might be a 3.6V version (like a DUE or M0). Perhaps the TWI port is only intended for this use case: A low voltage arduino with a 5V device. I admit: This should be noted in the documentation. So perhaps Braccio shields work outside the specification and may works under normal circumstances. But meanwhile I begin to understand why they are out of busines ;-).

* Supplement: the SCL and SCL signals are routed to two pairs of header pins as they are connected to different pins on different Arduinos. On a UNO you can not use A4 and A5 for analog as they are used for I2C for example. Do you use A4 A5 in any way? Or did you connect the second I2C pin pair in the power header when you had used the TWI connector? (rhetoric question ;-) of cause I will change the answer if you give me more information ;-) )

* Q2: The 220k resistor is necessary as it limits the current through the chip if VRef1 is lower than VRef2. Removing it with 0 Ohms would be a bad idea. As long as 5V is used on both sides, nothing would happen. But if Vref1 is 3.6Volts, you would waste energy and perhaps the chip would take part at a grill fest.

* Q3: Most I2C devices breakout boards already use their own pullup resistors. So lowering the pullups is not the best idea. -> too high current with LOW signals as the devices pull ups and the braccio pull ups are set in parallel.
-- There is a chance, that the resistors are too large for devices that don't use their own pull ups, but at a 100kHz bus speed I don't think, this could cause an issue.

BTW: You do not need to exchange the pull ups, if you insist to try out different values. Just use parallel resistors to lower the resistance (10K || 10K -> 5K) [|| means connected in parallel] (R || Rp -> (R*Rp) / (R+Rp))


body:
I would like to adopt this library on an Arduino Mega2560:

https://github.com/gueei/DShot-Arduino

However, the macro `DSHOT_PORT` needs defined for the Mega2560 here:
https://github.com/gueei/DShot-Arduino/blob/master/src/DShot.h

So I need to add a `#if defined(__AVR_ATmega2560__)` macro to that `DShot.h` header, however, it is not clear to me where to lookup the port mapping on a 2560 mega.  I'm looking directly at the schematic itself here:
https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf

And understand that the 'ports' are groupings of IO where the pins are described as `P?#`, ? being the port letter and # being 0-7.

So what are my valid options?  It appears that some ports (A,C,L) aren't pinned at all, some (D,J) only a few pins, and just about none of them (except K/F) have all port pins utilized.  Also, I can see most of these pins are reserved for some type of functionality (analog, SPI, etc).  I'm assuming I'm looking for a port with available pins reserved for PWM, such as Port B (pins 10-13 are PWM).  Would this be correct?

title: Valid options for output port on Mega 2560

Answers: 1

body:
It would seem this library needs a single pin to communicate. So it
doesn't really matter whether the port you choose has only a few pins
available. Also, you do not care that some pins can have extra
functionality, like SPI, I2C, etc, unless you do plan to use that
functionality.

There is one think you should be aware of: the library uses the `in` and
`out` assembly instructions to access the port. These instructions can
only access the ports that are mapped in the regular I/O space of the
microcontroller, not those that are in the “extended I/O” space. In the
case of the ATmega2560, this means you can use any of the ports A
through G, but you cannot use H, J, K nor L.


body:
I am using the stand alone Arduino IDE to build some projects, and I have a few `.cpp` files now, but during work I renamed them `.c` and back. When compiling the project now (with Ctrl-R), it is still trying to compile the `.c` files. But, I don't even see them on disk!

Changing the `.cpp` makes no difference. I am used to IDEs having some kind of project file, or a "clean project" option, but I cannot find those here.

title: IDE compiles incorrect file after renaming them

Answers: 1

body:
The Arduino IDE does not monitor changes to open files. So if you rename or change a file externally (i.e. in another editor), the IDE won't update the file contents. Therefore, after such a change, a restart might be necessary.

Note: If you use another editor to change a file but only compile (and upload) in the IDE, this will work, because the compiler correctly reads the updated file. But editing the source in the IDE and an external editor at the same time might overwrite either change!


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

    }

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

Answers: 3

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

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/


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

title: Timing push button code

Answers: 1

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.


body:
I'm using an Adafruit V1 Motor Shield for coding two 12 volt DC motors. In my code I'm changing the set speed, but the motors still seem to be going the same speed, which is really fast, and I want them to go slow.  What do I change to make my motors speed run the way I want them to run?

Here's my code below:

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

AF_DCMotor motor1(1);
AF_DCMotor motor2(2);

void setup() {
  Serial.begin(9600); // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  // turn on motor
  motor1.setSpeed(3);
  motor2.setSpeed(5);
}

void loop() {
  uint8_t i;

  //second motor
  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  //1 motor
  Serial.print("tick");

  motor1.run(FORWARD);

  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");

  motor2.run(FORWARD);

  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tack");

  motor1.run(BACKWARD);

  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }

  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }
}
```

title: How do I make my motors speed change?

Answers: 0


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

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

Answers: 1

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


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

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

Answers: 1

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.


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

title: Stepper not working properly using L298N

Answers: 2

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


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

title: (Arduino Uno) PWM output (and servo plugged on it) becomes unstable if I use 1Wire on another pin

Answers: 1

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


body:
I'm trying to make servo motor to increase or decrease degrees according to user choice.

I've created an code that get input from the user via Serial and according to the input the motor increase or decrease.

But for some reason, when I call each of one of the function the motor start working without a break.
do I miss something over here?

     #include <Servo.h>

    Servo servo1;
    int currentAngle = 0;
    String readString;
    void setup()
    {
       servo1.attach(8);
       Serial.begin(9600);
    }
    void increaseServo(){
      Serial.println('+');
      currentAngle += 5;
      servo1.write(currentAngle);
      delay(15);
    }
    void decreaseServo(){
      Serial.println('-');
      currentAngle -= 5;
      servo1.write(currentAngle);
      delay(15);
    }
    void loop()
    {
      while(Serial.available()>0) //Allocating the data from Serial Monitor.
      {
        delay(3);
        char c = Serial.read();
        readString += c;
      }
      readString.trim();
      if (readString.length() > 0) {
        if(readString == "+"){ //increase
          increaseServo();
        }else if(readString == "-"){ //decrease
          decreaseServo();
        }
        readString="";
      }
      delay(1000);
    }

Thanks for the help.

title: make servo motor to increase/decrease degree

Answers: 0


body:
I have a HMC5883L module connected to an Arduino Mega 2560 via +5, GND, SCL, SDA.  The Arduino code is from the MagMaster-master example, as follows:

    #include "Wire.h"
    #include "HMC5883L.h"

    HMC5883L compass; //Copy the folder "HMC5883L" in the folder "C:\Program Files\Arduino\libraries" and restart the arduino IDE.

    float xv, yv, zv;

    void setup()
    {
      Serial.begin(9600);
      Wire.begin();
      compass = HMC5883L();
      setupHMC5883L();
    }

    void loop()
    {
      getHeading();

      Serial.flush();
      Serial.print(xv);
      Serial.print(",");
      Serial.print(yv);
      Serial.print(",");
      Serial.print(zv);
      Serial.println();

      delay(100);
    }

    void setupHMC5883L()
    {
      compass.SetScale(0.88);
      compass.SetMeasurementMode(Measurement_Continuous);
    }

    void getHeading()
    {
      MagnetometerRaw raw = compass.ReadRawAxis();
      xv = (float)raw.XAxis;
      yv = (float)raw.YAxis;
      zv = (float)raw.ZAxis;
    }

When I run the code, I get the following output on the serial monitor

    -15872.00,-27601.00,1.00
    -15872.00,3264.00,1.00
    -15872.00,19536.00,1.00
    -15872.00,-18208.00,1.00
    -15872.00,12401.00,1.00
    -15872.00,-27647.00,1.00
    -15872.00,1170.00,1.00
    -15872.00,17442.00,1.00
    -15872.00,-21326.00,1.00
    -15872.00,7235.00,1.00
    -15872.00,21715.00,1.00
    -15872.00,-15261.00,1.00
    -15872.00,15604.00,1.00
    -15872.00,-22396.00,1.00
    -15872.00,7189.00,1.00
    -15872.00,23717.00,1.00
    -15872.00,-13259.00,1.00
    -15872.00,14534.00,1.00
    -15872.00,-24490.00,1.00
    -15872.00,3303.00,1.00
    -15872.00,17527.00,1.00
    -15872.00,-20473.00,1.00
    -15872.00,9368.00,1.00
    -15872.00,26664.00,1.00
    -15872.00,-8008.00,1.00
    -15872.00,8265.00,1.00
    -15872.00,23769.00,1.00
    -15872.00,-14231.00,1.00
    -15872.00,13562.00,1.00
    -15872.00,-24438.00,1.00
    -15872.00,3099.00,1.00
    -15872.00,17579.00,1.00
    -15872.00,-19397.00,1.00
    -15872.00,11468.00,1.00

As can be seen from the above, only the Y (middle column) values change when I move the sensor around.  If I plot these values in Excel, I get a plot that looks like this:

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

  [1]: https://i.stack.imgur.com/pwHtd.jpg

I have looked through the code, and the HMC5883L library code (below) and nothing seems amiss.  I tried a different HMC5883L module and got the same (bad) result.  I know I must be doing something wrong, but I can't for the life of me figure it out. Any hints would be appreciated! ;-)

HMC5883L.cpp:

    /*
    HMC5883L.cpp - Class file for the HMC5883L Triple Axis Magnetometer Arduino Library.
    Copyright (C) 2011 Love Electronics (loveelectronics.co.uk)/ 2012 bildr.org (Arduino 1.0 compatible)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the version 3 GNU General Public License as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

     WARNING: THE HMC5883L IS NOT IDENTICAL TO THE HMC5883!
     Datasheet for HMC5883L:
     http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/HMC5883L_3-Axis_Digital_Compass_IC.pdf

    */

    #include <Arduino.h>
    #include "HMC5883L.h"

    HMC5883L::HMC5883L()
    {
      m_Scale = 1;
    }

    MagnetometerRaw HMC5883L::ReadRawAxis()
    {
      uint8_t* buffer = Read(DataRegisterBegin, 6);
      MagnetometerRaw raw = MagnetometerRaw();
      raw.XAxis = (buffer[0] << 8) | buffer[1];
      raw.ZAxis = (buffer[2] << 8) | buffer[3];
      raw.YAxis = (buffer[4] << 8) | buffer[5];
      return raw;
    }

    MagnetometerScaled HMC5883L::ReadScaledAxis()
    {
      MagnetometerRaw raw = ReadRawAxis();
      MagnetometerScaled scaled = MagnetometerScaled();
      scaled.XAxis = raw.XAxis * m_Scale;
      scaled.ZAxis = raw.ZAxis * m_Scale;
      scaled.YAxis = raw.YAxis * m_Scale;
      return scaled;
    }

    int HMC5883L::SetScale(float gauss)
    {
     uint8_t regValue = 0x00;
     if(gauss == 0.88)
     {
      regValue = 0x00;
      m_Scale = 0.73;
     }
     else if(gauss == 1.3)
     {
      regValue = 0x01;
      m_Scale = 0.92;
     }
     else if(gauss == 1.9)
     {
      regValue = 0x02;
      m_Scale = 1.22;
     }
     else if(gauss == 2.5)
     {
      regValue = 0x03;
      m_Scale = 1.52;
     }
     else if(gauss == 4.0)
     {
      regValue = 0x04;
      m_Scale = 2.27;
     }
     else if(gauss == 4.7)
     {
      regValue = 0x05;
      m_Scale = 2.56;
     }
     else if(gauss == 5.6)
     {
      regValue = 0x06;
      m_Scale = 3.03;
     }
     else if(gauss == 8.1)
     {
      regValue = 0x07;
      m_Scale = 4.35;
     }
     else
      return ErrorCode_1_Num;

     // Setting is in the top 3 bits of the register.
     regValue = regValue << 5;
     Write(ConfigurationRegisterB, regValue);
    }

    int HMC5883L::SetMeasurementMode(uint8_t mode)
    {
     Write(ModeRegister, mode);
    }

    void HMC5883L::Write(int address, int data)
    {
      Wire.beginTransmission(HMC5883L_Address);
      Wire.write(address);
      Wire.write(data);
      Wire.endTransmission();
    }

    uint8_t* HMC5883L::Read(int address, int length)
    {
      Wire.beginTransmission(HMC5883L_Address);
      Wire.write(address);
      Wire.endTransmission();

      Wire.beginTransmission(HMC5883L_Address);
      Wire.requestFrom(HMC5883L_Address, length);

      uint8_t buffer[length];
      if(Wire.available() == length)
      {
       for(uint8_t i = 0; i < length; i++)
       {
        buffer[i] = Wire.read();
       }
      }
      Wire.endTransmission();

      return buffer;
    }

    char* HMC5883L::GetErrorText(int errorCode)
    {
     if(ErrorCode_1_Num == 1)
      return ErrorCode_1;

     return "Error not defined.";
    }

HMC5883L.h:

    /*
    HMC5883L.h - Header file for the HMC5883L Triple Axis Magnetometer Arduino Library.
    Copyright (C) 2011 Love Electronics (loveelectronics.co.uk) / 2012 bildr.org (Arduino 1.0 compatible)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the version 3 GNU General Public License as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

     WARNING: THE HMC5883L IS NOT IDENTICAL TO THE HMC5883!
     Datasheet for HMC5883L:
     http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/HMC5883L_3-Axis_Digital_Compass_IC.pdf

    */

    #ifndef HMC5883L_h
    #define HMC5883L_h

    #include <Arduino.h>
    #include <Wire.h>

    #define HMC5883L_Address 0x1E
    #define ConfigurationRegisterA 0x00
    #define ConfigurationRegisterB 0x01
    #define ModeRegister 0x02
    #define DataRegisterBegin 0x03

    #define Measurement_Continuous 0x00
    #define Measurement_SingleShot 0x01
    #define Measurement_Idle 0x03

    #define ErrorCode_1 "Entered scale was not valid, valid gauss values are: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1"
    #define ErrorCode_1_Num 1

    struct MagnetometerScaled
    {
     float XAxis;
     float YAxis;
     float ZAxis;
    };

    struct MagnetometerRaw
    {
     int XAxis;
     int YAxis;
     int ZAxis;
    };

    class HMC5883L
    {
     public:
       HMC5883L();

       MagnetometerRaw ReadRawAxis();
       MagnetometerScaled ReadScaledAxis();

       int SetMeasurementMode(uint8_t mode);
       int SetScale(float gauss);

       char* GetErrorText(int errorCode);

     protected:
       void Write(int address, int byte);
       uint8_t* Read(int address, int length);

     private:
       float m_Scale;
    };
    #endif

title: HMC5883L Magnetometer X, Z values constant, only Y value Changes

Answers: 0


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

title: Shift between the carrier frequency of the signal transmitted with arduino and my garage door RC (433 mhz)

Answers: 3

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


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

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

Answers: 1

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

It worked for me


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

title: Can we generate 20kHz tone with normal buzzer in arduino?

Answers: 2

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.


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

title: Arduino Pro micro Serial communication problem with Node MCU

Answers: 1

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.


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

title: Library ADC MCP33121

Answers: 1

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


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

title: Watchdog timer/deep sleep loop for Atmega 328 Pro Mini 5v 16 mhz

Answers: 1

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


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

title: How to restart ESP32 on any exception?

Answers: 1

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.


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

title: esp32 Stack canary watchpoint triggered

Answers: 1

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


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

title: How to use a push button & transistor as a kickstarter for power supply?

Answers: 2

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


body:
I have a problem in a project that I am working, basically I need to use a ESP-01 to receive the measurements from a HC-SR04 and send it to another ESP-01 (which I won't cover here).

Basically my ESP doesn't boot 95% of times, it just stays with the blue LED on all the time, on the remaining 5% of cases it boots normally and reads the sensor and also sends the information to another ESP.

I have done a lot of research and I am aware of these points:

1. HC-SR04 works in 5V and ESP in 3.3v, so a level convertor would be needed for the GPIO pins.  But, I have seen that the manufacturer (Espressif) stated that the ESP is resistant to 5V logic and it should work.  Also, I asked my professor and he said that it wouldn't be a problem.

2. Both IO pins need to be HIGH to boot, and the sensor seems to supply low, but like I said the ESP01 does boot, but not all the times.

That said, I would like to know why it works sometimes and others not, trying to get a little more of stability for presentation purposes...

Also it's worth noting that I have another ESP-01 connected with a DHT11 sensor with basically the same settings and it works normally.

The connections go like this:

|ESP-01     |HC-SR04|
|-----------|-------|
|GPIO0      |Trigger|
|GPIO2      |Echo   |
|GND        |GND    |

|Component          | Power|
|-----------|-------|
|ESP-01 Vcc, CH_PD |3.3v |
|HC-SR04 Vcc      | 5v  |

The code:

    // pins of the esp8266 connected to the sensor
    #define trigPin 0  //GPIO0
    #define echoPin 2  //GPIO2

    // intialize the variables for storing the measurement
    float timeElapsed;
    float distance;

    void setup() {
      // Init Serial Monitor
      Serial.begin(115200);

      pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
      pinMode(echoPin, INPUT); // Sets the echoPin as an Input

    }

    void loop() {
      // do the measurements of the sensor
       digitalWrite(trigPin, LOW);  //para generar un pulso limpio ponemos a LOW 4us
       delayMicroseconds(4);

       digitalWrite(trigPin, HIGH);  //generamos Trigger (disparo) de 10us
       delayMicroseconds(10);
       digitalWrite(trigPin, LOW);

       timeElapsed = pulseIn(echoPin, HIGH);
       distance = timeElapsed/58.3;

       delay(1000);

      if ((millis() - lastTime) > timerDelay) {
         // code to send the information over wi-fi

      }
    }

I have tried already:
- Changing the ESP and HCSR04
- Inverting GPIO0 and GPIO2
- Boot without the sensor and connect it after, no succes
- Different values in Arduino IDE during compilation of code

Thanks for your attention!

title: ESP-01 and HC-SR04 problems booting up

Answers: 0


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

title: Initialising timer interrupt crashes Mega 2560

Answers: 1

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!