body:
I have a number of atmega328-PU-on-breadboards. I build them with a 16MHz crystal and load the Uno Optiboot loader if they don't already have a bootloader installed. I program them with an [FTDI USB to TTL Serial 5V Adapter Cable 6 Pin 0.1 inch Pitch Female Socket Header UART IC FT232RL Chip][1] (or the 3.3v version of the same cable, if I built for 3.3v). By using a 16 MHz crystal and a standard bootloader, I can select 'Uno' as the board type in the IDE and everything works. <br>On the board, I build a 6-pin header to accept the cable's 6-pin female header I use connect it for for uploading and/or viewing debug output on the board's serial port, but otherwise remove it and power the board through a more compact micro-USB connector. You could always make a more permanent connection between your board and the USB-FTDI cable if you find that more suitable.

Update:

> what programmer do you choose ? Also can you share your pinout ?

My programmer is avrdude, run by the IDE. My boards program exactly like an Uno.

Pinout:

[![FTDI-cable pinout][2]][2].

The CTS output (brown wire) is unused; the RTS output is wired connected to the reset pin through a 0.1uF capacitor, if you want the auto-reset feature. If you are using a different FTDI device, you will, of course, have to use it's particular pinout but it should provide the same signals and behavior.

This is the reset circuit I use on my board (crudely drawn but gets the point across):

[![Reset circuit][3]][3]

  [1]: https://DTech FTDI USB to TTL Serial 5V Adapter Cable 6 Pin 0.1 inch Pitch Female Socket Header UART IC FT232RL Chip
  [2]: https://i.stack.imgur.com/MZeeU.jpg
  [3]: https://i.stack.imgur.com/kjreH.jpg


sender: user

message:
if statement does not work with fraction, but works with decimal equivalent

I'm trying to trouble shoot a problem with my code and narrowed it down to my if statement not working with a fraction.

The below code does not work and returns 0

    for(float i=0; i <= 1; i += .0001){
     t += .0001;
     if(t >= 1/440){ //Fraction
       t = 0;
     }
     Serial.println(t*100);
     delay(100);
    }

But when I replace the 1/440 with its decimal equivalent (.0022727) it works fine and counts from 0 to 2.2

    for(float i=0; i <= 1; i += .0001){
     t += .0001;
     if(t >= 0.0022727){ //Decimal
       t = 0;
     }
     Serial.println(t*100);
     delay(100);
    }

If there is a simple way to use a fractional value instead of a decimal value it would make my application much similar.
Thanks.

sender: assistant

body:
`1/440` will be treated as an integer expression, returning zero.

To make it work, make one or both operands a floating-point type. In your case:

     if(t >= (float)1 / 440){ //Fraction
       t = 0;
     }

Or:

     if(t >= 1.0/440){ //Fraction
       t = 0;
     }


message:
Arduino Bluepill STM32 spi doesn't work

Has anyone successfully use SPI1 of those pins?

    SCLK -> PB3
    SDIO -> PB5
    SDO -> PB4
    MISO CS -> PA15

I've tried to use another side of SPI1 pins on the other sides of the board (PA4, 5, 6, 7) and i can successfully communicate with
[![enter image description here][1]][1]

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

body:
It depends on how you use the SPI object. If you use the SPI object directly like what Arduino Uno without creating an instance object, the SPI construct will default to the PA4 - PA7, see the [default pins definition](https://github.com/stm32duino/Arduino_Core_STM32/blob/main/variants/STM32F1xx/F103C8T_F103CB(T-U)/variant_PILL_F103Cx.h#L104-L113) and [default Class construct](https://github.com/stm32duino/Arduino_Core_STM32/blob/main/libraries/SPI/src/SPI.cpp#L25) of Blue Pill.

For STM32 Arduino Core (Stm32duino), there are four STM32 Arduino Core specific APIs for configure the alternative SPI pins.

```
void setMISO(uint32_t miso)
void setMOSI(uint32_t mosi)
void setSCLK(uint32_t sclk)
void setSSEL(uint32_t ssel)
```
These **must** be called before the `SPI.begin()`.

Another alternative way of using the alternative SPI pins is to create an SPI object and pass-in the pin assignments like this:
```
#include <SPI.h>

SPIClass mySPI(PB5, PB4, PB3, PB15); //mosi, miso, sclk, ssel
```

See the [alternative construct](https://github.com/stm32duino/Arduino_Core_STM32/blob/main/libraries/SPI/src/SPI.cpp#L46-L52) API, and further information on STM32duino [wiki](https://github.com/stm32duino/Arduino_Core_STM32/wiki/API#spi) page.


message:
Arduino Mega Loopback Test with Several TX/RX Ports

I am trying to do a loopback test using an Arduino Mega. What I am looking to do is send a byte over TX and receive said byte back at RX and verify that the byte is unchanged. More or less I just have a jumper wire connecting the TX and RX ports (In reality I have a circuit hooked up to the TX RX ports that effectively acts like a wire, I'm just trying to verify that the circuit traces are sound).

I am also doing the exact same thing over TX2/RX2 and TX3/RX3.

The issue I have run into is that I can't seem to get the data to send out the TX ports. In my attempt I used Serial objects where I would do the following:

```
void setup() {
Serial.begin(9600); //0 and 1
Serial2.begin(9600); //16 and 17
Serial3.begin(9600); //14 and 15
}

void loop() {

//RX TX
int bytesSent = Serial.write(1);
delay(500);
if(Serial.read()!=bytesSent){

  //Do Something

}

delay(500);

//RX2 TX2
bytesSent = Serial2.write(2);
delay(500);
if(Serial2.read()!=bytesSent){

   //Do Something

}

delay(500);

//RX3 TX3
bytesSent = Serial3.write(3);
delay(500);
if(Serial3.read()!=bytesSent){

   //Do Something

}

delay(500);

}
````

I'm aware that the use of "delay(500)" is not optimal nor good coding practice but is left here for now while I'm still trying to understand what's wrong with my transmit and receive.

I believe my misunderstanding comes in with the Serial objects; Am I not using them correctly in this case? I've referenced the Arduino Serial reference guide, so this seems like it would work, but does not.

Further details: I am currently powering my Arduino via USB (which I'm aware can be an issue, but I currently do not have the battery power source). Would switching to the other power source resolve my issue? Just to reiterate I'm not trying to communicate with the PC, I'm just trying to verify that this external circuit (which acts like a wire) is able to carry the signal.

body:
There seems to be a slight misunderstanding here:

```c++
bytesSent = Serial2.write(2);
// [...]
if (Serial2.read() != bytesSent) // [...]
```

On the serial ports:

 * the method `write()` returns the number of bytes that were written,
   not the value of a written byte

 * the method `read()` returns the byte that was read (or −1 if nothing
   was available), not the number of bytes read.

I suggest you modify your test like this:

```c++
uint8_t byte_sent = random(256);
Serial2.write(byte_sent);
delay(100);
if (Serial2.read() != byte_sent) // there was an error
```


message:
Unexpected Behaviour w/ Arduino Uno Calculation

I have a really simple snippet of code wherein the same calculation outputs different values depending on how I do the calculation. The platform that I am running this code on is an **Arduino Uno** - with an **Atmel MEGA328P** microcontroller chip. Here's the code:

```
void setup() {

  Serial.begin(9600);
  unsigned long num = 100927;
  Serial.println(1000*60);
  Serial.println(num/(1000*60));
  Serial.println(num/(60000));
}

void loop() {}
```
This code prints the following on the console:
```
-> -5536
-> 0
-> 1
```
I don't understand why `num/(1000*60)` and `num/(60000)` evaluate to different values? Also, `1000*60` evaluates to a garbage value which looks like it somehow set the data type to int and resulted in overflowing the "int" range.

My programming background is heavy in Python. I figure I'm used to python dynamically interpreting variable data types for me which is why the arduino language confuses me a bit here. Any help is appreciated!

body:
This is a pure C++ programming issue, which I cover [on my web site](http://www.gammon.com.au/forum/?id=12146).

However, since link-only answers are not allowed here, I reproduce that post below:

---

On the Arduino (Uno) platform, what do you think will be printed here?

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

      Serial.println (30000 + 30000); // twice 30000
      Serial.println (60 * 60 * 24);  // seconds in a day
      Serial.println (50 / 100 * 1000); // half of 1000
      }  // end of setup

    void loop () { }

Did you guess:

    60000
    86400
    500

Nope!

It prints:

    -5536
    20864
    0

This is because of **integer arithmetic**. If the compiler can, it treats an numeric literal (like 60) as an int type, which means it has the range -32768 to +32767. This may be unexpected for users of modern compilers because nowadays an `int` is usually 32 bits. However on the 8-bit Arduino processors such as the Atmega328P the compiler treats an int as 16 bits wide. The C++ standard permits an int size of **at least** 16 bits, but you are not guaranteed that it will be larger.

And, arithmetic is done using the type of the largest argument, which means the arithmetic in each case is done as 16-bit arithmetic, and thus it overflows once it reaches 32767.

For example, 30000 + 30000 = 60000 which is 0xEA60 in hex. Unfortunately, 0xEA60 is exactly how -5536 is stored in an int type, which is why it prints -5536.

Meanwhile, 60 * 60 * 24 = 86400 which is 0x15180 in hex. As that doesn't fit in 16 bits, it is truncated to 0x5180 which is 20864 in decimal (as printed).

Finally, in integer arithmetic 50/100 is zero, multiply zero by 1000 and you still get zero, which is why the final result is zero.

---

So, can we "help" the compiler by telling it the sort of result we want, like this?

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

      long a = 30000 + 30000;
      long b = 60 * 60 * 24;
      float c = 50 / 100 * 1000;

      Serial.println (a);
      Serial.println (b);
      Serial.println (c);
      }  // end of setup

    void loop () { }

That prints:

    -5536
    20864
    0.00

So no, that hasn't helped.

---

## Solution

First, you can add a suffix to numeric literals (eg. L for long, or UL for unsigned long), and add a decimal place to floats, like this:

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

      Serial.println (30000L + 30000); // twice 30000
      Serial.println (60L * 60 * 24);  // seconds in a day
      Serial.println (50.0 / 100 * 1000); // half of 1000
      }  // end of setup

    void loop () { }

Now we get:

    60000
    86400
    500.00

You only need to help out with the first literal, once the compiler knows we are using longs (or floats) it sticks with them for the expression. \*

Or we can "cast" them:

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

      long a =  (long) 30000 + 30000;
      long b =  (long) 60 * 60 * 24;
      float c = (float) 50 / 100 * 1000;

      Serial.println (a);
      Serial.println (b);
      Serial.println (c);
      }  // end of setup

    void loop () { }

Results:

    60000
    86400
    500.00

Casting is useful for variables, because you can't just add "L" to the end of a variable name.

An alternative syntax is to use a constructor like this:

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

      long a =  long (30000) + 30000;
      long b =  long (60) * 60 * 24;
      float c = float (50) / 100 * 1000;

      Serial.println (a);
      Serial.println (b);
      Serial.println (c);
      }  // end of setup

    void loop () { }

(Same results).

---

\* It's actually somewhat more complex than that as this link explains: [Understand integer conversion rules](https://wiki.sei.cmu.edu/confluence/display/c/INT02-C.+Understand+integer+conversion+rules)

The compiler "promotes" a value in an expression to match another "higher-ranked" type, under certain circumstances. For example, adding an **int** and a **long** will result in the **int** being promoted to a **long** (regardless of whether it appears first in the expression or not). However if an **int** is being added to another **int**, it will *not* promote them to a **long**, even though the result may not fit into an **int**.

---

## More explanations

I was asked in the comments why `1000 * 60` is not the same as `60000` from the compiler's point of view.

The answer is that a compiler will treat an integer literal as an **int** (if possible) and an **int** on this platform is 16 bits.

Thus 1000 (an **int**) * 60 (another **int**) are multiplied using 16-bit arithmetic, giving a result that overflows.

However the literal, 60000, cannot be stored as an **int** and thus the compiler promotes it to **long** (aka "**long** **int**"). Since it has been promoted to a **long** it is correctly stored, and further operations on 60000 will be done with **long** arithmetic.

I have seen people code 60000 as 60000L however that is unnecessary. The compiler is not silly enough to make 60000 be stored as -5536, as that is clearly not the intent of the programmer.


message:
I need some help in transmitting voice via VLC

The project I'm working on: Short-Range Coded Visible Light communication System.

Visible Light Communication (VLC) systems utilize light to transfer data between transmitter and receiver over short-range links. This project intends to build a wireless VLC system capable of transmitting voice between two microcontrollers such as Arduino or Raspberry pi using visible light. A Light Emitting Diode (LED) or Laser diode deployed at the transmitter side and a Light Dependent Resistor (LDR) or photodiode deployed at the receiving side. Data transmission via air with relatively high speed compared to radio-frequency communication systems. Digital data transmitted using on-off keying where the LED function as on-off light. Strings of ones (1) and zeros (0) are transmitted with high frequency such that the LED flicking is undetectable to the human eye. Both hardware (Arduino / Raspberry pi microcontroller) and software (MATLAB/ Arduino/ another software) are required for successful data transmission and reception.

I'm using Arduino Uno and these are the codes that I used but I'm hearing noise from the speaker not my voice

    Transmitter code:
    // Define microphone pin
    const int micPin = A0;

    // Define LED pin
    const int ledPin = 9;

    // Define sampling frequency (in Hz)
    const int samplingFrequency = 8000;

    void setup() {
      // Set microphone pin as input
      pinMode(micPin, INPUT);

      // Set LED pin as output
      pinMode(ledPin, OUTPUT);

      // Begin serial communication at 9600 baud rate
      Serial.begin(9600);
    }

    void loop() {
      // Read analog voltage from microphone
      int analogValue = analogRead(micPin);

      // Map analog voltage to PWM duty cycle (0-255)
      int dutyCycle = map(analogValue, 0, 1023, 0, 255);

      // Set LED brightness based on duty cycle
      analogWrite(ledPin, dutyCycle);

      // Print duty cycle value to serial monitor
      Serial.println(dutyCycle);

      // Delay to maintain sampling frequency
      delay(1000 / samplingFrequency);
    }

Receiver code:

    const int ldrPin = 9;
    const int speakerPin = 11;
    int voiceSample;

    void setup() {
      Serial.begin(9600);
      pinMode(ldrPin, OUTPUT);
      pinMode(speakerPin, OUTPUT);
    }

    void loop() {
      analogWrite(ldrPin, voiceSample);
      delay(10);
      voiceSample++;
      if (voiceSample > 255) {
        voiceSample = 0;
      }
      int voiceInput = analogRead(A0);
      voiceInput = map(voiceInput, 0, 1023, 0, 255);
      analogWrite(speakerPin, voiceInput);
    }

body:
The `Serial.println(dutyCycle)` in your transmitter is going to seriously slow down communications. It takes 1.04 ms to send a single byte over serial at 9600 baud, and assuming you have 3 digits, plus carriage return and linefeed that will take over 5 ms for each serial print.

However you are trying to sample at 8000 times a second (once per 125 µs) so you simply won't keep up. I suggest removing the serial print.

---

>     delay(1000 / samplingFrequency);

The `delay` function takes a `long` argument, not a float. `1000 / 8000` will evaluate to zero so the sample rate will not in fact be 8000 times a second.

You may want to consider the [delayMicroseconds](https://www.tutorialspoint.com/arduino/arduino_delaymicroseconds_function.htm) function.

---

Did you write this code or ChatGPT? [ChatGPT questions are currently banned on Stack Overflow](https://meta.stackoverflow.com/questions/421831/temporary-policy-chatgpt-is-banned).  I'm not sure about their policy in regards to Arduino Stack Exchange.


message:
STM32 "black pill" won't enter DFU mode reliably

I'm following the standard process to put an STM32 "black pill" (STM32F401CC) into DFU mode so that I can upload from the Arduino IDE over USB:

1. Hold down boot0.
2. Press and release rst.
3. Release boot0.

When the board is not in a circuit this works somewhat reliably but not 100%. While breadboarding with only a few connections it becomes very unreliable and sometimes won't work at all.

The USB serial device set up by my Arduino sketch works fine, it is only DFU mode that does not want to work.

When it fails to enter DFU mode I see the following error in the Arduino upload process:

```
      -------------------------------------------------------------------
                        STM32CubeProgrammer v2.13.0
      -------------------------------------------------------------------

An error occurred while uploading the sketch
Error: Target device not found
Establishing connection with the device failed
```

I'm using Arduino on Ubuntu 20.04 and when it fails I see in `/var/log/syslog`:

```
Apr 27 13:26:08 smurfenaar kernel: [79594.279257] usb 1-3: USB disconnect, device number 10
Apr 27 13:26:08 smurfenaar kernel: [79595.078232] usb 1-3: new full-speed USB device number 11 using xhci_hcd
Apr 27 13:26:09 smurfenaar kernel: [79595.192387] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.413389] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.636370] usb 1-3: new full-speed USB device number 12 using xhci_hcd
Apr 27 13:26:09 smurfenaar kernel: [79595.751435] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.973367] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79596.082540] usb usb1-port3: attempt power cycle
Apr 27 13:26:10 smurfenaar kernel: [79596.462407] usb 1-3: new full-speed USB device number 13 using xhci_hcd
Apr 27 13:26:10 smurfenaar kernel: [79596.462674] usb 1-3: Device not responding to setup address.
Apr 27 13:26:10 smurfenaar kernel: [79596.666550] usb 1-3: Device not responding to setup address.
Apr 27 13:26:10 smurfenaar kernel: [79596.874414] usb 1-3: device not accepting address 13, error -71
```

When it is successful I see:

```
pr 27 13:22:33 smurfenaar kernel: [79379.772197] usb 1-3: new full-speed USB device number 9 using xhci_hcd
Apr 27 13:22:33 smurfenaar kernel: [79379.899601] usb 1-3: New USB device found, idVendor=0483, idProduct=df11, bcdDe
vice=22.00
Apr 27 13:22:33 smurfenaar kernel: [79379.899605] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Apr 27 13:22:33 smurfenaar kernel: [79379.899607] usb 1-3: Product: STM32  BOOTLOADER
Apr 27 13:22:33 smurfenaar kernel: [79379.899609] usb 1-3: Manufacturer: STMicroelectronics
Apr 27 13:22:33 smurfenaar kernel: [79379.899611] usb 1-3: SerialNumber: 3466365E3135
```

and I can also see it with the `lsusb` command:

```
Bus 001 Device 052: ID 0483:df11 STMicroelectronics STM Device in DFU Mode

