text:
Why am I receiving this Error: Debug exception reason: Stack canary watchpoint triggered (task1) in ESP32 using a FreeRTOS program?
I'm getting this error by running a FreeRTOS program on my ESP32 using arduino ide, I don't understand why this happens because this same program works on an arduino Uno with no errors:
Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception).
Debug exception reason: Stack canary watchpoint triggered (task1)
Core  0 register dump:
PC      : 0x40088a4f  PS      : 0x00060636  A0      : 0x800d3155  A1      : 0x3ffb9130
A2      : 0x3ffb8eb4  A3      : 0xffffffff  A4      : 0x00060620  A5      : 0x00060623
A6      : 0x00060623  A7      : 0x00000001  A8      : 0x00000001  A9      : 0x00000000
A10     : 0x00060623  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000000
A14     : 0x007bee88  A15     : 0x003fffff  SAR     : 0x00000000  EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000

This is the code I'm using:
//#include <Arduino_FreeRTOS.h>
//Overload happens if xTaskGetTickCount – lastTickCount (the first parm to vTaskDelayUntil) is >= period in ticks

void task1(void *pvParameters);
void task2(void *pvParameters);
void task3(void *pvParameters);

void setup() {

  Serial.begin(115200);

  //Create tasks
//xTaskCreate(Task function, Task name, , Task parameter, Task priority, );
  Serial.println("111111");
  xTaskCreate(task1, "task1", 512, NULL, 1, NULL);
  Serial.println("222222");
  xTaskCreate(task2, "task2", 512, NULL, 2, NULL);
  xTaskCreate(task3, "task3", 512, NULL, 3, NULL);
  //vTaskStartScheduler();

}

void loop() {}

void task1(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1){

    Serial.println('M'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period)
      Serial.println("Overload in task 1");

    vTaskDelayUntil(&waketime, period);

  }

}

void task2(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('E'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 2");
    vTaskDelayUntil(&waketime, period);

  }

}

void task3(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('S'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 3");
    vTaskDelayUntil(&waketime, period);

  }

}

I tried increasing the task stack memory in xtaskcreate and the same error occurs, although when I increased it to 1024 nothing shows up in the serial monitor. This same program works flawlessly on arduino uno and raspberry pi pico. I also tried changing the tasks' period and their execution time, which is the delay, and it still doesn't work

although when I increased it to 1024 nothing shows up in the serial monitor.

Doing nothing to your code except using 4096 for stack size causes it to print things on serial.
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0
111111
222222M

E
S
S
E
M
S
ME

I won't tell you that it's correct, but it seems fairly clear that you haven't given it enough stack to work with.
With my current setup
Serial.println(configMINIMAL_STACK_SIZE);

is printing 828. I don't know how exactly how to interpret that number. But unless I found otherwise, I could default to considering it the requirement to start a task that uses no stack of it own (no local variables, no calling). The memories of the esp32 seem large enough that no matter how you're using them it doesn't make sense to go so minimal for a handful to tasks. I chose 4096 somewhat arbitrarily. I'm not suggesting is a good value.


text:
Pls help with this prompt. I've been struggling last 2 days with this and its due tomorrow
"Use an Arduino, two potentiometers, and an alarm. Make one of the potentiometers act like a volume control, and make the other potentiometer control the tone that the alarm makes."
I added what I have so far. I'm not sure how to control the volume

that is a good start ..  the code should be added as text, not as a picture ... the tone() function has no volume control ... perhaps you are supposed to build a volume control circuit

@Mahmodol this site is a question and answer site ... its purpose is to answer questions ... if you ask a clear question, then someone will try to answer it

Post a schematic as you have it wired, part of your frizzy picture is not even connected. With such short notice I will be surprised if you get it resolved in time. When you are given an assignment it is best to start ASAP, waiting until the end causes problems like this and missed assignments.

Welcome to SE/Arduino! Please take the [tour] to learn how this site works. -- What have you tried to read the values of the potentiometers? -- Please [edit] your question, don't add a comment. This is not a forum. ;-)

Use the other potentiometer as a variable resistor. Instead of connecting to pins 1 and 3 (to control tone), Use the 2nd pin of the potentiometer to make a voltage divider. From the 3rd pin go to a + on a buzzer. I don't see the reason to have the circuit connected the way you have. if you want to control the tone with potentiometer, connect it to stable 5v, and connect the second pin with any analog pins that is configured as input. Then, use map function, and map the voltage, accordingly to the tone you'd like to use.

source: Stack Exchange

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

sort: votes


text:
Arduino 75kHz output frequency setup
i don't know how to manipulate arduino uno or mega registers and timers to be close to 75kHz output frequency. Could you help please ?

output frequency from where to where?

First you have to compute, from your desired frequency, the number of
CPU cycles per period of the signal:
F_CPU / 75 kHz = 16,000 kHz / 75 kHz ≈ 213.33
Since the timers can only count up to an integer, the closest you can
get is 213 CPU cycles. The frequency you get will then be
F_CPU / 213 = 16,000 kHz / 213 ≈ 75.12 kHz
Now you can configure a timer. I find that the easiest is to use a so
called “fast PWM” mode. Choose one of those modes where the TOP value
can be set with a register, and set it to one unit less than the desired
period: the timer will then repeatedly count from 0 to 212.
Here is an example using channel A of Timer 1 on an Arduino Uno.
The output is on digital pin 9 = OC1A = PB1:
// Configure Timer 1 for PWM @ 75.12 kHz.
DDRB  |= PB1;         // set OC1A = PB1 as output
TCCR1A = 0;           // clear the settings of the Arduino core
TCCR1B = 0;           // ...ditto
TCNT1  = 0;           // clear the timer
TCCR1A = _BV(COM1A1)  // non-inverting PWM on OC1A
       | _BV(WGM11);  // mode 14: fast PWM, TOP = ICR1
TCCR1B = _BV(WGM12)   // ...ditto
       | _BV(WGM13)   // ...ditto
       | _BV(CS10);   // clock at F_CPU
ICR1   = 213 - 1;     // period = 213 CPU cycles = 13.3125 us
OCR1A  = 213/2 - 1;   // duty cycle ~ 50%

You can easily adapt this to any timer on the Uno or Mega. Just avoid
Timer 0 if you are going to use the Arduino timekeeping functions.

I think the answer given by Edgar Bonet is the right one, all things considered, and I up-voted it for that reason.
For S&G, I want to add the following:

The easiest way is to simply use the tone(GPIO,Frequency); command - and there are caveats. BUT, the frequency argument is an unsigned int so the fastest frequency is 65535Hz - it will do you no good for 75kHz.

Using a frequency counter and an UNO (crystal), tone(10,65535); the output was 65556/8 Hz. On a Pro Mini 5V (ceramic resonator as I recall), it was 65540 Hz.

Again, for S&G, I tried this code (and adjusted the number of NOPs) to get as close as I could to 75kHz:

void setup() {
pinMode(10, OUTPUT);
}
void loop() {
here:
  digitalWrite(10, HIGH);
  delayMicroseconds(3);
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  digitalWrite(10, LOW);
  delayMicroseconds(3);
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  goto here;
}

The output on the UNO was 75004/6 Hz  - not too bad. On the Pro Mini, the best I could do was 74986 Hz.
Of course, we are talking about square waves.

Note that: 1. You can replace delayMicroseconds() and the train of nop with a single call to _delay_us(). This macro has single cycle resolution: _delay_us(3.4375) delays by exactly 55 CPU cycles with a 16 MHz clock. 2. This approach works better with interrupts disabled. Otherwise you get a small glitch on every timer interrupt. BTW: what does “S&G” mean?

https://www.urbandictionary.com/define.php?term=S%26G picked up the expression for someplace a long time ago :)

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


text:
4x3 keypad not providing any output and the output it does provide is incorrect
I am trying to figure out how to use a 4x3 keypad and just want to receive the key numbers I select on the serial monitor. The problem I am getting is that some of the keys I type don't give me any output and then the keys that do provide output do not match their corresponding number. For example key 1 does not provide any output, whereas keys 3 and 4 give an output of 4 and 9 respectively. I have attached pictures of how the keypad is connected
The code that I am using is below:
#include <Keypad.h>

// Constants for row and column sizes
const byte ROWS = 4;
const byte COLS = 3;

// Array to represent keys on keypad
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

// Connections to Arduino
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3};

// Create keypad object
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
  // Setup serial monitor
  Serial.begin(9600);
}

void loop() {
  // Get key value if pressed
  char customKey = customKeypad.getKey();

  if (customKey) {
    // Print key value to serial monitor
    Serial.println(customKey);}
}

