text:
Can we generate 20kHz tone with normal buzzer in arduino?
Can normal buzzer be used for generating high frequency audio and if this is possible then can normal microphone module be able to detect the same frequency range(15 kHz - 20 kHz).
Here is the specifications of this buzzer:-
Rated Voltage : 6V DC
Operating Voltage : 4 to 8V DC
Rated Current* : ≤30mA
Sound Output at 10cm* : ≥85dB
Resonant Frequency : 2300 ±300Hz
Tone : Continuous
Operating Temperature : -25°C to +80°C
Storage Temperature : -30°C to +85°C
Weight : 2g
*Value applying at rated voltage (DC)

That depends entirely on the response range of the transducers in question. Read the datasheets.

I am asking about cheap piezo buzzer

@astrick Please provide more information. For example a link to the product. Do you have just the piezo itself? We cannot really say much without knowing the product. Otherwise you would need to just test it. "Normal" microphones should also have a statement about the frequency range in their documentation. Otherwise again you would need to test yourself.

Piezo transducers have a resonant frequency, specified in the datasheet.

@Majenko this is having resonant frequency of 2300. Can it transmit more than that?

Only at very low efficiency, i.e, very quietly.

@astrick Are you sure, that this is a passive buzzer (which is directly driven by an AC signal)? The "Rated voltage: 6V DC" suggest, that it already sounds, when you apply just the 6V DC. That would mean, that it is an active buzzer, which creates the sound frequency itself. You cannot drive such a buzzer with your own frequency. You can test this, if you connect it to the 5V of the Arduino. It it sounds continuously in that case, it is an active buzzer

@chrisl Thanks for sharing this information. So that means I need to purchase a passive buzzer?

For 20kHz you need to buy a piezo transducer with a 20kHz resonant frequency.

What exactly is it you are trying to achieve?

@Majenko I want to transmit 20kHz sound and then receive it using microphone

No, that's what you think to want to do. Not what you want to achieve. Why do you want to transmit and receive 20kHz sound?

@Majenko Communication between 2 devices which we cannot hear

@astrick Then you want a pair of matched ultrasonic transducers, an amplifier / driver circuit and modulator circuit, and a band-pass filter / demodulator circuit. Not a speaker and a microphone.

An arduino is very well capable of producing a 20KHz signal. You can use a PWM signal on one of the PWM pins, generate the signal by alternating a pin high and low with a few microseconds in between or you can use a buzzer with an input signal that can play a continuous tone at a specified frequency. I really can't see if the module you show can generate a tone based on the input.
Detecting a tone, however is somewhat difficult. You need an analog microphone amplifier, an ADC (analog-to-digital-converter) and some processing to detect a frequency in the signal data.
The usual microphone modules that are sold for arduino's are mostly just noise detectors and generate a signal when loud noise is present.

Note that the PWM frequencies on the UNO are only 490 or 980 Hz, so the normal digitalWrite() approach won't work. If you are going to "roll your own" PWM as suggested, you can use any output.  The built-in ADC will work fine, but it uses 0-5 VDC range.  You can make a simple circuit to convert an amplified AC signal to this range. See https://www.daqarta.com/dw_rrll.htm

thanks Boggy, I completely missed the internal ADC. Because of the way that the ADC probably works internally, I doubt that you can sample this at more than 10kHz. We need at least 40 kHz to detect a 20kHz signal.

Hacky, the DaquinOscope that I mentioned can do burst sampling (1024 samples) at over 1 MHz for single-channel and over 47 kHz for 2 channels at 8 bits, and only slightly slower for 10 bits.  But you are correct if you are talking about interrupt-driven sampling, which tops out around 30 kHz.

As others have noted, the frequency range of the buzzer is given in the data sheet.  This is a mechanical property, like the tone of a bell; you can't change it electrically.  So if you really need to generate high frequency audio, you need a different type of device.  Something like a speaker whose output is controlled by its input signal.  You don't mention what you are planning on using this for, which might make a difference in your options.  There are inexpensive piezo tweeters that work in this range, but they typically have very ragged frequency responses.  Actually, most transducers in this range do, but dynamic types tend to be better, though more expensive and less efficient.
If you want to generate controllable high frequencies with Arduino, you might want to look at my open-source DaqPort sketch.  This is intended to be controlled by a computer over USB and includes data acquisition as well as generation, but the oscillator portion can run as a stand-alone.  The sketch is included with my Daqarta software, which is free for Arduino use.  Daqarta includes the Arduino_Oscillators mini-app, which is described here: https://www.daqarta.com/dw_rrss.htm   The oscillators are also used by the DaquinOscope mini-app https://www.daqarta.com/dw_rrss.htm which does simultaneous acquisition, but it uses the computer for display so it's not stand-alone.
Microphones should not be a problem; many inexpensive electrets can handle this range.  But we really need to know more about your plans.

Can I use this microphone for this ?

Astrick, I can't tell from those specs, which talk only about the preamp bandwidth and not the mic itself.  The photo shows a mic on the board, but never mentions it at all.  If you buy this and it won't go as high as you need, you might be able to replace the mic capsule.  You can get these at places like Digi-Key.  Make sure you get omnidirectional for the flattest response; directional mics have terrible responses.


text:
Arduino Pro micro Serial communication problem with Node MCU
I recently bought an ATmega32U4 based Arduino Pro micro. I am using the Keyboard library and interfacing with my PC via USB.
I am trying to create a serial communication between the Arduino Pro micro and a NodeMCU via Rx, Tx pins (0, 1), but it isn't working i.e. not giving any output with the code below on the Pro micro:
#include <Keyboard.h>

int incomingByte;
unsigned long lastTime;

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

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

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

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

On the NodeMCU there is a simple script flashed which only writes on serial some characters in a delayed loop.
When using the SoftwareSerial library with the Pro micro, it is working fine i.e. I can read data sent by the NodeMCU on custom Rx, Tx pins (9, 10). I tried this because I thought since Pro micro is communicating with a PC, the original Rx and Tx pins are busy. But after some research I got to know that unlike other Arduino boards like the UNO, the Pro micro doesn't use those for communication over USB.
Although custom serial using SoftwareSerial library is working, it is too slow and unreliable i.e. it takes 2-3 seconds to pass a string of length 10. Also its unreliable because on sending bigger length strings, the strings arrive incomplete or sometimes the data gets corrupted (characters shuffle).
Again this is not my main concern, if I can use original Rx, Tx pins as usual on any other Arduino boards, it solves my issue.
This is my circuit diagram:

The problem is your janky serial reading method. You're assuming there's data to read when there isn't. Read this: https://majenko.co.uk/blog/reading-serial-arduino

I probably missed something but: why are you using SoftwareSerial on the pro micro at all?

@timemage Yes, you missed that. He explained why - he assumed pins 0/1 were taken with the USB, then found out otherwise, and now is attempting to use those with Serial instead of SoftwareSerial.

