text:
Change Interrupts on the ATTiny 88
I am working on a project that requires a number of I/O pins for various purposes.  I chose the ATTiny88 because it has plenty of GPIO pins, and is relatively inexpensive.
Here is the updated code per timemage, with many thanks!
#include <Arduino.h>
#include <TM1637Display.h>
#include "PinChangeInterrupt.h"

int counter = 0;
bool Update = false;
int currentStatePhase_B;
int lastStatePhase_B;

// Shutdown Output
#define SW 11

// Rotary Encoder Inputs
#define Phase_A 13
#define Phase_B 12
#define DIO 3
#define CLK 4

TM1637Display display(CLK, DIO);

void setup() {

  // Set encoder pins as inputs
  pinMode(Phase_A,INPUT);
  pinMode(Phase_B,INPUT);
  pinMode(SW, OUTPUT);

    // Read the initial state of Phase_B
    lastStatePhase_B = digitalRead(Phase_B);

    // Call updateEncoder() when any high/low changed seen
    // on interrupt 0 (pin 2), or interrupt 1 (pin 3)
    attachPCINT(digitalPinToPCINT(Phase_A), updateEncoder, CHANGE);
    attachPCINT(digitalPinToPCINT(Phase_B), updateEncoder, CHANGE);

  display.setBrightness(0x0f);
  display.clear();
}

void loop() {
  delay(100);
    if (Update){
        // Show decimal numbers with/without leading zeros
    display.showNumberDec(counter, false);
    // Expect: ___0
        Update = false;
    }
}

void updateEncoder(){
  delay (4);
    // Read the current state of Phase_B
    currentStatePhase_B = digitalRead(Phase_B);

    // If last and current state of Phase_B are different, then pulse occurred
    // React to only 1 state change to avoid double count
    if (currentStatePhase_B != lastStatePhase_B  && currentStatePhase_B == 1){

        // If the Phase_A state is different than the Phase_B state then
        // the encoder is rotating CCW so decrement
        if (digitalRead(Phase_A) != currentStatePhase_B) {
            counter --;
        } else {
            // Encoder is rotating CW so increment
            counter ++;
        }

    if (counter > 1023){
      counter = 1023;
    }
    if (counter < 0){
      counter = 0;
    }
    delay(15);
    }

    // Remember last CLK state
    lastStatePhase_B = currentStatePhase_B;
    Update = true;
}

It is now capturing most, but not by any means all, interrupts, but the direction is highly unreliable.  More often than not, it counts up regardless of which way the encoder is turned,and often counts down when the encoder is turned clockwise.
Here is what seems to be a good reference:
ATtiny88 8-bit Microcontroller

forget about your code for now ... make sure that the interrupt actually works ... write a simple program that has one ISR (interrupt service routine) ... the ISR triggers when a pushbutton is pressed, and alternates the status of an LED at every press

you're overthinking the encoder program ... trigger on one channel only ... the state of the other channel indicates the direction of rotation

Here is what seems to be the best reference ... no, the manufacturer's website is the source of the best reference  not some 3rd party site ... look at page 53 in https://ww1.microchip.com/downloads/en/DeviceDoc/doc8008.pdf

more info https://onlinedocs.microchip.com/pr/GUID-19759098-FF73-4B52-AA3D-E651C849337D-en-US-2/index.html?GUID-EC4CAB0F-FADE-433B-8381-0866ED41CF64

Re “updated code per Edgar Bonet”: you mean “per timemage”. 2. Since updateEncoder() only cares about changes in Phase_B, there is no point in calling it when Phase_A changes. 3. Never delay() in interrupt context! 4. If you make counter unsigned, you won't need to clamp its value, and it will always be correct modulo UINT_MAX.

2′. Since updateEncoder() only cares about the rising edges of Phase_B (i.e. when it changes from 0 to 1), there is no point in calling it on the falling edges. Attach the interrupt on RISING events and remove the test on currentStatePhase_B and lastStatePhase_B (and remove those variables also).

I certainly understand delays in ISR routines are not  great idea, and this one was not my idea.  One of the references suggested putting in a brief delay to debounce the encoder.  If I only call updateEncoder() on the rising edge of B, then the code will miss a CCW turn, right, because B is already high and remains high?  I am going to start a new thread, because the original question is effectively answered

