body:
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

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

Answers: 1

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


body:
I needed SPI with CPOL=1 and CPHA=1. I read, that I could achieve this via SPI_MODE3. Further, I read to put the CS low and CS high code after SPI.beginTransaction(...) and before SPI.endTransaction() (See [official doc][1]). But the result does not look right.
Minimal example program:

    void setup() {   // put your setup code here, to run once:
        pinMode(52, OUTPUT); // CS high
        digitalWrite(52, 1);
    }

    void spi_transfer() {
        uint8_t buffer[] = {0, 0};

        delayMicroseconds(1);
        SPI.begin();
        SPI.beginTransaction(SPISettings(SPI_BAUD, MSBFIRST, SPI_MODE3));
        delayMicroseconds(1);

        digitalWrite(52, 0); // CS Low
        delayMicroseconds(1);

        SPI.transfer(buffer, 2); // Data
        delayMicroseconds(1);

        digitalWrite(52, 1); // CS High
        delayMicroseconds(1);

        SPI.endTransaction();
        SPI.end();
        delayMicroseconds(1);
    }

    void loop()
    {
      spi_transfer();
    }

[![Oscilloscope picture of SPI traffic][2]][2]

In yellow we see the CS signal (I use pin D52). In lila we see the clock signal.
To my understanding, this is not CPOL=1, as the Clock signal is low when the chip select goes low.
To my understanding, this is CPOL=0.

Is there a proper way to handle this? Setting CS outside of the begin/end Transfer would make the whole concept a bit superfluous.

  [1]: https://docs.arduino.cc/learn/communication/spi
  [2]: https://i.stack.imgur.com/udC64.jpg

title: How to properly set CS for SPI applications on Arduino Due

Answers: 0


body:
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.**

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

Answers: 1

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.


body:
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?

title: Upload to board with no USB connection

Answers: 2

body:
Use a [programmer][1], such as one based on CH341A that has pins broken out for CLK, CS, MOSI, MIOS [sic], GND, 3.3V, and connected those to pins on the Pro Micro as follows:

<pre>
Programmer    Pro Micro
CLK-----------15 (SCK)
CS------------RST
MOSI----------16 (MOSI)
MIOS----------14 (MISO)
GND-----------GND
3.3V----------RAW
</pre>

It doesn't appear that the programmer is supported in the Arduino IDE, so I grabbed [chavrprog][2].

And ran the command `$ sudo ./chavrprog -d mega32u4 -a s ~/Arduino/test/test.ino.leonardo.hex`

  [1]: https:////https://www.ebay.com/itm/234476270925?hash=item3697dff54d:g:JnwAAOSwnk9iOKEh&amdata=enc:AQAHAAAAsHjuKzkVJX5dTKd7OsCy1E+XU0DUH8PTbbLcgwpYpg7ogH4xfkh2SislVKc9c3Ca82xT24r4+0ePnzPYlUb8/dL14nr3hMP6tFWlFDynpay76gLsKo+/F7A9gt9psDvOevdlsoS/2U+TVYwgPwmQILUQxYZvz4IUdbxkaEWBUFpVyYErcj8Sn5ZTn5zDmHa/awsbvOD13sw4E/9dcmn3npK3D2szluez84DYmx9uOmVj|tkp:BlBMULyf3Z7oYA
  [2]: https://github.com/Trel725/chavrprog

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


body:
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

title: Robot car not working

Answers: 2

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.


body:
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?)
    }

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

Answers: 1

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.


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

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

Answers: 1

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


body:
With ESP8266 there is a requirement to not block the CPU execution for longer than few ms and then yield to networking stack and internal functions that are executed after each iteration of `loop()`. If you block CPU for too long, network will misbehave. If you block it for longer than ~3 seconds SWDT resets the MCU.

Now with ESP32 you have 2 CPU cores and RTOS running in the background that has full multithreading support. Is the Arduino framework for ESP32 taking advantage of this? Is the whole "user program" running as separate task besides the network and system stack? Would blocking the CPU in main loop cause similar problems as ESP8266?

From `xPortGetCoreID()` we can see that both setup and loop run always from core 1, not core 0, so I assume that user program is by default pinned to core 1 and network stack runs on core 0? Can someone confirm that?

This is just hypothetical question, I am just curious about internal ESP32 architecture and Arduino implementation, not making anything specific.