The Serial device is usually the USB serial connection, whether or not that is controlled by pins 0/1. For pins 0/1 with a native USB connection you need to use Serial1. I think. It's been a while since I used an Arduino with native USB...

I'm not confused about how Serial and Serial1 work on the 32u4 based Arduinos.  I don't see any indication that anything other than SoftwareSerial is being used.

@Majenko thanks, replacing Serial with Serial1 worked out for me.

RX and TX pin of Arduino Micro are Serial1. Replace Serial in your sketch with Serial1 to communicate with esp8266 over RX and TX pin.

Luckily I found out that last night and that worked too. Thanks for your inputs @Juraj.
The Rx and Tx (0 and 1) pins on Arduino Pro Micro are defined with Serial1 so replacing Serial with Serial1 worked out for me. Thanks to all for your interest.

source: Stack Exchange

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

sort: votes


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

There don't seem to be such a library for that specific chip. At least I found none when googling for it. You might need to write the code yourself.

You don't really need a library for that chip. You just do a pair of SPI transfers with the CS pin low.
For example:
digitalWrite(pinCS, LOW);
uint8_t msb = SPI.transfer(0xFF);
uint8_t lsb = SPI.transfer(0xFF);
digitalWrite(pinCS, HIGH);

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

Thanks for your answer, I was checking the datasheet and looking at the code that you provide, the digitalWrite(pinCS, LOW)... until the digitalWrite(pinCS, HIGH), it neglects the timing aspect. I mean the datasheet provides some timing for acquisition and conversion so, should I have to worry about that timing?

T_CNV is at worst 1300ns. That's only 20 clock cycles on a 16MHz Arduino. By the time you get round to sampling again that time will have passed. The T_EN is a mere 10ns. That's a sixth of the length of one clock cycle. You would have to be doing something really bizarre with your Arduino to even come remotely close to needing to even think about the possibility of timing being an issue.

Thanks for sharing.

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


text:
Watchdog timer/deep sleep loop for Atmega 328 Pro Mini 5v 16 mhz
I have been struggling to get my Adafruit 5v pro mini to loop in deep sleep mode several times, then awake to perform something then return to the deep sleep mode loop. While it is out of deep sleep mode I want the watchdog timer to be active to protect against system hangups. Although I can get in and out of deep sleep mode easy enough, and I can also use a loop that performs one deep sleep/awake cycle. I want to maximize the power savings by having a prolonged deep sleep period of several minutes. I have read many posts related to this subject, but have not yet found a response works for me.  Attached is my code, which loops through the sleep cycle twice, but not if ISR(WDT_vect) on row 85 calls my hardwareReset() function. If my call to hardwareReset is used, my test loop on rows 25-30 times out as expected, but my waitSleep function no longer loops twice. Can anyone please offer guidance? Many thanks
// thanks to KeyChainino for basic code. I added ADC disable to further reduce power from 0.67mA to 0.54mA
//
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
const int ledPin = 13;
const int resetPin = 9;

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

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

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

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