I just need help identifying where I am going wrong and how I can fix the problem I am having. Thanks.

Your pictures are useless to me, post a real schematic as to how you have it wired. I know first hand the keyboards will work if connected correctly to a good UNO. Be sure to show the keyboard in the schematic and properly label rows and columns.

Are those pins soldered onto the keypad? The connection looks a bit dodgy from the photo.

Hi Gil, I have included a schematic, however, I could only find a 4x4 keypad so just ignore the connection to pin 2. Hi Nick, yes they are soldered onto the keypad.

I determined where I was going wrong. The keypad has a different wiring compared to the traditional way of doing it. I found this this article helpful. The changes made to the code are as follows:
byte rowPins[ROWS] = {8, 3, 4, 6};
byte colPins[COLS] = {7, 9, 5};

As can be seen, the rows and columns pins need to be changed.


text:
Interrupt on button press + debouncing
I want to have an interrupt function executed whenever a button is pressed.
The button is connected to pin 2 and the GND. Therefore, the pin is turned to LOW whenever the button is pressed. In addition to that, proper debouncing should be used
As a proof of concept, the interrupt function should just toggle the BUILTIN_LED whenever the button is pressed.
I have tried many different approaches but i cannot make it work.
This is my last iteration:
bool led_status = LOW; // current state of output pin
int buttonState; // the current reading from the input pin
int lastButtonState = HIGH;  //the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

int button_switch = 2; // external interrupt pin
bool initialisation_complete = false; // inhibit any interrupts until initialisation is complete

// ISR for handling interrupt triggers arising from associated button switch
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
void button_interrupt_handler()
{
  //static long int elapse_timer;

  if (initialisation_complete == true) //only able to run the ISR when arduino has finished initialization
  {
    // new interrupt so okay start a new button read process -
    // now need to wait for button release plus debounce period to elapse
    // this will be done in the button_read function

    int reading = digitalRead(button_switch);
    if ( reading != lastButtonState) // If the switch changed, due to noise or pressing:
    {
      lastDebounceTime = millis(); // reset the debouncing timer
    }

    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:
    if ( (millis() - lastDebounceTime) > debounceDelay)
    {
      if (reading != buttonState) // if the button state has changed:
      {
        buttonState = reading;
        if (buttonState == HIGH) // only toggle the LED if the new button state is HIGH
        {
          led_status = !led_status;
        }
      }
    }
    digitalWrite(LED_BUILTIN, led_status); //set the LED
    lastButtonState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
  }
} // end of button_interrupt_handler

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(button_switch, INPUT_PULLUP); //no res = change to INPUT_PULLUP
  attachInterrupt(digitalPinToInterrupt(button_switch), button_interrupt_handler, FALLING); //no res = change to FALLING
  digitalWrite(LED_BUILTIN, led_status);
  initialisation_complete = true; // open interrupt processing for business
}

void loop()
{
  //do nothing
}

I am not sure what I am doing wrong or why this does not work.
EDIT: When I press the button, nothing happens at all.

I'd probably take a simpler approach. If the ISR is triggered, accept that and toggle the led then set a timer, as you have already done (lastDebounceTime). Use the timer to prevent subsequent calls of the ISR having any effect. When the timer expires (after 50ms) the ISR again behaves normally. An interrupt is, however, not usually the best way for handling a button and simply polling it every X ms is usually enough.

@jsotola Thanks! You are right, I edited the question.

Here is a non-blocking debouncing solution which is suitable also for electrically noisy environments. For example where there are long wires to the buttons which could pick up spurious signals. In this case, you cannot rely on short pulses being the direct result of button activity and must check that the button state has been stable for X ms before accepting it. It also handles potential bounces on the release of the button. It uses a simple finite state machine approach and does not use interrupts.
It can be tried also in a simulator: https://wokwi.com/projects/351021820324872788

const uint8_t ledPin = 13 ;
const uint8_t button_switch = 2;  // the button is wired between this pin and ground (LOW side)
const unsigned long debounceDelay = 100 ;    // the debounce time; increase if the output flickers

enum ButtonState  { PENDING_PRESS, IN_PRESS, PENDING_RELEASE} ;
ButtonState buttonState = ButtonState::PENDING_PRESS ;
uint32_t stateEnteredAtMs = millis() ;

void setup() {
  Serial.begin(115200);
  pinMode( ledPin, OUTPUT) ;
  pinMode( button_switch, INPUT_PULLUP) ;

}

void loop() {
  uint32_t ms = millis() ;
  static uint32_t lastButtonCheckAtMs = 0 ;

  if( ms - lastButtonCheckAtMs > 10 ) {

    switch ( buttonState ) {

     case ButtonState::PENDING_PRESS : {
        if ( digitalRead(button_switch)  == LOW ) {
          buttonState = ButtonState::IN_PRESS ;
          stateEnteredAtMs = ms ;
        }
        break ;
     }

     case ButtonState::IN_PRESS : {
        if ( digitalRead(button_switch) == HIGH )  {
          if ( ms - stateEnteredAtMs < debounceDelay ) {
            stateEnteredAtMs = ms ;
            buttonState = ButtonState::PENDING_PRESS ;
          }
          else {
            stateEnteredAtMs = ms ;
            buttonState = ButtonState::PENDING_RELEASE ;
            digitalWrite( ledPin, ! digitalRead(ledPin)) ;  // toggle led
          }
        }
        break ;
     }

     case ButtonState::PENDING_RELEASE : {
        if ( ms - stateEnteredAtMs > debounceDelay ) {
            stateEnteredAtMs = ms ;
            buttonState = ButtonState::PENDING_PRESS ;
          }
        break ;
     }
    }
    lastButtonCheckAtMs = ms ;
  }
}

Thank you! Does this code work for when the button press leads to LOW (this means no resistance), or when the button press leads to HIGH (this means button and resistor)?

@user1584421 The button is wired between Ground and the arduino pin. This means that when the button is pressed it is seen as LOW by digitalRead(). I added a link to a simulator. There it should also be clear how it is wired. I hope I've made that understandable.

Thank you. I hadn't clicked that link before. There is a weird behaviour when the button is pressed two times simultaneously. It doesn't register as two clicks. There has to be some time passed, until the second click can be registered. Also, can I take the loop() code and just place it in an external interrupt? I would like this to be inside an interrupt function.

@user1584421 That is not weird behaviour, that is filtering out potential bounces, You can adjust the parameter debounceDelay in the sketch. You can't run that sketch in an ISR because you can't hold up an ISR waiting for events like button release etc. However, if you want a ISR based solution, try here in the simulator: https://wokwi.com/projects/351221603927851607

Hmmm.. Thanks, but can you imagine how a can perform a button press inside an ISR? It does not matter if the button is connected to resistor or not (pin HIGH/LOW).

@user1584421 Try the code here https://wokwi.com/projects/351221603927851607 and say in what way it fails to meet your requirements. The button press forces an entry into the ISR. Once inside the ISR it cannot wait for more button activity. However, it  ensures that it is unaffected by bounces by locking out unwanted button pulses for a configurable period of milliseconds following the initial detection of a button press.

Thank you! I tried the code in real hardware, and wherever i press the button, the LED flashed briefly and then it turns off. It does not stay ON/OFF. Actually, the LED was just an experiment, in my practical application i want to build a state machine. Perhaps switch through states of an ENUM. One more observation i have to note has to do with this line last_entryAtMs = millis() ; The variable last_entryAtMs is static. Shouldn't there be an overflow protection in there as well?

Well the overflow point is not valid, since it is initialized at zero at every interrupt call. Unfortunately, i cannot edit the comment now.

@user1584421 The simulator runs slower than real time so some of the timings may have to be increased for usability, for example: debounceDelay = 300 ; . Static variables are initialised once only, NOT on each pass. An unsigned integer simply rolls over on overflow. millis() rolls over every approx. 50 days so there should be no big problem here.

Thank you so much! It worked! However, it is possible that my creation will be up for many many days. Therefore, it is essential that an overflow has to be taken care of. Where or how exactly should that happen?

In almost any run of the ISR it will read the button state as LOW, because the ISR is triggered by the falling edge. The time from the falling edge to the reading is very short, about microseconds, and therefore a level change is improbable.
As others already suggest, you can make the ISR "deaf" for some time after the accepted falling edge. You can do this inside the ISR. The approach is to accept subsequent triggers only if they are long enough after the former one.
Please be aware that some buttons bounce even when released. You might experience a trigger in such cases.
Anyway, do not base a decision on the reading of button state after its falling edge.