```

body:
I found [this solution](https://www.stm32duino.com/viewtopic.php?t=1807) in the stm32duino forums:

> Tying A10 to GND successfully makes it enter DFU bootloader mode 100% of the time (though just not leaving PA10 floating is probably sufficient)
>
>  **Hypothesized Explanation**: In the last paragraph of Sec 4.3 of AN2606 (the STM bootloader manual), it states:
>>It is recommended to keep the RX pins of unused bootloader interfaces (USART_RX, SPI_MOSI, CAN_RX and USB D+/D- lines if present) at a known (low or high) level at the startup of the bootloader (detection phase). Leaving these pins floating during the detection phase might lead to activating unused interfaces.
>
> PA10 is the RX pin for USART_1. I believe that since PA10 is floating, the bootloader senses traffic on USART_1, and believes that's the interface it should use, and thus turns off USB. By tying PA10 to GND, the bootloader doesn't sense UART traffic and correctly enables USB.

While I followed the advice of tying it to ground I assume tying it to ground via a high resistance value would work too and should allow you to keep using PA10 for something else. After tying PA10 to GND I find entering DFU mode is 100% reliable, even when the board is in a circuit.


body:
I recently purchased two **"WeAct V3.0 STM32F411" Black Pill boards** on eBay. I've purchased many boards & other electronic items from this seller in the past without any issues. This eBay seller is very highly rated: 99.8% positive feedback with >1 million items sold. However, I cannot confirm whether these boards are "genuine" WeAct boards since I did not purchase them directly from WeAct.

Both of my Black Pill boards can be programmed with ST-LINK V2 using the standard 3 (or 4) wire SWD interface pins. No problems.

However, both boards initially failed to enter USB DFU programming mode after resetting boards with the `BOOT0` button pressed. Then I tried grounding pin `A10` as suggested above. **This totally fixed DFU programming**. Now both boards program perfectly every time via DFU mode.

The only downside is the requirement to press `BOOT0` + `NRST` buttons on board to initiate DFU programming mode prior to uploading with Arduino IDE.


message:
IR Receiver Remote Controller for Windows

My dad watches netflix on his pc with his wireless mouse, hes gotten older and cannot hit the volume slide well enough.

I have an arduino kit (ard nano), an IR recevier and remote controller laying around (all from the arduino kit).

I want to use the remote control when you press volume down on it to make the windows volume go down.
I tried using chatgpt but have gotten nowhere, what would be the best simplest solution for this.

I was thinking it would be an easy read-in of the data from the receiver but how would you transfer this data on to windows? Is this possible, I havent found many examples online

Thank you all :)

body:
There are USB / HID keyboard codes for volume.  [Here][1] we see volume up is 0x80 and volume down is 0x81.

Consider obtaining an Arduino board which is capable of supporting a USB / HID port so that you can easily emulate a keyboard.  It would be best to choose a board with hardware USB / HID support.  But it may be possible to emulate (limited?) USB / HID support using software only.

There are plenty of Arduino USB / HID project ([here][2] and [here][3] are just 2 examples).  This should get you started designing an Arduino sketch which can transmit a keyboard's volume up and down control codes into one of the computer's USB ports.

And there are plenty of Arduino ASK / IR receiver projects ([here][4] and [here][5] are just 2 examples).  As there are many IR remote control codes, this part of the project might take a bit of research to uncover the codes used in the IR remote control you posses.

  [1]: https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2
  [2]: https://www.instructables.com/How-to-Make-a-Arduino-HID-Keyboard/
  [3]: https://learn.adafruit.com/circuitpython-essentials/circuitpython-hid-keyboard-and-mouse
  [4]: https://www.instructables.com/Using-an-IR-Receiver-With-Arduino/
  [5]: https://www.digikey.com/en/maker/blogs/2021/how-to-send-and-receive-data-over-ir-signals-with-an-arduino


message:
Program to Multiply Numbers Won't Actually Multiply Them

I am trying to write a program which takes in a number of pairs to be multiplied, then prints out the result of each multiplication. Instead of doing this, the program just prints out the number of multiplications and the numbers, but it never does the multiplications or add the newline characters (despite me explicitly using println). In the example below I specify 2 number pairs to multiply, and then enter 3,4,7,8 (entering a NL character after each number, but spaces and commas cause the same problem).

[![Result][1]][1]

I thought my approach would work, but I believe that there is something I am doing with the serial input that is causing the code not work (although there could be some other issue). I also wonder if maybe it's because I'm running this in Tinkercad and not the real Arduino IDE. Any help would be greatly appreciated.
```
void loop()
 {
  int numOfMults = 0;                             // number of pairs to multiply
  float *numArray;                                // pointer to beginning of array memory block
  numArray = (float *)malloc(sizeof(float)*50);   // dynamically allocate an array that can hold up to 50 floats

  numOfMults = Serial.parseInt(); // take in the number of multiplications from user

  Serial.println(numOfMults);

  // take in the specified amount of numbers (2 times the num of multiplications) in format: 1,2,3...
  // then convert that into an array of floats, where every 2 indices
  // is a pair of numbers to multiply
  for (int i = 0; i < (2*numOfMults) ;i++)
    {
      numArray[i] = Serial.parseFloat();
    }
      multNums(numOfMults,numArray);  // call function to get the product of all the numbers

      delay(5000);                    // wait 5 seconds before starting the loop again
 }