I am going to use UINT8_T.  An 8 bit data space is good enough for this purpose.  I will just double the value of counter when I output the voltage.

Wait, that will not work.  Using something like UINT8_T or indeed anything that rolls over will not work.  The counter must not only be restrained to positive integers between 0 and 1024, it must ignore any input that would cause the counter to roll over at 0 or 1024.  Instead, it should just stop counting in that direction.

If you needed an example of what I'd said (and a fair bit of dishonestly on the part of a mod) notice the messages are gone.

Interrupt types

One source says there are only two interrupt pins, ...

There are  two "external interrupt" pins; that is the term you'll find in the chip's datasheet. This is the term that refers to the kind of pins that attachInterupt uses. These are the ones in the pinout labeled INT0,INT1,INTn. The "external" term may be confusing for a couple of reasons. Lots of external things cause interrupts, but this name is applied to when you're not talking about events tied to particular peripherals, like USART (serial peripheral) receiving a character. The special function of "external interrupt" is dedicated to dispatching interrupts based on signals on these INT0/INT1/INT# pins. There's one interrupt vector for each of these signals (two in your case). As you've probably seen in the documentation they can be configured to trigger on rising or falling edges, both edges, and low levels.
So, they're right about that to the extent that they're talking about the "external interrupt" pins.
The "external" name is also confusing because of what else you've found:

Another source says there are quite a few Change Interrupt pins

This is also true. These are the "PCINT#" signal names listed in the chip pinout.  These "pin change interrupts" are newer; not new, but newer. There exist(ed) AVR that had/have "external interrupts" but no "pin change interrupts". I'd like  to think that if they were created at the same time they wouldn't have simply called the former ones "external", because these are no less external although they're less dedicated. There's only a single ISR/interrupt for each group of 8 PCINT pins. And unlike the others they only naturally detect that a pin has changed and nothing about the nature of that change (rising vs falling). But a lot of AVR support them and those that do have a significant number of them. In the case of your ATTiny88, all of the GPIO (Arduino "digital") pins are capable of dispatching a pin change interrupt.  However, the Arduino AVR core doesn't provide a function for using them.
Modifying NicoHood's PinChangeInterrupt library
One of the people that used to be in my circle was NicoHood, who created this PinChangeInterrupt library. I have a foggy memory of helping with bits of it.
What he did was model it after the normal attachInterrupt function. So, you can use it almost as though you have the RISING/FALLING/CHANGE "external interrupt" capability on all of your PCINT# pins; in your case all of your pins. Underneath it is tracking the state of each port pin to determine what has changed and in what direction. In other words, using an interrupt that fires given a change on any of 8 pins together with variables to synthesize per-pin callbacks for not just change but also specifically rising and falling if you want. This is not perfect it is possible to lose short lived events and it takes longer to dispatch your handler function. But it's probably fine for what you're doing.
It does not support your chip out of the box. However you can modify to support the ATTiny88; partially if you're not picky. You should find it in the library manager as "PinChangeInterrupt" by NicoHood, currently at version 1.2.9. If you install that it should show up under your sketchbook/libraries directory. You will need to edit the file at path:
<sketchbook-directory>/libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h
That's your local copy of this file.
Your ATTiny88's handling of PCINT is going to be nearly the same as the ATMega328P that's in the UNO. Or rather nearly a superset of it. The chips are closely related in a way.
However, you have extra PCINT capable pins on the ATTiny88 that aren't available on the ATMega328P. So you can crudely hack in a line into this section to read:
#if defined(__AVR_ATmega328__) || defined(__AVR_ATmega328A__) || defined(__AVR_ATmega328PA__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) \
   || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PB__) \
   || defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) \
   || defined(__AVR_ATtiny88__) \
   || defined(__AVR_ATmega48__) || defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PB__)

The addition of that second to last line above should make the library treat the ATTiny88 you have as though it were an ATMega328P. This compiles under ATTinyCore. I am not set up to test it on a real ATTiny88. But, I expect it will work if you try some examples.
Having done that, the library should be work on any of the pins that carry a PCINT0 through PCINT23 label.  If you want it to work with PCINT24-PCINT27, that can be done, but requires more work. But given what you've said you probably don't need one of those four and they're not available on the DIP package which I'm guessing you have anyway.
Updating your code
You would to #include "PinChangeInterrupt.h" at the top of your code, and then your current code:
    attachInterrupt(digitalPinToInterrupt(Phase_A), updateEncoder, CHANGE);
    attachInterrupt(digitalPinToInterrupt(Phase_B), updateEncoder, CHANGE);

