body:
Simple sketch and simple question: where does this sketch have undefined behavior?

Note: I don't need a solution to fix the code. I already have code that works. I really need to understand where my thinking is wrong.

Background: some kids were writing a program for a line follower robot which has 3 digital sensors. Many of them bricked their Arduino. I reduced the affected sketches to quite a minimum so that it still reproduces the problem. The sketch is pretty self-explanatory I hope.

It gives no warnings in Arduino IDE 1.8.9, 1.8.15 and 2.0.4 even with all warnings enabled.

Still, this code bricks all the Arduino clones (9 instances of Elegoo Smart Robot Car Kit 3.0 Plus) and I spent several hours to find a reliable procedure to unbrick them. Therefore I have strong belief that this code must have undefined behavior - except that I can't see it.

The unbrick procedure is:
1. Remove the shield, if not removed yet
2. Disconnect Arduino from USB
3. Connect Arduino to USB
4. Press Reset button on the Arduino board
5. Disconnect Arduino from USB again (!)
6. Connect Arduino to USB
7. Compile and upload an empty sketch

```cpp
long PIN_LINE_LEFT = 10;
long PIN_LINE_MID = 4;
long PIN_LINE_RIGHT = 2;
long DATARATE = 115200;

void setup() {
  pinMode(PIN_LINE_LEFT, INPUT);
  pinMode(PIN_LINE_MID, INPUT);
  pinMode(PIN_LINE_RIGHT, INPUT);
  Serial.begin(DATARATE);
}

void loop() {
  byte leftValue = digitalRead(PIN_LINE_LEFT);
  Serial.println(leftValue);
}
```

Here's my analysis:

IMHO, the sketch is unusual just in one way: instead of `#define`ing the pin numbers and other stuff, it declares them as global variables of type `long`.