void multNums(int numofNums,float nums[])
{
  float *productArray;                                 // pointer to beginning of the product array memory block
  productArray = (float *)malloc(sizeof(float)*25);    // dynamically allocate an array that can hold up to 25 floats (for the products)

  // multiply all the number pairs in the array, store the product in another
  for(int i=0;i<(2*numofNums);i+2)
  {
      productArray[i/2] = nums[i]*nums[i+1];         // multiply current number pair, store in the product array one index at a time
  }
  // print the products
  for(int i=0; i < sizeof(productArray) ;i++)
  {
    Serial.println(productArray[i]);
  }
}
```

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

body:
Ok I figured it out.

In the for loop I had to use i +=2, and not i+2.

What a dumb mistake..


body:
There are quite a few issues in this code:

 * In C++, you are supposed to do dynamic allocation with `new` rather
   than `malloc()`.

 * If you allocate dynamic memory in a loop and forget to free it (with
   `free()`/`delete`), you will quite quickly run out of memory.

 * Actually, you do not even need to do any dynamic allocation at all:
   automatic allocation is the safest way to handle these arrays.

 * Since you know the exact size you need, allocate that rather than a
   default size.

 * `multNums` receives as a parameter the number of multiplications, not
   the length of the array.

 * `i+2` does not change the value of `i`. You meant `i+=2`.

 * `sizeof(productArray)` does not give the length of the array, but its
   size in bytes. Besides, your last loop is supposed to iterate only
   through the initialized part of the array.

If you fix those issues, the program should work as expected.


message:
Why is my Arduino is getting power from the 5V pin?

[![enter image description here][1]][1]I have an Arduino that is controlling two 6V DC motors through a L298N motor driver. The motor driver is being powered (from its Vin pin) by a 7.4V external source.

I then have the 5V pin from the motor driver connected to the 5V pin on an Arduino UNO to power the logic board.

Now, when I plugged in my Arduino to my computer to upload the sketch, everything was fine. However, when I unplugged the Arduino from the laptop, the Arduino was still being powered somehow from the 7.4V external source, though that source should only be powering the motors. I thought that unplugging the Arduino from the laptop would have cut power to the Arduino, but it was still somehow being powered by the external source.

What is going on here?

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

body:
The Arduino Uno can be powered from the 5 volts present on the USB cable or from an external 5 volts connected to the Arduino's 5V and GND (ground) pins.

In general, power supply outputs should never be connected in parallel unless they are designed for such an unusual configuration. From the description in the Question, it appears the USB power and the L289N power supplies were connected in parallel. Fortunately, the Arduino design include a power cut off shich.  Look for part "T1" [in this schmatic][1].  If power is applied from both the 5V pin and the USB port, the 5V pin is used and the USB power is cut off.

To answer your question specifically:

* Assuming [this is your board's schematic][2] (note, this is a link to an RAR file which contains a JPG of what is likely the wb291111 board's schematic) and assuming you have J6 jumper installed.

* If the Arduino 5V and GND (ground) pins were connected to the L289N board and the L289N board was supplying 5V power to the Arduino board, the Arduino board was never powered from the computer's USB port as transistor "T1" would have disconnected the USB power from the Arduino.

  [1]: https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf
  [2]: http://www.geeetech.com/Documents/L298N_schematic.rar


message:
Help with program upload problem!

I'm gonna to upload some code to my LeArm using an Arduino board. I connected the rx and tx pins of the LeArm to the Arduino, but I got an error message when I tried to upload the code. I'm not sure if I did the connections correctly. Does anyone have any tips on how to upload the programs successfully?
[![enter image description here][1]][1]

[![enter image description here][2]][2]

[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/EYObL.jpg
  [2]: https://i.stack.imgur.com/TMQLO.jpg
  [3]: https://i.stack.imgur.com/F47fz.jpg

body:
Is the arduino MEGA you have a "chinese" version? if it is, try installing this drivers and try again :

> https://www.arduined.eu/ch340-windows-10-driver-download/


message:
Problem with some sensors but not with servos

I use a lot Arduino Uno, but in this case, I have some [BQ ZUM BT-328 boards][1], which are based on Arduino BT. The problem with some of BQ ZUM BT-328 boards is that the ultrasonic sensor ([HC-SR04][2]) is not working in any pin. However, apparantely, the boards work and the 2 servos ([SM-S4306R][3]) work fine too. When I change the ultrasonic sensor to other pins and with other wires, it is not working yet. However, I use that sensor in another different BQ ZUM BT-328 board and it is working fine, and if I add the same setup (2 SM-S4306R) and same code, it continues working fine. Then, the problem is just in some boards, not in everyone.

The ultrasonic example is:

    long distance;
    long responseTime;

    int pinTrig = 9;
    int pinEcho = 8;

    void setup(){
      Serial.begin(9600);
      pinMode(pinTrig, OUTPUT);
      pinMode(pinEcho, INPUT);
    }

    void loop(){
      digitalWrite(pinTrig, LOW);
      delayMicroseconds(5);

      digitalWrite(pinTrig, HIGH);
      delayMicroseconds(10);
      responseTime = pulseIn(pinEcho, HIGH);
      Serial.println("Tiempo "+ String(responseTime)+" microsegundos");

      distance = int(0.01716*responseTime);

      Serial.println("Distancia "+ String(distance)+"cm");
      delay(500);
    }

Then, I suppose that those BQ ZUM BT-328 boards have some problem and maybe they are starting to fail. I say this, because the same problem works in some boards and in others fails. In those board in which it fails I checked the correct connection of pins (GND, VCC, digitals), change the pin and the wires without result. However, the servos continue to work fine and I can upload the code to the board. My questions are:

Am I correct and they are failing?

Why they are just failing with that sensor and not the SM-S4306R? I mean, maybe some specific component of the board is failing?

  [1]: https://www.electronicsdatasheets.com/manufacturers/bq/parts/zum-bt328
  [2]: https://www.alldatasheet.com/datasheet-pdf/pdf/1132203/ETC2/HC-SR04.html?gclid=Cj0KCQjw6cKiBhD5ARIsAKXUdyZcI10wW6rgVh6BaDVhlH8hpniDbfgKCNIIO77sIs1qq-c9nZZLqMEaAl3IEALw_wcB
  [3]: https://datasheetspdf.com/pdf/897796/SPRINGRC/SM-S4306R/1

body:
Looks like in your sample code you did not complete the 10us pulse.

```C
  digitalWrite(pinTrig, LOW);
  delayMicroseconds(5);

  digitalWrite(pinTrig, HIGH);
  delayMicroseconds(10);
  digitalWrite(pinTrig, LOW); // you missed this
```

See [example](https://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/).


message:
interface pcf7991at to arduino

I wanted to try to interface the pcf7991at with arduino, I assembled the pcb containing the pcf7991at following the diagram shown in the datasheet.
I saw that a frequency of 125khz must go on the CLK pin of the pcf, so I ask you if it is possible to use an internal arduino timer to try to see if the pcf7991at works.

body:
The Arduino is indeed capable of generating a 125kHz signal.
This example generates a 125kHz signal (50% duty cycle) on digital pin 3 of an Arduino Uno/Nano using Timer 2.

```
const int pulsePin = 3;  // note OC2B Pin D3 ! ! !
volatile uint32_t pulseCount = 0;

void setup(){

  pinMode(pulsePin, OUTPUT);

  cli() ;
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;
  OCR2A = 127 ; // f =  125kHz @16MHz clock
  OCR2B = (float) OCR2A * 0.5 ;
  TCCR2A |= (1 << WGM21) | (1 << WGM20) | (1 << COM2B1 ) ; // Mode 7 (fast PWM )
  TCCR2B |= (1 << CS20) | (1 << WGM22) ;   // ps /1  mode 7
  sei() ;
}

void loop() {
}
```


body:
The communication between MCU (Arduino) and IC (PCF7991AT) can work at any frequency (like SPI or I2C). The 125khz antenna frequency is generated in the IC internally. But you need to set the divider of the clock source (your crystal hooked up to the IC)

[https://datasheet.lcsc.com/lcsc/2208260930_NXP-Semicon-PCF7991AT-1081-M_C5143533.pdf][1]

See
page 7 -> 8.4 short explanation
page 13 -> to set the register

Hope this helps!

  [1]: https://datasheet.lcsc.com/lcsc/2208260930_NXP-Semicon-PCF7991AT-1081-M_C5143533.pdf


message:
Arduino IDE Auto Format Error

Whenever I try to format a sketch in the IDE (1.8.19) I get this output in the terminal:

    Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: 'java.lang.String cc.arduino.packages.formatter.AStyleInterface.AStyleMain(java.lang.String, java.lang.String)'
           at cc.arduino.packages.formatter.AStyleInterface.AStyleMain(Native Method)
           at cc.arduino.packages.formatter.AStyle.run(AStyle.java:80)
           at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
           at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
           at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
           at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
           at java.base/java.security.AccessController.doPrivileged(Native Method)
           at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
           at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
           at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
           at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
           at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
           at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
           at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
           at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

...And formatting fails.

I can use astyle from the command line (linux mint) and it works well.

Guessing that some basic package was missing, or corrupted, I reinstalled Arduino, but the issue remained.

I don't precisely recall any specific changes made to my system prior to encountering this behavior, as it's been like this for at least 8 or 9 months now. I hadn't used Arduino for some time up until that point and it may have been a fresh instal.

Since I just started a new project for a buddy of mine and encountered the bug again I decided maybe it was time to see about a better solution.

Any help troubleshooting this would be greatly appreciated.

body:
I googled the first line of stack trace and found similar [issue on github](https://github.com/arduino/Arduino/issues/11728) (but for SUSE linux). In this issue the Arduino IDE was installed by system package manager and after downloading latest package from arduino.cc/en/software it started working.

In general Arduino IDE linux packages are somehow problematic (as far as I know Ubuntu has still version around 1.0.6) and it's better to use latest version directly from arduino.cc


message:
SIM7600 MQTT CONNECTION TO shiftr.io broker

I am trying to use SIM7600 MQTT command to publish and subscribe to shiftr.io broker.

I have not been able to get pass stage of connecting to broker.

I use this
AT+CMQTTCONNECT=0,"tcp://instance.cloud.io:1883",90,1,"username","token"

I get this error code.
+CMQTTCONNECT:  0, 25

Of which code 25 indicate DNS error

body:
You answered your own question with "DNS error".

The domain name that you're using, `instance.cloud.io`, is currently not valid. You can verify this quite simply by searching the web for any web site that looks up domain names for you and searching for that domain name.

In this case, "instance" is most likely a placeholder for the correct name. You need to go back to whatever tutorial or instructions you were following for this and use the correct name for this to work.


message:
attachInterrupt has no effect on Industruino SAMD21

I'm using Industruino D21G (SAMD21G version) with Visual Studio Code extension for Arduino. `attachInterrupt` seems to have no effect. I tried Industruino CH1, CH6 and CH7 with the same result. When I poll these channels in a loop, I detect signal level change as expected. Here is the code:

```
#include <Arduino.h>
#include <Indio.h>