then becomes:
    attachPCINT(digitalPinToPCINT(Phase_A), updateEncoder, CHANGE);
    attachPCINT(digitalPinToPCINT(Phase_B), updateEncoder, CHANGE);

With luck, that should do it provided Phase_A and Phase_B under your core (e.g. ATTinyCore) map to GPIO/Arduino "digital" pins that carry a PCINT# signal where the number less than 24.
As I said, I have no way of testing it on real hardware right now. But I expect it will work. If not, it is the sort of direction you need to go in.
Doing PCINT yourself
You can also take a more direct approach with reading the datasheet and sorting out how to do what the library does for you, only manually. One of the examples NicoHood provided with the library is not really an example of using the library but rather an explanation as to what the library does in the form of code. Notice it doesn't actually include the library; it would operate stand alone. So if you want to understand the guts yourself by following the ATtiny88 datasheet, that's a place to start.
One reason you might want to do it yourself anyway is if your encoders are being operated quickly, to the point where you can't afford some of the extra effective dispatch time imposed by what the PinChangeInterrupt library is doing in sorting out which pin changed and how. If you handle PCINT yourself, you can make a point of putting your two encoder pins in completely different groups of 8 such that there is only one source of pin change interrupt for each ISR and so there is no need to check which pin caused the interrupt and to route that to another function.

+1, very nice answer. Just a small correction: “they can be configured to trigger on rising or falling edges or at high and low levels”. They can be configured to trigger on change (like PCINT), rise, fall or low, but not on high level.

You're right. Brain on autopilot I guess. Will update it either on next natural edit or with in a couple of days if I have no other cause.

Well, I guess I'm going to integrate your change now, because they haven't given an indication on a change and this is likely going to by my last post.

I am sorry, I don't quite follow the conversation between the two of you.

Meanwhile, the code is close to working.  At least the interrupts are now occurring.  They frequently get missed, however, and they are counting erratically.  Instead of counting up when the encoder turns clockwise and down when it is turned counter-clockwise, more often than not iot counts up regardless of which way the encoder is turned, and occasionally it counts down regardless oif which way the encoder is turned.  I am unsure what is causing this behavior.

It's not important to your use case. As you found I tiered the explanation so you (or anyone else) could take the answer at whatever level they needed. Edgar Bonet pointed out a thinko I'd made in acknowledging/describing your findings about different counts of pins being described as capable of interrupts. For those that care and are going to follow that part, it only makes sense that it is also correct. And so it was corrected


text:
How to prevent the application code from getting stuck in forever loop when using SerialFlash library in Arduino-Adafruit framework
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.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
SD card breakout sometimes does not initialise (SPI connection - Teensy 3.2)
I have connected this Adafruit SD Breakout 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

What happens if you eject, then re-insert the SD card while it is stuck in the "SD initialization failed." while loop?

It depends. Once when I did it, the setup completed fine and the SD card was functional after that. Another time it just continued in the "SD initialization failed" loop. And then another time still, the setup completed fine but then the error popped up "error opening datalog.txt".
I have been noticing a pattern where whenever I get the "error opening datalog.txt" error, on subsequent resets the "SD initialization failed" error is more prevalent.

Try ejecting the SD card, then re-inserting it, then reboot the Arduino. Let me know what happens when you do those 3 steps in that order.

Then it immediately goes back into the "SD initialization failed" loop :L

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How to burn fuses in Digistump ATTiny85 with the Arduino IDE
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.

Which version of the IDE are you using, on what operating system?

Windows 11, IDE 2.0.4

To answer this well someone would need to to know which exact thing called "digispark" you have. The official one and various clones do different things with the reset pin and its configuration. It may also matter whether or not it is a "Pro" variant.

You can't change the fuses without using an ISP programmer (an Arduino or even another digispark can be configured as such). However, if the reset pin of the ATtiny85 has been disabled, you will first need a high voltage programmer to reset the ATtiny85 to its factory condition. See: http://digistump.com/wiki/digispark/tutorials/programming . With the ISP programmer connected, you can use AVRDUDE also to set the fuses. The last post here http://digistump.com/board/index.php/topic,2257.msg10556.html#msg10556 implies that 2.7v brown out is anyway already enabled.

