message:
Can't convert string to UTF-16LE for MD5 calculation on an Arduino

TLDR
----
I need to convert text from a website into UTF-16LE format so that I can get the proper MD5 checksum but can't figure out how to go about doing that. This is all happening on an Arduino to log in to a router.

Background
----------
I want to read values from a smart home device connected to a Fritz!Box router using an Arduino with an ethernet connection. The router has an open [API][1] and I'm using HTTP ([EN][2]|[DE][3]) to get the values. C++ programming is not my strong point.

I have been basing my attempts on [BASH][4] and [javascript][5] examples. For MD5 calculation I'm using tzikis' [ArduinoMD5 library][6].

Steps
-----

Based on the manual, you need to do the following:

 1. Contact the router to get a challenge string (router sends XML)
 2. Generate a response by calculating an MD5 checksum using the challenge string and password: `<challenge>-<password>`
 3. Send the response, `<challenge>-<response>`, via POST
 4. Receive the XLM answer from the router containing the SID
 5. Use SID to request data or control a smart home device

I'm stuck on step 2. I have the challenge but cannot calculate the correct checksum.

The manual states:

> The MD5 hash is generated from the byte sequence of the UTF-16LE
> coding of this string (without BOM and without terminating 0 bytes).

Attempts
--------
So far I can request the challenge: 70067288 for example. The reponse appears to always be alphanumeric. My password is also alphanumeric.

```cpp
unsigned char* hash2 = MD5::make_hash("1234567z-äbc");
char *md5str2 = MD5::make_digest(hash2, 16);
free(hash2);
Serial.print("MD5: ");
Serial.println(md5str2);
```
This was my attempt at confirmation. The manual gave `1234567z` as a challenge example with `äbc` (the a in the example does indeed have umlauts) as a password. The response shown for this example was `1234567z-9e224a41eeefa284df7bb0f26c2913e2` but my checksum from the above code was `935fe44e659beb5a3bb7a4564fba0513`.

I tried "manually" generating UTF-16LE and calculating the MD5 but that didn't work either.

```cpp
byte rawTest[] = {0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, 0x7a00, 0x2d00, 0xe400, 0x6200, 0x6300};
char buffer[12] = {};
unsigned char* hash2 = MD5::make_hash(&buffer[0]);
char *md5str2 = MD5::make_digest(hash2, 16);
free(hash2);
Serial.print("MD5: ");
Serial.println(md5str2);
```
It gave me `d41d8cd98f00b204e9800998ecf8427e`.

I am not entirely sure the example given was correctly calculated. Using their example in the API documentation with BASH code from the site mentioned above, I get a different answer: `1234567z-bb6e5b7c7d4d485590f4e084ad3da989`.

```bash
#!/bin/bash
# -----------
# definitions
# -----------
FBF="http://192.168.178.1/"
USER="root"
PASS="äbc"
AIN="AINOFYOURFRITZDECTDEVICE"
# ---------------
# fetch challenge
# ---------------
CHALLENGE="1234567z"
# -----
# login
# -----
MD5=$(echo -n ${CHALLENGE}"-"${PASS} | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}')
RESPONSE="${CHALLENGE}-${MD5}"
echo $RESPONSE
```

Any help getting it working is greatly appreciatet.

----------

Working Example (with caveats)
------------------------------

Requirements:

 - Password using only characters found in ASCII
 - Password at least 17 characters long

The password must use _only_ ASCII characters due to the simple way it's being converted to UTF-16LE.

I can't explain why the password must be at least 17 characters long though. My code checks the length of the actual password programmatically.

With a password at least 17 characters long I get something like this:

> Challenge: 6c607ee5
>
> Challenge Pass (26): 6c607ee5-01234567890123456
>
> Challenge Pass Preallocation Length: 26
>
> MD5 (UTF-16LE): 3b26241ae4aab8eaf71d5c1599932178

Any password short and I get something like this:

> Challenge: 621611e1
>
> Challenge Pass (26): 621611e1-0123456789012345�
>
> Challenge Pass Preallocation Length: 25
>
> MD5 (UTF-16LE): 30a163ab8a267adfbb524b2b7412e81b

Please excuse any poor coding, C++ is not my strongpoint.

```cpp
void fritzboxSID() {
  EthernetClient fritzBox;
  const char* pass = "01234567890123456";  // 17 ASCII character minimum
  const char* user = "fritz3456";  // Account on router, randomly generated or user created
  const size_t passLength = strlen(pass);  // Password length
  char c;
  uint8_t xml = 0;
  char challenge[9] = {0};  // Challenge
  char challengePass[8 + 1 + passLength];  // challenge-password
  uint8_t challengeCount = 0;

  if (fritzBox.connect("192.168.200.1", 80)) {
 // Send login request
    fritzBox.println("GET /login_sid.lua HTTP/1.1");
    fritzBox.println("Host: 192.168.200.1");
    fritzBox.println("Connection: close");
    fritzBox.println();

    while (fritzBox.connected()) {
      while (fritzBox.available()) {
        c = fritzBox.read();  // Read a single character from the router response
        if (c == '>') {
          xml++;
        }
        if (xml == 5) {
   // Challenge starts after the fifth >
         if (challengeCount > 0 & challengeCount < 9) {
    // Save the challenge, character by character
             challenge[challengeCount-1] = c;
             challengePass[challengeCount-1] = c;
           }
           challengeCount++;
        }
        Serial.print(c);  // Print HTTP response
      }
    }
    challengePass[8] = '-';
    for (size_t i = 0;i < passLength; i++){
      // Copy password into the combined challenge-password string
      challengePass[i+9] = pass[i];
    }

 // Show challenge and pass, checking lengths
 //  If the strlen(challengePass) doesn't equal the preallocation length then the MD5 will be incorrect
    Serial.println("");
    Serial.print("Challenge: ");
    Serial.println(challenge);
    Serial.print("Challenge Pass (");
    Serial.print(strlen(challengePass));
    Serial.print("): ");
    Serial.println(challengePass);
    Serial.print("Challenge Pass Preallocation Length: ");
    Serial.println(8 + 1 + passLength);

    // Convert to UTF-16LE (only works for standard ASCII characters)
    const size_t length = strlen(challengePass);
    char buffer[2*length];
    for (size_t i = 0; i < length; i++) {
      buffer[2*i] = challengePass[i];
      buffer[2*i+1] = 0;
    }

    // Generate MD5
    unsigned char* hash = MD5::make_hash(buffer, 2*length);
    char *md5str = MD5::make_digest(hash, 16);
    free(hash);
    Serial.print("MD5 (UTF-16LE): ");
    Serial.println(md5str);
  } else {
    Serial.println("Cannot connect to 192.168.200.1");
  }
}
```

If it helps, the response from the router for the initial login request is this:
```
HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: close
Content-Type: text/xml
Date: Fri, 16 Sep 2022 08:21:27 GMT
Expires: -1
Pragma: no-cache
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'none'; connect-src 'self'; font-src 'self'; frame-src https://service.avm.de https://help.avm.de https://www.avm.de https://avm.de https://assets.avm.de https://clickonce.avm.de http://clickonce.avm.de http://download.avm.de https://download.avm.de 'self'; img-src 'self' https://tv.avm.de https://help.avm.de/images/ http://help.avm.de/images/ data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; frame-ancestors 'self'; media-src 'self'

<?xml version="1.0" encoding="utf-8"?><SessionInfo><SID>0000000000000000</SID><Challenge>621611e1</Challenge><BlockTime>0</BlockTime><Rights></Rights><Users><User last="1">fritz3456</User><User>UserName</User></Users></SessionInfo>
```

  [1]: https://avm.de/service/schnittstellen/
  [2]: https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID_english_2021-05-03.pdf
  [3]: https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID_deutsch_2021-05-03.pdf
  [4]: https://raspberrypiandstuff.wordpress.com/2017/08/03/reading-the-temperature-from-fritzdect-devices/
  [5]: https://github.com/andig/fritzapi/blob/master/index.js
  [6]: https://github.com/tzikis/ArduinoMD5

body:
You have to convert the string "<challenge>-<password>" to
UTF-16LE. If the whole string is plain ASCII, the conversion is trivial:
you just have to add a zero byte after each ASCII byte.

```c++
// ASCII string to be hashed.
const char* text = "1234567z-abc";  // umlaut removed

// Convert to UTF-16LE.
const size_t length = strlen(text);
char buffer[2*length];
for (size_t i = 0; i < length; i++) {
    buffer[2*i] = text[i];
    buffer[2*i+1] = 0;
}

// Compute and print the hash.
unsigned char* hash2 = MD5::make_hash(buffer, 2*length);
char *md5str2 = MD5::make_digest(hash2, 16);
free(hash2);
Serial.print("MD5: ");
Serial.println(md5str2);
```

Note that I use the two-parameter version of `MD5::make_hash()` in order
to pass the length of the buffer. The one parameter version of this
method would stop at the first zero byte.

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

**Edit**: Regarding your extended question (the new section “Working
Example”), this is a problem completely unrelated to the previous one.
It is about string termination.

In C and C++, strings are arrays of characters terminated with a NUL
ASCII character (numeric value zero). The terminating NUL is not part of
the string per se, but it should be stored in the array holding the
string. String literals are interpreted by the compiler as
NUL-terminated arrays of characters. Every function that expects a
string as an input expects it to be NUL-terminated.

In this particular instance, you failed to NUL-terminate
`challengePass`. When this array is given to `strelen()`, this function
scans the memory until it finds a zero byte. If that zero byte happens
to be right after the end of the array, your code will work as expected.
Otherwise, any non-zero byte coming after `challengePass` in memory will
be interpreted as being part of the string. The program behavior is
unpredictable, because you do not know what will be stored in memory
right after `challengePass`.

The solution is to NUL-terminate the string. Start by allocating one
more byte:

```c++
char challengePass[8 + 1 + passLength + 1];  // challenge-password
```

Then, right after copying the password, add a zero byte to terminate the
string:

```c++
challengePass[8 + 1 + passLength] = '\0';  // terminate the string
```

Note that `'\0'` means “the character with numeric value zero”.

Alternatively, you can terminate the string right after adding the dash,
then use `strcat()` to concatenate the password. `strcat()` will take
care of terminating the string:

```c++
challengePass[8] = '-';
challengePass[9] = '\0';  // temporarily terminate the string
strcat(challengePass, pass);  // append password
```


sender: user

message:
IF statement to run even if the requirement isn't met anymore

I have built a flasher for the headlamps on my race car. Whilst it works when I hold the switch down, if I release the switch and the circuit is closed my IF statements requirements are no longer met and it stops flashing.

Is there a way to have it continue to run the IF statement (but only once) even after I've let go of the switch and the requirement is no longer met?

Thanks in advance.