The most simple solution to read buttons is a cyclic timer with a period of several milliseconds. Take a sample each 50ms or so, and detect the button change in software. You don't even need to add debouncing code, if the period is longer than the bouncing time of your button.
Since this timer will commonly trigger an ISR, you have already an interrupt as source of the button state for other parts of your software.
If you want an extra interrupt, trigger some unused interrupt in software.

Thanks. If i don't base the reading of a button after its fallig edge, this means i have to use a resistor? Or i can achieve this without one?

No, of course you need defined levels at the input. With a simple SPST button you need a resistor. How else would the digital logic detect the falling edge? However, you can use an internal resistor, if the device provides one.

Take a look at this line in your code - the very first thing that is done in the ISR,
int reading = digitalRead(button_switch);
I think that the reason that your program does not “do anything” is because you are reading the button state inside the ISR and, because you trigger an interrupt on a falling edge, you will ALWAYS see 0 as the button state at that point. It can never change when you read it once at the beginning of the ISR, it will always =0, unless you stay in the ISR and wait for a change, which is a very, very, bad idea.
The rest of your comparisons and detections all fail because within the ISR, the button read is always going to be the same and = 0, because that is how you got to the ISR. As far as your program is concerned, the button has never been pressed or depressed.
It is true, depending on how you configure the button; a single state change will be detected because of initialization, but that is besides the point.
You can test this yourself by moving all of your variables to volatile globals and then in your loop run this:
void loop()
{
Serial.print("lastButtonState ");
Serial.println(lastButtonState);
Serial.print("buttonState ");
Serial.println(buttonState);
Serial.print("reading ");
Serial.println(reading);
}

You may have other problems, but that one stuck out to me.
I would suggest that you take a look at this project and see how he is doing it - https://create.arduino.cc/projecthub/ronbentley1/button-switch-using-an-external-interrupt-7879df
He does read the switch within the interrupt [I don't see why he needs to test the value since in his case it will always be HIGH]. The difference is that he uses the ISR only as a trigger. The rest of the reading of the switch to detect when there are state changes, is all done outside of the ISR.
Additionally, once an interrupt occurs, a triggered status is set and, thereafter the ISR just leaves until the status is changed to "not triggered" and that is done outside of the ISR. The accompanying article explains what he is doing in the code and why.
You are doing, literally nothing [after setup()] outside of the ISR and I think maybe you should re-think that approach.
I tested his program and it works fine. I note that he functionally defines a "press" as pressing and releasing the button (with associated debouncing). So, you don't see the led toggle until you press and release the button. That's not always how I would like it, but it is also besides the point.
Two other points...
Keep your ISR as short as you can. I don't have any hard core evidence, but, right or wrong, yours looks longer than I would be comfortable with.
Finally, I think you would enjoy this excellent thread on millis() inside an ISR. Using millis() and micros() inside an interrupt routine
To be sure, you are NOT using delays inside an ISR and there is nothing wrong with using millis() inside an ISR, but you need to be aware of the behavior.
That's my two cents - hope it helps.


text:
Analog Microphone values not changing
I just bought a microphone for my Ardoino Nano 33 BLE. The mic can use both Analog and Digital input. Here is the mic and how it's connected.
Here is the code where I read the input
int sensorPin = A5; // select the input pin for the potentiometer
int sensorValue = 0;
void setup ()
{
 Serial.begin (9600);
}
void loop ()
{
 sensorValue = analogRead (sensorPin);
 delay (500);
 Serial.println (sensorValue, DEC);
}

I've followed an example by the manufacturer and the reads are going random between 0 and 5 sometimes a little higher. It states in the example that it should go up to 1023.
Is something wrong, can I have connected something wrong that would make this? Also when I give 5v nothing happens on the Mic but if I connect 3.3v the mic turns on 2 red led lights and gives me a value around 80 but doesnt respond to any sounds.

"There is also this 10K potentiometer that is used to set a reference voltage for the op-amp, also this potentiometer is used to generate the reference voltage for the analog out function of the module." - https://circuitdigest.com/microcontroller-projects/interfacing-sound-sensor-with-arduino

/* edited to specifically provide a potential solution as commented by @jstola */
You have posted a picture of a ubiquitous sound detection sensor - typically a Keyes KY-037.
It is based on an LM393 dual comparator.

The board has a digital output [marked DO] and an analog output marked AO. It also has + and G (Ground) connections.

I dug mine out and attached it to a Nano 33 BLT.

Notice that I have + connected to 3.3v, G connected to ground and AO connected to A5.
A little trick is to connect just power and ground and turn the potentiometer until L2 (that's the LED nearest the pot) turns off. If you make some noise, you will see L2 flash briefly. This sets the digital output threshold and works well for testing the analog out.
Then I ran this simple program (very similar to yours)
void setup() {
  pinMode(A5,INPUT); // not absolutely needed in this case
  Serial.begin(9600);
}
void loop() {
  Serial.println(analogRead(A5));
}

Opened the Arduino IDE serial plotter (shift+ctr+L) and watched the waveform change when I snapped my fingers - see the spikes?.

So what is the solution to your problem that is does not work?
A couple of possibilities.

You have a different board.

Does your board look just like the one I posted or does it look different? If it is a different board then what you posted, that is another matter.
Assuming it is the same board (or at least the same generic board), it is possible that:

You don't have the connections correct. Double check that.

You don't have the pot set near the mid point - follow the direction for that and observe that the LED can be turned off. That is a multi-turn pot and if you hear a little 'click', you went too far in that direction - move it the other way and see if you can get that LED to just turn off.

Failing any of those, your board could be toast

Welcome! This is generic in nature because you did not provide any links to the hardware items so everything is a pure SWAG.
I cannot properly answer your question without knowing what board you have, there are several that look similar in red and other colors. Maybe the following will help you determine what you have. Look at the specifications closely.
Your statement "The mic can use both Analog and Digital input." The mic is analog by nature but can be converted to a digital signal with an op-amp  or comparator circuit as many of these modules have done.
It appears to me that your board will give you a logic 1 or zero, not an analog output. The pot on those generally sets the reference voltage for the comparator (may be an op amp) function, If it is a dual op amp the other half is an amp for the microphone. If there is an analog output the microphone signal needs to be amplified as the microphone output is only a few millivolts and the A/D needs volts.


text:
How to lower the power consumption of this ESP32 during delay(500)?
The following code works. It does the following:

wake up when pin GPIO0 is connected to GND  (the pulse duration is 400 milliseconds)
once every 10 wakings, I send the current index to a server with a HTTP request over WiFi
then go to deep sleep

Since GPIO0 is connected to GND during 400 milliseconds, it can reboot multiple times during these 400 milliseconds, which I don't want. So I added delay(500); at the end of the code.
Problem: this delay(500); is probably a waste of power, since the ESP32 is battery powered.
Question: by what could I replace this delay(500) to avoid that the ESP32 reboots multiple times while pin 0 is connected to GND during 400 milliseconds, with the least power consumption possible?
#include "WiFi.h"
#include "HTTPClient.h"
#include "esp_sleep.h"
byte WIFI_BSSID[] =         {0x01, 0x23, 0x45, 0x67, 0x89, 0x00};
String URL =                "http://example.com/submit?bootcount=";
RTC_DATA_ATTR int bootcount = 0;
HTTPClient http;
void setup() {
    bootcount++;
    pinMode(0, INPUT_PULLUP);
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0);
    if (bootcount % 10 == 0) {
        WiFi.begin("MySSID", "password", 0, WIFI_BSSID);
        while (WiFi.status() != WL_CONNECTED) {
            delay(20);
        }
        URL += bootcount;
        http.begin(URL.c_str());
        http.GET();
        http.end();
    }
    delay(500);
    esp_deep_sleep_start();
}
void loop() {
}

it happens during 400 milliseconds ... what does this mean? ... does the pin interrupt happen every 400 ms?

@jsotola It's like a switch: usually pin 0 is not connected to GND. Then when a pulse happens, during 400 ms pin 0 is connected to GND, it's the pulse duration.

so, you want the ESP32 to wake only on the transition of GPIO0 ... perhaps a simple circuit could be used to modify the input pulse ... maybe the ULP processor could be used

@jsotola Yes, since the pulse lasts 400ms, if I don't add the delay(500), multiple "wake_up+increment_bootcount+deep_sleep" sequences can happen during one signe pulse. I want to wake up only on the transition. Do you think there is a purely software way (without additional hardware components), other than my delay(500) solution? And possibly that doesn't require to stay fully powered during the 500ms?

If the chip cannot be waked by the transition, you might consider to use a timer. Start it when the delay shall start, disable the pin interrupt, and go to sleep. Let the timer overflow/interrupt wake up the chip again, stop the timer, enable the pin interrupt, and go to sleep. Please be aware that a running timer might not allow a deep sleep.

Instead of driving the Pin 0 directly, add a small capacity (0.1uF) in serial between the driver and the Pin0, so that it generate a short pulse during the transition but not during the entire holding down period.

@hcheung Thanks I will try this. Also, isn't there a 100% code solution without hardware? It fully works with delay(500), the only problem is that it probably consumes 100 mA or 200 mA during these 500 milliseconds. Is there a deep_sleep_delay(500) or something similar that would consume max 1 mA ?

As I suggested, a timer needs no additional hardware, your microcontroller certainly has such timers. In that sense this is a "100% code" solution, just try it. -- Since you say that there is no "edge-triggered" wake-up but only a "level-triggered" wake-up, delay(500) is the only "100% code" solution, as it simply runs an empty loop. Anything else needs something more to measure the time or change the trigger.

@thebusybee oh ok thank I initially didn't understand! Would you have a short code example to demonstrate this part (timer), as an answer?

Sorry, no, I don't have an ESP32 here, not to mention a compiler. Please try this yourself, this is the way you will learn. SE/Arduino is not a code writing service. ;-)

I know ;) @thebusybee btw I already wrote the code (in my question). But by experience, often the devil is in the details, so sometimes some code can be useful for an answer :)