constexpr int PROXIMITY_SENSOR_NC = 6;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Indio.digitalMode(PROXIMITY_SENSOR_NC, INPUT);
  attachInterrupt(digitalPinToInterrupt(PROXIMITY_SENSOR_NC), blink, FALLING);
  digitalWrite(LED_BUILTIN, HIGH);
}

void blink() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void loop() {
}
```
Any ideas what could be wrong?

body: Industrial level I/O on Industruino, which includes CH1, CH6 and CH7 I tried, is not connected directly to the microcontroller. It uses a buffer and communicates through I2C in pull mode. That's why interrupt on I/O change has no effect.


message:
How can when the button is clicked to display its name

I need to recognize a signal from an IR remote, not to use a library for working with IR remotes/receivers. How can when the button is clicked to display its name. I have PIC12F615 microcontroller with this code: [code][1] and 5 buttons connected to him and I need recognise which button pressed. I have some code but it gives different hex codes if I pressed the same button.

    byte IRpin = 2;

    volatile boolean remote = false;
    volatile unsigned long irCode = 0;

    void remoting ()
    {
      if ( remote )
      {
        remote = false;
        unsigned long T;
        for ( byte n = 0; n < 32; n ++ )
        {
          do
          {
            T = pulseIn ( IRpin, HIGH, 2200 );
          }
          while ( T < 64 );
          bitWrite ( irCode, n, T > 1120 );
        }
      }
    }

    void setup ()
    {
      Serial.begin ( 9600 );
      Serial.println ( "\n\tReady for keyboard reading!\n" );
      pinMode ( IRpin, INPUT_PULLUP );
      attachInterrupt ( digitalPinToInterrupt ( IRpin ), remoting, FALLING );
    }

    void loop ()
    {
      if (irCode)
      {
        Serial.println (irCode, HEX);
        irCode = 0;
      }
      delay (40);
      remote = true;
    }

Schema: [![enter image description here][2]][2]

  [1]: https://github.com/circuitvalley/IR-Remote-Control/blob/master/NEC IR Transmitter Remote/main.c
  [2]: https://i.stack.imgur.com/Pf4Ik.jpg

body:
The function pulseIn() has this comment in the source code: "This function performs better with short pulses in noInterrupt() context" see: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_pulse.c. It is not clear if your code violates the "short pulse" rule, however, blocking an Interrupt Service Routine (in your case, the external interrupt call back routine remoting() ) for the entire length of an IR data stream is certain to cause other problems, for example, with the millis() timer.

This is in the style of your code but avoids using interrupts. It has been tested against an NEC remote control and gives repeatable results. Your code fails the same test.

```
byte IRpin = 2;

unsigned long irCode = 0;

void setup ()
{
  Serial.begin ( 9600 );
  Serial.println ( "\n\tReady for keyboard reading!\n" );
  pinMode ( IRpin, INPUT_PULLUP );
}

void loop () {
  while ( digitalRead ( IRpin ) );  // wait until start of first pulse
  unsigned long T;
  uint8_t validPulses = 0 ;
  for ( byte n = 0; n < 36 ; n ++ ) // enough to drop long header
  {
    T = pulseIn ( IRpin, HIGH , 12000 );  // 12ms timeout
    if ( T < 4000 && T > 400 && validPulses < 32 ) {
      // valid pulse
      bitWrite ( irCode, validPulses++, T > 1120 );
    }
  }
  if (irCode > 0 ) Serial.println (irCode, HEX);
  else Serial.println ("no code");
  irCode = 0 ;
}

```


message:
It is required to turn on the LED if the distance to the object is less than or equal to 200 centimeters. Find the error in the code

```
int trigPin = 10;

const int echoPin = 8;

int led = 7;

const int distance = 200;

void setup()
{
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(led, OUTPUT);
}
void loop()
{
 int duration, cm;
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH);
 cm = duration/58;
 if (cm < distance)
 {
  digitalWrite(led, HIGH);
 }
 else
 {
  digitalWrite(led, LOW);
 }
 delay(100);
}
```
[![enter image description here][1]][1]

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

body:
1. You have `trigPin` as pin 10, however your wiring diagram shows it connected to pin 9, so that won't work.

2. `pulseIn` returns an `unsigned long` (microseconds) - see [pulseIn](https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/). You are collecting the results in an `int` which has a maximum value of 32767. The value may be overflowing and thus not be correct.


message:
Arduino Readings Update Correctly on Windows but not Linux

I have written a simple script to get angle measurements from a magnetic sensor. The script works very well on Windows. However, when compiling the script on a Linux VirtualBox (Ubuntu 20.04), the sensor repeats the first angle reading and does not change from this, despite the angle changing. There are no errors/warnings given by Windows or Linux at any stage of compiling/uploading.

Uploading the script on Windows and then viewing in Linux serial monitor works. However, uploading it on Linux and then viewing in Windows serial monitor does not work ("Board is not available"), even when connecting the board to Linux and not Windows.

I've compared both systems and everything seems to be the same: the same Arduino Uno R3 board, Arduino IDE 1.8.19 on both systems, Arduino AVR Boards 1.8.3 on both, "Arduino Uno" selected as the board on both, the library is SimpleFOC v2.2.0 on both. The only difference I can see is that the Windows port is COM3, whereas the Linux port is /dev/ttyACM0.

My script is the following and I would appreciate any help or advice to get this working on Linux. Thank you.

```
#include <SimpleFOC.h>

#define PI 3.1415926535897932384626433832795

// Magnetic sensor instance
MagneticSensorSPI AS5x4x = MagneticSensorSPI(8, 14, 0x3FFF);

void setup() {
  // initialize magnetic sensor hardware
  AS5x4x.init();

  // use monitoring with serial
  Serial.begin(9600);

  Serial.println("Ready.");
  _delay(1000);
}

void loop() {
  Serial.println(AS5x4x.getAngle()); // display angle
}
```

body: It turns out that the Arduino Library Manager was giving me incorrect information about the library version installed. By removing the library it was using and then installing the correct library that corresponds to the required version number, the code now works well.


message:
FreeRTOS is not solving my problem to run tasks parallelly

I'm pretty new to esp32 and I'm trying to combine two codes in one, they are simple codes from projects that I found online, the first one uses PIR sensor to send message to telegram each time motion is detected, second code uses RFID to open door lock. When I tried directly merging the two codes together the esp32 went crazy on serial monitor and nothing worked even the WIFI failed to connect.

Then I tried creating task for each one using freeRTOS and I did it like this:

 ***task1***: *for* Wifi connection **running on CORE 0** //wifi function is taken from sketch 1

 ***task2***: *for* RFID and door lock **running on CORE 1** //taken from sketch 2

 ***task3***: *for* motion detection and sending telegram message **running on CORE 0** //taken from sketch 1

Again esp32 went crazy when I opened serial monitor and it gave me this error:` " Guru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled. " `

I have no clue why is this happening, does it really require RTOS to combine the two sketches and run them at the same time, or a simple delays and if statements would solve the problem? I need some help please.

**Sketch 1: Motion detection** from [enter link description here][1]

```
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/telegram-esp32-motion-detection-arduino/

  Project created using Brian Lough's Universal Telegram Bot Library: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
*/

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Initialize Telegram BOT
#define BOTtoken "XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"  // your Bot Token (Get from Botfather)

// Use @myidbot to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
#define CHAT_ID "XXXXXXXXXX"

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

const int motionSensor = 27; // PIR Motion Sensor
bool motionDetected = false;

// Indicates when motion is detected
void IRAM_ATTR detectsMovement() {
  //Serial.println("MOTION DETECTED!!!");
  motionDetected = true;
}

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

  // PIR Motion Sensor mode INPUT_PULLUP
  pinMode(motionSensor, INPUT_PULLUP);
  // Set motionSensor pin as interrupt, assign interrupt function and set RISING mode
  attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);

  // Attempt to connect to Wifi network:
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

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

void loop() {
  if(motionDetected){
    bot.sendMessage(CHAT_ID, "Motion detected!!", "");
    Serial.println("Motion Detected");
    motionDetected = false;
  }
}
```

**Sketch 2: RFID door lock** from [enter link description here][2]

```
/*
 * This ESP32 code is created by esp32io.com
 *
 * This ESP32 code is released in the public domain
 *
 * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-rfid-nfc-door-lock-system
 */

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN    5  // ESP32 pin GIOP5
#define RST_PIN   27 // ESP32 pin GIOP27
#define RELAY_PIN 22 // ESP32 pin GIOP22 connects to relay

MFRC522 rfid(SS_PIN, RST_PIN);

byte keyTagUID[4] = {0xFF, 0xFF, 0xFF, 0xFF};

void setup() {
  Serial.begin(9600);
  SPI.begin(); // init SPI bus
  rfid.PCD_Init(); // init MFRC522
  pinMode(RELAY_PIN, OUTPUT); // initialize pin as an output.
  digitalWrite(RELAY_PIN, HIGH); // lock the door

  Serial.println("Tap an RFID/NFC tag on the RFID-RC522 reader");
}

void loop() {
  if (rfid.PICC_IsNewCardPresent()) { // new tag is available
    if (rfid.PICC_ReadCardSerial()) { // NUID has been readed
      MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);

      if (rfid.uid.uidByte[0] == keyTagUID[0] &&
          rfid.uid.uidByte[1] == keyTagUID[1] &&
          rfid.uid.uidByte[2] == keyTagUID[2] &&
          rfid.uid.uidByte[3] == keyTagUID[3] ) {
        Serial.println("Access is granted");
        digitalWrite(RELAY_PIN, LOW);  // unlock the door for 2 seconds
        delay(2000);
        digitalWrite(RELAY_PIN, HIGH); // lock the door
      }
      else
      {
        Serial.print("Access denied, UID:");
        for (int i = 0; i < rfid.uid.size; i++) {
          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i], HEX);
        }
        Serial.println();
      }

      rfid.PICC_HaltA(); // halt PICC
      rfid.PCD_StopCrypto1(); // stop encryption on PCD
    }
  }
}