CODE:

    #define trig A3

    const int flash = 3; //D3
    const float mVc = 4.67; //reference voltage
    float counts = 0;
    float mV = 0;

    void setup() {
      Serial.begin(115200);
      pinMode(flash, OUTPUT);
    }

    void loop() {
      counts = analogRead(trig);
      //counts = 255;
      Serial.println(String(counts));

      mV = (counts*mVc) / 1000;
      Serial.println("Input Voltage: " + String(mV) + "v");

      //delay(1000);

    // voltage will need to be changed to matched output voltage when on car
      if (counts > 10) {
        analogWrite(flash, 100);
        delay(300);
        analogWrite(flash, 0);
        delay(80);
        analogWrite(flash, 100);
        delay(300);
        analogWrite(flash, 0);
        delay(80);
        analogWrite(flash, 100);
        delay(300);
        analogWrite(flash, 0);
        delay(80);
        analogWrite(flash, 100);
        delay(300);
        analogWrite(flash, 0);
        delay(80);
        analogWrite(flash, 100);
        delay(300);
        analogWrite(flash, 0);
        delay(1000);
      }
    }

-------
EDIT:

TL;DR Don't use voltage dividers to power the Nano.

When using a voltage divider to power the Nano (I know, I know) the below solution didn't fix the issue. I thought it may be due to the voltage dropping when the Nano supplies the 5vo to the mosfet but I'm not sure why holding the switch would stop that from happening. Regardless I swapped to a linear voltage regulator and then it started to flash, *"Hurrah!"* -- almost.

With the regulator in it was running the code constantly. I decided to print the runcount and I got a number over 35,000, meaning it would run the flash 5 times for >35,000 times. Although curious as to what would happen when it reached zero, I decided to go back to my original code and...now it works.

So I guess the lesson is: Even if you can calculate the drop off, don't run your Nano on a voltage divider.

----

**I have checked the answer below as the solution, although it didn't fix my issue there is no reason it shouldn't have worked and it may be useful to someone else.**

sender: assistant

body:
You could define an `int runcount = 0` variable at the top. Then change your loop logic to something like

    if (counts > 10) {
      runcount = 2;
    }

    if (runcount-- > 0) {
      //flashy flashy
    }

The effect is, that while button is pressed and `counts > 10`, runcount is set to two. Every time we check the runcount, it is decreased by 1. While the button is pressed, runcount is resat to 2. If you let go of the button, runcount will be 1 at the start of the if condition check. It will be compared to 0, condition will be true, and it will then be decreased to 0 and the if section will be executed one last time. Using another number than 2 will change the number of extra runs.


message:
Upload to board with no USB connection

I have a Spark Fun Pro Micro (ATmega32U4) without a USB connection (it was broken off at an earlier point) that I want to use to duplicate a prototype running on another Pro Micro.

How can I upload a sketch to an Arduino without a USB connection?

body:
The best solution is to solder back the connector or to buy a new board.

Ways to use a board with ATmega32u4 without USB for development are:
* ICSP programming
* upload over a serial bootloader.

Both require additional hardware.

For ICSP upload you need a programmer device. After configuring it, select the programmer in Tools menu and you can use "Upload using programmer" from the sketch menu. It is even possible to create a custom board definition which will use "Upload using programmer" with the "Upload" button from the toolbar.

To make serial upload possible you will need and USB-to-TTL-Serial adapter and  Optiboot compiled for the 32u4. To burn the bootloader you will need an ICSP programmer or a second Arduino to use with the [Arduino as ISP sketch][1].

  [1]: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP


message:
Robot car not working

My robot car won’t respond to my command. The code below worked before however, this time there is no response. I’ve tried experimenting with the code in the first while loop. I’ve tried different code from other projects similar to this. I’ve played with the schematics however, nothing seems to work.

This is my code:
```
#include <SoftwareSerial.h> // TX RX software library for bluetooth
#include <Servo.h> // servo library
Servo myservo1, myservo2, myservo3; // servo name
int bluetoothTx = 10; // bluetooth tx to 10 pin
int bluetoothRx = 11; // bluetooth rx to 11 pin
int motorOne = 4;
int motorOne2 = 5;
int motorTwo = 6;
int motorTwo2 = 7;
int enA = 3;
int enB = 2;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

//initial motors pin

char command;
char Value;

void setup()
{
  myservo1.attach(2); // attach servo signal wire to pin 9
  myservo2.attach(8);
  myservo3.attach(12);

  //Setup usb serial connection to computer
  Serial.begin(9600);
  //Setup Bluetooth serial connection to android
  bluetooth.begin(9600);
}
void loop()
{
  while (bluetooth.available() > 2) {
    Value = bluetooth.read();
    Serial.println(Value);
  }

  if ( Value == 'F') {
    // Robo Pet Run Forward
    digitalWrite(enA, 255);
    digitalWrite(enB, 255);
    digitalWrite(motorOne, HIGH);
    digitalWrite(motorOne2, LOW);
    digitalWrite(motorTwo, HIGH);
    digitalWrite(motorTwo2, LOW);
  } else if (Value == 'B') {
    //Robo Pet Run Backward
    digitalWrite(enA, 255);
    digitalWrite(enB, 255);
    digitalWrite(motorOne, LOW);
    digitalWrite(motorOne2, HIGH);
    digitalWrite(motorTwo, LOW);
    digitalWrite(motorTwo2, HIGH);
  } else if (Value == 'L') {
    //Robo Pet Turn Left
    digitalWrite(enA, 255);

    digitalWrite(motorOne, LOW);
    digitalWrite(motorOne2, LOW);
    digitalWrite(motorTwo, HIGH);
    digitalWrite(motorTwo2, LOW);
  } else if (Value == 'R') {
    //Robo Pet Turn Right

    digitalWrite(enB, 255);
    digitalWrite(motorOne, HIGH);
    digitalWrite(motorOne2, LOW);
    digitalWrite(motorTwo, LOW);
    digitalWrite(motorTwo2, LOW);
  } else if (Value == 'S') {
    //Robo Pet Stop
    digitalWrite(motorOne, LOW);
    digitalWrite(motorOne2, LOW);
    digitalWrite(motorTwo, LOW);
    digitalWrite(motorTwo2, LOW);
  }

  //Read from bluetooth and write to usb serial
  if(bluetooth.available()>= 2 )
  {
    unsigned int servopos = bluetooth.read();
    unsigned int servopos1 = bluetooth.read();
    unsigned int realservo = (servopos1 *256) + servopos;
    Serial.println(realservo);
    if (realservo >= 1000 && realservo <1180) {
      int servo1 = realservo;
      servo1 = map(servo1, 1000, 1180, 0, 180);
      myservo1.write(servo1);
      Serial.println("Servo 1 ON");
      delay(10);
    }
    if (realservo >= 2000 && realservo <2180) {
      int servo2 = realservo;
      servo2 = map(servo2, 2000, 2180, 0, 180);
      myservo2.write(servo2);
      Serial.println("Servo 2 ON");
      delay(10);
    }
    if (realservo >= 3000 && realservo <3180) {
      int servo3 = realservo;
      servo3 = map(servo3, 3000, 3180, 0, 180);
      myservo3.write(servo3);
      Serial.println("Servo 3 ON");
      delay(10);
    }

  }
}
```

I’m using this app:
https://play.google.com/store/apps/details?id=com.giumig.apps.bluetoothserialmonitor&hl=en&gl=US

And here are the schematics:
[![schematic][1]][1]

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

body:
In short, among whatever other problems you might have, **you've wired your TX and RX connections backwards according to your diagram and code.
Swap them either in hardware or in software.**

---

According to the [documentation][1]:
```c++
SoftwareSerial var_name(rxPin, txPin)
```

|SS Operation|
|------------|
|RX          |
|TX          |

You've constructed your `SoftwareSerial` object as:
```c++
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
```

|SS Operation|Pin Variable |
|------------|-------------|
|RX          |`bluetoothTx`|
|TX          |`bluetoothRx`|

Defined your pin variables to these pins:
```c++
int bluetoothTx = 10; // bluetooth tx to 10 pin
int bluetoothRx = 11; // bluetooth rx to 11 pin
```

|SS Operation|Pin Variable |Arduino Pin|
|------------|-------------|-----------|
|RX          |`bluetoothTx`| 10        |
|TX          |`bluetoothRx`| 11        |

Connected them as:

[![Serial connections][2]][2]

|SS Operation|Pin Variable |Arduino Pin|BT Operation|
|------------|-------------|-----------|------------|
|RX          |`bluetoothTx`| 10        |RX          |
|TX          |`bluetoothRx`| 11        |TX          |

**So, you have them backwards. Connecting their RX (inputs) which is is harmless but not helpful and connecting their TX (outputs) which *may* damage something.**

In case this isn't clear, the RX and TX on the HC-05 are labeled from its perspective and not from the perspective of the Arduino. Except for some things like an old external modem, RX and TX on device are nearly always labeled from that device's perspective.

---

A variable name like `bluetoothTx` can be confusing if you're not sure which thing is doing the transmitting. Is this the pin number *for transmitting* to Bluetooth or the pin that will be connected to the Bluetooth transmitter (in other words, *for receiving*)?

In some cases I just describe the situation in the variable name:
```c++
static const int PIN_SOFTSERIAL_RX_TO_BLUETOOTH_TX = 11;
static const int PIN_SOFTSERIAL_TX_TO_BLUETOOTH_RX = 10;
/// ...
SoftwareSerial bluetooth(
  PIN_SOFTSERIAL_RX_TO_BLUETOOTH_TX,
  PIN_SOFTSERIAL_TX_TO_BLUETOOTH_RX
);
```
I dunno that I'd go with a name *quite* that long, but you get the idea.

I'm swapping them in software here, leaving your physical connections as they were in the diagram mostly because I don't feel like redrawing your diagram. Though, if it were my project I would swap the wires (and defined pin numbers above), because the convention is to have SoftwareSerial receive on 10 just like hardware receives on pin 0 and to have SoftwareSerial transmit on 11 just like hardware transmits on pin 1; in order words, keeping the relative order of the pin numbers.

So this is what you have with the above code:

|SS Operation|Pin Variable                       |Arduino Pin|BT Operation|
|------------|-----------------------------------|-----------|------------|
|RX          |`PIN_SOFTSERIAL_RX_TO_BLUETOOTH_TX`| 11        |TX          |
|TX          |`PIN_SOFTSERIAL_TX_TO_BLUETOOTH_RX`| 10        |RX          |

Transmitters connected to receivers.
If you get confused build your own table and make sure your variable names make sense.

This has nothing to do with our question really, but: Most Arduino users, new ones anyway, are better off with an Arduino that has connectivity that displaces the need for SoftwareSerial. A minimal change from the Nano for what you're doing is a Micro or Pro Micro board. That board has native USB support which it uses to send "Serial" to the computer. That leaves the one actual hardware serial peripheral on the (Pro) Micro available for you to to connect to HC-05 (or whatever). There are a pile of options, including ones that just do Bluetooth also (without need of HC-05). Anyway, there are lots of ways to not use SoftwareSerial.

  [1]: https://docs.arduino.cc/learn/built-in-libraries/software-serial#softwareserial
  [2]: https://i.stack.imgur.com/speYU.png


body:
@timemage

Your answer was part of the solution!

Thank you very much! In the first while loop I switched it from ```bluetooth.available > 2``` to ```bluetooth.available > 0``` and then switched the signs of the TX and RX. Now the robot car is responding and running. However it won't turn left even though both motors work fine.


message:
On ATtiny84, why does delay() stop working properly when RadioHead ASK is used?