text:
ESP8266 Wemos D1 Mini Pro v2.0 - Load sharing and battery
I have a simple question regarding the new version of Wemos D1 Mini Pro v2.0 and specifically about its load sharing circuitry. Schematic is here :
https://www.wemos.cc/en/latest/_static/files/sch_d1_mini_pro_v2.0.0.pdf
Battery charger is TP4054 and there's a load sharing configuration based on P-MOSFET CJ2301.
My question is what happens if you do NOT connect any battery.
It seems that the charging LED faintly flashes, and positive voltage appears in positive battery terminal. Moreover, voltage appears in A0 and ADC input (provided that SJ1 is connected), while someone would expect a zero voltage there, since there's no battery.
Am I missing something here? Is there any way to fix this issue?

If you are not using battery, the SJ1 should be cut off so that A0 can be used as the input source to the ADC.

I have test it and you are right. When you plug power into the USB connector with no battery connected to the Wemos D1 mini Pro v2.0.0 (provided BAT-A0 is connected) and I have got 1023, the maximum read into A0, when it should be 0.
I think a related problem is that when you are running with battery and you connect a charger into the USB port you can not read the battery voltage, you are getting always 1023, like if the battery was fully charged. So, you can use A0 to monitor battery voltage when discharging, but not when charging.


text:
A few Bitshifting questions!
So int in Arduino is 2 bytes, which could technically hold up to a value of 65535. However, the MSB is used as a sign bit, so now we have -32,768 to 32,767. So it's a signed integer, easy stuff. While I was messing around with bitshifting I ran across something interesting. If I do the following code:
int a = 1023 << 6;  // 1023 = 0b0000001111111111
Serial.println(a, BIN);

it returns a ridiculous number, 11111111111111111111111111000000, which is 4 bytes. I know this is some error with bit shifting into the signed bit, because if I do
int a = 1023 << 5;  // equals 111111111100000 as expected

It works just fine. Question 1: What is happening here? Where is that number coming from?
So I got smart (so I thought) and was like okay, if I need more bytes, then I'll just use long. So I tried the following code:
long a = 1023 << 6;
Serial.println(a, BIN);

I figured I'd have 3 "extra" bytes to shift my number into. However, the same number is returned. Question 2: What is happening?
Question 3: What is the order of operations with bitshifting?
Wire.write(CMD_VDR | PD_NPD | voltageLevel >> 6);

This code I wrote produces the correct result. However, what is the order of operations? Is it just left to right? Putting voltageLevel >> 6 in parenthesis does not change the output. It's working fine but I want to know why!
Thanks!

Your third part was tacked on after I'd started answering and it is largely unrelated to the rest of it. You can probably sort it out by looking at this.

research  sign extend

Please do not put multiple unrelated questions in one post.

timemage provided an excellent answer to your first question (upvoted!).
Let me try to answer the subsequent ones:

long a = 1023 << 6;

Here you are evaluating 1023 << 6, then assigning the result to a
long. It is important to realize that the C++ rules for evaluating an
expression do not depend on what you are going to do later with the
result. Given that 1023 is an int constant, the expression has the
type int and is evaluated as such. The result is then undefined
behavior, which just happens, because you are unlucky, to give
the expected value, i.e. −64.
Assigning −64 to a long converts the type while preserving the value.
This is sign extension at work. As explained by timemage,
println(long, int) casts the value to unsigned long, hence the
result you see.

What is the order of operations
[in the expression CMD_VDR | PD_NPD | voltageLevel >> 6]?

The shift has higher precedence than the bitwise OR. The expression is
thus equivalent to
CMD_VDR | PD_NPD | (voltageLevel >> 6)

C.f. C++ Operator Precedence.

Thank you for sharing the precedence list! That's quite helpful.

Well, technically I did attempt to answer the second one. It just wasn't as clear as how you'd put it. The storage I was talking about was the intermediate result of the right-hand side, which applies to both of their expressions. But, since you've written this I'm just going to vote yours up rather than try to clarify what I meant.

So int in Arduino is 2 bytes