```

  [1]: https://RandomNerdTutorials.com/telegram-esp32-motion-detection-arduino/
  [2]: https://esp32io.com/tutorials/esp32-rfid-nfc-door-lock-system

body:
No, you don't need an RTOS to do something simple like:

    if (motionDetected)
        open_the_door ();

---

You basically have two loops:

    void loop ()
      {
      if (motionDetected)
          send_a_message_to_open_the_door ();
      }

And:

    void loop ()
      {
      if (message_received_to_open_the_door)
         open_the_door();
      }

So, you combine them into a single loop:

    void loop ()
      {
      if (motionDetected)
         open_the_door();
      }

I'll leave you to make the actual code changes.


message:
Why NEC IR remote control decoder does not work

I need to recognize a signal from an IR remote, not to use a library for working with IR remotes/receivers. How can when the button is clicked to display its name. I have PIC12F615 microcontroller with this code: [code][1] and 5 buttons connected to him and I need recognise which button pressed. Why NEC IR remote control decoder does not work, it doesn't set nec_ok to true.If output nec_state to the terminal, I get 0 1 0 1 0 1 and so on.

        boolean nec_ok = 0;
    byte i, nec_state = 0, command, inv_command;
    unsigned int address;
    unsigned long nec_code;

    void setup() {
    Serial.begin(9600);
    // Timer1 module configuration
    TCCR1A = 0;
    TCCR1B = 0; // Disable Timer1 module
    TCNT1 = 0; // Set Timer1 preload value to 0 (reset)
    TIMSK1 = 1; // enable Timer1 overflow interrupt
    attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Enable external interrupt (INT0)
    }

    void remote_read() {
    unsigned int timer_value;
    if(nec_state != 0){
    timer_value = TCNT1; // Store Timer1 value
    TCNT1 = 0; // Reset Timer1
    }
    switch(nec_state){
    case 0 : // Start receiving IR data (we're at the beginning of 9ms pulse)
    TCNT1 = 0; // Reset Timer1
    TCCR1B = 2; // Enable Timer1 module with 1/8 prescaler ( 2 ticks every 1 us)
    nec_state = 1; // Next state: end of 9ms pulse (start of 4.5ms space)
    i = 0;
    return;
    case 1 : // End of 9ms pulse
    if((timer_value > 19000) || (timer_value < 17000)){ // Invalid interval ==> stop decoding and reset
    nec_state = 0; // Reset decoding process
    TCCR1B = 0; // Disable Timer1 module
    }
    else
    nec_state = 2; // Next state: end of 4.5ms space (start of 562µs pulse)
    return;
    case 2 : // End of 4.5ms space
    if((timer_value > 10000) || (timer_value < 8000)){
    nec_state = 0; // Reset decoding process
    TCCR1B = 0; // Disable Timer1 module
    }
    else
    nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
    return;
    case 3 : // End of 562µs pulse
    if((timer_value > 1400) || (timer_value < 800)){ // Invalid interval ==> stop decoding and reset
    TCCR1B = 0; // Disable Timer1 module
    nec_state = 0; // Reset decoding process
    }
    else
    nec_state = 4; // Next state: end of 562µs or 1687µs space
    return;
    case 4 : // End of 562µs or 1687µs space
    if((timer_value > 3600) || (timer_value < 800)){ // Time interval invalid ==> stop decoding
    TCCR1B = 0; // Disable Timer1 module
    nec_state = 0; // Reset decoding process
    return;
    }
    if( timer_value > 2000) // If space width > 1ms (short space)
    bitSet(nec_code, (31 - i)); // Write 1 to bit (31 - i)
    else // If space width < 1ms (long space)
    bitClear(nec_code, (31 - i)); // Write 0 to bit (31 - i)
    i++;
    if(i > 31){ // If all bits are received
    nec_ok = 1; // Decoding process OK
    detachInterrupt(0); // Disable external interrupt (INT0)
    return;
    }
    nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
    }
    }

    ISR(TIMER1_OVF_vect) { // Timer1 interrupt service routine (ISR)
    nec_state = 0; // Reset decoding process
    TCCR1B = 0; // Disable Timer1 module
    }

    void loop() {
    Serial.println(nec_ok);
    if(nec_ok){ // If the mcu receives NEC message with successful
    nec_ok = 0; // Reset decoding process
    nec_state = 0;
    TCCR1B = 0; // Disable Timer1 module
    address = nec_code >> 16;
    command = nec_code >> 8;
    inv_command = nec_code;

    attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Enable external interrupt (INT0)
    }
    }

Schema: [![enter image description here][2]][2]

  [1]: https://github.com/circuitvalley/IR-Remote-Control/blob/master/NEC IR Transmitter Remote/main.c
  [2]: https://i.stack.imgur.com/Pf4Ik.jpg

body:
External interrupt version of NEC protocol decoder using micros() for timing instead of Timer 1.
Drops NEC repeat codes,
Otherwise, in the style of the code in the question.

```
volatile boolean nec_ok = 0;
byte command, inv_command;
volatile byte nec_state = 0 ;
unsigned int address;
volatile unsigned long nec_code;
volatile uint32_t errFlag = 0 ;
volatile uint32_t decodeStartAtMs = 0 ;

void setup() {
  Serial.begin(9600);
  pinMode( 2, INPUT_PULLUP ) ;
  attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Enable external interrupt (INT0)
}

void remote_read() {

  static byte i = 0 ;
  static bool wasSpace;
  static unsigned long enteredAtUs = 0 ;
  static unsigned long pulseLengthLastUs ;

  wasSpace = ! digitalRead( 2 ) ;
  pulseLengthLastUs = micros() - enteredAtUs; // Calculate pulse length
  enteredAtUs = micros(); // Store current time for next entry

  switch (nec_state) {

    case 0 : // Wait here until 9ms pulse found )
      if ( pulseLengthLastUs > 8000 && pulseLengthLastUs < 10000 ) {  // got a 9ms pulse
        decodeStartAtMs = millis() ;  // for timeout
        nec_state = 1 ;
        nec_code = 0 ;
        i = 0 ;
      }
      break;

    case 1 : // handle 4.5ms space
      /*
      if ((pulseLengthLastUs > 2000) && (pulseLengthLastUs < 2500)) {
          // silently drop repeat codes !!!
          nec_state = 0; // Reset decoding process
      }
      else
      */
      if ((pulseLengthLastUs > 5500) || (pulseLengthLastUs < 3500)) {
        errFlag = 10000000 + pulseLengthLastUs ;
        nec_state = 0; // Reset decoding process
      }
      else
        nec_state = 2; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
      break;

    case 2 : // handle 562µs or 1687µs space
      if ((pulseLengthLastUs > 1900) || (pulseLengthLastUs < 400)) { // Time interval invalid ==> stop decoding
        errFlag = 20000000 + pulseLengthLastUs ;
        nec_state = 0; // Reset decoding process
        break;
      }

      if ( wasSpace ) {
        // we are interested only in the space length
        if ( pulseLengthLastUs > 1000) // If space width > 1ms (short space)
          bitSet(nec_code, (31 - i)); // Write 1 to bit (31 - i)
        else // If space width < 1ms (long space)
          bitClear(nec_code, (31 - i)); // Write 0 to bit (31 - i)
        i++;
        if (i > 31) { // If all bits are received
          i = 0 ;
          nec_ok = 1; // Decoding process OK
          detachInterrupt(0); // Disable external interrupt (INT0)
        }
      }
      break;
  }
}

void loop() {

  if ( errFlag > 0 ) {
    Serial.print( "Error: " ) ;
    Serial.println( errFlag ) ;
    errFlag = 0 ;
  }

  if ( nec_state > 0 && millis() - decodeStartAtMs > 90 ) {
    Serial.println( "Timeout" ) ;
    nec_state = 0 ;
  }

  if (nec_ok) {
    Serial.print( "Code received = " ) ;
    Serial.println( nec_code, HEX ) ;

    address = (nec_code >> 16) & 0xFF; // Extract address from received code
    inv_command = (nec_code >> 8) & 0xFF; // Extract inverted command from received code
    command = nec_code & 0xFF; // Extract command from received code
    if (command == ((~inv_command) & 0xFF)) { // Verify command validity
      Serial.print("Received valid NEC code: ");
      Serial.print(address, HEX); Serial.print(", ");
      Serial.print(command, HEX); Serial.print(", ");
      Serial.println(inv_command, HEX);
    }
    else {
      Serial.println("Received invalid NEC code!");
    }
    nec_ok = 0; // Reset decoding process
    nec_state = 0; // Reset decoding state
    attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Re-enable external interrupt (INT0)
  }

}
```

This utility can be used to verify the output of an IR receiver showing the timings of the pulses and spaces to  4us resolution.

```
// protocol analyser utility
// intended to dump timings to the serial console for example from demodulated NEC IR codes
// Connect the IR receiver output to pin 2

const uint8_t DATA_SIZE = 100 ;

struct intervalRead_t {
  uint32_t durationUs ;
  bool space ;
} ;

intervalRead_t intervalRead[ DATA_SIZE ] ;

volatile unsigned long enteredAtUs = 0 ;
volatile uint8_t index = 0 ;
volatile bool firstPulse = true ;

void saveTimes() {

  bool wasSpace;
  uint32_t pulseLengthLastUs ;

  wasSpace = ! digitalRead( 2 ) ;
  pulseLengthLastUs = micros() - enteredAtUs; // Calculate pulse length
  enteredAtUs = micros(); // Store current time for next entry

  if ( firstPulse ) {
    firstPulse = false ;
    index = 0 ;
  }
  else {
    if ( index < DATA_SIZE  )  {
      intervalRead[ index ].durationUs = pulseLengthLastUs ;
      intervalRead[ index ].space = wasSpace ;
      index++ ;
    }
  }
}

void setup() {
  Serial.begin(9600);
  pinMode( 2, INPUT_PULLUP ) ;
  attachInterrupt(digitalPinToInterrupt(2), saveTimes, CHANGE); // Enable external interrupt (INT0)
}

void loop() {
  if ( !firstPulse && micros() - enteredAtUs > 500000UL  ) {
    for ( uint8_t i = 0; i < index ; i++ ) {
      Serial.print( i ) ;
      Serial.print( "\tinterval= " ) ;
      Serial.print( intervalRead[ i ].durationUs ) ;
      Serial.print( "us  \t") ;
      Serial.print( intervalRead[ i ].space ? "space" : "pulse" ) ;
      Serial.println( ) ;
    }
    Serial.println( ) ;
    firstPulse = true ;
  }
}