According to [the Arduino reference about data types](https://www.arduino.cc/reference/en/language/variables/data-types/long/) a `long` is 32 bit. Printing `sizeof(long)` confirms that. Therefore, 115200 will not overflow at 65536 (16 Bit).

For `Serial.begin()`, the `DATARATE` will be converted into an `unsigned long`, which IMHO should not be a problem here, since the number is positive.

Sure enough, the pin numbers needn't be `long` and should be declared as `uint8_t` to better match the `pinMode()` and `digitalRead()` function. But I still think the implicit conversion down to `uint8_t` should be fine, since there is no overflow either.

Next, `digitalRead()` officially returns an `int`. The result is assigned to a `byte` which is an alias for `uint8_t`. It seems that this also gets converted implicitly. However, the values should only be `HIGH` or `LOW`, i.e. 1 or 0, which does not generate a signed overflow either.

What I tried:

Changing `DATARATE` to the more appropriate `unsigned long DATARATE = 115200UL;` doesn't change anything.

Changing `byte leftValue = digitalRead(PIN_LINE_LEFT);` to the more appropriate `int leftValue = digitalRead(PIN_LINE_LEFT);` also didn't change anything.

Changing `long PIN_LINE_MID = 4;` and all others to the more appropriate `uint8_t PIN_LINE_xxx = xxx;` also doesn't change anything.

IMHO with these changes, there's basically nothing left to fix and this should be a super valid C/C++ program without any implicit dangerous casts.

A `Serial.flush();` in the loop is not needed according to the [documentation of `Serial.write()`](https://www.arduino.cc/reference/en/language/functions/communication/serial/write/). So there will not be a buffer overflow.

title: Where does this sketch have Undefined Behavior?

Answers: 2

body:
Your sketch does not have undefined behaviour. It works:

>  I already have code that works.

Your problem apparently is that after loading this sketch you have trouble uploading a new sketch:

> this code bricks all the Arduino clones

They aren't "bricked" as you say:

> But your method works in ~9 out of 10 cases. I can't believe this.

Your sketch, which outputs repeatedly to the serial port, apparently makes it hard for a **clone** to respond to a new upload. The cheaper USB interface which the clones use, to save a few cents, evidently don't react as well as the genuine Arduino to attempts to upload a new sketch.

The suggested method in the comments (referencing my post https://arduino.stackexchange.com/questions/13292/have-i-bricked-my-arduino-uno-problems-with-uploading-to-board) indicates the solution, and I quote:

> Take these steps:
>
> *    Power off the board completely (remove the USB cable).
> *    Hold down the Reset button, and keep it held down (or, run a jumper wire from the RESET pin to the GND pin). This stops the problem sketch from starting, and thus activating the watchdog timer
> *    Still holding down Reset, reconnect the USB cable.
> *    Start uploading a sketch that does not have this problem (eg. Blink)
> *    Once the IDE reports "Uploading" release the Reset button (or remove the jumper wire).
> *    It should now upload OK - as the sketch which activated the watchdog timer never started.

The solution above is to not let the current sketch run at all, thus avoiding whatever-it-is that it does to stop new sketches from uploading.

*The references to the watchdog timer are from the original post, they are not relevant here.*

---

> It gives no warnings in Arduino IDE 1.8.9, 1.8.15 and 2.0.4 even with all warnings enabled.

That's because there are no problems with the sketch per se. The hardware? Well, you buy cheaper hardware, you may get some problems. The technique described above helps you work around those problems.

body:
With some USB to TTL Serial chips it is a problem to start the upload if there is too much input from the MCU on the Serial side. In this case it is the Holtek UART Bridge which is not common for Arduino boards.

To stop the sketch, hold the reset button until the upload from IDE starts. When the reset button is released, the bootloader starts and receives the upload.


body:
I have equipment transmitting data via uart with a baud rate of 1382400 and I would like to read this information through the Serial2 port of the ESP32.
I've tried to set this high baud rate using Serial2.begin(1382400) but I can't read anything.
Using the function below to detect the baud rate I can read a maximum of 922190 bauds.
Below is the sketch I used to check the baudrate:

```
void setup() {

     Serial.begin(115200);
     delay(100);
     Serial.println();
     // Passing 0 for baudrate to detect it, the last parameter is a timeout in ms
     Serial2.begin(0, SERIAL_8N1, -1, -1, true, 11000UL);

     unsigned long detectedBaudRate = Serial2.baudRate();
     if(detectedBaudRate) {
       Serial.printf("Detected baudrate is %lu\n", detectedBaudRate);
     } else {
       Serial.println("No baudrate detected, Serial2 will not work!");
     }
   }

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

}
```
The answer I get is as follows:
Detected baud rate is 922190

I managed to communicate between the equipment and the esp32 using a baud rate of 115200.
I changed the baud rate to 230400 and I couldn't communicate anymore. From 230400 no baud rate worked.

The transmitting equipment uses pic 18F4520 and engineering sent me the following information:

The crystal of the equipment is 11.0592 MHz
The PLL quadruples this frequency, so the pic's clock is 44.2368 MHz
I connect the tx with the rx , I interconnect the GND. As far as I understand it is not a connection problem because in 115200 it works.
Unfortunately I can't change it to 115200 definitively because it changes other functions of the equipment.

Is this a limitation of ESP32? Could I do something else to test?
Sorry for the long post and language mistakes as English is not my main language .

title: Baud rate above 115200 don't work for esp32

Answers: 0


body:
I have an 8 channel relay, an Arduino Uno, and this HM-10 bluetooth module: https://www.amazon.com/dp/B06WGZB2N4

**The Goal**
Send a number (1-8) from my Android phone via bluetooth to turn a relay on.

**The Problem**
I can't seem to get the bluetooth to reply to anything I send. I'm trying to use "Arduino Bluetooth" from the app store to send commands, but it either errors or ignores me and doesn't do anything. I can't communicate with the bluetooth from the Arduino IDE either.

**The wiring**
I'm SUPER new to small electronics, I suspect I'm not giving the system enough power and might need to give my relay its own 5.5v supply, but here's what I've got:

```
HM-10    | Uno
-------------------
RX       | Digital 3
TX       | Digital 2
VCC      | 3.3V
GND      | GND
```
```
Uno      | Relay
-------------------
Digital 4       | IN8
Digital 5       | IN7
Digital 6       | IN6
Digital 7       | IN5
Digital 8       | IN4
Digital 9       | IN3
Digital 10      | IN2
Digital 11      | IN1
GND             | GND
5V              | VCC

```

The code:
```
#include <SoftwareSerial.h>

const int relayPins[] = {4, 5, 6, 7, 8, 9,10,11};
SoftwareSerial HM10(2, 3);

void setup() {
  Serial.begin(9600);
  HM10.begin(9600);
  for (int i = 0; i < sizeof(relayPins) / sizeof(relayPins[0]); i++) {
    pinMode(relayPins[i], OUTPUT);
    digitalWrite(relayPins[i], HIGH); // set relays to OFF
  }
}

void loop() {
  if (HM10.available() > 0) {
    int relayNum = HM10.read() - '0'; // convert ASCII to integer
    if (relayNum >= 1 && relayNum <= 11){
        digitalWrite(relayPins[relayNum - 1], LOW);
        Serial.print("Turned on relay ");
        Serial.println(relayNum);
        delay(1000); // wait for 1 second
        digitalWrite(relayPins[relayNum - 1], HIGH);
        Serial.print("Turned off relay ");
        Serial.println(relayNum);
    }
  }
}
```

title: Connecting HM-10 and relay to Arduino Uno

Answers: 0


body:
I have the beetle board, a Leonardo clone same as in this  [question][2].

[![Arduino Leonardo Beetle mini board][1]][1]

Using the reset pin and quick hands on the keyboard, I am able to flash with avrdude and get also the board info with a command line like this:

```
$ avrdude -c avr109 -p atmega32u4 -P /dev/ttyACM1
```

And get the output:

```
Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587 (probably m32u4)

avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)

avrdude done.  Thank you.
```
This is good but when I flash something from the ArduinoIDE I noticed I don't have to reset the board manually by grounding the reset pins, the boot loader starts automatically

How does ArduinoIDE reset the bootloader, some kind of communication on `/dev/ttyACM1`?

  [1]: https://i.stack.imgur.com/07oIh.jpg
  [2]: https://arduino.stackexchange.com/q/69433/89339

title: How does Arduino IDE reset a board before flashing? Why doesn't avrdude do it?

Answers: 1

body:
The uploaded Arduino sketch has in the part provided by core a code which waits for a 1200 baud connection on USB. If a 1200 baud connection is established it resets the board to bootloader. The bootloader then starts the com port and waits for the upload.

To reset a board which has in boards.txt `upload.use_1200bps_touch=true` Arduino IDE opens a 1200 baud connection to the board, then detects the new com port and start avrdude for the upload.


body:
I was tasked to take functions that work, and create a library with these functions.

Take a look at the following function that existed inside a program:

    char* Num_to_HEX_char_array(int32_t value)
    {
      Clear_array(MyTempArray, MY_TEMP_ARRAY_LENGTH);
      ltoa(value, MyTempArray, HEX);
      return MyTempArray;
    }

(Let's ignore the fact that this function)
This cannot be immediately made into a library, as `MyTempArray` is non existant.
This, in the `.cpp` file, i will have to manually create these lines:

    #define MY_TEMP_ARRAY_LENGTH 20
    char MyTempArray[MY_TEMP_ARRAY_LENGTH];

Now the library compiles fine.
However, this library can be called by many programs that I create, and some of them might require a different array length, while others ay require a different name than this one.

So what is the best way to create this library?

*One approach that I thought was to dynamically create these arrays with `malloc()`.
And then, on the main program, you will have to `realloc()` the arrays with the ones you want.
Also, use `undef` and re`#define`.
The drawbacks to this approach is that you have to remember to ALWAYS use these statements, if you want your library to work

*Another approach is to place all this code:

    #define MY_TEMP_ARRAY_LENGTH 20
    char MyTempArray[MY_TEMP_ARRAY_LENGTH];

inside a configuration header file. The variables will be of global scope.
Then, when you create an application, you will only have to change this file.

My question to this approach is How exactly can you make sure that this configuration file is read by all the libraries?

Maybe you many libraries, for example, string-handling, or sensor-handling...
Each and every one of these user-created libraries have to `#include` and see that configuration header file, in order to make sure that the definitions and arrays of correct/name and size.
How can you do this so that it is visible by all your user-created libraries?
Where is the optimal location to place that file?

In general, what is the best approach to solve this issue?

title: What is the best way to create a library from existing functions?

Answers: 3

body: I'd write such a function to expect the calling function to allocate the array and pass it and its size as arguments. That leaves the memory allocation and deallocation up to each library user, who may want/need (for other reasons) to use a static array, heap memory, or an automatic array and allows them to de-allocate it (or not) when their application no longer needs it. Coding these details into your library would restrict its usability.

body:
First of all, I must say I have an issue with the example you provide.
The function `Num_to_HEX_char_array()` should use an array that has the
maximum size that `ltoa()` may ever need. No more, no less. There is no
point in letting the user of the library choose this size. Here is how I
would implement this function:

```c++
char *Num_to_HEX_char_array(int32_t value)
{
    static char buffer[2 * sizeof(long) + 1];
    return ltoa(value, buffer, HEX);
}
```

That being said, I am willing to accept the idea that your library has
some static buffers for which it does make sense to let the user choose
the size. You could probably find a better example to put in the
question though.

In this case, I would suggest you first consider the approach proposed
by JRobert, and let the user provide those buffers. Using static buffers
in a library can make the API easier to use in the most common cases.
There are many function in the C standard library that do this, like,
e.g. [`ctime()`][man]. This, however, comes at a cost:

 - the user must be well aware that calls to the library can clobber
   data returned by previous calls

 - the functions are not re-entrant, meaning they cannot be used in
   multiple threads, and they cannot be used both in interrupt and
   non-interrupt contexts.

This is why you have functions such as [`ctime_r()`][man]: to provide an
alternative that lets the user handle the buffer, and does not suffer
from the previous shortcomings.

If you still believe you want static buffers inside your library, then
you should first consider whether it is possible to fix the size, like
in the `Num_to_HEX_char_array()` example. If this is not possible, then
the best I can think of is to use C++ templates. For example:

```c++
template<size_t size> class CircularBuffer {
    int buffer[size];
    // ...
};
```

which would be instantiated like this:

```c++
// Let `queue' be a 42-slot circular buffer.
CircularBuffer<42> queue;
```

Keep in mind, though, that this technique forces you to put most of the
code in the header file.

[man]: https://man7.org/linux/man-pages/man3/ctime.3p.html

body:
Command line compilers and most IDEs for C and C++ enable to set project defines as -D parameters in project settings. Arduino IDE does not enable this yet, because it doesn't have a project configuration file.

With Arduino IDE you can add defines for platform or for board definitions with build.extra_flags in platform.local.txt or in boards.local.txt. Example for boards.local.txt for Arduino Mega:

`mega.build.extra_flags=-DUIP_CONF_UDP_CONNS=20 -DUIP_CONF_MAX_LISTENPORTS=30`

platform.local.txt and boards.local.txt must be in boards package folder nect to platform.txt and boards.txt.


body:
I am trying to get a simple non-blocking replacement for:

    digitalWrite(stepPinX, HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPinX, LOW);
    delayMicroseconds(500);

This is what I tried, and the stepper motor stays still:

    const int dirPinX = 0;
    const int stepPinX = 2;

    unsigned long startMicros = micros();
    unsigned long currentMicros;
    const unsigned long period = 500;

    void setup()
    {
      pinMode(stepPinX, OUTPUT);
      pinMode(dirPinX, OUTPUT);

      digitalWrite(dirPinX, HIGH);
    }

    void loop()
    {
      stepX();
    }

    void stepX()
    {
      currentMicros = micros();  //get the current "time" (time since program start)

      if (currentMicros - startMicros >= period)  //test whether period elapsed
      {
        digitalWrite(stepPinX, HIGH);
      }
      if ((currentMicros - startMicros >= period) && (currentMicros - startMicros <= period*2))
      {
        digitalWrite(stepPinX, LOW);
      }

      startMicros = currentMicros;
    }

Any suggestions on how to correct this? (I do not want to use a library like Accelstepper. I want to use millis/micros.)

title: Stepper motor micros (millis) non-blocking delay simple example?

Answers: 2

body:
Your `stepX()` function looks like this:

```c++
void stepX()
{
  currentMicros = micros();
  // conditionally do some stuff..
  startMicros = currentMicros;
}
```

Since there is nothing that can block it, it will always execute very
fast. This means that, by the time the function returns, `startMicros`
will be very close to the current time. Then, on the following call,
`currentMicros - startMicros` will be very small, way smaller than
`period`, and the conditional code will never execute.

The solution is to change the meaning of `startMicros`: instead of
representing the time of the last call to `stepX()`, let it represent
the time when the last step started. For this, you have to reset it only
when finishing a step:

```c++
void stepX()
{
  currentMicros = micros();
  if (currentMicros - startMicros < period) {           // 1st phase
    digitalWrite(stepPinX, HIGH);
  } else if (currentMicros - startMicros < 2*period) {  // 2nd phase
    digitalWrite(stepPinX, LOW);
  } else {                                              // complete cycle
    startMicros = currentMicros;
  }
}
```

body:
Looks like `startMicros` and `currentMicros` values always stay close to each other because of using `micros()` before and after the conditional block. Since the conditional block executes faster than 500 micros, resulting in never entering the conditional block.

From here you can take two approaches,
 - **Approach 01:** Play with your code variables and debug in realtime to see what's wrong and where. Then tweak,debug, repeat until you reach the desired result
 - **Approach 02:** Rethink w.r.t the code execution and simplify your code right from entry to exit in sequential steps.

Since your action can be simplified to a toggle operation every `500 microseconds`, we can refactor code similar to what I have written,

    bool toggle_flag = false;
    unsigned long last_toggle;
    const unsigned long period = 500;

    void setup() {
        last_toggle = micros();
        pinMode(stepPinX, OUTPUT);
    }

    void loop() {
      // Check to see if time elapsed
      if (micros() - last_toggle >= period ) {

          // Step 01: reset the last_toggle with current time
          last_toggle = micros();

          // Step 02: check toggle flag and perform the toggle action
          (toggle_flag) ? digitalWrite(stepPinX, HIGH) : digitalWrite(stepPinX, LOW);

          // Step 03: toggle the toggle flag variable after our action
          toggle_flag = !toggle_flag;

      }

    }

Hope this answer helps.


body:
I have been working on a project that runs on Adafruit's Bluefruit nRF52 board. I used the SerialFlash library for Arduino provided by Paul Stoffregen: https://github.com/PaulStoffregen/SerialFlash.The Flash chip used here is the Winbond 25Q128J. This library uses SPI protocol to communicate with the hardware flash memory connected to the Feather. The issue I'm facing is that sometimes (like 1 in 10 chance) during runtime, the code crashes and device gets reset due to watchdog trigger. I suspect this is due to the timer interrupt that I have set to trigger every 200us to generate a pulse wave and this interrupts the SPI's write functionality which the program calls in the main loop every 15 ms, causing some sort of race condition.

I observe that SerialFlash waits until the data is transmitted and received to/from the flash through SPI before leaving the subroutine and the timer interrupt setup in the code is causing invalid state (potentially race condition) and crashed the code. Is there a good way to debug this runtime error? Stepping through Debugger doesn't help since it introduces more timing issues.

title: How to prevent the application code from getting stuck in forever loop when using SerialFlash library in Arduino-Adafruit framework

Answers: 0


body:
I have connected [this Adafruit SD Breakout][1] to a Teensy 3.2 over SPI. Because Teensy 3.2 is 3.3 V, I've connected the 3.3 V pin of the Teensy to the 3V pin of the SD breakout.

See sketch below. I'm using Arduino IDE 2.0.4. The SD card is a micro SD HC 32 GB, see photos. FAT32.
The SD setup usually goes fine, but every now and then it fails. Whenever the setup goes fine, writing data to the SD card thereafter also goes fine. Does anyone know what this failing could be caused by? Perhaps the SD card is a bit flaky? Or something in software (library)?

My initial guess would be with the wiring, but I've seen similar problems on a PCB with a SD module on it. Hence I think there's more at play than just wiring.

N.B. on the photo you can see there is also an ADXL breakout board connected. However that is over I2C and does not participate in this setup. I've left it in there because I don't want to have to take it out and reconnect it later.

````
/*
  SD card datalogger

  This example shows how to log data from three analog sensors
  to an SD card using the SD library. Pin numbers reflect the default
  SPI pins for Uno and Nano models

  The circuit:
   analog sensors on analog pins 0, 1, and 2
   SD card attached to SPI bus as follows:
 ** SDO - pin 11
 ** SDI - pin 12
 ** CLK - pin 13
 ** CS - depends on your SD card shield or module.
   Pin 10 used here for consistency with other Arduino examples
    (for MKR Zero SD: SDCARD_SS_PIN)

  created  24 Nov 2010
  modified  24 July 2020
  by Tom Igoe

  This example code is in the public domain.

*/

#include <SPI.h>
#include <SD.h>

const int chipSelect = 10;
#define LED_PIN 7

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // wait for Serial Monitor to connect. Needed for native USB port boards only:

  pinMode(LED_PIN, OUTPUT);
  Serial.print("Initializing SD card...");

  while(!SD.begin(chipSelect)) {
    Serial.println("SD initialization failed.");
    delay(100);
    digitalWrite(LED_PIN, HIGH);
    delay(50);
    digitalWrite(LED_PIN, LOW);
    delay(50);
    digitalWrite(LED_PIN, HIGH);
  }

  Serial.println("initialization done.");
  digitalWrite(LED_PIN, HIGH);
}

void loop() {
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ",";
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    // Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}
````

Output:
````
09:09:03.970 -> Initializing SD card...initialization done.
09:09:19.976 -> Initializing SD card...initialization done.
09:09:28.293 -> Initializing SD card...initialization done.
09:09:38.538 -> Initializing SD card...SD initialization failed.
09:09:42.748 -> SD initialization failed.
09:09:44.924 -> SD initialization failed.
09:09:47.140 -> SD initialization failed.
09:09:49.346 -> SD initialization failed.
09:09:51.556 -> SD initialization failed.
09:09:53.770 -> SD initialization failed.
09:09:55.939 -> SD initialization failed.
09:09:58.147 -> SD initialization failed.
09:10:00.352 -> SD initialization failed.
09:10:02.518 -> SD initialization failed.
09:10:04.725 -> SD initialization failed.
09:10:06.965 -> SD initialization failed.
09:10:09.160 -> SD initialization failed.
09:10:11.353 -> SD initialization failed.
09:10:13.566 -> SD initialization failed.
09:10:15.775 -> SD initialization failed.
09:10:17.954 -> SD initialization failed.
09:10:20.169 -> SD initialization failed.
09:10:22.368 -> SD initialization failed.
09:10:24.574 -> SD initialization failed.
09:10:26.777 -> SD initialization failed.
09:10:28.979 -> SD initialization failed.
09:10:31.159 -> SD initialization failed.
09:10:33.376 -> SD initialization failed.
09:10:35.565 -> SD initialization failed.
09:10:37.783 -> SD initialization failed.
09:10:39.978 -> SD initialization failed.
09:10:42.166 -> SD initialization failed.
09:10:44.384 -> SD initialization failed.
09:10:46.573 -> SD initialization failed.
09:10:48.793 -> SD initialization failed.
09:10:50.974 -> SD initialization failed.
09:11:51.284 -> Initializing SD card...initialization done.
09:12:18.656 -> Initializing SD card...initialization done.
09:12:28.948 -> Initializing SD card...initialization done.
09:12:32.867 -> Initializing SD card...initialization done.
09:12:38.416 -> Initializing SD card...initialization done.
09:12:44.657 -> Initializing SD card...initialization done.
09:12:52.141 -> Initializing SD card...initialization done.
09:13:08.003 -> Initializing SD card...initialization done.
09:13:10.421 -> Initializing SD card...initialization done.
09:13:12.893 -> Initializing SD card...initialization done.
09:13:15.070 -> Initializing SD card...initialization done.
09:13:17.771 -> Initializing SD card...initialization done.
09:13:19.922 -> Initializing SD card...initialization done.
09:13:25.418 -> Initializing SD card...initialization done.
09:13:28.104 -> Initializing SD card...initialization done.
09:13:30.835 -> Initializing SD card...initialization done.
09:13:33.217 -> Initializing SD card...initialization done.
09:13:36.146 -> Initializing SD card...initialization done.
09:13:40.727 -> Initializing SD card...initialization done.
09:13:44.985 -> Initializing SD card...initialization done.
09:13:49.089 -> Initializing SD card...initialization done.
09:13:51.687 -> Initializing SD card...initialization done.
09:13:55.698 -> Initializing SD card...initialization done.
09:14:00.868 -> Initializing SD card...initialization done.
09:14:03.965 -> Initializing SD card...initialization done.
09:14:06.697 -> Initializing SD card...initialization done.
09:14:10.518 -> Initializing SD card...initialization done.
09:14:13.549 -> Initializing SD card...initialization done.
09:14:18.414 -> Initializing SD card...initialization done.
09:14:22.145 -> Initializing SD card...Initializing SD card...initialization done.
09:14:31.614 -> Initializing SD card...initialization done.
09:14:34.230 -> Initializing SD card...initialization done.
09:14:37.077 -> Initializing SD card...SD initialization failed.
09:14:41.273 -> SD initialization failed.
09:14:43.482 -> SD initialization failed.
09:14:45.675 -> SD initialization failed.
09:14:47.858 -> SD initialization failed.
09:14:50.080 -> SD initialization failed.
09:14:52.286 -> SD initialization failed.
09:14:54.464 -> SD initialization failed.
09:14:56.665 -> SD initialization failed.
09:14:58.931 -> SD initialization failed.
09:15:01.088 -> SD initialization failed.
09:15:03.253 -> SD initialization failed.
09:15:05.482 -> SD initialization failed.
09:15:07.696 -> SD initialization failed.
09:15:09.902 -> SD initialization failed.
09:15:12.096 -> SD initialization failed.
09:15:20.904 -> SD initialization failed.
09:15:23.112 -> SD initialization failed.
09:15:25.287 -> SD initialization failed.
09:15:27.494 -> SD initialization failed.
09:15:29.720 -> SD initialization failed.
09:15:30.936 -> Initializing SD card...SD initialization failed.
09:15:35.095 -> SD initialization failed.
09:15:37.304 -> SD initialization failed.
09:15:39.515 -> SD initialization failed.
09:15:41.713 -> SD initialization failed.
09:15:43.899 -> SD initialization failed.
09:15:46.108 -> SD initialization failed.
09:15:48.320 -> SD initialization failed.
09:15:50.502 -> SD initialization failed.
09:15:52.685 -> SD initialization failed.
09:15:54.920 -> SD initialization failed.
09:15:57.887 -> Initializing SD card...SD initialization failed.
09:16:01.902 -> SD initialization failed.
09:16:04.097 -> SD initialization failed.
09:16:06.312 -> SD initialization failed.
09:16:08.518 -> SD initialization failed.
09:16:10.720 -> SD initialization failed.
09:16:12.901 -> SD initialization failed.
09:16:15.125 -> SD initialization failed.
09:16:17.328 -> SD initialization failed.
09:16:19.521 -> SD initialization failed.
09:16:21.734 -> SD initialization failed.
09:16:23.925 -> SD initialization failed.
09:16:26.097 -> SD initialization failed.
09:16:28.332 -> SD initialization failed.
09:16:30.533 -> SD initialization failed.
09:16:32.732 -> SD initialization failed.
09:16:34.917 -> SD initialization failed.
````

EDIT: Now I've also added logic analyser output of failed SD setup.

EDIT 2:  The Teensy SD library is used:
````
Multiple libraries were found for "SD.h"
  Used: C:\Users\xxxxx\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.57.2\libraries\SD
  Not used: C:\Users\xxxx\AppData\Local\Arduino15\libraries\SD
 ````
[![enter image description here][2]][2]
[![enter image description here][3]][3]
[![enter image description here][4]][4]
[![enter image description here][5]][5]
[![enter image description here][6]][6]

  [1]: https://www.adafruit.com/product/254
  [2]: https://i.stack.imgur.com/wiOVHt.jpg
  [3]: https://i.stack.imgur.com/acxXbm.jpg
  [4]: https://i.stack.imgur.com/kWUXZl.jpg
  [5]: https://i.stack.imgur.com/GAgRC.png
  [6]: https://i.stack.imgur.com/RidI5.png

title: SD card breakout sometimes does not initialise (SPI connection - Teensy 3.2)

Answers: 0


body:
I have a Digispark / digistump Attiny85.  Working with Windows 11 and the Arduino IDE 2.0.4
I would like this guy to have Brown Out Detection set to 101 (2.7V)

For this, I'd need to set the BOD fuses.

How can I do this with the USB interface of the Arduino IDE?
To use the USB programming, I have to set the Board to "Digispark (Default 16.5Mhz)".

I have seen that in normal ATTiny85 operation, under the Tools-Menu I could choose the fuses I like.
In the Digispark Default setting this is not available.

title: How to burn fuses in Digistump ATTiny85 with the Arduino IDE

Answers: 1

body:
The first thing to say (already mentionened by @timemage) is that there is a large variety of "Digispark / Digistump" devices, both original, clones using the Micronucleus bootloader, even when considering only the ATTiny85 variants. Those variants, where the reset pin has not been re-configured as a GPIO pin, are easier to use. Otherwise, you firstly need a high voltage programmer to reset the ATTiny85 to its factory state, to restore the reset pin for configuring fuses etc.

The second thing is that the last post here:  digistump.com/board/index.php/topic,2257.msg10556.html#msg10556 implies that 2.7v brown out, which you appear to need, is anyway already enabled (at least with the variant described by the author) That  is, the fuse settings are: lfuse 0xE1 hfuse 0x5D efuse 0xFE.

Anyway, to change the fuses (or load the "Digispark / Digistump" (Micronucleus) bootloader) you need an ISP programmer (an Arduino or even another digispark can be configured as such). See: digistump.com/wiki/digispark/tutorials/programming. With the ISP programmer connected, you can then use AVRDUDE also to set the fuses.

In the worst case, you have to start with a factory condition ATtiny85 and go through the entire process of loading the "Digispark / Digistump" firmware onto it and configuring the appropriate fuse settings. See https://circuitdigest.com/microcontroller-projects/attiny85-ic-programming-through-usb-using-digispark-bootloader


body:
im sending the value 1500 from another MCU with

     fdserial_txChar(transmit, send >> 7);    // send Higher 7 bits
     fdserial_txChar(transmit, send & 0x7F);  // send Lower 7 bits

and was receiving it with code that looked like this

    servo1  = fdserial_rxChar(receive) << 7;    // get Higher 7 bits
    servo1 += fdserial_rxChar(receive) & 0x7F;  // get and add Lower 7 bits

how do i rewrite the receiving code so arduino will compile it?

Thank you.

here is the code im trying to get working

    void setup() {
    // physical pin 2=TX 3=RX
      Serial.begin(9600);
      pinMode(3, OUTPUT);      // set LED pin as output
      digitalWrite(3, LOW);    // switch off LED pin
    }

    void loop() {

      if (Serial.available()) {
      //  char data_rcvd = Serial.read();   // read one byte from serial buffer and save to data_rcvd

        int data_rcvd = Serial.read() << 7;     //get Higher 7 bits
        int data_rcvd += Serial.read() & 0x7F;  //get and add Lower 7 bits

        if (data_rcvd == 1500) digitalWrite(3, HIGH); // switch LED On
        if (data_rcvd == '0') digitalWrite(3, LOW);  // switch LED Off
      }

    //  if (digitalRead(8) == HIGH) Serial.write('0');    // send the char '0' to serial if button is not pressed.
    //  else Serial.write('1');                           // send the char '1' to serial if button is pressed.

    }

title: how to convert a line of code for arduino to receive a value

Answers: 2

body:
You have a few obvious problems here.

---

>     if (Serial.available()) {
>      int data_rcvd = Serial.read() << 7;     //get Higher 7 bits
>      int data_rcvd += Serial.read() & 0x7F;  //get and add Lower 7 bits

You are testing that one byte is available on the serial port and then reading two bytes. Too soon. Test for two bytes if you are planning to read two.

---

>     if (data_rcvd == '0') digitalWrite(3, LOW);  // switch LED Off

Why the quotes? Why not: `if (data_rcvd == 0)` ?

---

How are you intending to synchronize the sending and receiving?

Your sender is sending `HLHLHLHL` - what if the receiver starts while the low byte is being sent? You will receive `LHLHLH` which means your received data will be meaningless.

You are better off sending "readable" data, like "1500" rather than 1500, terminating with a newline, and structuring your receiving code to read until it hits a newline. That will synchronize the receiver (after the first reading, anyway).

---

For more tips about reading serial data see: https://arduino.stackexchange.com/questions/19756/how-does-serial-communications-work-on-the-arduino

Also [my post about serial data on my forum](http://www.gammon.com.au/serial) has code for buffering incoming serial data and waiting for a newline.

body:
the answer to my question of how to write

    servo1  = fdserial_rxChar(receive) << 7;    // get Higher 7 bits
    servo1 += fdserial_rxChar(receive) & 0x7F;  // get and add Lower 7 bits

so Arduino would compile it is....

    combined = (val1 << 7) | (val2);


body: I am trying to control a servo without the "Servo.h" library.I am sending using `analogWrite()` some values to the servo.I know the servo takes input a continuous time signal however I dont know the necessary frequency of that signal so I am not producing any sensible movement.What else should I consider when trying to control the servo using `analogWrite()`s?

title: Controlling a servo without the servo library

Answers: 1

body:
It can be done using `digitalWrite()` and `delayMicroseconds()`.

A servo is driven by a pulse. The pulse is between 1 ms (0°) over 1.5 ms (90°) to 2 ms (180°), followed by a pause that makes the total duration of a cycle 20 ms.

The 20 ms correspond to a 50 Hz signal. `analogWrite()` uses frequencies from 490 to 1000 Hz (depending on your hardware), which is why that won't work unless you figure out how to change the frequency.


body:
I've been trying to get my esp8266 to send a message to a telegram bot as soon as it connects to the wi-fi, whenever it encounters an obstacle, or whenever an SOS push button is pressed. But I didn't receive any message on telegram whenever I tested for either of the mentioned cases. Let me know if anything is wrong with the code and please suggest ways to make it work.

```
#include <ArduinoJson.h>
#include <ArduinoJson.hpp>

#include <Servo.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

#define trigPinF 2 // Front sensor trig pin
#define echoPinF 0 // Front sensor echo pin
#define trigPinL 5 // Left sensor trig pin
#define echoPinL 4 // Left sensor echo pin
#define trigPinR 14 // Right sensor trig pin
#define echoPinR 12 // Right sensor echo pin
#define ledPin 13 // LED pin
#define vibPin 15 // Vibration motor pin
#define buttonPin 16 // Button pin
#define servoPin 3 // Servo pin

const char* ssid = "XXXXX";
const char* password = "XXXXX";

#define token "XXXXXXXXXXXXXXXXX"
#define telegramChatId "XXXXXXXXXX"

WiFiClientSecure client;
UniversalTelegramBot bot(token, client);

Servo servo;

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

 pinMode(trigPinF, OUTPUT);
 pinMode(echoPinF, INPUT);
 pinMode(trigPinL, OUTPUT);
 pinMode(echoPinL, INPUT);
 pinMode(trigPinR, OUTPUT);
 pinMode(echoPinR, INPUT);
 pinMode(ledPin, OUTPUT);
 pinMode(vibPin, OUTPUT);
 pinMode(buttonPin, INPUT);
 servo.attach(servoPin);

 WiFi.begin(ssid, password);
 Serial.println("Connecting to WiFi...");
 while (WiFi.status() != WL_CONNECTED) {
 delay(1000);
 Serial.print(".");
  }
 Serial.println();
 Serial.println("WiFi connected");

 bot.sendMessage(telegramChatId, "Bot started up", "");
}

void loop() {
  long durationF, distanceF, durationL, distanceL, durationR, distanceR;
 digitalWrite(trigPinF, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPinF, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPinF, LOW);
  durationF = pulseIn(echoPinF, HIGH);
  distanceF = durationF * 0.034 / 2;
 digitalWrite(trigPinL, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPinL, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPinL, LOW);
  durationL = pulseIn(echoPinL, HIGH);
  distanceL = durationL * 0.034 / 2;
 digitalWrite(trigPinR, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPinR, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPinR, LOW);
  durationR = pulseIn(echoPinR, HIGH);
  distanceR = durationR * 0.034 / 2;

 if (distanceF < 30) { // Front obstacle detected
 digitalWrite(ledPin, HIGH);
 digitalWrite(vibPin, HIGH);
 bot.sendMessage(telegramChatId, "Obstacle detected!");
 if (distanceL > distanceR) { // Turn towards the direction with more space
 servo.write(90 + (distanceL - distanceR));
    } else { // Turn towards left if both directions have same space
 servo.write(90 - (distanceR - distanceL));
    }

    String message = "Obstacle detected!";
 bot.sendMessage(telegramChatId, "Obstacle detected!");
  } else {
 digitalWrite(ledPin, LOW);
 digitalWrite(vibPin, LOW);
  }

 if  (digitalRead(buttonPin) == LOW) { // Button pressed
    String message = "Button pressed!";
 bot.sendMessage(telegramChatId, "Button pressed!");
  }

 delay(100);
}
```

title: ESP8266 not sending text message to telegram bot

Answers: 0


body: If I disable interrupts (for example `noInterrupts` or `cli`) and enable them (`interrupts` or `sei` for example) later, would interrupts which would have executed in the window in between fire by the execution of the latter? I guess not, and haven't confirmed or denied it. If not it is always an option to manually disable timers or components with similar concerns with respect to the interrupt status? It makes sense that AVR-based Arduino boards would behave similarly. It seems plausible that the bits for the force interrupt execution will turn on and turned off when the jump occurs. Thanks for reaching out.

title: Checking a thing about interrupts

Answers: 1

body:
See https://arduino.stackexchange.com/questions/30968/how-do-interrupts-work-on-the-arduino-uno-and-similar-boards/30969#30969

Yes, most interrupts will be remembered and the ISR will be executed when interrupts are enabled again, plus one more instruction has been executed. If that didn't happen it would be very bad, as you may turn off interrupts briefly and you wouldn't want to miss the thing that the interrupt was for (eg. incoming serial data).

To stop that happening you need to clear the "interrupt has happened" bit for the individual interrupts. This is documented in the datasheet for each interrupt.

The order in which outstanding interrupts will be serviced is the interrupt priority, that is lower-numbered interrupts will be serviced first. The call to the ISR causes the processor to clear the "interrupt has happened" bit for that interrupt.


body:
I would like to power a dfrobot firebeetle 2 using 3 alkaline batteries. I tried connecting the battery pack to the GND and VCC, but the board does not seem to react. What pins should i connect the leads to?

The firebeetle 2 info page:
https://www.dfrobot.com/product-2195.html

title: AA alkaline batteries on firebeetle?

Answers: 1

body:
The following is based purely on the small amount of information in your question. You haven't described your code or your setup, which would allow this answer to be more specific.

According to the FireBeetle ESP32 schematics [here](https://dfimg.dfrobot.com/nobody/wiki/fd28d987619c16281bdc4f40990e5a1c.PDF), you should be able to connect an external power supply between VCC(+) and GND(-).

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

The voltage regulator on the FireBeetle ESP32 is a low-dropout RT9080 regulator, which, according to its [datasheet](https://www.farnell.com/datasheets/2183318.pdf) has a maximum voltage drop of about 0.5 V when outputting the 3.3 V needed by your board and a maximum input voltage of 5.5 V.

That means the voltage supplied at VCC should be between 3.8 V and 5.5 V, and the ~4.5 V supplied by your 3 x AA batteries (assuming they're connected in series), falls nicely into this range.

The fact that your board does not seem to run your code might be caused by a number of things.
1) Does your program expect a Serial port connection which, of course, is not available when it's not connected to a PC by USB?
2) The power demanded by your board might be too high for the batteries. Are there other things connected to the board that that could cause that?

If you have a multimeter, you should be able to measure a stable 3.3 V on the 3.3 V pin of the FireBeetle.

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


body:
I have a Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500 that indicates the firmware installed is too old for the Wifi101 library (Version 0.16.1).  I have been trying to do a firmware update but when I run the Wifi101 Firmware updater, the GUI indicates that there are no compatible boards connecter.  The board I have selected is the Adafruit Feather M0.  I tried selecting the MKR1000 and the GUI seemed to think that was okay, but after starting the FW update fails.    Which board should I be selecting to get the Firmware Update running?

Per the comment below, I should have mentioned that I did follow the instructions at https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/updating-firmware.  One of the pictures showed the board as Adafruit Feather M0, which is what I do have selected, however the WiFi101 Firmware Updater GUI says the board is unsupported.

[![screenshot][1]][1]

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

title: Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500 Firmware updater

Answers: 0


body:
I have so many commands that i need help to setup my SIM800L module. Tutorials i have seen so far involves the messages going directly to the mCu this is problematic for me because if the mCU is currently bussy doing something as of the moment and multiple messages arrive. The buffer would fill up without getting read.

I would like my program logic to be like this:

Wait for new messages/ do some other stuff -> check inbox -> if new message -> read message -> delete read messages-> repeat...

Would this be possible? Im having a hard time finding the commands for these actions.
I know that setting how messages are handled are set by `AT+CNMI=` i could not understand the datasheet. I have also came across this command : `AT+CMGL="ALL"` and `AT+CMGD=X` which deletes
the read message.

`AT+CMGL= ALL` seems dangerous because if too much pending message is present it would overflow the buffer i set in my arduino (256 bytes). Is there a command thats just 1 at a time?

so the sequence of commands would be:

    //setup:
    AT
    AT+CMGF=1
    AT+????? //tells the module to save incoming to memory

    //reading:
    AT+CMGL="XXX" //read one unread if present
    AT+CMGD=??    //CMGL should return a number identifier which i can then use for delete
    //do something else or loop though all unread messages.

Can anyone help me sort this out?

title: How to set SIM800L to save messages to memory and reading them

Answers: 0


body:
I'm curently playing with sleep modes. When I push the button, melody starts, push again go to deep down sleep and save 3v battery, push again wake up and melody starts again. But seems like it doesn't completely goes to sleep and can't wake up.

    #include <OneButton.h>
    #include <avr/sleep.h>
    #include <avr/power.h>

    #define cs6 1109
    #define fs5 740
    #define d6 1175
    #define c6 1047
    #define f5 698
    #define b5 988
    #define e5 659
    #define bf5 932
    #define ef5 622
    #define b4 494
    #define g5 784
    #define led1 8
    #define led2 7

    const uint16_t halloween[] PROGMEM = { cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                           c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                           cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                           c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                           c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                           b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                           b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                           bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                           bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                           b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                           b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                           bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                           bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                           fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4
                                         };

    typedef enum {
      ACTION_OFF,
      ACTION_ON
    }
    MyActions;

    const int buzzer = PA1;
    unsigned long previousMillis = 0;
    unsigned long pauseBetweenNotes = 218;
    int noteDurations = 6;
    int thisNote=0;
    int ledState = LOW;

    OneButton button(10, true, true);

    MyActions nextAction = ACTION_OFF; // no action when starting

    void setup() {
      pinMode(buzzer, OUTPUT);
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);
      attachInterrupt(digitalPinToInterrupt(10), wakeUpFromSleep, FALLING);
      button.attachClick(myClickFunction);

    }

    void melody () {

      unsigned long currentMillis = millis();

      if (thisNote <= 290 && currentMillis - previousMillis >= pauseBetweenNotes)
      {
        previousMillis = currentMillis;

        if (ledState == LOW) {

          ledState = HIGH;

          tone(buzzer, pgm_read_word(&halloween[thisNote]), 168);
          pauseBetweenNotes = 167 * 0.65;
          thisNote++;
        }

        else {

          ledState = LOW;
        }
        digitalWrite(led1, ledState);
        digitalWrite(led2, ledState);

      }
    }

    void wakeUpFromSleep() {
      // Rimuovi l'attivazione dell'interrupt per il pulsante
      detachInterrupt(digitalPinToInterrupt(10));
      sleep_disable();
      power_all_enable();
     }

    void myClickFunction() {

      if (nextAction == ACTION_OFF)
      {
        nextAction = ACTION_ON;
        thisNote = 0;
        pauseBetweenNotes = 0;
        previousMillis = 0;
      }

      else
      {
        nextAction = ACTION_OFF;
        digitalWrite(led1, LOW);  // spegni i led
        digitalWrite(led2, LOW);
        noTone(buzzer);
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        sleep_cpu();
      }
    }

    void loop() {

      button.tick();

      if (nextAction == ACTION_OFF) {
        wakeUpFromSleep();
      }

      else if (nextAction == ACTION_ON) {
        melody();
        }
    }

title: Wake-UP the ATtiniy44 from sleep_mode_pwr_down with a PushButton

Answers: 1

body:
**EDIT**
I've written the following programm. It should provide the requested features.

But for the time being I don't have access to an ATtiny44a so I used a Arduino UNO. I read both data sheets and did not find anything that prevents the program from running on a ATtiny44. So please try it and if it runs you can read the comments in the program to understand what I did to get it running.

I have a very "chirpy" button, so some times the program can not differ whether I clicked twice or the button bounces. I've used long debouncing periods to get rid of that. I've commented it in the code, please check what value works best for you.

Ah, And I've accellerated the the melody a little bit ;-). I like Heavy Metal more than Walzing Matilda style ;-). And I change the programm so that it runs the mellody again and again until you pressed the button again. Your Program stopped ofter playing the melody once.

    // This Code is intended to run on an ordinary Arduino Uno
    // The original request was to implement it for an ATtiny44a.
    // I will document if there are difference to take
    // into consideration. Most of the code should run on a
    // attiny44 as well.

    // The purpose of this program is to let the MCU play a melody
    // started and stopped by clicking a button. The mcu should enter
    // a enerngy saving sleep mode when the melody stops.
    // When in sleep mode, pressing a button should wake up the MCU
    // which then should continue playing the melody.

    #include <avr/sleep.h>
    #include <avr/power.h>

    // The button pin must be pin two for Arduino Uno
    // for a tiny any pin can be used so pin 2 is fine.
    const int buttonPin = 2;
    const int buzzerPin = 10;
    const int led1 = 8;
    const int led2 = 7;

    // Attention!!!!: I use a pull up and a push button
    // connected to GND.
    // With this setup pressing the button will pull the pin to GND.
    // Therefore we read LOW while the button is pressed.
    // If the button is HIGH active - that means the button
    // is connected to VCC - the LOW of the following constant must
    // be changed to HIGH and the RISING must be changed to FALLEN.
    #define BUTTON_PRESSED LOW
    #define INTERRUPT_TRIGGER_METHOD RISING

    // I decided to use a very long debounce delay, because I
    // featured a very "chirpy" button. Feel free to experiment
    // with this delay.
    const long debounceDelay = 150L;

    // setup for the melody

    // define the note pitch values
    #define cs6 1109
    #define fs5 740
    #define d6 1175
    #define c6 1047
    #define f5 698
    #define b5 988
    #define e5 659
    #define bf5 932
    #define ef5 622
    #define b4 494
    #define g5 784

    // provide a melody as an array.
    const uint16_t halloween[] PROGMEM = {
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
      c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
      c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
      c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
      b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
      b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
      bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
      bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
      b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
      b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
      bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
      bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
      fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4
    };

    //define processing variables for the play functionallity
    unsigned long previousMillis = 0;
    unsigned long pauseBetweenNotes = 300;
    unsigned long lengthOfActiveNote = 300;
    int noteCounter = 0;
    boolean toneOn = false;

    // handling the play mode
    // after inserting the battery the melody does not play.
    // After the user will have pushed and released
    // the push button, we will start with the melody.
    volatile boolean playMelody = false;
    volatile bool playModeChangeRequested = false;

    // reading and debouncing the button
    volatile unsigned long lastDebouncingMillis = 0;

    void stopTheMelody()
    {
      noTone(buzzerPin);
      toneOn = false;
      digitalWrite(led1, toneOn);
      digitalWrite(led2, toneOn);
    }

    void startTheMelody()
    {
      previousMillis = 0;
      pauseBetweenNotes = 0;
      noteCounter = 0;
      toneOn = false;
      digitalWrite(led1, toneOn);
      digitalWrite(led2, toneOn);
    }

    void melody ()
    {
      unsigned long currentMillis = millis();
      if (! toneOn &&
          (currentMillis - previousMillis) > pauseBetweenNotes)
      {
        pauseBetweenNotes = 167 * 0.2;
        tone(buzzerPin, pgm_read_word(&halloween[noteCounter]));
        noteCounter++;
        if (noteCounter > 290)
        {
          // the old program plays the melody only once
          // with resetting the note counter to 0
          // the melody start again and again.
          noteCounter = 0;
        }
        toneOn = true;
        digitalWrite(led1, toneOn);
        digitalWrite(led2, toneOn);
        previousMillis = currentMillis;
      }
      else if(toneOn &&
              (currentMillis - previousMillis) > lengthOfActiveNote)
      {
        lengthOfActiveNote = 58;
        noTone(buzzerPin);
        toneOn = false;
        digitalWrite(led1, toneOn);
        digitalWrite(led2, toneOn);
        previousMillis = currentMillis;
      }
    }

    // This is the interrupt service routine.
    // It is called every time the button will have been released.
    void ISR_buttonReleased()
    {
      // Here, we know that this ISR is called because,
      // the button was released.
      lastDebouncingMillis = 0L;
      playModeChangeRequested = true;

      if (!playMelody)
      {
        // if the interrupt was triggered while the MCU was sleeping
        // we need to switch off the sleep mode to resume
        // normal activity. Otherwise the debouncing method does not
        // work, as it is done by code outside of the ISR.
        sleep_disable();
        power_all_enable();
      }
    }

    void setup()
    {
      pinMode(buttonPin, INPUT_PULLUP);
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);
      pinMode(buzzerPin, OUTPUT);

      // paranoia setup
      playMelody = false;
      playModeChangeRequested = false;
      lastDebouncingMillis = 0;

      // the interrupt is triggered on rising edge, i.e.
      // when the button will be released
      attachInterrupt(
           digitalPinToInterrupt(buttonPin),
           ISR_buttonReleased,
           INTERRUPT_TRIGGER_METHOD);

      // stop melody and sleep
      stopTheMelody();
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      sleep_enable();
      sleep_cpu();
    }

    void loop()
    {
      // lastDebouncingMillis will be set to 0 1st) in the
      // setup routine and 2nd) in the ISR.
      if (lastDebouncingMillis==0 ||
          digitalRead(buttonPin)==BUTTON_PRESSED)
      {
        // Here lies the magic!
        // We synchronize the ISR, the sleep mode, a long button
        // press without release and the
        // button bouncing with this single if statement.
        lastDebouncingMillis = millis();
      }

      if (playModeChangeRequested)
      {
        unsigned long tempMillis = millis();
        if((tempMillis - lastDebouncingMillis) > debounceDelay)
        {
          playModeChangeRequested = false;
          playMelody = !playMelody;
          if (!playMelody)
          {
            // stop melody and sleep
            stopTheMelody();
            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
            sleep_enable();
            sleep_cpu();
          }
          else
          {
            startTheMelody();
          }
        }
      }

      if(playMelody)
      {
          melody();
      }
    }

**Old Answer removed**

The old answer was not clear enough for this complicated topic.


body:
I am using ENC28J60 and EthernetENC library to connect an Arduino UNO with ATmega328 to the network. Everything works fine within the local network, but outside of it, I cannot ping the device. What could be the problem? The network settings are 100% correct (other devices work fine, and examples from the Ethernet library also respond to pings).

```
////////////////////////////////////// Settings //////////////////////////////////////
#define DHCP false          // true/false
#define CUSTOM_MAC true     // true/false

#if CUSTOM_MAC              // if true you can enter your custom mac address
#define MAC 0x00,0x5f,0x1C,0x05,0x5f,0x1C
#else
#define MAC 0x00,0x5f,0x1C  // Organizationally Unique Identifier (OUI)
#endif

#define IP_ADDRESS  192,168, 11,242
#define SUBNET      255,255,255,248
#define GATEWAY     192,168, 11,241
#define DNS         192,168, 11,241

// #define UIP_CONF_MAX_CONNECTIONS 0
///////////////////////////////////// Libraries //////////////////////////////////////
#include <Arduino.h>
#include <EthernetENC.h>  // Include the Ethernet library
#include <Agentuino.h>    // SNMP library
#include <EEPROM.h>
#include <microDS18B20.h>
/////////////////////////////// Arduino sensor pins //////////////////////////////////
#define TEMPERATURE_1_PIN 0
#define TEMPERATURE_2_PIN 1
#define TEMPERATURE_3_PIN 2
#define TEMPERATURE_4_PIN 3
#define SENSOR_220V_PIN   4
#define SERVO_PIN         5
#define LED_ALERT_PIN     6
#if !SOUND_MUTE
#define SPEAKER_PIN       7
#else
#define SPEAKER_PIN       8
#endif
#define FLOOD_PIN         A0
#define DOOR_PIN          A1
#define GAS_PIN           A2

///////////////////////////// Ethernet / SNMP init ///////////////////////////////////
#if !DHCP
IPAddress ip(IP_ADDRESS);   // IP Address for arduino
IPAddress gateway(GATEWAY); // Gateway for arduino
IPAddress subnet(SUBNET);   // SubNet mask for arduino
IPAddress myDns(DNS);       // DNS for arduino
#endif

byte mac[] = {MAC};

//////////////////////////////////// My OIDs /////////////////////////////////////////
...
//////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////// function SNMP resived ////////////////////////////////
void pduReceived(){...}
//////////////////////////////////////////////////////////////////////////////////////

void setup(){
  ///////////////////////////////// init pins ////////////////////////////////////
  pinMode(TEMPERATURE_1_PIN, INPUT);
  pinMode(TEMPERATURE_2_PIN, INPUT);
  pinMode(TEMPERATURE_3_PIN, INPUT);
  pinMode(TEMPERATURE_4_PIN, INPUT);
  pinMode(SENSOR_220V_PIN, INPUT);
  // pinMode(SERVO_PIN, INPUT);
  pinMode(FLOOD_PIN, INPUT);
  pinMode(DOOR_PIN, INPUT);
  pinMode(GAS_PIN, INPUT);
  pinMode(LED_ALERT_PIN, OUTPUT);
  #if !SOUND_MUTE
  pinMode(SPEAKER_PIN, OUTPUT);
  #endif

  ////////////////////////////// init other //////////////////////////////////////
  Serial.begin(9600); // Serial monitor init
  Agentuino.begin();  // Begin Snmp agent on Ethernet shield

  ///////////////////////// Generate random mac address //////////////////////////
#if !CUSTOM_MAC
  if (EEPROM[0] == 255 && EEPROM[1] == 255 && EEPROM[2] == 255){
    for (int i = 3; i < 6; i++){
      randomSeed(analogRead(A5));
      mac[i] = random(0xFF);
      EEPROM.put(i - 3, mac[i]);
    }
  }
  else{
    for (int i = 3; i < 6; i++){
      EEPROM.get(i - 3, mac[i]); // Reed saved mac addres from EEPROM
    }
  }
#endif

#if DHCP
  Ethernet.begin(mac) // Initialize Ethernet Shield in DHCP mode
#else
  Ethernet.begin(mac, ip, myDns ,gateway, subnet); // Initialize Ethernet Shield in static mode
#endif

///////////////////////////////////// Debug //////////////////////////////////////
Serial.println();
Serial.println();
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println(F("Ethernet shield was not found.  Sorry, can't run without hardware. :("));
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    delay(500);
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
  }

  Serial.print(F("localIP: "));
  Serial.println(Ethernet.localIP());
  Serial.print(F("dnsServerIP: "));
  Serial.println(Ethernet.dnsServerIP());
  Serial.print(F("gatewayIP: "));
  Serial.println(Ethernet.gatewayIP());
  Serial.print(F("subnetMask: "));
  Serial.println(Ethernet.subnetMask());
  Serial.print(F("mac: "));
  for (int i = 0; i < 6; i++){
    Serial.print(mac[i], HEX);
    if (i <= 4) Serial.print(F("."));
  }

  Serial.println();
  ////////////////////////////////////////////////////////////////////////////////

  Agentuino.onPduReceive(pduReceived);
  delay(10);
}

void loop(){
  Agentuino.listen();

  //////////////////////////////// Other code ////////////////////////////////////
  ...
  ////////////////////////////////////////////////////////////////////////////////
}
```

title: The gateway is not working in Arduino EthernetENC

Answers: 1

body:
From outside your local network (i.e the internet) you can only ping the external IP address of your router, local IPs such as your 192.168.11.242 are not routable on the internet. Additionally many home routers are configured to not respond to external pings.
I see you're using snmp to communicate with your Arduino, you could forward the snmp port (normally port 161) from your router to the Arduino on 192.168.11.42:161 to achieve what you want but this is a security risk. You would then connect your snmp manager to your external IP address and your router would connect to your Arduino and do the required Network Address Translation to communicate. This assumes your router and internet provider allow port forwarding of the snmp port.


body:
I wanted to compare the debug output of the Arduino Zero when connecting via two different debug paths.

 1. Via the embedded debugger (EDBG) connected to Arduino IDE via USB
 2. Via the JTAG hardware connector J100 to a Black Magic Probe and GDB

The two paths being compared are shown on the [Zero Schematic][1]:
[![Snipped image of the JTAG related part of the schematic][2]][2]

Using the Blink.ino compiled for debug, the EDBG works as expected into the Arduino IDE 2.0.4 debugger via USB.

However using the same sketch with the JTAG hardware port to a black magic probe fails to connect, reporting "Target voltage: 1.0V".

    rowan@rowan-ThinkPad-X1-Carbon-4th:/tmp/arduino/sketches/1EBCACBEAD6C08902D692E87F523B56E$ arm-none-eabi-gdb Blink.ino.elf
    GNU gdb (GNU Arm Embedded Toolchain 10.3-2021.10) 10.2.90.20210621-git
    Copyright (C) 2021 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <https://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <http://www.gnu.org/software/gdb/documentation/>.

    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from Blink.ino.elf...
    (gdb) target extended-remote /dev/ttyACM1
    Remote debugging using /dev/ttyACM1
    (gdb) monitor jtag_scan
    Target voltage: 1.0V
    JTAG device scan failed!
    Failed
    (gdb)
[![Photo of JTAG connection to Zero][3]][3]

The same probe and setup successfully debugs an Arduino Due. Acknowledging different processors on the two boards.

The JTAG connector is correctly oriented.

Is a switching action needed to enable one debug path or the other, or is something else wrong?

**Update 2023-04-01:** I bought an SWD breakout board so I could get some test leads on without risking bent pins (it took a couple of weeks to arrive). The VREF pin on the Zero is 0V when running the debug version of Blink.ino. In comparison the same test rig connected to Due running debug Blink.ino VREF is 3.3V as expected.

Tracing back the Zero JTAG VREF pin connection on the PCB, the connection is as expected compared to the [published PCB Layout][4]. It connects to a pin on the Atmel EDBG chip (IC3).
[![PCB Layout Snippet][5]][5]

At J100 the schematic (snippet above) labels this connection VCC_P3V3. However it seems to connect to VCC_EDBG_P3V3.

I'm going to spend some time with the [Atmel EDBG User Guide][6]

**Update 2023-04-01 #2:** During successful debugging using the USB EDBG to Arduino IDE method, the JTAG (J100) VREF pin remains at 0V.

**Update 2023-04-01 #3:** Refering to the [EDBG datasheet][7] section 5. The pin on the EDBG chip (IC3) to which the JTAG Vref pin is connected is (K9) EDBG_TCK. Noting the orientation is inverted compared to the PCB image.
[![EDBG VBGA Package Pinout][8]][8]
EDBG_TCK is described as "JTAG Test Clock pin for EDBG device", and is in the EDBG manufacturing programming group of pins.

**OK, it's clear to me now, that this isn't the JTAG I was looking for, I'll write it up as an answer.**

  [1]: https://cdn-shop.adafruit.com/product-files/2843/Arduino-Zero-schematic.pdf
  [2]: https://i.stack.imgur.com/uLQ1w.png
  [3]: https://i.stack.imgur.com/EfOAb.jpg
  [4]: https://docs.arduino.cc/hardware/zero
  [5]: https://i.stack.imgur.com/0kObT.png
  [6]: http://ww1.microchip.com/downloads/en/devicedoc/atmel-42096-microcontrollers-embedded-debugger_user-guide.pdf
  [7]: https://mil.ufl.edu/4744/docs/XMEGA/EDBG_Embedded_Debugger_Datasheet.pdf
  [8]: https://i.stack.imgur.com/kjlxy.png

title: Does Arduino Zero need to be switched between USB EDBG and JTAG port debug use?

Answers: 1

body:
I believe the problem occured because I assumed that J100 on the schematic is the populated JTAG interface. Tracing through the schematics and PCB layout indicate that J100 on the schematic is CN2 on the PCB layout (the JTAG interface with no headers populated). J301 on the schematic is the JTAG interface with headers installed, called CN1 on the PCB layout
[![Zero PCB Layout][1]][1]

J301 (CN1) is for programming the EDBG chip.
[![J301 CN1 Schematic snippet][2]][2]

J100 (CN2) breaks out JTAG target interface pins, but does not have header installed.
[![J100 CN2][3]][3]

[![Arduino Zero Image][4]][4]

Contrary to the schematic, looking at J100 (CN2) on the PCB laypout and also by visual inspection of the physical PCB VREF pin 1 does not seem to have any connection to +3V3.

Top View:
[![J100 (CN2) VREF pin detail - top][5]][5]
Bottom View:
[![J100 (CN2) VREF pin detail - bottom][6]][6]

Counter to the microscope photo evidence, I do read 3.3V (using multimeter) on the square solder pad of the VREF pin, which matches the schematic. I'm having trouble explaining it though. This is a two layer PCB right?

**Updated 2/4/2023: My conclusion is that the EDBG JTAG port is not useful with the Black Magic Probe as an alternative to EDBG. The J100 (CN2) port seems like it would be usable if it had headers.**

  [1]: https://i.stack.imgur.com/veBfQ.jpg
  [2]: https://i.stack.imgur.com/ZiTdg.png
  [3]: https://i.stack.imgur.com/KhdcI.png
  [4]: https://i.stack.imgur.com/KDSAn.jpg
  [5]: https://i.stack.imgur.com/158fD.jpg
  [6]: https://i.stack.imgur.com/8gNZi.jpg


body:
The hardware I am using is ESP32 with MAX30102, MLX90614 and MPU6050 sensors and Using Blynk to show my data from the sensors. The issue I am facing is when I ran the code with all three sensors only the MAX30102 sensor doesn't show data.

I tried troubleshooting with only two sensors at a time and when the MAX30102 sensor is involve I only can get the other sensors data.
I tried troubleshooting with only the MAX30102 sensor only and it works I don't understand what is going on.

```
#include <WiFi.h>                   // include the Arduino WiFi library
#include <Wire.h>
#include <math.h>
#include <MAX30105.h>
#include <heartRate.h>
#include <Adafruit_MLX90614.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Blynk.h>
#include <BlynkSimpleEsp32.h>

#define BLYNK_PRINT Serial

Adafruit_MLX90614 mlx = Adafruit_MLX90614(); //0x5A
MAX30105 particleSensor;

char auth[] = "0GUsnEJQJCDHF2HsLzYscYcDgXoe4KFg";  // Blynk code
const char *ssid = "Get your own Wifi";            // WiFi access name
const char *pass = "w1frjoyf00bar";                // WiFi password

const byte RATE_SIZE = 4; // Settings for Max 30102
byte rates[RATE_SIZE];
byte rateSpot = 0;
long lastBeat = 0;
float beatsPerMinute = 0;
float beatAvg = 0;

const int MPU_addr = 0x68; // I2C address of the MPU-6050
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
float ax = 0, ay = 0, az = 0, gx = 0, gy = 0, gz = 0;

void setup() {
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  particleSensor.begin(Wire, I2C_SPEED_FAST);
  particleSensor.setup();
  particleSensor.setPulseAmplitudeRed(0x0A);   // Turn Red LED to low to indicate sensor is running
  mlx.begin();  // Start MLX sensor
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");              // print … till not connected
  }
  Serial.println("");
  Serial.println("WiFi connected");
}

void mpu_read() {
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
  AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
}

void loop() {
  Blynk.run();

  long irValue = particleSensor.getIR();

   if (checkForBeat(irValue) == true)                    //If a heart beat is detected
  {
    Serial.println("BPM");
    Serial.println(beatAvg);
    Serial.println();
    delay(100);
    long delta = millis() - lastBeat;                   //Measure duration between two beats
    lastBeat = millis();
    beatsPerMinute = 60 / (delta / 1000.0);             //Calculating the BPM
    if (beatsPerMinute < 255 && beatsPerMinute > 20)    //To calculate the average we strore some values (4) then do some math to calculate the average
    {
      rates[rateSpot++] = (byte)beatsPerMinute;         //Store this reading in the array
      rateSpot %= RATE_SIZE;                            //Wrap variable
      beatAvg = 0;                                      //Take average of readings
      for (byte x = 0 ; x < RATE_SIZE ; x++)
        beatAvg += rates[x];
      beatAvg /= RATE_SIZE;
    }
//    Serial.println("");
//    Serial.println("BPM: ");
//    Serial.println(beatAvg);
  }

  delay(100);

  mpu_read();
  ax = (AcX + 1704) / 16384.00;
  ay = (AcY - 412) / 16384.00;
  az = (AcZ + 1765) / 16384.00;
  gx = (GyX + 82) / 131.07;
  gy = (GyY + 6) / 131.07;
  gz = (GyZ + 32) / 131.07;
  // calculating Amplitute vactor for 3 axis
  float Raw_Amp = pow(pow(ax, 2) + pow(ay, 2) + pow(az, 2), 0.5);
  int Amp = Raw_Amp * 10;  // Mulitiplied by 10 bcz values are between 0 to 1
  float roll = 57.2883514 * atan(ay / sqrt(ax * ax + az * az));

  Serial.print("\nAMP:");
  Serial.print(Amp);
  Serial.print("      ");
  Serial.print(", Roll:");
  Serial.println(roll);

  Serial.print("BPM = ");
  Serial.print(beatsPerMinute);
  Serial.print(", Avg BPM = ");
  Serial.print(beatAvg);
  Serial.println();

  Serial.print("Ambient Temp = ");
  Serial.print(mlx.readAmbientTempC());
  Serial.print("\n Object Temp = ");
  Serial.print(mlx.readObjectTempC());
  Serial.print("      ");

  Serial.print("      ");
  alertBPM();
  Serial.print("      ");
  alertTemp();

  Serial.print("\n-----------------------------------------------------------------");
  Blynk.virtualWrite(V1, beatAvg);
  Blynk.virtualWrite(V2, mlx.readObjectTempC());

}

void alertBPM() {                                 // Alert Trigger for Heart rate
  // BPM alert
  if (beatAvg >= 60 && beatAvg <= 110) {
    Serial.println("Heart rate normal");
  }

  if (beatAvg < 60 && beatAvg > 110) {
    Serial.println("Heart Rate Abnormal");        // Need to change the HR to hhr
    Blynk.logEvent("HR", "Heart Rate Abnormal");
  }
}

void alertTemp() {                                  // Alert Trigger for Body Temp
  // Body and ambient temp alert
  if (mlx.readObjectTempC() >= 35 && mlx.readObjectTempC() <= 39) {
    Serial.println("Body temp normal");
  }

  if (mlx.readObjectTempC() < 35 && mlx.readObjectTempC() > 39 ) {
    Serial.println("Body temp Abnormal");
    Blynk.logEvent("BT", "Body temp Abnormal");   // Need to change BT to hbt
  }
}
```

The output is this

```
-----------------------------------------------------------------
AMP:11      , Roll:-2.12
BPM = 0.00, Avg BPM = 0.00
Ambient Temp = 30.75
 Object Temp = 36.07                  Body temp normal

-----------------------------------------------------------------
AMP:10      , Roll:3.90
BPM = 0.00, Avg BPM = 0.00
Ambient Temp = 30.77
 Object Temp = 36.07                  Body temp normal

-----------------------------------------------------------------
AMP:11      , Roll:-0.15
BPM = 0.00, Avg BPM = 0.00
Ambient Temp = 30.79
 Object Temp = 35.99                  Body temp normal

-----------------------------------------------------------------
```

title: MAX30102 doesnt show data when it's interfacing with other sensors MLX90614 and MPU6050

Answers: 0


body: When I connected my Arduino Nano 33 IoT to my 2017 iMac (Ventura OS), the USB port did not show in the Arduino IDE port list, even after double-clicking the Nano reset button to put it in the right mode. Installing the special CH34X device driver on the Mac for the USB port did not work either.

title: Why is Arduino not visible in MacOS USB port list?

Answers: 1

body:
This is a common problem as judged by online questions. The most common solution seems to be to install the special CH34X device driver on the Mac for the USB port, but I'm suspecting many people actually have the same problem I did.

Have you heard of a “charge only” USB cable? I was skeptical, but I discovered that **four of my six USB-to-microUSB cables were charge-only!** If you want to communicate data￼, for example connecting your computer to an Arduino microprocessor to program it, the charge-only cable will not work.

How to tell the difference? There are four wires in the data-capable cable. The outside two on the connector are for charging and the inside two are￼ for data. If yours is missing the inside connectors, then it’s charge-only. But if it has them, it still might be charge-only. Use a meter to do a continuity check to test if those middle connectors are connected. You’ll need to use a little fine wire to get inside the little micro-USB connector to make contact, and you’ll probably need somebody to help you by holding one end in contact.

**As soon as I switched to a data-capable cable, the Nano USB port showed up in the IDE list!** (After double-clicking the Nano reset button).

After I got it working, I uninstalled the special driver I had installed, and it continued to work.

Thanks ptillisch on Arduino Team!


body:
I am trying to create a class (Arm) that controls an arm. The arms have 2 motors, each with an encoder, so I pass 4 integers for the pins and I am trying to pass 2 pointers (one for each encoder object).

the .ino file is:
```c++
#include "Arm.h"
#include <Encoder.h>

//motor driver pins
#define ShoulderUP 7
#define ShoulderDW 8

#define ElbowUP 9
#define ElbowDW 10

#define encoderShoulderPinA 20
#define encoderShoulderPinB 21

#define encoderElbowPinA 22
#define encoderElbowPinB 23

//make encoder objects
Encoder ElbowEncoder(encoderElbowPinA, encoderElbowPinB);
Encoder ShoulderEncoder(encoderShoulderPinA, encoderShoulderPinB);

//make arm object
Arm Arm1(ShoulderUP, ShoulderDW, ElbowUP, ElbowDW, ElbowEncoder, ShoulderEncoder);

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

void loop() {

  Arm1.ShoulderMoveTime(1, 255, 1000);
}
```

the .h file is:
```c++
#ifndef Arm_h
#define Arm_h

#include <Arduino.h>
#include <Encoder.h>

class Arm {

public:
  Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder);

  //pins connected to your encoder:
  //   Best Performance: both pins have interrupt capability
  //   Good Performance: only the first pin has interrupt capability
  //   Low Performance:  neither pin has interrupt capability

  void ShoulderMoveTime(int dir, int speed, int time);
  //dir = 0 means up, dir = 1 means down; speed between 0-255
  void ElbowMoveTime(int dir, int speed, int time);
  //dir = 0 means up, dir = 1 means down; speed between 0-255

  //Moves arm to poition given
  void ArmMovePosition(int shoulderPos, int elbowPos);

  // calibrates current arm position to zero
  void ZeroArm();

  //returns position of the arm
  void getArmPosition();

private:
  Encoder *ElbowEncoder;
  Encoder *ShoulderEncoder;
  int _ShoulderUpPin;
  int _ShoulderDownPin;
  int _ElbowUpPin;
  int _ElbowDownPin;
};