This is not true in the general case, for what it's worth. It is true of the AVR based Arduinos though, which I'll assume are in use below.
Strictly speaking, when you do int a = 1023 << 6; with a 16-bit integer, all bets are off, because you're already in undefined behaviour. 1023 is type int right hand side is expected to be of type int and trying to store something that won't actually fit in a signed integer is undefined.
But for the moment, lets just say it does roughly what you expect with the bit pattern, like it would for an unsigned type. You've produced the bit representation for a signed 16-bit integer with the value -64.
You're calling the println(int, int) here.
It's in turn calling println(long, int) here. It is only handling signedness for base 10. So, you are just forwarding your -64 value to printNumber here, which handle unsigned long values (which may have been prefixed by - for base 10).
So you are converting a -64 into an unsigned long. Conversion to unsigned types reduce modulo their maximum value plus 1.  The 32-bit unsigned long maximum is 0xFFFFFFFF, with one added you get 0x100000000. In other words, you're ultimately printing 0x100000000 - 64, which is the number you're seeing.
1023 << 5 does not overflow the 16-bit signed int. Does not result in a negative number (again if we're being charitable about undefined behavior) and so you see different result.

"It is true of the AVR based Arduinos though," - (Not calling you out on this, but) for completeness it's worth mentioning that int is 2-bytes on an AVR Arduino with the gcc compiler because that is what the implementers of that compiler chose for it to do. Another C/C++ compiler on the same hardware might do things differently. Which is to say, the width of int is not a function of the hardware but of the compiler. The width of int is usually chosen as the native word size of that hardware, but on an AVR, that would be 8 bits which isn't nearly as useful as 16.

@JRobert Yeah, I didn't know how far into the weeds they wanted to go. It actually wouldn't be compliant to have a 8-bit int type an account of it not meeting the minimum required range, though gcc will let you do it with -mint8.  But yeah, a compliant compiler could target the AVR and do any number of things like that. E.g. you could make all of the integer types 64bit, even the char type and have CHAR_BIT be 64. Again, it's difficult to know where to stop with it.

I could put something like "The actual range of the int type is determined by the compiler rather than hardware. It is subject to the standards requirements to the extent that the compiler is trying to adhere a standard, which is partly under the control of what options have been specified to the compiler. The intention is normally to have it follow the standard and where possible to have it follow some notion of the natural integer size of the underlying architecture." or shorter "without going into the details it is ultimately the compiler that determines the int type size."

Thank you for the detailed response

@timemage: Fair enough! I do tend to see the details....


text:
Ramping servo motor taking longer than calculated
I'm learning how to code a "BOE Shield bot" with a partner at my university (first year). To clarify for those that do not know: a BOE Shield bot is a small robot equipped with 2 servo motors, a battery pack and an Arduino Uno. If you google the name you'll find plenty of pictures.
We were tasked to code a program that would make the robot accelerate the continuous rotational servo motors according to a given velocity-time graph in RPMs and seconds. We wrote the code, followed a pretty logical method, and passed the assignment. However one thing, and I spent days on trying to fix it, is still confusing me. The code is ahead, I've tried to make it as readible as possible. The RPM to PWM conversion for the motors is:  PWM = 2 \times RPM + 1500
#include <Servo.h>

class motor {
public:
  double Speed = 0;  //The actual speed of the servo in RPM
public:
  Servo servo;

  //returns true if the desired speed "newSpeed" is reached, otherwise increments the current speed and returns false.
  //increment is the calculated speed increase based on the differance in time (interval) and the acceleration which is constant.
  bool accel(double increment, double newSpeed) {
    if (abs(Speed - newSpeed) < 0.1) {
      return true;
    }

    Speed += increment;
    return false;
  }

  void writeMS(double value) {
    servo.writeMicroseconds(value);
  }
};

motor servoLeft = motor();
motor servoRight = motor();

void setup() {
  Serial.begin(9600);
  servoLeft.servo.attach(11);   //vänster -2 * speedLeft + 1500
  servoRight.servo.attach(10);  //höger 2 * speedLeft + 1500
}

//This nested array contains instructions for both servo motors: the desired speed, how long it should take to accelerate to it and how long
//the instruction duration is. The first instruction starts from the second row. The first row is skipped and only used for calculations.
//The columns are in the following order: {instruction length in ms, speed of the left motor in RPM, speed of right motor in RPM, acceleration time}.
double instructions[7][4] = {
  { 0, 0, 0, 0 },
  { 3000, 25, 25, 500 },
  { 2550, 50, 10, 500 },
  { 3000, 25, 25, 500 },
  { 2850, 10, 50, 500 },
  { 3000, 25, 25, 500 },
  { 3000, 15, -15, 500 },
};

//time stuff
unsigned long currentMillis;
unsigned long previousMillis = 0;
unsigned long lastInstructionMillis = 0;
const double interval = 20;

//i is the index for the instructions.
int i = 0;
bool updateL = false;
bool updateR = false;

//the speed increments for each servo. Calculated in the loop.
double incrementL;
double incrementR;

void loop() {
  //This is to help keep track of the time so we can calculate the increments. It essentially means the speeds are only updated ever 20ms.
  currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    //if the desired speed is reached, stop updating. This is just to optimize code.
    if (updateL)
      updateL = !servoLeft.accel(incrementL, instructions[i][1]);

    if (updateR)
      updateR = !servoRight.accel(incrementR, instructions[i][2]);
  }

  //this runs only once after each instruction.
  if (currentMillis - lastInstructionMillis >= instructions[i][0]) {
    lastInstructionMillis += instructions[i][0];
    i++;

    //exit program after all instructions have been completed.
    if (i == 7)
      exit(0);

    //the increments are calculated like such: increment = acceleration * interval
    //where constant acceleration = (newSpeed - oldSpeed) / accelerationTime
    incrementL = (instructions[i][1] - instructions[i - 1][1]) * interval / instructions[i][3];
    incrementR = (instructions[i][2] - instructions[i - 1][2]) * interval / instructions[i][3];

    updateL = true;
    updateR = true;
  }

  Serial.println((String)servoLeft.Speed + " " + (String)servoRight.Speed + " " + (String)currentMillis + " " + (String)i);

  //the actual ms signlas sent to the servos.
  servoLeft.writeMS(2 * servoLeft.Speed + 1500);
  servoRight.writeMS(-2 * servoRight.Speed + 1500);
}

For some reason the acceleration is taking longer than specified in the instructions. For example, the first instruction specifies that both servos will accelerate from 0 to 25 RPM within 500ms. But printing out the speeds and time to the serial monitor shows that it actually takes around 860ms. That is if interval is set to 20. If it's set to 50, it takes 560ms.
Suspected causes were:

Void loop taking longer than the interval

Not the case as measuring it with micros() proved it never took longer than 0.26ms; this was the done with complete program as well.

Rounding errors

Not the case as switching pretty much all the number types to double still didn't fix anything. And double is more than enough precise for this program.

millis() not being accurate enough

I don't believe this is the case. I researched how accurate it actually is, and while it's nowhere near perfect, it should be accurate enough for the program. I tried using micros() instead and that lead to the same result, I do not know if that means something.
Other than that I have no idea what the cause could be. The code itself runs fine, and the robot actually seems to be following the instructions perfectly with no errors. It's just that the speeds and accelerations aren't accurate for some reason.

Have you seen this? https://forum.arduino.cc/t/use-of-exit-0/210352

Are you sure you are properly driving the motors and that they are not slipping?

From Arduino reference on double: "On the Uno and other ATMEGA based boards, this occupies 4 bytes. That is, the double implementation is exactly the same as the float, with no gain in precision."

When you call the accel() method of your class, you provide first the second and third element of the array describing the instruction. These are the target speeds according to your comment. Then as second parameter you are providing incrementL or incrementR. So first target speed, then increment. But the function definition has this the other way round: First the increment, then the new speed. Please try switching the parameters at either the function definition or the function calls. Does it work correctly then?

@VE7JRO I do not think that is the issue. While I am aware how "taboo" exit is, it is only used at the end of the program. It has no effect on anything else.

@Gil well see, the values are not actually dependent on the motors. In other words when I run the program with the servos turned off, it still works. The speed variable within the motor class doesn't read the actual speed of the servos. It just contains the calculated value that we then use to write to the servos. So this issue is not at all caused by the servos.

@chrisl Isn't that precise enough for double? I printed the increments to the serial monitor and they were correct so I do not think that's the problem. The speeds are increasing correctly the only problem is it's taking longer than planned.
As for your second comment, sorry that's just a typing mistake. I will edit the question so it's correct. I rewrote bits of the code and cleaned it up for the question so it would be more readable. I guess I mistakenly switched the values. That would still not have been the issue because the robot wouldn't have worked at all.

Yes, float precision should be enough. Are you sure about the duration of loop()? Currently you are pretty much spamming the Serial interface. At only 9600 baud that will take some time (as priting waits until enough space is free in the buffer)

There are two things going on here.
You are printing too much to the serial port. After the first second
(between 1000 and 9999 ms), each line you print is 20 bytes, including
the CRLF terminator. At 9600 b/s, each bytes takes 1.04 ms (1 start bit,
8 data bites and 1 stop bit). This is about 20.8 ms for the whole line,
which is slightly longer than interval. You should either print less
often (say, every other loop iteration) or faster. Just moving to the
next standard speed (19200 b/s) will be enough to ensure you do not miss
any interval. You can go faster though.
The second issue is the way you keep track of previousMillis:
if (currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;
  // ...
}

This is prone to accumulating errors. The test will most likely not
happen exactly at previousMillis + interval, mostly because of the
serial port. You are a little bit late and, by updating previousMillis
this way, these errors are cumulative. You can avoid this by updating
previousMillis as:
previousMillis += interval;

You will still have timing errors, but these will manifest themselves in
the form of jitter, not as a systematic timing drift.
Interestingly, you are updating lastInstructionMillis the right way!

Edit: Here are some extra comments about your question and your
sketch, not necessarily related to the problem you are seeing.
You wrote:

measuring [loop()] with micros() proved it never took longer than
0.26ms.

It seems you measured incorrectly. Maybe you measured a version of the
program that was not printing so much to the serial port. Or maybe you
looked only at the first iterations of the loop, where
Serial.println() is fast because the output buffer hasn't filled yet.
The following code is fragile:

bool accel(double increment, double newSpeed) {
  if (abs(Speed - newSpeed) < 0.1) {
    return true;
  }
  // ...
}

The value 0.1 is arbitrary, and the “right choice” is dependent on the
program timing. I suggest something more robust, like:
bool accel(double increment, double newSpeed) {
  if (increment > 0) {
    Speed = min(Speed + increment, newSpeed);
  } else {
    Speed = max(Speed + increment, newSpeed);
  }
  return Speed == newSpeed;
}

Note that, although it is generally recommended to not test floating
point numbers for exact equality, in this case it is safe, because
min() and max() return exactly one of their arguments.
The optimization consisting of calling motor::accel() only during the
acceleration phase is futile: this methods takes an very tiny fraction
of the loop() time. In the same vein, there would be no harm in
calling Servo::writeMicroseconds() on every loop iteration, even if
some of the calls turn out to be useless.
The code would be more readable if instructions was an array of
struct rather than an array of arrays: this way the fields of each
instruction could have evocative names rather than numeric indices.
You are using too much floating point here. Most of the data fields,
including all the contents of instructions, could be integers of
suitable length.