When I call the `delay()` function on the ATtiny84 micro, it delays for the expected time, until I call the `init()` function on an `RH_ASK` object. After this, the micro seems to freeze.

    #include <RH_ASK.h>
    RH_ASK driver();

    void setup() {
        delay(100); // works ok
        driver.init();
        delay(100); // freezes a long time (or maybe forever?)
    }

body:
After reading the source code, `RH_ASK.cpp`, I found a commented out macro.

    // RH_ASK on ATtiny8x uses Timer 0 to generate interrupts 8 times per
    // bit interval. Timer 0 is used by Arduino platform for millis()/micros()
    // which is used by delay()
    // Uncomment the define RH_ASK_ATTINY_USE_TIMER1 bellow, if you want to use
    // Timer 1 instead of Timer 0 on ATtiny
    // Timer 1 is also used by some other libraries, e.g. Servo. Alway check
    // usage of Timer 1 before enabling this.
    // Should be moved to header file
    //#define RH_ASK_ATTINY_USE_TIMER1

In other words, the default behaviour of RadioHead ASK `init()` is to use **Timer 0**, which causes `delay()` (which uses `millis()`/`micro()`) to behave incorrectly.

**To fix:** Tell RadioHead ASK to use **Timer 1**. Because the `RH_ASK_ATTINY_USE_TIMER1` macro is in the source and not the header (for now), you have to modify the actual RadioHead ASK source file, `RH_ASK.cpp`*. Un-comment the line `#define RH_ASK_ATTINY_USE_TIMER1` which will use **Timer 1** instead of **Timer 0**. Re-compile your code, and `delay()` should start working properly again.

\* `RH_ASK.cpp` can be found in `%USERPROFILE%\Documents\Arduino\libraries\RadioHead` on Windows, if you installed RadioHead via the Arduino IDE library manager.


message:
Unable to upload code to my digispark ATtiny 85 after upgrading bootloader

I've just received my digispark ATtiny85 (model B, I believe). I'm using Pop_OS for my PC, had a bit of a headache getting the arduino IDE recognising the device but after some trial and error I got there.

When uploading a sketch I would then get *erase errors* and if I recall correctly it was error -71.

I couldn't work it out but found out that my boards came with v1.6 of the micronucleus firmware. So I upgraded to the latest which is v2.6. Now when I upload a sketch however the output looks like the following

```
Sketch uses 718 bytes (11%) of program storage space. Maximum is 6012 bytes.
Global variables use 9 bytes of dynamic memory.
Running Digispark Uploader...
Plug in device now... (will timeout in 60 seconds)
Warning: device with unknown new version of Micronucleus detected.
This tool doesn't know how to upload to this new device. Updates may be available.
Device reports version as: 2.6
Warning: device with unknown new version of Micronucleus detected.
This tool doesn't know how to upload to this new device. Updates may be available.
Device reports version as: 2.6
```

I don't have a clue what to try next as everything feels like it should be at a working point. Not sure how to decipher "Updates may be available". I'm using the latest arduino IDE, with the digistump board manager url and using the latest micronucleus firmware for the board.

I tried to re-flash the firmware to v2.4 just on the off chance that the firmware was too new to be supported in arduino IDE but I received the same error as above but with just a different version number reported.

body:
It seems the latest version (1.6.7) of the [Digispark board support package][1] is quite old, older than I'd have guessed. And so it does come with an old Micronucleus programming tool. The tool [appears to compare the major version number of the firmware][2] as found in the USB device version. And since the Micronucleus tool in the 1.6.7 package is expecting nothing newer than major version 1, major version 2 of the firmware is not going to work with it.

You have a couple of options.

### Reprogram old firmware (1.11)

You already seem familiar with burning .hex files. So, if you want to use the latest official Digispark board support you need to burn the hex file for Micronucleus version 1.11.  I replicated your error, but using an [OLIMEXINO-85-ASM][3] which is highly similar to the Digispark but may not be identical.  After programming [micronucleus-1.11.hex][4] the board worked with the official Digispark board support package.

### Use ATTinyCore

However, you could also just abandon that old official package and use [ATTinyCore][5] which does come with a Micronucleus bootloader new enough to program the Digispark board with Micronucleus 2.6. I tested that as well.

### Patch a new Micronucleus tool into your old official support package

You can replace the Micronucleus tool with a newer one in your *arduino15*`/packages/digistump/tools/micronucleus/2.0a4` directory. Incidentally, I have no idea where the `2.0a4` comes from, but it is not indicative of a Micronucleus 2.0 in any way that I can tell.

For testing I put the 2.6 firmware on the board, specifically the [t85_default.hex][6] file, and stole the Micronucleus tool out of the latest ATTinyCore board packages tools directory, by renaming the existing file an symbolically linking in the other one:

```txt
$ pwd
/home/user/.arduino15/packages/digistump/tools/micronucleus/2.0a4
$ ls
launcher  micronucleus
$ mv -iv micronucleus micronucleus.backup
renamed 'micronucleus' -> 'micronucleus.backup'
$ ln -s ~/.arduino15/packages/ATTinyCore/tools/micronucleus/2.5-azd1b/micronucleus
$ readlink micronucleus
/home/user/.arduino15/packages/ATTinyCore/tools/micronucleus/2.5-azd1b/micronucleus
$
```

And that works as well.

  [1]: https://github.com/digistump/DigistumpArduino
  [2]: https://github.com/micronucleus/micronucleus/blob/v1.11/commandline/library/micronucleus_lib.c#L47-L59
  [3]: https://www.olimex.com/Products/Duino/AVR/OLIMEXINO-85-ASM/open-source-hardware
  [4]: https://github.com/micronucleus/micronucleus/blob/v1.11/firmware/releases/micronucleus-1.11.hex
  [5]: https://github.com/SpenceKonde/ATTinyCore
  [6]: https://github.com/micronucleus/micronucleus/blob/v2.6/firmware/releases/t85_default.hex


message:
Strange problems driving an Optocoupler (PC123) with a Nano

I'm having some strange issues getting a Nano to drive a PC123 optocoupler properly.

What I'm trying to do: In the real world, I need to press a button ONCE, and have the device that I'm connecting this too, see FIVE quick button presses... (Input 1 press, and Output 5 presses, at the timing I set in the code). I am using a mix of LED "Blinking / Flashing" code to do what I need.

My connection of the Opto seems fine. It works perfectly if I run this "BLINK" code: (With the PC123 optocoupler connected to Pin13):

```lang-cpp
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);                       // wait for a while
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(200);                       // wait for a while
}
```

When I run this, the Optocoupler turns ON and OFF as I need, and the device I am controlling is happy, but it obviously runs forever as I have no counters or anything.. (This proves my hardware is good at this point!)

But, when I try this following code, with the exact same hardware circuit, the output goes HIGH as soon as I ground Pin2, and it stays HIGH! It holds the optocoupler ON and there is no ON/OFF or "blinking or flashing". BUT, it only does this when the OPTO is connected (there is load) on the Nano output. If I disconnect the Opto, the Pin13 LED will flash as expected. And my code seems to work fine (on the on-board Pin 13 LED).

VERY interestingly and very strangley though, when the "power-up" Pin 13 LED flashes (i.e- when you power cycle the Nano, or press the reset button) this will trigger the Opto ON/OFF perfectly! But when the code starts to run, via my Pin 2 input switch, with the Opto connected to the Nano, the output locks HIGH again! What the!?

```lang-cpp
int ledPin = 13;   // LED is connected to digital pin 13
int switchPin = 2;   // switch connected to digital pin 2
int switchValue;   // a variable to keep track of when switch is pressed
int counter = 0;

void setup()
{
      pinMode(ledPin, OUTPUT);   // sets the ledPin to be an output
      pinMode(switchPin, INPUT);   // sets the switchPin to be an input
      digitalWrite(switchPin, HIGH);   // sets the default (unpressed) state of switchPin to HIGH
}

void loop()   // run over and over again
{

    switchValue = digitalRead(switchPin);   // check to see if the switch is pressed
      if ((switchValue == LOW) && (counter <= 1)) {   // if the switch is pressed then,
          for(int ii = 0; ii <= 5; ii++)   // 7 = 4 flashes, 5 = 3 flashes, etc
      {
          digitalWrite(ledPin, !digitalRead(ledPin));
          delay(100); // Length of the flashes in ms
          counter++;
      }
    }
      if (switchValue == HIGH)
      //if ((switchValue == HIGH) && (counter > 2))
      {
           counter = 0;
           delay(100); // Debounce

      }
}
```

I have tried filtering capacitors, diodes, resistance, pull-ups, pull-downs, everything I can think of and I am at a loss. Can anyone help me out? I'm thinking its a code issue (because I am an Arduino noob - please be gentle!), or a maybe a deficiency in the hardware of the Nano? FYI, I have done all of this on different Input and Output pins with the same results.

Any help would be greatly appreciated!

body:
I confess that I am not sure what you are trying to do, but I have an idea and I hope this helps. First, there are several Nanos and not all of them are AVR-based. I used an OLD Nano clone and even had to select the ATMega 328P (old bootloader) - it's been a while. I also used a 4N25 opto [this could make a difference, look at the data sheet for your device)..

You have not shown exactly how you have things wired up. Let's assume that it is like this - and I DO NOT think it is a good way of doing things (bear with me), and

[![WRONG WAY][1]][1]

Using this code, it works exactly as it should.

    int ledPin = 13;
    int switchPin = 2;
    int nflashes=10;
    void setup()
    {
      pinMode(ledPin, OUTPUT);
      pinMode(switchPin, INPUT);
    }

    void loop() {
      if ( digitalRead(switchPin)==HIGH) {
      for (int i = 0; i < nflashes; i++) {
          digitalWrite(ledPin, !digitalRead(ledPin));
          delay(100);
        }
        while (digitalRead(switchPin) == HIGH); // wait until switch is released
      }
    }

The opto turns on with D13 lighting the added LED and the onboard LED also turns on. Note that the onboard LED is dimmer because you are driving TWO LEDs ; the onboard one attached to D13 and the LED inside the opto and you have no current limiting resistor on the opto LED. I'm not sure if you have it wired this way but if so, in my view, it is not a good way of doing things.

Apart from that, think about what happens when you hit reset...my guess is that the ATMega sets all GPIO to input AND the boot loader initializes the onboard LED to an output and apparently flashes that LED - I am guessing and have not gone through the code. I notice that with the above scheme, I see both the new LED and the onboard LED flash once briefly on reset, as I would expect.

Hooking up the switch as I have shown (pulled to ground) will eliminate any problems from floating states during a reset. It will only be read HIGH when you press the switch after you initialize the GPIO.

________________________

I would put the opto on a separate GPIO like this:

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

...and using this slightly modified code

    int ledPin = 13;
    int switchPin = 2;
    int optoPin=10;
    int nflashes=10;
    void setup()
    {
      pinMode(ledPin, OUTPUT);
      pinMode(switchPin, INPUT);
      pinMode(optoPin, OUTPUT);
    }

    void loop() {
      if ( digitalRead(switchPin)==HIGH) {
      for (int i = 0; i < nflashes; i++) {
          digitalWrite(ledPin, !digitalRead(ledPin));
          digitalWrite(optoPin, !digitalRead(optoPin));
          delay(100);
        }
        while (digitalRead(switchPin) == HIGH); // wait here until switch is released
      }
    }