Thank you very much!

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

Basically you're saying I should use ISP instead of using the advantage of the Digistump USB driver. Thanks, that's an answer!

Yes, but only for the one-time operation of configuring the fuses. Once that is done, you can revert to the USB method for uploading code.


text:
how to convert a line of code for arduino to receive a value
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.

}

Please show us a complete code, not only snippets. Where are those functions defined?

i removed the second int for data_rcvd and the code compiled but did not turn on the LED

not sure if it matters but im using an attiny412

Your code doesn't contain any calls to fdserial_rxChar() or similar. So what is your actual problem? You eon't get good answers if you don't ask an understandable and complete question

im sending the value 1500 ... what does that mean? ... are you sending a integer? ... are you sending text? ... something other?

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: How does serial communications work on the Arduino?
Also my post about serial data on my forum has code for buffering incoming serial data and waiting for a newline.

thanks for your Help Nick, you steered me towards finding my answer. is there a way to get arduino to pause/wait until it receives a specific value such as 129/0x81 ? kinda like a way to sync things up?

@benjaminnikkel The simplest solution is what I suggested in my answer. Send a "line" of data including a newline at the end. The newline will separate each reading from the next. Instead of transmitting the low-order and high-order bytes, just do a sprintf into a buffer, turning the number into ASCII characters, and add a newline to the end. The Arduino can read a line of data. For tips see my post about reading serial data. However the link on my own forum has better information about reading lines of data.

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


text:
Controlling a servo without the servo library
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?

analogWrite() is not suitable for driving servos. What is your issue with the Servo library?

I dont know the necessary frequency of that signal ... it is not the frequency that is critical ... it is the pulse width that is critical

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.


text:
ESP8266 not sending text message to telegram bot
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);
}

what about the message Bot started up? ... why did you not say anything about that?


text:
Checking a thing about interrupts
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.

your question is not about Arduino ... it is a general question about the AVR microcontroller ...  better fit at https://electronics.stackexchange.com/questions

Thanks, it seems that I made the same mistake as before, I thought that noInterrupts and interrupts would justify it.

@jsotola this is a reasonable question - otherwise you could hive off almost all questions about Arduino saying they are about AVR microcontrollers.

See How do interrupts work on the Arduino Uno and similar boards?
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.

Note that each interrupt has a single 'interrupt occurred' bit, so that if a particular interrupt fires multiple times during the CLI-SEI window, it will only be serviced once outside the window.  So the handler has to check all possible triggers...

@user10489 Can you elaborate on what you mean by "all possible triggers?". The interrupt bit will be set only once in that window. Once it is set it can't be "double set". It is important for ISRs to handle their respective interrupts quickly, so as not to unnecessarily delay the processing of other interrupts.

Right.  If an interrupt is multiple triggered but only fires once, your handler will only be called once, but might have to handle all the things that would have caused it to fire.  For example, if you have an interrupt for characters received by the uart, you might end up reading multiple characters.

Yes, in that case, the UART has a (small) buffer so reading until it is empty would be advisable.

As a note to somebody who might find this useful, it seems that the interrupts flags are those force bits, like the force compare A and B in the timer registers.


text:
AA alkaline batteries on firebeetle?
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

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, you should be able to connect an external power supply between VCC(+) and GND(-).

The voltage regulator on the FireBeetle ESP32 is a low-dropout RT9080 regulator, which, according to its datasheet 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.

Does your program expect a Serial port connection which, of course, is not available when it's not connected to a PC by USB?
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.

Before trying to measure the 3.3v coming out of the regulator, it might be good to measure the voltage at the output terminals of your battery pack as well...

Sorry, this appears to be a PEBCAK issue, the boards actually runs fine, i just came to the wrong conclusion because the board did not behave like i expected.


text:
Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500 Firmware updater
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.

https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/updating-firmware

did you notice "If you are using a Feather M0 or WINC1500 breakout, don't forget to update the pins as necessary with setPins()!"?

In the picture above, partially obscured by the board selection dialog, the WiFI.setPins(8,7,4,2); line can partially be seen.  I believe the message above 'No supported board connected', seems more to do with the Adafruit Feather M0 being selected than the pin configuration.