#endif
```

and the .cpp file is:
```c++
#include "Arduino.h"
#include "Encoder.h"
#include "Arm.h"

Arm::Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder) {

  pinMode(ShoulderUpPin, OUTPUT);
  pinMode(ShoulderDownPin, OUTPUT);
  pinMode(ElbowUpPin, OUTPUT);
  pinMode(ElbowDownPin, OUTPUT);

  _ShoulderUpPin = ShoulderUpPin;
  _ShoulderDownPin = ShoulderDownPin;
  _ElbowUpPin = ElbowUpPin;
  _ElbowDownPin = ElbowDownPin;
  //_ShoulderEncoderPinA = ShoulderEncoderPinA;
  //_ShoulderEncoderPinB = ShoulderEncoderPinB;
  //_ElbowEncoderPinA = ElbowEncoderPinA;
 // _ElbowEncoderPinB = ElbowEncoderPinB;
  ElbowEncoder = *ElbowEncoder;
  ShoulderEncoder = *ShoulderEncoder;
  //ElbowEncoder(_ElbowEncoderPinA, _ElbowEncoderPinB);
  //ShoulderEncoder(_ShoulderEncoderPinA, _ShoulderEncoderPinB);
}

void Arm::ShoulderMoveTime(int dir, int speed, int time) {
...
}

