# Question
Title: Why does controlling power with a transistor interfere with MHZ19B's serial communication?
I've been trying to turn off an MHZ19B (datasheet and teardown photos: revspace.nl/MH-Z19B). I've used an Arduino, NPN, PNP transistors and mosfets as well as the diagram below for connecting the sensor to an ESP32. In all cases, PWM communication works great! I can power off the sensor, turn it back on, and values derived from PWM communication are as expected. However when I connect the Rx and Tx lines (to software serial Tx and Rx pins respectively on Uno pins A0 A1 or ESP32 pins 32 33) they spit out gibberish and the PWM signal also suffers hiccups.

Otherwise, without any kind of logic power control, the MHZ19B works great and can communicate with anything via UART, even my PC usb port via FTDI.

I added resistors to the Rx and Tx lines so the voltage on them doesn't exceed Vcc. I tried 1n4007 diodes (they're the only ones I have; no Schottky diodes either). I tried an NPN equivalent optocoupler. I also tried powering the sensor from my breadboard. I don't own an oscilloscope :(

My High School teacher said to just use PWM, but as I searched for a solution to this error, I noticed hundreds of others have this exact same problem with all sorts of different sensors and loads with ICs; no one has come up with a general solution.

I've been obsessing with this for weeks and if anyone can help or can recommend a book about sensor schematics I would really appreciate it. Thanks!

# Answer
> 1 votes
Just guessing but I suggest you use a level translator. Also when you power off the sensor the serial output should go to ground disabling that channel. Check your voltages and put a bypass cap on the transistor for the sensor. You can use a simple P channel Logic Level fet,only a 50 ohm resistor in the gate to prevent oscillation. Your output will now be active low instead of active high. If you stay with transistors make R2 & R3 510 ohm so you have enough drive for the transistor and be sure it is NOT a darlington device, if it is you will not have enough voltage for the sensor.

# Answer
> 1 votes
When troubleshooting a problem like this, try 'cutting the world in half' before doing anything else. In this case, replace the entire circuit with a manual switch (or a wire) and manually power and de-power the sensor. If you still have the problem, then the circuit is irrelevant to the solution. If the problem goes away, then the circuit IS the problem.

Once this experiment has been performed, then 'cut the world in half' again, working on the 'half' that is the problem. Repeat until only one component is left.

---
Tags: softwareserial, esp32, uart, transistor, mosfet
---


title: Hand position sensor

text:
# Question
Title: Hand position sensor
What is the simplest way to get an alarm sound when a human raise hands up. Assuming he is wearing a sensor or whatever as a watch or ring.

# Answer
> 2 votes
A tilt sensor, can be used as what you are trying to say, whenever someone (who wore it) raise his hand or move it, will trigger an alarm.

If you want to carry your alarm with you then... You can use arduino nano or micro with a sensor and buzzer connected to it to just place it in gloves or watches etc.

---
Tags: sensors, prototype
---


# Question
Title: How do i improve this Code? (or how to pass a Char String into a Function to behave like a Variable)
Sorry i am a beginner and amateur when it comes to coding, can somebody help me to make the code inside the loop() less "monkey-like" by using a proper function?

I have tried a lot and at some point i am running out of ideas about how to even phrase the question on google.

My main problem when writing a function for this case is that i don't know how to pass a variable into a function which has to be written out as part of a Variable but also as part of Char Strings if that makes sense.

If you look at the code inside the loop() i actually only had to pass the number to the function, like "3" to change some Variables and Char Strings accordingly. I would be able to solve the issue with those Char Strings but i am completely clueless how to handle the Variable (rmd3, rmd4...).

"3" as in: Variable: rmd3, Char String "rmd3 = 1", Variable Value: rotary\_mode = 3 and Char String: "rotary\_mode = 3"

This is a simplified version of my code but boils down to where i am stuck at. It refers to a rotary selector i am using which has 6 Positions (rmd1 - rmd6). However if i knew how to solve this issue i could use it in many other situations as well.

Bounce rmd3 = Bounce(45,10);    //rotary selector on pos.3
Bounce rmd4 = Bounce(44,10);    //rotary selector on pos.4
int rotary_mode = 0;            //Rotary Mode

void setup() {
  Serial.begin(11520);
  pinMode(45, INPUT_PULLUP);   //pin of pos.3
  pinMode(44, INPUT_PULLUP);   //pin of pos.4
  }

void loop() {
             rmd3.update();
             if (rmd3.fallingEdge()) {
                Serial.print("rmd3 = 1");
                rotary_mode = 3;
                Serial.print("rotary_mode = 3");
             }
             if (rmd3.risingEdge()) {
                Serial.print("rmd3 = 0");
                rotary_mode = 0;
                Serial.print("rotary_mode = 0");
             }

             rmd4.update();
             if (rmd4.fallingEdge()) {
                Serial.print("rmd4 = 1");
                rotary_mode = 4;
                Serial.print("rotary_mode = 4");
             }
             if (rmd4.risingEdge()) {
                Serial.print("rmd4 = 0");
                rotary_mode = 0;
                Serial.print("rotary_mode = 0");
             }
}´´´

Pseudocode:

´´´void loop() {
int rmd_int;            //Mode numbers as int from 1 to 6
char rmd_char = [2];    //Mode numbers as char from "1" to "6"

              rmd3.update();
              rmd_int = 3;
              rmd_char = "3";
              void selected_mode(rmd_int, rmd_char);
}

void selected_mode(int rmd_int, char rmd_char ){
             if (rmd[rmd_int].fallingEdge()) {
                Serial.print("rmd[rmd_char] = 1");
                rotary_mode = [rmd_int];
                Serial.print("rotary_mode = [rmd_char]");
             }
             if (rmd[rmd_int].risingEdge()) {
                Serial.print("rmd[rmd_char] = 0");
                rotary_mode = 0;
                Serial.print("rotary_mode = 0");
             }
}```
</code></pre>

# Answer
> 3 votes
The question is somewhat confused, but I think I got what you mean. Your code suffers from too much repetition. You only showed the handling of two selectors, but you want to handle 6 of them. Repeating all the logic 6 times would make the code unwieldy and hard to maintain. So you want to put the logic in a function and just call that function six times.

> I actually only had to pass the number to the function, like "3" to change some Variables and Char Strings accordingly

You do not need to pass the number as a string: you can use `Serial.print()` to format the number instead. And you do not need to write a function either: you can just put a `for` loop inside the `loop()` function:

```
const int rmd_count = 6;

Bounce rmd[rmd_count] = {
    Bounce(48, 10),  // rotary selector on pos. 0
    Bounce(47, 10),  // rotary selector on pos. 1
    Bounce(46, 10),  // rotary selector on pos. 2
    Bounce(45, 10),  // rotary selector on pos. 3
    Bounce(44, 10)   // rotary selector on pos. 4
    Bounce(43, 10)   // rotary selector on pos. 5
};

void loop() {
    for (int i = 0; i < rmd_count; i++) {
        rmd[i].update();
        if (rmd[i].fallingEdge()) {
            Serial.print("rmd[");
            Serial.print(i);
            Serial.println("] = 1");
            rotary_mode = i;
            Serial.print("rotary_mode = ");
            Serial.println(i);
        }
        if (rmd[i].risingEdge()) {
            Serial.print("rmd[");
            Serial.print(i);
            Serial.println("] = 0");
            rotary_mode = 0;
            Serial.println("rotary_mode = 0");
        }
    }
}

```

The key to using `for` loops is to structure your data in arrays, instead of collections of variables named with numbers. Thus, instead of `rmd3` you would use `rmd[3]`. Note that array indices start at zero.

Obviously, you could put the body of the `for` loop inside a function, but at this point that would not help much in simplifying the code.

---

**Edit**: As a clarification, and per Delta\_G's suggestion, I'll try to explain the difference between an array and a collection of variables. Each variable you define is mapped by the compiler (technically, the linker) to a memory area. You can think of the variable names as convenient names assigned to those memory locations. If you write:

```
Bounce rmd0(48, 10), rmd1(47, 10), rmd2(46, 10), ...;

```

You get:

```
      ┌───────┐        ┌───────┐        ┌───────┐
rmd0: |       |  rmd1: |       |  rmd2: |       |  ...
      └───────┘        └───────┘        └───────┘

```

In the picture above, the boxes are the memory areas. They are large enough to hold a `Bounce` object, i.e. their size is `sizeof(Bounce)`. Each one has a name. You have no control over where, within the memory, those variables are allocated: it's the linker's call.

In contrast, when you declare an array, you get a *single variable* which is mapped to a contiguous memory area large enough to hold the whole array:

```
Bounce rmd[6] = { ... };

```

Gives:

```
     ┌───────┬───────┬───────┬───────┬───────┬───────┐
rmd: |       |       |       |       |       |       |
     └───────┴───────┴───────┴───────┴───────┴───────┘

```

The individual cells do not have a name, and you instead use indices to access them. For instance, `rmd[0]` references the first cell. Please, note that in this example there is no variable named `rmd0`: if you try to use that identifier the compiler will complain it is not defined. Again, an array is not a “collection of variables”: it is a single variable.

The array cells do behave in some sense much like individual variables (they are called *lvalues*), as you can use `rmd[0]` in the same way you would have used `rmd0` in the previous code. The point of using an array is that the indices do not need to be literals: you can use a variable instead (`rmd[i]`, where `i` is a variable), which comes handy when you want to loop over all the cells.

> Edgar pointed out that I can write the variable `rmd3` by `int i = 3` and `rmd[i]`.

I hope it is now clear that this is not the case. There is no variable named `rmd3` unless you create it explicitly. Declaring an array named `rmd` *does not* create such a variable.

> \[Can I\] "form" a variable by "characters"?

Your question is not very clear, but my guess is you are talking about *computed variable names*. This is a programming technique where you access a variable by computing its name at run time. For example, you combine the strings "rmd" and "3" in order to build the name of the variable "rmd3". Then you use this computed name to access the variable that has this name.

Computed variable names are quite often supported by interpreted languages. For example, in PHP this is called *variable variables*:

```
$foobar = 42;           // the variable we want to access
$start = "foo";         // one piece of the name
$end = "bar";           // the other piece
$name = $start . $end;  // build the name from its pieces
print $name . "\n";     // prints the variable name: "foobar"
print $$name . "\n";    // prints the variable's value: "42"