try it with older version of the fw updater, before they added update for the NINA fw and board selection


text:
How to set SIM800L to save messages to memory and reading them
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?


text:
Wake-UP the ATtiniy44 from sleep_mode_pwr_down with a PushButton
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();
    }
}

When you press the button , the chances are high that, the interrupt is deactivated. You attach the interupt in the setup routine but then detach it with the first
"loop" run. Without an active interrupt and after the first button press the MCU sleeps and pressing the button again does nothing.

So you think I should attach interrupt somewhere else ?

attachInterrupt(digitalPinToInterrupt(10), cannot be fully understood without knowing which configuration of which board core you are using.

I'm using attiny44a mcu and button pin is attached to PB0 pin

That isn't exactly what I asked, but it is relevant information to a correct answer which you should edit into your question.

I wrote Attiny44 in my thread title, I should also insert in the text of question?

"attiny44" is not "which configuration of which board core you are using". You can at least include "PB0" in your question so someone (not me) can explain to you why attachInterrupt simply won't work with that pin. And why it won't wake with that pin.

According to the datasheet external interrupt are triggered by any pin PCINT[11:0] so i think PB0 is ok for attachInterrupt

I understand your confusion. But, that is not the case. attachInterrupt works with INT# not PCINT#. These are different things. Importantly none of the PCINT will wake your chip from powerdown.

ok so the new code will never work, I have to redesign completely.....

And for the button pin i have to use PB2 that according datasheet have INT0

Alright, so I've found another datasheet and this one did mark PCINT as a wake-up source in the table, not just in the statement elsewhere in the sheet. To confirm this isn't just an error, I set up a T44A with CKOUT fuse enabled, verified that stops outputting clock in powerdown mode sleep. Configured PCINT and triggered it with a button and it did wake and resume CKOUT production. So at least with at T44A it's verified to wake with PCINT. The part regarding PCINT and attachInterrupt stands; so you'd need to integrate NicoHood's library for that part.

Yes I've used his library and with PB0 seems working for power down

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.

Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed.


text:
The gateway is not working in Arduino EthernetENC
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 ////////////////////////////////////
  ...
  ////////////////////////////////////////////////////////////////////////////////
}

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.

I am using a corporate network, not the internet, where I ping my device through a monitoring system. Many other devices work on the same principle in this corporate network. Therefore, all I need is for Arduino to properly route packets to the gateway.

I think this answer is correct.  You have to use the external ip address and perhaps set up port forwarding to your server.


text:
Does Arduino Zero need to be switched between USB EDBG and JTAG port debug use?
I wanted to compare the debug output of the Arduino Zero when connecting via two different debug paths.

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

The two paths being compared are shown on the Zero Schematic:

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)

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. It connects to a pin on the Atmel EDBG chip (IC3).

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

I’ve been trying out Chat GPT-4. Here’s what it has to say about the error message:
…There could be several reasons why the JTAG device scan failed. Some possible reasons include a faulty connection between the test probe and the target device, incorrect configuration settings in the test probe, or an issue with the JTAG interface of the target device.
… you could try checking the connections between the test probe and the target device, verifying that the test probe is configured correctly, and ensuring that the JTAG interface of the target device is functioning properly…

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

J301 (CN1) is for programming the EDBG chip.

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

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:

Bottom View:

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.

https://content.arduino.cc/assets/Pinout-ZERO_latest.pdf

Thanks Juraj. That newer pin out is more clearly labeled. I’m still not convinced by the reported +3v3 at J100. I’ll add some microscope photos so you can see what I mean.

Re: This is a two layer PCB? No it's not as it turns out. Note the green traces in the photo above. Assumption is that J100 (CN2) VREF is making its connection to +3V3 on the middle layer and it's been missed out of the PCB layout diagram.


text:
MAX30102 doesnt show data when it's interfacing with other sensors MLX90614 and MPU6050
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

-----------------------------------------------------------------

what do you want to know? ... please add a clear, answerable question to your post

if you want to know where to start debugging, then start by running an I2C scanner sketch

is Blynk somehow involved in the problem?

@Juraj blynk is not the issue in this.

try to create a minimal reproducible example

@Juraj what is a reproducible example

https://en.wikipedia.org/wiki/Minimal_reproducible_example