I do not currently have access to the robot, it's with my partner. But I'm very excited to try out this solution. I think you may have found the problem. @chrisl already hinted toward the serial interface spamming with the short speed. All your other suggestions are appreciated and insightful as well. I will try to get my hands on the robot as quickly as I can. In the meantime I will accept your answer as I'm pretty sure you solved it. If not, I will get back to you. It's the end of of the semester so I might not be able to access the robot and I don't want the question left unanswered.


text:
FastLED WS2812B with Esp8266 Wemos D1 mini shows 1 first led only
I'm working with WS2812B LED Strip (and Ring), Esp8266 Wemos D1 mini and FastLED library. I want to show  leds with same solid color in every startup.
There is a strange behavior that only the first 1 Led lights up. The code is very simple:
#include <FastLED.h>

#define NUM_LEDS 24
#define DATA_PIN D6

CRGB leds[NUM_LEDS];
void setup()
{
  uint8_t i = 0;
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(50);

  for (i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB::Black;
  }

  for (i = 0; i < 7; i++) {
    leds[i] = CRGB::Red;
  }
  FastLED.show();  //1 show() lights up only first led
}

void loop() {
}

If I add one more show() call, it works as expected.
#include <FastLED.h>

#define NUM_LEDS 24
#define DATA_PIN D6

CRGB leds[NUM_LEDS];
void setup()
{
  uint8_t i = 0;
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(50);

  for (i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB::Black;
  }

  for (i = 0; i < 7; i++) {
    leds[i] = CRGB::Red;
  }
  FastLED.show();   //1st show()
  FastLED.show();   //2nd show() works as expected
}

void loop() {
}

I'm not sure what the correct way to show LEDs is. This is just a short code from my bigger project, I made it minimal for debugging. Please help me this.
Thank you.

have you tried example code that is included with the library?

@jsotola the example codes are color animation. I just want to show solid color. Could you please let me know what I am missing?

does the example code work as expected?

@jsotola The example code animation run so fast so I don't know what the first color is expected.

I tried Blink example with little changes
void loop() {
// Turn the LED on, then pause
leds[0] = CRGB::Red;
leds[1] = CRGB::Red;  //Added
FastLED.show();
delay(500);
// Now turn the LED off, then pause
leds[0] = CRGB::Black;
leds[1] = CRGB::Black;  //Added
FastLED.show();
delay(500);
}
At start up, it shows only the first LED, after that 2 LEDs are blinking -> The same issue with mine

@hcheung it's not a proper way to put show() into for loop. As I mentioned, this is just a small part of my bigger project where has hundreds of leds. Moving show() into loop cause the system very slow

@hcheung as per my understanding, show() will clock ALL data out. It means if there is 500 leds, one show() will clock 500 data out. Therefore, if you put show() in loop, it will clock out 500*500 data - 250000 data which will cause system hanged up. Have you tried with lednum = 500 and print the execution time after a loop?

Not sure if it's relevant but I recall hearing/seeing/reading somewhere that you should "clear" (turn off) all LEDS (using .show()) before displaying what you want ... so, it kinda means that the minimum number of calls to .show would be two

@JaromandaX Wow... that's a useful information that I've never read before. Do you remember that the "clear" show() should be called everytime or just the first time in setup()?

just once in setup of course ... you don't want to keep "blanking" the LED, that would be annoying ... since most uses of WLED are in the loop(), most would not probably notice that the "first" show() doesn't work right ... but, again, I'm not 100% sure of the veracity of my comment

@JaromandaX ok, thank you very much for your information


text:
ATTiny85(Digispark) not connected/recognized
I have 1xDigispark(ATTiny85) from Amazon https://www.amazon.pl/gp/product/B076KS2QDS/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&th=1.
When i connect it into USB port nothing happen i didn't get windows sound alert.
And Arduino IDE not detecting it(Not displayed as a port).

I have this link to the drivers in settings and drivers installed.
When I try to upload a code with "COM1" port nothing relly happens.
Regards,
Wiktor Wołos

You have the wrong board selected in your IDE
This

Is a "Digispark (Default 16.5 mhz)" (sic) not a "Digispark Pro". The latter is based on an ATtiny167 not an ATtiny85.
I have bought the exact same item from the same seller.

Thanks, but for me i not working... :(

And I have message sending completed before i see "Plug in device now... (will timeout in 60 seconds)" isn't it weird?

@asdads this information does not belong in a comment to an answer ... it belongs in the question at the top of this page, so that everyone will see it


text:
Sketch uses 33218 bytes (102%) of program storage space. Maximum is 32256 bytes?
I need to upload code on atmega328 wihout bootloader
https://github.com/EasyOne2030/test
but see Sketch uses 33218 bytes (102%) of program storage space. Maximum is 32256 bytes ?

If you eliminate the use of PPT_bits, you would have sufficient memory already. Alternative, you had 4 images representing RSSI, 5 images representing battery, and 3 images representing volume, if you eliminate one each, you would have sufficient memory also. If you insists to have all of them, then change the MCU to have bigger flash.

In the case where the size of the program (sketch) has become too large for the available program storage space (flash memory), there are a number of options. Note that this is not the same case as exceeding the amount of dynamic memory (RAM) which requires a different set of solutions.
_1. Microcontroller (MCU) upgrade.
This can be a solution. The closer
the architecture of the new MCU matches that that of the old MCU the
easier this is likely to be. However, this approach can become
complex, even when using a different MCU in the same series as the
original, if low level configuration of (and access to) hardware
peripherals such as timers, ports etc. has been used. Be aware that
any libraries used may not be compatible with the new MCU so testing
is important. In the worst case, there may be no supporting Arduino
core available for the new MCU. Major incompatibilities can be
tested with a simple compilation of a sketch for the new target MCU
and this does not even require the new MCU to be present.
In the
specific case of the ATmega328P, this is already the highest
specified MCU in its series so a new MCU is required to increase
resources such as Flash memory, RAM etc. An ATMega1284 may be a
possible replacement within the AVR range. Also to consider is an
ATmega4809 (newer megaAVR range) based board such as the Nano Every
but here there are more significant architectural differences
_2. Optimising the use of flash memory.
_2.1 Bootloader.
Sometimes, changing the bootloader for a smaller one can help. For example, with some Arduino Nanos, this can free 1.5KB of flash memory by changing to the same bootloader which is used on the Arduino Uno (Optiboot). Dropping the bootloader altogether and using an ISP programmer (or an Arduino configured as one) to program the MCU can also save flash memory. Here it is important to select an Arduino core which supports a "No Bootloader" option to achieve the maximum benefits from this approach. The core "Minicore" https://github.com/MCUdude/MiniCore is such an example. Important to note is the the Arduino IDE (base 1.8.19) has a special upload procedure when using a programmer (Sketch--> Upload using programmer).
Note also that the target (AVR) MCU must have the fuses correctly set for "no bootloader" operation. That is the fuse BOOTRST must be unset. This is achieved by using the "burn bootloader" option supplied by the core. Despite its (inappropriate) name this has the effect of setting the fuses. Alternatively, the fuses can be set manually using the AVRDUDE command line.
_2.2 General.
The compiler is quite good at optimising code however, it is important to be aware that the use of some program features can have a one time penalty when used. Examples are the String class, sprintf(), floating point handling etc. which force a large amount of code to be added to the compiled sketch. Some libraries can consume a large amount of program memory. Graphic libraries are notorious for this because often these include large font tables etc. Here the options are limited to looking for a lighter weight library or a hacking out unused parts of an existing library.

I need to upload code on atmega328 wihout bootloader

@onenext Download and install "MiniCore" from the location in the answer above. The readme.md there has a "how to install" section.
Once you have  correctly installed this, then from the Tools menu in the Arduino IDE select: Boards -> Minicore -> 328P. Again in the Tools menu, select the Bootloader Option and choose "No Bootloader". Once your sketch is ready to upload, you connect your programmer and use the special upload function under the sketch menu "Upload using Programmer". This procedure will give you an extra 256 bytes of program memory (flash).

I have  usbasp avr programmer and AVRDUDESS   Ineed hex file to uplod this code on atmega328 but When  export compiled binary  i see error message ........ Sketch uses 33198 bytes (102%) of program storage space. Maximum  is 32256 bytes.
Global variables use 966 bytes (47%) of dynamic memory, leaving 1082 bytes for local variables. Maximum is 2048 bytes ......   You can have a look at the original project   https://youtu.be/EPfLin7sqp4   ...

To recover the 512 bytes (my first comment incorrectly said 256) which is allocated to the bootloader, the recommendation is to use minicore. You do, however,  also have the option of hacking a new entry into the boards.txt file of the standard Arduino core, if you prefer. See:
https://forum.arduino.cc/t/boards-txt-definition-for-no-bootloader/630225

was unsuccessful

@onenext Which method did you try? Minicore or hacking boards.txt in the standard core? Did you fail to reduce the program size to 32,768 bytes or less or did the program fail to run after being uploaded? I can't try with your code because some local libraries are missing from the repository.

Minicore and  hacking boards.txt  Project files https://drive.google.com/file/d/1vLRAP2AkSIFmFd-1AyrlVtAfuOZqbbNy/view  How did he succeed .... https://youtu.be/EPfLin7sqp4 .... Please watch this  video

I've added an answer specifically related to Minicore, mainly because it may also help someone else. Much more I cannot do. I've used a test file and am not going to download the suggested RAR file. I've looked at the video (but don't speak Russian). However, (a) that is a project of considerable complexity so I guess your problems are only just starting (b) I notice its author has not responded positively to your style of  extremely brief problem reports.