```

Computed variable names are *not* supported by C++, which is the language you use to program an Arduino. And for a good reason: when the compiler translates your program to machine code, the names of the variables are lost, they do not make their way to the actual Arduino. And this is a good thing, as you would not want those names to consume memory on the microcontroller.

Note that the names are present in the .elf file, as they could be useful for debugging. If you were programming for a PC, you program could in principle look into the file and find those names. On Linux you would do that with the `dlopen()` and `dlsym()` functions, from the libdl library. The libdl technique is, however, very far from the capabilities of your typical Arduino, orders of magnitude more complex than a simple array, and perfectly useless for your use case.

---
Tags: programming, c++, string, variables, functions
---


# Question
Title: What is the best and most reliable way to detect if a book is pulled out of a book case?
What is the best and most reliable way to detect if a book is pulled out of a book case?

I have a book case which I want to mount sensors to so that I can detect when certain books are pulled out, I don't need to know how much, all I need is a boolean trigger if the book has been pulled out 2+ cm or so (works with lower too). I would preferably also want to know when they have been replaced but that is just a bonus.

The goal of the project is to move a servo which may or may not open a secret door when 3 books are pulled out in a certain order.

The sensors need to be able to work continuously 24/7 for years.

Here is a masterfully drawn picture to explain it even better.

So far I have been thinking of mechanical switches, Ultrasonic Sensor (HC-SR04), or possibly some sort of infrared light and sensor that can detect a change in intensity (where a lower intensity is book being pulled out).

The mechanical switch I could easily do, but I would prefer something that is less obvious, and less "clicky" when it's triggered. I don't want to give away that there is something special with a book if someone picks it up on accident.

Any ideas on how it can be done? Would love tips for specific components as I'm not native to the arduino world and have a hard time finding exactly what I'm looking for.

# Answer
> 3 votes
As Majenko stated in the comments, an easy and discrete way would be using IR proximity sensors behind each book. The IR light from them is invisible to the eye, they are easy to read with an Arduino and often the casing of the IR LED and IR sensor are black, so that you could easily hide them in a black backplate of your book case.

The IR sensor will output one pin state (HIGH or LOW depending on the sensor), when something (the book) is near it (on most sensor modules you can change to threshold to your liking), and the other, if nothing is near it (empty place in the book case)

Searching "ir proximity sensor" at amazon gives multiple good looking results for ready to use sensor boards.

---

Another - more hacky - way would be to build your own switches at the top of the book case. As a switch is nothing more than 2 electrical contacts with some mechanic suroundings, you could add a small piece of cardboard above each book, which falls down a bit, when the book is removed, but not enough, that it is easily spotted (a few millimeters should be enough). At the top of the case and on the cardboard piece you put some piece of tinfoil or aluminum tape. When the book is put in the box, the tinfoil pieces get pressed together by the book, thus make contact. Wire one piece to ground, the other to an Arduino pin.

I find the IR sensor solution better, but I wanted to include a solution, where you don't need to buy extra sensor modules.

# Answer
> 1 votes
If you want the book and shelf to look normal, then use tiny magnets in the books and either reed switches or hall magnetic sensors embedded in the bookshelf. You can even discriminate two books by minding the magnet's polarity.

# Answer
> 0 votes
I assume all these solutions need to know exactly what book is where (positioned).

A solution could be a long LED strip (or other light) above the books, and at the bottom a strip of photo resistors (LDR), placed at every 2 cm. Place this photo resistors far enough backwards to cover the end of the shortest book (unless you do never change the order of the books you can place them exactly at the width of the book minus a cm or so).

# Answer
> 0 votes
Why not use RFID tags and sensor. You can do an inventory any time you want. The RFID tags are inexpensive and the sensor is not that much and available for the Arduino. Nothing shows if you put the tag in the spine of the book.

---
Tags: sensors, ir
---


title: ESP8266 ASyncTCP class example

text:
# Question
Title: ESP8266 ASyncTCP class example
I am new to ESP programming on Arduino, as before I was developing on eLua. There were some memory problems in Lua, so I decided to move to Arduino.

After looking at some examples, I found a library called AsyncTCP and I was very glad because it provides callbacks for events just like Lua. But I was very disappointed when I found no example of an async TCP server. Instead there is an AsyncWeb Server but I don't want to use an HTTP server: I want a simple telnet server. Does someone have a working example?

# Answer
There are examples in the ESP8266 library

https://github.com/me-no-dev/ESPAsyncTCP/tree/master/examples
> 2 votes

# Answer
If there are no examples provided with the library then you will have to make do with the example you have :(

If you think about what a web server does it is really just a glorified Telnet server without proper security. When the web server comes up it creates a waiting socket on port 80, you want port ?? (too long ago). It sits there waiting for text messages from clients, which is what you want to do. Every time it receives a message it sends it to a handler.

I don't know how experienced a programmer you are, but you should be able to pick up enough from the webserver code to write your own telnet server. However with you being new to Arduino you may be much better doing it as a synchronous application to start with.

Another approach is to find a the source for a telnet server and see if you can port that to the ESP.
> 1 votes

---
Tags: esp8266, tcpip, callbacks
---


# Question
Title: Convert Hex to Decimal from signed 2's complement
I am reading data from a meter over dlms protocol and I am getting hex values from there. I want to convert that hex string to signed decimal value. For example - ff9d denotes a value of -99 \[reference\].

My hex to decimal code is:

```
unsigned int hexToDec(String hexString)
{
  unsigned int decValue = 0;
  int nextInt;

  for (int i = 0; i < hexString.length(); i++)
  {
    nextInt = int(hexString.charAt(i));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
  return decValue;
}

```

Can anyone please help me how to do it in Arduino IDE?

# Answer
> For example – ff9d denotes a value of -99

The function you wrote returns an *unsigned* integer which, being unsigned, cannot be negative. The simple fix is to declare it as

```
int hexToDec(String hexString)

```

That should be enough to get it working as expected. Note that the local variable `decValue` still has to be unsigned, otherwise you would get a signed overflow, which is *undefined behavoir* (i.e. “forbidden”) in C++. Returning an unsigned number from a function that is supposed to return a signed number is perfectly fine: you get an implicit conversion which is guaranteed to do the right thing.

Now, if I may provide some more feedback about this function:

* Use, if you can, plain C strings (`char *`) instead of `String` objects, as the latter are not very friendly to your Arduino's memory.
* Use fixed-length integers (`uint16_t` if your protocol dictates 16-bit integers) instead of the generic `int`, otherwise your code will fail if you move to a 32-bit platform, such as an ARM-powered Arduino.
* Use character literals (`'0'` instead of `48`) instead of hard-coding ASCII code points, as that makes the code more readable.
* Use a simple subtraction (`nextInt - '0'`) instead of the quite expensive `map()` function.

Here is my take at it. Note that it has a “classic C” accent you do not need to replicate. You may prefer using indices to crawl the string.

```
int16_t hex2int(const char *hex)
{
    uint16_t value;  // unsigned to avoid signed overflow
    for (value = 0; *hex; hex++) {
        value <<= 4;
        if (*hex >= '0' && *hex <= '9')
            value |= *hex - '0';
        else if (*hex >= 'A' && *hex <= 'F')
            value |= *hex - 'A' + 10;
        else if (*hex >= 'a' && *hex <= 'f')
            value |= *hex - 'a' + 10;
        else
            break;  // stop at first non-hex digit
    }
    return value;
}

```

Example usage:

```
Serial.println(hex2int("ff9d"));  // prints "-99"

```

---

**Edit**: As revealed by the comments, the whole question is an XY problem. You are asking help about your misguided *solution* rather than your actual *problem*. The data you have is not hex: it's binary. You have a 16-bit signed integer stored in a byte array, most significant byte first. You figured out you can convert that to an integer by converting it first to a string representation as hexadecimal, then converting that representation back to a binary number. Of course you can do that, but it's an overly complicated and expensive way of doing something trivial.

The canonical way to recover an integer from a byte array is by assembling the bytes together using bitwise logic and bit shifts. In this case:

```
int16_t reactive_power = (uint16_t) data[dataSize - 5] << 8
                       | data[dataSize - 4];

```
> 2 votes

# Answer
Which mode of DLMS you are you using?

> IEC 61107 or currently IEC 62056-21, was an international standard for a computer protocol to read utility meters. It is designed to operate over any media, including the Internet. A meter sends ASCII (in modes A..D) or HDLC (mode E) data to a nearby hand-held unit (HHU) using a serial port. IEC 62056

In your question you mentioned:

> hex string

which means a string of hex characters using ASCII (modes A to D).

However, in the comments you mentioned:

> `void ReactivePower(unsigned char data[], int dataSize)` `String reacP = String(data[dataSize - 5], HEX) + String(data[dataSize - 4], HEX);`

which means an array of bytes obtained from a stream of bytes using HDLC (mode E).

# ASCII (Modes A to D)

For ASCII (modes A to D), there is a simple transformation to get the digit value from the hex character.

```
              ASCII
 Hex   --------------------                            Digit
 char  Decimal  Hexadecimal    Op1    Low nibble  Op2  Base 10
-----  -------  -----------  -------  ----------  ---  -------
 '0'      48        30        & 0x0F       0              0
 '1'      49        31        & 0x0F       1              1
 '2'      50        32        & 0x0F       2              2
 '3'      51        33        & 0x0F       3              3
 '4'      52        34        & 0x0F       4              4
 '5'      53        35        & 0x0F       5              5
 '6'      54        36        & 0x0F       6              6
 '7'      55        37        & 0x0F       7              7
 '8'      56        38        & 0x0F       8              8
 '9'      57        39        & 0x0F       9              9
 'A'      65        41        & 0x0F       1       +9    10
 'B'      66        42        & 0x0F       2       +9    11
 'C'      67        43        & 0x0F       3       +9    12
 'D'      68        44        & 0x0F       4       +9    13
 'E'      69        45        & 0x0F       5       +9    14
 'F'      70        46        & 0x0F       6       +9    15
 'a'      97        61        & 0x0F       1       +9    10
 'b'      98        62        & 0x0F       2       +9    11
 'c'      99        63        & 0x0F       3       +9    12
 'd'     100        64        & 0x0F       4       +9    13
 'e'     101        65        & 0x0F       5       +9    14
 'f'     102        66        & 0x0F       6       +9    15

```
* For characters '0' to '9', simply `AND` with 0x0F.
* For characters 'A' to 'F' and 'a' to 'f', `AND` with 0x0F and `add` 9.

```
char ch = '1';
byte b = 0;
if (ch >= '0' && ch <= '9')
{
  b = ch & 0x0F;
}
else if ((ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
{
  b = (ch & 0x0F) + 9;
}

```

It's also important to know whether the transformation was successful, e.g. the first character could be bad (either a null terminator or non hex character), so this needs to be tested for during the transformation. Also, there are four nibbles in an `int16` so the transformation needs to quit when a maximum of four hex characters have been processed:

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

void loop()
{
  char string[] = "A";
  //char string[] = "Waffle";
  //char string[] = "ff9d";
  int16_t the_int = 0;
  int count = AsciiToInt16(string, the_int);

  Serial.print(string);
  Serial.print(",  ");
  if (count)
  {
    Serial.print("Ok,  ");
    Serial.print(count);
    Serial.print(",  ");
    Serial.println(the_int);
  }
  else
  {
    Serial.println("Bad");
  }
}

int AsciiToInt16(const char* ch, int16_t& value)
{
  int count = 0;
  byte nibble = 0;

  // Stop after 4th nibble or null terminator.
  for(int i = 0; i < 4 && ch[i] != 0; i++)
  {
    if (AsciiToNibble(ch[i], nibble))
    {
      value <<= 4;
      value |= nibble;
      count++;
    }
    else
    {
      break;  // Stop after non hex digit.
    }
  }
  return count;
}

bool AsciiToNibble(const char ch, byte& b)
{
  if (ch >= '0' && ch <= '9')
  {
    b = ch & 0x0F;
    return true;
  }
  else if ((ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
  {
    b = (ch & 0x0F) + 9;
    return true;
  }
  return false;
}

```

**Output**

```
A,  Ok,  1,  10
Waffle,  Bad
ff9d,  Ok,  4,  -99

```

# HDLC (Mode E)

For HDLC (mode E), simply do:

```
void ReactivePower(byte data[], int dataSize)
{
  uint16_t reacP = (data[dataSize - 5] << 8) | data[dataSize - 4];
  Serial.println(dataSize);
  Serial.println(reacP);
}
. . .
  byte data[] = { 1, 3, 5, 2, 4, 8 };
  ReactivePower(data, sizeof(data));

```

**Output**

```
6
773

```
> 1 votes

---
Tags: arduino-ide
---


title: Voltage divider and NodeMCU inputs

text:
# Question
Title: Voltage divider and NodeMCU inputs
Some sensors give as output a voltage between 0 and 5V. The analog inputs of the NodeMCU require voltages between 0 and 3.3V. I plan to make a voltage divider with two resistors like in this link for compatibility.

To provide the desired voltage the quotient of the values of the resistances is fixed (approx. 1/2 for this case). However, the absolute values of the resistances are not.

**Q:** How to choose those absolute values? Which are the criteria and why?

I have a good background in electromagnetism but I know very few about electronic Engineering.

I think that low values must work, e.g. 1Ω and 2Ω (and surely greater values). But I am unsure of VERY high resistance values because I suspect that there should be some current intensity requirements.

Thank you.

# Answer
> 6 votes
As @Majenko commented, the A0 input has a fixed voltage divider (see NodeMCU Schematics) that connects the A0 input to a 220kOhm resistor, then to the ADC pin of the ESP8266, then to ground via a 100kOhm resistor.

This effectively fixes the resistor values that can be used to scale the input of the NodeMCU. For a 0-5.0V input range (with sufficiently low impedance) you need to scale the ADC pin from 0-1.0V by adding a ~180kOhm resistor between the 5V output and the A0 input of the NodeMCU, creating a 400kOhm-\> ADC -\> 100kOhm divider like this:

simulate this circuit – Schematic created using CircuitLab

# Answer
> 1 votes
The low end of the values is limited by how much current your sensor can provide. If you use 1Ω and 2Ω resistors in series then your sensor will need to provide 1.67A to create 5V across the divider. I doubt that your sensor can do that. For most sensors, you would want to use resistors in the kilohm or tens of kilohm range.

The high end is limited by the input impedance of the analog input pin. If your resistor values are large compared to this input impedance then the input impedance of the analog pin will affect how the voltage divider works. If the analog input is multiplexed and the ADC has a sample-and-hold at the input, then very large resistances in the divider will not allow the sampling capacitor to charge fast enough. For most ADC inputs, you would want to use resistors in the tens or hundreds of kilohms.

# Answer
> 1 votes
To better understand voltage divider, one can look at this online calculator https://ohmslawcalculator.com/voltage-divider-calculator to see the actual formula and try the calculator to compute the unknown wanted.

It is not well publish the existing voltage divider on the NodeMCU, of course you need to browse the schematic to figure it out.

It goes the same with existing pullup resistor for some GPIO.

@Majenko your explanation is excellent!

---
Tags: sensors, nodemcu, voltage-divider
---


# Question
Title: Why must I reload ArduinoCreateAgent-1.1-windows-installer-chrome every time I restart my computer?
What am I missing that this is happening? Used to use a laptop (with Create Agent installed on hard drive) which never had this problem. Now using a Windows 10 desktop and the On-line Create Agent. Unless I reload the Arduino Create Agent, I always get the 'No Plug-In Connection' error message, please see screen capture.  Device manager recognizes the Arduino Uno and assigns COM3 to the USB connection, please see screen capture.

# Answer
> 1 votes
Thank you to all who have suggested corrective action for my posted communication problem. After trying all of the suggestions, I threw up my hands and deleted all evidence of Arduino Create Editor. Next I installed the Arduino Create Editor as a fresh/new install. Magically, all of my communication issues with the Arduino Uno have been corrected. Apparently, something in the communication code was corrupted during my first attempt install on my desktop PC.

---
Tags: arduino-uno
---


# Question
Title: Sketch is not being received by Arduino even though Arduino Editor acts like it is finished?
In my attached screen capture the Arduino Editor appears to be performing the upload, however it never finishes. Completes three steps, the last being the sketch up-load and then states that it is busy. Sorry that I can't submit a short video. Please suggest ideas to solve this issue. Maybe this is related to my first question?

# Answer
> 1 votes
Thank you to all who have suggested corrective action for my posted communication problem. After trying all of the suggestions, I threw up my hands and deleted all evidence of Arduino Create Editor. Next I installed the Arduino Create Editor as a fresh/new install. Magically, all of my communication issues with the Arduino Uno have been corrected. Apparently, something in the communication code was corrupted during my first attempt install on my desktop PC.

# Answer
> -1 votes
I would suggest you start with a simple blink example sketch and be sure it works. I believe it will. Your picture is almost impossible to read but i caught you have multiple libraries and several other problems. Look at the errors and resolve them one at a time. Until you do it will never load, that is the way it was designed. Be SURE there is only one file with the .ino extension unless it is also part of your sketch.

---
Tags: arduino-uno, uploading
---


title: BMP280 returns 0

text:
# Question
Title: BMP280 returns 0
I have connected a BMP280 temperature/pressure sensor to an Arduino Uno just like here:

and used the example code provided by the Adafruit BMP280 library. However, the values for temperature and pressure return 0.00 on the serial monitor. What might be the reason for this? I have set it up in I2C mode and deleted the lines responsible for the SPI connections.

```
    /***************************************************************************
  This is a library for the BMP280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BMEP280 Breakout
  ----> http://www.adafruit.com/products/2651

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

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

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

#define BMP_SCK 13 // deleted the following 4
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10

Adafruit_BMP280 bme; // I2C
// and the following 2 lines:
//Adafruit_BMP280 bme(BMP_CS); // hardware SPI
//Adafruit_BMP280 bme(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);

void setup() {
  Serial.begin(9600);
  Serial.println(F("BMP280 test"));

  if (!bme.begin()) {
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    while (1);
  }
}

void loop() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");
    Serial.print(bme.readPressure());
    Serial.println(" Pa");

    Serial.print("Approx altitude = ");
    Serial.print(bme.readAltitude(1013.25)); // this should be adjusted to your local forcase
    Serial.println(" m");

    Serial.println();
    delay(2000);
}

```

# Answer
> 1 votes
I2C has to have pull up resistors on the data lines, otherwise it just doesn't work.

Have a quick search for the correct value but off the top of my head is 4.7k ish.

You have to place a resistor from the SDA and SCK lines to the +5V and suddenly it will jump into life. (Hopefully)

# Answer
> 2 votes
Recently i bought a bmp280 which is not an adafruit one and connected it to esp32 and and tried to upload the code from the examples test but i got the error no valid bmp 280 found, i searched on google and found https://www.circuitschools.com/interfacing-bmp280-with-esp-32-on-i2c-with-errors-and-solutions/ i read on i2c addresses errors,then from there i copied the code for an i2c scanner and ran it to get the correct i2c address I checked on I2c address and replaced the i2c hex address in the BMP initiialization line.

then the sensor worked and gave me temp, pressure and approx altitude. Thanks

# Answer
> 1 votes
I had the same problem and I solved it by changing I2C address from 0x77 to 0x76, in Adafruit\_BMP280.h

# Answer
> 1 votes
well the reason for changing the I2C address from 0x77 to 0x76 is when you have your SD0 pulled down to ground.

If there is nothing attached to SD0 on the BMP280 the device address is 0x77 by default.

---
Tags: arduino-uno, sensors, temperature-sensor
---


title: AccelStepper help - it just won't move!

text:
# Question
Title: AccelStepper help - it just won't move!
I should begin by saying I am not a programmer, do not really know much about programming, and am programming an Arduino Uno for the first time. I am using a Nema 23 motor (23HS22-2804S) with a microstep driver (ST-M5045). Within the following code is the description of what I need the program to do:

```
#include <AccelStepper.h>

/* Using a stepper motor,
 rotate a vibrational model using gears interconnected by springs
 in such a way as to induce torsional vibration, which should be visible by comparing
 movement of juxtaposed rotating gears with markers painted on. */

AccelStepper stepper(AccelStepper::FULL4WIRE, 2, 6, 4, 8);

int Microstepping = 8; /* Microstepping factor, as set on the ST-M5045 control board.
                          Multiplies the number of steps per revolution on the stepper motor.
                          Reference controller manual for adjustments to this number. */
int Steps = 200; /* Number of steps on your stepper motor.*/
int SPS;
int Amp;
int Freq;
// int SC;
int n = 2;
int i;
int totalSteps = Microstepping * Steps;

/* It should be noted that the Microstepping and Steps factors are not necessary, and adjusting the microstepping factor
 *  on the fly will not break the code. However, be aware that changing the microstepping factor by more than one interval
 *  at a time can cause the motor to not keep up with the sudden changes, i.e. losing torque or vibrating/stuttering. */

void setup() {               // THIS RUNS ONCE //

  // read potentiometers; raw inputs from 0 to 1023 //
  SPS = analogRead(0)*0.733; // MAX RPM ~28, max speed ~750 steps per sec (speeds above 1000 steps per second are unreliable,
                             // according to AccelStepper documentation)//
  Amp = analogRead(1)/20;     // MAX AMP ~51//
  Freq = analogRead(2)/170;   // MAX FREQ ~6 Hz//

  stepper.setMaxSpeed(SPS);
  stepper.setAcceleration(SPS/1.5);

  int nextStop = totalSteps/Freq;

  stepper.moveTo(nextStop);
  stepper.run();
}

void loop() {
  int nextStop = totalSteps/Freq;

// reaches here, doesn't execute if loop.
   if(stepper.distanceToGo()== 0){
     SPS = analogRead(0)*0.733;
     Amp = analogRead(1)/20;
     Freq = analogRead(2)/170;
     i = SPS - Amp;
     if(i <=0)
       i = 1;
     stepper.setSpeed(i);
     stepper.moveTo(nextStop*n);
     stepper.run();
    }
    n++;
}

```

When I use Serial.println() to check where the program is working and where it isn't, I see that it completes the setup loop without ever moving, and in slightly different versions of the same code, it has entered the if() statement and executed it (also without moving.)

An earlier version of the program runs and executes all statements, but only moves a maximum of about 20 steps per second, without the fluctuations in speed I call for, and doesn't respond in real time to any input from the speed potentiometer that puts the speed above 20.

Ideally, the program would run the demo at full speed, and *freq* times per second, it would slow down just enough to be noticeable as a torsional vibration.

I have tried running the program with and without the run() lines, and I have tried using runToNewPosition() in attempts to get the program to stop and properly execute the movement.

I made the setup loop as close as possible to the setup loop in bounce.pde, the example program in the AccelStepper documentation which moves the stepper motor between two points repeatedly, accelerating and decelerating before changing directions. The reason I did this is because I know that the setup loop in bounce.pde *works*, and so I would feel more confident that my setup loop is not the root problem.

Any help you can offer me is appreciated! Thanks for your time.

# Answer
> 0 votes
Please read the documentation for the AccelStepper library.

> Poll the motor and step it if a step is due, implementing accelerations and decelerations to achieve the target position. **You must call this as frequently as possible**, but at least once per minimum step time interval, preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due, based on the current speed and the time since the last step.

source

You are only calling `run` once, after setting a new position.

Move `stepper.run();` out of the `if` statement, the the end of the `loop` function.

```
      ...
      stepper.moveTo(nextStop*n);
    }
    stepper.run();
    n++;
}

```

---
Tags: arduino-uno, stepper
---


# Question
Title: status whether the switch is connected to arduino or not?
I made a small circuit in which a push-button is connected to Arduino via a pulldown resistor. So, whenever it is pressed it connects to 5V otherwise pulled down to the ground. this is working fine but I wanted to know is there any way to detect whether the push-button is connected to the circuit or not? In case if push-button disconnects from the circuit, how to detect it?

# Answer
The simplest way, as @jsotola has said, is to put a resistor across the terminals of the SPST push-button and read the voltage using an ADC input of the MCU.

However, the resistor needs to be bonded to the push-button (or inside the push-button housing) to ensure that when, for example, a vandal rips the push-button out of your switchboard, the resistor is certain to go with it so that the MCU can tell the difference between HIGH, LOW, and MISSING as @EdgarBonet pointed out. You also need to consider the continuous current draw of the extra resistor for low power/battery devices. You could increase the resistor values, but that tends towards weak pullup/pulldown. If you increase the value of only the extra resistor, it shifts the output voltage closer to the rail voltage reducing the margin for error.

*Figure 1 – SPST Push-Button AWOL Detector.*

Perhaps a better, but more expensive way, is to use a SPDT push-button. This push-button requires no modification, but is more expensive than a SPDT push-button and requires an extra wire and resistor. This circuit draws less continuous current and has stronger pullup/pulldown.

*Figure 2 – SPDT Push-Button AWOL Detector.*
> 1 votes

---
Tags: arduino-uno, button, electronics, switch
---


# Question
Title: Can an Arduino access a network database?
This is a similar question to a previous question I have asked. Primarily I am looking to find out more about the capability of the Arduino. Here is the scenario. There is a PC that is connected to a database via local network or internet. Is it possible that by plugging an Arduino in the usb port of this PC the Arduino could read from this database by means of an SQL query? Given that the Arduino would have the correct credentials. I am not asking if the Arduino could Hack into the database. I am asking if it is capable of accessing the database at all. Also this must be done without installing any special program on the PC. If that isn't possible, what type of program is needed? I am not necessarily looking for a tutorial, but if you could point me in the right direction that's be great. Thank you.

# Answer
> 1 votes
The M0 has a "native" USB interface. Because of that it can be programmed to appear as any kind of device you can image - as long as you can find (or write) the code to do that.

You *could* (though I have never tried and don't know what code is readily available for this) program the USB interface to be a USB Ethernet device. Your computer would then see it as a new Ethernet interface.

It would then be trivial to "share" your internet connection in Windows with that new Ethernet interface (nothing to install, but settings on the computer need changing), and your Arduino would then be on the network the same as your computer (just as if you'd given it a WiFi interface or something like that). Then it can connect to the database itself (or to a website that communicates with the database if that is simpler) and do whatever it needs to do.

Step one, of course, will be to find a library that will give you that USB Ethernet interface...

A much simpler option, if you're willing to change your M0 for something else, is to use a chip with a built in WiFi interface, such as the ESP32. There's no need for your computer at all then.

---
Tags: data
---


# Question
Title: How to use ADC interrupt on STM32 blue pill
I'm currently using the STM32F1xx boards from http://dan.drown.org/stm32duino/package\_STM32duino\_index.json To program my blue pill but I can’t find how to write the interrupt for the ADC. I’ve set the registers to output an interrupt when it finishes but I can’t find how to write the code for the interrupt.

I’ve tried the ”ISR(ADC\_vect)” function which works for arduino, but the compiler is complaining that ”ISR” is not recognized. I’ve tried to look for the documentation for the STM32duino, but the little I could find didn’t even mention the ADC or any interrupt routines. I’ve searched though the STM32duino forum without any luck. If anyone knows how to solve this or where to find information about interrupt code for the STM32 boards I would be very happy :)

# Answer
As you already found, the function to override is `__irq_adc()` defined weakly here and bound to the interrupt vector table here.

If you've defined it and it's not working, it's probably because you got rid of the `attachInterrupt()` call entirely, which does more than just assign an interrupt handler; it also enables the interrupt for that ADC. So:

```
myADC.calibrate();
myADC.setSampleRate(ADC_SMPR_1_5);
adc_enable_irq(ADC1, ADC_EOC);
myADC.setPins(&pin, 1);

extern "C" void __irq_adc() {
// handle the interrupt
// make sure to check statuses and clear flags as shown in the default handler
}

```

Not sure if the `extern "C"` will be needed, probably will be, you'll have to check and find out.
> 1 votes

# Answer
I couldn't find the function being called directly, but there's a good example explaining how to attach interrupts to the ADC which works well: https://github.com/rogerclarkmelbourne/Arduino\_STM32/blob/master/STM32F1/libraries/STM32ADC/examples/SingleConversionInterrupt/SingleConversionInterrupt.ino

If anyone knows the actual function being called directly that would be great to add on here, but until then this example does what I need and will hopefully help others having the same problem.
> 1 votes

# Answer
first you need to enable the interrupt (I don't know if the stm32 wrapper for arduino does it or not):

```
NVIC_EnableIRQ(ADC1_IRQn);

```

then you have to write ISR as gerben said:

```
extern "C" void ADC1_IRQHandler()
{
    //clear ADC flag
}

```

`extern "C"` because \[as far as I know\] the arduino projects are C++.
> 0 votes

---
Tags: interrupt, adc, stm32
---


# Question
Title: How can i make my MLX90614ESF scan temperature after the MFRC522 scans the RFID tag?
```
//THIS IS THE RFID CODE

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

#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

//*****************************************************************************************//
void setup() {
  Serial.begin(9600);                                           // Initialize serial communications with the PC
  SPI.begin();                                                  // Init SPI bus
  mfrc522.PCD_Init();                                              // Init MFRC522 card
    //shows in serial that it is ready to read
}
//*****************************************************************************************//
void loop() {
  // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  //some variables we need
  byte block;
  byte len;
  MFRC522::StatusCode status;
  //-------------------------------------------

  // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

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

  byte buffer1[18];

  block = 4;
  len = 18;

  //------------------------------------------- GET FIRST NAME
  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid)); //line 834 of MFRC522.cpp file
  if (status != MFRC522::STATUS_OK) {
    return;
  }

  status = mfrc522.MIFARE_Read(block, buffer1, &len);
  if (status != MFRC522::STATUS_OK) {
    return;
  }

  //PRINT FIRST NAME
  for (uint8_t i = 0; i < 16; i++)
  {
    if (buffer1[i] != 32)
    {
      Serial.write(buffer1[i]);
    }
  }
  Serial.print(" ");

  //---------------------------------------- GET LAST NAME

  byte buffer2[18];
  block = 1;

  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834
  if (status != MFRC522::STATUS_OK) {
    return;
  }

  status = mfrc522.MIFARE_Read(block, buffer2, &len);
  if (status != MFRC522::STATUS_OK) {
    return;
  }

  //PRINT LAST NAME
  for (uint8_t i = 0; i < 16; i++) {
    Serial.write(buffer2[i] );
  }

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

  delay(1000); //change value if you want to read cards faster

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}
//*****************************************************************************************//

// AND THIS IS THE MLX90614 CODE
#include <Wire.h>
#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

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

  mlx.begin();
}

void loop() {

  Serial.print("*\Body Temperature = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");

  Serial.println();
  delay(500);
}

```

# Answer
It appears that you have simply concatenated the code from the RFID tag Sketch and the code from Temperature Sketch together. This will not work as both programs contain identically named functions. Specifically "setup()" and "loop()". What you need to do is integrate the code for each "setup()" function into one "setup()" function. Similarly, you need to do the same with the "loop()" functions.

Assuming you only want to scan the temperature after you have successfully recovered data from the RFID tag, place the Temperature Sketch loop code immediately before the delay in the RFID tag code.
> 0 votes

---
Tags: arduino-uno, rfid, temperature-sensor, infrared
---


# Question
Title: can i use bluetooth from a speaker as a bluetooth module?
**i have a Bluetooth speakers that i don't want,and i was wondering if i can use its Bluetooth as a Bluetooth module to use it with Arduino. if so how what pins should i use. here is a pin diagram for the module.**

# Answer
Bluetooth actually uses many different protocols to support many different Bluetooth applications. For 2 channel good fidelity music with high latency and a very low bandwidth return only suitable for short infrequent commands like PAUSE and PLAY, most use A2DP or Advanced Audio Distribution Profile.

As most Arduino platforms use very low powered processors, good fidelity sound manipulation is not possible or is very difficult. This only leaves the very low bandwidth return channel only suitable for short infrequent commands. If you can imagine a use case for this channel it may be possible to use a low powered Arduino to send these PAUSE, PLAY, STOP type commands.

That said, you may want to buy a new well supported (in the Arduino community) Bluetooth module which uses the HID (Human Interface Device) protocol so you can build a keyboard for example or which uses the SPP (Serial Port Profile) protocol so you can build something that sends arbitrary data.

Added later...

I see in the diagram that there may be an "microphone in pin". If true this hints that the module also supports the Bluetooth HFP (Hands Free Profile) protocol. This is a lower fidelity 2 directional low latency audio channel with a very low bandwidth return only suitable for short infrequent commands like ANSWER and HANGUP. Instead of music this is used to make phone calls. This might be of more interest to Arduino project builders as this might be made into an intercom.
> 0 votes

---
Tags: bluetooth, speaker
---


# Question
Title: ESP8266 NodeMCU first WS2812 LED lights up green
I'm trying to power some WS2812 LEDs from my ESP8266 ESP-12E NodeMCU board (circuit here). I'm simply trying to use the NeoPixel Strandtest which works perfectly on my Arduino UNO with the same LED strip, but when I change the `#define pin 6` to `#define pin D4` (or `12` as GPIO) only the first LED lights up and it's green. I did throw in a 470 ohm resistor between data and DIN, but that didn't do anything different.

When I use one of the other pins, nothing seems to light up, even if I disconnect all pins and hit reset. Here is my wiring:

Don't mind the actual `3v -> 5v`. It works fine with 3v. I have also tried powering it off externally. I have tried all other pins from D0 to D7 (I saw many people say "STAY AWAY FROM PIN D8"). Could my ESP8266 be dead on arrival?

# Answer
> 5 votes
So here comes my solution: I was playing around with NeoPixelBus by Makuna and the examples. I noticed in one of his examples, it said:

> // You can also use one of these for Esp8266,
>
> // each having their own restrictions
>
> //
>
> // These two are the same as above as the DMA method is the default
>
> // NOTE: These will ignore the PIN and use GPI03 pin
>
> //NeoPixelBus\<NeoGrbFeature, NeoEsp8266Dma800KbpsMethod\> strip(PixelCount, PixelPin);

So I tried outcommenting that line and used that instead, and then it worked! I've always used `Neo800KbpsMethod` whenever I saw NeoPixelBus being used, because that was what other people did. Notice it also said:

> These will ignore the PIN and use GPI03 pin

That pin is the RX pin on my board. No other example I have seen, has used the RX pin on the board.

After 6+ hours of constant troubleshooting, I can finally power on my strip and control each LED!

# Answer
> 2 votes
Ok i got it working after banging my head for couple of days, i was using a Node MCU Board V3, the pin number on board were D1 D2 D3 D4 etc all other library when data was connected to D4 in code where we specify the pin number we use to write D4.

However for FASTLED codes tbe code you need to write is just 4 without the letter D and when i did the same it just worked like magic

# Answer
> 0 votes
Please read and understand the manual

You say it works on an Arduino, a big difference between the Uno and ESP8266 is the voltage (and voltage regulators).

Another difference is the chip/architecture itself.

So that leads to having to debug these two factors.

**Debug the power/circuit/voltage**

Please check if the 3V pin of your particular dev board can supply the current for the 3 LED's. Alternatively you can try by using another 5V power supply, or the 5V from your USB or (Arduino, since that did work) to try and power the LED's.

Another problem may be that the voltage will slowly go down over the length of the strip. Your strip is small, though you also power it from 3V, increasing the effect. You can try to power it on multiple points, or from the middle.

Try using a logic level shifter to increase the logic output pin from 3V to 5V, it may not be sufficient to transmit the data. This usually isn't a problem, but you should exclude this possibility.

The guide also shows some peculiar things regarding the wiring. They say you should use a capacitor between the + and - lines. I don't see how that can fail, but you may as well try.

Also doublecheck the wiring, maybe some connector is a little loose. I've also had problems with LED strips that have been bent, the copper may come loose from the strip, or the strip may get teared a little.

You should also check with another piece of LED strip, just to be sure.

**Debug the controller**

It works on the Arduino, but not the ESP8266, and we have checked that it's not due to the voltages/power.

The NeoPixels have pretty strict timing, I would actually advise anyone to NOT use them. Since you can't write to the strip "pixel by pixel", you'll have to put the whole strip in memory, and then send it all at once.

Other SPI based LED strips can receive the pixels one by one, like streaming. So you can simply make a loop that sets a color and sends it (while slowly increasing color, to make an virtually infinite rainbow effect). The cool thing is that it even doesn't block interrupts from happening. (Neopixels disable interrupts, need 3 bytes per pixel, and can't do calculations between sending)

If you still want to use NeoPixels, there may be a timing issue. You can check at which clock speed you've set the ESP8266.

Also are you using ESP show with the right "is800KHz" option? `espShow(pin, pixels, numBytes, is800KHz);`

You may also try another ESP8266 from another manufacturer, to be sure that it's not the board. They may have used a crystal that isn't as accurate as it should be.

# Answer
> 0 votes
Ok, I am using WS2812B with nodemcu and Fastled. Now all folks out there reading this need not worry about voltages if your led is not blinking at all. It was not working at D0, it worked for me when I changed to D1, I am not aware of issue though. Need to check that. I did not use any other component and connected directly to nodemcu. Below is the simple code for first led to blink.

```
#define FASTLED_ESP8266_RAW_PIN_ORDER
#include <FastLED.h>
// How many leds in your strip?
#define NUM_LEDS 3

// For led chips like WS2812, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
// Clock pin only needed for SPI based chipsets when not using hardware SPI
#define DATA_PIN D1
#define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];

void setup() {
    Serial.begin(9600);
    // Uncomment/edit one of the following lines for your leds arrangement.
    // ## Clockless types ##
    FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
    Serial.println("Setup");
}

void loop() {
  // Turn the LED on, then pause
  leds[0] = CRGB::Red;
  FastLED.show();
  //digitalWrite(DATA_PIN, HIGH);
  delay(500);
  // Now turn the LED off, then pause
  leds[0] = CRGB::Black;
  FastLED.show();
  delay(500);
}

```

---
Tags: nodemcu
---


# Question
Title: Arduino Pro Mini is burned by 12v. Can I save it?
I have this Arduino Pro Mini clone (ATmega328) 5v.

I gave it exactly 12 volts through the RAW power input, but it instantly got hot and started fuming. Fumes were coming out of the area close to the black S4 thingy. I don't know why, because I thought it can accept up to 12v through that input.

Now when I give it 5v only the middle led is lighting up and it's not connecting to the USB-UART interface anymore.

Is there any chance to save it?

# Answer
## 1. Your microcontroller is probably/maybe fine; your tiny little voltage regulator is dead; here's why:

Sergio, yes, you can probably/perhaps save it: your Arduino (the microcontroller--ie: processor at least) is likely just fine, assuming the linear regulator smoked and failed *open*, meaning it did NOT pass through the raw input voltage to your ATmega328 mcu. It's the linear voltage regulator that is fried! That's this circled component below:

So, desolder that part and throw it away and you can continue using the Arduino just fine. Just power it with a **regulated** 5V directly to VCC is all and you'll be fine. I've done exactly this on some parts I exploded or smoked the regulator on (see below), and they continued working just fine.

*IMPORTANT: if this is a safety-critical part, or a product, throw away the whole Arduino just in case.*

### Details on the fixes:

1. Desolder the voltage regular (circled in the image above, and shown desoldered on my Pro Mini in the photo below) and throw the desoldered voltage regulator away.
2. Power the board now through Vcc with anything between 3.3V and 5V (recommended: a regulated 5V into Vcc, such as the 5V line coming straight out of your USB hub).
3. Reflash the bootloader with a USBasp programmer (shown in 2nd of the two photos below).
4. Upload a new blink sketch via the external USB serial UART to blink the built-in LED13. This works fine on my Pro Mini below shown with exploded and desoldered regulator:

```
// 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(500);                       // wait for a half-second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(500);                       // wait for a half-second
}

```
5. Unplug the USBasp programmer when done, and continue development with just the external serial UART plugged in.

Here's some photos of my Arduino Pro Mini with exploded voltage regulator that I desoldered. I found it today. The Arduino still works fine! I desoldered the regulator around the year 2014 or so, but just re-flashed the bootloader, uploaded the code, tested it, and took these photos today:

**Image 1:** Arduino Pro Mini used as a data-logging altimeter in ~2014; photo from today. The voltage regulator exploded (read below), so I desoldered it. Both the power LED (top center of board), and LED13 (bottom-left of board) are ON. *The power LED comes on automatically so long as you are powering the board through Vcc and GND from your USB port through your USB UART adapter, and the LED13 is blinking ON here due to the blink sketch above AND by powering the board with Vcc and GND from the USB serial UART to the Pro Mini. Note that the LED13 would NOT light up properly with just the USBasp plugged in, even when it was properly powered and programmed by the USBasp. I think it's because the USBasp was interfering with that pin. Plugging in the external serial UART to the Pro Mini's Vcc and GND fixed that, allowing LED13 to function properly as well while the Pro Mini ran the blink sketch above.*

**Image 2:** External USB serial UART (in the USB hub top port), USBasp programmer wired to program the bootloader (in the USB hub under the USB UART), Pro Mini (bottom left) with power LED ON and LED13 (bottom-left of board) OFF.

---

On the surface, you didn't do anything wrong! You plugged 12V into the correct pin (`RAW`, which is the battery-in or voltage in line), and that is within the voltage limits of this part. BUT, what you neglected to consider is the *power dissipation capability* of this footprint or size of a part. The power dissipation capability is soooo low that realistically, 12V is too much, and will destroy the part.

6 years ago or so I made a couple little data-logging altimeters with the Arduino Pro Mini, connected 12.6V (a fully-charged 3S LiPo battery) to the RAW pin, and 15 seconds later: pop! They **exploded**! Literally, that little voltage regulator *exploded* into bits with 12.6V in. After that, I never put more than 8.4V in (a fully-charged 2S Lipo battery), and all was well. Since I was powering it from my main RC plane's 3S LiPo motor battery, this was accomplished by just tapping off of 2 of the 3 cells in the battery by plugging into the correct points on the battery's balance lead. So, I was able to use the same battery but just use 2 of its 3 cells instead of all 3 of them.

These regulators are just so tiny that they can't take much heat is all, and since they are *linear* regulators, all excess voltage is burned off as heat. Here's a couple example power dissipation calculations to make the point:

Imagine you are drawing 100mA total (0.1A) from this regulator. With 12V plugged in, you have to burn off `12V - 5V = 7V` in that regulator chip.

```
Power_dissipated = Current*Voltage = I*V = 0.1A * 7V = 700mW

```

700mW is HUGE! Pop! Explosion! Dead voltage regulator chip.

But, if you feed it just 8V this same chip would have to burn off only `8V - 5V = 3V` of excess voltage:

```
Power_dissipated = Current*Voltage = I*V = 0.1A * 3V = 300mW

```

That's `300mW/700mW = 43%` as much power, or `57%` less power. These numbers are just for example purposes, but you get the point.

Solution? 1) switch to Arduino Nanos, and/or 2) use a much lower input voltage (ex: 8~9V instead of 12V!). Nanos have MUCH bigger and beefier voltage regulators, and Nanos cost like $1 more when buying the Chinese clones.

## 2. How to calculate 1) how much power your regulator can dissipate without burning up, and 2) how much current you can therefore draw for different raw input voltages to the voltage regulator:

(Also: I wrote an article on my website covering more of these power, current, and voltage specs--see link here and at bottom.)

By the way, looking at the Pro Mini schematic here, I see that the original board used a MIC5205 linear regulator. The Chinese clone you have certainly uses a different regulator, but let's look up the MIC5205 datasheet for benchmarking purposes. A google search for "mic5205 datasheet" leads me here: https://ww1.microchip.com/downloads/en/DeviceDoc/20005785A.pdf. The device is rated up to **150mA current** and **up to +16V input voltage**, but you *must* consider power!

The equation for that is hidden on pg 5 here:

```
Power_dissiplation_max =  P_D_max = (T_J_max – T_A)/theta_JA

theta_JA = thermal resistance from Junction to Ambient = 220 degC/W

T_A = ambient temperature = let's say, 40 deg C (104 deg F)

T_J_max = max junction (internal chip) temperature = +125 degC

```

So, we crunch the numbers:

```
P_D_max = (125C - 40C)/220 C/W = 85C / 220 C/W = 0.386W = 386mW max
power.

```

Final result: this tiny, linear voltage regulator, assuming absolute max junction temperature of +125 C (257 F) \[HOT HOT HOT!--not good\] and ambient air temperature of 40C (104 F) can dissipate **386mW max power before you risk making it go "pop"!**

So, assuming you power it with 12V, how much current can you draw?

```
Voltage drop across the regulator = V_D = Vin - Vout = 12V - 5V = 7V

Power dissipation in the regulator = P_D = current * voltage drop = I*V_D

```

Solve for `I`:

```
I = P_D/V_D = 0.386W/7V = 0.055A = 55mA current!

```

**With *12Vin* and *5Vout*, any more than *55mA* current draw goes "pop" or smokes the chip!**

With 8Vin, however, you could draw:

```
V_D = 8V - 5V = 3V
I = P_D/V_D = 0.386W/3V = 0.129A = 129mA current

```

**With *8Vin* and *5Vout*, any more than *129mA* current draw goes "pop" or smokes the chip!**

So, use a lower input voltage and you can draw much more current! How low can you go? Don't go lower than 5V + dropout voltage. The datasheet on p3 for this regulator shows a max dropout voltage of ~350mV, so stay \> 5.35V input to get a regulated 5V output.

That's all for this MIC5205 chip, though. Note that other voltage regulators may have dropout voltages as high as 2~3V, so you'd have to have an input voltage of at least 7V or so to ensure a regulated 5V output. I can't see the numbers well enough on your chip to google for its actual Chinese or whatever datasheet to do the calculations for your chip, but you can use my example calculations above to redo these calculations for any datasheet or part.

## Other reading:

1. Google search for "sot 23-5 power dissipation"
    1. Microchip Application Note AN792: A Method to Determine How Much Power a SOT23 Can Dissipate in an Application
2. I also wrote an article on my personal website on 6 Jan. 2014 called "Arduino Power, Current, and Voltage Limitations", here, for more info. on these limitations.
> 12 votes

# Answer
Unfortunately, it sounds like it is dead.

I did this early on when I started with arduinos. In my case I plugged in a "12v 1amp" wall adapter from a linksys router that I didn't check with a DMM to a uno-R3 barrel jack.

The adapter was putting out 22v @ god only knows how many amps. But it had the exact same symptoms I am sorry to say.

I wound up going with a cheap 5v/3.3v selectable breadboard power supply. You might want to look into those for future use, I got mine for less than $3 on eBay.

https://www.ebay.com/itm/1pcs-Breadboard-Power-Supply-Module-Shield-3-3V-5V-MB102-Solderless-Bread-Board/133519600754?hash=item1f16636c72:g:9NcAAOSwZzNfYHel
> 1 votes

# Answer
Wall adapters are not all the same. They can have AC and DC outputs. The DC outputs can be regulated or unregulated. Assuming 1 12V DC wall adapter unregulated you can get maybe 19Vdc from it depending on the design.Always check first, it is much more cost effective then going to the store to buy a new Arduino and what other devices.
> 1 votes

---
Tags: arduino-pro-mini
---


title: Connect SDRAM to STM32

text:
# Question
Title: Connect SDRAM to STM32
Well, first of all hello to everything and thanks for reading my question. I am designing a board with STM32F730R8T6 MCU, and I want to connect MT48LC16M16A2P-6A to it which is 4MB SDRAM chip. The connections are pretty basic from what I saw, the thing is, how can I access that memory from my MCU? I mean there is a library or something to use it? and, if someone can send me an example schematic, to connect the memory I would appreciate it. Greetings.

# Answer
> 2 votes
As far as I know, you have to choose variant with FMC module (Flexible Memory Controller) with SDRAM support - that means you have to use 144pin version STM32F730**Z**8. The 100pin version does have FMC but doesn't support SDRAM.

After resolving this issue, it should be about configuring FMC module for using SDRAM (in STM32CubeMX for example) and the RAM will be available at some memory location according to the MCUs memory layout.

---
Tags: memory-usage, memory, sram, stm32
---


title: Understanding NRF24L01 specifications

text:
# Question
Title: Understanding NRF24L01 specifications
I was reading this tutorial about the NRF24L01 and came across a few terms which I did not clearly understand.

> It uses the 2.4 GHz band

1. Does this refer to the frequency of the EM waves that the device uses to communicate?

> If used in open space and with lower baud rate its range can reach up to 100 meters.

2. I know baud rate refers to how many "groups of bits" are transmitted per second. I don't quite understand why the range increases for a lower baud rate.

> The module can use 125 different channels which gives a possibility to have a network of 125 independently working modems in one place. Each channel can have up to 6 addresses, or each unit can communicate with up to 6 other units at the same time.

3. Here, does a channel mean a single frequency? How is the range of possible channels decided (why 125) and how is the smallest detectable resolution decided (smallest change in frequency which would cause a change in channel)? So does a single unit work on only one frequency or could the same unit communicate at different frequencies at the same time and so be a part of different networks simultaneously? In effect, I am not able to make sense of this paragraph!

# Answer
> > It uses the 2.4 GHz band
>
> Does this refer to the frequency of the EM waves that the device uses to communicate?

Yes. It generates (and receives) radio waves in the region of 2.5GHz.

> > If used in open space and with lower baud rate its range can reach up to 100 meters.
>
> I know baud rate refers to how many "groups of bits" are transmitted per second. I don't quite understand why the range increases for a lower baud rate.

Think of it like talking to someone. If you're stood right next to them you can speak nice and fast and they can understand you. Your speech comes across nice and clear.

However if you're the other side of a quarry you have to shout really loud, and if you talk too fast they can't understand you. You. Have. To. Shout. Slowly. so that they can understand you.

The environment makes a lot of difference to how your speech propagates. In large areas there's lots of echo and other things. It's similar with RF communications. There's more noise and things that can interrupt communication. By having lower baud rates you're giving the receiver more time to understand what it's receiving and make sense of the data.

> > The module can use 125 different channels which gives a possibility to have a network of 125 independently working modems in one place. Each channel can have up to 6 addresses, or each unit can communicate with up to 6 other units at the same time.
>
> Here, does a channel mean a single frequency? How is the range of possible channels decided (why 125) and how is the smallest detectable resolution decided (smallest change in frequency which would cause a change in channel)? So does a single unit work on only one frequency or could the same unit communicate at different frequencies at the same time and so be a part of different networks simultaneously? In effect, I am not able to make sense of this paragraph!

There's a number of different factors at play here. First there is the "Bandwidth" of the channel. This is the maximum amount of data that can be squeezed into a particular carrier frequency with a particular amount of "space" around the signal. You can think of the channel width as the diameter of a pipe. The wider the pipe the more water can be pushed through the pipe per second.

You want to slice the RF allocation up into enough channels to give enough concurrent access to lots of devices, but at the same time you want to have enough bandwidth per channel that you can transfer reasonable amounts of data.

It's all a balancing act.

Nordic decided 125 channels was the optimal balance for their application.

One nRF24L01+ can work at one frequency at a time. That's not to say you can't instruct it to change frequencies at any time, but it can only be listening on the one frequency at once. Just like a normal FM radio - you can only listen to one radio station at a time.

But the nRF24L01+ protocol uses addresses within that one chosen channel, so lots of devices can all be on the same channel to talk together, and each is distinct by its address.

The protocol also includes the concept of "pipes" which are virtual wireless circuits between two physical devices. Once you have configured a pipe with an address any other device can communicate with that pipe. You can configure up to 6 pipes, so up to 6 devices can send to the same target at the same time and each devices data is kept separate and distinct from the others. It's kind of like having 6 serial ports all connected to different devices at once.
> 4 votes

# Answer
1. Yes. They call it a band, because the nRF24L01 can operate on frequencies from 2.400GHz to 2.525GHz
2. It's like talking slower to someone. It makes it easier to distinguish the signal from the noise.
3. Kind of. Every channel is 1Mhz apart from the next (`2.4Ghz + (125 * 1Mhz) = 2.525GHz` which is the range specified above). This difference is chosen more of less arbitrarily. The 125 channels is because it has to stay inside the ISM band 2.4-2.5Ghz. Note that the different channels can still interfere with each other, unless they are far enough apart from each other. Just like with WiFi where you had 11 channels, but were advised to only use channels 1, 6, or 11. The NFR can only run at one frequency/channel at a time. You can however change channels while it's running. But its better to have all running on the same channel and use the NRFs pipes to create separate "networks". Or even use the same pipe, but have the packet contain the info on what kind of data it contains.
> 2 votes

---
Tags: nrf24l01+, wireless, network
---


title: Using TIMER0_COMPB_vect

text:
# Question
Title: Using TIMER0_COMPB_vect
I'm trying to understand how to fully use the COMPB vector ISR of Timer0 on the ATMega328 (standard Arduino core). I realize it will make delay() and millis() not work but that's ok by me. I've setup some test code that *should* output a 244Hz signal on D4 and 488Hz on D5 (note, this is running at 8MHz). But D5 (COMPB) is always what D4 (COMPA) is. Any thoughts? Code below:

```
#include <avr/interrupt.h>

volatile bool stateA = false;
ISR(TIMER0_COMPA_vect)
{
    if (stateA)
        PORTD |= _BV(PIND4);
    else
        PORTD &= ~(_BV(PIND4));

    stateA = !stateA;
}

volatile bool stateB = false;
ISR(TIMER0_COMPB_vect)
{
    if (stateB)
        PORTD |= _BV(PIND5);
    else
        PORTD &= ~(_BV(PIND5));

    stateB = !stateB;
}

void setup()
{
    DDRD |= _BV(PIND4) | _BV(PIND5);

    //set timer0 interrupt at 2kHz
    TCCR0A = 0;// set entire TCCR2A register to 0
    TCCR0B = 0;// same for TCCR2B
    TCNT0 = 0;//initialize counter value to 0
    // set compare match register for 2khz increments
    OCR0A = 255;//244Hz
    OCR0B = 127;//488Hz
    // turn on CTC mode
    TCCR0A |= (1 << WGM01);
    // Set CS01 and CS00 bits for 64 prescaler
    TCCR0B |= (1 << CS01) | (1 << CS00);
    // enable timer compare interrupt
    TIMSK0 |= (1 << OCIE0B) | (1 << OCIE0A);

    interrupts();

}

```

**Update:** After thinking about it, I'm realizing that it's not that I need two separate frequencies (though I just kinda wanted to know how, so this is good stuff) but I just need two separate interrupts, only using Timer0 (1 & 2 are already in use elsewhere). They can be the same frequency, most likely. I probably *could* put all the functionality I need in the same TIMER0\_COMPA\_vect, however I was trying to use that in a library I was writing and was trying to keep the functionality separate... this may not be possible.

# Answer
> 1 votes
Your code doesn't do what you think it does. The timer always runs at 244Hz, and OCR0B only matches twice per period, causing it to have the same frequency but a different phase. What you need to do is set OC0B on compare match and clear it in the overflow ISR. OCR0A you can simply set to toggle on match.

```
TCCR0A = _BV(COM0A0) | _BV(COM0B1) | _BV(COM0B0) | _BV(WGM01);
TIMSK0 |= _BV(OCIE0A);

 ...

ISR(TIMER0_COMPA_vect)
{
  PORTB &= ~_BV(PD5);
}

```

Also, OC0A is D6, not D4.

# Answer
> 1 votes
I think your code did not set `TIMSK0` properly.

Instead of:

```
TIMSK0 |= (1 << OCIE0B) | (1 << OCIE0A);

```

You should use:

```
TIMSK0 = (1 << OCIE0B) | (1 << OCIE0A);

```

Why? Because `TIMSK0` is already initialized by Arduino libraries before your `setup()` is called.

If you take a look at `hardware/arduino/cores/arduino/wiring.c` and search for the `init()` function, you will see that it contains the following lines:

```
    // enable timer 0 overflow interrupt
#if defined(TIMSK) && defined(TOIE0)
    sbi(TIMSK, TOIE0);
#elif defined(TIMSK0) && defined(TOIE0)
    sbi(TIMSK0, TOIE0);
#else
    #error  Timer 0 overflow interrupt not set correctly
#endif

```

With these lines, the `TOIE0` bit of `TIMSK0` is set, but your `setup()` does not clear it.

# Answer
> 1 votes
Actually, after reading the ATmega328P datasheet again, I am not sure that you can use both `OCR0A` and `OCR0B` in normal timer mode.

In particular, since you use CTC mode, I think that `TCNT0` will be cleared every time its value reaches `OCR0A` i.e. 127.

Since you need 244Hz and 488Hz (exactly twice 244Hz), I think you can operate with only one of `OCR0A` or `OCRB0` and do the work in one ISR only:

```
#include <avr/interrupt.h>

volatile bool setBothPins = false;
ISR(TIMER0_COMPA_vect)
{
    if (setBothPins)
        // D4 is changed only once (244Hz)for every 2 changes of D5 (488Hz)
        PORTD ^= _BV(PIND4);
    PORTD ^= _BV(PIND5);

    setBothPins = !setBothPins;
}

void setup()
{
    DDRD |= _BV(PIND4) | _BV(PIND5);

    //set timer0 interrupt at 2kHz
    TCCR0A = 0;// set entire TCCR2A register to 0
    TCCR0B = 0;// same for TCCR2B
    TCNT0 = 0;//initialize counter value to 0
    // set compare match register for 2khz increments
    OCR0A = 127;//488Hz
    // turn on CTC mode
    TCCR0A |= (1 << WGM01);
    // Set CS01 and CS00 bits for 64 prescaler
    TCCR0B |= (1 << CS01) | (1 << CS00);
    // enable timer compare interrupt
    TIMSK0 = (1 << OCIE0A);

    interrupts();
}

```

# Answer
> 1 votes
It *is* possible to use the Timer0 compare interrupts without affecting the `millis()` and `micros()` functions. Simply set the compare interrupts to occur at 1/3rd and 2/3rds of the overflow period. That way they won't conflict with each other because there will be some time between each of the three interrupts (overflow, compare A and compare B). You can't change the frequency though because that would change the update of `millis()` and `micros()`. Instead, you could use software *post*-scalers within the ISRs, something like this:

```
volatile bool     isr_t0a_flag = false;
volatile uint32_t isr_t0a_delta_time = 0;
#define           TIMER_0_COMPARE_A_POST_SCALER 50

volatile bool     isr_t0b_flag = false;
volatile uint32_t isr_t0b_delta_time = 0;
#define           TIMER_0_COMPARE_B_POST_SCALER 100

void setup()
{
  Serial.begin(115200);
  Serial.print("\n\n");

  // Find out what Timer0 has been initialised to.
  Serial.println(TCCR0A);  // 3 = Fast PWM mode with a fixed timeout of 255.
  Serial.println(TCCR0B);  // 3 = 64 prescaler.
  Serial.println(OCR0A);   // 0
  Serial.println(OCR0B);   // 0
  Serial.println(TIMSK0);  // 1 = Timer overflow interrupt enabled for millis()/micros().
  Serial.print("\n\n");

  cli(); // Disable interrupts.

  //
  // Set Timer0 compare interrupts
  //
  // Clock frequency     = 16 MHz
  // Prescaler           = 64
  // Timeout             = 255
  //
  // Overflow interrupt frequency = 16 MHz / 64 / (255 + 1) = 977 Hz (1024 us)
  // Overflow interrupt frequency =  8 MHz / 64 / (255 + 1) = 488 Hz (2048 us)
  //
  OCR0A  = 85;              // Set 1/3rd phase shift for compare A.
  OCR0B  = 171;             // Set 2/3rds phase shift for compare B.
  TIMSK0 |= (1 << OCIE0A);  // Enable compare A interrupt.
  TIMSK0 |= (1 << OCIE0B);  // Enable compare B interrupt.

  sei(); // Enable interrupts.

  // Verification.
  Serial.println(TCCR0A);  // 3   = Fast PWM mode with a fixed timeout of 255.
  Serial.println(TCCR0B);  // 3   = 64 prescaler.
  Serial.println(OCR0A);   // 85  = 1/3rd phase shift for compare A.
  Serial.println(OCR0B);   // 171 = 2/3rds phase shift for compare B.
  Serial.println(TIMSK0);  // 7   = All 3 interrupts enabled.
  Serial.print("\n\n");
}

void loop()
{
  uint32_t t0a_delta_time = 0;
  uint32_t t0b_delta_time = 0;

  ////////////////////////////
  // BEGIN CRITICAL SECTION

  cli();  // Disable interupts.

  bool t0a_flag = isr_t0a_flag;
  if (t0a_flag)
  {
    t0a_delta_time = isr_t0a_delta_time;
    isr_t0a_flag = false;
  }

  bool t0b_flag = isr_t0b_flag;
  if (t0b_flag)
  {
    t0b_delta_time = isr_t0b_delta_time;
    isr_t0b_flag = false;
  }

  sei();  // Enable interrupts.

  // END CRITICAL SECTION
  ////////////////////////////

  if (t0a_flag)
  {
    Serial.print("T0a ");
    Serial.println(t0a_delta_time);
  }

  if (t0b_flag)
  {
    Serial.print("T0b ");
    Serial.println(t0b_delta_time);
  }
}

ISR(TIMER0_COMPA_vect)
{
  static byte count = 0;
  count++;
  if (count >= TIMER_0_COMPARE_A_POST_SCALER)
  {
    count = 0;
    static uint32_t previous_time = 0;
    uint32_t time = micros();
    uint32_t delta_time = time - previous_time;
    previous_time = time;
    isr_t0a_delta_time = delta_time;
    isr_t0a_flag = true;
  }
}

ISR(TIMER0_COMPB_vect)
{
  static byte count = 0;
  count++;
  if (count >= TIMER_0_COMPARE_B_POST_SCALER)
  {
    count = 0;
    static uint32_t previous_time = 0;
    uint32_t time = micros();
    uint32_t delta_time = time - previous_time;
    previous_time = time;
    isr_t0b_delta_time = delta_time;
    isr_t0b_flag = true;
  }
}

```

---
Tags: timers, interrupt
---


# Question
Title: How to connect 10 coin vibration motors to UNO?
I am new to arduino and anything related to electricals and electronics. I need info on how to connect 10 vibration motors to arduino uno without damaging the board. Do I need an external circuit to regulate and control power supply or can I directly plug in all 10 motors to the board directly?

# Answer
I would suggest a pair of ULN2003 chips. These are 6 darlington transistors in a single chip. Two chips will give you the ability to connect 12 motors.

Each one needs an IO pin to control it - if you want speed control then you will have to look into adding extra PWM channels. For just ON/OFF control any IO pin will do (even analog ones).

10 motors running at the same time will be up near the limit of the Arduino's 5V pin current supply, so you really should consider a separate external 5V power supply (maybe a USB phone charger) of 1A or more to power everything (connect the power supply to the motors and the 5V pin of the Arduino).
> 2 votes

# Answer
The motor is not a constant output device, it still works by watts of power. The motor will only draw enough current to move its load at a given speed. Lets assum the impedance of the motor is a constant; If we change the voltage we change the wattage and hence the torque and probably speed. "The Arduino a power supply it is not!" On a good day it has a 200ma max capability. This is dependent on the power the regulator can dissipate, dictated by load and the voltage going into the Vin pin.

If we look at the 66mA it draws times 10 motors that is 660 mA is way beyond the Arduino rating of 200ma. Total chip Vcc current (all output pins total and chip overhead): 10 output pin driving 10 motors @ 66 ma is way beyond max for whole chip.
> 0 votes

---
Tags: arduino-uno, motor
---


# Question
Title: having problems with my arduino bluetooth car project(with L298n Motor Driver)
so the scenario is i am making a bluetooth controlled car(voice control)+obstacle avoidance function.I am using Arduino UNO with L298n motor driver and a HC-05 BT module in the sensors i am using the ultrasonic sensor and a IR sensor for the back and a servo motor is also used to rotate the ultrasonic sensor.so the problem is when i am sending command "turn left" the servo moves left and nothings happens and the other command i.e turn right,move backward,move forward are not working at all.

circuit diagram and code is given if i have done something wrong with the code or else my motor driver or wiring is creating the issue

```

#include <NewPing.h>
#include<Servo.h>
#define TRIGGER_PIN A1
#define ECHO_PIN A0
#define MAX_DISTANCE 300
#define IR A2

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

Servo myservo;

String voice;

void setup() {
  Serial.begin(9600);
  myservo.attach(8);
  myservo.write(90);
  pinMode(IR, INPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode( 9, OUTPUT);

}

void loop() {
  int distance = sonar.ping_cm();

  if (Serial.available() > 0) {
    voice = "";
    delay(2);
    voice = Serial.readString();
    delay(2);
    Serial.println(voice);

    if (voice == "turn left") {
      left();
    } else if (voice == "left") {
      left();
    } else if (voice == "turn right") {

    } else if (voice == "right") {

    }

  }
  while (voice == "move forward") {
    forward();
  }
  while (voice == "move backward") {
    backward();
  }
}

void forward() {
  int distance = sonar.ping_cm();

  if (distance < 10) {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite( 9, LOW);
    voice = "";
  } else {
    digitalWrite(12, HIGH);
    digitalWrite(10, HIGH);
  }
}
void backward() {
  int IR_Sensor = digitalRead(IR);
  if (IR_Sensor == 0) {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite( 9, LOW);
    voice = "";
  } else {
    digitalWrite(11, HIGH);
    digitalWrite( 9, HIGH);
  }
}
void left() {
  myservo.write(180);
  delay(500);
  myservo.write(90);
  delay(500);
  int distance = sonar.ping_cm();

  if (distance < 10) {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite( 9, LOW);
    voice = "";
  } else {
    digitalWrite(12, HIGH);
    delay(700);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite( 9, LOW);

  }
}

void right() {
  myservo.write(0);
  delay(500);
  myservo.write(90);
  delay(500); {
    int distance = sonar.ping_cm();

    if (distance < 10) {
      digitalWrite(12, LOW);
      digitalWrite(11, LOW);
      digitalWrite(10, LOW);
      digitalWrite( 9, LOW);
      voice = "";
    } else {
      digitalWrite(10, HIGH);
    }
    delay(700);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite( 9, LOW);
  }
}

void Stop() {
  digitalWrite(12, LOW);
  digitalWrite(11, LOW);
  digitalWrite(10, LOW);
  digitalWrite( 9, LOW);
}

```

# Answer
The code seems to have a few missing lines for logic. Here's a corrected version from my understanding.

```
#include <NewPing.h>

#include<Servo.h>

#define TRIGGER_PIN A1
#define ECHO_PIN A0
#define MAX_DISTANCE 300
#define IR A2

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

Servo myservo;

String voice;

void setup() {
  Serial.begin(9600);
  myservo.attach(8);
  myservo.write(90);
  pinMode(IR, INPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);

}

void loop() {
  int distance = sonar.ping_cm();

  if (Serial.available() > 0) {
    voice = "";
    delay(2);
    voice = Serial.readString();
    delay(2);
    Serial.println(voice);

    if (voice == "turn left") {
      left();
    } else if (voice == "left") {
      left();
    } else if (voice == "turn right") {
      right();
    } else if (voice == "right") {
      right();
    } else if(voice == "move forward"){
      forward();
    } else if(voice == "move backward"){
      backward();
    }

  }

}

void forward() {
  int distance = sonar.ping_cm();

  if (distance < 10) {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    voice = "";
  } else {
    digitalWrite(12, HIGH);
    digitalWrite(10, HIGH);
  }
}
void backward() {
  int IR_Sensor = digitalRead(IR);
  if (IR_Sensor == 0) {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    voice = "";
  } else {
    digitalWrite(11, HIGH);
    digitalWrite(9, HIGH);
  }
}
void left() {
  myservo.write(180);
  delay(500);
  myservo.write(90);
  delay(500);
  int distance = sonar.ping_cm();

  if (distance < 10) {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    voice = "";
  } else {
    digitalWrite(12, HIGH);
    delay(700);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);

  }
}

void right() {
  myservo.write(0);
  delay(500);
  myservo.write(90);
  delay(500); {
    int distance = sonar.ping_cm();

    if (distance < 10) {
      digitalWrite(12, LOW);
      digitalWrite(11, LOW);
      digitalWrite(10, LOW);
      digitalWrite(9, LOW);
      voice = "";
    } else {
      digitalWrite(10, HIGH);
    }
    delay(700);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
  }
}

void Stop() {
  digitalWrite(12, LOW);
  digitalWrite(11, LOW);
  digitalWrite(10, LOW);
  digitalWrite(9, LOW);
}

```
> 1 votes

---
Tags: arduino-uno, bluetooth, l298n
---


title: Multiple Push buttons to one input

text:
# Question
Title: Multiple Push buttons to one input
So I am trying to use one input to control an LCD display. The goal being that once one of the buttons is pressed it delivers a message. I have watched quite a few tutorials and can get the program to work sometimes. Yet, it is still pretty buggy and I am wondering why that is. To get this make this project work somewhat used this code.

```
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int buttonPin = A0;     //Button and LED pin numbers
    void setup()
{
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  //lcd.print("hello, world!");
  Serial.begin(9600);           //Serial monitor used to determine limit values

 }

void loop()
{
  int temp = analogRead(buttonPin);   //Read the analogue input
  Serial.println(temp);               //Display the read value in the Serial monitor
  if (temp = 340)                     //Lower limit for first button - if below this limit then no button is pushed and LEDs are turned off
  {
  lcd.print("No Button Pushed \n");
  }
  else if (temp = 867)                //First button limit - if below this limit but above previous limit then the first button is pressed
  {
    lcd.print("Button 1 Pushed");
  }
  else if (temp = 156 )                //Second button limit
  {
    lcd.print("Button 2 Pushed");
  }

  else                                //If none of the previous buttons are pressed, then the third button must be pressed
  {
    lcd.print("Button 3 Pushed");
  }
  delay(100);                         //Delay for stability
}

```

The output sometimes is correct other times it is off. I think it has something to do with the circuit. Yet, I am scratching my head to find out what.

# Answer
Michel Keijzers pointed out the issues you have in your code. But then there is also an issue with your circuit: if you press any of the push buttons, the analog input pin gets connected to one of the nodes of the resistor ladder, and you get a well defined voltage reading. Good. However, if none of the buttons is pressed, the input is not connected to anything: it is floating. In this case the reading you get is unpredictable, as it depends on parasitic influences of stray capacitances, environmental noise, etc. You should modify your circuit to make sure that the input voltage is well defined even when no button is pressed.

Then, regarding the program, I recommend you remove everything after `Serial.println(temp);`. Just make it work like this, and take note of the readings you get in each case. Make sure they are consistent. Once you know the values you expect, you can decide on the threshold to apply, which should be about halfway between the typical readings. E.g. if the two lowest values you get are 0 and 240, you would set a threshold at 120.
> 4 votes

# Answer
You made a few mistakes with the three lines, first one being:

```
if (temp = 340)

```

First, the single '=' is an assignment operator instead of a comparing operator. You want to use '=='.

However, you need to check if it is within a range, so you need to use \<= (to see if it is smaller or equal). Also you need to put them in the correct order, so you get something like:

```
if (temp <= 156)
{
   // Process value if temp is smaller or equal than 156
}
else if (temp <= 340)
{
   // Process value if temp is smaller or equal than 340 (and higher than 156)
}
else if (temp <= 860)
{
   // Process value if temp is smaller or equal than 860(and higher than 340)
}
else
{
   // Process value if temp is higher than 860
}

```
> 3 votes

---
Tags: lcd, input, analog
---


# Question
Title: How to slowly change direction of the stepper motor with AccelStepper?
I know that direction can be changed with

```
.setSpeed(speed);
... //check input
.setSpeed(-speed);

```

I need to slowly decelerate and accelerate backwards, so I have to use

```
.setAcceleration(200);
...
.setMaxSpeed(speed);
... //check input
.setMaxSpeed(-speed);

```

but documentation told that .setMaxSpeed argument Must be \> 0.

So how to properly change direction with deceleration? Probably I have to use .moveTo with some very big values

# Answer
> 2 votes
I have tested it on real motor, and it works as I want with function .moveTo . Speed slowly changed from +maxSpeed to -maxSpeed acording to Acceleration

```
#define maxSpeed 1000
#define Acceleration 500
............
void setup(){
  stepper.setMaxSpeed(maxSpeed);
  stepper.setAcceleration(Acceleration);
}
void loop() {
 ............
 if(bDirection!=bDirection_last)
 {
  stepper.moveTo(bDirection?6000000:-6000000);
  ...........
 }
 stepper.run();
}

```

---
Tags: stepper-motor, speed
---


# Question
Title: How to connect MPU9250 with NodeMCU using SPI or I2C Slave?
I want to connect 3 MPU9250 sensors, but since there is just one I2C bus, so there are another 2 sensors I want to connect through SPI.

Library used - https://github.com/bolderflight/MPU9250/blob/master/examples/Basic\_SPI/Basic\_SPI.ino

There is an SPI example code written, but I don't know about the connections. There are no MISO and other pins on the sensor which i use but its SPI compatible. How do I connect 2 MPU9250 to NodeMCU with SPI?

If SPI connection is not possible then please post about I2C slave connection.

# Answer
If you want to use SPI-

The homepage of the library you mentioned, clearly explains the circuit connections.-

The MPU-9250 pins should be connected as:

* VDD: this should be a 2.4V to 3.6V power source.
* GND: ground.
* VDDI: digital I/O supply voltage. This should be between 1.71V and VDD.
* FSYNC: not used, should be grounded.
* INT: (optional) used for the interrupt output setup in enableDataReadyInterrupt and enableWakeOnMotion. Connect to interruptable pin on microcontroller.
* SDA / SDI: connect to MOSI.
* SCL / SCLK: connect to SCK.
* AD0 / SDO: connect to MISO.
* nCS: connect to chip select pin. Pin 10 was used in the code snippets in this document and the included examples, but any digital I/O pin can be used.
* AUXDA: not used.
* AUXCL: not used.

Each sensor's nCS (chip select pin) needs to be connected to a slave select pin (any digital pin) on the NodeMCU. This allows the NodeMCU toselect which sensor it wants to talk to.

Another easy way of connecting multiple sensors with the same I2C address is by using an I2C multiplexer like the Adafruit TCA9548A  This would allow you to connect up to 8 sensors having the same I2C address. Here's a youtube video explaining how to do so.

However, if you just want connect two MPU9250s, you dont need to do any of this, as the board offers two unique addresses via the AD0 pin-

* 0x68 if AD0 is grounded
* 0x69 if AD0 is pulled high
> 2 votes

# Answer
To connect multiple SPI components, you only need 4 pins on each 'slave' (thus sensors): SLCK, MOSI, MISO and SS (Slave Select).

The Slave select pin depends to which the master (NodeMCU in your case) is 'talking too'. So on your NodeMCU you will have 3 SS pins (one for each slave sensor). The NodeMCU should talk exactly to one slave device at the same time by setting that SS pin LOW (while the other SS pins are high).

See for the full article: Multiple-SPI-devices-to-an-arduino-microcontroller.
> 1 votes

# Answer
The MPU-9250 pins should be connected as:

--Vcc: this should be a 2.4V to 3.6V power source.

--GND: ground.

--FSYNC: not used, should be grounded.

--SDA / SDI: connect to MOSI.

--SCL / SCLK: connect to SCK.

--AD0 / SDO: connect to MISO.

--nCS: connect to chip select pin (Any digital pin but in your example is PIN 10).

Also, you can check the connection from:

https://learn.sparkfun.com/tutorials/mpu-9250-hookup-guide?\_ga=1.139382715.926858641.1470020364
> 1 votes

---
Tags: i2c, spi, nodemcu, mpu6050, imu
---