# Question
Title: Nano: All digital pins do not output anything
New user here. Using the examples provided on the Arduino IDE software I could produce melodies with a piezo buzzer, or have a blinking LED.

Not anymore. No digital pin is giving anything. I can see the embedded LED blink if I program the Pin 13, but no impact outside of it.

So I tried connecting an output digital pin (13) to an Analog input pin, or any one that can be put as input (A7, D5, etc.) (with a resistor so not to destroy the little thing).

```
const char out=13;
const char  in=8;
char         i=0;
void setup() {
  Serial.begin(9600);
  pinMode(out, OUTPUT);
  pinMode(in,  INPUT);
  digitalWrite(out, LOW);
}
void loop() {
  if(i&1){
    digitalWrite(out,i&2?HIGH:LOW);
  }else{
    Serial.println(analogRead(in));
  }
  i++;
  delay(50);
}

```

The output has been 0, whichever digital pin it is connected to.

How can I actually find out if, by any chance, I successfully (!) damaged all my digital pins?

* I currently use a breadboard
* The ground is connected correctly (to GND)
* It stopped working between uses, last time I was trying a `Tone(out,val)` melody
* I'm measuring the out-pin value by connecting it to an analog in-pin with a resistor in series
* I did set the out-pin as such during setup. (`pinMode(out, OUTPUT);`)

---

So! Looks like I didn't understand the codes for the digital pins. I thought we had to use the pin number, but the digital pin number (say `10` for `D10`) is what it takes to address it. And I was always referring myself back to the schematic for each pin -\_-.