Using Minicore  to compile and load a program onto an ATmega328P without a bootloader. Screen shots and sample output.
Resources used

CH340 ATmega328P Arduino Nano clone
A programmer (Nano based) running the Arduino ISP sketch
Minicore 2.1.3   https://github.com/MCUdude/MiniCore
Arduino IDE 1.8.19

/*
   Example sketch to use all flash memory of an ATmega328P
*/

const uint8_t bigArray[30121] PROGMEM = {0} ;

void setup() {
  Serial.begin( 115200 ) ;
  Serial.println("test-01" ) ;
  byte buffer = pgm_read_byte_near(bigArray+50); // stop compiler optimising the array away
  Serial.println(buffer ) ;
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Select Board

Select Programmer

Select No Bootloader

Verify

Burn Bootloader /set fuses

Yes, even though you don't want a boot loader, you have to do this to correct the fuses (specifically, BOOTRST is unset by this procedure)
. . .
. . .
Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0f:
avrdude: load data lock data from input file 0x0f:
avrdude: input file 0x0f contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lock verified

avrdude done.  Thank you.

Upload Using Programmer

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware -hardware C:\Users\6v6gt\Documents\ArduinoData\packages -hardware C:\Users\6v6gt\Documents\Arduino\hardware -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\tools-builder -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware\tools\avr -tools C:\Users\6v6gt\Documents\ArduinoData\packages -built-in-libraries C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\libraries -libraries C:\Users\6v6gt\Documents\Arduino\libraries -fqbn=MiniCore:avr:328:bootloader=no_bootloader,eeprom=keep,variant=modelP,BOD=2v7,LTO=Os,clock=16MHz_external -vid-pid=1A86_7523 -ide-version=10819 -build-path C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964 -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avrdude-6.3.0-arduino18.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.arduinoOTA.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.avr-gcc.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -verbose C:\Users\6v6gt\Documents\Arduino\big_flash_V0_01\big_flash_V0_01.ino
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\arduino-builder -compile -logger=machine -hardware C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware -hardware C:\Users\6v6gt\Documents\ArduinoData\packages -hardware C:\Users\6v6gt\Documents\Arduino\hardware -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\tools-builder -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware\tools\avr -tools C:\Users\6v6gt\Documents\ArduinoData\packages -built-in-libraries C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\libraries -libraries C:\Users\6v6gt\Documents\Arduino\libraries -fqbn=MiniCore:avr:328:bootloader=no_bootloader,eeprom=keep,variant=modelP,BOD=2v7,LTO=Os,clock=16MHz_external -vid-pid=1A86_7523 -ide-version=10819 -build-path C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964 -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avrdude-6.3.0-arduino18.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.arduinoOTA.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.avr-gcc.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -verbose C:\Users\6v6gt\Documents\Arduino\big_flash_V0_01\big_flash_V0_01.ino
Using board '328' from platform in folder: C:\Users\6v6gt\Documents\ArduinoData\packages\MiniCore\hardware\avr\2.1.3
Using core 'MCUdude_corefiles' from platform in folder: C:\Users\6v6gt\Documents\ArduinoData\packages\MiniCore\hardware\avr\2.1.3
Detecting libraries used...
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++17 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ATmega328 -DARDUINO_ARCH_AVR "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\cores\\MCUdude_corefiles" "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\variants\\standard" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\sketch\\big_flash_V0_01.ino.cpp" -o nul
Generating function prototypes...
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++17 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ATmega328 -DARDUINO_ARCH_AVR "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\cores\\MCUdude_corefiles" "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\variants\\standard" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\sketch\\big_flash_V0_01.ino.cpp" -o "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\preproc\\ctags_target_for_gcc_minus_e.cpp"
"C:\\Program Files\\WindowsApps\\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\preproc\\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++17 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ATmega328 -DARDUINO_ARCH_AVR "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\cores\\MCUdude_corefiles" "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\variants\\standard" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\sketch\\big_flash_V0_01.ino.cpp" -o "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\sketch\\big_flash_V0_01.ino.cpp.o"
Compiling libraries...
Compiling core...
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -c -g -x assembler-with-cpp -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ATmega328 -DARDUINO_ARCH_AVR "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\cores\\MCUdude_corefiles" "-IC:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\variants\\standard" "C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\MiniCore\\hardware\\avr\\2.1.3\\cores\\MCUdude_corefiles\\wiring_pulse.S" -o "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring_pulse.S.o"
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\hooks.c.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\WInterrupts.c.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\wiring.c.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\wiring_shift.c.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\wiring_digital.c.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\wiring_analog.c.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\wiring_pulse.c.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\CDC.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\HardwareSerial1.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\HardwareSerial2.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\HardwareSerial.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\IPAddress.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\PluggableUSB.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\HardwareSerial3.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\Stream.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\Print.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\HardwareSerial0.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\Tone.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\abi.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\USBCore.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\new.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\main.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\wiring_extras.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\WMath.cpp.o
Using previously compiled file: C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964\core\WString.cpp.o
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring_pulse.S.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\WInterrupts.c.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\hooks.c.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring.c.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring_analog.c.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring_digital.c.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring_pulse.c.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring_shift.c.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\CDC.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\HardwareSerial.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\HardwareSerial0.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\HardwareSerial1.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\HardwareSerial2.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\HardwareSerial3.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\IPAddress.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\PluggableUSB.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\Print.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\Stream.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\Tone.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\USBCore.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\WMath.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\WString.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\abi.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\main.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\new.cpp.o"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-ar" rcs "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\core.a" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\core\\wiring_extras.cpp.o"
Linking everything together...
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -Wall -Wextra -Os -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino.elf" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964\\sketch\\big_flash_V0_01.ino.cpp.o" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/core\\core.a" "-LC:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964" -lm
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino.elf" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino.eep"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -R .eeprom "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino.elf" "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino.hex"
cmd /C "C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objdump" --disassemble --source --line-numbers --demangle --section=.text "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino.elf" > "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino_atmega328p_16000000L.lst"
"C:\\Users\\6v6gt\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\6v6gt\\AppData\\Local\\Temp\\arduino_build_577964/big_flash_V0_01.ino.elf"
Sketch uses 32640 bytes (99%) of program storage space. Maximum is 32768 bytes.
Global variables use 196 bytes (9%) of dynamic memory, leaving 1852 bytes for local variables. Maximum is 2048 bytes.
C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18/bin/avrdude -CC:\Users\6v6gt\Documents\ArduinoData\packages\MiniCore\hardware\avr\2.1.3/avrdude.conf -v -patmega328p -cstk500v1 -PCOM6 -b19200 -Uflash:w:C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964/big_flash_V0_01.ino.with_bootloader.hex:i

avrdude: Version 6.3-20201216
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\6v6gt\Documents\ArduinoData\packages\MiniCore\hardware\avr\2.1.3/avrdude.conf"

         Using Port                    : COM6
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964/big_flash_V0_01.ino.with_bootloader.hex"
avrdude: writing flash (32640 bytes):

Writing | ################################################## | 100% 35.80s

avrdude: 32640 bytes of flash written
avrdude: verifying flash memory against C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964/big_flash_V0_01.ino.with_bootloader.hex:
avrdude: load data flash data from input file C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964/big_flash_V0_01.ino.with_bootloader.hex:
avrdude: input file C:\Users\6v6gt\AppData\Local\Temp\arduino_build_577964/big_flash_V0_01.ino.with_bootloader.hex contains 32640 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 19.57s

avrdude: verifying ...
avrdude: 32640 bytes of flash verified

avrdude done.  Thank you.

Compiler LTO  when he chose  LTO enabled it work !  is this good ?

@onenext LTO = Link Time Optimisation. If the author of that project enabled it then you should also enable it.

the author of that project disabled it   thank you so much  I will try


text:
ESP32 can not deep sleep longer than 35 minutes
I'm trying to get my Lilygo T5 4.7" epaper to deep sleep for 12 hours.
But I only seem to be able to get about half an hour (2100s) of deepsleep on it.
If I set the timer for longer, it just reboots right away.
#include <Arduino.h>
#include "epd_driver.h"

long DEEP_SLEEP_TIME_SEC = 43200;

void start_deep_sleep()
{
    epd_poweroff_all();
    esp_sleep_enable_timer_wakeup(1000000L * DEEP_SLEEP_TIME_SEC);
    Serial.println("Starting deep-sleep period...");
    esp_deep_sleep_start();
}

void setup() {
  Serial.begin(115200);
  Serial.println("\n- - - - - - - - -INITIALIZING - - - - - - - - - -");
  delay(10000);
  start_deep_sleep();
}

void loop() {
}

The sbove code gives the following:
16:44:25.104 -> - - - - - - - - -INITIALIZING - - - - - - - - - -

16:44:35.105 -> Starting deep-sleep period...

16:44:35.105 -> ets Jul 29 2019 12:21:46

and it just continues to reboot..

Maybe I'm using the wrong variables in some way?
Regards
Kasper

refer the ESP32 datasheet for the longest deep sleep available

I will try Ul tommorrow, but searching the datasheet for timer and sleep didn't help me learn how long it will go to sleep for..

I don't know what the max duration is, but the function you're calling seems to accept uint64_t, in which case you're probably looking for 1000000ULL rather than 1000000UL. Or uint64_t(1000000) or (uint64_t)1000000 or static_cast or ... whatever. In other words, the same thing Juraj appears to be saying, only more so.

alright, so I changed this esp_sleep_enable_timer_wakeup(1000000ULL * DEEP_SLEEP_TIME_SEC); and tried for 1 hour (3600s) and that worked (+- 15 seconds). Could you post an answer @timemage, so that I can close the question? Still unsure as to how long it will work for.. I don't seem to have the problem @hcheung suggests..

I can, I kind of figured Juraj had dropped an L and was otherwise thinking this, but I see their comment is gone.

So, formalizing this into an answer:
long DEEP_SLEEP_TIME_SEC = 43200;
// ...
esp_sleep_enable_timer_wakeup(1000000L * DEEP_SLEEP_TIME_SEC);

This is attempting to calculate the result of 1000000L * DEEP_SLEEP_TIME_SEC as a long type because both operands are of long type. The language does not consider the values of the operands (your constant and variable) of an operator (the multiplication) when determining the type of the result (the product) nor what you do with the result after that (passing it to the function).
The long type on ESP32 has a maximum value of 2147483647 which is as you said, "about half an hour" (not quite 36 minutes) worth of microseconds.
According to the documentation esp_sleep_enable_timer_wakeup accepts a uint64_t type for its requested duration parameter. I don't know what the valid maximum value to call with is, but the original poster confirmed it was large enough for 12 hours.
An unsigned long long is 64-bit on the ESP32 and the ULL suffix on 1000000ULL forces the compiler to only consider types which are unsigned and which are not smaller than a long long. In practice it means make me an unsigned long long with value 1000000. In
esp_sleep_enable_timer_wakeup(1000000ULL * DEEP_SLEEP_TIME_SEC);

the compiler follows something called the usual arithmetic conversions which will cause it to upconvert the long type of DEEP_SLEEP_TIME_SEC to match the unsigned long long that it is finding in 1000000ULL. The multiplication is therefore carried out in the unsigned long long type, so that the calculation itself accommodates more microseconds than you'll ever know what to do with. What the actual maximum is for esp_sleep_enable_timer_wakeup is still unclear. If I find out I will update with that information.

The ESP32-Arduino support comes with a fairly complete C++ standard library. So, if you want to get fancy you can use the <chrono> header. Just to give an example of what that could look like in your context:
#include <chrono>
// ...
static constexpr auto DEEP_SLEEP_TIME = std::chrono::hours{12};
// ...
esp_sleep_enable_timer_wakeup(
    std::chrono::duration_cast<std::chrono::microseconds>(
        DEEP_SLEEP_TIME
    ).count()
);

I'm being very explicit in the above. But you can import parts of the chrono namespace so you don't have to name everything fully. You can also import chrono literals support so that you can use time constants that look more like natural language(not yet apparently; there's still no C++14 support in Arduino-ESP32 I guess). You can control the underlying integer type used to represent the unit. It is also possible to create and name your own duration types to represent things like bit durations in a serial protocol etc. The default underlying type for chrono::microseconds is large enough for what you're doing; the default widths of underlying types are generally pretty sensible.  Different time units are different std::chrono types so you can't mix them up accidentally. duration_cast is a means of explicit conversion of time units. The .count() in the above is just a way to get the raw integer value out of the chrono type for when you need to do that, like calling this function.
If you wrap the function with your own taking std::chrono::milliseconds the unit conversion could just happen automatically in the call to your own wrapper:
static constexpr auto DEEP_SLEEP_TIME = std::chrono::hours{12};
//...
esp_err_t esp_sleep_enable_timer_wakeup_using_chrono(
  std::chrono::milliseconds duration
) {
  return esp_sleep_enable_timer_wakeup(
    duration.count()
  );
}
// ...
esp_sleep_enable_timer_wakeup_using_chrono(DEEP_SLEEP_TIME);

The way durations work in chrono is such that you don't need to duration_cast when you're going to type that can represent the same values as the source type. The the prior example the point of the duration_cast was just so that .count() was getting a count of microseconds. In other words, the duration_cast performed the multiplication and would have selected a more appropriate underlying integer size. Here that conversion takes place during the call. Anyway, it may be worth some effort to learn about as it tends to help avoid problems with unit conversions and integer ranges.


text:
How to tri-state an output circuit?
I need a circuit where an Arduino MCU can set an output to 3 different states.

HIGH (12V)
LOW (GND)
N/A (completely disconnected)

Using transistors seems to be the correct way but I am too much of a noob in this area to be sure.
I’ve been researching “tri-state” online but there seems to be different meanings of this.
I’d appreciate a circuit for this or information that can get me on the right track.
Update:
I did test this schematic and it almost works. Although in the high state I got 2.7V output when the input was 12V. Very odd. I used two NPN transistors.
This is a half h-bridge, right?

Have you tried googling for something like "tri state transistor circuit"? Found this site which seems promising.

Thank you, I will check that out!

In your schematic Q1 needs to be an PNP transistor, not NPN. And keep in mind, that you will loose a bit of the voltage on your diode.

Thank you, I will try this as well!

Q1 will work, it is in the emitter follower configuration. You will lose about 0.7V when fully on. That will be dissipated as heat. The emitter voltage will follow the base voltage but -0.7V lower referencing ground. You will also lose another 0.7V across the diode. If you put 5V on the  base you lost about 1.3V across the resistor, something is not correct.

Have you looked at 74Cxx buffers? Input is appears on the pin about the same as tri-state, you may be able to get by with two states.

The simplest solution could probably be an H-bridge, like the ones you
have on motor driver shields. Actually you only need half an H-bridge.
You will typically be driving two inputs of the chip: “input 1” and
“enable”:

if you set “enable” to LOW the bridge output will be in the high
impedance state (your “completely disconnected” state)
if you set “enable” to HIGH, the output will be HIGH or LOW,
mirroring “input 1”.

Edit: your transistor circuit looks slightly similar to half an
H-bridge. However, in order to operate from 12 V, you typically need at
least three transistors, one of them being a PNP. See for example this
discussion in the Arduino forum. I suggest you use a ready-built
H-bridge, as this will simplify things for you.

Another possibility is a tristate buffer with enable. There are lots available, just make sure the voltage can be 12 volts (eg MC14503B)

The MC14503B is not suitable: if supplied with 10 V, its inputs are only guaranteed to read HIGH if they are driven above 7 V. You have to find a tri-state buffer that can drive 12 V while being driven by 5 V logic. H-bridge chips are designed for this: they typically have dual supplies (one for the logic inputs, one for the driver outputs).

Thank you for your input Edgar!

Another option is to use a pair of opto-mosfets arranged as half bridge.
The opto's LEDs could easily be controlled by logic levels.
Another option is to use complementary pair of PNP and NPN transistors again arranges as half bridge (joined collectors as ouput, PNP emitter at +12V, NPN emitter at GND.
The NPN transistor is controlled directly; the PNP via an auxiliary small NPN (collector driving the PNP base)

Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.