title: ESP32: Is the networking stack running in separate thread? Can you safely block task executed from loop() for longer time? (>3s)

Answers: 0


body:
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!

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

Answers: 2

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


body: 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?

title: Simulate pin behaviour based on PulseView recording

Answers: 1

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.


body:
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

title: Removing spaces between characters in MD_Parola

Answers: 2

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


body:
What is the purpose of C2 on this schematic below?

How does it work when the microcontroller is being programmed?

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

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

title: How does C2 work on the ATMega328P?

Answers: 0


body:
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

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

Answers: 1

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.


body:
i do some project. There is DS18B20, 3 mosfet modules, 1 relay, display 1602, buzzer... I built it on bread board, everything worked.
Now i soldered it: arduino works, display works but DS18B20 doesn't return temperature.

I tried to solder thermometer over again - no result.
Then i glanced at my sketch and tried to remove some code in loop and setup. I understood that DS18B20 works only if in setup function no `pinMode(...)` for other modules. It's odd!

This is part of my code:
```
#include <EncButton.h>     // For buttons
#include <microDS18B20.h>  // For thermometer DS18b20
#include <EEPROM.h>        // For EEPROM memory to save settings
#include <ezBuzzer.h>      // For buzzer
#include "Screen.h"

/* --- PINS --- */
#define kettle_relay_pin 4     // Relay of kettle
#define mixer_pin 5            // Mixer pin
#define termometer_pin A2      // Termometer pin
#define hot_pump_pin A0        // Hot water
#define sugar_dispenser_pin A1 // Sugar dispenser
#define buzzer_pin 9           // Buzzer pin

#define l_button_pin 11      // Left button
#define r_button_pin 12      // Right button
#define potent_pin A3        // Potentiometer pin for set int values
/* --- PINS --- */

#define INIT_ADDR 1023  // EEPROM addres for init key
#define INIT_KEY 1      // EEPROM init key

/* --- Initialize objects --- */
// Connect thermometer DS18b20
MicroDS18B20<termometer_pin> ds;

ezBuzzer buzzer(buzzer_pin); // create ezBuzzer object that attach to a pin;

// Buttons
EncButton<EB_TICK, l_button_pin> l_button;
EncButton<EB_TICK, r_button_pin> r_button;

// LCD Display
#define _LCD_TYPE 1
#include <LCD_1602_RUS_ALL.h>
LCD_1602_RUS lcd(0x27, 16, 2);
Screen screen(&lcd); // Create screen object instance for convient work with lcd display
/* --- Initialize objects --- */

/* --- Initial values --- */
enum modes {
  // ...
};
modes currentMode = normalMode;

// Default settings
struct Settings{
   //...
} settings;

// Current values
int current_temp = 25; // Current temperature
// ...
/* --- Initial values --- */

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

    // Buttons and potentiometer
    r_button.setButtonLevel(HIGH);
    l_button.setButtonLevel(HIGH);
    pinMode(potent_pin, INPUT);

    // Kettle
    pinMode(kettle_relay_pin, OUTPUT);
    digitalWrite(kettle_relay_pin, LOW);

    // Pump
    pinMode(hot_pump_pin, OUTPUT);
    digitalWrite(hot_pump_pin, LOW);

    // Mixer
    pinMode(mixer_pin, OUTPUT);
    digitalWrite(mixer_pin, LOW);

    // Sugar dispenser motor
    pinMode(sugar_dispenser_pin, OUTPUT);
    digitalWrite(sugar_dispenser_pin, LOW);

    // Buzzer
    pinMode(buzzer_pin, OUTPUT);

    // Init EEPROM
    if (EEPROM.read(INIT_ADDR) != INIT_KEY) {
        // EEPROM haven't been initialized yet
        EEPROM.write(INIT_ADDR, INIT_KEY); // Write init key
        EEPROM.put(0, settings); // Set default data
    }

    // Read settings and apply it
    EEPROM.get(0, settings);
    tea_temp = settings.tea_temp_default;
    sugar_count = settings.sugar_count_default;
    settings.mixer_time = 15 * 1000;

    // Init display
    screen.init();
}

unsigned long screenUpdateTimer = 0;

void loop() {
  buzzer.loop();

  l_button.tick();
  r_button.tick();

  creen.render(); // Always render information on display

  Serial.println(ds.online()); // TRUE

  // For ds18b20 tests
  ds.requestTemp();
  delay(1000);
  if (ds.readTemp()) Serial.println(ds.getTemp());
  else Serial.println("error");

  menuControl();
}
```