As well with the accepted answer, I needed to pull down (or up? still can't figure it out!) the input pin with a resistor to ground.

Thanks everyone!

# Answer
Your sketch works on a Nano (clone) that I have

I am using a high-brightness white LED with a 10kΩ resistor to bring the brightness down to a bearable level, so the current drawn is about (5v-2.2v)/10kΩ = 0.28mA. This is a low level of current and should be safe for poking around with.

> **I can see the embedded LED blink if I program the Pin 13, but no impact outside of it.**

That suggests that the ATmega328P is essentially undamaged and that at least the IC leg connected to D13 is working as it should.

> **How can I actually find out if, by any chance, I successfully (!) damaged all my digital pins?**

Without a multimeter or other tools, I would take a LED and resistor that draw less than 5mA, test them between VCC and GND to make sure they work

Then I would use the resistor and LED to check the output of each of the D2 to D13 outputs using your existing sketch.

When the onboard LED blinks, I am able to attach a LED and series resistor to pin D13 and get it to blink.

---

I wasn't sure what you intended by setting `in` to `8` so I later changed your program as follows:

```
const char  in=A1;

```

and I got this output on the serial monitor after connecting a jump lead from D13 to A1

```
0
1010
0
1009
0
1009
0
1009
0
1009
0
1009
0
1009
0
1009
0
1008

```

---

If I pivot the LED away from pin D13, I can use a jump lead as a test probe

Main points:

* pick a high resistor value that minimises current drawn but is still easily visible.
* check the LED works! (is right way around etc)
* use a jump lead as a probe.

There are more sophisticated test circuits you could build with a FET etc but this would normally be enough for me to decide if an Arduino's outputs are damaged.

---

Extract from ATmega328 datasheet - note the max current draw per pin is 40mA. Exceeding that is probably the easiest way to damage the IC but if the onboard LED labelled "L" (and connected to D13) works, it means that part of the IC is undamaged.
> 2 votes

---
Tags: arduino-nano, analogread, digital, digitalwrite
---


title: Joining several PIR sensors

text:
# Question
Title: Joining several PIR sensors
I wish to use some PIR (HC-SR501) sensors and give some response if at least one of them detects human movements.

For simplicity I wish to use *only one input pin* in an Arduino UNO. My idea is to connect all the output wires into a single Arduino digital input. Should it work?

I am in doubt because the following two reasons:

* The sensors must be far away from each other (about 5 sensors partially covering an area of about 200 m^2). That implies that wires are long and I do not know if this can have some adverse effect.
* I do not know if it is bad to supply the 3.5V of some sensor that is currently detecting movement to the output of the sensors that are not detecting anything.

Thanks in advance

# Answer
The BISS0001 that your unit uses provides an "active high" output. To connect multiple devices together you just need to "OR" the signals.

There's many ways of doing that.

The simplest method is the "wired OR" circuit, which just involves one pulldown resistor plus one diode per device:

simulate this circuit – Schematic created using CircuitLab

You could also use a multiple-input OR gate chip. You can get these in 2- (74HC32), 3- (74HC4075), 4- (74HC4072) input versions.
> 3 votes

---
Tags: arduino-uno
---


title: Node MCU Wifi connection problem

text:
# Question
Title: Node MCU Wifi connection problem
I'm trying to connect my nodeMCU to my WiFi network also i have provided ip address but it keeps printing ........ it is not connecting to the network. Below is my code.

```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// Configration Parameter for Access Poin
char * ssid_ap = "";
char * password_ap = "";
IPAddress ip(192, 168, 1, 158);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255,255,255,0);

// Set up the server object
ESP8266WebServer server (80);

// Keep track of sensor data that's going to be sent by the client
float sensor_value = 0.0;

void setup()
{
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(ip,gateway,subnet);
  WiFi.softAP(ssid_ap,password_ap);

  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid_ap);

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

  Serial.println("");
  Serial.println("WiFi connected");

  server.begin();
  Serial.println("Server started");
  Serial.print("IP Address:");
  // Serial.print(WiFi.localIP());
  // Configure Server Router
  server.on("/",handleIndex); // use the top root path to report the last sensor value
  server.on("/update",handleUpdate);
  // server.begin();
}

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

}

void handleIndex()
{
  server.send(200,"text/plain",String(sensor_value)); //we'll need to refresh the page for getting the latest value

}

void handleUpdate()
{
 sensor_value = server.arg("value").toFloat();
 Serial.println(sensor_value);
 server.send(200,"text/plain","Updated");

}

```

# Answer
You are creating a SoftAP (in essence creating a separate Wifi network). In this configuration, the ESP8266 will not "connect" to anything so polling `WiFi.Status` for the `WL_CONNECTED` status is meaningless.

To see if the SoftAP instance was created successfully, you should look at the output of `WiFi.SoftAP()` when you create the SoftAP instance, which returns a boolean indicating success (`true`) or failure. Or you should see the SSID of your newly created access point appearing on your PC or phone.

I suggest you look at the ESP8266 examples included in the Arduino IDE when you install device support for the ESP8266 to get some ideas about what you can do with a SoftAP.
> 1 votes

---
Tags: nodemcu
---


title: Storing IR Sensor value not working

text:
# Question
Title: Storing IR Sensor value not working
This is my first time working on Arduino for my project and I ran into an issue. I'm trying to make a very simple Vending Machine. Coin or any obstacle passes in front of the IR sensor and based on that, the user can either press button 1 or 2 and based on that motor 1 or 2 would run respectively.
The overall logic works exactly how I want it to, the issue I'm facing is that the variable (`sensorStatus`) storing the IR sensor value isn't working correctly. Whether anything passes in front of it or not, it lets me press the buttons anyways and the motor starts working.

```
void loop() {

  int sensorStatus;

  //this is where im having the issue
  if (digitalRead(inSensor) == LOW) sensorStatus = LOW;

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);

      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
      }

      buttonStatus2 = digitalRead(inButton2);

      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
      }

      sensorStatus = HIGH;
   }
}

```

If I don't use this logic and store the value of the sensor directly into the variable (`sensorStatus`), the whole program seems to be working till I have an obstacle in front of the sensor continuously. I don't want this to happen, I want it to work in such a way that once an obstacle passes in front of the sensor it keeps the value (even after the obstacle is gone) until a button is pressed and after that, it gets rid of the value to repeat the process once again. It seems to be a code logic issue but I can't seem to figure out the logic behind it.

**My Complete Source Code:**

```
const int relayControl1_1 = 13; // relay 1 of 1 (input 1)
const int relayControl1_2 = 12; // relay 1 of 2 (input 2)
const int relayControl2_1 = 11; // relay 2 of 1 (input 3)
const int relayControl2_2 = 10; // relay 2 of 2 (input 4)

const int inButton1 = 9; //input button 1
const int inButton2 = 8; //input button 2

int buttonStatus1 = 0;
int buttonStatus2 = 0;

const int inSensor = 7;

void setup() {
  Serial.begin(9600);
  pinMode(relayControl1_1, OUTPUT);
  pinMode(relayControl1_2, OUTPUT);
  pinMode(relayControl2_1, OUTPUT);
  pinMode(relayControl2_2, OUTPUT);

  pinMode(inButton1, INPUT_PULLUP);
  pinMode(inButton2, INPUT_PULLUP);

  pinMode(inSensor, INPUT_PULLUP);

}

void loop() {

  int sensorStatus;

  //this is where im having the issue
  if (digitalRead(inSensor) == LOW) sensorStatus = LOW;

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);

      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
      }

      buttonStatus2 = digitalRead(inButton2);

      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
      }

      sensorStatus = HIGH;
   }
}

```

# Answer
Thanks to the help from `@Majenko♦` I was able to fix the issue.

1 - `int sensorStatus;` should have been set to `static int sensorStatus = HIGH;` to make the program remember the value of the sensor.

2 - `sensorStatus = HIGH;` should have been right after `digitalWrite(relayControl1_1, HIGH);` in the `buttonStatus` conditional else part to make the program set the `sensorStatus` back to HIGH correctly.

3 - Unrelated to the question posted, doing the above steps made the program run the motors continuously unless they were stopped by an obstacle from the IR sensor. This was fixed by adding `delay(2000); digitalWrite(relayControl1_1, LOW);` after the `sensorStatus = HIGH;` mentioned in the 2nd step.

**Source Code after fixing:**

```
const int relayControl1_2 = 12; // relay 1 of 2 (input 2)
const int relayControl2_1 = 11; // relay 2 of 1 (input 3)
const int relayControl2_2 = 10; // relay 2 of 2 (input 4)

const int inButton1 = 9; //input button 1
const int inButton2 = 8; //input button 2

int buttonStatus1 = 0;
int buttonStatus2 = 0;

const int inSensor = 7;

void setup() {
  Serial.begin(9600);
  pinMode(relayControl1_1, OUTPUT);
  pinMode(relayControl1_2, OUTPUT);
  pinMode(relayControl2_1, OUTPUT);
  pinMode(relayControl2_2, OUTPUT);

  pinMode(inButton1, INPUT_PULLUP);
  pinMode(inButton2, INPUT_PULLUP);

  pinMode(inSensor, INPUT_PULLUP);

}

void loop() {

  static int sensorStatus = HIGH;

  if (digitalRead(inSensor) == LOW) {
    sensorStatus = LOW;
  }

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);

      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
        sensorStatus = HIGH;
        delay(2000);
        digitalWrite(relayControl1_1, LOW);
      }

      buttonStatus2 = digitalRead(inButton2);

      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
        sensorStatus = HIGH;
        delay(2000);
        digitalWrite(relayControl2_1, LOW);
      }
   }
}

```
> 1 votes

---
Tags: arduino-uno, code-review, ir, variables
---


title: 74HC595 to 5v pin shuts down uno

text:
# Question
Title: 74HC595 to 5v pin shuts down uno
I'm new to using the SN74HC595 shift register, and trying to follow this tutorial: https://www.arduino.cc/en/tutorial/ShiftOut based on this configuration:

When my arduino Uno R3 is plugged in by USB to my Windows-7 x64 PC, it works (in general etc.), but right when I attach pin 16 or pin 10 of the 74HC595 to the 5V pin on the Uno, as it says to do, the entire arduino shuts off and the computer no longer recognizes it, until I disconnect the jumper wire from pin 16 or 13, from the 5v pin on the Uno, then it starts up again

Also just tested, and the same thing happens when I try to connect any of the 74HC595 pins to the 5v Uno pin (after pin 8 of the 74HC595 is connected to the Uno's GND), the whole Uno shuts off and disconnects from the computer

Am I missing something here?

# Answer
> 1 votes
> **when I attach pin 16 or pin 10 of the 74HC595 to the 5V pin on the Uno ... the entire arduino shuts off**

This sort of thing usually happens to me when I have made a mistake in the wiring.

This is easy to do as the 595 needs a lot of connections in a small space and it is easy to make a mistake.

In your case it seems you have a wiring mistake that is pulling Vcc low and the ATmega328 IC etc can't run.

---

I would

* Re-check the orientation of the 595
* Re-check each wire paying particular attention to the ground wires, especially the one that pulls 595 OE to ground (it's pin 13 on the 595).
* If necessary, pull everything off the breadboard and start again with things in a completely different position (turn the IC's round etc) to make me re-think everything.

---

For fun, I set this up on a Uno clone. I made some mistakes in the wires linking the 595 to the Uno but careful inspection found the problem. I found it easy to mix up the pin-number on the 595 with that on the Uno. Using the same wire colours mentioned in the guide may help.

Here's it working

---
Tags: arduino-uno, shift-register
---


# Question
Title: Controlling keyboard LEDs with USB Host Shield
I've got a USB keyboard connected to my Arduino Uno with a USB Host Shield. I'm reading keystrokes using this example from the USB Host Shield library.

I need to toggle the LEDs in the keyboard (that indicate the state of Caps Lock, Num Lock etc.)

This thread mentions using `Usb.setReport()`, but this method doesn't seem to exist any more: there's no such method in Usb.cpp in the library. There does seem to be a method called `SetReport` in the USBHID class, which looks like it takes the same arguments, which I'm trying to use.

What I'm currently doing:

```
void keyboard_setup(){
    static HIDBoot<USB_HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb);
    if (Usb.Init() == -1) {
        Serial.println("OSC did not start.");
    }
    delay(200);
    HidKeyboard.SetReportParser(0, &Prs);

    static USBHID usbhid(&Usb);
    uint8_t leds = 1;
#define KBD_ADDR 1
#define KBD_IF 0
    usbhid.SetReport( KBD_ADDR, 0, 1, KBD_IF, 0, &leds );
    delay(100);
    leds = 255;
    usbhid.SetReport( KBD_ADDR, 0, 1, KBD_IF, 0, &leds );
    delay(100);

```

Neither call to SetReport seems to work, and I'm not certain the values of KBD\_ADDR or KBD\_IF are correct (I'm using ones that I've seen in examples), or event that calling SetReport is right .

What am I doing wrong?

# Answer
> 2 votes
> There does seem to be a method called `SetReport` in the USBHID class, which looks like it takes the same arguments, which I'm trying to use.

The method arguments of the new `SetReport()` method aren't quite the same and some are in a different order.

The old method signature was:

```
uint8_t setReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr );

```

...while the new one is:

```
uint8_t SetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr);

```

It seems to me the equivalent call would be:

```
usbhid.SetReport( 0, KBD_IF, 0x02, 0, 1, &leds );

```

---
Tags: c++, usb, keyboard
---


# Question
Title: How to write to the second line of a display?
I got this 4 line display from Mouser: https://www.gravitech.us/20chbllcd.html, and I get it to work fine for lines 1 and 3 (as line 3 is just the 21st character of line 1). But I am struggling to get lines 2 and 4 working. If I understand correctly, these are "line 2" for the HD44780 controller, and I should set the DDRAM address to `0x40` before I write there.

But, when I try that, nothing happens.

I tried writing `0x04` to the DDRAM address counter, and I can see the cursor jumping there, but when I write to that address, no text shows up. If I omit the command, text pops up correctly.

Also, when changing the contrast of the display (using the potentiometer on the Vdd and Vo pins), only lines 1 and 3 change contrast.

My code:

This method I use for convenience:

```
void set(int _rs, int _rw, int _d7, int _d6, int _d5, int _d4, int _d3, int _d2, int _d1, int _d0) { ... }

```

To set the DDRAM address to `0x40`:

```
set(0,0,1,1,0,0,0,0,0,0);

```

The general timing and control is correct, as I can get text on the display, and also a function like "shift" works fine.

# Answer
> 1 votes
* Line 1 starts at address 0x00 | 0x80 `0b10000000` and ends at 0x13 | 0x80 `0b10010011`
* Line 2 starts at address 0x40 | 0x80 `0b11000000` and ends at 0x53 | 0x80 `0b11010011`
* Line 3 starts at address 0x14 | 0x80 `0b10010100` and ends at 0x27 | 0x80 `0b10100111`
* Line 4 starts at address 0x54 | 0x80 `0b11010100` and ends at 0x67 | 0x80 `0b11100111`

That 0x80 `0b10000000` is the HD44780 command for set DDRAM address. The other bits `0b1xxxxxx` define the address.

You'll find more details at Arduino with HD44780 based Character LCDs

# Answer
> 0 votes
You need to setup the HD44780 in 2-line mode. The command is `| 0 | 0 | 1 | DL | N | F | X | X |` with:

* DL: 0 = 4-bit / 1 = 8-bit interface
* N: 0 = 1 line / 1 = 2 lines **(this is the bit to set)**
* F: 0 = 5x7 / 1 = 5x10 font size

Most probably you have that command already in your program to set the width of the interface, but with N = 0.

*Note: The common algorithm is to send the command `0x33` three times to make sure to be in 8-bit mode. The first can be the second part of a half-done 4-bit command, possibly not changing the interface width. Then the second and third will switch into 8-bit mode. If the device is already in 8-bit mode, or gets into it in the course, it makes no harm to repeat.*

Since in 4-bit mode only D7 to D4 are used, you can change `0x33` into `0x38` to enable the 2-lines mode.

---
Tags: display
---


# Question
Title: Char buffer for serial input: char str[2] vs char* str = (char*) malloc(2)
I am using software serials on my Arduino nano to read data from my esp01 in functionality testing for the software serial. I simply make the esp01 to send a string "OK" to an Arduino's software rx serial port (in this case pin 9) , and then the Arduino prints it on the monitor via its hardware serial (USB).

I've found that when I allocate space for the string in Arduino using `char str[2]`, the message seems to be correct. However, with `char* str = (char*)malloc(2)`, there appear to be an unkown character tai ling the string "OK"

Below is the code I use

```
#include<SoftwareSerial.h>

SoftwareSerial s(9,10);
void setup() {
  pinMode(2,OUTPUT);
  Serial.begin(9600);
  s.begin(9600);      // link to esp01
}

void loop() {

  if(s.available() > 0){
    char txt[2];
    int indx = 0;

   // read input
    while(s.available() > 0 && indx <=SIZE-1){
        char buff;
        buff=  s.read();
        txt[indx] =  buff;
        Serial.println(indx);
        indx++;

    }
   // bink an LED for debugging
   if((String)txt == "OK"){
    digitalWrite(2,HIGH);
    delay(500);
    digitalWrite(2,LOW);
    delay(500);
   }

   //reset index
   if(indx ==2){

     Serial.println(txt);
     Serial.print("Size of string:");
     Serial.println(sizeof(txt));
    indx = 0;
   }
  } // if(s.available())

}

```

here is the print-out of the serial monitor

That tailing square is the myster for me.

Any help would be grateful!!

Boris

# Answer
First, a few general notes:

* The difference between `char str[2]` and `char* str = (char*) malloc(2)` is irrelevant to you problem. It changes the place where the array is stored, the meaning of `sizeof str`, and `malloc()` will blow up your RAM if you call it repeatedly and forget to `free()`.
* In your code, `sizeof(txt)` is the constant `2`: the actual size in bytes of the array `txt`, irrespective of how much relevant data it holds.
* You want `txt` and `indx`to remember their contents across calls to `loop()`. You should either make them global or qualify them as `static`.
* Avoid the `String` class if at all possible. Here, since you use it only to compare two strings, you can use the traditional `strcmp()` function instead.

Now, the bulk of my answer is just about expanding on what has already been said about properly terminating strings.

A string is a variable-length list of characters. Whenever you are dealing with a list that has a variable length, you need to somehow keep track of this length. There are two common ways to do so:

1. either you store the length in a variable,
2. or you put a sentinel value (a value that would be invalid within the list) after the last element to mark the end of the list.

Both methods are valid, and I am going to illustrate both of them below. However, in the case of strings, the C++ language uses method 2, with the ASCII “NUL” character (numeric value 0) as a sentinel.

**Method 1**:

```
void loop() {
  static char txt[2];
  static size_t indx = 0;

  while (s.available()) {
    // read input
    char c = s.read();
    txt[indx++] = c;

    // report
    Serial.print("Received: '");
    Serial.print(c);
    Serial.print("', string: \"");
    Serial.write(txt, indx);
    Serial.print("\", size: ");
    Serial.println(indx);
    if (indx == 2 && memcmp(txt, "OK", 2) == 0) {
      Serial.println("Correct message");
    }

    // reset index
    if (indx >= sizeof txt) {
      indx = 0;
    }
  } // if(s.available())
}

```

Some things to note:

* The `indx` variable holds the length of the string. It also happens to be the index of the next available cell in the `txt` array, if any.
* The string is printed using the `write(const char *buffer, size_t size)` method, which accepts a size as a second argument. Unlike `print(const char *)`, it doesn't depend on the string being NUL-terminated.
* In order to check that we received “OK”, we have to check for both the correct length (`indx == 2`) and correct contents. The contents is checked using the `memcmp()` function, which can compare arbitrary byte arrays and, again, does not depend on NUL-termination.
* An important loop invariant here is `idx < sizeof txt`. It is true at initialization and is restored by the “reset index” section at the end of the loop. The “read input” section depends on this invariant to not overflow the buffer.

**Method 2**:

```
void loop() {
  static char txt[3];
  static size_t indx = 0;

  while (s.available()) {
    // read input
    char c = s.read();
    txt[indx++] = c;
    txt[indx] = '\0';

    // report
    Serial.print("Received: '");
    Serial.print(c);
    Serial.print("', string: \"");
    Serial.print(txt);
    Serial.print("\", size: ");
    Serial.println(indx);
    if (strcmp(txt, "OK") == 0) {
      Serial.println("Correct message");
    }

    // reset index
    if (indx >= sizeof txt - 1) {
      indx = 0;
      txt[indx] = '\0';
    }
  } // if(s.available())
}

```

Again, some notes:

* This is actually an hybrid of methods 1 and 2, as the `indx` variable is still used to keep track of where to insert the next incoming character. This just happens to be more convenient and efficient than putting that character into its own length-1 string and using `strcat()`.
* The array is now one cell longer, to make room for the terminating NUL.
* There is another loop invariant now: correct string termination (`txt[indx] == '\0'`). This invariant has to be enforced both on reading and on resetting.
* The string being NUL-terminated, it can now be printed with `print()` and compared with `strcmp()`. The string literal `"OK"` is guaranteed to be NUL-terminated by the compiler.

This second method is generally safer because there are a lot of functions and methods in Arduino and C++ that expect strings to be NUL-terminated. If your strings are not, you have to be extra careful to not use any of these string-oriented functions.
> 1 votes

# Answer
As others have pointed out, C strings are null-terminated. So to hold 2 characters of content you need a 3-byte array. Your code that reads the chacters into the buffer also needs to be changed. (That code isn't adding the required terminating null.)

You should probably rewrite your code to use the `strncat()` function.
> 0 votes

---
Tags: serial, softwareserial
---


# Question
Title: ESP8266 malloc/calloc-related crashes ("segfaults")
This is sort of the continuation of this problem. After getting hints that the problem I had were related to bad memory, I checked all of my heap-allocating code again and found a malloc that didn't allocate enough memory for an array. After fixing that and fiddling around with calloc, which may be safer for array-related stuff, I think I exposed the actual programming errors themselves. The crash message I get now is:

```
No poison after block at: 0x3fff0fb8, actual data: 0x84 0xf 0xff 0x3f

User exception (panic/abort/assert)
Panic umm_malloc.cpp:422 umm_malloc_core

```

which sounds to me like some sort of ESP segfault. The code where this happens according to the stack trace is the following:

```
Menu* createMenuStructure(ace_time::TimeZone* mainTZ) {
  // create an array of all clock faces, i.e. a pointer to an array of function pointers
  void (**allClockFaces)(T_DISPLAY*, ace_time::ZonedDateTime*);
  // funkiest malloc in the world; undefined behavior? I hope not.
  allClockFaces = (void (**)(T_DISPLAY*, ace_time::ZonedDateTime*)) calloc(DESIGN_MENU_SIZE, sizeof(*allClockFaces));
  // initialize array
  allClockFaces[0] = &basicDigitalCF;
  allClockFaces[1] = &digitalWithSecondsCF;
  allClockFaces[2] = &basicAnalogCF;
  allClockFaces[3] = &binaryCF;
  allClockFaces[4] = &fullDayBinaryCF;
  ClockFaceSelectMenu* cfMenu = (ClockFaceSelectMenu*) malloc(sizeof(ClockFaceSelectMenu));
  cfMenu = new ClockFaceSelectMenu((char**)design_menu, (size_t)DESIGN_MENU_SIZE, allClockFaces);

  // time zone select menu
  TimeZoneSelectMenu* tzMenu = (TimeZoneSelectMenu*) malloc(sizeof(TimeZoneSelectMenu));
  tzMenu = new TimeZoneSelectMenu();

  Menu** allMenus = (Menu**) calloc(3, sizeof(*allMenus));
  // initialize first layer of sub menus
  allMenus[0] = cfMenu;
  allMenus[3] = tzMenu;

  OptionsMenu* mainMenu = (OptionsMenu*) malloc(sizeof(OptionsMenu));
  mainMenu = new OptionsMenu((char**)main_menu, (size_t)MAIN_MENU_SIZE, allMenus);

  // for now, manually set the sub menu's parent to the main menu. When all menus are finished, the main menu will do this automatically
  allMenus[0]->parent = mainMenu;
  allMenus[3]->parent = mainMenu;

  ClockMenu* clk = (ClockMenu*) malloc(sizeof(ClockMenu));
  // timeClient is a global NTPClient variable
  clk = new ClockMenu(&timeClient, mainTZ, (Menu*)mainMenu);

  return clk;
}

```

All names containing `Menu` are classes derived from that base class, and the top couple of lines allocate an array of function pointers. And just to be clear: This code was working perfectly fine for the last several days of development until I made some changes to the SD card functionality that caused the constant crashes.

I am not very used to working in manual memory management. Is this way of allocating appropriate, and if so, correct? What am I doing wrong, or does the error lie somewhere else in the (~1500sloc) project?

Edit: Although the issue is already solved, thanks to the approved answer, I wanted to clarify that the constants used in the array allocation are all correct and correspond to the string array's length. E.g. main\_menu is a string array of length 5 and MAIN\_MENU\_SIZE is a constant defined right next to the array definition that is also defined to 5. This is of course necessary as C arrays have no way (that I know of) of finding the length of complex pointer arrays such as these.

# Answer
> 0 votes
You wrote:

> ```
> // funkiest malloc in the world
>
> ```

Funky, indeed. ;-) I kind of like its twisted beauty, but not everyone does. Some may urge you to `typedef` that function type.

> ```
> allClockFaces[4] = &fullDayBinaryCF;
>
> ```

Are you sure `DESIGN_MENU_SIZE` is strictly larger than 4? Maybe an `assert()` would be good to use here.

> ```
> ClockFaceSelectMenu* cfMenu = (ClockFaceSelectMenu*) malloc(...);
> cfMenu = new ClockFaceSelectMenu(...);
>
> ```

You are assigning a value to `cfMenu` twice in a row, which means the value assigned first is lost. This is a memory leak. You do not need `malloc()` here, as `new` takes care of the memory allocation prior to initializing the object. This error is repeated several times in this function.

> ```
> allMenus[3] = tzMenu;
>
> ```

`allMenus` has length 3: valid indices range from 0 to 2. This is an out-of-bounds array access, and the likely cause of the errors you see.

---
Tags: esp8266
---


# Question
Title: I'm trying to use a E18-D80NK but the output is always 1
i'm trying to use a E18-D80NK sensor with arduino but the output is always at 1, i really don't understand why This is my code :

```
int irPin2 = 8;// define pint 2 for sensor

void setup() {
  Serial.begin(9600);// setup Serial Monitor to display information
  pinMode(irPin2, INPUT);// define pin as Input  sensor
}

void loop() {
  int out = digitalRead(irPin2);// read the sensor

    Serial.println(out);

  delay(250);
 // E18-D80NK Obstacle Sensor
}

```

and circuit:

# Answer
There are a few possibilities for what is wrong:

1) The wiring may be wrong: the datasheet you reference lists two types (red,black,yellow) and (blue,brown,black) but in your pic it looks like you have (blue, grey, black). I wouldn't assume the color coding of the sensor wires are correct.

2) The "pull-up" resister mentioned in the data sheet referenced (and included schematic) is not functioning as a pull-up resistor. I would get rid of the resistor and plug the digital-output wire of the sensor directly into the arduino input. Also, try configuring the input with pull-up like: pinMode(irPin2, INPUT\_PULLUP); The Arduino inputs are high impedance and typically do not need a series resistor.
> 1 votes

# Answer
Your sensor pull low and not high, normally they pull high , I did however buy a few that is permanently on and then switch of ( pull low) when object in range.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: esp32 http client response only 200 didn't receive the data after that
i am using esp32 as a client and using following example. So here i am getting header response only that is 200. I am not getting any response after that. here is the example

```
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "yourNetworkName";
const char* password =  "yourPassword";

void setup() {

  Serial.begin(115200);
  delay(4000);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");

}

void loop() {

  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status

    HTTPClient http;

    http.begin("http://jsonplaceholder.typicode.com/comments?id=10"); //Specify the URL
    int httpCode = http.GET();                                        //Make the request

    if (httpCode > 0) { //Check for the returning code

        String payload = http.getString();
        Serial.println(httpCode);
        Serial.println(payload);
      }

    else {
      Serial.println("Error on HTTP request");
    }

    http.end(); //Free the resources
  }

  delay(10000);

}

```

given url works with me as well. but if i give other url then i am getting response as 200 only. but not receiving json data which is present on the request url.

# Answer
A 200 response doesn't guarantee that your `payload` will actually contain any data. It depends on the server. The server might determine to respond with a 200 code but still not return any JSON code for your request.

I am not at all sure, but the server may be rejecting your request because it doesn't like your user agent. I have seen my own ESP8266 supply ESP8266HTTPClient as its user agent for HTTP requests. You can see from the source code of the HttpClient class that this is the default:

```
HTTPClient::HTTPClient()
    : _client(nullptr), _userAgent(F("ESP8266HTTPClient"))
{
// etc...
}

```

You might consider setting the user agent for your http client object:

```
http.setUserAgent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0");

```

If you'd like to investigate a bit more, you might use curl from the command line (this works on linux) to emulate the http request being formulated by your ESP device:

```
curl -vA "ESP8266HTTPClient" http://jsonplaceholder.typicode.com/comments?id=10

```

On my linux machine, this returns all the HTTP header information, followed by some JSON for the url you've specified in your code:

```
[
  {
    "postId": 2,
    "id": 10,
    "name": "eaque et deleniti atque tenetur ut quo ut",
    "email": "REDACTED@EXAMPLE.COM",
    "body": "voluptate iusto quis nobis reprehenderit ipsum amet nulla\nquia quas dolores velit et non\naut quia necessitatibus\nnostrum quaerat nulla et accusamus nisi facilis"
  }
]

```

Maybe try that with the other url and see what comes out?

You might also modify your post with the Serial output of your sketch to provide more detail.
> 2 votes

---
Tags: esp8266, arduino-ide, esp32, http, iot
---


# Question
Title: I am tying to split a float variable into bytes and then re combine to the original float
Here is the code I am currently using, there have been many and various alternatives I have tried all so far without success, this being the latest incarnation sitting within my main program loop (void loop)...

```
// get temperature from Dallas Temperature Sensor
  sensors.requestTemperatures();
  sen0_data = sensors.getTempC(sensor_0_address);             // read temperature sensor0

// split float
  float f1 = sen0_data;
  byte* fb = (byte*) &f1;

  Serial.println(f1);
  Serial.println(fb[0]);    // Take a look at the bytes
  Serial.println(fb[1]);
  Serial.println(fb[2]);
  Serial.println(fb[3]);

// rebuild float
  temp = (fb[0] << 24) + (fb[1] << 16) + (fb[2] << 8) + (fb[3]);
  Serial.println(temp);

```

Now for the result as seen in the serial monitor - original float, split byte 0, byte 1, byte 2, byte 3, and finally rebuilt float. What am I doing wrong? as no doubt can be seen from the dirty coding I am a relative newbe The starting float value -127.00 is because I currently have no temperature sensor connected to the Arduino, but I would still expect the rebuilt float to be the same and not -318.00. Even if I connect a sensor the rebuilt float does not mirror the original...

```
-127.00
0
0
254
194
-318.00

```

I look forward to any advice... Regards, Simon.

# Answer
I have been told to be careful about a simple casting of non-byte variables to an array of bytes because there's no guarantee that the memory allocated for certain data types will be *contiguous*. I.e., the bytes might be spread out to non-adjacent spots in memory. For example, I was encouraged to use a union to convert a unit64\_t, which is 8 bytes, to a byte array on an ESP8266. This involves declaring a `union` type:

```
union u64_bytes {
  uint64_t u64;
  uint8_t u8[sizeof(uint64_t)];
};

```

And then you can use this to convert either way, for example:

```
  uint64_t myNum = 1;
  u64_bytes splitNum;
  splitNum.u64 = myNum;
  // now i can loop thru the bytes
  for(int i=0; i<sizeof(uint64_t); i++) {
      uint8_t myByte = splitNum.u8[i];
      Serial.print("byte ");
      Serial.print(i);
      Serial.print(" is ");
      Serial.println(myByte);
  }
  // or just refer to individual bytes
  uint8_t oneByte = splitNum.u8[0];

  // you can also take bytes and convert the other way
  u64_bytes rebuilt;
  for(int i=0; i<sizeof(splitNum); i++) {
      rebuilt.u8[i] = splitNum.u8[i];
  }

  Serial.print("The rebuilt value is ");
  Serial.println(rebuilt.u64);

```

EDIT: I added some code to show conversion the other way.

That said, it's probably pretty safe in your case to use the bitwise operators you are using. A float is in all likelihood 4 bytes on your hardware, and most hardware allocates memory these days in four-byte blocks.

HOWEVER you still have to take into account the Endianness of the system when it stores values. The basic idea is that if you have four bytes that represent one number, are the **most** significant bytes first or are the **least** significant bytes first?

For example, if you are talking about a four byte unsigned integer the number **1**, aka 0x00000001, it would be stored like this in Big-Endian hexadecimal:

```
0x00 0x00 0x00 0x01

```

But on little endian hardware (like mine) the order is different. They put the *least significant bytes first* in memory like so:

```
0x01 0x00 0x00 0x00

```

This might be very confusing, but the bottom line is you might have to think twice about what the byte order is for your data. I'd add that floats and signed integers might have some aspects that surprise you, and when you try and communicate any information over a serial line (SPI, I2C, etc.) or over a network then you might have to worry about what sort of conversions are happening. You must have to make sure that you know what order your bytes are and you unpack them in a way that's appropriate to the way you packed them.

Lastly, I would encourage you maybe think about (and possibly elaborate) what you are hoping to accomplish by taking apart a float into bytes? If you don't know about the structure of bits inside a float, you would need to get better acquainted with that before you start monkeying with the bytes inside it.

EDIT 2: here's an example where I use a struct to convert a float:

```
  union float_bytes {
    float flt;
    uint8_t u8[sizeof(float)];
  };

  float myNum = -127.0;
  float_bytes splitNum;
  splitNum.flt = myNum;
  // now i can loop thru the bytes
  for(int i=0; i<sizeof(splitNum); i++) {
      uint8_t myByte = splitNum.u8[i];
      Serial.print("byte ");
      Serial.print(i);
      Serial.print(" is ");
      Serial.println(myByte);
  }
  // or just refer to individual bytes
  uint8_t oneByte = splitNum.u8[0];

  // you can also take bytes and convert the other way
  float_bytes rebuilt;
  for(int i=0; i<sizeof(splitNum); i++) {
      rebuilt.u8[i] = splitNum.u8[i];
  }

  Serial.print("The rebuilt value is ");
  Serial.println(rebuilt.flt);

```
> 1 votes

---
Tags: float
---


# Question
Title: Can't read PWM signal from 2-pin fan header
I'm trying to get PWM values from a 2-pin fan header on DuetWifi board (it is a 3D Printer Controller Board). Here is some info about the fan connection on that board.

From their forum, I got to know that fan output is open-drain and can operate with frequency up to 65535 Hz (frequency for each fan is configurable).

First of all, I connected Duet FAN- to Arduino D7 and tried that code:

```
int pin = 7;
unsigned long duration;

void setup() {
  Serial.begin(9600);
  pinMode(pin, INPUT_PULLUP);
}

void loop() {
  duration = pulseIn(pin, HIGH);
  Serial.println(duration);
}

```

But it shows constant readings between 6-7 in Serial Monitor:

```
7
6
7
7
7
7
7
6
6
7

```

Also, any fan speed adjustment in the Duet UI doesn't affect those readings as well.

After that, I have tried a lot of different libraries and codding approaches from Arduino forum to get suitable PWM readings from FAN- pin, but have no luck.

# Answer
Your picture shows that you have only connected one line to the Arduino. You do not have a common ground between the Arduino and the fan controller. You need to connect the grounds together.

Voltage is like height, it requires two points to measure. If I point at a hill and I say, "How high is that hill?" that seems like a pretty easy question to answer at first. But it becomes ambiguous quickly. Do we want to say how high it is compared to the ground around it? Or how high from sea level? Or how high from where we are standing? You simply can't say how high a hill is unless you agree on where to measure from.

It's the same with voltage. You can't measure a voltage unless you have a potential that you can consider the 0 point to measure from. That 0 point is the ground wire. And as you have drawn the circuit the two boards don't agree on where they will consider 0 volts.
> 1 votes

---
Tags: arduino-nano, pwm
---


# Question
Title: Arduino Joystick Library not Recognized by Games (Steam)
I have an Arduino Pro Micro running code that uses the Arduino joystick library to act as a gamepad. I'm just doing testing right now so there's a single button wired up and configured in the code.

Windows recognizes the gamepad just fine and I can read button presses in the properties dialog for that controller. However the gamepad doesn't work in games that work with a usb gamepad normally (I testing using Rocket League).

I would like to get my Arduino to act just like a normal gamepad (i.e. an xbox controller).

There is lots of discussion on the internet about making custom USB devices (which is what I'm trying to do) but they never seem to get answered very well or at all. I want to achieve this on the hardware/firmware/driver side rather than having some windows application running on the computer. If I have to write firmware on the Arduino, buy a USB PID, and/or write a USB driver for the computer, I'll do whatever it takes.

# Answer
There is an Arduino Xbox 360 (XInput) library. But I do not use Steam so I have no idea if this works.

https://github.com/dmadison/ArduinoXInput
> 1 votes

---
Tags: usb, arduino-leonardo, arduino-micro, arduino-pro-micro, joystick
---


# Question
Title: Recommendations For High Capacity Microcontrollers
For a new project I'm working on, I'm turning an old Casio Personal Mini into a Speak & Spell (with possibly other functions). However, the speech library I plan on using is Talkie, and it takes up quite a bit of program space. I've been trying to look around for some microcontrollers I could use that have high program storage capacity, but I really don't know much about what I should look for, nor how to find ones that are compatible with the Arduino boot loader. Would any of you have any good suggestions? I'd probably need one with over 256KB of program storage.

# Answer
> 1 votes
In a comment, Juraj wrote:

> the ATmega MCUs are similar so a port to Arduino Mega should be possible

This seems indeed to be very much the case.

Looking at the source code of the library, it appears it uses timer 2 for generating the PWM signal and timer 1 for scheduling the samples. These timers are almost identical between the ATmega328P of the Uno and the ATmega2560 used in the Arduino Mega 2560. The only relevant difference between these boards, as far as the library is concerned, is the output pin, which is the “OC2B” pin of the microcontroller:

* on the Uno, OC2B is digital pin 3
* on the Mega, OC2B is digital pin 9

So my guess is that the library should work on the Mega with just this tiny change:

```
--- a/Talkie/talkie.cpp
+++ b/Talkie/talkie.cpp
@@ -71,7 +71,7 @@ void Talkie::say(uint8_t* addr) {
        //
        // Enable the speech system whenever say() is called.

-       pinMode(3,OUTPUT);
+       pinMode(9,OUTPUT);
        // Timer 2 set up as a 62500Hz PWM.
        //
        // The PWM 'buzz' is well above human hearing range and is

```

Also, make sure you plug your headphones on pin 9 rather than pin 3.

If you try this and it works, please report that either here or directly to the author of the library. It should then be easy to modify the library to support both boards out of the box.

---

**Edit**: If you download Talkie through the Arduino library manager, you will get this version, which does supports the Arduino Mega 2560.

---
Tags: arduino-uno
---


# Question
Title: Simple serial message not consistent (sometimes jumbled up)
I have the following code, it works (most of the time) - yet it's not 100% reliable and now and then will send through a double message on one line or 2 subsequent alpha characters:

```
const byte interruptPin0 = CONTROLLINO_IN0;
const byte interruptPin1 = CONTROLLINO_IN1;
int counter1 = 0;
int counter2 = 0;
unsigned long previousMillis = 0;
unsigned long interval = 2000;
int a = 60;
char buffer1[256];
char buffer2[256];

void setup()
{
  pinMode(interruptPin0, INPUT_PULLUP);
  pinMode(interruptPin1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin0), pin1Fired, RISING);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), pin2Fired, RISING);
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    sprintf(buffer1,"A%d",counter1);
    Serial.println(buffer1);
    sprintf(buffer2,"D%d",counter2);
    Serial.println(buffer2);
    counter1 = 0;
    counter2 = 0;
  }
}

void pin1Fired()
{
  counter1 = counter1 + 1;
}

void pin2Fired()
{
  counter2 = counter2 + 1;
}

```

Result:

This later causes a problem when my code on the other end of the serial comms expects \[LETTER\]\[NUMBER\].

What have I missed here? I'm relatively new to C for Arduino so quite possibly took a bad approach here?

I've tried to avoid sending serial comms from the interrupt, I read that was risky - hence me tracking the interrupt counts separately.

Can also confirm baud rate matches.

## EDIT

To confirm MCU resets I have printed in setup - note: no interrupts firing, still the same issue:

# Answer
Very frustrating time trying to diagnose this.

All credit to Controllino for their support when looking into whether it was a hardware/code issue (it wasn't!).

The problem turned out to be the recipient of these messages. The performance of the PC the Controllino was plugged into was really bad. I noticed what you've seen in the screenshots I've shared every time I'd open a new app or dragged a window.

The serial monitor in the Arduino IDE would lock up for a few seconds and so would miss the serial messages (and have to catch up).
> 0 votes

# Answer
My guess is that an interrupt is occurring *during* your reading or writing of the counter variables.

Since the variables are bigger than the native size of the registers in the CPU multiple instructions are required to work with them, and an interrupt can occur right in the middle of that work which changes the values it's working on. That can cause a mess (though I wouldn't expect it to make that kind of mess, TBH).

You should wrap all accesses to the counters that aren't in the interrupts inside a *critical section*. This is a segment of the code where interrupts are *not* allowed to happen. For obvious reasons you want to keep that code as short as possible.

Also in the code you have given there is no need for your buffers and sprintfs. You can just use multiple Serial.prints to achieve the same result with a much smaller code/memory footprint.

Here's an example:

```
void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;

    // Copy and reset the counter values in a critical section
    noInterrupts();
    int nowCounter1 = counter1;
    counter1 = 0;
    int nowCounter2 = counter2;
    counter2 = 0;
    interrupts();

    Serial.print("A");
    Serial.println(nowCounter1);
    Serial.print("D");
    Serial.println(nowCounter2);
  }
}

```

Also your counter variables should be `volatile` since they are accessed from both the interrupts and the main loop:

```
volatile int counter1 = 0;
volatile int counter2 = 0;

```
> 4 votes

# Answer
This is not an answer, but showing a way to make your code more clean.

Use the critical sections as proposed by Majenko.

You can rewrite

```
sprintf(buffer1,"A%d",counter1);
Serial.println(buffer1);
sprintf(buffer2,"D%d",counter2);
Serial.println(buffer2);

```

as

```
sprintf(buffer, "A%d\r\nD%d", counter1, counter2);
Serial.println(buffer);

```

Also, an unsigned long int can be maximum around 10 characters (2^32), so including the 'A', 'D', extra new line and \0, a single buffer of around 30 characters will suffice, instead of 2 buffers of 256 bytes (which takes 25% of an Arduino UNO's SRAM).

Also you can rewrite

```
counter1 = counter1 + 1;

```

as

```
counter1++;

```

which increases a variable with 1.

Also `counter1` and `counter2` should never be negative so an `unsigned` type is better.
> 0 votes

# Answer
This isn't meant to be a solution; it's more of a workaround.

To avoid repeated letters, you could use code to make sure that each alpha character isn't the same as the one before, and if so, delete the current character before printing.

Then to tackle doubling, if the string has an even number of characters, split the string in half, and if both halves are equal, remove one of them from the string.

This isn't exactly what you wanted but it's more of a worst-case scenario kind of thing.
> 0 votes

---
Tags: serial, interrupt
---


# Question
Title: Setup of Arduino Uno as ArduinoISP for programming attiny45
I have an Arduino Uno SMD and an attiny45, which I want to use as a sensor communicating via i2c. For a first step in finding out how to work with the attiny45 I just want to use the attiny as controller for a blinking led.

When first setting up the Arduino as "Arduino as ISP" some questions came up:

1. I found a lot of different information about wheter or not to use a capacitor between RESET and GND on the Arduino. Also the capacity differs between 0.1uF and 10uF. Unfornately, I found not a single comment on why this capacitor is needed (or not) and which capacities are suitable. All tutorials used electrolytic capacitors (which I only have in 100uF at hand). I have 10nF and 0.1uF at hand but only the film capacitor type. It would be brilliant if some could help me with deciding if I should use a capacitor, which one is suitable and what's the reason for using it.
2. My second question is about the clock rate I should set in the Arduino IDE. I added the board package from https://github.com/SpenceKonde/ATTinyCore to my Arduino IDE, which offers a large variety of clock rates in the tools dropdown menu. In some tutorials they mentioned that it's crucial to pick the correct clock speed to avoid wrecking the attiny. But, unfortunately, the mentioned clock speeds vary between "1 MHz (internal)" and "8 MHz (internal)". In the attiny45 datasheet (http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85\_Datasheet.pdf) I found the "Calibrated Internal Oscillator" to be the clock set up in freshly shipped chips, which I understand to operate at 8 MHz. But, the datasheet also says, that the CKDIV8 fuse is set on shipment, which leads to a clock prescale value of 8 and to a clock rate of 1 MHz. I'm highly confused... Maybe someone here can help me to find the correct clock rate to set.

I hope I didn't forget any important information. If so, please let me know.

Kind regards and thank you in advance, Matthias

# Answer
1. The capacitor is meant to prevent the programming Arduino from being reset. Normally, when you open the serial connection, the Arduino gets reset and first starts into the bootloader (which would be used to program it). But when using the Arduino as ISP programmer, you don't want to run the bootloader of the programmer. You want to let the programmer sketch work as intended. Thus you want to prevent the programmer from resetting on serial connection. The capacitor between Reset and ground holds the 5V level of the reset pin for the time, that the reset pulse from the USB Serial chip is trying to pull the pin to low. So it prevents the reset from happening.

The value and type of the capacitor is not critical here. I always use a 47uF bipolar electrolyte capacitor, because I have a bunch of them just laying around. The value just shouldn't be unreasonable small or big. The mentioned range of yours is just giving you a hint in which order the value should be. Also you can simply test, if the reset happens with your capacitor. You cannot break things with a wrong value here.
2. Which clock frequency to use is up to your exact requirements. There is no "this is the best for all occasions"-frequency. Also you are not wrecking the Attiny with any of the clock speeds. Though you should note, that choosing an external clock source means, that you actually need to provide that clock source for the ATTiny to work. The fuses can be reprogrammed, if you have chosen a wrong frequency by accident.

The datasheet states just as you wrote. The interal oscillator is by default set to 8MHz, while the prescaler divides that down to 1MHz as the main CPU clock. So by default the ATTiny runs on 1MHz. You can change that, if you like.

For my Attiny85s I always used internal 8MHz as the setting (the option, that appears in the IDE menu). That is the easiest way (internal means you need no external components for the clock), while being the fastest speed you can get with the internal clock, I think.
> 1 votes

---
Tags: attiny, arduinoisp, arduino-uno-smd
---


# Question
Title: Is there any way or command to do the double reset of the esp8266 through CODE(sketch)?
I just want to do the double reset of the ESP8266 through code (sketch) .Is there any command or function for this ?is it possible??

# Answer
There are not enough details in the question so we need to guess the goal of the project. Assuming the goal is to have alternative behaviors depending on pressing the reset button once or twice with in a given span of time.

This project at github likely uses the RTC and some of the RTC flash memory in an ESP8266 to determine if the reset button has been pressed once or twice in a given span of time.

From that project:

> PURPOSE: Detects a double reset so that an alternative start-up mode can be used. One example use is to allow re-configuration of a device's wifi.
> 0 votes

---
Tags: esp8266
---


title: Convert String to IPAddress

text:
# Question
Title: Convert String to IPAddress
How can i convert a String to IPAddress on arduino / esp ?

etc. "192.168.1.2" -\> IPAddress(192, 168, 1, 2)

Tried this

```
void setup() {

  Serial.begin(115200);

  IPAddress apip;

  const char *apipch;
  apipch = "192.168.4.1";

Serial.println(apip.fromString(apipch));

}

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

```

But i just get an output "1"

# Answer
The `IPAddress` class has a member function `bool fromString(const char *address)`.

```
const char *apipch = "192.168.4.1";
IPAddress apip;

if (apip.fromString(apipch)) { // try to parse into the IPAddress
    Serial.println(apip); // print the parsed IPAddress
} else {
    Serial.println("UnParsable IP");
}

```
> 6 votes

# Answer
You could do this:

```
String myip="192.168.1.2"
IPAddress local_IP;
bool x= local_IP.fromString(myip);

```
> 1 votes

# Answer
```
IPAddress str2IP(String str) {

    IPAddress ret( getIpBlock(0,str),getIpBlock(1,str),getIpBlock(2,str),getIpBlock(3,str) );
    return ret;

}

int getIpBlock(int index, String str) {
    char separator = '.';
    int found = 0;
    int strIndex[] = {0, -1};
    int maxIndex = str.length()-1;

    for(int i=0; i<=maxIndex && found<=index; i++){
      if(str.charAt(i)==separator || i==maxIndex){
          found++;
          strIndex[0] = strIndex[1]+1;
          strIndex[1] = (i == maxIndex) ? i+1 : i;
      }
    }

    return found>index ? str.substring(strIndex[0], strIndex[1]).toInt() : 0;
}

```
> 0 votes

# Answer
Please check the function into `IPAddress.cpp` file of line 70 :

```
bool IPAddress::fromString(const char *address) {
// TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats
....
}

```

I think you need to drop the parentheses from the `IPAdress ip()` in your code, The code should be like below :

```
Void yourMethod (const char *addr, String ipStr){

IPAdreess ip;
bool i;

i = ip.fromString(ipStr);
    if (i) {
        for (int a = 0; a < 4; a++) {
            addr[a] = ip[a];
          ....
        }
    }
}

```

Hope this helps.
> -1 votes

---
Tags: esp8266, string, esp32, convert
---


# Question
Title: Can I use a MCP23017 to connect multiple RC522 modules?
I want to connect multiple (exactly 64) RFID-RC522 modules to one Nodemcu ESP8266. I already know, that it is possible to connect multiple RC522's by just using different pins for the SDA pin, while the rest of the RC522 pins can be connected to the same pins on the ESP8266. But not that many, of course.

My research on "how do I get more pins", got me to the MCP23017 port expander. Further research is not exactly clear, if I can use these pins as ChipSelect/SlaveSelect pins for the RC522. The two libaries I found for MCP23017 (blemasle/arduino-mcp23017 and Adafruit-MCP23017 seem not to support this, when I use miguelbalboa/rfid (which I have to use, as there seems to be no alternative), because the MCP-Libs do not provide a "Pin Number" for the MFRC522 constructor(?).

So, is this just a "software" thing, or a technical limitation, and what I want is simply not possible? My research was not exactly clear about this, but I'm also very new to electronics and might be researching in the wrong direction.

# Answer
> 0 votes
Sure, you can use IO expanders for the chip-select pins of SPI devices. You *will* have to modify the device libraries to support them, though, because no one is going to do that by default unless it's a very very specific library.

However you will probably not have much luck with your project anyway, since you will more than likely run into problems with fan-out and bus capacitance before you even remotely approach 64 devices on your bus.

You would need to be adding extra bus drivers and partition your bus to reduce and spread the load - at which point it would be simpler and cheaper to just use multiple microcontrollers with just a few RC522s one each.

---
Tags: esp8266
---


# Question
Title: Displayng 2 error messages on a 16x02 display
I am trying to display on a 16x02 LCD display 2 error codes. The error message is when one or both thermocouple wires get disconnected and the second error message is when the soldering iron temp goes higher than 432 C. I am using MAX6675 module. The problem is that when I disconnect one thermocouple wire (the + or the -) sometimes the displayed message is "Overheating !!!" instead of "No tc conn !!!".

Is there any way to display the correct error ?

```
heaterTemp = thermocouple.readCelsius();
  Input = heaterTemp - 100;
   //No TC connection
  if (isnan(Input)) // No TC Connection
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("NO TC CONN !!!");
      delay(1000);
    }
  }

  //Soldering Iron overtemperature
  if (Input >= 432)
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("OVERHEATING !!!");
      delay(1000);
    }
  }

```

Edit: I finally decided to use the same message for both errors - no TC connection and overheating. I used the code below:

```
heaterTemp = thermocouple.readCelsius();
  Input = 0.779828 * heaterTemp - 10.3427;
  if (isnan(heaterTemp) or Input >= 432) // No TC Connection OR over-temperature
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      for (int i=0; i<=1; i++){
      lcd.clear();
      lcd.setCursor(0, i);
      lcd.write((byte)0);
      lcd.setCursor(1, i);
      lcd.write((byte)0);
      lcd.setCursor(5, i);
      lcd.print("ERROR!");
      lcd.setCursor(14, i);
      lcd.write((byte)0);
      lcd.setCursor(15, i);
      lcd.write((byte)0);
      delay(1000);
      }
    }
  }

```

and

```
byte thermometer[8] = //icon for termometer
{
  B00100,
  B01010,
  B01010,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110
};

```

The code displays the thermometer symbol at the beginning and at the end of the row and the text (including the symbols) are moving from one to another row.

Now it is sufficiently to display a error message when the thermocouple gets disconnected or when the iron temperature goes above 432 \*C.

I have also left the 2 while(true) loops because I need the program to stay in the loop and display the error message until I turn off the power and start again the soldering station.

# Answer
> 1 votes
I think before the disconnection is detected, it goes into overheating (maybe just for some milliseconds).

However, because there is a `while (true)` loop within the overheating part, it will never show the `NO TC CONN` error.

If you consider the `NO TC CONN` error to be higher than the `OVERHEATING` error, than check within the `while` loop of the `OVERHEATING` error also for the `NO TC CONN` error and display `NO TC CONN` when it is detected.

# Answer
> 1 votes
I'd reserve line #1 for one message, line #2 for the other

```
  heaterTemp = thermocouple.readCelsius();
  Input = heaterTemp - 100;
  lcd.clear();
  //No TC connection
  if (isnan(Input)) // No TC Connection
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      // lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("NO TC CONN !!!");
      delay(1000);
    }
  }

  //Soldering Iron overtemperature
  if (Input >= 432)
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      // lcd.clear();
      // lcd.setCursor(0, 0);
      lcd.setCursor(1, 0);
      lcd.print("OVERHEATING !!!");
      delay(1000);
    }
  }

```

# Answer
> 1 votes
According to MAX6675 datasheet page 5, it will set Bit 2 of SPI register to HIGH when the thermocouple is open. Adafruit's MAX6675 library however changed this to return a NAN when Bit 2 is set when you call the `readCelsius()` method of the library, so what you should do is to check is `isnan(heaterTemp)` instead of `innan(Input)`.

```
heaterTemp = thermocouple.readCelsius();
if (isnan(heaterTemp)) // No TC Connection
{
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("NO TC CONN !!!");
      delay(1000);
    }
}
else
{
  Input = heaterTemp - 100;
  //Soldering Iron over-temperature
  if (Input >= 432)
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("OVERHEATING !!!");
      delay(1000);
    }
  }
}

```

# Answer
> 1 votes
You should get rid of the `while(true)` loops, because when you enter one of them, you'll never get out.

```
void loop()
{
    heaterTemp = thermocouple.readCelsius();
    Input = heaterTemp - 100;

    //No TC connection
    if (isnan(Input)) // No TC Connection
    {
        digitalWrite(relay_pin, LOW);
        digitalWrite(11, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("NO TC CONN !!!");
    }

    //Soldering Iron overtemperature
    if (Input >= 432)
    {
        digitalWrite(relay_pin, LOW);
        digitalWrite(11, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("OVERHEATING !!!");
    }

    delay(1000);
}

```

EDIT: code below is needed to cut of the power

Don't know the purpose of
```
digitalWrite(relay_pin, LOW);
digitalWrite(11, LOW);

```

Maybe it's better to move these lines to `setup()`

---
Tags: arduino-nano, temperature-sensor, max6675
---


title: DH11 and uno relay controle fridge

text:
# Question
Title: DH11 and uno relay controle fridge
I want to control my bar fridge with temp sensor and relay,

This is my first project with code, i copied this: https://robojax.com/learn/arduino/?vid=robojax-DHT22\_11\_TM1637\_relay

But

I want some extra code that will prevent the fridge (ie relay) from going on too often.

For my purposes I want the relay to close if the temp is above 4c, but only if the relay has been off for say 20min or more. FYI this is because my power source does not like to start the compressor when it is hot, so i don't want it cycling if it was just on.

# Answer
> 1 votes
Cool question! ;-) Instead of a fixed timer, I would build in some (so-called) hysteresis, which means turning refrigeration on above a certain temperature (say 4 °C) but only turning off when the temperature has dropped again to a temperature well below that (say 3 °C). This ensures the temperature stays within set limits while at the same time preventing fast cycling. You don’t need any timers for this and it will work in any situation (even when it’s very hot or very cold outside of the fridge). This is how commercial thermostats work.

If you really need to ensure the compressor cools enough between cycles, you just need to start a timer when it turns off, and not turn on again before it expires. Look at examples like BlinkWithoutDelay for some coding ideas.

---
Tags: relay
---


# Question
Title: How to specify a timer's name depending on the chip it will be compiled to?
I need to enable a timer interrupt for a chip, and in the mean time, I am testing the code on Arduino Nano rather than `(feed the chip, test the chip)++`.

So as part of the code I have to `TIMSK0 |= (1 << OCIE0A);` which works great on the Arduino Nano, but has to be changed to `TIMSK` (without the 0) for the ATtiny45.

I was planning to go for something along the line of

```
#define NANO//Put // in front for the AtTiny45
#ifdef NANO
  const char in  = A0;
  const char out = 3;
  const char pwr = 10;
  char *timer = &TIMSK0;
#else
  const char in  = 3;
  const char out = 0;
  const char pwr = 1;
  char *timer = &TIMSK;
#endif
//...
*timer  |= (1 << OCIE0A);

```

So here are my three questions:

* Do #these commands take space on a chip?
* Is a pointer the way to go for this kind of things?
* Am, am I doing it right?

# Answer
> 2 votes
Just as a complement to Delta\_G's answer:

2. The names `TIMSK0`, `OCIE0A`, etc. are already preprocessor macros so, for consistency, it makes sense to define your own preprocessor macros for them. I tend to be lazy and use one of the already defined names, like

```
#ifdef TIMSK0  // support both ATtiny{25,45,85} and ATmega328P
# define TIMSK TIMSK0
#endif

```

A `const` pointer for `&TIMSK0` is fine though.
3. The macros identifying the MCU are defined to the value 1. Thus you have the choice between these three idioms:

```
#ifdef __AVR_ATtiny45__
...
#endif

#if defined(__AVR_ATtiny45__)
...
#endif

#if __AVR_ATtiny45__
...
#endif

```

The third one is convenient when you want to address several MCU models with the same code:

```
#if __AVR_ATtiny25__ || __AVR_ATtiny45__ || __AVR_ATtiny85__
...
#endif

```

---
Tags: arduino-nano, interrupt, timers, attiny, pointer
---


# Question
Title: Arduino Micro: Why am I getting 6.00 as a result instead of 6.66?
Basically, on the TWR calculator page, when I entered 20 as the initial value and 3 as the value that comes after, I somehow get 6.00 as a result instead of 6.66 in the computeTWR() function. How can I fix this?

```
// ------------------- DIVIDER ---------------------
/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 1.1
   An Open-Source Project by John Seong
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Show a two-line message on the LCD.
void lcdShow(const char *line0, const char *line1) {
  lcd.clear();
  lcd.print(line0);
  lcd.setCursor(0, 1);
  lcd.print(line1);
}

void computeTWR(int thrustR, int weightR) {
  float result = thrustR / weightR;
  lcd.print(result);
}

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcdShow("Jeb's Launch", "Control System");
  delay(3000);
  lcdShow("Alpha Build 1.1", " STUDIO HORIZON");
  delay(3000);
  lcdShow("Welcome, Kerman", "Press any key...");
  while (!keypad.getKey()) ;  // wait for key press
}

void loop() {
  static enum {START, MENU, SET_COUNT, COUNT_DOWN, SET_THRUST, SET_WEIGHT, TWR_COMPUTE} state = START;
  static uint32_t last_second;  // millis() value on last full second
  static int count, thrust, weight;             // countdown, thrust, weight value
  static float ratio;

  char key = keypad.getKey();

  switch (state) {
    case START:  // transitional state
      lcdShow("1. Countdown", "2. TWR");
      state = MENU;
    /* fallthrough */
    case MENU:
      if (key == '1') {  // Countdown
        lcdShow("Countdown Timer", "Seconds: ");
        count = 0;
        state = SET_COUNT;
      } else if (key == '2') {  // TWR
        lcdShow("TWR Calculator", "Thrust: ");
        thrust = 0, weight = 0, ratio = 0;
        state = SET_THRUST;
      }
      break;
    case SET_COUNT:
      if (key >= '0' && key <= '9' && count <= 99) {
        lcd.print(key);
        count = 10 * count + (key - '0');
      } else if (key == '#') {
        lcdShow("Lift off in", "     seconds");
        // Force a refresh on entering COUNT_DOWN:
        last_second = millis() - 1000;
        count++;
        state = COUNT_DOWN;
      } else if (key == '*') {
        state = START;
      }
      break;
    case COUNT_DOWN:
      if (millis() - last_second >= 1000) {
        last_second += 1000;
        count--;
        if (count == 0) {
          Serial.println("Lift off!");
        } else if (count < 0) {
          state = START;
          break;
        }
        lcd.setCursor(1, 1);
        lcd.print(count < 10 ? "  " : count < 100 ? " " : ""); // pad
        lcd.print(count);
      } else if (key == '*') {
        state = START;
      }
      break;
    case SET_THRUST:
      if (key >= '0' && key <= '9' && thrust <= 9999) {
        lcd.print(key);
        thrust = 10 * thrust + (key - '0');
      } else if (key == '#') {
        lcdShow("TWR Calculator", "Weight: ");
        state = SET_WEIGHT;
      } else if (key == '*') {
        state = START;
      }
      break;
    case SET_WEIGHT:
      if (key >= '0' && key <= '9' && weight <= 9999) {
        lcd.print(key);
        weight = 10 * weight + (key - '0');
      } else if (key == '#') {
        lcdShow("Thrust-to-weight", "ratio: ");
        computeTWR(thrust, weight);
      } else if (key == '*') {
        state = START;
      }
      break;
  }
}

```

# Answer
> 1 votes
(community wiki answer derived from comments - takes Q off unanswered list)

> Why am I getting 6.00 as a result instead of 6.66?

because integer arithmetic discards fractional parts of results, including intermediate results

```
static int count, thrust, weight;             // countdown, thrust, weight value

```

If some of these are intended to have decimal values you need to use a more suitable data type (e.g. `float`)

---
Tags: arduino-micro
---


# Question
Title: PubSubClient - MQTT_MAX_PACKET_SIZE How is it calculated
I'm using an ESP32, and I want to rule out a probable MQTT error. In `PubSubClient` , `MQTT_MAX_PACKET_SIZE` is set to 256. Is 256 the size for message only ? if not, what is left for message only ?

# Answer
> 3 votes
It is the maximum size of an entire packet. In `publish()` this check is done:

```
if (MQTT_MAX_PACKET_SIZE < MQTT_MAX_HEADER_SIZE + 2+strlen(topic) + plength) {

```

So the maximum length of a message payload will be

```
MQTT_MAX_PACKET_SIZE - MQTT_MAX_HEADER_SIZE - 2 - strlen(topic)

```

`MQTT_MAX_HEADER_SIZE` is defined as 5, so if you have, for example, a 20 character topic you would have `256 - 5 - 2 - 20 = 229` bytes left for your payload.

---
Tags: mqtt
---


title: Parallel servo control?

text:
# Question
Title: Parallel servo control?
I have an Arduino Nano & am success fully controlling 4 servos from it but it then occurred to me that I am controlling these in a serial manner, ie I set 1 position then the next then the next....

I would like the servos to act in a parallel manner i.e. that their motions can happen at the same time but at different speeds or different position.

Is this possible using just 1 controller (maybe some sort of polling/interrupt setup?) or will I need to run separate controllers for each set of servos & synchronize them?

EDIT: Added the PC side code & the Arduino side code

PC Python code:

```
from Tkinter import *
import serial

usbport = 'COM5'
ser = serial.Serial(usbport, 9600, timeout=1)

def init():
    for servo in range(1, 5):
        print servo
        ser.write(chr(255))
        ser.write(chr(servo))
        ser.write(chr(90))

class App:

    def __init__(self, master):

        frame = Frame(master)
        frame.pack()
        self.scale1 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(1), bd=5, bigincrement=2, length=360, width=30, label='Servo 1')
        self.scale1.set(90)
        self.scale1.pack(side=LEFT)
        self.scale2 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(2), bd=5, bigincrement=2, length=360, width=30, label='Servo 2')
        self.scale2.set(90)
        self.scale2.pack(side=LEFT)
        self.scale3 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(3), bd=5, bigincrement=2, length=360, width=30, label='Servo 3')
        self.scale3.set(90)
        self.scale3.pack(side=LEFT)
        self.scale4 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(4), bd=5, bigincrement=2, length=360, width=30, label='Servo 4')
        self.scale4.set(90)
        self.scale4.pack(side=LEFT)
        self.centre = Button(frame, text="Centre All", command=self.centre)
        self.centre.pack(side=TOP)

    def getAngle(self, slider):
        if slider==1:
            ang = self.scale1.get()
        if slider==2:
            ang = self.scale2.get()
        if slider==3:
            ang = self.scale3.get()
        if slider==4:
            ang = self.scale4.get()
        ser.write(chr(255))
        ser.write(chr(slider))
        ser.write(chr(ang))

    def centre(self):
        for servo in range(1, 5):
            ser.write(chr(255))
            ser.write(chr(servo))
            ser.write(chr(90))
        self.scale1.set(90)
        self.scale2.set(90)
        self.scale3.set(90)
        self.scale4.set(90)

init()
root = Tk()
app = App(root)
root.mainloop()

```

Arduino code

```
*
 * ------------------------------
 *   MultipleSerialServoControl
 * ------------------------------
 *
 * Uses the Arduino Serial library
 *  (http://arduino.cc/en/Reference/Serial)
 * and the Arduino Servo library
 *  (http://arduino.cc/en/Reference/Servo)
 * to control multiple servos from a PC using a USB cable.
 *
 * Dependencies:
 *   Arduino 0017 or higher
 *     (http://www.arduino.cc/en/Main/Software)
 *   Python servo.py module
 *     (http://principialabs.com/arduino-python-4-axis-servo-control/)
 *
 * Created:  23 December 2009
 * Author:   Brian D. Wendt
 *   (http://principialabs.com/)
 * Version:  1.1
 * License:  GPLv3
 *   (http://www.fsf.org/licensing/)
 *
 */

// Import the Arduino Servo library
#include <Servo.h>

// Create a Servo object for each servo
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

// Common servo setup values
int minPulse = 600;   // minimum servo position, us (microseconds)
int maxPulse = 2400;  // maximum servo position, us

// User input for servo and position
int userInput[3];    // raw input from serial buffer, 3 bytes
int startbyte;       // start byte, begin reading input
int servo;           // which servo to pulse?
int pos = 90;        // servo angle 0-180
int i;               // iterator

// LED on Pin 13 for digital on/off demo
int ledPin = 13;
int pinState = LOW;

void setup()
{
  // Attach each Servo object to a digital pin
  servo1.attach(3, minPulse, maxPulse);
  servo2.attach(4, minPulse, maxPulse);
  servo3.attach(5, minPulse, maxPulse);
  servo4.attach(9, minPulse, maxPulse);

  // LED on Pin 13 for digital on/off demo
  pinMode(ledPin, OUTPUT);

  // Open the serial connection, 9600 baud
  Serial.begin(9600);
}

void loop()
{
  // Wait for serial input (min 3 bytes in buffer)
  if (Serial.available() > 2) {
    // Read the first byte
    startbyte = Serial.read();
    // If it's really the startbyte (255) ...
    if (startbyte == 255) {
      // ... then get the next two bytes
      for (i=0;i<2;i++) {
        userInput[i] = Serial.read();
      }
      // First byte = servo to move?
      servo = userInput[0];
      // Second byte = which position?
      pos = userInput[1];
      // Packet error checking and recovery
      if (pos == 255) { servo = 255; }

      // Assign new position to appropriate servo
      switch (servo) {
        case 1:
          servo1.write(pos);    // move servo1 to 'pos'
          break;
        case 2:
          servo2.write(pos);
          break;
        case 3:
          servo3.write(pos);
          break;
        case 4:
          servo4.write(pos);
          break;

        // LED on Pin 13 for digital on/off demo
        case 99:
          if (pos == 180) {
            if (pinState == LOW) { pinState = HIGH; }
            else { pinState = LOW; }
          }
          if (pos == 0) {
            pinState = LOW;
          }
          digitalWrite(ledPin, pinState);
          break;
      }
    }
  }
}

```

# Answer
The python code is polling through the servos sequentially/serialy, but the arduino code looks parallel. The arduino will parse the string and pass the command to the servo code, passing control back to the loop() command before the servo reaches its assigned position. Maybe that is your question: "is servo.write(position) a blocking call?" If so, the answer is no, it is non-blocking, the motors will drive at the motors speed to the final positions independently. If you want coordinated movement through this scheme, you have to break the movements up and coordinate it on the python side without feedback.

For instance, if you want to go from position (90,90,90,90) to position (81,0,90,90) you will need to know it takes 900ms (for example) to complete the -90 move, and break it up into 10 segments of 100ms to coordinate the (-1,0,-10,0) steps. Doing the coordination without feedback will be awkward, and might be better handled from your python/UI side.
> 1 votes

# Answer
You can use an interpolation library and interpolate in-between as many servos as you like. The YouTube channel James Bruton does it on a lot of his robots so you can probably learn from his code. Also check out this GitHub repository:

https://github.com/luisllamasbinaburo/Arduino-Interpolation
> 0 votes

---
Tags: arduino-nano, servo
---


# Question
Title: Arduino Micro: Button inputs are not working!
I have no clue why this is happening to me but the buttons (in this case, buttonAbort and buttonStage) are not working whatsoever.

Edit: Basically the LEDs are placed right next to the button,(e.g. ledStage -\> placed next to the buttonStage) they start to blink when the timer hits zero with a buzzer noise, and if the user presses one of the buttons, the buzzer noise stops and the LED placed next to the button they pressed turns on whereas the other turns off. I also connected the buttons without resistors. (directly to the pins)

```
/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 2.00
   An Open-Source Project by John Seong
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

const int buzzer = A3;
const int ledAbort = 5;
const int ledStage = A5;
const int buttonAbort = 4;
const int buttonStage = A4;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Show a two-line message on the LCD.
void lcdShow(const char *line0, const char *line1) {
  lcd.clear();
  lcd.print(line0);
  lcd.setCursor(0, 1);
  lcd.print(line1);
}

void lcdShowResult(float result) {
  lcd.print(result);
}

void setup() {
  pinMode(buzzer, OUTPUT);
  pinMode(ledAbort, OUTPUT);
  pinMode(ledStage, OUTPUT);
  pinMode(buttonAbort, INPUT_PULLUP);
  pinMode(buttonStage, INPUT_PULLUP);

  Serial.begin(9600);
  lcd.begin(16, 2);
  while (!keypad.getKey()) ;  // wait for key press
}

void loop() {
  static enum {START, MENU, SET_COUNT, COUNT_DOWN, LAUNCH, SET_THRUST, SET_WEIGHT} state = START;
  static uint32_t last_second;  // millis() value on last full second
  static int count;
  static float thrust, weight, ratio;

  int stageConfirm = digitalRead(buttonStage);
  int abortConfirm = digitalRead(buttonAbort);

  char key = keypad.getKey();

  switch (state) {
    case START:  // transitional state
      lcdShow("1. LAUNCH SEQ", "2. TWR CALC");
      state = MENU;
    /* fallthrough */

    case MENU:
      if (key == '1') {  // Countdown
        lcdShow("COUNTDOWN TIMER", "SECONDS: ");
        count = 0;
        state = SET_COUNT;
      } else if (key == '2') {  // TWR
        lcdShow("TWR CALCULATOR", "THRUST: ");
        thrust = 0, weight = 0, ratio = 0;
        state = SET_THRUST;
      }
      break;

    case SET_COUNT:
      if (key >= '0' && key <= '9' && count <= 99) {
        lcd.print(key);
        count = 10 * count + (key - '0');
      } else if (key == '#') {
        lcdShow("    T-MINUS", "     SECONDS");
        // Force a refresh on entering COUNT_DOWN:
        last_second = millis() - 1000;
        count++;
        state = COUNT_DOWN;
      } else if (key == '*') {
        state = START;
      }
      break;

    case COUNT_DOWN:
      if (millis() - last_second >= 1000) {
        last_second += 1000;
        count--;
        if (count <= 10) {
          tone(buzzer, 500);
          delay(500);
          noTone(buzzer);
        }
        if (count == 0) {
          Serial.println("Lift off!");
        } else if (count < 0) {
          state = LAUNCH;
          break;
        }
        lcd.setCursor(1, 1);
        lcd.print(count < 10 ? "  " : count < 100 ? " " : ""); // pad
        lcd.print(count);
      } else if (key == '*') {
        state = START;
      }
      break;

    case LAUNCH:
      tone(buzzer, 3000);
      digitalWrite(ledAbort, HIGH);
      digitalWrite(ledStage, HIGH);
      lcdShow(" T-ZERO WARNING", "CONFIRM IGNITION");
      delay(1000);
      lcd.clear();
      digitalWrite(ledAbort, LOW);
      digitalWrite(ledStage, LOW);
      delay(500);

      stageConfirm = digitalRead(buttonStage);
      abortConfirm = digitalRead(buttonAbort);

      if (stageConfirm == LOW) {
        noTone(buzzer);
        digitalWrite(ledStage, HIGH);
        digitalWrite(ledAbort, LOW);
        lcdShow("  LIFT OFF", "HAVE A SAFE FLIGHT");
        break;

      } else if (abortConfirm == LOW) {

        break;
      }
      Serial.println(stageConfirm);
      Serial.println(abortConfirm);

      break;

    case SET_THRUST:
      if (key >= '0' && key <= '9' && thrust <= 9999) {
        lcd.print(key);
        thrust = 10 * thrust + (key - '0');
      } else if (key == '#') {
        lcdShow("TWR CALCULATOR", "WEIGHT: ");
        state = SET_WEIGHT;
      } else if (key == '*') {
        state = START;
      }
      break;

    case SET_WEIGHT:
      if (key >= '0' && key <= '9' && weight <= 9999) {
        lcd.print(key);
        weight = 10 * weight + (key - '0');
      } else if (key == '#') {
        lcdShow("THRUST-TO-WEIGHT", "RATIO: ");
        if (thrust != 0 || weight != 0) {
          ratio = thrust / weight;
          lcdShowResult(ratio);
        }
      } else if (key == '*') {
        state = START;
      }
      break;
  }
}

```

# Answer
> 0 votes
This code is reading the buttons at two places in `loop()`, but the first time the results are ignored. Only the readings done in the LAUNCH state can have any effect. The problem is that the reading is done only at one very specific time, 1.5 seconds after displaying “CONFIRM IGNITION”. If you press the button before or after this moment, it has no effect.

Reading only once per loop iteration is fine, as long as the loop turns fast enough, without getting stuck in a `delay()`. As a general rule, you try to avoid `delay()` whenever you want to write a program that should react to external events such as button presses. See the Arduino example Blink without delay for a technique for achieving that. A *finite state machine* is a good way to program without delays, and fortunately you are already working with one. To detect a button press, you typically use two distinct states:

* a “wait for button press” state that is sensitive to the button
* a “button has been pressed” state that is reached when the user presses the button.

There can be multiple “button pressed” states if there are multiple buttons to wait for. The transition from the “waiting” state to the others is then conditioned on the button presses:

```
case WAIT_FOR_BUTTON_PRESS:
    if (digitalRead(button_1_pin) == LOW) {
        do_the_action_relevant_to_button_1();
        state = BUTTON_1_HAS_BEEN_PRESSED;
    } else if (digitalRead(button_2_pin) == LOW) {
        do_the_action_relevant_to_button_2();
        state = BUTTON_2_HAS_BEEN_PRESSED;
    }
    break;

```

Obviously you would choose state names that are more relevant for your specific project.

---
Tags: arduino-micro
---


title: .toFloat() giving incorrect anwsers

text:
# Question
Title: .toFloat() giving incorrect anwsers
I am broadcasting a fixed value float over a HC-12 radio which is then received by another HC-12 radio. I am then trying to convert that String to a Float which requires 6 decimal places. However, when I print the String value out and then the Float value out, I get two different answers.

Code:

```
    String lat=getValue(_msg, '|', 6); // Function to get lat value from incoming message
    Serial.println(lat);
    Serial.println(lat.toFloat(), 6);

```

This then results in the following values being displayed to the user:

```
51.507401
51.507396

```

The value 51.507401 is the correct value, so I would ideally like the float value to be the same.

# Answer
It seems the `toFloat()` method is being a bit sloppy in its conversion. The float closest to 51.507401 is 51.5074005126953125, which is only 0.13 ulps off. The number you got is the float right before it, namely 51.507396697998046875, which is 1.13 ulps off. Alas, the avr-libc functions `atof()` and `strtod()` make the same error.

I would suggest first considering whether the error is really significant for your application: it is only about 48 cm on the surface of the Earth. If this level of accuracy is relevant for you, then follow Majenko's suggestion and use an integer count of microdegrees.
> 2 votes

---
Tags: string, float
---


# Question
Title: How do I set up an Arduino to be a wireless HID?
The question below describes how to set up an Arduino as an HID (Human Input Device -- like a keyboard, mouse, etc.). How can I set up an Arduino as a wireless HID?

I'm flexible as to the wireless format. Bluetooth, USB receiver, or any other format is acceptable.

Arduino as USB HID

# Answer
> 2 votes
I'm not sure for Arduino, but it has been done with ESP32. If you have not yet spent the money into a Bluetooth module for Arduino, you'll find that the ESP32 is not expensive either.

You can find the code on Github. The author uses a TinyPico because it's pin compatible with one of his earlier projects. IMHO, any ESP32 should do as well.

The key thing is to

```
#include <BleKeyboard.h>

```

the ESP32 BLE Keyboard library that you need to download and install. That library comes with example code that should be easy to adapt to your needs.

You can program the ESP32 in Arduino IDE, but you need to add support for the boards by adding a URL to the board manager.

Have fun with the project. It sounds very interesting. Maybe I try that myself.

---
Tags: wireless, hid
---


# Question
Title: Is there a variable type of half byte? Is there a workaround?
I have this long array of 64 values going from 0 to 15, values which only cost 8 bits, for a pulse width modulation.

So I made a test to see its cost in space, commenting one of the two arrays.

```
const byte wave[64] = {8,9,9,10,11,11,12,12,13,13,14,14,14,15,15,15,15,15,15,15,14,14,14,13,13,12,12,11,11,10,9,9,8,7,7,6,5,5,4,4,3,3,2,2,2,1,1,1,1,1,1,1,2,2,2,3,3,4,4,5,5,6,7,7};
//const byte wave[2] = {8,9};
byte i = 0;
void setup() {pinMode(1,OUTPUT);}
void loop() {            //(Don't worry about the code in here,
  analogWrite(1,wave[i]);//it's just to get the program
  i++;delay(1);          //to hold on to the data)
}

```

The compiler said `Sketch uses 1112` and `1050 bytes (3%) of program storage space.` or a difference of 62 bytes.

This tells me that one could save a lot of memory by keeping them in a 4-bit or what I'd like to call half byte, going from `0` to `f` rather than from `00` to `ff`.

How could I do so without turning the code to unreadable bit mush?

# Answer
> 1 votes
Keeping your 4-bit values in half-bytes is doable using structs and bitfields. You'll want an access function to separate the "array index" into a byte-index and a nibble selector (the LSb of the "array index") and return or store the appropriate nibble.

This related question on StackOverflow has some answers showing ways to do this. There will be obviously be some overhead to unpacking 4-bit nibbles since they can't be addressed directly, but it will be minor and is the trade-off for saving memory when memory is scarce.

# Answer
> 2 votes
If the point is to save program storage space, you're probably going to have to live with some unreadable bit mush or do bit-swapping in your head. Here's a code example that encodes your same array as a 32-byte array, but you have to combine pairs of your original numbers into bytes. It's not especially difficult because each hex digit represents one of your original numbers.

I.e., `8,9` becomes `0x89`. Likewise, A is 10, B is 11, etc. Then you can iterate 1 thru 64 and do some division and bit-shifting to pull out the original value you wanted. This will iterate through your 32-byte array and pull out 64 half-byte values.

```
    const byte wave[32] = {0x89,0x9A,0xBB,0xCC,0xDD,0xEE,0xEF,0xFF,0xFF,0xFF,0xEE,0xED,0xDC,0xCB,0xBA,0x99,0x87,0x76,0x55,0x44,0x33,0x22,0x21,0x11,0x11,0x11,0x22,0x23,0x34,0x45,0x56,0x77};
    for(int i=0; i<64; i++) {
        byte val;
        if (i % 2) {
            // the little byte is first (LITTLE ENDIAN)
            val = wave[i/2] & 0x0F;
        } else {
            // the BIG byte is second
            val = (wave[i/2] >> 4) & 0x0F;
        }
        Serial.printf("%i=%i\n", i, val);
    }

```

NOTE: that the Endianness if your system may be different than mine. Most systems are little-endian these days, but you never know.

---
Tags: code-optimization, bytes
---


# Question
Title: Using Arduino to control a high voltage DC device
I am an amateur hobby electronics enthusiast , and given the situation , I too am trying to make a contactless hand Sanitizing system like everyone else. My project requires a 36V DC solenoid valve to be actuated through the arduino momentarily for the sanitizer to drop. Obviously I will be using a relay module to electrically isolate both the circuits. But I don't have a 36 V DC adapter . So what is the best way to power up the solenoid valve? Batteries are available to me right now? How do I calculate how many 9v batteries do I need ? How many AH would they require ? Would they get drained too fast?

# Answer
Batteries are going to be annoying because they're run out and have to be recharged/replaced. A mains power supply would be easier to "set and forget.

I did a google search on "36V DC power supply" and found a 4A power supply from "Alitove" on Amazon for $22.99 US. That should be fine. (Assuming you are somewhere with 120VAC mains power. If you live somewhere with 240VAC mains power you would need a different unit, but since I found one, I would expect a google search in your region would find one for your area.)

I would suggest using a logic-level MOSFET transistor + flyback diode to switch your DC power. That's easier to do than a relay (That would require another power supply.)
> 1 votes

---
Tags: arduino-uno, relay
---


# Question
Title: Can I have backup power for an Arduino device?
I have an arduino project that will work while plugged into a generic outlet. But I want to connect a battery in case the power goes out. I know there are various power sources (coin cell, polymer lithium, 9V, etc.). But if I code my project to use the backup power if the main power goes down, would that mean the backup always has to be running? How would I go about this?

Thanks for the help! Every time you help me you save a kitten!!

# Answer
> 4 votes
You could set up a relay to work in reverse with the mains power.

Have your backup battery connected to the gate contacts of the relay, and then use the mains power running your project to open the relay and keep it open as long as there is power. If the mains turns off, then the relay closes and the battery is connected.

You might want to put something in line with the power to the Arduino to make sure you don't get any spikes when things switch.

I hope this helps as I love kittens

# Answer
> 2 votes
I have been looking into this myself. After getting some advice online I have come up with this circuit :

http://everycircuit.com/circuit/5059191601364992

The top left power source is the mains supply and the bottom left is the battery.

A voltage divider is connected to both that then feeds into an OPAMP comparator. For illustrative purposes there is a switch at the top left you can toggle to see the circuit in action.

When the mains power gets cut off the op amp comparator sends a logic level signal through the diode and into the mosfet which enables the battery circuit. the capacitor is there to keep power while the comparator makes the switch.

The link on every circuit is interactive, so feel free to have a play about with it. The LED represents your Arduino. The OpAmp is powered by the Positive and negative rails of thi diagram (impossible to draw on EveryCircuit)

Be sure to attach a voltage regulator to this circuit (at the input of the Arduino) so that the voltage doesn't change to your Arduino.

Here's where I researched about comparator OPAMPS ... Setting up a comparator OpAmp circuit

The LM358 is a good very cheap OPAMP for this circuit. All parts well sourced will cost you about £1 (or less).

Or if your battery is rechargeable you can try this circuit :

http://everycircuit.com/circuit/5232232327282688

Again this is just for illustrative purposes. You will need a 5V step-up converter to get 5v from a 3.7v battery. Also the battery I am using has a builtin protection circuit, if yours doesn't it's important you include it in your schematic.

**Here's a video of it working for me with a 3.7V Li-Polymer Battery:** https://www.youtube.com/watch?v=Sv2rjVqQg3U

# Answer
> 2 votes
I suggest this "Battery boost" circuit from AdaFruit. It's designed to do exactly what you describe. An Arduino needs a smooth, steady 5 V supply with no "blips". The AdaFruit unit does just that, and charges the battery while on Mains supply.

# Answer
> 0 votes
You could solve this very simply with some diodes or get creative with a bridge rectifier. Connect both positive sources to the ac input one on each leg. then the positive side of the bridge rectifier would be your positive source. the grounds need to be all tied together

# Answer
> 0 votes
You can use https://www.regaldreamtech.com/micro-ups/ for the backup 5V power supply to Arduino in absence of main power. It has 5000mAh battery and 5V 2A output. It will handle the switching on its on between main and battery power.

Disclosure: We manufacture this product.

---
Tags: power, battery
---


# Question
Title: How to make Serial.read() return an integer instead of an ascii value?
I want Serial.read() to return an integer instead of an ASCII value. For example, in the below code if I input 2, I want the output as 2 instead of 50

```
void setup(){
    Serial.begin();
}

void loop(){
    if(Serial.available()){
    int t = Serial.read();
    Serial.println(t);
}

```

# Answer
If it's a single digit:

```
if (t >= '0' && t <= '9') {
    int numeric_value = t - '0';
} else {
    // Handle the input error.
}

```
> 1 votes

# Answer
You can use an alternate method like this

```
void setup()
{
Serial.begin(9600);
}
void loop()
{
 if(Serial.available()){
    String a = Serial.read();
    int b = a.toInt();
    Serial.println(b);
}

```
> 1 votes

---
Tags: arduino-uno, serial
---