```


message:
override pinMode, digitalWrite and digitalRead

I am using the [ESP32 Arduino Framework](https://github.com/espressif/arduino-esp32) and I have some [GPIO expanders](https://www.ti.com/product/TCA6408A) attached via I²C. They work fine and I now want to map some unused pin numbers to them so I can used my custom pin numbers in `pinMode`, `digitalRead` and `digitalWrite`.

Luckily, [the Arduino core links these functions weakly](https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c#L228).

```c++
extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode")));
```

I defined my own functions like so:
```c++
void pinMode(uint8_t pin, uint8_t mode) {
    if(pin<0x80)
        // call conventional handler
    else
        // communicate with GPIO expander via I²C
}
```

Unfortunately, calling any of the functions will not result in the linker picking my implementation but the linker picks the default implementation.

Any ideas how to override the weakly linked `pinMode`, `digitalWrite` and `digitalRead`?

body:
I found the issue: I ran `platformio run --target clean` instead of `platformio run --target cleanall`. It seems that only the latter command cleans all build artifacts. The next time I compiled and uploaded, it worked as expected.

Another issue occurs only with Adafruit libraries: Some libraries do not use `uint8_t` for ports but `int8_t` and they do checks like
```c++
if(pin_number >=0)  {
    // code that only works with pin numbers between 0x01 and 0x80
}
```
Take the [Adafruit GFX library](https://github.com/adafruit/Adafruit-GFX-Library/blob/5ea4be3ffeae918899aeec8cbb67f87359cf0026/Adafruit_SPITFT.cpp#L533) as an example. As a workaround, I will map my GPIO expander ports to 0x40, 0x41, ...


message:
timing changes once DC motors are connected to power

I'm using an arduino uno with two DC motors. I'm also using the built in LED to tell me when the motors should be on as a debug tool. The code is a simple while loop that turns both the motors and the LED on for 10 seconds, and off for 5, and repeat, while a witch is on. This works fine when the motors are not connected to power (when the switch is on, the LED turns on for 10 secs, off for 5 and repeat), but when the motor driver is connected to the power the timing is changed. The motors and the LED are on for less than a second, and off for 5. the "on" period changes a bit, once it even reached the intended 10 seconds.

Why is that and how do I fix that? I tried changing batteries (though i don't know how that might change things, as the led is also working incorrectly and it works of a seperate power source).

the Arduino is connected to a 9V battery and the motors are connected to 4 AA batteries through a L298N motor driver.

this is my code:
```
#include <Arduino.h>
int RightSpeedPin = 5;
int Rdir2 = 6;
int Rdir1 = 7;
int led = 13;
int LeftSpeedPin = 10;
int Ldir2 = 8;
int Ldir1 = 9;
int SwitchPin = 4;
int ReadVal;
void setup() {
  // put your setup code here, to run once:
  pinMode(Rdir1, OUTPUT);
  pinMode(Rdir2, OUTPUT);
  pinMode(RightSpeedPin, OUTPUT);
  pinMode(LeftSpeedPin, OUTPUT);
  pinMode(Ldir1, OUTPUT);
  pinMode(Ldir2, OUTPUT);
  pinMode(SwitchPin, INPUT);
  pinMode(led, OUTPUT);
}

void loop() {
  ReadVal = digitalRead(SwitchPin);
  while (ReadVal == 1)
  {
    digitalWrite(led, HIGH);
  // starting situation- both motors heading forward
    // running for 10 secs
    digitalWrite(Rdir1, HIGH);
    digitalWrite(Ldir1, HIGH);
    digitalWrite(Rdir2, LOW);
    digitalWrite(Ldir2, LOW);
    analogWrite(RightSpeedPin, 255);
    analogWrite(LeftSpeedPin, 255);
    delay(10000);
    // off for 5
    analogWrite(RightSpeedPin, 0);
    analogWrite(LeftSpeedPin, 0);
    digitalWrite(led, LOW);
    ReadVal = digitalRead(SwitchPin);
    delay(5000);
  }
}
```
[link to the schematics][1]. its rough, I'm not very experienced at drawing schematics. Note that all the ground wires are connected to a breadboard ground rail other that the 9V that powers the arduino. its connected with a round plug, so i don't have individual wires.
EDIT: fixed the schematic
[![circuit][2]][2]

  [1]: https://crcit.net/c/58642dd9da3d41948a9847bb69c874b9
  [2]: https://i.stack.imgur.com/eBwSk.png

body:
After debugging by printing:

    sTime = millis();
    analogWrite(RightSpeedPin, 255);
    analogWrite(LeftSpeedPin, 255);
    delay(5000);
    analogWrite(RightSpeedPin, 0);
    analogWrite(LeftSpeedPin, 0);
    Serial.print(millis() - stime);

I got times that are less than 300 ms, and no reset (added print to setup). I still have no idea why.
after that, I just replaced delay with `while (millis() < Stime + t) {` which solved my problem.


message:
How to configure I2S with ESP32 and MAX98357A to reproduce wav files?

I have configured I2S to reproduce files with an ESP32 and a MAX98357A from and SD card. The problem is that it reproduces the files way too fast, like they are sped up * 100. Here is my (simplified) code:
```cpp
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26

void setup() {
// Start SD card and sqlite
  SPI.begin();
  if (!SD.begin()) {
    Serial.println("SD card not found");
    while (1) {};
  }
// Configure I2S
  i2s_config_t i2s_config = {
      .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = 44100,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
      .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
      .communication_format = I2S_COMM_FORMAT_I2S_MSB,
      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
      .dma_buf_count = 2,
      .dma_buf_len = 1024,
      .tx_desc_auto_clear = true,
  };

  i2s_pin_config_t pin_config = {
      .bck_io_num = I2S_BCLK,
      .ws_io_num = I2S_LRC,
      .data_out_num = I2S_DOUT,
      .data_in_num = -1,
  };

  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
  i2s_set_sample_rates(I2S_NUM_0, 44100);
}

void loop() {
// Play the audio file
  string filename = "/audios/" + text + ".wav";
  File file = SD.open(filename.c_str());
  if (!file) {
    Serial.println("Failed to open file for reading");
    return;
  }

  const size_t buffer_size = 512;
  uint8_t buffer[buffer_size];
  size_t bytes_read;
  size_t bytes_written;
  while (file.available() && (bytes_read = file.read(buffer, buffer_size)) > 0) {
    i2s_write(I2S_NUM_0, buffer, bytes_read, &bytes_written, portMAX_DELAY);
    if (bytes_read == 0) break;
  }
  file.close();
}
```

How do I configure it correctly?

body:
So I figured it out (a somewhat long time ago) but forgot to post here hahaha.

Basically, the `i2s_config_t` was not properly configured. Here's a corrected version:

```cpp
i2s_config_t i2s_config = {
      .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = 44100,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
      .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
      .communication_format = I2S_COMM_FORMAT_I2S_MSB,
      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
      .dma_buf_count = 8,
      .dma_buf_len = 1024,
      .use_apll = false,
      .tx_desc_auto_clear = true,
  };
```

If you compare, the `.channel_format` configuration changes from `I2S_CHANNEL_FMT_RIGHT_LEFT` to `I2S_CHANNEL_FMT_ONLY_LEFT`. This is important because when using `RIGHT_LEFT` and only using one amplifier, 2 sound outputs were sent but only one amp was receiving them, causing the sound to play at twice the speed. Now, the `.dma_buf_count` was increased to 8, and added the `.use_apll` config, because I saw it somewhere else, I don't really know what it does hahaha.

There are other things.
In the setup for the i2s communication, I didn't include

```cpp
i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
i2s_set_sample_rates(I2S_NUM_0, 44100);
```

And created a new function, `play_sound`.

Here's the complete code:

```cpp
// sound.cpp

#include <sound.h>

bool parseWavHeader(File &file, WavHeader &header) {
  if (file.read() != 'R' || file.read() != 'I' || file.read() != 'F' || file.read() != 'F') {
    Serial.println("Invalid WAV file");
    return false;
  }

  file.seek(22);
  header.num_channels = file.read() | (file.read() << 8);
  header.sample_rate = file.read() | (file.read() << 8) | (file.read() << 16) | (file.read() << 24);
  file.seek(34);
  header.bits_per_sample = file.read() | (file.read() << 8);
  file.seek(44);  // Skip to the audio data
  return true;
}

void setup_sound() {
  i2s_config_t i2s_config = {
      .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = 44100,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
      .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
      .communication_format = I2S_COMM_FORMAT_I2S_MSB,
      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
      .dma_buf_count = 8,
      .dma_buf_len = 1024,
      .use_apll = false,
      .tx_desc_auto_clear = true,
  };

  i2s_pin_config_t pin_config = {
      .bck_io_num = I2S_BCLK,
      .ws_io_num = I2S_LRC,
      .data_out_num = I2S_DOUT,
      .data_in_num = -1,
  };

  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
}

void play_sound(std::string text, fs::FS &SD) {
  std::string filename = "/audios/" + text + ".wav";
  File file = SD.open(filename.c_str());
  if (!file) {
    Serial.println("Failed to open file for reading");
    while (1) delay(1);
  }

  WavHeader header;
  if (!parseWavHeader(file, header)) {
    Serial.println("Invalid WAV file");
    return;
  }

  i2s_set_sample_rates(I2S_NUM_0, header.sample_rate);

  const size_t buffer_size = 512;
  uint8_t buffer[buffer_size];
  size_t bytes_read;
  size_t bytes_written;
  while (file.available() && (bytes_read = file.read(buffer, buffer_size)) > 0) {
    i2s_write(I2S_NUM_0, buffer, bytes_read, &bytes_written, portMAX_DELAY);
    if (bytes_read == 0) break;
  }

  file.close();
}
```

```cpp
// sound.h

#ifndef SOUND_H
#define SOUND_H

#include <SD.h>
#include <driver/i2s.h>

#define I2S_DOUT 25
#define I2S_BCLK 33
#define I2S_LRC 26

struct WavHeader {
  uint32_t sample_rate;
  uint16_t bits_per_sample;
  uint16_t num_channels;
};

bool parseWavHeader(File &file, WavHeader &header);
void setup_sound();
void play_sound(std::string text, fs::FS &SD);

#endif  // SOUND_H
```

Hope it helps you not go through the struggle I went through!


message:
ARDUINO DC Motor Control over IR Sensor INPUT

I'm working on a school project where I'm building a small convyeor belt using an ARDUINO, DC motor and IR sensor for moving object detection so my color sensor can read color value.

I'm using single mosfet IRFZ44N to control DC motor. I can control DC motor using mosfet normally as turning it ON/OFF using digitalWrite using an arduino.

So, I want to stop convyeyor belt for 500ms when IR sensor detects HIGH and let color sensor read color of object and then let object move ahead normally on belt.
I have written below code but the IR sensor detect object but motor never stops running.
```
#define IR_COLOR 34

const int MOTORpin = 32;
const long onDuration = 1000;// OFF time for LED
const long offDuration = 1000;// ON time for LED
int MOTORState =HIGH;// initial state of LED

boolean MOTOROnFlag          = true;

long rememberTime=0;

void setup() {
  pinMode(IR_COLOR, INPUT);
  pinMode(MOTORpin,OUTPUT);// define MOTORpin as output
  digitalWrite(MOTORpin,MOTORState);// set initial state
}

void loop() {

  int state = digitalRead(IR_COLOR);

 if( state == false )
 {
    if( (millis()- rememberTime) >= onDuration){
    MOTORState = LOW;
    rememberTime=millis();
    }
 }
 else if(state == true)
 {
    if( (millis()- rememberTime) >= offDuration){
    MOTORState =HIGH;// change the state of LED
    rememberTime=millis();// remember Current millis() time
    }
 }

 digitalWrite(MOTORpin,MOTORState);// turn the LED ON or OFF

}// loop ends

```

body:
You have the general idea.

Your code looks a bit cluttered. Comments are not part of the program, keep them away from the code.

The `if` statements reduce to `if (true)`, that means that `== true` part is redundant.
All you need is `if(state)`. The `if` block will execute when `state` is true.
Conversely `if (!state)` tests for `state` being false

When there are only two possible values, then `else if(state == true)` can be simply `else`.

Identical code that is in both parts of the `if-else` block should be moved to outside of the block, `rememberTime=millis();` should be moved to after the closing brace `}` of the `if-else` block.

Here is some code that does what you want.

This code has not been tested on a hardware device.

https://wokwi.com/projects/364353854313747457

```lang-cpp
const int     sensor_blocked  = LOW;              // define sensor values
const int     sensor_clear    = HIGH;