void Arm::ElbowMoveTime(int dir, int speed, int time) {
 ...
}

void Arm::ArmMovePosition(int shoulderPos, int elbowPos) {
  int ShoulderinitialPos = ShoulderEncoder.read();
  int ElbowinitialPos = ElbowEncoder.read();

  //TODO:I think this will only move one joint at a time

  //Move shoulder-------------------------------------------------------------------------------------
  if (shoulderPos > ShoulderinitialPos) {  //check to see which direction arm needs to move

    while (shoulderPos > ShoulderEncoder.read()) {  //while the target position is greater than the motor's actual position, move the shoulder up
      digitalWrite(_ShoulderUpPin, HIGH);           //THIS MAY BE REVERSED
    }
    digitalWrite(_ShoulderUpPin, LOW);  //stop the arm from moving up

  } else if (shoulderPos < ShoulderinitialPos) {

    while (shoulderPos < ShoulderEncoder.read()) {
      digitalWrite(_ShoulderDownPin, HIGH);
    }
    digitalWrite(_ShoulderDownPin, LOW);

  } else {
    Serial.print("Error: invalid shoulder target position");
  }

  //Move elbow-------------------------------------------------------------------------------------
  if (elbowPos > ElbowinitialPos) {  //check to see which direction arm needs to move

    while (elbowPos > ElbowEncoder.read()) {  //while the target position is greater than the motor's actual position, move the elbow up
      digitalWrite(_ElbowUpPin, HIGH);        //THIS MAY BE REVERSED
    }
    digitalWrite(_ElbowUpPin, LOW);  //stop the arm from moving up

  } else if (elbowPos < ElbowinitialPos) {

    while (elbowPos < ElbowEncoder.read()) {
      digitalWrite(_ElbowDownPin, HIGH);
    }
    digitalWrite(_ElbowDownPin, LOW);

  } else {
    Serial.print("Error: invalid elbow target position");
  }
}