@jsotola i used it and got this
Scanning...
I2C device found at address 0x57
I2C device found at address 0x5A
I2C device found at address 0x68
done


text:
Why is Arduino not visible in MacOS USB port list?
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.

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!

This is a common issue with several Q+As already in the system. https://arduino.stackexchange.com/a/19856/37523

Yes, I looked at the others and they were either locked for further addition, or not quite appropriate.


text:
How to pass Encoder object to constructor of a different class
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:
#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:
#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:
#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.

What happens when you pass the Encoder object as pointer via &ElbowEncoder?

I get "Compilation error: no match for 'operator=' (operand types are 'Encoder' and 'Encoder*')"

please copy all of the error message and paste it into your question ... do not put it into a comment like you just did ... also, no pictures of text ... format the text as code

you can use reference. member and parameter as Encoder& type and in constructor initialization list you set the value of the member from the value of the parameter. MyClass::MyClass(Encoder& _encoder) : encoder(_encoder) {}

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


text:
Correctly connecting a four-pin tilt sensor to a breadboard before going live
I'm working on Arduino Kit book's Project 8: the digital hourglass. I've got the picture and the circuit diagram below.

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

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:

the tilt sensor us most likely  mechanical switch ... find two pins that open and close the circuit when the switch is moved ... connect it between a data pin and ground ... enable the pullup resistor on the data pin

@jsotola : This doesn't quite hit the core of the OP. At the crux of it is my ignorance of which pin is power and which is ground. Also, it is unclear to me whether there is a data pin, which is new information to me. According to the datasheet for the RBS040100, there is only a connection for the power and a connection for the ground. Nothing related to any kind of data.

there is no power and ground connection... it's just two wires that get shorted together by a metal ball ... connect it same as a pushbutton switch ... there are many tutorials about connecting switches to an arduino

hold one wire in you left hand ... hold another wire in your right hand ... touch the ends of the wires together ... that is the exact same circuit as the tilt switch

@jsotola : Then how can any switch possibly yield an "on" signal without power and ground? No power and ground, no current. No switch output of 1 to be read, right?

So I've asked this question on the Arduino.cc forum (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.

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.

if you connect one pin to power and the other to ground, then you will short circuit the power supply when the switch closes

@jsotola : I'm not sure if a short circuit would be possible considering that I have a 10kOhm resistor channeling the tilt sensor to the ground.

then that side of the switch is not connected to ground ... it's connected to an input pin and to a pulldown resistor on one side and to V+ on the other side

@jsotola : Then what is the 10kOhm resistor even for in the first place? Because my experiments guided by the book's instructions (see the images of the results in the edit section of my answer) show something different from what you are suggesting.

the schematic diagram in your post shows a pull-down resistor ... research pull-up and pull-down resistors ... the resistor prevents the arduino input pin from floating when the switch is open ... a floating pin would have an undefined state

@jsotola : So it is my understanding that the high resistance would make my resistor a pull-down to keep the voltage/current from getting too hot because otherwise that would make the input from the switch unreadable somehow (i.e., we can't get a good reading of the input). Did I get it right?

an understanding that short-circuiting a power supply is a bad thing should supercede

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.

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:

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:

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:

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.


text:
Sending an image captured using ov7670 using arduino and serially transmit it to python
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

You didn't show your code, nor a sample of a distorted image, nor your python code. What exactly makes you think, that Serial.write() is the problem here?


text:
Attiny84 with external eeprom-write and read beyond 255
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;
}

You are already sending a 2-byte memory address to the EEPROM. It should work to do the same operations with the value to save. Research about the bitwise operators, especially the shift operator >>, the AND operator & and the OR operator |.

Thats the frustrating part of it.  I totally get that and I actually now am able to send the two bytes to the two registers.  I just cant figure out the TinyWireM syntax to read the values from the 2nd address.  I'm looking for a way to tell ask for the data in (address + 1 & 0xFF) and I keep getting the data from the only the first address.

@VinnyP this site is not a forum ... all of what you said in a comment belongs in the question at the top of this page ... please edit your question and then delete the comment

You asked for two bytes of data with TinyWireM.requestFrom(EEPROM_I2C_ADDRESS, 2);, but your function and your rdata is a byte instead of an int, and you only get one byte with TinyWireM.receive();.