Everything works fine and the new LED does not flash during a reset and nothing gets stuck.

I wish you had show exactly what connections you made and I apologize if I missed some point.

Again, hope it helps.

  [1]: https://i.stack.imgur.com/PRmpq.jpg
  [2]: https://i.stack.imgur.com/8UjZ1.jpg


body:
**Thank you @DrG** for your excellent reply! I really appreciate the time you have taken on this. I will answer your questions here:

- What am I trying to do? I am adding the Nano to a Ham Radio Transceiver, that can change frequency (via button presses on the microphone) in only 1kHz, or 10kHz frequency steps. What I am doing here, is by adding this Nano to the microphone button circuit, and selecting the "1kKz" step option, I will get a "5kHz" step! This is great for searching for SSB signals quicky (1kHz is slow, 10kHz is too big and you miss some!). So, I press 1 time, the radio will step 5 times. This is the purpose of my project. :)

- How have I wired it up? **Exactly** the same as you have shown, and I have also used both D13 (not recommended as you said, and D10 (as you have used in your proposed answer).

- Your code is great, and I really like that it will use D13 to show what it's doing on the LED, and use D10 to drive the Opto. GREAT!

Now - here is the crazy part... Even with your code, and the exact circuit (other than my PC123 vs your 4N25 (I have 4N35's here too), I get exactly the same problem I had before! As soon as the Nano drives the Opto, regardless of the GPIO I configure, it locks HIGH! The D13 LED flashes as expected, but D10 goes high and never goes low again, until a reboot or power cycle...

I now believe that even my original code is fine (not the best way to do it, but still functional) but my NANO is faulty! It's an "ELEGOO NANO" clone. And I think it's the issue!!!

Your input is not wasted as I will use your code, it is much better than mine! :) I am going to get a new NANO and try this again, and now I am pretty confident that with a new Arduino, this will work! I will report back and let you know how it goes.

Best regards,

Pez


message:
Simulate pin behaviour based on PulseView recording

I have a bunch of PulseView recordings from an existing device. Currently to verify if my Arduino handles the input properly I always use the real device. However it would be great if I could somehow test my code with existing recordings. I am using platform.io. Perhaps there is some test framework that can mock a pin based on a recording? For example when I start the test, pin 8 should be high for 10μs then low for 7 and so on. Is there some framework to mock such things?

body:
I've never heard of such a test framework and I doubt there is one, at least for hobbyists. Such a framework would need to include a lot of hardware to accommodate all the possible electrical test cases and also a rather complex software to control the hardware according to user input. So it is not really practical to have a general testing framework.

But you can build your own for your specific case. Using another Arduino and outputting the requested pulses should not be too difficult. In the simplest version just some `digitalWrite()`s and some `delayMicroseconds()` calls.


message:
Removing spaces between characters in MD_Parola

I'm using ESP8266 and Max7219 module (8*32) and [MD_Parola library][1]. To create my own font, at first I used of [MDParolaFontEditor][2] and created the following fonts.

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

I edited file MD_MAX72xx_font.cpp using Arduino IDE and saved them as 150 and 151. I want to have the output as the following.

[![enter image description here][4]][4]

But, the output is as:

[![enter image description here][5]][5]

As you can see, there is a space between them! I think this space is automatically added between characters. My problem is that, how can I remove this space?

My code:

    void loop () {
    char MyText[]={151,150,0};
    P.displayText(MyText, PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
    P.displayAnimate();
    delay(3000);
    }

  [1]: https://github.com/MajicDesigns/MD_Parola
  [2]: https://pjrp.github.io/MDParolaFontEditor
  [3]: https://i.stack.imgur.com/JXRHF.png
  [4]: https://i.stack.imgur.com/GxMZg.png
  [5]: https://i.stack.imgur.com/G3Rso.png

body:
add this line in the void setup part

P.setCharSpacing(0);


body: The matrix with the extra space is 9 (not 8) columns wide (possibly because is was designed to be able to display a colon on a clock).


message:
How does a callback function get revoke itself eg. Connect function get revoked when there is new connection

Further to my previous question [here][1]

Can anyone help me understand how the callback function gets revoked itself? The connect function, disconnect function.

BLE custom UUID code source [here][2]

Another example is BLEUART which have callback functions:

    /*********************************************************************
     This is an example for our nRF52 based Bluefruit LE modules

     Pick one up today in the adafruit shop!

     Adafruit invests time and resources providing this open source code,
     please support Adafruit and open-source hardware by purchasing
     products from Adafruit!

     MIT license, check LICENSE for more information
     All text above, and the splash screen below must be included in
     any redistribution
    *********************************************************************/

    /*
     * This sketch demonstrate the central API(). A additional bluefruit
     * that has bleuart as peripheral is required for the demo.
     */
    #include <bluefruit.h>

    BLEClientBas  clientBas;  // battery client
    BLEClientDis  clientDis;  // device information client
    BLEClientUart clientUart; // bleuart client

    void setup()
    {
      Serial.begin(115200);
    //  while ( !Serial ) delay(10);   // for nrf52840 with native usb

      Serial.println("Bluefruit52 Central BLEUART Example");
      Serial.println("-----------------------------------\n");

      // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1
      // SRAM usage required by SoftDevice will increase dramatically with number of connections
      Bluefruit.begin(0, 1);

      Bluefruit.setName("Bluefruit52 Central");

      // Configure Battery client
      clientBas.begin();

      // Configure DIS client
      clientDis.begin();

      // Init BLE Central Uart Serivce
      clientUart.begin();
      clientUart.setRxCallback(bleuart_rx_callback);

      // Increase Blink rate to different from PrPh advertising mode
      Bluefruit.setConnLedInterval(250);

      // Callbacks for Central
      Bluefruit.Central.setConnectCallback(connect_callback);
      Bluefruit.Central.setDisconnectCallback(disconnect_callback);

      /* Start Central Scanning
       * - Enable auto scan if disconnected
       * - Interval = 100 ms, window = 80 ms
       * - Don't use active scan
       * - Start(timeout) with timeout = 0 will scan forever (until connected)
       */
      Bluefruit.Scanner.setRxCallback(scan_callback);
      Bluefruit.Scanner.restartOnDisconnect(true);
      Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms
      Bluefruit.Scanner.useActiveScan(false);
      Bluefruit.Scanner.start(0);                   // // 0 = Don't stop scanning after n seconds
    }

    /**
     * Callback invoked when scanner pick up an advertising data
     * @param report Structural advertising data
     */
    void scan_callback(ble_gap_evt_adv_report_t* report)
    {
      // Check if advertising contain BleUart service
      if ( Bluefruit.Scanner.checkReportForService(report, clientUart) )
      {
        Serial.print("BLE UART service detected. Connecting ... ");

        // Connect to device with bleuart service in advertising
        Bluefruit.Central.connect(report);
      }else
      {
        // For Softdevice v6: after received a report, scanner will be paused
        // We need to call Scanner resume() to continue scanning
        Bluefruit.Scanner.resume();
      }
    }

    /**
     * Callback invoked when an connection is established
     * @param conn_handle
     */
    void connect_callback(uint16_t conn_handle)
    {
      Serial.println("Connected");

      Serial.print("Dicovering Device Information ... ");
      if ( clientDis.discover(conn_handle) )
      {
        Serial.println("Found it");
        char buffer[32+1];

        // read and print out Manufacturer
        memset(buffer, 0, sizeof(buffer));
        if ( clientDis.getManufacturer(buffer, sizeof(buffer)) )
        {
          Serial.print("Manufacturer: ");
          Serial.println(buffer);
        }

        // read and print out Model Number
        memset(buffer, 0, sizeof(buffer));
        if ( clientDis.getModel(buffer, sizeof(buffer)) )
        {
          Serial.print("Model: ");
          Serial.println(buffer);
        }

        Serial.println();
      }else
      {
        Serial.println("Found NONE");
      }

      Serial.print("Dicovering Battery ... ");
      if ( clientBas.discover(conn_handle) )
      {
        Serial.println("Found it");
        Serial.print("Battery level: ");
        Serial.print(clientBas.read());
        Serial.println("%");
      }else
      {
        Serial.println("Found NONE");
      }

      Serial.print("Discovering BLE Uart Service ... ");
      if ( clientUart.discover(conn_handle) )
      {
        Serial.println("Found it");

        Serial.println("Enable TXD's notify");
        clientUart.enableTXD();

        Serial.println("Ready to receive from peripheral");
      }else
      {
        Serial.println("Found NONE");

        // disconnect since we couldn't find bleuart service
        Bluefruit.disconnect(conn_handle);
      }
    }

    /**
     * Callback invoked when a connection is dropped
     * @param conn_handle
     * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
     */
    void disconnect_callback(uint16_t conn_handle, uint8_t reason)
    {
      (void) conn_handle;
      (void) reason;

      Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
    }

    /**
     * Callback invoked when uart received data
     * @param uart_svc Reference object to the service where the data
     * arrived. In this example it is clientUart
     */
    void bleuart_rx_callback(BLEClientUart& uart_svc)
    {
      Serial.print("[RX]: ");

      while ( uart_svc.available() )
      {
        Serial.print( (char) uart_svc.read() );
      }

      Serial.println();
    }

    void loop()
    {
      if ( Bluefruit.Central.connected() )
      {
        // Not discovered yet
        if ( clientUart.discovered() )
        {
          // Discovered means in working state
          // Get Serial input and send to Peripheral
          if ( Serial.available() )
          {
            delay(2); // delay a bit for all characters to arrive

            char str[20+1] = { 0 };
            Serial.readBytes(str, 20);

            clientUart.print( str );
          }
        }
      }
    }

The following helps set the callback functions:

    clientUart.setRxCallback(bleuart_rx_callback);
    ...
    Bluefruit.Central.setConnectCallback(connect_callback);
    ...
    Bluefruit.Central.setDisconnectCallback(disconnect_callback);

Tracing back the libraries I found :

    void BLEPeriph::setConnectCallback( ble_connect_callback_t fp )
    {
      _connect_cb = fp;
    }

    void BLEPeriph::setDisconnectCallback( ble_disconnect_callback_t fp )
    {
      _disconnect_cb = fp;
    }

But I can't understand how this initializes the calling of the connect or disconnect function while getting a new connection or break in connection respectively.

 [1]: https://arduino.stackexchange.com/questions/90671/nrf52832-ble-conn-handle-to-disconnect-the-current-connected-devices
  [2]: https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/custom-central-hrm

body:
All a callback function assignment does is link an internal pointer to the function that you provide.

Any time the callback is needed to be called the code just uses the pointer that your function has been assigned to.

Thus `_connect_cb` and `connect_callback()` are one and the same thing. Any time `connect_callback()` would be expected to be used `_connect_cb()` is used instead.

It is, in effect, just creating an internal alias to your code then using that alias to call your code when it needs to.


message:
Arduino keyboard Input language problem

I need my Arduino (Leonardo) to open cmd, but if keyboard input language isn’t English it prints another language letters.

——— code ———
```
Keyboard.begin();
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
delay(1000);
Keyboard.releaseAll();
Keyboard.write("cmd");
Keyboard.press(KEY_RETURN);
Keyboard.releaseAll();
delay(1000);
```
——— ——— ———

So my question is: can I somehow detect language, and if it’s not there add it?

My idea was to set languagelist via powershell, and it would be perfect for my program, but I don’t know how I can write English text from Arduino on pc with another language :(

Also my Arduino has sd card, maybe it helps.

——— code ———
```
powershell $OldList = Get-WinUserLanguageList

powershell Set-WinUserLanguageList -LanguageList en-US -Force

-something

powershell Set-WinUserLanguageList -LanguageList $OldList -Force
```
——— ——— ———

Sorry if it is 0iq question, I’m very new to Arduino, it will be great to hear your ideas!

body:
Your Arduino will be virtually typing on a keyboard like this:

[![unlabeled keyboard](https://upload.wikimedia.org/wikipedia/commons/thumb/3/33/Happy_Hacking_Keyboard_Professional_2.jpg/640px-Happy_Hacking_Keyboard_Professional_2.jpg)](https://commons.wikimedia.org/wiki/File:Happy_Hacking_Keyboard_Professional_2.jpg)
<small>© Aon fi – CC-BY 3.0</small>

See the labels on the keys? There are none. Your Windows OS has its
own idea of what each key means, but the Arduino has no way of knowing
that. Instead, you have to tell it explicitly what keyboard layout to
use, e.g.:

```c++
Keyboard.begin(KeyboardLayout_fr_FR);
```

If you don't, the Keyboard library will assume `KeyboardLayout_en_US`.

There is no way the computer can tell the keyboard what layout it
expects.


body:
i finaly found a solution for my problem. I wrote an algorithm, that automaticly change system input language if there are only two languages and one of them is English. This code is writen on Duckduino shortcuts, but it is not a problem to convert it back.

```
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ok"
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList en-US, ru -Force
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

ALT SHIFT
DELAY 1000
GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ok"
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList ru, en-US -Force
ENTER
DELAY 1000
ALT SHIFT
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ENGLISH"
ENTER
DELAY 1000
```

You can use for ru another language, for **"ok"** i want to add `Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json` to save user's list.

> Than language is different than english this code makes errors, and than language is right it changes language list, thats how it works!

Update:
```
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList en-US, ru -Force
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

ALT SHIFT
DELAY 1000
GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList ru, en-US -Force
ENTER
DELAY 1000
ALT SHIFT
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "CODE IN ENGLISH"
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList
ENTER
DELAY 1000
STRING $importedFile = Get-Content C:\WinUserLanguageList.json | ConvertFrom-Json
ENTER
DELAY 1000
STRING $langCollection = New-Object System.Collections.Generic.List[Microsoft.InternationalSettings.Commands.WinUserLanguage]
ENTER
DELAY 1000
STRING foreach ($item in $importedFile) {
ENTER
DELAY 1000
STRING $lang = [Microsoft.InternationalSettings.Commands.WinUserLanguage]::new($item.LanguageTag)
ENTER
DELAY 1000
STRING $lang.InputMethodTips.Clear()
ENTER
DELAY 1000
STRING foreach ($inputMethod in $item.InputMethodTips) {
ENTER
DELAY 1000
STRING $lang.InputMethodTips.Add($inputMethod) }
ENTER
DELAY 1000
STRING $lang.Handwriting = $item.Handwriting
ENTER
DELAY 1000
STRING $lang.Spellchecking = $item.Spellchecking
ENTER
DELAY 1000
STRING $langCollection += $lang }
ENTER
DELAY 1000
STRING Set-WinUserLanguageList $langCollection -Force
ENTER
DELAY 1000
STRING Remove-Item C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING https://ma.kak.si
ENTER
```


message:
When Writing Library, return String or return char *

I am trying to write my own Arduino library and I would like to make it useful not just for ESP32/ESP8266 boards but also with Arduino boards.

I have created my header file like this
>test.cpp

    #ifndef TEST
    #define TEST
    #include "Arduino.h"

    #define MAX_STRING_LEN 50

    class MyClass{
        private:

        public:
            String getString();
            char * getCharPointer();
            char * getAnotherCharPointer();
    };

    #endif

and my
>test.cpp

    #include "test.h"

    static char buffer[MAX_STRING_LEN+1];

    String MyClass::getString(){
        // Sample REST API call
        String testString = String("{\"test:\" \"hello String json\"}");

        return testString;
    }

    char * MyClass::getCharPointer(){
        // Sample REST API call
        const char * sample_json = "{\"test:\" \"hello Char Pointer json\"}";
        strcpy(buffer, sample_json);
        return buffer;
    }

    char * MyClass::getAnotherCharPointer(){
        // Sample REST API call
        const char * sample_json = "{\"test:\" \"hello Another Char Pointer json\"}";
        strcpy(buffer, sample_json);
        return buffer;
    }

My test file main.cpp
>main.cpp

    #include <Arduino.h>
    #include "test.h"

    MyClass myClass;
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);

      Serial.println(myClass.getString());
      Serial.println(myClass.getCharPointer());
      Serial.println(myClass.getAnotherCharPointer());
    }

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

Result is ok

    {"test:" "hello String json"}
    {"test:" "hello Char Pointer json"}
    {"test:" "hello Another Char Pointer json"}

I have these doubts that I would like to ask for suggestions.
 1. Is returning the String class in Header files, not a good idea?  For ESP32/ESP8266 they are okay as they have big memory but for Arduino Uno boards I see a lot of discussions about not using String because it is bad and causes memory fragmentation etc.
 2. Is returning char * the safest way to make it compatible and useful to all MCU boards?
 3. Next question in char pointer, I often see this pattern done when returning char pointers like in this [Time.cpp][1] wherein a static buffer is used and defined at the implementation file (**test.cpp**) and all functions(getCharPointer, getAnotherCharPointer) that needs to return a char pointer just manipulates the static char buffer by using strcpy.  Is this the proper way to go in Arduino programming?

Can somebody please clear my doubts?  Thank you.

  [1]: https://github.com/PaulStoffregen/Time/blob/master/DateStrings.cpp

body:
>  I often see this pattern done when returning char pointers like in this Time.cpp wherein a static buffer is used and defined at the implementation file (test.cpp) and all functions(getCharPointer, getAnotherCharPointer) that needs to return a char pointer just manipulates the static char buffer by using strcpy. Is this the proper way to go in Arduino programming?

Arduino programming is C++ programming. You can return a pointer to a static buffer, of course. But the user of your function needs to know that if they call the function a second time the data will be overwritten. So, they would need to `strcpy` (that is, copy) the data before it is overwritten.

Personally I would stay away from the String class, unless it is being used only occasionally. It is fine with strings that are always the same size, but if they are not, memory fragmentation will be an issue.


body:
> [The OP asks:] For ESP32/ESP8266 they are okay as they have big memory but for Arduino Uno boards I see a lot of discussions about not using String because it is bad and causes memory fragmentation etc.

On Unos and other boards with very low memory, fragmentation won't take very long to happen. On boards with larger memories, it will merely *take longer!* but it will happen; it's just a difference of when. (And for completeness, I should say that allocating a few objects, *once*, and within the device's available free memory, won't cause fragmentation, any more than static allocation would).

>So why is allocation/deallocation used at all [I ask, rhetorically...]?

On systems running a full OS, driven by ourselves with a keyboard and mouse, most application programs are transient - they start up, do a job, and exit; even longer running ones like office applications are fairly speed-limited by us slow humans. And if a program crashes, we're still sitting there to re-run it, and no external device gets left hanging for hours or days, maybe destroying itself (by overheating, perhaps), maybe injuring or killing a patient (in the case of a medical device), injuring or killing many people (in case of a vehicle's engine- or flight controls).

Otherwise, run-time memory allocation is a convenience for the programmer.

> So what to do in an embedded system, instead [asks I]?

I use two techniques to get around the crash-proneness of the compiler-libraries' allocator/deallocators:

 1. When I write a library, I design it to expect an `(object *)` from the caller, as you anticipated in your 'doubt #3'. All the library has to do is put its result there; the memory will already have been allocated. *The library doesn't need to know or care **how** it was allocated.* Does this sound like I'm avoiding solving the problem and leaving memory issues for some else to deal with? Yes, indeed, and it is deliberate! The user of my library - you, (or me, some other day), the application writer/system architect - is the best one to anticipate their particular system's memory needs, and to decide how best to meet them.

Writing my library this way lets the library-user decide whether a static buffer, a local one, or a dynamic allocation is the best fit for their application.

2. I write my own memory management (probably at the application level rather than in the library). This almost always takes the form of an array of fixed-length buffers. No matter how much memory the caller asks for, as long as it is less than that fixed size, and one is available, then the call succeeds and a buffer will be returned; otherwise, the call fails. The caller doesn't know, or need to know, that the buffer returned to them might be larger than they requested.

Why is this technique any better? `malloc()`/`free()` and `new()`/`delete()` break up free memory into ever smaller pieces, as they are requested. *A fixed-size-buffer allocater does not break up memory.*

A system using these techniques together avoids memory fragmentation. The only way such a system can fail (due to memory allocation) is to not have enough in the first place, and the only fixes are 1) for the programmer to assign more memory for fixed-size buffers; or, if the board doesn't have enough more, then 2) build the system with a host board that has enough memory.


message:
What happen with my code? My sensor module LED2 Always ON

I got this code from robojax.com
i have follow all the step but when i try to clap its not turn off or turn on
but when i blowing on the sound sensor it reacts and makes the light turn on

```lang-cpp
int soundInPin = 2;// connect output to Sound module DO
int relayPin = 8;// Connected to relay or buzzer (or LED)
int extra5V = 12;// define a pin for extra extra 5V

// do not change values bellow
int val = 0; // sound value from pin 2
int relayON = 0;//light status
int heard = 0;//sound heard status

void setup() {

//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  Serial.begin(9600);
  pinMode(soundInPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
  pinMode(extra5V,OUTPUT);// set extra5V as output
  digitalWrite(extra5V,HIGH);// turn the extra5V pin HIGH to get 5V

}

void loop() {
//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  val = digitalRead(soundInPin);// read the sound pin

  if(val == HIGH && relayON == LOW){

    heard = 1-heard;// toggle the value of "heard" from HIGH to LOW or from LOW to HIGH
    delay(100);
  }
//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  relayON = val;// save the value of pin 2

      if(heard == HIGH){
        Serial.println("Light ON");
        digitalWrite(relayPin, LOW); // turn relay ON

      }else{
        Serial.println("Light OFF");
        digitalWrite(relayPin, HIGH);// turn relay OFF

      }

//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  delay(100);
}

body:
This is not an answer, so I will delete it after you read it.

Since you are a beginner, here is a comment on programming style.

Your code feels very cluttered and overwhelming because the comments are made a part of the program lines.

There is a difference in readability between these two lines.

```digitalWrite(extra5V,HIGH);// turn the extra5V pin HIGH to get 5V```

```digitalWrite(extra5V,HIGH);                // turn the extra5V pin HIGH to get 5V```

The comments are there for future, like next year, to remind you what the program does.

Also the following two lines are on the same indentation level

```
  relayON = val;     // save the value of pin 2

      if(heard == HIGH){
```
 and should be

```
  relayON = val;     // save the value of pin 2

  if(heard == HIGH){
```

With some formatting changes, your code could look something like this.

```
int soundInPin =  2;                       // connect output to Sound module DO
int relayPin   =  8;                       // Connected to relay or buzzer (or LED)
int extra5V    = 12;                       // define a pin for extra extra 5V

// do not change values below

int val        =  0;                       // sound value from pin 2
int relayON    =  0;                       // light status
int heard      =  0;                       // sound heard status

void setup() {                             // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338

  Serial.begin(9600);

  pinMode(soundInPin, INPUT_PULLUP);
  pinMode(relayPin,   OUTPUT);
  pinMode(extra5V,    OUTPUT);             // set extra5V as output

  digitalWrite(extra5V,HIGH);              // turn the extra5V pin HIGH to get 5V

}

void loop() {                              // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338

  val = digitalRead(soundInPin);           // read the sound pin

  if (val == HIGH && relayON == LOW) {

    heard = 1-heard;                       // toggle the value of "heard" from HIGH to LOW or from LOW to HIGH
    delay(100);

  }                                        // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338

  relayON = val;                           // save the value of pin 2

  if (heard == HIGH) {

    Serial.println("Light ON");
    digitalWrite(relayPin, LOW);           // turn relay ON

  } else {

    Serial.println("Light OFF");
    digitalWrite(relayPin, HIGH);          // turn relay OFF

  }
                                           // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  delay(100);
}
```


message:
How to get the scan duration below 1sec with Arduino BLE?

I want to scan continuously for other Bluetooth devices with my ESP32 using BLE. The `scan` method only accepts integers larger than 0, such as `scan->start(1, false)`. However I want the results to be more "responsive" and a 1 second scanning duration is too long. This is my sample code:
```c++
    #include <Arduino.h>
    #include <BLEAdvertisedDevice.h>
    #include <BLEDevice.h>
    #include <BLEScan.h>
    #include <string>
    #include <iostream>

    const int PIN = 2;
    const int CUTOFF = -40;
    BLEScan* scan;

    #define SERVICE_UUID "f5aeb701-4395-4387-b8d4-e1f542b05151"
    #define CHARACTERISTIC_UUID "b2bd617f-6f78-45e7-bfdd-3edf29a5661a"

    void setup() {
      pinMode(PIN, OUTPUT);
      BLEDevice::init("ESP32 GrooveBrick");
      Serial.begin(9600);

      BLEServer *pServer = BLEDevice::createServer();
      BLEService *pService = pServer->createService(SERVICE_UUID);
      BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                             CHARACTERISTIC_UUID,
                                             BLECharacteristic::PROPERTY_READ |
                                             BLECharacteristic::PROPERTY_WRITE
                                           );

      pService->start();
      BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
      pAdvertising->addServiceUUID(SERVICE_UUID);
      pAdvertising->setScanResponse(true);
      pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
      pAdvertising->setMinPreferred(0x12);

      scan = BLEDevice::getScan();
      scan->setActiveScan(true);
      /*!< Scan interval. This is defined as the time interval from
      when the Controller started its last LE scan until it begins the subsequent LE scan.
      Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
      Time = N * 0.625 msec
      Time Range: 2.5 msec to 10.24 seconds*/
      scan->setInterval(100); //interval (how often there is a scan)
      /*!< Scan window. The duration of the LE scan. LE_Scan_Window
      shall be less than or equal to LE_Scan_Interval
      Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
      Time = N * 0.625 msec
      Time Range: 2.5 msec to 10240 msec */
      scan->setWindow(99);  // window (how long the scans are) must be <= interval

      BLEDevice::startAdvertising();
    }

    void loop() {

      BLEScanResults results = scan->start(1, true);
      int best = CUTOFF;

      std::cout << "Scanning!" << "\n";

      for (int i = 0; i < results.getCount(); i++) {
        BLEAdvertisedDevice device = results.getDevice(i);
        std::cout << "Found BT-device: " << device.getName() << " RSSI: " << std::to_string(device.getRSSI()) << "\n";
        int rssi = device.getRSSI();
        if (rssi > best) {
          best = rssi;
        }
      }
      digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
      scan->clearResults();   // delete results fromBLEScan buffer to release memory

    }
```

body:
you cant using the callback from that function, but what you can do is to add you own callback that will receive every new radio event.

add this to your init code:

    BLEDevice::setCustomGapHandler(custom_handler);

and this before it:

    static void it_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
    {
     switch (event)
     {
      case ESP_GAP_BLE_SCAN_RESULT_EVT:
       if (param->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT)
       {
        // This event is triggered every time a new device is found, and contains the advertised data.
        // We should avoid processing or printing anything here to avoid hardware congestion
        // log_i("ESP_GAP_BLE_SCAN_RESULT_EVT");

        if (param->scan_rst.ble_adv != NULL)
        {
         //this makes sure that there is data to be processed
        }
       }
       break;
      default:
       // log_i("Event %d unhandled", event);
       break;
     }
    }


message:
DHT11 stops working when power comes from a power supply board

I had a mini project with a DHT11, a temperature and humidity sensor, working perfectly on my Arduino UNO clone. Then, I bought a power supply board, that can feed the sensor with the 5V it requires, but for some reason, it does not work. Powering the sensor with the Arduino makes it get the correct values, powering it with the board makes it to stop working at all.

I have used a multimeter for checking the volts and amps. The readings on the sensor are the same with the Arduino and the board, 5V, but the amps are not. It seems that the sensor only uses power for an instant, while "sensing". Using Arduino, a 1.62mA current flows to the sensor and then drops to 0, but using the board it never gets higher than 0.001mA.

I repeated the test with different wires, protoboards and even power supply boards. I have three of them, all working apparently ok and reading the same on the multimeter. The board have the jumpers in the correct position: 5V.

I am just an amateur learning how electronics works, and I do not understand what is happening here. Some ideas?

Working:

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

Not working:

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

I don't think the problem is in the code, but just in case...

```
#include "DHTStable.h"

DHTStable DHT;

#define DHT11_PIN 5

void setup() {
 Serial.begin(115200);
 Serial.println(__FILE__);
 Serial.print("LIBRARY VERSION: ");
 Serial.println(DHTSTABLE_LIB_VERSION);
 Serial.println();
 Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}

void loop() {

 // READ DATA
 Serial.print("DHT11, \t");
 int chk = DHT.read11(DHT11_PIN);

 switch (chk)
 {
  case DHTLIB_OK:
   Serial.print("OK,\t");
   break;
  case DHTLIB_ERROR_CHECKSUM:
   Serial.print("Checksum error,\t");
   break;
  case DHTLIB_ERROR_TIMEOUT:
   Serial.print("Time out error,\t");
   break;
  default:
   Serial.print("Unknown error,\t");
   break;
 }

 // DISPLAY DATA
 Serial.print(DHT.getHumidity(), 1);
 Serial.print(",\t");
 Serial.println(DHT.getTemperature(), 1);

 delay(2000);
}
```

  [1]: https://i.stack.imgur.com/Hryuk.jpg
  [2]: https://i.stack.imgur.com/7UfKw.jpg

body:
In your question in the image below your grounds are not connected. The solution to your problem is to connect the ground (and only the ground, not the +5V) of your external power supply to the ground of the Arduino and the DHT11 will probably work again.

**A bit of background**

Sensors needs to be connected to the same ground as the Arduino. This is true in general with all parts of an electronic circuit. Ground functions as a fixed, common, reference voltage by which other signals (such as the digital data that's exchanged between the DHT11 sensor and the Arduino) are measured.

By connecting grounds, you make sure that a "high" that is output by the DHT11 is read as a "high" by Arduino and vice versa. When grounds are not connected, voltages between two parts of the circuit would "float" relative to each other and they would not be able to communicate. [This link](https://www.build-electronic-circuits.com/what-is-ground/) explains a bit more.


message:
Why wont my custom Arduino-Micro-based board receive power via USB?

UPDATE: I believe I have mostly solved the power issues, but now have USB connectivity issues described in EDIT 3 at the bottom.

I designed and printed a PCB for my MIDI controller project with a modified Arduino Micro microcontroller built in. I swapped out the USB Micro for a USB-C type port (just using the 2.0 protocol), but when I plug it in, after programming the bootloader to the ATMEGA32U4 via "Arduino as ISP" with an Uno as ISP to the ICSP of my board, my board seems to get no power from the USB bus (the power LED doesn't light up, nor is it recognized as a USB device), but it does get power over the ICSP and I got a success message after programming it with the Uno.

I have tried many USB cables, including USB-C ones I know to be 2.0 compatible and USB Micro cables (which have been tested with regular Arduino Micros) with micro-to-C adapters, but still get nothing. My PCB has full parity with my SCH file, and I tested it on multiple  of these boards that I got printed, so I am pretty sure I must have messed something up in the schematic or in component selection (not all the exact components from the official Arduino Micro schematic were available at JLCPCB where I had mine printed so I made some substitutions).

Can anyone help me figure out what the issue might be?

EDIT 1: So I found out that the power is coming in through the USB,  its reading 5V at the USB pins, 5V on either side of the fuse F1 and the VUSB pin of the T1 FDN340P/PMV48XP, but 0V at both the VIN and +5V pins of the same T1, so that seems to be the problem component? I'm using a PMV48XP in that position, not sure if I messed that up somehow? I'm a bit out of my depth here I think

I've uploaded the schematic and the component list below:
[![Edited Arduino Micro Schematic][1]][1]

Components:

    | Designator                                             | Value                   | Component                |
    |:--------------------------------------------------------|:-------------------------|:--------------------------|
    | C_ARD_1, C_ARD_2, C_ARD_6, C_ARD_9, C_ARD_10, C_ARD_11 | 100n                    | CL05B104KO5NNNC          |
    | C_ARD_3, C_ARD_14                                      | 22u                     | RVT22UF16V67RV0017       |
    | C_ARD_4, C_ARD_5, C_ARD_7                              | 1uF                     | CL05A105KA5NQNC          |
    | C_ARD_12, C_ARD_13                                     | 22pF                    | 0402CG220J500NT          |
    | D_ARD_2                                                | CD1206-S01575           | CDSU4148-HF              |
    | F1                                                     | MF-MSMF050-2 500mA      | MF-MSMF050-2             |
    | J3                                                     | USB_C_Receptacle_USB2.0 | KH-TYPE-C-16P            |
    | L1                                                     | green                   | 19-217/GHC-YR1S2/3T      |
    | L2                                                     | MH2029-300Y             | BLM21PG300SN1D           |
    | ON1                                                    | blue                    | 19-217/BHC-ZL1M2RY/3T    |
    | R_ARD_1, R_ARD_2, R_ARD_4, R_ARD_9                     | 10K                     | 0402WGF1002TCE           |
    | R_ARD_5, R_ARD_6, R_ARD_7, R_ARD_8                     | 1K                      | 0402WGF1001TCE           |
    | R_ARD_10, R_ARD_11                                     | 5.1k                    | 0402WGF5101TCE           |
    | RP3                                                    | 22R                     | 4D03WGJ0220T5E           |
    | RX1, TX1                                               | yellow                  | 19-213/Y2C-CQ2R2L/3T(CY) |
    | T1                                                     | FDN340P/PMV48XP         | PMV48XP                  |
    | T2                                                     | PMV48XP                 | PMV48XP                  |
    | U1                                                     | ATMEGA32U4-XUMU         | ATMEGA32U4-MU            |
    | U2                                                     | NCP1117-5               | NCP1117ST50T3G           |
    | U4                                                     | LP2985-33DBVR           | LP2985-33DBVR            |
    | Y3                                                     | 16MHz KX-7              | 3225-16.00-10-10-10/A    |
    | Z1, Z2                                                 | CG0603MLC-05E           | EZJZ0V500AA              |

EDIT 2: I think I found the problem. It looks like something got messed up when I was choosing the footprints of the MOSFET transistors T1 and T2. Here is a screenshot from the datasheet of the PMV48XP datasheet showing the pinning info:
[![PMV48XP Pinning Info][2]][2]
and now here is a screenshot of the relevant part of my PCB file:
[![enter image description here][3]][3]
So according to my schematic (again, based on the official Arduino Micro SCH, so I'm assuming its correct?) T1 Gate should be VIN, T1 Source should be +5V, T1 Drain should be VUSB. On my PCB T1 Gate is actually VUSB, T1 Source is +5V, T1 Drain is actually VIN. So it looks like the Gate and Drain pins got swapped between my SCH and my PCB. Same story for T2.
Can anyone with more knowledge confirm that the connections outlined in the schematic are correct? And whether that would explain the problems I've described?

EDIT 3: I have de-soldered T1 and T2, which were in indeed incorrectly wired. I have shorted the contacts between VUSB and +5V on the footprint of T1 and the board is getting power as it is supposed to.

Now I have a new issue which is that after I have programmed the board via ICSP (using the Arduino as ISP method, burning the Arduino Micro bootloader to it), when I plug the board into my computer (again, testing with a variety of cables and ports), my computer won't recognize it as a USB device. I'm not sure if this is a related problem to my previous one (and maybe I should make a new post if not?) or where I am going wrong now.

  [1]: https://i.stack.imgur.com/UjIkH.jpg
  [2]: https://i.stack.imgur.com/2AWTc.png
  [3]: https://i.stack.imgur.com/h1v9K.png

body:
I think you need to understand a little bit of how the T1 and T2 functions in order to troubleshoot. The purpose of T1 is when power is supplied via VBUS, and when Vin is not presented (i.e. at 0v), the VUSB is directly supplied as the 5V(bypassing the NCP1117 regulator). However, when you power via Vin and it is at least higher than 5V(likely at 7V), it will turn off the T1 and cut off the VUSB supply, and T2 is on, Vin is apply as the input to the NCP1117.

So with this in mind, if you connect your board via VBUS but can't get 5V, then you either has a malfunction T1 or you had connect T1 drain and source wrongly. However, if you supply your board via Vin, and don't get the 5V, there could be that your Vin is not high enough to turn on the T2, or your had wrong connection on T2.


message:
How do I go about pausing/stopping the timer1 task setup in this library, so I can use timer1 for something else in my code

So I want to use this library, that uses timer1 to fetch samples from analog input on pin A0.
It works great, and so after proper detection I'd like to perform all kinds of different tasks. But for those I need timer1 again and I think this library keeps it's timer1 routine continuously running. (Am I right?)

(EDIT: clarification) I think therefore a different library using timer1 won't work as expected. That's why after the first library's task is done, I'd like to free up timer1 for the second library.)

```
/*
  Original text created by Jacob Rosenthal:

  The Goertzel algorithm is long standing so see
  http://en.wikipedia.org/wiki/Goertzel_algorithm for a full description.
  It is often used in DTMF tone detection as an alternative to the Fast
  Fourier Transform because it is quick with low overheard because it
  is only searching for a single frequency rather than showing the
  occurrence of all frequencies.

  This work is entirely based on the Kevin Banks code found at
  http://www.embedded.com/design/configurable-systems/4024443/The-Goertzel-Algorithm
  so full credit to him for his generic implementation and breakdown. I've
  simply massaged it into an Arduino library. I recommend reading his article
  for a full description of whats going on behind the scenes.

  Created by Jacob Rosenthal, June 20, 2012.
  Released into the public domain.

  Modifications 6v6gt 09.09.2019
  1. Restructure instance variables to permit multiple instances of class.
  2. Make sample array static to share it between instances
  3. Pass in sample array as pointer so it can be reused outside class.
  4. Drive ADC by timer1 instead of polling ADC in loop()
      and reduce resolution to 8 bits.
  5. Separate coeeficient calculation from constructor because it
       now relies on data unknown at invocation (sample rate)
  5. Some consolidation of methods.
  6. Software "as is". No claims made about its suitability for any use.
       Use at your own risk. Special care required if you use other
       analog inputs or an AVR chip other than ATmega328P (Uno etc.).
*/

#include "Arduino.h"
#include "Goertzel.h"

// set by Goertzel::init()
uint8_t * Goertzel::testData;             // static declaration in .h
uint16_t Goertzel::N ;                    // ditto
uint16_t Goertzel::SAMPLING_FREQUENCY ;   // ditto

volatile bool Goertzel::testDataReady = false ; // static declaration in .h

//ADC interrupt service routine
ISR(ADC_vect) {
  // load sample buffer on sample conversion.
  static uint16_t sampleIndex = 0 ;
  if ( ! Goertzel::testDataReady   ) {
    if ( sampleIndex < Goertzel::N  ) {
      *(Goertzel::testData + sampleIndex++ )  = ADCH ; // 8 bits. Direct adressing into byte buffer
    }
    else  {
      Goertzel::testDataReady = true ;    // make buffer available to consumer
      sampleIndex = 0 ;
    }
  }
  TIFR1 = _BV(ICF1); // reset interrupt flag
}

// constructor
Goertzel::Goertzel(float TARGET_FREQUENCY  )
{
  _TARGET_FREQUENCY = TARGET_FREQUENCY; //should be integer of SAMPLING_RATE/N
}

//static method
void Goertzel::init( uint8_t *sampleArray , uint16_t sampleArraySize, uint16_t sampleFrequency ) {
  // set up sample array, number of samples and sample frequency.

  // load class static variables
  testData = sampleArray ;
  N = sampleArraySize ;
  SAMPLING_FREQUENCY = sampleFrequency ;

  // initialise ADC and Timer1. Timer1 triggers ADC at frequency SAMPLING_FREQUENCY.
  // ISR(ADC_vect) called when conversion complete.
  cli() ;

  // Setup Timer1 for chosen sampling frequency.
  TCCR1A = 0;
  TCCR1B = _BV(CS10)  |    // Bit 2:0 – CS12:0: Clock Select =  no prescaler
           _BV(WGM13) |    // WGM 12 = CTC ICR1 Immediate MAX
           _BV(WGM12);     // WGM 12 ditto
  ICR1 = ( (F_CPU ) / SAMPLING_FREQUENCY ) - 1;

  // Setup ADC for triggering by timer1; 8bit resolution; Analog Port PC0 (pin A0) ADMUX
  ADMUX =  _BV(REFS0) ;    // Fixed AVcc reference voltage for ATMega328P
  ADMUX |= _BV(ADLAR) ;    // left adjust conversion result in ADCH (8bit)
  DIDR0 |= _BV(ADC0D);     // DIDR0  Digital Input Disable Register 0
  ADCSRB = _BV(ADTS2) |    // Bit 2:0  ADTS[2:0]: ADC Auto Trigger Source
           _BV(ADTS1) |    // Timer/Counter1 Capture Event
           _BV(ADTS0);     // ditto

  ADCSRA = _BV(ADEN) |      // Bit 7   ADEN: ADC Enable
           _BV(ADSC) |      // Bit 6   ADSC: ADC Start Conversion
           _BV(ADATE) |     // Bit 5   ADATE: ADC Auto Trigger Enable
           _BV(ADIE) |      //
           _BV(ADPS0) |     // Bits 2:0  ADPS[2:0]: ADC Prescaler Select Bits  (div 8 )
           _BV(ADPS1);      // ditto
  sei() ;

}

// instance method
void Goertzel::getCoefficient( void ) {
  // previously in constructor. Now SAMPLING_FREQUENCY unknown at invocation time.
  float omega = (2.0 * PI * _TARGET_FREQUENCY) / SAMPLING_FREQUENCY;
  coeff = 2.0 * cos(omega);
}

// instance method
float Goertzel::detect()
{
  Q2 = 0;
  Q1 = 0;
  for ( uint16_t index = 0; index < N; index++)
  {
    // byte sample is ( *( testData + index ) );
    float Q0;
    Q0 = coeff * Q1 - Q2 + (float) ( *( testData + index ) - 128 ) ; //  128 for 8bit; 512 for 10bit resolution.
    Q2 = Q1;
    Q1 = Q0;
  }

  /* standard Goertzel processing. */
  float magnitude = sqrt(Q1 * Q1 + Q2 * Q2 - coeff * Q1 * Q2);
  return magnitude  ;
}
```
I'm new to using timers on Arduino, but I want to understand and learn more about it. So I'm reading up on it. Seeing that it's not the easiest subject to wrap my head around I'd like to ask for some directions.

On this splendid page I gathered some examples of stopping / disabling timer1.
```  TCCR1A = 0;    // stop timer 1
  TCCR1B = 0;
  TIMSK1 = 0;    // disable Timer1 Interrupt
```
[Nick Gammons Timer info page][1]

However I don't completely recognise the usage of the library's timer names, registers, variables yet. And so I'm unsure what part of the code is doing what exactly, ie where, how and when the timer starts. And therefore I'm equally unsure how to go about stopping it when the task is done, and to start it again when a new detection is needed. It seems there is TCCR1A, TCCR1B, cli() and sei() that have something to do with it and ISR(ADC_vect). One of you probably knows ;)

EDIT: Reading the suggested [ATmega328p datasheet][2] I found out a little bit more about the following abbreviations:
```
cli // disable interrupts during timed sequence __disable_interrupt();
sei // Set global Interrupt Enable __enable_interrupt();
TCNT1 // Timer/Counter (setting 0 will reset)
TIFR1 // Timer Interrupt Flag Register
TCCR1A // Timer/Counter Control Register 1a (setting 0 will reset)
TCCR1B // Timer/Counter Control Register 1b (setting 0 will reset)
TIMSK1 // Timer Interrupt Mask Register
ICR1 // Input Capture Register
ICF1 // Input Capture Flag
ICP1 // Input Capture Pin
WGM // Waveform Generation Mode
CS // Clock Select Bits (prescaler??)
F_CPU // The CPU speed (What is the default value? 8000000??? 1000000??? 16000000???)
DIDR1/DIDR0 // Digital Input Disable Registers (if left enabled they will use excessive power when Analog input is floating or close to VCC/2)
ADMUX // ADC Multiplexer Selection Register
REFS1 & REFS0 // Voltage Reference Selection
ADLAR // ADC Left Adjust Result
MUX
ADEN // ADC Enable
ADSC // ADC Start Conversion
ADATE // ADC Auto Trigger Enable
ADTS // ADC Trigger Source Select
ADCSRB //
ADIE // ADC Conversion Complete Interrupt Enable
ADPS0 & ADPS0 // ADC Prescaler Select Bits

```
But hasn't really lightened things up entirely for me. What is _BV? for example.

EDIT: I think I'm starting to make sense of it more. Am I right here(??):
```
ADMUX = (0b00 << REFS0) | (1 << ADLAR) | (0b00000 << MUX0);
Is the same as:
ADMUX = (0b00 << REFS0); // 0 shift has no effect so can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (0b00000 << MUX0); // 0 shift has no effect so can be omitted
Is de same as:
ADMUX = (1 << REFS0); // can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (1 << MUX0); // can be omitted
is the same as:
ADMUX = _BV(REFS0); // can be omitted
ADMUX |= _BV(ADLAR);
ADMUX |= _BV(MUX0); // can be omitted
Is the same as:
ADMUX = (1 << ADLAR);
Is the same as:
ADMUX = _BV(ADLAR);
```

Understanding it all would be great, but may be unnecessary.
If only I'd know how I can stop and free Timer1 usage for other purposes. Starting it all up again would be easier I guess ;)

  [1]: https://www.gammon.com.au/timers
  [2]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

body:
I'm not sure why you need to stop the timer in the first place. Timers are just things that count "ticks" which can be programmed to arrive at various speeds (usually some division of the processor speed).

Imagine you have a clock in your kitchen. And imagine you are baking a cake. You observe the time that you put the cake into the oven. Then you note at what time the cake will be done. Meanwhile that same clock can be used to time boiling an egg. You don't need to stop or "reset" the clock to achieve this.

Just let the clock run and do its thing, and meanwhile make a note of what time needs to arrive for things to be "done".

Meanwhile, the Uno (and Nano) have other timers. You can use those. It's like owning three clocks, that can run at different speeds — or perhaps more accurately — different levels of precision.


body:
I am answering here only a tiny part of the question:

> ```c++
> ADMUX = (0b00 << REFS0); // 0 shift has no effect so can be omitted
> ADMUX |= (1 << ADLAR);
> ADMUX |= (0b00000 << MUX0); // 0 shift has no effect so can be omitted
> ```
> Is de same as:
> ```c++
> ADMUX = (1 << REFS0); // can be omitted
> ADMUX |= (1 << ADLAR);
> ADMUX |= (1 << MUX0); // can be omitted
> ```

No, it is not the same.

Starting from the first line: `(0b00 << REFS0)` means “**zero**
left-shifted by REFS0 (i.e. six) bits”. It is not a zero shift, as
stated in the comment: it is a 6-bit shift. The resulting value is zero,
because the number being shifted is zero to start with, and because
vacated bits are zero-filled during a left-shift.

In contrast, `(1 << REFS0)` means “**one** left-shifted by REFS0 bits”.
The resulting value is:

2REFS0 = 26 = 0b01000000 = 64

In the first code snippet, ADMUX ends up with only the ADLAR bit being
set. In the second snippet, all three bits (REFS0, ADLAR and MUX0) are
set.

**Edit**: explaining the notion that “vacated bits are zero-filled
during a left-shift”. Let's assume x = 0bABCDEFGH is a byte, where A…H
are the individual bits (“0b” is a prefix meaning “what follows is in
binary”). Left-shifting this byte gives the following:

    x << 0 = 0bABCDEFGH
    x << 1 = 0bBCDEFGH0
    x << 2 = 0bCDEFGH00
    x << 3 = 0bDEFGH000
    ...

By “vacated bits are zero-filled” I mean that the bits that are beyond
the last original bit (beyond H) are replaced by zeros. Note that a zero
shift “has no effect” in the sense that `x<<0` is the same as `x`. Note
also that shifting the value zero by any amount always yields zero.

In this particular code, the value being written to ADMUX can be
computed as follows:

    1 << REFS0 = 1 << 6 = 0b00000001 << 6 = 0b01000000
    1 << ADLAR = 1 << 5 = 0b00000001 << 5 = 0b00100000
    1 << MUX0  = 1 << 0 = 0b00000001 << 0 = 0b00000001
    ──────────────────────────────────────────────────
    (1<<REFS0) | (1<<ADLAR) | (1<<MUX0)   = 0b01100001


body:
Time hasn't been on my side lately. But here is the code I've come up with so far. Needs testing still to see if it solves all my problems but in regards to my original question this seems to hold the answer I was looking for. Later on I might add some more info/links to register settings, hex/binary/ascii tables, bitwise operations and what they all do. But the manual is your friend pretty much.

Alright then. First of all this print function comes in handy:
```
// Handy while experimenting with all different bitwise operations and settings
void printRegSettings() {
  const String regNames[8] = {"TCCR1A", "TCCR1B", "ICR1", "ADMUX", "DIDR0", "ADCSRA", "ADCSRB", "TIFR1"}; //other: "TCNT1", "OCR1A", "OCR1B", "TIMSK1"
  uint8_t regVars[8] = {TCCR1A, TCCR1B, ICR1, ADMUX, DIDR0, ADCSRA, ADCSRB, TIFR1}; //other: TCNT1, OCR1A, OCR1B, TIMSK1

    for (uint8_t index = 0; index < sizeof(regVars)/sizeof(regVars[0]); index++) {
      Serial.print(regNames[index]+" = 0b");
      for (uint8_t i = 8; i > 0; i--) {
        Serial.print(bitRead(regVars[index], i-1));
      }
    Serial.write('\n');
    }
}
```
Next put all library register settings in function, notice the boolean in the end, for emptying the ISR (later described):
```
void dtmfTimerSetup () {

  TCCR1A = 0;
  TCCR1B = _BV(CS10) | // Bit 2:0 – CS12:0: Clock Select = no prescaler
           _BV(WGM13) | // WGM 12 = CTC ICR1 Immediate MAX
           _BV(WGM12); // WGM 12 ditto
  ICR1 = ( (F_CPU ) / 9600 ) - 1;

  ADMUX = _BV(REFS0) ; // Fixed AVcc reference voltage for ATMega328P
  ADMUX |= _BV(ADLAR) ; // left adjust conversion result in ADCH (8bit)
  DIDR0 |= _BV(ADC0D); // DIDR0 Digital Input Disable Register 0
  ADCSRB = _BV(ADTS2) | // Bit 2:0 ADTS[2:0]: ADC Auto Trigger Source
           _BV(ADTS1) | // Timer/Counter1 Capture Event
           _BV(ADTS0); // ditto
  ADCSRA = _BV(ADEN) | // Bit 7 ADEN: ADC Enable
           _BV(ADSC) | // Bit 6 ADSC: ADC Start Conversion
           _BV(ADATE) | // Bit 5 ADATE: ADC Auto Trigger Enable
           //_BV(ADIE) | //
           _BV(ADPS0) | // Bits 2:0 ADPS[2:0]: ADC Prescaler Select Bits (div 8 )
           _BV(ADPS1); // ditto

  Goertzel::dtmfListenerISR = true;
}
```
Next add a function to clear all these settings. Initial values of registers is 0 as far as I checked. So setting them zero does the job. Again notice the boolean false this time.
```
void clearTimerSettings() {
  //Empty Goertzel dtmf interrupt ISR routine
  Goertzel::dtmfListenerISR = false;

  //reset all altered registers to initial value 0
  Serial.println(F("***CLEARING ALL BIT SETTINGS***"));
  TCCR1A = TCCR1B = ICR1 = ADMUX = DIDR0 = ADCSRA = ADCSRB = TIFR1 = 0;

// pauze but don't erase current interrupt settings:
// bitClear(ADCSRA, ADIE); //risk interference when different timer adc library sets bit again
}
```
In Goertzel.h Add this static bool declaration to class Goertzel public:
```
static volatile bool Goertzel::dtmfListenerISR;
```
Add boolean declaration to Goertzel.cpp and add 'if statement' inside ISR(ADC_vect) to only execute interrupt if dtmfListenerISR is true.
```
volatile bool Goertzel::dtmfListenerISR;

//ADC interrupt service routine

ISR(ADC_vect) {
  //if dtmfListenerISR is false, this code is skipped, freeing timer1 for other purposes
  if (Goertzel::dtmfListenerISR) {

    // load sample buffer on sample conversion.
    static uint16_t sampleIndex = 0 ;
    if ( ! Goertzel::testDataReady  ) {
      if ( sampleIndex < Goertzel::N  ) {
        *(Goertzel::testData + sampleIndex++ )  = ADCH ; // 8 bits. Direct adressing into byte buffer
      }
      else  {
        Goertzel::testDataReady = true ;    // make buffer available to consumer
        sampleIndex = 0 ;
      }
    }
    TIFR1 = _BV(ICF1); // reset interrupt flag
  }
}
```
Finally use these functions like this in your sketch. The setup can be done in setup but the clearing should take place in your void loop of course, once the library and timer interrupt have finished their job and you want another library / timer routine to take over. Just for testing I put them all inside a setup and a simple sketch now.
```
void setup() {
  Serial.begin(115200);
  //setup/initialize timer interrupt routine:
  dtmfTimerSetup();
  //FOR TESTING: check and print current settings:
  printRegSettings();
  //clear timer interrupt routine;
  clearTimerSettings();
  printRegSettings(); //only for testing purposes

}

void loop() {
  // put your main code here, to run repeatedly:
}
```
Ofcourse for the other libraries using timer1 you should do the same: setup functions with register settings / cleanup and declare/set boolean for ISR part. There might be some overkill here, but so far I didn't find a more elegant way of achieving all this.


message:
Question about Buttons and INPUT_PULLUP

I am ok as a developer but have very little experience if it comes to electronics/hardware. I am always too cautious and have the fear that I could wreck something with the wrong wiring. This question may sound silly to you, but I couldn't find the answer anywhere. It's probably very easy to answer.

I'd like to integrate a Push Button into my Arduino Uno Setup. The only other connections are 3 wires leading to an WS2811b Strip, standard setup. From what I have found out online, I should basically connect Digital Pin 2 (or any other) to one side/connector of the Button and GND to the other side, no Resistor, and then set the Pin Mode to INPUT_PULLUP:

    pinMode(BUTTON_PIN, INPUT_PULLUP);

This makes sense. But all tutorials I'v seen use these small black Push Buttons looking like the Reset Switch. I needed something bigger, so I bought these:
https://de.aliexpress.com/item/4001095221773.html

Now the question: Should I connect these Buttons to my Arduino in the same way? Or could it be that there is some difference from one type of Push Button to the other that I have not thought about (that could probably ruin things)?

Thanks a lot!

body:
Yes, just connect them in the same way.

It doesn't matter what type of button you use. You could even use a wire and let it touch ground when you want a "press". That also would work correctly. The only requirement is, that the part has to make a direct connection between the digital input pin and ground when pressed and it has to release that connection when no longer pressed.


body: You can connect them with no external pull up resistors. If those switch wires are more than a few inches long or you are in an electrical noisy environment I would suggest an external pull up as well as the wires will act as an antenna. The internal pull ups are week so electrical noise can easily overpower them. The buttons you selected will probably oxidize over time and fail as the oxide is an insulator. To prevent that use pull up resistors that will force at least 1mA through the contacts (old school). We use to be sure we had some current through the switch when it was not a dry contact switch (those were expensive). Rule of thumb was at least 1mA more was good. This also helped reduce noise in the switch lines. Long term this is much more effective then sealing the switch.