void Arm::ZeroArm() {
  ShoulderEncoder.write(0);
  ElbowEncoder.write(0);
  Serial.println("Arm has been tared");
}

void Arm::getArmPosition() {
  Serial.print("Shoulder Position: ");
  Serial.print(ShoulderEncoder.read());
  Serial.print("Elbow Position: ");
  Serial.println(ElbowEncoder.read());
}

```

Unfortunately, there appears to be some sort of problem with passing the  Encoder object. I am getting the error:
>Compilation error: no matching function for call to 'Arm::Arm(int, int, int, int, Encoder&, Encoder&)'

I am definitely a noob when it comes to coding, so thanks in advance for what is probably a simple problem.

title: How to pass Encoder object to constructor of a different class

Answers: 1

body:
You're jumping backwards and forwards between pointers and the objects themselves.
Change it to pass pointers to the arm constructor and consistently use pointers (or pass a reference and always use that, just be consistent). This would be something like:

```c++
    // main code, pass a pointer rather than the object itself
    Arm Arm1(ShoulderUP, ShoulderDW, ElbowUP, ElbowDW, &ElbowEncoder, &ShoulderEncoder);

    // header
    public:
      Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder);

    // cpp
    Arm::Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder) {

      pinMode(ShoulderUpPin, OUTPUT);
      pinMode(ShoulderDownPin, OUTPUT);
      pinMode(ElbowUpPin, OUTPUT);
      pinMode(ElbowDownPin, OUTPUT);

      _ShoulderUpPin = ShoulderUpPin;
      _ShoulderDownPin = ShoulderDownPin;
      _ElbowUpPin = ElbowUpPin;
      _ElbowDownPin = ElbowDownPin;
      this.ElbowEncoder = ElbowEncoder; // use 'this.' to indicate the class private variable since it's the same name as the passed parameter.
      this.ShoulderEncoder = ShoulderEncoder;
    }