What's problem?

If i comment all `pinMode and digitalWrite` code, `ds.readTemp` works, else it's error.

**UPDATE #1**
I figured out that if i use ports A0 and A1, i get message "error" for this sketch:
```
#include <microDS18B20.h>
MicroDS18B20<A2> sensor;
void setup() {
  Serial.begin(9600);
}
void loop() {
  sensor.requestTemp();

  delay(1000);

  if (sensor.readTemp()) Serial.println(sensor.getTemp());
  else Serial.println("error");
}
```

And more. I get this message "error" every time without any connected modules. After some connects and disconnects of mosfet module to pins A0, A1, D5, D6. No temperature at all!
[![enter image description here][1]][1]
[![enter image description here][2]][2]
[![enter image description here][3]][3]

**Update #2**
I think it's died.

My main sketch (it worked yesterday) now doesn't work at all. But then i try some reboots and it works but not properly...
So, if it works, i can see my menu on display but it's ierogliphs sometimes. also sometimes buttons stop to work...

Is aruino dead?
[![enter image description here][4]][4]

  [1]: https://i.stack.imgur.com/yzyQ7.jpg
  [2]: https://i.stack.imgur.com/ihUOK.jpg
  [3]: https://i.stack.imgur.com/fEuoG.jpg
  [4]: https://i.stack.imgur.com/q2UUk.png

title: DS18B20 doesn't work with pinMode for other devices

Answers: 0


body:
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!

title: Arduino keyboard Input language problem

Answers: 2

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


body:
I've been trying to solve this problem for a while now. Fedora 36 cannot recognise my arduino board. Well, not correctly at least.

Arduino IDE v2 picks it up as ttyS4, but platformio only has an empty list for "pio device list".

In addition, "dmesg -w" and any other variation of it doesn't see any new USB devices, even if they do work.

I've tried installing the independent drivers to no avail. I bought a new board to make sure it's not a fried board. I also checked quite a number of USB cables, but still be problem persists.

Finally, I made sure to only use a fresh install of Fedora 36 but still no luck.

Has anyone here had similar problems before and if so any advice on how to get this sorted out? I'm currently using a laptop.

title: Fedora 36 cannot find TTGO32 arduino board

Answers: 0


body:
I want to synchronize time with NTP server once in some time. I am using DOIT ESP32 DEVKIT V1, I tried with getLocalTime() function but it returned ```true``` even without wifi, but as I know without wifi it can not conect to NTP server. Can anyone say if it is possible how to correctly synchronize time with NTP server? Maybe with some other libraries or with other functions.

```c++
    #include <WiFi.h>
    #include "time.h"

    const int  gmtOffset_sec = 7200;
    const int  daylightOffset_sec = 3600;
    const char* ntpServer = "pool.ntp.org";

    void setup() {
        Serial.begin(115200);
        Serial.println("Board started\n");
        WiFi.begin("<ssid>", "<password>");
        struct tm timeinfo;

        Serial.print("Connecting...");
        while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
        }
        Serial.println("");
        Serial.println("WiFi connected.");
        configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
        if (!getLocalTime(&timeinfo)) {
            Serial.println("Failed to obtain time 1");
        } else {
            Serial.println("Time obtained 1");
        }
        WiFi.disconnect(true);
        WiFi.mode(WIFI_OFF);
        if (!getLocalTime(&timeinfo)) {
            Serial.println("Failed to obtain time 2");
        } else {
            Serial.println("Time obtained 2");
        }
    }

    void loop() {
    }
```

The output to console is:

    Board started
    Connecting....
    WiFi connected.
    Time obtained 1
    Time obtained 2
But I would expect 2nd output to be ```Failed to obtain time 2```.

title: How to correctly synchronize time with NTP server?

Answers: 0


body:
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

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

Answers: 2

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.


body:
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);
}

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

Answers: 1

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


body:
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

    }
```

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

Answers: 1

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


body:
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

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

Answers: 1

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.


body:
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

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

Answers: 1

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.