void watchdogSetup() {

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

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

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

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

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

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

I'm not exactly sure what the problem is. I feel like your not fully understanding how the wachdog timer works, in conjunction with the ISR, but I may be wrong. Your loop to force timeout is called before the watchdog is setup. So this only works the second time around. Maybe you do this for testing, but I always put this in my setup function (minus the WDIE bit, that is). Remember that later on you need to call wdt_reset(); if you expect the loop the take more than 8 seconds.

If I remember correctly the WDIE bit is cleared every time the watchdog times out. So if you code hangs or sleeps for 8 seconds the ISR is called, and the WDIE bit is cleared. Then if another 8 seconds pass by, the chip is reset. Try changing  i<9 to  i<17 and see if the chip now resets itself.

I only wish I could fully understand how the watchdog timer works. I can no longer remember why I moved watchdog out of the setup. I tried so many different things. I didn't want the interrupt to fire only once, then on the next timeout perform a reset. It was my way of waking up the device with the built-in reset button, while still allowing a reset if the software hangs. Maybe I should try controlling the WDIE bit differently. I changed "i<9" to "i<17". There was no change. Thanks for the input Gerben.

I didn't want the interrupt to fire only once; you can. You just have to set the WDIE bit after each time the interrupt is called. In you case that would be, setting the WDIE bit each time the MCU goes to sleep. Maybe you could tell what it is you are trying to achieve in the end, instead of what isn't working as you expect in your piece of test-code. As I'm still not fully getting what it is you are asking/expecting.

Resetting the WDIE was the answer I was looking for. Simple. Thanks. This is to control a peristaltic bilge pump on a sailboat wintering in the water. The pump keeps the bilge bone dry, but operates continuously. Ice is a problem, so the Arduino senses temperature and will shut down the pump via a relay when it's near freezing. To conserve battery the arduino will check temp every 15 mins. I can't risk software hanging hence watchdog reset. External interrupt needed to fire up OLED if I want to read high and low saved readings. Next I will test for water flow via barometric pressure sensor.

I don't know if this is the best solution, but I found a workaround. In the ISR(WDT_vect) function I added a while statement where I added a boolean variable set to true when running the basic program, and false when I enter looping deep sleep mode. I'd appreciate if someone out there can provide a better solution, but for now this one works for me. Below is the revised code in case anyone's interested.
// thanks to KeyChainino for basic code. I added ADC disable to further reduce power from 0.67mA to 0.54mA
//revised by John Bedford 01/12/2020
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
const int ledPin = 13;
const int resetPin = 9;
volatile boolean wdtInterrupt;    //watchdog timer interrupt flag

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

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

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

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

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

void watchdogSetup() {

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

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

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

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

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

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


text:
How to restart ESP32 on any exception?
While developing a lot of projects (In Arduino IDE) for ESP32 one common issue I am facing is termination of program execution on unhandled exceptions. There are various exception I get.  For example: stack canary watchpoint triggered (looptask), invoke_abort, etc. I have no idea how to handle them, hence I prefer to restart the ESP manually.
Is there any way where I can restart the ESP32 automatically on all unhandled or unfortunate exceptions other than handling the exceptions ?

I know little of the ESP32's internals, but would using the watchdog timer work for this? Or  maybe changing the panic routine so that it resets the MCU?

@ocrdu hi . can u guide me with sample code for changing the panic routine so that it resets the MCU.

No, sorry, I have never done that on an ESP32. Sounds googlable, though. Watchdog not an option?

i have disabled watchdog as it is giving issues in my code flow.

it should reboot  whenever something blows up, I never see one just crashed out, so you must have changed something. don't disable the watchdog, fix the issues instead.

I have problems with the ESP8266 running for days then it would stop communicating with the I2C bus. My solution was to monitor a pin toggling on one of the port expanders and if it failed it would power down the whole system then restart it by killing power then turning it back on. Since my variables did not change very often I keep them in NVM. I hope this helps.

@Gil i had i2c issues too, but calling Wire.begin() again fixed it w/o a reboot.

Well, why not correct your application to never throw exceptions? That would be the only serious way to solve the issue. (Exceptions prove the rule, for example a remote application with high reliability requirements, but low quality. However, any restart should lead to an enhanced version.)

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

Hi.
watchdog is not only getting triggered.


text:
esp32 Stack canary watchpoint triggered
I am writing a program for esp32 on Arduino IDE. On some point of execution of code for File reading I am facing this exception,
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask)

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

The best way to handle this exception is to identify what's using so much space on the stack and rewrite your code to avoid it.
The three most common ways you'd use too much stack space are:

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

#define VERY_LARGE_STRING_LENGTH 8000

void loop() {
  char my_very_large_string[VERY_LARGE_STRING_LENGTH];

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

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

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

int count(i) {
  i--;

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

  return i;
}

void loop() {
  count(8000);
}

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

mistakes in your code like wild pointers and buffer overruns

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

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

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

when you overrun an array on the stack you'll probably overwrite other variables and corrupt their values. Do it enough and you'll hit the stack guard. Remember that C strings (char arrays and pointers) need n+1 characters to store a string of length n because they're terminated with an extra null '\0' character.
If you're using recursive functions, look at ways to limit the recursion or use tail recursion which the compiler may be able to optimize to avoid using excessive stack space.
If you're using large variables, think about why and rewrite your code to be able to use smaller variables. For instance, if you're reading a large file, try to process it a line at a time rather than reading the entire file into memory. If you're downloading large JSON from a web server, try using a streaming JSON parser rather than downloading the entire thing and then processing it.
A mistake in your code will be the hardest to figure out, given that it's a mistake. Be careful about pointers and memory allocation. Although memory is allocated from the heap and not the stack, if it's overwritten or reused after it's been freed using it as a pointer can still cause stack corruption. Also be careful to not return pointers to local variables inside functions:
int *do_not_do_this() {
  int this_will_not_work_the_way_you_hope = 0;

  return &this_will_not_work_the_way_you_hope;
}

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


text:
How to use a push button & transistor as a kickstarter for power supply?
My goal is to save energy, and I intend to do so by powering a chip with itself, and cut power whenever unnecessary. The best image I can have is of a startled monkey who jumps on the branch, screams its profanities while holding to the branch, and when the screams are done, lets go of the branch and falls back on the floor, asleep.
The chip, in my case an ATtiny45, has a program that just makes a specific sound (hopefully more pleasing than an angry monkey's) with a PWM, but would also power an output pin connecting to a transistor acting as a relay between the battery and the power pin.
This is the ideal protocol:
(No closed circuit, no power)
Press Button
Battery power goes through to transistor
Transistor allows current from Battery to PWR pin
Software: Chip starts PWM to Speaker and Outputs constantly the Hold Pin
Hold pin powers the transistor and thus the chip for when the button won't be pressed
Software: When Button still pressed, makes Chip Scream louder
Software: Button not pressed anymore makes chip scream softer until it's done screaming
Software: Scream is finished, stops powering the Hold Pin
Transistor isn't powering the chip anymore.

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

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

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

simulate this circuit – Schematic created using CircuitLab

why do you expect the ATtiny45 to wake up when it is disconnected from power? ... research deep sleep

I have a feeling, that you would need a PNP transistor in this case, because you need a specific minimum voltage difference between base and emitter for the NPN transistor to get conductive, which would not work with the MCU connected to the emitter. NPN transistors are usually low side switches, not high side. Currently not sure about that, but I've definitely seen a good answer somewhere from Majenko, who described a similar circuit, only based on NMOS transistors.

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

..and in practice I've found the typical current to be much less.
If, say, you are using AAA batteries for you project then you could sleep for more than 100 years. In practice your batteries will self discharge long before this, so any potential power savings by completely disconnecting the chip are wasted (and remember there is some leakage loss though the transistors that might even be more than the sleep power used by the ATTINY).
Instead connect the batteries directly to the power pins of the ATTINY and connect the button between any IO pin and ground. Activate the internal pullup on the IO pin and then set a pinchange interrupt on that pin to wake the chip when the button is pressed. Now go to sleep and wait for a button press to wake you.

A lot more simple and practical than my aspiration, especially due to the fact I need to do it for multiple units. Thank you!

Your idea is sound, but your implementation is flawed.
First, you don't want to bother with "wake" and things like that - when the chip gets power it just starts from scratch - that's your "wake" signal. Your code will just be "Hold it on" and "Make a sound" followed by "Let it switch off".
You only need one IO pin for that - the "Hold it on" signal. The "catch" signal in your schematic is just the chip getting power.
And then there's your schematic.  You should really use a P-channel MOSFET to do the switching of the power, not an NPN transistor. An NPN won't work, and a PNP (which would be what you would use for this if you were using a BJT) would impose a voltage drop, which you don't want.
Your circuit would in fact need to look like this:

simulate this circuit – Schematic created using CircuitLab
When idle M1 (P-channel with threshold voltage well below the battery voltage) is turned off by R1 pulling the gate up to the source voltage. Pressing the button pulls the gate below its threshold voltage allowing M1 to turn on. The chip then gets power.
M2 (N-channel with threshold voltage well below the chip voltage) is then activated by the chip by driving the GPIO HIGH to bypass the switch and connect the gate of M1 to GND.  R2 keeps M2 turned off while idle.
M2 is needed so that there is no current flow between the battery and the GPIO when the power is turned off.  Without it current can flow through R1 into the GPIO, through the ESD protection diodes inside the chip, and potentially break the chip.
Now to help clear up some of your questions:

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

Yes, it is.

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

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

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

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

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

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

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

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

Wow @Majenko this is a thorough answer that makes me understand a lot more! For the PNP, the fact that it does a voltage drop actually would solve another problem of mine. As per another question I posted, 2x3V batteries are too much voltage and could likely destroy the chip, and the PNP induced voltage drop could work, depending on how much voltage is dropped?

However why is the second transistor and resistor necessary instead of a simple diode? As for the resistor, if I understand properly, is it to direct the current a certain way, or to protect the chip from full amperage on the input pin?

@B7th A diode won't protect the chip from the incoming current when turned off. You need to sink current from the gate of the P-channel, which means the diode would have to be oriented to allow current flow into the chip - thus negating any possible protection. The resistors are purely pullup/down resistors to keep the gates at the right level when the chip is unpowered.

@B7th And for the battery voltage you should be considering a proper buck regulator with very low (or zero) dropout voltage, or at worst a zener diode to clamp the voltage at 5V (which is wasteful of power).

So a buck converter will help correct the voltage, the two MOSFET must be of the opposite "charge", and the two resistors to pull the gates. I understand the importance of each of them, however I will have to repeat these for each of the chips that will do the same task and there will be between 12 and 32 of them, all screaming asynchronously. If there is any of these items that can be removed, paralleled, simplified, or coded in one way or another, what could it be? The buck converter can be used for more than one so that helps.

@B7th You can get a single chip with the P/N channel MOSFETs in them as a pair, such as this one (though of course check your current requirements, but it sounds like you don't need much).

If you need that many of them, it might be better to not do this in hardware, but putting the chips in sleepmode instead. That way, all that's needed is the chip, the button, and the buzzer. It's perhaps a bit more work to get the software right, but you only need to do that once, not 12-32 times. Current in sleepmode should be negligible, like Majenko said.


text:
ESP-01 and HC-SR04 problems booting up
I have a problem in a project that I am working, basically I need to use a ESP-01 to receive the measurements from a HC-SR04 and send it to another ESP-01 (which I won't cover here).
Basically my ESP doesn't boot 95% of times, it just stays with the blue LED on all the time, on the remaining 5% of cases it boots normally and reads the sensor and also sends the information to another ESP.
I have done a lot of research and I am aware of these points:

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

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

That said, I would like to know why it works sometimes and others not, trying to get a little more of stability for presentation purposes...
Also it's worth noting that I have another ESP-01 connected with a DHT11 sensor with basically the same settings and it works normally.
The connections go like this:

ESP-01
HC-SR04

GPIO0
Trigger

GPIO2
Echo

GND
GND

Component
Power

ESP-01 Vcc, CH_PD
3.3v

HC-SR04 Vcc
5v

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

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

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

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

}

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

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

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

   delay(1000);

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

  }
}

I have tried already:

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

Thanks for your attention!

You powered the SR04 with 3.3 Volt. That does not work reliably. https://www.raspberrypi.org/forums/viewtopic.php?t=124216. The ultrasonic sender need more voltage to work well.

You should power up the HC-SR04 sensor with 5V, not 3.3V, as the sensor do not work properly with 3.3v supply

Sorry for the misunderstanding, the HCSR04 is powered by 5V, i just typed incorrectly.


text:
Initialising timer interrupt crashes Mega 2560
Below is the entirety of my prototype code, the cycling of pin 13 is what I use to confirm the board is restarting. The board resets continually on this implementation of initialising the interrupt. There is no code implemented for the interrupt, simply initialising the interrupt and specifically enabling the Output Compare Interrupt by setting its bit high is enough to cause the crash. The evidence of the crash is the onboard LED cycling as instructed in the setup() routine.
I have tried setting OCR3A in one and two operations, I have tried initialising TIMSK3 and not, I have tried intialising TCNT3 to zero and non-zero values, and setting the prescaler with the bit shift and the discrete value, nothing seems to work..
What is going on?
void FlashLED() {
  digitalWrite(13, !digitalRead(13));
  delay(100);
  digitalWrite(13, !digitalRead(13));
  delay(100);
  digitalWrite(13, !digitalRead(13));
  delay(100);
  digitalWrite(13, !digitalRead(13));
  delay(100);
}

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

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

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

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

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

}

Update:
I had also been trying with an empty ISR handler and discounted its effect:
ISR(Timer3_COMPA_vect) {

}

However, as the astute viewer would notice, the signature is incorrect in its capitalisation. The correct handler is
ISR(TIMER3_COMPA_vect) {

}

This has resolved the issue.

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

How irritating. I have for hours been working with an empty ISR handler, the whole problem has been incorrect capitalisation!! The Oscar Liang tutorial routinely mixes the case of the ISR, so it never occurred to me to change it: https://oscarliang.com/arduino-timer-and-interrupt-tutorial/ Feel free to submit ans answer that I will accept, since your prompt got me home.

Glad to be of assistance.

Unrelated; You should be able to use OCR3A = count to set both the H and L register with only one line of code.

That is what I was doing initially, but using Serial.print(OCR3A); returned 36, indicating that only the low byte was being written. I don't know how my code could possibly be behaving differently to anyone else's.

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


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

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

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

void setup() {
  imu.initialize();

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

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

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

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

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

But as I want to add more functionality to the main program - I want to move MPU6050 specific code to separate file.
So, I created Sensor.h with the following content,
#ifndef SENSOR_H
#define SENSOR_H

#include <MPU6050_6Axis_MotionApps20.h>

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

void sensorInit();
void sensorUpdate();

#endif

And placed the implementation in the Sensor.cpp file.
# include "Sensor.h"

void sensorInit(){
  imu.initialize();

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

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

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

And finally, modified the main.cpp file in the following way,
#include "Sensor.h"
#include <Arduino.h>

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

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

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

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

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

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

Main.cpp, Sensor.cpp and Sensor.h files are in the same directory. I am using PlatformIO to build and deploy the code on an Arduino Uno and the platformio.ini file content is the following,
[env:uno]
platform = atmelavr
board = uno
framework = arduino
lib_deps = jrowberg/I2Cdevlib-MPU6050@0.0.0-alpha+sha.fbde122cc5

I am wondering what is causing the linking errors.

The failing is not with your code. The failing is with the MPU6050_6Axis_MotionApps20.h library. It erroneously has code in the header rather than in a separate CPP file.
You have done everything right. The author of that library could do well in taking a leaf out of your book.
To get it working you will have to move the code out of the header file into the .cpp file - or move it to reside inside the class definition and make it inline.

I would be nice if there were a feature that would tell me how many people were typing in answers, scrapping mine now.

@Majenko Thanks! I just added inline keyword before each offending method in the header file, and the resolved the multiple definition issue. I've also added MPU6050 imu; int16_t ax, ay, az, gx, gy, gz; to global space of main.cpp to resolve the undefined reference issue.


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

section 10.3.1 https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf

PB1 has no analog input. So no, you can't read analog with it.
For analog you must use any of PB2 through PB5.

oh shoot... alright, thank you for the quick answer!!


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

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

void loop()
{
delay(100);
}

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

while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}

and here is my code on the XBee:
from machine import I2C

# Instantiate an I2C peripheral.
i2c = I2C(1)
slave_addr = 72
i2c.writeto(slave_addr, b'123', False)

Additionally, when I run an i2c.scan() on the xbee with an ISM330DHCX connected to the xbee's I2C, the address pops right up. But when I use the exact same code with the xbee connected to the trinket m0, the xbee cannot find any devices. (Code pasted below)
from machine import I2C

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

# Scan for I2C slaves connected to the interface and print their address.
for address in i2c.scan():
    print("- I2C device found at address: %s" % hex(address))

Does anyone have any ideas what I'm doing wrong with configuring the trinket m0 to be an i2c peripheral? Thank you!

Did you solve this problem? I'm trying to communicate with I2C between two Trinket M0 and am facing the same issue.

I never solved it. After some additional research, I figured that the trinket M0 couldn't be configured as a peripheral. I ended up using a different microcontroller.

I have two Adafruit Trinket M0 arduino boards running on my bench right now talking to each other over I2C. The trick is that you need to install a pull-up resistor between SDA and +3V, and another one between SCL and +3V. Typically it is the peripheral boards that come with those but when you talk between two microcontrollers which are often used as the master controller themselves they are open drain or not powerful enough to drive the bus. Any resistor between 4.7k and 10k ohms should do.
see the following reference doc:
https://docs.particle.io/cards/firmware/wire-i2c/pull-up-resistors-i2c/
From the other direction if you have many peripheral boards that all include their own pull up resistors, the combined resistance on the bus may low enough leak enough current to raise "low" state above 0.4v, at which point communication may have errors.
Or if the wires are too long or there are too many devices without enough pull up resistance (thus too much inherent capacitance) it will take too long for the data lines to reach the "high" state, and you will have to slow down the clock rate or add a signal booster like the LTC4311 (e.g. Adafruit product #4756) to get stable results.

This is very helpful! Thanks for posting.  I have moved on in this project, so I'm unable to check to see if it solves the problem.  Nevertheless, this is great information for anyone who may be experiencing similar issues.


text:
Arduino Mega 2560 + BLE HM-10 - I cannot execute AT commands
I have an Arduino Mega 2560 and a HM10 Bluetooth module (this one)
I have connected the Bluetooth according to the manufacturer's specifications:
VCC -> 5v
GND -> GND
TXD and RXD of the Bluetooth, I have tried to put them in pins of Arduino, in Serial1, in Serial2, in Serial3, with the same result.
The code I use for my tests is this:
#define BTserial Serial1

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

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

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

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

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

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

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

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

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

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

So the Bluetooth works.
My problem is trying to see the list of Bluetooth commands (AT+HELP command).
I have a method that is responsible for sending AT+HELP to bluetooth, but I have no response.
This is the method, which I run in the main:
String str_ii = "";
int ii_0 = 0;
void ble_help(){
    Serial.println("ble_help");

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

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

First thing first you can see all AT commands available from the data sheet available from datasheet
Second to get strings from Serial to BTserial you can just use c = Serial.readStringUntil('\n'); like here
#define BT_RX           0
#define BT_TX           1
#define BT_Serial       Serial1
#define BT_Timeout      100

String c, c2;

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

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

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

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

And lastly you need to make sure your HM-10 is genuine/has genuine firmware installed or it's a clone. Check if it respond to "AT" with "OK" at all. If it does then it's genuine and you can continue. If it doesn't then you need to flash genuine firmware onto it, then upgrade from there if you. Here is a good tutorial on flashing the genuine firmware onto the module.
After that you can follow a tutorial here on upgrading the firmware from an older genuine firmware. You can get the latest genuine firmware from the Manufacture's website.


text:
Reading a string from Firebase and storing it as a CString
I have a mobile app (done using MIT App Inventor) storing some values to a Firebase database. App inventor stores all the values as strings (i.e. with quotes, and strings have quotes enclosed within quotes eg. "\"hello\"").
I'm using this library to fetch data from Firebase to ESP8266. I'm using String var to store the value retrieved and then change it to a CString (trying to store it directly doesn't work) as below:
This doesn't work:
Firebase.get(firebaseData, "/SCHEDULE DETAILS/SCHEDULE1/FREQ FR");
Serial.print("node -- schedule1 /FREQ FR -- type: ");
Serial.println(firebaseData.dataType());
char * cstr1 = new char [33];
cstr1 = firebaseData.stringData();
Serial.print(" -- data: ");
Serial.println(cstr1);

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

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

I feel like I'm doing one step more than what is required! Any suggestions on how to go about this would be very useful!
Try1 Based on the answer from @Majenko, I tried this before adding to the library:
const char* get_cstring() {
  String str = "will it work" ;
  return str.c_str();
}

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

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

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

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

Could you please post the solution so others can benefit.

In returning a String object the Firebase first generates that String object and copies the C string data into it.
If you want to get at the raw C string data you will have to look at adding a new "getter" to the library to return the pointer to that C string data:
I'd write it for you, but since you posted a screenshot of the Firebase function, and the change from that code to the new code is very minor (just change the function name and the return type), I can't copy-and-paste it. And I'm not going to peer at that little image and type it all in again.
Incidentally, internally the Firebase library actually uses std::string, which is a better implementation of the same thing that String does. String was created because the Arduino compiler has no STL, and hence no std::string. Either way they both use dynamic allocation.

The problem you have is that your str variable is local to the function. It, and the memory allocated within it, gets destroyed when the function returns. So what you have in new_c is a pointer to nothing much. That shouldn't be the case with Firebase, since _data is a std::string that is a member variable, not a local variable.

I tried with a global String var ; it works! But when I try to use new_c.atoi() with an integer value as input, it fails; so how should the return type be declared!? or where should the change be made to perform those type conversions !?

@SomasundharamSampath Use atoi(new_c)

that was very stupid from me!!! Thanks a lot! Looks like I need another primer on C.


text:
Infared: some controllers send code into infinite loop
I have a piece of code that captures input from infrared and spits it out to the serial port.
When I use it with a simple controller that comes with a typical kit, it receives the infrared code just fine for each button I depress.
But when I try and capture information from my air conditioning remote (the one I need to clone), I receive the first hexcode and then the output gets thrown into an infinite loop with that 1 hexcode, and will not break out.
#include <IRremote.h>

const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(115200);
  irrecv.enableIRIn();
  irrecv.blink13(true);
}

void loop(){
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume();
  }
}

What is causing the infinite loop from "some" controllers and how do I prevent it?
Update:
In changelog they say they renamed RAW_BUF to RAW_BUFFER_LENGTH. I find RAW_BUFFER_LENGTH in IRremoteInt.h and not IRremote.h
I'm not calling on IRremoteInt.h
I did try and reset the buffer from 101 to 201 in IRremoteInt.h, recompiled, uploaded, same issue.

some air conditioners have really long bit sequences ... they can also use error checking

@jsotola That sounds very plausible. How do I capter all of it?

@jsotola  Quilo model QP114

try this to capture all of the bit stream ... https://stackoverflow.com/questions/22751255/how-to-correctly-receive-and-send-raw-ir-data-from-arduino

@jsotola The code from that page performs a much more robust infinite loop, but still the same infinite loop. In the answers they mention #define RAWBUF 100. That does not exist in my IRremote.h

i wonder if you are on the wrong track ... your sketch is an infinite loop ... basically, all arduino sketches are infinite loops

@jsotola so, you're saying that 10 million lines (and counting, very quickly) of https://i.imgur.com/3VU4t39.png is sane?
No, it is not because of the main program loop.


text:
How to clear heap memory in ESP32?
I am using Free RTOS on ESP32 in my program. However at some point of time when I execute xTaskCreate() it returns -1 , the error being  could_not_allocate_required_memory. In my program, each time I pring getFreeHeap() it is reduced by 2,000 approximately and is never cleared or reset. When it is not sufficient or below 2,000 xTaskCreate returns -1.
After reading a lot of forums I could not find a way to clear the memory to create a task. Can anyone guide me with this?
code snippet
void createTsk(){
  SerialDebug.print("available Heap size: ");
  SerialDebug.println(ESP.getFreeHeap());

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

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

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

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

  delay(10);

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

  vTaskDelete(th);
}

I don't know much about FreeRTOS, but memory on the heap can be cleared by deleting the dynamically created objects, that you don't need. Have you searched for a function in FreeRTOS to do this? In plain C/C++ it is just the delete operator.

@chrisl hi. thanks for the reply.
I am using arduino ide, hence i am not be able to do few custom modification. is there any more resolved way can you suggest ?

I'm not asking for "custom modifications". Code inside the Arduino IDE is just plain C/C++ with the Arduino framework (and the FreeRTOS framework in your case). You have some code (please show it in your question by editing it) and in this code you create objects dynamically. These objects must be deleted again. Someone must keep track over the objects, that are created, and free the memory, when they are not needed anymore. That can be you with your own code, or maybe the FreeRTOS framework (which I don't know enough to say, if it is capable of doing that).

@chrisl code added. please suggest.

xTaskCreate returns a pointer. You have to free it. When you're done with the task, you need to call xTaskDelete.

@PMF it is written in furtherExecutionHttp method at the end.

@Androing: Hmm.. True, that looks right. However, since thOne is a global variable, this only works if only one task is running at a time. If you start a new task while the old has not exited, the next call to xTaskDelete will delete the task that was most recently started, not the current one. Try xTaskDelete(null) to delete the current task.

is the http response about 2kb?

@dandavis 700-900 bytes

The heap memory in ESP32 cannot be cleared explicitly. The heap memory is used to store dynamically allocated objects, and when an object is no longer needed, it is automatically deallocated by the garbage collector.
You can free up some heap memory by deleting unused objects. In your code, you create a new object called taskdataholder in the furtherExecutionHttp() function. This object is allocated on the heap and will only be deallocated once the function returns. If you want to free up this memory, you can call the free() function before the function returns.

You probably don't want to "clear" the heap, assuming you mean either deallocating or zeroing all memory that you've allocated from the heap.
If you simply return all memory to the heap when you run out, your code may have pointers to that memory remaining when that memory gets allocated to another use, meaning some data will likely get over-written. Or, if you clear the heap (by zeroing it) you will be over-writing data already stored there, and possibly still be unable to allocate more memory if the allocator doesn't "know" that you meant to return it.
Instead, your code should free each memory allocation as soon as it is no longer useful, and make sure its pointer to that memory won't be used again. One way to protect re-use of dead pointers is 1) zero them when you deallocate the memory they point to; and 2) always test for a valid pointer (non-zero) before you try to use it.


text:
How to connect a thermal printer to an ESP32?
I want to attach my GOOJPRT Thermal Printer (I believe model QR701, communication RS232) to my ESP32 but I cannot seem to get them working.
I tried all the Adafruit Thermal Printer library examples but get the same error each and every time:
"Error compiling for board ESP32 Dev Module."

I guess the libraries are not meant for the ESP32.
I also tried the "Thermal Printer Library" by Larry Bank (which should be compatible with the ESP32 according to its github docs) but there I cannot figure out how to connect the wires of thermal printer to the ESP32 correctly.
Of course, I do not ask for a specific solution, I am just looking for someone to point me in the right direction!

This is an image of the exact thermal printer I have
Full error message from Adafruit Thermal Printer examples:
C:\Users\Thomas\Documents\Arduino\libraries\SoftwareSerial-master\SoftwareSerial.cpp:41:27: fatal error: avr/interrupt.h: No such file or directory
compilation terminated.
Multiple libraries were found for "Adafruit_Thermal.h"
 Used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit_Thermal_Printer_Library
 Not used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit-Thermal-Printer-Library-master
Multiple libraries were found for "SoftwareSerial.h"
 Used: C:\Users\Thomas\Documents\Arduino\libraries\SoftwareSerial-master
 Not used: C:\Users\Thomas\Documents\Arduino\libraries\EspSoftwareSerial
exit status 1
Error compiling for board ESP32 Dev Module

Second error message from Adafruit Thermal Printer example after removing the manually installed SoftwareSerial.h:
A_printertest:21:28: fatal error: SoftwareSerial.h: No such file or directory
Multiple libraries were found for "Adafruit_Thermal.h"
compilation terminated.
 Used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit_Thermal_Printer_Library
 Not used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit-Thermal-Printer-Library-master
exit status 1
SoftwareSerial.h: No such file or directory

What is the error you are actually getting? The message you pasted us is the one telling you that an error occurred, not what the error was. Without the actual error we can't help you.

@Majenko♦ Please see the full error message above, which I copy pasted from the Arduino IDE

It looks like you have installed some other SoftwareSerial library manually. You should never ever need to do that since almost all cores bundle their own version that is specific to the core. Delete it. You don't want it. Ever.

@Majenko♦ Thanks for the info! I manually installed the SoftwreSerial because the IDE was giving the error "No such file or directory" error. It also gives me this error after I deleted the library which I installed manually.

Well, remove the library again, then try compiling, and post what you get then.

@Majenko I posted the other message on the bottom again. I am a tiny step further now, I managed to get output from my thermal printer through the Serial2 port on my ESP32 (tx/rx on pin16/17). Unfortunately the output is all gibberish but consistent (baudrate is correct). I posted a topic here on the Adafruit forum: https://forums.adafruit.com/viewtopic.php?f=22&t=174116

ÊSP32 has three hardware serial ports (UARTS), so no need for SoftwareSerial. To use Serial1 and Serial2, see e.g. https://github.com/espressif/arduino-esp32/issues/1838#issuecomment-418744153

@ridgy thanks for your reply, I have figured that out and I got the printer to output something. There still is a problem though, the text that comes out of the printer is not as it should even though my baudrate is correct. Please see the following link, maybe you know what goed wrong https://forums.adafruit.com/viewtopic.php?f=22&t=174116

What if you replace printer.println() by Serial2.printl()? You should not need the Thermalprinter library to just print out normal text - if that works, the error is in the library.

You need to use the <HardwareSerial. h> library. SoftwareSerial is for Arduino boards.
"Thermal Printer Library" by Larry Bank is for GOOJPRT PT-210 and uses Bluetooth. Won't work for QR-701.
Instead of using Adafruit Library, you can try with this: ThermalPrinter.
This May Help,
Peter


text:
Why are characters with value above 127 "padded" with 1s to be 16 bits long, while ones with values 0-127 aren't?
I am using the Arduino IDE to run and monitor, with an Arduino Nano clone.
This code shows what I mean by the question:
char foo = 127;
char bar = 128;
Serial.println(String(foo, BIN));
Serial.println(String(bar, BIN));
foo = 383;
bar = 384;
Serial.println(String(foo, BIN));
Serial.println(String(bar, BIN));

prints
1111111
1111111110000000
1111111
1111111110000000

It still happens if I then cast the elements to char, but not if I cast them to uint8_t:
char foo = 127;
char bar = 128;
Serial.println(String((char)foo, BIN));
Serial.println(String((char)bar, BIN));
Serial.println(String((uint8_t)foo, BIN));
Serial.println(String((uint8_t)bar, BIN));

1111111
1111111110000000
1111111
10000000

It behaves the same if I do some arithmetic as well:
char foo = 127;
char bar = 128;
Serial.println(String(foo / 64, BIN));
Serial.println(String(bar / 64, BIN));

1
1111111111111110

Why is this? If I assign a number bigger than 255, but smaller than 384, it behaves like for numbers below 128, but above that, it does it again, so it's obvious that only the least significant 8 bits of the value are stored as expected, but in cases where (n mod 255) > 127 (so the 8th bit is 1) they are retrieved from memory together with another 8 bits, which are all 1s.
I can live without an answer to the above issue, what I really need to have confirmed is the following:
If I were to store and retrieve a uint16_t as two elements of a char[], it would always be safe (and not undefined behavior) if I did it as follows, right?:
uint16_t foo = 34952;
char bar[2];
bar[0] = foo >> 8;
bar[1] = foo;
uint16_t extracted = (uint16_t((uint8_t)bar[0])) << 8 | (uint8_t)bar[1];

Thank you in advance for any help you can provide.

On the AVR platform the char type happens to be signed, and it can
store numbers in the range [−128, +127]. Thus, when you write
char bar = 128;

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

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

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

"the char type happens to be signed" Oh, right! I forgot about that before, and I thought this was the key, but now I checked, and the results for -128 are exactly the same as for 128, it also doesn't help if I try casting it to char (either for storing or retrieving). "use uint8_t instead of char" great that you pointed that out, I shouldn't have been using char[] in the first place, but originally I was using a String and then moved over as that would terminate at the first NUL. It didn't occur to me to just use uint8_t[], but thankfully that still works with LoRa.

@Boba0514, 'Arduino language' has byte type too. it is a nicer name for uint8_t

@Juraj: “nicer” is subjective. Personally, the word “byte” evokes to me a unit of information storage equal to 8 bits, which could be used to store a signed number, an unsigned number, a collection of flags (that would have no meaningful interpretation as a number), or whatever one may want to put there. The name “uint8_t”, while not as nicely sounding, clearly states that it holds an unsigned integer. Note that Java has a byte data type, and it is signed.


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

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

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

I made this code but it does not work can anyone suggest an edit without using millis() because it will crash after 49 days and without using delay function.
Note that the device will work 24 hours / 365 days.
const int input1 = 19;
const int input2 = 36;
const int relay1 = 10;
const int relay2 = 21;
const int reset = 40;
const int buzzerreset = 45;
const int buzzerrelay = 46;

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

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

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

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

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

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

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

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

millis doesn't crash after 50 days. It just overflows, and starts back at zero. This is only a problem if you compare two timestamps. You can get around this problem all together by calculating the difference of the two timestamps. You can then check if the difference is more that 10000ms in you case. For example if( millis()-buzzerStartTime > 10000){/*stop buzzer*/}

Could you expand on the it does not work  part? What happens when you run your code? What do you expect do happen when you run your code?

why do you bother with states? ... your description says that the buzzer does the same thing in both states ... all you have to do, is to sound the buzzer for 10 seconds

when i run the code if the input not contentious there is no problem with the timer ,but when is the input is contentious the buzzer is also contentious and this is the problem i want the buzzer run for 10 seconds every time one of the inputs go HIGH (i have 25 inputs) even the input is contentious or not .  – Gerben

You say that when you detect an input (continuous or intermittent) you want to turn on a buzzer for 10 seconds, then turn it off again. What should it to once the buzzer is off again? Should it have a "lock-out" period where it ignores the input? Or should it simply wait for another input? Once 10 seconds has passed, should it wait until the input goes to the off sate before looking for a new trigger?

simply the buzzer will turned ON for 10 seconds in all cases( continuous or intermittent input )and wait for another trigger from another input if input is go high the buzzer will go ON for 10 seconds and so on @DuncanC

What if the input turns on and stays on for 5 minutes? How should the buzzer behave then?

the input could be go ON for a month the buzzer should be ON for 10 seconds and then turn of and ignore the input state until the input goes LOW

That's what I thought. You need to update your question to make that clear. My answer explains how to do that. Is there only one buzzer that buzzes if any of your inputs goes on, or does each input have its own buzzer?

yes there is one buzzer in the circuit

I would suggest having a buzzerPlaying state, an oldInput state, and a buzzerOffTime (unsigned long millis when you should turn the buzzer off.
Ignore input if buzzerPlaying == true and just check the buzzerOffTime. When buzzerOffTime passes, turn off the buzzer, set buzzerPlaying to false, and start checking the input again.
If the buzzerPlaying == false and input is high:

check buzzerPlaying. If it's true, do nothing.

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

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

thanks for replay , im new to arduino and i have 25 inputs and 25 outputs i do not think that i could handle adding  this three status to my code put i will try hope it will work @

25 inputs and 25 outputs? That means you need 50 i/o pins. Do you have an Arduino with that many pins?

i will use arduino mega 23 input and 23 output and pin for buzzer and pin for buzzer reset and pin for output reset that will be 49 i/o

Whatever the inputs do, when one of them first goes HIGH you want the buzzer to sound, stopping after 10 seconds or a button-press, whichever comes first?
Then you need something like this:
if any input is HIGH,
   save millis();
   start the buzzer;

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

thanks for replay i will try this

This pseudocode will have the buzzer play continuously as long as any input is high. The OP wants the buzzer to only play for 10 seconds, whether the input stays on or not. And they said they only want the buzzer to play again if the input goes low again once the buzzer stops. There need to be some state variables as I suggested in my answer.

Yes, that's right. :) And the psuedo-code reflects the problem statement as it had been stated until they clarified it in response to your pointing that out. That was 5 hours after my post.


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

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

Thank you for any suggestions.

google keyboard scan codes

Thank you, I have the needed scan codes. What I need is information about where to put them in the IDE.

you said that you are able to generate PgUp and PgDn keypresses .... you do other keypresses the same way

The functions for keyboard.press (RIGHT-ARROW) and left arrow work as expected. F11, WAKE and SLEEP  are not available or are not named that way, hence my questions about the list of available functions, or what the header file is named so that I can add to it.

names like RIGHT-ARROW and F11 are just numbers ... i would suspect that they are scan codes ... i would just use a scancode for PgDn to see if my hunch is correct

try some of these codes ... http://ts.thrustmaster.com/download/accessories/pc/hotas/software/TARGET/TARGET_SCRIPT_EDITOR_basics_v1.2_Appendix.pdf

@jsotola You were right about putting numbers directly in the keypress function. I found the name for F11, namely, KEY_F11. It also works with 0xCC as argument. However, the USB HID code for F11 is 44, and that doesn't work to toggle fullscreen with the Leonardo, so there is something else going on. The HID code for sleep is 82, but that is also used for caps lock. So, there's something else going on here. The doc you linked doesn't mention wake or sleep.

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


text:
HC-05 voltage divider
I am currently testing a small Arduino Nano project (schematic below) and have encountered issues when communicating between a HC-05 Bluetooth module and the Arduino. I am using a simple LED bulb which I am trying to turn on and off from a phone which is connected to the HC-05. The HC-05 is powered separately by some batteries instead of being powered by the Arduino itself. The Bluetooth connection is functional, and so is the actual LED functionality on the Arduino, but there seems to be a problem when I am trying to send stuff through the RX/TX connection. I previously attempted this without a voltage divider and had the same problem. Am I using the right resistors for the voltage divider or should I step them up to 1k and 2k respectively? I measured the voltage on the RX/TX and for some reason it only amounts to around 1.5V (instead of the desired 3.3V). Is there any other issue I am not seeing?

Edit: I also measured the voltage on the RX/TX without the voltage divider and somehow it's straight up 0. Why would that be?

connect the grounds together

both the 200 ohm resistor branch and the HC-05 GND are connected to the cathode of my batteries

What about the ground of the Arduino...?

Arduino is plugged in (via mini USB)

Connect the grounds of the 2 boards together, like jsotola said!


text:
Checking if Arduino board works or is damaged
I have an Arduino Uno and Mega, but when I connect them to a computer with the USB they came with, there is no green light near the reset button that illuminates.
On the Uno board the pin 13 continuously flashes with red light while on the Mega board the R17 and R18 both illuminate red light but no flashing.
How do I know if the boards work or are damaged?

Does your Operating System recognize the Serial Port when you connect them? Have you tried uploading a sketch? Is there a reason to suspect they do not work? Some boards (like your Uno maybe) have a “blink” sketch installed by the manufacturer, others do not.

in device manager in my computer nothing changes when i connect the Arduino. Yes I tried  uploading files and the "port option" is gray.  no reason to suspect it's working.

If the LED 13 is blinking, that's generally a good sign. I'd check the connection and try a different cable. On Windows, you might need to install the Arduino IDE first, because that includes the serial port driver for some of the boards.

the blinking is like in every one and half seconds. the power and the led 13 lights are both red. on the device manager of my computer, communication port (com11) appear with warning sign. but in the Arduino IDE the port is still gray .

See also: https://arduino.stackexchange.com/questions/153/how-to-check-my-arduino-board-is-working-or-dead

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


text:
Strain Gauge with HX711 Load Cell Amp
I am trying to get a strain gauge working with the HX711 load cell amp. I posted about this a few months ago and got told to get some high precision resistors for the wheatstone bridge. I have now obtained these (https://www.digikey.fi/product-detail/en/vishay-foil-resistors-division-of-vishay-precision-group/Y0007350R000T9L/Y0007-350-ND/2609877).
My wiring and code are as shown below. The wiring is basically a wheatstone bridge with one arm replaced by the strain gauge and each of the corners of the wheatstone bridge connected to RED, BLK, WHT and GRN on the red HX711 (BLK and GRN are the ones connected to the strain gauge arm). On the other side, VCC is to 5V on the arduino, GND to GND on the arduino, DAT to digital pin 5 and CLK to digital pin 6.
#include "HX711.h"

#define calibration_factor -550.0 //This value is obtained using the SparkFun_HX711_Calibration sketch
#define DOUT  5
#define CLK  6

HX711 scale;

void setup() {
  Serial.begin(9600);
  Serial.println("HX711 scale demo");

  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0

  Serial.println("Readings:");
}

void loop() {
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
  Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();
}

The problem is that the values are not changing when I bend the strain gauge. Only random, short spikes in values are happening and they do not seem to correspond to the strain gauge being strained or unstrained (see below). Any ideas what could be causing this?

Any help is greatly appreciated.


text:
Arduino Serial Communication possible with IDE 1.8.5 but not with IDE 1.8.13
I have the following problem: I am working with an Arduino Nano 33 IoT and a second serial interface via sercom0. The code is just taken from this tutorial:
http://www.getmicros.net/serial-communication-on-the-arduino-nano-iot.php
In loop, I just print the input from my serial connection to the standard serial connection. The input comes from a ozon sensor that sends data packages every single second.
Now when I program the arduino with my Laptop, my IDE version being 1.8.5, it works well, but when I use my PC with a newer version (IDE 1.8.13), it doesn't work any more. The code is the same, the cable and the arduino are the same, the only difference is the PC. But when I try to use an hyperterminal to print the data packages recieved from the sensor, both the Laptop and the PC receive the correct packages. Somehow, the Arduino or the difference in IDE versions causes the communication to fail....
Does anyone have experience with this error?

"this error" Are you getting an actual error message?  If so, what is it?

If you program on your laptop then plug into your PC does it work? How about the other way around?

Serial1 is there for pins labeled RX/TX. the boards package version is independent from IDE version so IDE version doesn't give any useful information here.

I am not getting an error message since for both cases, data is being revied by the arduino. The problem is that the data is different when I use the serial interface on my PC.
No, sadly programming it on my Laptop and then plugging it into my PC does not work...
I don't really understand what you mean, Serial1 is not being used. I use the normal Serial for sending the data to the PC or Laptop and the sercom0 interface for reading in the sensor values.


text:
Set parameters after compilation
I am extremely new to Arduino and have searched for this on the web but have not found it.
My project has 2 files, a .ino file with the sketch and another .h file with the secrets and configuration parameters, such as reading intervals, credentials to connect to WiFi, etc.
Now I need in runtime to be able to connect to the arduino, either by serial or by any other way to be able to set these parameters.
My question is: How can I change the parameters after compiling the sketch? For example, how can I specify the credentials for the Arduino to connect to the client's WiFi, since each client has different credentials?

It is likely 2 features are desired for this project:

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

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

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

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

The idea of the latter is that, when the Arduino can't connect to an available network (because it is unknown, or because it doesn't have the right credentials stored), it sets itself up as an access point with a known SSID, password, and IP address.
You can then (first) connect to the Arduino's access point WiFi network, and then open a HTML page from the Arduino in a webbrowser that lets you enter your WiFi credentials for the "real" WiFi network. This is how the WiFiManager library works (for the ESP8266 and the ESP32).
Once the credentials have been entered, you can store them (permanently) in EEPROM using the EEPROM library or, if the MCU on your Arduino doesn't have EEPROM, using a library that stores in flash, like the FlashStorage library for SAMD21-based Arduinos.
The same mechanisms can be used for other parameters you may want to set at run time.