const int     motor_on        = HIGH;
const int     motor_off       = LOW;

const int     master_enable   =  2;
const int     motor_pin       =  3;
const int     sensor_pin      = 12;

int           sensor_state;
int           sensor_previous = sensor_clear;
int           motor_state     = motor_on;

unsigned long millis_previous = 0;
unsigned long millis_now;

const long    interval        = 500;

void setup() {

  pinMode(master_enable, INPUT_PULLUP);
  pinMode(sensor_pin,    INPUT_PULLUP);
  pinMode(motor_pin,     OUTPUT);

}

void loop() {

  sensor_state = digitalRead( sensor_pin );

  // ---------------------------------------------------------------------------------------------------

  if ( sensor_state != sensor_previous ) {             // only run this code when sensor state changes
    sensor_previous = sensor_state;                    // remember new sensor state

    if ( sensor_state == sensor_blocked ) {            // sensor became blocked
      motor_state = motor_off;                         // turn off motor
      millis_previous = millis();                      // start of "motor off" interval
    }
    delay(20);                                         // debounce sensor
  }

  // ---------------------------------------------------------------------------------------------------

  if ( motor_state == motor_off ) {                    // timer check is relevant only when motor is off
    millis_now = millis();
    if ( millis_now - millis_previous >= interval ) {  // check if timer expired
      motor_state = motor_on;                          // enable motor
    }
  }

  // ---------------------------------------------------------------------------------------------------

  if ( digitalRead( master_enable ) != LOW ) motor_state = motor_off;     // master switch

  // ---------------------------------------------------------------------------------------------------

  digitalWrite(motor_pin, motor_state);                // translate motor state into action

}

```


message:
Avoid 1-LSB noise on ADC readings

I have a potentiometer connected to an ADC input of an Arduino Leonardo.
The ADC resolution is 10-bit (0..1024), while I need just 7-bit (0..127).

I use a simple filter to reduce the noise and then a `map` to cut the unused bits:

    #define ADC_CH                18
    #define ADC_FILTER            0.90

    uint16_t value;

    uint16_t adc = analogRead(ADC_CH);
    value = (uint16_t) ((float) ADC_FILTER * adc + (1. - ADC_FILTER) * value);

I show `value` on an LCD. It's very stable, but it may happen that if the adc readings are in the nearby of two values, there is nothing that could prevent a change in the final value, even if the noise is of just few LSBs.

Is there a simple way to implement an hysteresis for each low-res value?

In this way the change between N and N+1 happens on a different ADC reading than between N and N-1, improving the noise rejection without increasing the filter delay (that would only increase the change interval).

body:
When you reduce the resolution from 10 bits to 7 bits, every possible
output corresponds to an interval of inputs. If you add some hysteresis,
then those intervals should overlap. Below is a representation of the
input intervals corresponding to outputs 0, 1,… 6, for an
hysteresis width of 4:

```text
input: 0    5   10   15   20   25   30   35   40   45   50   55   60
       └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴
       ├─────0────┤
           ├───────1──────┤
                   ├───────2──────┤
                           ├───────3──────┤
                                   ├───────4──────┤
                                           ├───────5──────┤
                                                   ├───────6──────┤
```

To implement this in code, you have to remember the last output, and
change it only if the input lies outside the interval assigned to this
output. Here is an example implementation:

```c++
const int hysteresis = 4;  // tune to taste

/* Remove 3 bits of resolution while adding some hysteresis. */
int resample(int adc)
{
    static int value;  // last output
    if (adc < (value<<3) - hysteresis) {
        value = (adc + hysteresis) >> 3;
    } else if (adc >= ((value+1)<<3) + hysteresis) {
        value = (adc - hysteresis) >> 3;
    }
    return value;
}
```

Note that a `static` local variable keeps its value between successive
calls to the function.


message:
Why Did I Have To Program Duemilanove Bootloader?

As a volunteer for Public Invention, I have developed an Atmega328 based design in which I thought I was largely duplicating the Arduino UNO.
Unlike the UNO, I did choose a CH340 USB to UART chip as that was a part on some UNO clones I have purchased.

Our project, the General Alarm Device, is at:
https://github.com/PubInv/general-alarm-device

In the summer of 2022 We built up 15 Verion 1 assemblies.
When we went to put boot loader into them we found we could put the Duemilanove bootloader but not the UNO.  We do not know why.

Even with the Duemilanove bootloader we from time to time have problems uploading code. Some times the IDE reports a problem but the code uploaded.  And perhaps some times we had to try to load more than once.
Here is an issue written up after one user had some difficulty with firmware upload:
https://github.com/PubInv/general-alarm-device/issues/127

Related questions,
Is their a way to check which boot loader is in a board?

Could our root problem have been due to which boot loader was on the UNO we were using as the ICP?

body:
> Related questions, Is their a way to check which boot loader is in a board?

I wrote some code to detect chip signatures a while ago which also reports on known bootloaders: <http://www.gammon.com.au/forum/?id=11633>

It really is too long to post here. The code however is at <https://github.com/nickgammon/arduino_sketches> in particular in the **Atmega_Board_Detector** folder.

It's the same processor chip, you shouldn't have problems uploading, provided you use the appropriate clock speed and baud rate.

See my answers here:

* https://arduino.stackexchange.com/questions/13292/have-i-bricked-my-arduino-uno-problems-with-uploading-to-board/13293#13293

* https://arduino.stackexchange.com/questions/15936/what-happens-when-code-is-uploaded-using-the-bootloader/15937#15937

---

> Where do I learn what is appropriate?

Well, the bootloaders have hard-coded into them the speed at which they expect the serial data to arrive. In the case of Optiboot it is 115200 baud, some other bootloaders may use 9600, 57600 or other speeds.

Now this baud rate is also dependent on the clock rate of the processor, because the baud rate is derived from the system clock.

So for example, on a Uno, Optiboot "expects" (in the sense that a computer can expect anything) that it will be running on a board at 16 MHz, and that the communication will be at 115200 baud.

So, if you are running at 8 MHz (half that speed) then the baud rate will naturally be 57600. However you can compensate for that by editing the file `boards.txt` in your Arduino installation and changing the baud rate, eg.

    uno.name=Arduino Uno

    uno.vid.0=0x2341
    uno.pid.0=0x0043
    uno.vid.1=0x2341
    uno.pid.1=0x0001
    uno.vid.2=0x2A03
    uno.pid.2=0x0043
    uno.vid.3=0x2341
    uno.pid.3=0x0243

    uno.upload.tool=avrdude
    uno.upload.protocol=arduino
    uno.upload.maximum_size=32256
    uno.upload.maximum_data_size=2048
    uno.upload.speed=115200

    uno.bootloader.tool=avrdude
    uno.bootloader.low_fuses=0xFF
    uno.bootloader.high_fuses=0xDE
    uno.bootloader.extended_fuses=0xFD
    uno.bootloader.unlock_bits=0x3F
    uno.bootloader.lock_bits=0x0F
    uno.bootloader.file=optiboot/optiboot_atmega328.hex

    uno.build.mcu=atmega328p
    uno.build.f_cpu=16000000L
    uno.build.board=AVR_UNO
    uno.build.core=arduino
    uno.build.variant=standard

Change the line "uno.upload.speed" to read 57600 in this case. That way the program (avrdude) which uploads to the board will upload slower, and since you are running at a slower speed, all will be well.

---

So, to make it all work:

* Find which bootloader you have (by comparing signatures) or simply upload a new bootloader of a known type. I have a [page about uploading bootloaders](http://www.gammon.com.au/forum/?id=11635) which might help you there.

* Look up (eg. in that file) what the baud rate this particular bootloader uses (eg. 115200 for Optiboot).

* Set your processor to run at that clock speed with a crystal or resonator. (see the line "uno.build.f_cpu" which is 16000000 in this case).

* If you choose to run the processor at a different speed (eg. using the internal clock, at 8 MHz) then either use a bootloader designed for 8 MHz, or change the upload speed baud rate line in the file as mentioned above. I suggest copy/pasting an existing entry, changing for example "uno" at the start of each line to "myboard" or something like that, and the "name" line as well, so it will appear in the drop-down menu of available boards).


message:
How to make the built-in LED blink with a frequency of 5 Hz using interrupts

The task is: after five clicks on OK, the built-in LED starts flashing with a frequency of 5Hz using an interrupt. After the eighth click on OK, the flashing (and glowing) should stop.Why is flashing not working

    bool ledState = false;
    volatile bool ledOn = true;

    void setup(){
    TCCR2A = 0;
      TCCR2B = 0;
      TIMSK2 = 0;
      TCNT2 = 0;
      OCR2A = 77;
      TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
      TIMSK2 |= (1 << OCIE2A);
     pinMode(13, OUTPUT);
    }

    void loop(){
     if(button5.buttonPressedCount >= 5 && button5.buttonPressedCount < 8){
        ledState = true;
      }

      if(button5.buttonPressedCount > 7){
        ledState = false;
      }
    }

    ISR(TIMER2_COMPA_vect){
      if(ledState){
      digitalWrite(13, ledOn);
      ledOn = !ledOn;
      }
    }

body:
On the Uno (ATmega328P microcontroller), timers 0 and 2 are 8-bit only:
they cannot count beyond 255. Timer 1, on the other hand, is 16-bits.
This is the most convenient timer for generating low frequencies.

Speaking of frequencies... One LED period involves two toggles (turn on,
then turn off). Thus, if you want the LED to blink at 5 Hz, the toggle
action should happen at 10 Hz. Given that the CPU is clocked at 16 MHz,
this means you have to toggle the LED every 1,600,000 CPU cycles.

If you set the prescaler to 1,024, you then you have to count
1,600,000/1,024 = 1,562.5 timer cycles. You cannot count a non-integer
number of cycles, but you probably do not care about such accuracy. If
you do care, set the prescaler to 256 and count 1,600,000/256 =
6,250 timer cycles by setting the compare match register to 6,249.

One last issue: keep in mind that, in normal counting mode, the timer
counts up to its maximum value (65,535, or 255 on an 8-bit timer) and
then restarts at zero. If you want it to count only up the value set in
the compare match register, you should choose the appropriate waveform
generation mode: the fast PWM mode that lets you control the TOP value
with OCR1A.


message:
Program work when used Delay() but same program doesn't work with millis()

I'm running a dc motor using esp32 and mosfet by taking readings of IR.

Program works fine when used delay() but same program doesn't work when uploaded using millis().

```
//This uses fixed delay()