```
And then within your class, since ElbowEncoder is a pointer rather than the encoder itself, use `ElbowEncoder->method()` rather than `ElbowEncoder.method()`

Personally, I'd restructure it a little. Why create the encoders at the top level when they are only used within the arm class?
Create them in the arm class instead:
```c++
    //in .h
    public:
      Arm(int ShoulderUpPin, int ShoulderDownPin, int ShoulderEncoderPinA,int ShoulderEncoderPinB,
          int ElbowUpPin, int ElbowDownPin, int ElbowEncoderPinA, int ElbowEncoderPinB);

    private:
      Encoder ShoulderEncoder;
      Encoder ElbowEncoder;

    // in .cpp
    Arm::Arm(int ShoulderUpPin, int ShoulderDownPin, int ShoulderEncoderPinA,int ShoulderEncoderPinB,
             int ElbowUpPin, int ElbowDownPin, int ElbowEncoderPinA, int ElbowEncoderPinB) :
                 ShoulderEncoder(ShoulderEncoderPinA,ShoulderEncoderPinB),
                 ElbowEncoder(ElbowEncoderPinA,ElbowEncoderPinB) {
       // constructor code
    }
```
This will create the encoders as private to the arm as soon as you call the arm constructor. Especially handy if you want to have more than one arm.


body:
I'm working on Arduino Kit book's Project 8: the digital hourglass. I've got the picture and the circuit diagram below.

[![picture of the circuit][1]][1]

[![diagram of the circuit][2]][2]

My question is a fundamental one, and I really don't know how others figured it out. The question is: How do I correctly tie a four-pin tilt sensor to the power and to the ground? I've been through a couple of datasheets for the RBS040100 and none of them were particularly helpful in determining which pin is responsible for what. The most helpful anything has got to be is [this pdf sheet][3] where the PCB layout diagram points out an index for every pin and how the pins within the sensor are related, yet it does not explain where the power goes and where the ground is connected.

I also ran into this [Arduino SE page][4] but nobody got close to actually explaining how to use (i.e., correctly integrate) the sensor into the circuit.

I know that if you plug a capacitor in the wrong way, it may explode. By the same token I do not want to screw up the sensor or the board, but what do I know. This is the only tilt sensor I've got.

Before my board goes live, I'd like to confirm whether I have the tilt sensor connected correctly.

[![picture of the tilt sensor currently plugged in][5]][5]

Any help would be appreciated. Let me know if you need anything else for further clarification. Thank you in advance.

Edit: Here's a picture of the four-pin tilt sensor:

[![picture of the tilt switch][6]][6]

  [1]: https://i.stack.imgur.com/t8sDo.jpg
  [2]: https://i.stack.imgur.com/c0DRK.jpg
  [3]: https://docs.rs-online.com/05f0/0900766b8066b85f.pdf
  [4]: https://arduino.stackexchange.com/questions/16517/do-i-need-to-solder-wires-to-my-tilt-sensor
  [5]: https://i.stack.imgur.com/XFyQz.jpg
  [6]: https://i.stack.imgur.com/6Qsm0.jpg

title: Correctly connecting a four-pin tilt sensor to a breadboard before going live

Answers: 3

body:
So [I've asked this question on the Arduino.cc forum][1] (just to get a safe answer quickly to hustle up on the project). If you look at the pins on the four-pin tilt switch with the notch facing down (as shown on the aforementioned RBS040100 datasheet's PCB layout diagram), you need to know that the connected pins 1 and 2 are to be tied to the power and the connected pins 3 and 4 are to be tied to the ground **with a high-Ohm-value resistor (which will serve as a pull-down resistor, e.g. 10kOhm)**. That means that the "up" arrow on my pictures is indeed to face "east" (in relation to the breadboard) if northern pins are power and southern pins are grounded with a resistor. If for some reason you need it pointing "to the west", then the pins on the northern half are to be connected to ground with a good resistor and the pins to the south are to be connected to power.

[![updated power-ground schematic][2]][2]

Edit: Here are the results. Image 1 is for the first take and image 2 is for the second take after a tilt to the switch.

[![take one][3]][3]

[![take two][4]][4]

  [1]: https://forum.arduino.cc/t/correctly-connecting-a-four-pin-tilt-sensor-to-a-breadboard-before-going-live/1102594
  [2]: https://i.stack.imgur.com/b4O9v.png
  [3]: https://i.stack.imgur.com/lvpqr.jpg
  [4]: https://i.stack.imgur.com/ehmau.jpg

body:
Like any switch, this is a passive device. It doesn't require power to operate, in the usual sense - it has no active circuitry. Read it just like a push button. Wire one side to a pullup (or pulldown) and an input pin, and the other side to ground (or to +V). When the input is in it's non-passive state (opposite the state it is being pulled to), the device is tilted. The metal ball inside it just shorts two pins (or not).

The only thing that isn't clear from the data sheet is whether all four device pins are independent so the device could indicate one of four directions of tilt (and therefore needs four input pins); or the pins are internally connected in pairs, and only one direction of tilt can be indicated (with a single input pin). A quick experiment should resolve that.

A search for 'tilt sensor' yields a page on arduino.cc relating to tilt sensors and apparently refers to the latter type (one direction of tilt, one input pin). The remaining question is whether your sensor is of the same type.

body:
A tilt switch is just a switch and doesn't need to be powered per se. You just need to detect when it is open or closed, like any other mechanical switch. I have a page about switches: http://www.gammon.com.au/switches

In brief, you can wire a switch with a pull-down resistor as you appear to have done in the end:

[![Pull-down resistor][1]][1]

In this configuration the input pin will be 0V (LOW) when the switch is open and 5V (HIGH) when it is closed.

---

Or, you can wire it with a pull-up resistor:

[![Pull-up resistor][2]][2]

In this configuration the input pin will be 5V (HIGH) when the switch is open and 0V (LOW) when it is closed.

---

Or, you can use the internal pull-up of the processor and wire it like this:

[![Internal pull-up][3]][3]

In this configuration the input pin will be 5V (HIGH) when the switch is open and 0V (LOW) when it is closed.

In this case your code might be:

    const byte switchPin = 8;

    void setup ()
      {
      Serial.begin (115200);
      pinMode (switchPin, INPUT_PULLUP);
      }  // end of setup

    void loop ()
      {
      if (digitalRead (switchPin) == LOW)
         {
         Serial.println ("Switch closed.");
         delay (1000);
         } // end if switchState is LOW

      // other code here ...

      }  // end of loop

---

Your switch appears to have 4 pins rather than two. Maybe they work in different planes (eg. tilting left/right for one and up/down for the other) or maybe they work at different angles of tilt. A quick check with a multimeter should confirm that.

  [1]: https://i.stack.imgur.com/lbVOZ.png
  [2]: https://i.stack.imgur.com/4YTpZ.png
  [3]: https://i.stack.imgur.com/kmRT4.png


body:
I am working on using an ov7670 camera module with arduino uno,capturing the image frame wise and transmitting the image serially line by line of each frame to python for image processing, however i am getting very distorted images once is use the serial.write() command,how do i send the bytes without using serial.write().

[This is the link i used for setting up the Ov7670][1]

  [1]: https://circuitjournal.com/arduino-OV7670-to-pc

title: Sending an image captured using ov7670 using arduino and serially transmit it to python

Answers: 0


body:
Just starting with external EEPROM and ATTiny's.  I am successfully writing and reading to the 24LC64 chip using the following code with TinyWireM (thanks to other help on the forums). However, I really need to store integers up to 8500.
I'm assuming I need to store the number as 2 bytes and reassemble them when needed, just dont have the knowledge yet to do so.  Any help is truly appreciated...

        //------------------I2C EEPROM-----------------------
    void writeAddress(int address, int val)
    {
      TinyWireM.beginTransmission(EEPROM_I2C_ADDRESS);
      TinyWireM.send(address >> 8);   // MSB
      TinyWireM.send(address & 0xFF); // LSB
      TinyWireM.send(val);
      TinyWireM.endTransmission();
      delay(10);
    }

    byte readAddress(int address)
    {
      byte rdata = 0xFF;

      TinyWireM.beginTransmission(EEPROM_I2C_ADDRESS);
      TinyWireM.send(address >> 8);   // MSB
      TinyWireM.send(address & 0xFF); // LSB
      TinyWireM.endTransmission();
      TinyWireM.requestFrom(EEPROM_I2C_ADDRESS, 2);

     if (TinyWireM.available())
      {
        rdata = TinyWireM.receive();
      }
      return rdata;
    }

title: Attiny84 with external eeprom-write and read beyond 255

Answers: 0