// Pin definitions
const int irSensorPin = 34;  // IR sensor connected to GPIO 2
const int motorPin = 32;     // DC motor connected to GPIO 4

// Variables
bool isObjectDetected = false;

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Set pin modes
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  // Check if object is detected
  if (digitalRead(irSensorPin) == LOW) {
    if (!isObjectDetected) {
      // Object detected for the first time
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Stop the motor
      delay(500);                   // Wait for 500ms
      Serial.println("Resuming motor.");
      digitalWrite(motorPin, HIGH); // Start the motor
    }
  } else {
    if (isObjectDetected) {
      // Object is no longer detected
      isObjectDetected = false;
    }
  }
}

 ```

```
//This uses millis()

// Pin definitions
const int irSensorPin = 34;  // IR sensor connected to GPIO 34
const int motorPin = 32;     // DC motor connected to GPIO 32

// Variables
bool isObjectDetected = false;
unsigned long motorStopTime = 0;
const unsigned long motorDelayTime = 500;  // Delay time in milliseconds

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Set pin modes
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);

  // Initialize motor state
  digitalWrite(motorPin, HIGH);  // Start the motor
}

void loop() {
  // Check if object is detected
  if (digitalRead(irSensorPin) == HIGH) {
    if (!isObjectDetected) {
      // Object detected for the first time
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Stop the motor
      motorStopTime = millis();     // Record the stop time
    }
  } else {
    if (isObjectDetected) {
      // Object is no longer detected
      isObjectDetected = false;
      unsigned long currentTime = millis();
      if (currentTime - motorStopTime >= motorDelayTime) {
        Serial.println("Resuming motor.");
        digitalWrite(motorPin, HIGH); // Start the motor
      }
    }
  }
}

```

body:
I am not sure I quite understand what the requirements are for this
program. However, they do not do the same thing. I tried to represent
their behavior as [state diagrams][], and here is what I got:

Version using `delay()`:

[![state diagram][1]][1]

Version using `millis()`:

[![state diagram][2]][2]

In the above diagrams, states with a gray background are those where the
motor is off. As can be seen here, the first version never keeps the
motor off for more than 0.5 s, where the second one can keep the
motor indefinitely off if the sensor remains HIGH.

I suggest you start by drawing the state diagram corresponding to the
behavior you actually want. Then, use the technique outlined in this
[tutorial on finite state machines][fsm] to turn the diagram into code.
Note that finite state machines work well with `millis()`-based timing.

[state diagrams]: https://en.wikipedia.org/wiki/State_diagram
[fsm]: https://majenko.co.uk/blog/finite-state-machine

  [1]: https://i.stack.imgur.com/gl1I6.png
  [2]: https://i.stack.imgur.com/VCS0S.png


message:
RFID card read loop seems to stop

I successfully programmed an RFID card reader to switch lights on and off if any rfid card is presented.  I have tested this and it works, with the lights continually switching on and off if any rfid enabled card is is presented.

I tried to add a command that if two specific cards are read (identified by their UID numbers) then only those cards would reset the lights to "off" no matter what the state they were currently in - like a reset button.

The problem is that once one of those cards is presented, the light goes off but the system stops responding and presenting one of the other cards no longer turns the light on and off.

I am fairly new to programming Arduino, as well as with RFID technology, but it seems like the loop does not reset to the beginning properly, or my IF statement somehow leaves the system in a state where the beginning code can't be run.

My code is below.  Any thoughts would be appreciated.

`

    #define r1 A0
    int relay1 = LOW;

    #include <SPI.h>
    #include <MFRC522.h>

    #define SS_PIN 10
    #define RST_PIN 9
    MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

    void setup()
    {
      pinMode(r1, OUTPUT);

      Serial.begin(9600);   // Initiate a serial communication
      SPI.begin();      // Initiate  SPI bus
      mfrc522.PCD_Init();   // Initiate MFRC522
      Serial.println("Approximate your card to the reader...");
      Serial.println();
    }

    void loop()
    {
      // Look for new cards
      if ( ! mfrc522.PICC_IsNewCardPresent())
      {
        return;
      }

    // Select one of the cards
      if ( ! mfrc522.PICC_ReadCardSerial())
      {
        return;
      }

      //Show UID on serial monitor
      Serial.print("UID tag :");
      String content = "";
      byte letter;
      for (byte i = 0; i < mfrc522.uid.size; i++)
      {
        Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
        content.concat(String(mfrc522.uid.uidByte[i], HEX));
      }
      Serial.println();
      Serial.print("Message : ");
      content.toUpperCase();

      if ((content.substring(1) == "23 49 1F BE") || (content.substring(1) == "CB CB 2C E3")) //change here the UID of the card/cards that you want to give access
      {
       Serial.println("Staff access");
        Serial.println();
        relay1 = HIGH;
        digitalWrite(r1, relay1);
        delay(500);
      }
      else
      {

        Serial.println("Authorized access");
        Serial.println();
        relay1 = ~ relay1;
        digitalWrite(r1, relay1);
        delay(500);
      }
    }

`

body:
The problem is the inappropriate use of the tilde (~) , which is a bitwise NOT operator, against the `int` variable `relay1`.
It appears to work correctly when relay1 starts with LOW which has the value 0. That is, relay1 has the internal value 0b0000000000000000.  If now the statement `relay1 = ~relay1` is executed, relay1 has the internal value 0b1111111111111111. This is treated as a HIGH in the expression `digitalWrite(r1, relay1);` So it appears to work correctly.
If again the statement `relay1 = ~relay1` is executed, relay1 has the internal value 0b0000000000000000 This is treated as a LOW in the expression `digitalWrite(r1, relay1);`
So that would also appear to work continuously, turning the relay on and off.

The problem comes when you explicitly set relay1 to HIGH here: `relay1 = HIGH;`. HIGH has the value 1, that is relay1 now has the intenal value 0b0000000000000001 and again that works, however, the next execution of the statement `relay1 = ~relay1` gives relay1 the internal value
0b1111111111111110 which is also treated as HIGH. So, from now on, the statement `relay1 = ~relay1` will always result in relay1 having a value which is interpreted as HIGH. So the relay appears to be stuck.

The solution, which already appears in a comment, is to change the statement `int relay1 = LOW;` to `bool relay1 = LOW;` and change this statement `relay1 = ~ relay1;` to `relay1 = ! relay1;`


message:
How can I observe the "voltage dips" the starter kit talks about in Project 5?

Project 5 of the Arduino Starter Kit [book](https://www.uio.no/studier/emner/matnat/ifi/IN1060/v21/arduino/arduino-projects-book.pdf) (page 63) involves wiring up a potentiometer to control a servomotor (see diagram). The book also recommends wiring up decoupling capacitors as shown in the diagram:

> When a servo motor starts to move, it draws more current than if it were already in motion. This will cause a dip in the voltage on your board. By placing a 100uf capacitor across power and ground right next to the male headers as shown in Fig. 1, you can smooth out any voltage changes that may occur. You can also place a capacitor across the power and ground going into your potentiometer.

Since the book doesn't explicitly warn against it, I decided to do this whole project without the capacitors just to see what would happen. It seemed to work fine, I didn't notice any erratic behavior. Is there some experiment I could do to actually measure these voltage "dips"?

I thought maybe I could try to measure the voltage drop across the servo, so I wired it in series with a resistor and connected the A0 ADC pin between the servo and the resistor. I did measure a drop, but the servo didn't work... I'm guessing it wasn't getting enough power because of the resistor?

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

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

body:
> I'm guessing it wasn't getting enough power because of the resistor?

Yes, that is probably what happened (you didn't specify what value your resistor had). When the servo tries to draw more current, more current has to flow through the resistor. This means more voltage over the resistor and less for the servo, which then doesn't have enough to to powerful or even run at all (depending on the resistors value).

> Is there some experiment I could do to actually measure these voltage "dips"?

You tried to measure the dips with the Arduino. Since the servo is connected directly to the 5V line of the Arduino, so its own Vcc, you cannot measure it the same way as the potentiometer. By default `analogRead()` uses Vcc as reference, meaning the max value. Instead you can configure it to use the internal 1.1V fixed reference (which doesn't depend on Vcc)(refer to [`analogReference()`][1]) and divide down Vcc with a fixed voltage divider (so that the voltage on the analog input pin would not exceed 1.1V).

Though to see the dips you still would need to measure the data points fast enough to catch them. Without knowing how long the dips might be it is difficult to say, if you can easily catch them. There are ways to do analog measurements relatively fast, but for a beginner (and specifically for a beginner book) that is a bit much.

The easier, but also more expensive solution (in terms of tools) is to measure Vcc with an oscilloscope. As entry a USB oscilloscope might be fitting (in the range of maybe 50$). If you don't wanna buy, you might be able to get access to one at the next makerspace or university. Some schools also might have some oscilloscopes.

> Since the book doesn't explicitly warn against it, I decided to do this whole project without the capacitors just to see what would happen. It seemed to work fine

Dips in your supplied voltage might cause the Arduino to reset. But that only happens, when the dip is too big. And that depends on multiple factors:

- How much current can be drawn from your power supply. USB ports on a PC won't give you more than 500mA for example. And some battery types have a big series resistance, meaning that the voltage will drop significantly, when you draw too much current from them.
- Sometimes, when working on a breadboard, the contacts might also have a significant resistance to them. This can lead to a voltage loss there.
- How strong the motor is. In starter kits you typically have these cheap and small SG90 micro servos. These don't draw a lot of power generally and are not really strong.
- How much load is on the motor. A motor draws different amounts of current depending on its load. When it runs feely the currently is the smallest. When its starting, then it needs to fight against its own inertia, thus needing more current. The most current is used, when the motor stalls, because it is not powerful enough to push against the load.

The last two points affect the motor current, which might cause a voltage dip, if the power supply cannot provide that much current with the specified voltage.

The capacitors are a precaution in this case. I think the author wanted to explain this to make sure that it would work for everyone and that students would already know about this, when moving to bigger, more power hungry projects.

  [1]: https://reference.arduino.cc/reference/en/language/functions/analog-io/analogreference/


message:
Arduino uno weird behavior on a simple counter program

So I just got my first Arduino Uno board and the output on the serial monitor doesn't make sense to me. For this code

    int counter = 0;

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

    }

    void loop() {
      counter++;
      Serial.println(counter);
      delay(1);
    }
I'm expecting to see an increment once every 1ms. But what I see from the console is odd[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/4AFWH.png
First, I'm expecting to see the timestamp like this: 27.270, 27.271, 27.272...
Second, from 27.301 to 27.334, I only saw the counter increase by 7 instead of ~30.

body:
If you do something like

```c++
Serial.println(580);
```

that is 5 characters printed (3 digits, then CR and LF to end the
line). Each character takes ten bits worth of transmission time (one
start bit, 8 data bits and one stop bit). The whole message is then
50-bit long on the serial line. At 9600 bits per second, this takes
about 5.2 milliseconds.

Note that the PC seems to be buffering the data, which is displayed in
batches, each batch having a single timestamp. Thus you see that, on
**average** there are 5.2 ms between increments.