# Question
Title: How can I assign a variable to a function output in Arduino?
I'm trying to assign the output of my function (which adjusts a DAC output) to a variable so I can print and display it in my serial monitor. Here's the code

```
#include <Wire.h>
#include <Adafruit_MCP4725.h>

Adafruit_MCP4725 dac;

int volza;

void setup() {
  Serial.begin(38400);
  Serial.println("Hello!");
  dac.begin(0x60);
}

void loop() {
    volza = dac.setVoltage(1095, 1); // THIS IS THE PROBLEM
    Serial.println(volza);
}

```

I am receiving an error because of the commented line. I think it's because I am trying to return a value while inside a void loop. How do you fix this?

# Answer
> 1 votes
The `setVoltage` method has the following prototype:

```
void setVoltage( uint16_t output, bool writeEEPROM );

```

This means it does not return a value.

If you expect to return 1095, why not write:

```
volza = 1095;
setVoltage(volza, 1);
Serial.println(volza);

```

Some background information:

Assume you want to have the library a `getVoltage` method, than this is possible (you have to make a copy in your own project of the file and add the method. However, I'm not sure how easy it is to get the value from the EEPROM. If it is not easy, there is some programming work to do. Another solution is to store the value in memory, but that means some extra bytes from the scarce free SRAM. Also, in theory the content could be changed already (if another MCU would have access to the EEPROM too).

---
Tags: arduino-ide, c++, loop
---


# Question
Title: Sizes of the original ESP32-DevKitC-32U Wifi board
I know that this topic does not apply to Arduino, but for me it is important to find a solution to the problem. I know the consequences.

I'm creating a pcb board into which the original ESP32-DevKitC-32U module will be inserted. I can not find the original dimensions of the board, in particular the distance between the contact rails. The site espressif has a small description.

27.9mm is indicated here. It is not clear to me, is this the full width of the board or the distance between the contacts?

What I want to do:

It is very important for me to find out the correct dimensions of the original board. Maybe someone has such a board and can measure this size?

# Answer
> 2 votes
The distance of the headers is breadboard and perfboard compatible for 0.1" (2.54 mm) pin standard. 25.4 mm is 10 rows.

# Answer
> 0 votes
I am taking a class and the instructor used a DEVKITC V4, which on a standard breadboard, plugged into columns b and i. The DEVKITC that I ordered from Mouser plugs into columns b and j. So one is a pin-to pin width of 25.4 mm and the other is 27.9 mm. It seems that the newer DEVKITC V4 is 27.9 and is very difficult to work with on standard breadboard. PITA!

---
Tags: esp32, pcb-design
---


title: How does WiFiServer.status() work?

text:
# Question
Title: How does WiFiServer.status() work?
What are the possible outcomes of calling `status()` on a `WiFiServer` from `ESP8266WiFi.h`? The only documentation I could find only says it returns `uint8_t`. Here's the link.

# Answer
> 0 votes
The basic set of functions of the esp8266 WiFi object follows the API of the Arduino's first WiFi library for Arduino WiFi Shield. It is documented here.

The esp8266 implementation of status() focuses on state of the STA and maps SDK status to some of Arduino documented codes.

```
wl_status_t ESP8266WiFiSTAClass::status() {
    station_status_t status = wifi_station_get_connect_status();

    switch(status) {
        case STATION_GOT_IP:
            return WL_CONNECTED;
        case STATION_NO_AP_FOUND:
            return WL_NO_SSID_AVAIL;
        case STATION_CONNECT_FAIL:
        case STATION_WRONG_PASSWORD:
            return WL_CONNECT_FAILED;
        case STATION_IDLE:
            return WL_IDLE_STATUS;
        default:
            return WL_DISCONNECTED;
    }
}

```

---
Tags: esp8266, wifi
---


# Question
Title: Is it possible to transmit radio signal with cheap 433Mhz transmitter as strings and receive it with an RTL-SDR
I have these Arduino transmitters and receivers.

They are very common. I am just trying to transmit a "Hello" Message using this code.

```
#include <RH_ASK.h>
#ifdef RH_HAVE_HARDWARE_SPI
#include <SPI.h> // Not actually used but needed to compile
#endif

RH_ASK driver;
// RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2
// RH_ASK driver(2000, 3, 4, 0); // ATTiny, RX on D3 (pin 2 on attiny85) TX on D4 (pin 3 on attiny85),

void setup()
{
#ifdef RH_HAVE_SERIAL
    Serial.begin(9600);   // Debugging only
#endif
    if (!driver.init())
#ifdef RH_HAVE_SERIAL
         Serial.println("init failed");
#else
    ;
#endif
}

void loop()
{
    const char *msg = "hello";

    driver.send((uint8_t *)msg, strlen(msg));
    driver.waitPacketSent();
    delay(200);
}

```

But they have to be received from the receiver module using another set of codes which I have done it.

But my question is, is it possible to receive the transmitted message with one of RTL-SDR's INSTEAD of using the receiver module? If so, How to do it?

# Answer
In general you can use RTL-SDR to decode any AM and FM modulated signals (+some digital modulations) that lie within the frequency range form roughly 50MHz to about 1GHz. So 433MHz is confortably within that range.

There are many projects on GitHub that leverage the RTL-SDRs ability to decote 433MHz OOK modulated signals like:

RTL\_433
Which comes with a ton of decoders for various appliances.

OOK\_Decoder
Which will give you the demodulated raw output for you to decode the bits yourself.

I'm sure you will find more but those are in my opinion the most noteworthy for the 433MHz OOK space.
> 1 votes

---
Tags: arduino-uno, wireless, rf, software
---


# Question
Title: Why does SoftwareSerial::read() return int?
The documentation on Arduino's website shows `SoftwareSerial::read()` as returning a `char`. (link)

The header shows that the method returns an `int`. (link)

The cpp definition shows `SoftwareSerial::read()` returning the value from a buffer array of `uint8_t` values. (link)

Given all of this:

1. Why would the interface return an `int` instead of a `uint8_t`?
2. Why do the Arduino docs show it as returning a `char`?
3. Is it safe to send/receive 8-bits at a time using this library?

For (3) I'm using an HC-06 if that matters.

# Answer
1. You'll see in the code just above your third link that the function can return a value of `-1` if there is no data present. Thus a 16-bit value is used to cover the range of 8-bit `uint8_t`s, plus one extra value to show 'no valid data available'.
2. For simplicity, I guess.
3. Yes. This is what it's designed for.

In short, for all intents and purposes, only an 8-bit value is returned, but if you were to read into an `int`, you couldn't differentiate between a valid and invalid value.
> 3 votes

# Answer
> The documentation on Arduino's website shows SoftwareSerial::read() as returning a char.

No it doesn't. There is nothing in the documentation that tells you the return type. There is only an example where the returned value is assigned to a `char` variable. That doesn't mean that it returns a char - it just means that whatever data type it does return can be invisibly cast to a `char` by the compiler.

> The header shows that the method returns an int.

Indeed it does. That is because that is what it returns.

> The cpp definition shows SoftwareSerial::read() returning the value from a buffer array of uint8\_t values.

Yes, because the valid data that it deals with is 8 bits in size. Just because it handles 8 bit "valid" data doesn't mean that that's *all* it ever wants to return. The "no data available" return value of -1 is obviously not something that is stored in the data. It's a status, not data.

---

> Why would the interface return an int instead of a uint8\_t?

Because a `uint8_t` cannot encompass all the functionality stated in the "Returns" section:

> the character read, or -1 if none is available

You can't return -1 in a `uint8_t`.

> Why do the Arduino docs show it as returning a char?

It doesn't - as I mentioned above. It makes no claims at all about the returned data type.

> Is it safe to send/receive 8-bits at a time using this library?

Yes. It performs serial data transfers using 8-N-1 by default. That's 8 data bits, no parity, and one stop bit.

---

It's this kind of confusion with return types and bytes and integers and things that make people ask why they keep getting ÿÿÿÿÿÿ on the serial monitor. That's -1 cast as a char. I.e., "no data available" but they ignore that and treat everything returned as a `char` \- most probably because the Arduino documentation shows an overly simplified example that ignores the possibility of a -1 being returned and treats everything as a `char`.

IMHO much of the Arduino documentation is somewhat sub-par and should not be taken literally - only as a rough guide for what is available. The same goes for much of their example code and projects.
> 4 votes

# Answer
Stream declares `read` as returning `int` (look in `hardware/arduino/avr/cores/arduino/Stream.h`). `SofrtwareSerial` inherits from `Stream`, so they have to override that declaration, otherwise there would be two `read()` methods, one returning `int` and one returning `uint8_t`. Since `SoftwareSerial::read()` would onlyreturn an `int` between 0 and 255, which would fit in a `uint8_t`, there is no problem.

As for the Arduino docs, you get what you pay for :)
> 0 votes

---
Tags: softwareserial, hc-06
---


title: Memory size issue with the struct

text:
# Question
Title: Memory size issue with the struct
I am working on a project where I have to build an IR program that works with all of the AVR/Arduino boards to control the IR devices such as TV, DVD, etc. I am building a struct that can carry the Pronto code information and this is what I have so far:

```
struct Pronto {
    char* code;
public:
    Pronto(){}
    Pronto(char* code) {
        bool isValid = validateProntoCode(code);
        if(isValid)
            this->code = code;
    }
    Pronto toPronto(char* code) {
        Pronto cde(code);
        return cde;
    }
    void setPronto(char* code){
        bool isValid = validateProntoCode(code);
        if(isValid)
            this->code = code;
    }
    char* toString(){
        return code;
    }
    private:
    bool validateProntoCode(char* code) {
        if(!isInHex(code[strlen(code)-1]))
            return false;
        for (int i = 0; i < strlen(code); i++) {
            if (!isInHex(code[i]) && !(i % 5 == 4 ))
                return false;
            if (i % 5 == 4 && code[i] != ' ')
                return false;
            if (i % 5 == 0 && (!isInHex(code[i]) || !isInHex(code[i] + 1) || !isInHex(code[i] + 2) || !isInHex(code[i + 3])))
                return false;
        }
        return true;
    }
    bool isInHex(char c) {
        char list[22] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'};
        for (int i = 0; i < 22; i++) {
            if (c == list[i])
                return true;
        }
        return false;
    }
};

```

This struct code I can set the Pronto code, validate it, and get the string value from it. Now, whenever I declare the struct inside the Arduino IDE:

```
pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");

```

I get this following message:

---

Sketch uses 4082 bytes (12%) of program storage space. Maximum is 32256 bytes.

Global variables use 2137 bytes (104%) of dynamic memory, leaving -89 bytes for local variables. Maximum is 2048 bytes.

Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.

---

Pictures:

https://prnt.sc/ohu4d9

https://prnt.sc/ohu4io

https://prnt.sc/ohu4m8

https://prnt.sc/ohu4pr

https://prnt.sc/ohu4tn

Basically, I just showed all my work on code I did. I commented out any global vars, nothing changed. BUT, when I comment "pronto.setPronto("0000 0000");", I get free space.

---

So, how can I modify this struct in-order for it not to take allot of space?

---

The char\* code right? That's the problem. Now can you help me modify code or at least tell me how I can resolve this.

# Answer
> 1 votes
In your screen shots you are using string literals that are waaaay longer than in your sample code. I suspect using PROGMEM could be a way to work around. But why bothering with constant strings and verify and convert them at run time and not store them as raw data instead? (Also the outcome of the verification for a constant string literal will be always the same. So consider removing verification of your production code.)

```
uint16_t myParsedProntoCode[] = {
    0x0000, 0x006D, 0x0000, 0x00BF, 0x009F, 0x0031, 0x0030, 0x0010, 0x0010, 0x0031
};

```

This is much more space efficient as storing a nibble (4 bits) requires only 4 bits instead of 8 bits. So just half the space, not even taking the pointless whitespaces into account.

# Answer
> 0 votes
Based on your question I prepared a fresh sketch (single file) to test the issue.

The code:

```
struct Pronto {
    char* code;
  public:
    Pronto() {}
    Pronto(char* code) {
      bool isValid = validateProntoCode(code);
      if (isValid)
        this->code = code;
    }
    Pronto toPronto(char* code) {
      Pronto cde(code);
      return cde;
    }
    void setPronto(char* code) {
      bool isValid = validateProntoCode(code);
      if (isValid)
        this->code = code;
    }
    char* toString() {
      return code;
    }
  private:
    bool validateProntoCode(char* code) {
      if (!isInHex(code[strlen(code) - 1]))
        return false;
      for (int i = 0; i < strlen(code); i++) {
        if (!isInHex(code[i]) && !(i % 5 == 4 ))
          return false;
        if (i % 5 == 4 && code[i] != ' ')
          return false;
        if (i % 5 == 0 && (!isInHex(code[i]) || !isInHex(code[i] + 1) || !isInHex(code[i] + 2) || !isInHex(code[i + 3])))
          return false;
      }
      return true;
    }
    bool isInHex(char c) {
      char list[22] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'};
      for (int i = 0; i < 22; i++) {
        if (c == list[i])
          return true;
      }
      return false;
    }
};

Pronto pronto;

void setup() {
  pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");
}

void loop() {}

```

The verification procedure for ATmega328P returns:

```
D:\Extra\Arduino\BatteryRestorer\BatteryRestorer.ino: In function 'void setup()':

D:\Extra\Arduino\BatteryRestorer\BatteryRestorer.ino:50:71: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

   pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");

                                                                       ^
Sketch uses 844 bytes (2%) of program storage space. Maximum is 30720 bytes.
Global variables use 83 bytes (4%) of dynamic memory, leaving 1965 bytes for local variables. Maximum is 2048 bytes.

```

Can you check if this one file sketch is still experiencing the issue? Maybe you installed and linked a library that allocates a lot of global variables.

---
Tags: infrared, struct, sketch-size
---


title: How to read distance of passing object?

text:
# Question
Title: How to read distance of passing object?
Ok, guys this is my first post and I am new to Arduino but somewhat familiar with programming so I hope you guys can assist me. If any of this is confusing, I apologize in advance! :)

I want to be able to utilize a TOF sensor that will be stationary to capture the distance of a passing object at a certain moment after it is first detected, because it is round. So I wanted to use a photoelectric switch, so when the object would pass, it would send the signal to the TOF sensor to read the distance 17ms after that moment.(I've done the math, and the delay to be in the center(closest edge to the sensor of solid ball) of the object passing would take 17ms) Then I would like to have that distance be displayed onto a LCD screen, until the next object passes and the process repeats....Think of a conveyor belt with a basketball on it. The basketball would be moving and pass the sensor, but the distance to the center(closest edge to the sensor)of the ball would be measured at a certain moment and displayed until the next ball passes.

The next problem is that the distance needs to be converted to a "zone" So like between 10-12cm, it would = 2. 12.1-14 would be 3 etc... The last part is probably the easiest but, I have no idea where to start...I appreciate all who helps!

I was needing help with the code to make this work with the Arduino uno. The tof sensor is VL53L1X and E-931-S35RRQ photoelectric sensor. And the LCD will be a 7 segment display so as long as it’s programmed for that I can change out sizes later..

# Answer
So break this into parts and solve each part separately. First, figure out how to interface the photoelectric sensor. First just write a loop() that waits for the state change when the sensor trips.

To get accurate timing you'll probably want to respond to the photoelectric sensor with an interrupt service routine that starts a timer. Get that working next.

Then figure out how to interface with your ToF sensor. When I googled it I found the bare sensor as well as versions on PC boards with an I2C interface. You may be able to find somebody's library that interfaces with the sensor. Get that working so you can take readings from the TOF sensor.

Then figure out how to drive the 7-segment display. Just write code that displays the values from 0-9 for 1 second each using a delay.

Once you've got all the pieces working separately, it's time to map out the logic if your program and make it work. Take a look at the "arduino blink without delay" example for how to write code that handles timed responses without using the `delay()` function.
> 0 votes

# Answer
The sensor has a 50Hz ranging frequency; depending on the speed of the balls passing the measuring section, you may only need to wait for ranges of less than (whatever passes for inifinity in your setup) and then track the ranges until they hit a minimum, save that value, and there's your first answer. This saves a detector and has the additional virtue of being independent of the speed of the traveling ball (up to a resolution limited by the sensor's measuring frequency & your precision requirements).

The second part just needs a few `ifs`, such as:

```
if( range < 10.0 ){
  zone = 1;   // or whatever else you need to do here
}
else if( range < 12.0 ){
  zone = 2;
}
else {
  zone = 3;   // anywhere else
}

```
> 0 votes

---
Tags: arduino-uno, programming, lcd
---


title: Restart variable every day

text:
# Question
Title: Restart variable every day
How can I restart a variable every day? I have an RTC1307. The problem is that I can't use an alarm event because the Arduino will be shut down during that hour. So I need a more reliable solution.

Will this work? A date could be an integer?

```
#include <EEPROM.h>
#include "RTClib.h"

int  lastDay;
int EE_ADDR = 0;
int totalLitres;

void setup() {
  EEPROM.get(EE_ADDR, lastDay);
}

void loop() {
DateTime now;
  if (now.day() != lastDay) // this happens exactly once a day.
    totalLitres = 0; // reset the accumulated volume

  lastDay = now.day();
}

```

# Answer
Here are a few suggestions:

* Since your RTC has some non-volatile RAM (NVRAM) onboard, you could use it instead of the EEPROM. This way you will not have to worry about the EEPROM endurance.
* If there is the possibility that the device gets power-cycled within a single day, you probably want it to preserve the liter count. This can be achieved by periodically saving this count to the NVRAM, and restoring it at startup. You can save often, as you don't have endurance limits.
* If the device is started after a full month of being off, if should notice some days have passed, even it the day number is the same as when it was turned off. Instead of saving just the day number, I would store the total number of days elapsed since 2000 Jan 1.

Untested implementation of the above suggestions:

```
#include <Wire.h>
#include <RTClib.h>

const uint32_t NVRAM_UPDATE_PERIOD = 10000;  // 10 seconds

/* Addresses for data items saved in the RTC's NVRAM. */
const uint8_t ADDRESS_LITERS    = 0x00;
const uint8_t ADDRESS_RESET_DAY = 0x02;

RTC_DS1307 rtc;
uint16_t liters;
uint16_t reset_day;

/*
 * If `liters' has not been reset today, reset it now and update both
 * the RAM and NVRAM copies of `reset_day'.
 */
void reset_liters_if_needed()
{
    uint16_t current_day = rtc.now().secondstime() / 86400;
    if (current_day > reset_day) {
        liters = 0;
        reset_day = current_day;
        rtc.writenvram(ADDRESS_RESET_DAY,
                (uint8_t *) &reset_day, sizeof reset_day);
    }
}

void setup()
{
    /* Pull the initial `liters' and `rest_day' from NVRAM. */
    rtc.begin();
    rtc.readnvram((uint8_t *) &liters, sizeof liters,
            ADDRESS_LITERS);
    rtc.readnvram((uint8_t *) &reset_day, sizeof reset_day,
            ADDRESS_RESET_DAY);
    reset_liters_if_needed();
}

void loop()
{
    /* Periodically update the NVRAM. */
    static uint32_t last_nvram_update;
    if (millis() - last_nvram_update >= NVRAM_UPDATE_PERIOD) {
        reset_liters_if_needed();
        rtc.writenvram(ADDRESS_LITERS,
                (uint8_t *) &liters, sizeof liters);
    }
}

```

For extra safety you may want to add a large capacitor in order to keep the Arduino powered for a few milliseconds after being unplugged. And a circuit that detects when it gets unplugged in order to immediately save the data and stop accessing the NVRAM before it gets out of juice. This kind of trick has already been discussed here, you should be able to find the relevant questions and answers.
> 2 votes

---
Tags: rtc
---


# Question
Title: Pro Micro with Atmega32U4 - reset - reprogramming
i am a new user on arduino card. i have a question about "Pro Micro with Atmega32U4". \- is this product programmable several times ? and the third pin (RST) - (Reset). so, does reset mean it erases memory?

Thank you in advance for your answers.

# Answer
> 1 votes
Yes, the microcontroller on Arduinos (in this case the Atmega32U4) can be reprogrammed many times, only limited by the write limit of the flash memory (As I remember Microchip garantuees about 100,000 write cycles at minimum). You can program it over the USB port of the board or through an ISP programmer.

The Reset pin will do the same as a power cycle (turning off an on again) would do. If you program the Arduino, this program will start, when the Arduino get's power (after the Bootloader, which is used to program over USB without ISP programmer). This program will then run until the power is turned off, or until a reset is done by pulling the RST pin to ground. When the RST pin is released again, the Arduino will again start up. The flash memory and the EEPROM stay untouched and will not loose any data. But the data, that lies in SRAM (like any normal variable in the program) will be lost.

---
Tags: arduino-uno, programming
---


# Question
Title: maximum interrupt-based PWM frequency at 500 Hz
I need to control a 24 kHz ultrasonic transducer and decided to use an arduino uno I have lying around.

Using `tone()` or the atmega's hardware pwm is not very suitable because I need two 50/50 square waves with a phase difference of pi (which is equal to two XOR'ed pins) to switch the output polarity of the h-bridge synchronously. As the uC dosen't have anything else to do I wrote the following sketch where I just wait for an interrupt and toggle pins 2&3:

```
bool do_task=false;
void timer_init () {
  TCCR0A |= (1 << WGM01);
  OCR0A = 83;
  TIMSK0 |= (1 << OCIE0A);
  TCCR0B |= (1 << CS01);
}
ISR (TIMER0_COMPA_vect) {
  do_task=true;
}

bool state=false;
void toggle() {
  state=!state;
  digitalWrite(2,state);
  digitalWrite(3,!state);

}

void setup() {
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  timer_init();
}

void loop() {
  if(do_task) {
    do_task=false;
    toggle();
  }
}

```

I expected the output to have a frequency of ~24 kHz, but it is 500 Hz instead.

From my understanding:

* 16 MHz CPU frequency
* timer0 prescaler is 8 (`TCCR0B |= (1 << CS01)`)
* output compare value (`OCR0A`) is 83

would result in a frequency of `16 MHz / 8 / 83 = 24096,4 kHz` -but as I mentioned- it's 500 Hz and doesn't seem to depend on the prescaler.

# Answer
> 2 votes
> what exactly is it that makes a simple function like digitalWrite() so damn slow??! Why isn't it just a wrapper function for direct port manipulation?

Well, it can take a variable as an argument. And the contents of the variable have to be looked up in a table to see which port and which bit.

If you use the DigitalWriteFast library then that turns your writes into direct port manipulation *providing you use constants*.

So you can use:

```
digitalWriteFast(2,HIGH);  // or LOW

```

But not:

```
digitalWriteFast(myPort,someState);  // assuming they are not constants

```

In fact you *can* send variables, but it degrades into the same slow calls that digitalWrite uses.

---

> I now decided not to use the arduino core

The core is absolutely fine. However you need to understand what it is doing. To be nice to newbies things like digitalWrite can take variables as arguments, so this sort of thing is possible:

```
for (int i = 0; i < 13; i++)
  digitalWrite (i, HIGH);

```

---

As I hinted in a comment, you could do it all in the ISR:

```
ISR (TIMER0_COMPA_vect) {
  static bool state;
  if (state)
    {
    digitalWriteFast(2,HIGH);
    digitalWriteFast(3,LOW);
    state = false;
    }
  else
    {
    digitalWriteFast(2,LOW);
    digitalWriteFast(3,HIGH);
    state = true;
    }
}  // end of TIMER0_COMPA_vect

```

---

> Initially, I planned to read the frequency from a potentiometer after each interrupt, wouldn't this be easily possible in 8×83=664 cycles?

Analog reads (reads from the ADC) take around 104µs using the default ADC prescaler. That is, 1664 clock cycles. So, no, you can't read in that time. That is a hardware limitation. You can reduce the prescaler without losing much accuracy.

See my page about the ADC. Making the prescaler 16 rather than 128 will significantly increase speed with minimal accuracy loss.

To do that on the Uno:

```
ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2)); // clear prescaler bits
ADCSRA |= bit (ADPS2);                               //  16

```

# Answer
> 3 votes
You wrote:

> Using \[...\] the atmega's hardware pwm is not very suitable because I need two 50/50 square waves with a phase difference of pi

I believe hardware PWM is the best solution to your problem. The PWM outputs can be set to either “inverting” or “non-inverting” mode. Set the two channels of a single timer to the same duty cycle, with one in non-inverting mode and the other one in inverting mode, and you have your complementary outputs.

Example using Timer 1:

```
const float SIGNAL_FREQUENCY = 24e3;
const uint16_t HALF_PERIOD = round(F_CPU / SIGNAL_FREQUENCY / 2);
const uint16_t PERIOD = 2 * HALF_PERIOD;

int main()
{
    /* Set the PWM pins as outputs. */
    DDRB |= _BV(PB1);  // digital  9 = PB1 = OC1A
    DDRB |= _BV(PB2);  // digital 10 = PB2 = OC1B

    /* Configure Timer 1. */
    ICR1   = PERIOD   - 1;
    OCR1A  = PERIOD/2 - 1;
    OCR1B  = PERIOD/2 - 1;
    TCCR1A = _BV(COM1A1)  // non-inverting PWM on OC1A
           | _BV(COM1B0)  // inverting PWM on OC1B
           | _BV(COM1B1)  // ditto
           | _BV(WGM11);  // mode 14: fast PWM, TOP = ICR1
    TCCR1B = _BV(WGM12)  // ditto
           | _BV(WGM13)  // ditto
           | _BV(CS10);  // clock at F_CPU, start timer
}

```

---
Tags: arduino-uno, pwm, atmega328, timers, h-bridge
---


# Question
Title: 'Delay command' and bluetooth communication problem
I have a project where I send data to Arduino via Bluetooth using an Android application. For example, when I press 1 from the 'bar led' part of the application, an animation needs to happen. When I press 2, a different animation will be displayed. However, because there is a 'delay command' in the animations, there is a delay in data exchange when I press the button. **How can I prevent this? Is there a command I can use instead of the 'Delay command'?**

```
void loop() {
  if (bluetooth.available()) {
  while (bluetooth.available())
    {
      bar_analog = bluetooth.parseInt();
      head_analog = bluetooth.parseInt();
      bar_anim = bluetooth.parseInt();
      strip_anim = bluetooth.parseInt();
      motor_speed = bluetooth.parseInt();
      direct = bluetooth.parseInt();
      level = bluetooth.parseInt();
      if (debug) {
        Serial.print("Bar Brightness: ");
        Serial.println(bar_analog);
        Serial.print("Bar Animation Type: ");
        Serial.println(bar_anim);
        Serial.print("Headlight Brightness: ");
        Serial.println(head_analog);
        Serial.print("Strip Animation Type: ");
        Serial.println(strip_anim);
        Serial.print("Motor Speed Level: ");
        Serial.println(motor_speed);
        Serial.print("Direction: ");
        Serial.println(direct);
        Serial.print("Mast Goes: ");
        Serial.println(level);
        Serial.println("--------------------------------");
      }
      if (bluetooth.read() == '\n') {

      }
  }}
  if(bar_anim==1) {
  digitalWrite(8,HIGH);
  delay(50);
  digitalWrite(8,LOW);
  delay(250);
  }
  else if(bar_anim==2) {
  digitalWrite(8,HIGH);
  delay(250);
  digitalWrite(8,LOW);
  delay(50);
}
}

```

# Answer
> 1 votes
I see 2 problems with your code:

1. You use the `delay()` function, which is not good coding style, since it is basically busy waiting. The Arduino will do nothing in this time, also not reacting to any input. Instead you should use a non-blocking coding style, which only does something, when it is time to do so, and will not block until something happens. You can see this style in the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It uses `millis()` as a time measure. Think of how you would bake a pizza. You would not sit on front of the oven doing nothing, until the pizza is ready. You would do other things while looking at your watch regularily, checking, if it is time to take out the pizza.
2. In the Serial communication part you use `parseInt()`. That can be a problem, since it has a timeout of 1s (standard value). Until the timeout the function will block. This is mitigated, if you consecently send a non-digit character at the end of every value. But it is better to first read a full message (until the newline character `\n`) and then process the message as a whole.

Also the line `if (bluetooth.available())` is not necessary here, since the `while` loop will do the same.

---
Tags: bluetooth
---


# Question
Title: Sending code for error detection facing problem with error not able to compile code
**MY PROJECT CODE:**

```
#include ESP8266WiFi.h
#include LiquidCrystal.h
#include FirebaseArduino.h>
#include HX711.h>
#define FIREBASE_HOST "iot-based-smart-dustbin.firebaseio.com"
#define FIREBASE_AUTH "ljIbV03K07rLwoHRKSaAxWzJNCb3Lh6buc76dkvb"
#define WIFI_SSID "AndroidAP"
#define WIFI_PASSWORD "ashu1234"
char c; //ESP
String data   = "";  //ESP
#define DOUT  15
#define CLK  13
#define IR1 14
#define IR2 12
HX711 scale(DOUT, CLK); // Init of library
float calibration_factor = -96650; //-106600 worked for 3-40Kg max scale setup
const int rs = 16, en = 5, d4 = 4, d5 = 0, d6 = 2, d7 = 10;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup()
{
   Serial.begin(9600);
   pinMode(IR1,INPUT);
  pinMode(IR2, INPUT);
  pinMode(DOUT, INPUT);
  pinMode(CLK, OUTPUT);
  lcd.begin(16, 2);     // Print a message to the LCD.
  lcd.print("WELCOME");
  delay(2000);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
//  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED)
    {
  //    Serial.print(".");
      delay(500);
    }
//  Serial.println();
//  Serial.print("connected: ");
//  Serial.println(WiFi.localIP());
  scale.set_scale();
  scale.tare(); //Reset the scale to
}
void loop()
{
  scale.set_scale(calibration_factor); //Adjust to this calibration factor
  float a=scale.get_units();   // a Variable to take weight values at input
  lcd.clear();
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.setFloat("Weight", a);  //to set value in firebase // value on a sent to weight variable
  if (digitalRead(IR1)==HIGH)
  {
    Firebase.setFloat("IR1", HIGH);
    lcd.setCursor(0, 0);
    lcd.print("Location 1:High");
  }
   if (digitalRead(IR1)==LOW)
  {
    Firebase.setFloat("IR1", LOW);
    lcd.setCursor(0, 0);   //column, Row
    lcd.print("Location 1: Low");
  }
   if (digitalRead(IR2)==HIGH)
  {
    Firebase.setFloat("IR2", HIGH);
    lcd.setCursor(0, 1);
    lcd.print("Location 2:High");
  }
   if (digitalRead(IR2)==LOW)
  {
    Firebase.setFloat("IR2", LOW);
    lcd.setCursor(0, 1);
    lcd.print("Location 2: Low");
  }
  delay(2000);
  lcd.clear();
  if (a>=4)
  {
    lcd.setCursor(0, 0);
    lcd.print("Weight: High");
  }
   if (a<4)
  {
    lcd.setCursor(0, 0);
    lcd.print("Weight: Low");
  }
 delay(2000);
}
void send_msg_1()
{
  Serial.println("AT+CMGF=1");// for GSM module in TEXT mode
  delay(1000);
  Serial.println("AT+CMGS=\"+9921526975\"\r");// Phone number (change)
  delay(1000);
  Serial.println("Dustbin at Location 1 is full");// Message body (change as per requirement)
  delay(1000);
  Serial.println((char)26);// send message
  delay(1000);
}

```

**ERRORS I am Getting while compiling as follows:**

```
sketch_jul18a:34:22: error: no matching function for call to 'HX711::HX711(int, int)'
 HX711 scale(DOUT, CLK); // Init of library
                      ^
C:\Users\Admin\Desktop\Neha\sketch_jul18a\sketch_jul18a.ino:34:22: note: candidates are:
In file included from C:\Users\Admin\Desktop\Neha\sketch_jul18a\sketch_jul18a.ino:23:0:
C:\Users\Admin\Documents\Arduino\libraries\HX711_Arduino_Library\src/HX711.h:30:3: note: HX711::HX711()
   HX711();
   ^
C:\Users\Admin\Documents\Arduino\libraries\HX711_Arduino_Library\src/HX711.h:30:3: note:   candidate expects 0 arguments, 2 provided
C:\Users\Admin\Documents\Arduino\libraries\HX711_Arduino_Library\src/HX711.h:19:7: note: constexpr HX711::HX711(const HX711&)
 class HX711
       ^
C:\Users\Admin\Documents\Arduino\libraries\HX711_Arduino_Library\src/HX711.h:19:7: note:   candidate expects 1 argument, 2 provided
exit status 1
no matching function for call to 'HX711::HX711(int, int)'

```

Please help me to solve this problem. Too much struggling...

# Answer
> 2 votes
Probably the main problem is already in the first lines:

```
#include ESP8266WiFi.h
#include LiquidCrystal.h
#include FirebaseArduino.h>
#include HX711.h>

```

You should use the correct formatting:

```
#include "ESP8266WiFi.h"
#include "LiquidCrystal.h"
#include "FirebaseArduino.h"
#include "HX711.h"

```

Also, HX711 does not have a constructor with arguments, so instead of

```
HX711 scale(DOUT, CLK);

```

uese

```
HX711 scale;

```

and in Setup:

```
scale.begin(DOUT, CLK);

```

You probably have the code meant for a different library.

See HX711\_full\_example. Or use the code belonging to your used HX711 library.

---
Tags: esp8266, lcd
---


# Question
Title: Reading consecutive two pulse periods continuously
I'm controlling the DC motor/fan speed by PWM through varying analog input. Using Uno or Nano.

The loop is as follows:

```
void loop()
{
  val = analogRead(analogPin0);  // read the analog input pin
  analogWrite(pwmPin9, map(val, 0, 1024, 0 , 255));
}

```

Above analogPin0 value is varied by a poti.

But I also want to output the rpm on an LCD. To do that I need to measure the period between two consecutive pulses as shown below:

How could I measure continuously "period between two consecutive pulses"? Should I use interrupt? Does anybody have any experience with that?

# Answer
I see 2 ways to go here:

1. You could attach a simple interrupt for rising edge to the pin with `attachInterrupt()` and count the rising edges with a variable. If the third rising edge is sensed, you have 1 period. To measure the time you can save the starting time of the first rising edge to a variable with `micros()` (which gives you the time since startup in microseconds). At the third rising edge save the time difference between start and end to another variable (declared volatile): `micros()-start_time`. This variable can then be displayed in your `loop()` function. Be sure to only copy the variable to a local variable in this part and deactivate interrupts during this operation with `noInterrupts()` (reactivate interrupts after that with `interrupts()`. Also you should use an atomic flag variable (atomic meaning, that writing or reading this variable cannot be interrupted. For example if you use `byte` or any other 1byte variable) to show the `loop()` function, that there is new data to display. Only if that's the case, the code in the `loop()` function would process the data.
2. If you want to go fancy or if you want to measure higher speeds (lower periods), You can use the hardware of Timer1 as counter. You give the Timer1 your signal as clock input. On every edge the timer value get's incremented by 1. So when the timer value is 5, one period has passed. You can use the timer in compare match mode, so that it will generate an interrupt, if a special value (here 5) is in the timers value register. In that ISR (Interrupt Service Routine) you would record the current time with `micros()`. On compare match the timer will generate the interrupt, set the value to zero again (if configured right) and again start to count. So the period would be the time between 2 consecutive time measurements. Displaying in the `loop()` function can be handled similar to the principle above.

It might also be good to directly take a mean of the period (to filter out noise in the period) by counting, until multiple periods have gone by. In the first case you could count to 11 to get 5 periods. Then divide the time difference by 5 to get 1 period. For the second case you can set the Timer1 match register to 21 to get 5 periods. Here also divide the time by 5 to get 1 period.

Since you seem to be a beginner, I would suggest the first way: Using `attachInterrupt()`. The second way is more if you want to dig into the microcontrollers registers and the descriptions in the datasheet.

The first way could look something like this:

```
const int pin = 2;

volatile byte counter = 0;
volatile unsigned long start_time;
volatile unsigned long period;
volatile byte data_flag = 0;

void speed_ISR(){
    counter++;
    if(counter==3){
        unsigned long now = micros();
        period = now - start_time;
        data_flag = 1;
        start_time = now;
        counter = 1;
    }
}

void setup(){
    pinMode(pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(pin), speed_ISR, RISING);
}

void loop(){
    if(data_flag){
        noInterrupts();
        unsigned long local_period = period;
        data_flag = 0;
        interrupts();
        // Now display the period on the LCD her
    } else {
        // Print zero to the LCD
    }
}

```

The code gives you the opportunity to write zero to the LCD, when there is no pulse input (hence no data --\> data\_flag has to be zero). This may be uncomfortable to read on low pulse frequencies, if the LCD doesn't need longer to display the results as the next pulse will be measured, as it might display zero and the next measurement in fast succession. You could either use `millis()` to set `data_flag` to zero after a specified time (instead of resetting it near the LCD code), or you can limit the display rate like the blinking is done in the `BlinkWithoutDelay` example, that comes with the Arduino IDE.

Note that this code is not tested.
> 1 votes

# Answer
An interrupt off of one of the timers sounds like the easiest way to go. To get a measurement precision of, say 3% at 4ms means sampling every (4000us * .03) = 120us (8.333 KHz). If your code has little else to do, you might get away with clock-watching - `micros()` ticks every 4us - but you'll need to keep anything else you do between reads of `micros()` to under 120us, and half of that might be a good target figure.

In this answer I described a general non-blocking procedure for managing several tasks in a timely way. If you chose such a design, one task might manage the potentiometer and analog output, another one the RPM measurement, and another the LCD. The ISR would do nothing but set a flag.

The RPM & LCD tasks can run at a relatively low rate as they're intended for human consumption only. They may have to work piece-wise, though, to meet their time restrictions.
> 1 votes

---
Tags: arduino-uno, pulsein
---


# Question
Title: Controlling a servo motor with two arduinos?
I have two Arduinos, two buttons and one servo motor.

I want to control a servo motor with two Arduino's when I pressed the buttons. I linked Arduino PWM pins (first Arduino PWM pin is 9, and second one is 3) to the servo motor signal input.

When I pressed button 1 servo motor moving a few, or pressed button 2. but the signal isn't clear, and servo motor doesn't move correctly that I assigned degree.

What can I do for the solution?

My first Arduino code is here:

```
#include<Servo.h>

#define Buton 8

Servo myServo;

void setup() {
  pinMode(Buton, INPUT);
  myServo.attach(3);
}

void loop()
{
  if (digitalRead(Buton) == 1)
  {
    myServo.write(90);
  }
  else
  {
    myServo.write(180);
  }

}

```

and second arduino code is:

```
#include<Servo.h>

#define Buton 8

Servo myServo;

void setup() {
  pinMode(Buton, INPUT);
  myServo.attach(9);
}

void loop()
{
  if (digitalRead(Buton) == 1)
  {
    myServo.write(90);
  }
  else
  {
    myServo.write(180);
  }

}

```

# Answer
You can't just connect random pins together like that. Connecting two output pins together is a recipe for disaster. Best case scenario: nothing works. Worst case scenario: you break one or both Arduinos.

Only one Arduino can control a servo. If you want a second Arduino to make something happen to the servo you have to make it tell the Arduino that is controlling the servo that something should happen.

That could be a simple output of the second Arduino connected to an input of the first Arduino, in which case it kind of acts like a button. Or you could create some kind of communication channel between them - maybe using a Serial connection, or a Wire (I2C) connection. There's many ways, and which is best depends on how much control one Arduino needs to exert over the other.
> 2 votes

---
Tags: motor, servo, pwm
---


# Question
Title: Arduino Bluetooth communication is slowing down because of the 'for' loop!
I'm sending data to Arduino through the mobile app. So far, all the code has been running consistently.

```
#include <SoftwareSerial.h>
#define FASTLED_INTERNAL
#include <FastLED.h>
#define NUM_LEDS_PER_STRIP 48
SoftwareSerial bluetooth(53,52);    // TX,RX
int bar_analog=0;
int head_analog=0;
int bar_anim=0;
int anim=0;
int motor_speed=1;
int direct=0;
int level=0;
CRGB strip1[NUM_LEDS_PER_STRIP];
CRGB strip2[NUM_LEDS_PER_STRIP];
CRGB strip3[NUM_LEDS_PER_STRIP];
CRGB strip4[NUM_LEDS_PER_STRIP];
boolean debug = true;
int IN1a=49;
int IN2a=48;
int PWM1=3;
int IN1b=22;
int IN2b=23;
int PWM2=4;
int hiz=100;
int PWM_kare=2;
int INA_kare = 51;
int INB_kare = 50; //LED '+'sı OUTPUT B'de olduğu için INB'yi  HIGH yapıyoruz.
void m1_cw() {
digitalWrite(IN1a,HIGH);
digitalWrite(IN2a,LOW);
analogWrite(PWM1,hiz);
}
void m1_ccw() {
digitalWrite(IN1a,LOW);
digitalWrite(IN2a,HIGH);
analogWrite(PWM1,hiz);
}
void m2_cw() {
digitalWrite(IN1b,HIGH);
digitalWrite(IN2b,LOW);
analogWrite(PWM2,hiz);
}
void m2_ccw() {
digitalWrite(IN1b,LOW);
digitalWrite(IN2b,HIGH);
analogWrite(PWM2,hiz);
}
void m1_stop() {
digitalWrite(IN1a,LOW);
digitalWrite(IN2a,LOW);
analogWrite(PWM1,0);
}
void m2_stop() {
digitalWrite(IN1b,LOW);
digitalWrite(IN2b,LOW);
analogWrite(PWM2,0);
}
void mast_up() {
digitalWrite(24,HIGH);
digitalWrite(25,LOW);
}
void mast_down() {
digitalWrite(24,LOW);
digitalWrite(25,HIGH);
}
void mast_stop() {
digitalWrite(24,LOW);
digitalWrite(25,LOW);
}
void kare() {
analogWrite(PWM_kare,head_analog);
digitalWrite(INB_kare, HIGH);
digitalWrite(INA_kare, LOW);
}
void strip_dim() {
for(int i=0;i<256;i=i+10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Parlaklık
strip1[j] = CRGB( 100, 172, 45); //leds[0] şeritteki 1.Ledi ifade eder. (Buradaki leds variable'dır.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show();
}}
for(int i=255;i>=0;i=i-10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Parlaklık
strip1[j] = CRGB( 100, 172, 45); //leds[0] şeritteki 1.Ledi ifade eder. (Buradaki leds variable'dır.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show();
}}
}
void strip_stop() {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(0); //Parlaklık
strip1[j] = CRGB( 100, 172, 45); //leds[0] şeritteki 1.Ledi ifade eder. (Buradaki leds variable'dır.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show();
}
}
void setup() {
  Serial.begin(9600);
  bluetooth.begin(9600);
  Serial.println("Program is starting...");
  Serial.println("by Berke Ogulcan Parlak");
pinMode(IN1a,OUTPUT);
pinMode(IN2a,OUTPUT);
pinMode(IN1b,OUTPUT);
pinMode(IN2b,OUTPUT);
pinMode(PWM1,OUTPUT);
pinMode(PWM2,OUTPUT);
pinMode(24,OUTPUT);
pinMode(25,OUTPUT);
pinMode(INA_kare, OUTPUT);
pinMode(INB_kare, OUTPUT);
pinMode(PWM_kare, OUTPUT);
digitalWrite(IN1a,LOW);
digitalWrite(IN2a,LOW);
digitalWrite(IN1b,LOW);
digitalWrite(IN2b,LOW);
digitalWrite(PWM1,LOW);
digitalWrite(PWM2,LOW);
digitalWrite(24,LOW);
digitalWrite(25,LOW);
digitalWrite(INA_kare, LOW);
digitalWrite(INB_kare, LOW);
digitalWrite(PWM_kare, LOW);
FastLED.addLeds<NEOPIXEL, 26>(strip1, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 28>(strip2, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 30>(strip3, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 32>(strip4, NUM_LEDS_PER_STRIP);
FastLED.setBrightness(0);
}

void loop() {
  while (bluetooth.available())
    {
      bar_analog = bluetooth.parseInt();
      head_analog = bluetooth.parseInt();
      bar_anim = bluetooth.parseInt();
      anim = bluetooth.parseInt();
      motor_speed = bluetooth.parseInt();
      direct = bluetooth.parseInt();
      level = bluetooth.parseInt();
      if (debug) {
        Serial.print("Bar Brightness: ");
        Serial.println(bar_analog);
        Serial.print("Bar Animation Type: ");
        Serial.println(bar_anim);
        Serial.print("Headlight Brightness: ");
        Serial.println(head_analog);
        Serial.print("Strip Animation Type: ");
        Serial.println(anim);
        Serial.print("Motor Speed Level: ");
        Serial.println(motor_speed);
        Serial.print("Direction: ");
        Serial.println(direct);
        Serial.print("Mast Goes: ");
        Serial.println(level);
        Serial.println("--------------------------------");
      }
      if (bluetooth.read() == '\n') {

  }}
        kare();
       if(direct==1) { //ileri
  m1_ccw();
  m2_ccw();
  }
else if(direct==2) { //geri
  m1_cw();
  m2_cw();
  }
else if(direct==3) { //sol
  m1_ccw();
  m2_cw();
  }
else if(direct==4) { //sağ
  m1_cw();
  m2_ccw();
  }
else if(direct==0) { //durur
  m1_stop();
  m2_stop();
  }
if(level==1) { //mast yukarı
  mast_up();
  }
else if(level==2) { //mast aşağı
  mast_down();
  }
else if(level==0) { //mast durur
  mast_stop();
  }
if(anim==2) {
  strip_dim();
  }
else if(anim==0) {
  strip_stop();
  }
  }

```

But when I added the for loop to the code, all the data started to shift. (When I press the button from the application 'lag' occurs and the data is mixed.)I mentioned that part of the code below. **Why does the data shift?**

```
void strip_dim() {
for(int i=0;i<256;i=i+10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Parlaklık
strip1[j] = CRGB( 100, 172, 45); //leds[0] şeritteki 1.Ledi ifade eder. (Buradaki leds variable'dır.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show();
}}
for(int i=255;i>=0;i=i-10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Parlaklık
strip1[j] = CRGB( 100, 172, 45); //leds[0] şeritteki 1.Ledi ifade eder. (Buradaki leds variable'dır.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show();
}}
}
void strip_stop() {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(0); //Parlaklık
strip1[j] = CRGB( 100, 172, 45); //leds[0] şeritteki 1.Ledi ifade eder. (Buradaki leds variable'dır.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show();
}
}

```

# Answer
Your chief problem is that FastLED turns off interrupts when sending the data. It does that because timing is critical, and with interrupts turned on that timing will get completely messed up.

So with FastLED running repeatedly in a loop there is very little time when interrupts are enabled for reception to occur over SoftwareSerial.

Unlike a real UART, which can receive and store a byte before triggering an interrupt, SoftwareSerial triggers an interrupt to at the start of receiving a byte and that interrupt routine is used to do the actual reception. So if interrupts aren't enabled at the moment a byte starts arriving on the GPIO pin it can't start receiving, so it misses the byte and it ends up a mess.

Since you are using an Arduino Mega there is absolutely no reason for you to use SoftwareSerial. You have plenty of real hardware UARTs available to connect your Bluetooth device to which will be able to receive a byte while FastLED is sending out data (as long as it's not sending out data for too long...).
> 3 votes

# Answer
You are creating an instance of a class a lot of times (25 * 48 * 8 + 255 * 48 * 4 = 58,560 times), and that is a costly operation.

Instead, make one instance (before the for loops), and use that to assign everywhere you need it.

Something like;

```
CRGB crgb( 100, 172, 45);

for(int i=0;i<256;i=i+10) {
    for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
        FastLED.setBrightness(i);
        strip1[j] = crgb;
        ...

```
> 1 votes

---
Tags: arduino-mega, bluetooth, serial-data
---


title: Does DmxSerial stops interrupts?

text:
# Question
Title: Does DmxSerial stops interrupts?
I am trying to build a setup with an Arduino Mega, having a DMX output (using DMXSimple library), and a MIDI library (to be done).

I was wondering, if I get into problems. According to This question, where Majenko's answer mentions that FastLED holds interrupts, I wonder if I can get into problems if I try to read MIDI data from 3 serial ports while sending DMX.

Probably FastLED (for led strips) and DMX (250 kbps) have some similarity. DMXSimple works with just one data line (no UART), but MIDI is using UART (31.25 kbps), 3 UARTS.

My fear is that everything works separately (I tried it before, long time ago with MIDI), but when I try to combine it, I get timing problems.

# Answer
Yes, it does disable interrupts when sending a byte:

```
#if defined(__AVR__)
void dmxSendByte(volatile uint8_t value)
{
  uint8_t bitCount, delCount;
  __asm__ volatile (
    "cli\n"                            <<==== DISABLE INTERRUPTS
    "ld __tmp_reg__,%a[dmxPort]\n"
    "and __tmp_reg__,%[outMask]\n"
    "st %a[dmxPort],__tmp_reg__\n"
    "ldi %[bitCount],11\n" // 11 bit intervals per transmitted byte
    "rjmp bitLoop%=\n"     // Delay 2 clock cycles.
  "bitLoop%=:\n"\
    "ldi %[delCount],%[delCountVal]\n"
  "delLoop%=:\n"
    "nop\n"
    "dec %[delCount]\n"
    "brne delLoop%=\n"
    "ld __tmp_reg__,%a[dmxPort]\n"
    "and __tmp_reg__,%[outMask]\n"
    "sec\n"
    "ror %[value]\n"
    "brcc sendzero%=\n"
    "or __tmp_reg__,%[outBit]\n"
  "sendzero%=:\n"
    "st %a[dmxPort],__tmp_reg__\n"
    "dec %[bitCount]\n"
    "brne bitLoop%=\n"
    "sei\n"                             <<==== ENABLE INTERRUPTS
    :
      [bitCount] "=&d" (bitCount),
      [delCount] "=&d" (delCount)
    :
      [dmxPort] "e" (dmxPort),
      [outMask] "r" (~dmxBit),
      [outBit] "r" (dmxBit),
      [delCountVal] "M" (F_CPU/1000000-3),
      [value] "r" (value)
  );
}

```

Also that routine is run from within a timer interrupt routine. On AVR with no interrupt priorities even without disabling interrupts it would still be blocking all other software from running.
> 1 votes

---
Tags: interrupt, midi, timing, dmxsimple
---


title: How to heat the air with arduino?

text:
# Question
Title: How to heat the air with arduino?
I have a plant growing box, fully controlled with arduino.

Youtube: ESP8266 IOT Flora

All things are under control, besides the air temperature. I can cool it down running fans, but cannot find a way to heat it up.

Need to keep the temperature between **25-28 C** all the time.

I was thinking of:

* 8x8 (64) Leds - maybe this can heat up the temperature, how much ?
* Dedicated Module - is there any 5v heating module available ?

# Answer
LEDs are not really efficient for heating up, you can better use a normal light bulb for that (they are less efficient, thus giving more heat).

The Arduino can only control some 100's of mA, that's not much for heating purposes.

Did you think about using a real heater (maybe small size), and use a relay to turn it on by your Arduino, and using a temperature sensor to switch it off above 28 and switch it on below 25 (or a lesser margin to keep up with the time it takes to change the environment temperature)?

If you do not want an external mains power, you could use probably a 12V heater and use a 12V-\>5V converter for your Arduino, or use a 5V heater pad, but according to what I have seen they are more for warming up cold hands, I doubt they can bring up the heat to 25-28 degrees Celcius. Besides, they are probably not very efficient.
> 3 votes

# Answer
The total current of your power supply, 5V • 3A is only 15 watts. That's not enough power to create a meaningful amount of heat. (although looking at your video your grow box is really tiny...)

LEDs are a terrible choice for providing heat. They produce mostly light, and very little heat (which is good if you want light, but bad if your goal is to build a heater.)

You probably want 30-60 watts of heat. As others have said, you could use a light bulb with a relay to control it. You could use a digital thermometer like a DHT11 to measure the temp, and then have a "digital" relay to control the heat source. You'd write a sketch that would turn your heater on at slightly above your minimum temp and turn it off at slightly below your max temp. (How much above and below your thresholds should be would depend on how strong your heater is and how long it takes to heat up your grow space. You'd need to do some testing.)

I created a forced air "boot dryer" where I used a couple of 120V, 500 watt heating elements in series (which lowers the power to 250 watts) and a thermostat. That is likely way too much heat for your tiny grow-box. Here is a link to that heating element: https://www.amazon.com/gp/product/B005RG64LQ/ref=ppx\_yo\_dt\_b\_asin\_title\_o01\_s00?ie=UTF8&psc=1

And for a relay I used a 5V "digital" relay like this one: https://vetco.net/products/single-relay-module-for-arduino?gclid=EAIaIQobChMIgfy8jtjJ4wIVA5-fCh2TXQH1EAQYBCABEgI3mfD\_BwE
> 1 votes

# Answer
You can use nickle chrome wire to easily heat that small box.

From Wikipedia:

> Almost any conductive wire can be used for heating, but most metals conduct electricity with great efficiency, requiring them to be formed into very thin and delicate wires in order to create enough resistance to generate heat. When heated in air, most metals then oxidize quickly, become brittle, and break. Nichrome wire, however, when heated to red-hot temperatures, develops an outer layer of chromium oxide, which is thermodynamically stable in air, is mostly impervious to oxygen, and protects the heating element from further oxidation.

5V nickle chrome wires are available online to order, it's usually used as car seat heater.

Just be careful do **not** use Nickle chrome wire with Arduino directly because it can draw up to 2A from the power source and burn your Arduino board, instead use a relay to control the heater.

Here's the schematic to control a heater using Arduino and a relay:

simulate this circuit – Schematic created using CircuitLab
> 1 votes

# Answer
One simple way I can think of would be to turn a 100 W lightbulb (**EDIT** or whatever size makes sense for your application) on / off using a relay. You could use a heat lamp, but with a small box like you have, a lightbulb should give off plenty of heat. You would want to make sure that the bulb didn't give off enough heat to damage any plastic too close to it.
> 0 votes

---
Tags: temperature
---


# Question
Title: Two flow sensors, one ESP32, LCD and/or Arduino
I want to build a flow meter but the Gal/Min rating of something like this flow meter is too low. I am thinking of strapping two side by side with suitable plenums for In and Out.

I have found some sketches like this but wondering how to use the two inputs to aggregate the results to GPM and Gallons total for display on an LCD screen. I am unsure what happens if two Hall-results arrive at or about the same time but on different Data Pins.

I have priced some single sensors with a higher flow rate for the pipe size but they run to several hundred dollars. Gallons are not critical as long as I can be within about 5% error over ten minutes, our average tank fill time.

Can someone please point me at some code to get me started for an ESP32 and LCD. I'd even consider adding a Nano if that makes things easier. I imagine that would certainly prevent collision issues. Basically I need to be able to handle the flow rate to a single LCD.

Thanks

# Answer
> 0 votes
A Hall Effect Sensor like that just gives you a pulse every rotation (or two pulses per rotation, etc) of the internal vanes.

If you use interrupts to count the pulses then two pulses arriving at the same time will be handled sequentially. The interrupt flag indicating a pulse has arrived is set in hardware the moment the pulse arrives, and the CPU checks all the interrupt flags between instructions. Each flag is handled sequentially, the order determined by interrupt priority settings and a "natural" order determined by the internal wiring of the CPU.

However there is a better way on the ESP32, and that is the Pulse Counter peripheral. This is designed to count pulses like the signals from Hall Effect sensors.

You can just leave the Pulse Counter counting your pulses, then periodically read and reset the pulse count to see how much water has flowed in that period. It looks from the documentation that you can have two inputs both making the same counter increment, so it will do the aggregating for you.

---
Tags: arduino-uno, sensors, arduino-nano
---


# Question
Title: Why the global variables info is not shown for Arduino Due in IDE?
If I compile a sketch for the Arduino Mega:

```
Sketch uses 1804 bytes (0%) of program storage space. Maximum is 253952 bytes.
Global variables use 188 bytes (2%) of dynamic memory,
leaving 8004 bytes for local variables. Maximum is 8192 bytes.

```

If I compile the same sketch for the Arduino Due:

```
Sketch uses 26304 bytes (5%) of program storage space. Maximum is 524288 bytes.

```

Why is the global variables part not supported for the Due, it seems to me it's quite important (even more than the sketch size).

Or can I enable this option somehow? (and if yes, how)

# Answer
> 0 votes
There is a difference in how the build system calculates the memory size for AVR and SAM. The platform.txt file contains the rule for calculating the size. There is a difference how this is done for SAM (Arduino Due).

The AVR size rules (https://github.com/arduino/ArduinoCore-avr/blob/master/platform.txt#L79) are:

```
## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).*
recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).*
recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*

```

And the rules for SAM (https://github.com/arduino/ArduinoCore-sam/blob/master/platform.txt#L91) are:

```
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=\.text\s+([0-9]+).*

```

They may be updated to give more information about the memory size. A good reference on the subject is http://www.support.code-red-tech.com/CodeRedWiki/FlashRamSize which shows that the output from size command for SAM contains much more information.

I assume that from the above information you see how this could be updated.

Cheers!

---
Tags: arduino-due, memory-usage, ide
---


title: How do I implement reverse enumeration?

text:
# Question
Title: How do I implement reverse enumeration?
Basically I'm trying to output a string based upon a value in an array, the following code is what I have come up with to achieve my desired result, but I have a feeling that there is a better way to do it.

```
String day(int day) {
  if (day == 1) return "Sunday";
  if (day == 2) return "Monday";
  if (day == 3) return "Tuesday";
  if (day == 4) return "Wednesday";
  if (day == 5) return "Thursday";
  if (day == 6) return "Friday";
  if (day == 7) return "Saturday";
  else return "Undefined";
}

void setup() {
  Serial.begin(57600);
  while (!Serial);
  Serial.println(day(1));
}

void loop() {
;
}

```

This prints "Sunday" in the Serial monitor

I would appreciate any input on how to optimize this code, thank you!

# Answer
> 3 votes
My method makes use of the `__FlashStringHelper` class:

```
// For convenience:
typedef const __FlashStringHelper *FlashString;

FlashString reverseEnum(int val) {
    switch (val) {
        case 0: return F("Option zero");
        case 1: return F("Option one");
        case 2: return F("Option two");
        default: return F("Invalid Enum");
    }
}

```

Printing now is as simple as:

```
Serial.println(reverseEnum(2));

```

Because it's a "flash string" the `print` function is overloaded properly and it performs the proper PROGMEM reading.

You can, of course, assign to a `FlashString`:

```
FlashString myString = reverseEnum(2);
Serial.println(myString);

```

Or if you don't want to use a typedef you can use the raw type:

```
const __FlashStringHelper *myString = reverseEnum(2);
Serial.println(myString);

```

It's just much cleaner to use a typedef.

# Answer
> 1 votes
I'm no expert, but I imagine something along these lines would work:

```
char* day(int day) {

  static char* dayName[7] = {"Sunday", "Monday", .... };

  if (day > 0 && day < 8) {
    return dayName[day-1];
  }
  else
    return "Undefined";
  }
}

```

In any case, I'll be interested to hear why it's wrong (-:

---
Tags: programming, c, string, struct, typedef
---


title: Wifi Data Logger without Delay

text:
# Question
Title: Wifi Data Logger without Delay
I am really new to Arduino so please bear with me.

I am running an Arduino Uno with several sensors to capture some data related to a fish tank. Here is basically what it does:

* Capture data (light, temperature, etc.)
* Display data on an LCD screen when a button is pressed
* Upload data to thingspeak every 5 minutes, using a ESP8266
* Feed the fish every 4 hours through a servo
* An RGB led blinks at various colors to let me see what's happening (e.g. red when connecting to wifi).

Everything is working reasonably well. That being said, my code is super messy and I am not sure I have the right approach. With the code I have: \- Nothing can be done while the Arduino uploads the wifi \- Nothing can be done when the fish are fed.

This is not so much about the servo, it is more about the wifi problem. How would you suggest that I rewrite my code so that (1) I can run the wifi more than once every 5 minutes and (2) it does not block my sensors and LCD display while I am doing it.

Sorry for the poor quality of the code. Newbie here.

```
//Include LCD Libraries
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <stdlib.h>

//Include Water Probe library
    #include <OneWire.h>

//Include DHT11 Libraries
    #include <dht11.h>

//Include Servo Libraries
    #include <Servo.h>

//Set Peripherals
    dht11 DHT11;
    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
    Servo myservo;  // create servo object to control a servo

//Pins for LCD are SDA=A4 and SCL=A5

//Variables for sensors
    String sunlight;
    String watertemp;
    float airtemp;
    float airhumid;
    OneWire  ds(10); //water temperature, pin 10

//Variables for LCD button
    #define BUTTON_PIN A3    // Set pin Buttons for Backlight LCD.
    unsigned int currentLcdLightOnTime = 0; // For calculating the lcd light on time.
    unsigned long lcdLightOn_StartMillis;
    boolean isLcdLightOn;
    int buttonState = 0;// For checking push-button state.

// Variables for Status LED
    int ledState = LOW;             // ledState used to set the LED
    long previousMillis = 0;
    long interval = 1000;           // interval at which to blink (milliseconds)

//Variables to display LCD Numbers
    char bufferhours[5]; //Output of the itoa function for hours
    char bufferminutes[5]; //Output of the itoa function for minutes
    // We don't care for seconds. It's irrelevant.
    int moisture;

//Variables for Wifi Update
    //long DELAYWIFI = 10000; //For test purposes
    long DELAYWIFI = 300000; //Every 5 minutes
    long endtimewifi;
    long nowwifi;

//Variables for Servo
    long FEEDINGDELAY = 14400000; // Feed every 4 hours
    //long FEEDINGDELAY = 30000; //For test purposes
    int pos = 0;    // variable to store the servo position
    long endtime;
    long now;
    long timeuntilfeeding;

//Variables for Sunlight
    float percent; //transform number above into a percent

// Variables for Wifi Updates

    #include <SoftwareSerial.h>

    //Hardware Serial
    #define _baudrate 9600

    //Software Serial
    #define _rxpin      0
    #define _txpin      1
    SoftwareSerial esp8266( _rxpin, _txpin ); // RX, TX

    //Thingspeak and Wifi Information
    #define SSID "xxx"
    #define PASS "yyy"
    #define IP "zzz" // ThingSpeak IP Address: 184.106.153.149

    // GET /update?key=[THINGSPEAK_KEY]&field1=[data 1]&filed2=[data 2]...;
    String GET = "GET /update?key=www";

// Initiates special characters. http://omerk.github.io/lcdchargen/

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

byte droplet[8] = //icon for water droplet
{
    B00100,
    B00100,
    B01010,
    B01010,
    B10001,
    B10001,
    B10001,
    B01110,
};

byte degree[8] = { // degree centigrade
  B01000,
  B10100,
  B01000,
  B00011,
  B00100,
  B00100,
  B00011,
  B00000
};

byte sun[8] = {
    0b00100,
    0b10001,
    0b01110,
    0b11111,
    0b11111,
    0b01110,
    0b10001,
    0b00100
};

void setup()
{
  lcd.init();// initialize the lcd

//Initialize DHT/
    DHT11.attach(2);

// set the digital pin as output for LED:
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(11, OUTPUT);

//Connect to Wifi
    Serial.begin(9600);
    esp8266.begin(9600);
    boolean wifi_connected=false; //not connected yet...

    sendesp8266("AT");
    delay(2000);
    for(int i=0;i<5;i++) //attempt 5 times to connect to wifi - this is a good idea
    {
    if(connectWiFi()) //are we connected?
    {
    wifi_connected = true; //yes
    break; //get outta here!
    }
    }

//Initiate characters
    lcd.createChar(0, thermometer);
    lcd.createChar(1, droplet);
    lcd.createChar(2, degree);
    lcd.createChar(3, sun);

}

void loop(){
    now = millis();
    endtime = now + FEEDINGDELAY;

    while(now < endtime) {   // While loop for the feeding
    timeuntilfeeding = endtime - millis();
    now = millis();

    nowwifi = millis();
    endtimewifi = nowwifi + DELAYWIFI;

    while(nowwifi < endtimewifi) {   // While loop for wifi update
    nowwifi = millis();

//We capture sensors

    //Sunlight
    float value_sunlight = analogRead(A2);
    percent = value_sunlight / 1024.0 * 100;  //Convert dryness score into moisture percentage
    String sunlight =String(percent);// turn integer to string

    //Water Temperature
    float value_watertemp = getTemp();
    String watertemp= String(value_watertemp);// turn integer to string

    //Air Temperature and Humidity
    int chk = DHT11.read(); //Read DHT11 Sensor
    float airtemp=float(DHT11.temperature);// turn integer to string
    float airhumid=float(DHT11.humidity);// turn integer to string

    // LED Blinking
    unsigned long currentMillis = millis();
    if(currentLcdLightOnTime == 0){ //We only blink when LCD is not on
    if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    // set the LED with the ledState of the variable:
    digitalWrite(11, ledState);
    }}

  buttonState = digitalRead(BUTTON_PIN);// Check the state of the push-button.

  if (buttonState == HIGH){// Button pressed.

      digitalWrite(11, LOW);

    lcdLightOn_StartMillis = millis();
    currentLcdLightOnTime = 0;
    isLcdLightOn = true;
    lcd.setBacklight(1); // switch on the backlight

    //Screen 0 Presentation

    lcd.setCursor(0, 0);
    lcd.print(" Aquaponics Bot ");

    lcd.setCursor(0, 1);
    lcd.print("  Version 1.0      ");
  }

  else{
    // Button not pressed.

    //Serial.println("Button not pressed - LOW");

    if(isLcdLightOn){
      currentLcdLightOnTime = millis() - lcdLightOn_StartMillis;

        //Screen 2
        if(currentLcdLightOnTime > 3000 && currentLcdLightOnTime <= 6000){

    //Screen 2 - Air Temperature & Humidity

    //Line 1
    lcd.setCursor(0, 0);
    lcd.print("  Air Sensors  ");

    //Line 2
    lcd.setCursor(0, 1);
    lcd.write(0);
    lcd.print(": ");
    lcd.println(airtemp);
    lcd.setCursor(5, 1);
    lcd.write(2);

    lcd.print(" - ");
    lcd.write(1);
    lcd.print(": ");
    lcd.print(airhumid);
    lcd.setCursor(14, 1);
    lcd.print("%   ");

        }

        //Screen 3
        if(currentLcdLightOnTime > 6000 && currentLcdLightOnTime < 9000){

     //Screen 3 - Water Data

    //Line 1
    lcd.setCursor(0, 0);
    lcd.print(" Water Sensors ");

    //Line 2
    lcd.setCursor(0, 1);
    lcd.write(0);
    lcd.print(": ");
    lcd.println(watertemp);
    lcd.setCursor(5, 1);
    lcd.write(2);

    lcd.print(" -  soon   ");

   }

    //Screen 4

        if(currentLcdLightOnTime > 9000 && currentLcdLightOnTime < 12000){

   //Screen 4 - Light Sensors

    //Line 1
    lcd.setCursor(0, 0);
    lcd.print(" Light Sensors  ");

    //Line 2
    lcd.setCursor(0, 1);
    lcd.write(3);
    lcd.print(": ");
    lcd.println(sunlight);
    lcd.setCursor(5, 1);
    lcd.print("% - soon   ");

      }

            if(currentLcdLightOnTime > 12000 && currentLcdLightOnTime < 15000){

     //Screen 5 - Next Feeding

                long hours=0;
                long mins=0;
                long secs=0;

                secs = timeuntilfeeding/1000; //convect milliseconds to seconds
                mins=secs/60; //convert seconds to minutes
                hours=mins/60; //convert minutes to hours
                secs=secs-(mins*60); //subtract the coverted seconds to minutes in order to display 59 secs max
                mins=mins-(hours*60); //subtract the coverted minutes to hours in order to display 59 minutes max
                //Display results
                itoa(hours, bufferhours, 10);//Convert the number of hours into readable by LCD
                itoa(mins, bufferminutes, 10);//Convert the number of minutes into readable by LCD
                lcd.setCursor(0, 0);
                lcd.print("Fish Feeding: ");
                lcd.setCursor(0, 1);
                lcd.print(bufferhours);
                lcd.print(" hours ");
                lcd.print(bufferminutes);
                lcd.print(" min.   ");

   }

        // Turn Off the Screen
      if(currentLcdLightOnTime > 15000){
        lcd.clear();
        isLcdLightOn = false;
        lcd.setBacklight(0); // switch off the backlight

        currentLcdLightOnTime = 0; //So that the blinking can start again.
        ledState = LOW;
      }
    }
  }

    } // End of the while wifi loop

    // Make sure we are still connected to the internet

    esp8266.begin(9600);
    boolean wifi_connected=false; //not connected yet...

    sendesp8266("AT");
    delay(2000);
    for(int i=0;i<5;i++) //attempt 5 times to connect to wifi - this is a good idea
    {
    if(connectWiFi()) //are we connected?
    {
    wifi_connected = true; //yes
    break; //get outta here!
    }
    }

    digitalWrite(13, HIGH);

    //We capture sensors again to send the value

    //Sunlight
    float value_sunlight = analogRead(A2);
    percent = value_sunlight / 1024.0 * 100;  //Convert dryness score into moisture percentage
    String sunlight =String(percent);// turn integer to string

    //Water Temperature
    float value_watertemp = getTemp();
    String watertemp= String(value_watertemp);// turn integer to string

    //Air Temperature and Humidity
    int chk = DHT11.read(); //Read DHT11 Sensor
    String airtemp=String(DHT11.temperature);// turn integer to string
    String airhumid=String(DHT11.humidity);// turn integer to string

    updateTS(sunlight,watertemp, airtemp, airhumid);
    delay(3000); //
    digitalWrite(13, LOW);

  } // End of the while feeding loop

  // Double Swipe to Feed the Fish

    //Intialize Servo
    myservo.attach(3);  // attaches the servo on pin 3 to the servo object
    //Display that the fish is being fed.
    digitalWrite(13, HIGH);

    for(pos = 0; pos < 180; pos += 5)  // goes from 0 degrees to 180 degrees
      {                                  // in steps of 1 degree
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);                       // waits 15ms for the servo to reach the position
       }

    for(pos = 180; pos>=0; pos-=5)     // goes from 180 degrees to 0 degrees
       {
         myservo.write(pos);              // tell servo to go to position in variable 'pos'
         delay(15);                       // waits 15ms for the servo to reach the position
       }

    myservo.detach();  // detattaches the servo from pin 3
    //Clears display
    digitalWrite(13, LOW);

    // SEND AN EMAIL OR UPDATE A DATABASE..

    }

    //----- update the  Thingspeak string with 4 values
    void updateTS( String L, String W , String T, String H)
    {
    // ESP8266 Client
    String cmd = "AT+CIPSTART=\"TCP\",\"";// Setup TCP connection
    cmd += IP;
     cmd += "\",80";
    sendesp8266(cmd);
      delay(2000);
    if( Serial.find( "Error" ) )
    {
      esp8266.print( "RECEIVED: Error\nExit1" );
    return;
    }

     cmd = GET + "&field1=" + L +"&field2="+ W + "&field3=" + T + "&field4=" + H +"\r\n";
     Serial.print( "AT+CIPSEND=" );
     Serial.println( cmd.length() );
     if(Serial.find( ">" ) )
     {
     esp8266.print(">");
     esp8266.print(cmd);
     Serial.print(cmd);
     }
     else
     {
     sendesp8266( "AT+CIPCLOSE" );//close TCP connection
     }
     if( Serial.find("OK") )
     {
     esp8266.println( "RECEIVED: OK" );
    }
    else
    {
    esp8266.println( "RECEIVED: Error\nExit2" );
     }
     }

    void sendesp8266(String cmd) //Send info to esp8266
     {
    esp8266.print("SEND: ");
     esp8266.println(cmd);
     Serial.println(cmd);
     }

     boolean connectWiFi()
      {
     digitalWrite(11, LOW);
     digitalWrite(12, HIGH);
     Serial.println("AT+CWMODE=1");//WiFi STA mode - if '3' it is both client and AP
     delay(5000);
     //Connect to Router with AT+CWJAP="SSID","Password";
     // Check if connected with AT+CWJAP?
     String cmd="AT+CWJAP=\""; // Join accespoint
     cmd+=SSID;
     cmd+="\",\"";
     cmd+=PASS;
     cmd+="\"";
     sendesp8266(cmd);
     delay(15000);

     digitalWrite(12, LOW);

     if(Serial.find("OK"))
     {
      esp8266.println("RECEIVED: OK");
      return true;
     }
     else
     {
       esp8266.println("RECEIVED: Error");
       return false;
     }

     cmd = "AT+CIPMUX=0";// Set Single connection
     sendesp8266( cmd );
     if( Serial.find( "Error") )
     {
     esp8266.print( "RECEIVED: Error" );
      return false;
     }
   }

   float getTemp(){ //Get the water temperature
    //returns the temperature from one DS18S20 in DEG Celsius

    byte data[12];
    byte addr[8];

     if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
     }

    if ( OneWire::crc8( addr, 7) != addr[7]) {
     Serial.println("CRC is not valid!");
     return -1000;
    }

    if ( addr[0] != 0x10 && addr[0] != 0x28) {
     Serial.print("Device is not recognized");
      return -1000;
    }

    ds.reset();
    ds.select(addr);
    ds.write(0x44,1); // start conversion, with parasite power on at the end

     byte present = ds.reset();
    ds.select(addr);
    ds.write(0xBE); // Read Scratchpad

    for (int i = 0; i < 9; i++) { // we need 9 bytes
     data[i] = ds.read();
    }

    ds.reset_search();

    byte MSB = data[1];
    byte LSB = data[0];

    float tempRead = ((MSB << 8) | LSB); //using two's compliment
    float TemperatureSum = tempRead / 16;

    return TemperatureSum;

    }

```

# Answer
> 1 votes
As already pointed out,

You can use a while loop for your purposes:

```
while(adc/send/recive_flag == 1){
// do stuff
}

```

instead of the very bad habit of using delay. (You don't need to wait any longer than you have to)

As for LCD and RGB leds, use them inside an interrupt. Make interrupt timer something like 50 ms. This way, whatever main code you are running, ISR will timout and LCD and RGB will be updated.

> Capture data (light, temperature, etc.)

Use dedicated atmega registers to read ADC. AnalogRead is **SLOW**. I think you can find information about this all over google.

> Upload data to thingspeak every 5 minutes

This should be fine. Increase transmission BAUD RATE if necessary.

To me the way it looks, you have to wait for data capture, theres no solution for that so make it faster.

As for Wifi, disable ISR, send a single message, enable ISR and wait for a bit and so on. Something like this could work.

As for feeding the fish, all you do is send PWM to servo, right? Use dedicated PWM registers on atmega for faster execution but it doesn't matter anyway for the LCD and RGB LED because they are in interrupt routine so they will be updated anyways.

# Answer
> 1 votes
You can use several approaches.

Lesto already pointed out the finite state machine, but this approach will run the code as fast as possible and this might not be the behaviour you want. It's a good approach to manage, for instance, wifi connections and other communications but it won't let you schedule a task in a fixed pace.

Other options:

1) In the arduino default examples there's "Blink without delay" (\examples\digital), here you can read the code explanation. It's different from what you used

(`while(now < endtime)`)

because your code execution is kept inside the while.

If you otherwise use an

`if (currentMillis - previousMillis >= interval)`

the code will do the check but it continues to run other instructions until the right time has come.

2) Use a scheduler! This is handy if you have several different tasks that should run at a constant (and relatively slow for the MCU) pace.

For instance:

```
#include "leOS.h"
leOS myOS

void setup() {
  myOS.begin();
}
void setup() {
  myOS.begin();
  myOS.addTask(updateTS, scheduleTime[30000, SCHEDULED]);
}

```

With this code you'll run the updateTS function every 5 min, without blocking the execution of other tasks.

# Answer
> 0 votes
Instead of using a delay, you may use some variable (maybe a struct or an object) to keep the status of your transmission or reading; every things that need a delay became a new state in this state-machine, every loop, based on witch status you have, you check if there are the information to execute the next step.

You may have multiple thing with status, but if they share a resource you'll need to add an abstraction layer on that resource to take care of that. (Like an event system or a message router or an output buffer)

Also you may have a status in witch you wait for a status in another state machine.

---
Tags: arduino-uno, esp8266, sensors
---


# Question
Title: No Data Received on Serial Port & Unable to DFU Reset. Advice?
Having a problem running my original code that I tested last week, which worked on multiple days last week.

I tried to do a DFU reset and update the BootLoader, but it didn't work. I checked the baudrate and board selections in the Tools tab, but those were fine.

I didn't change anything in the code, I checked the wires on the hardware setup (nothing looks loose).

Thought it could be an error with the USB cable, changed the USB cable to a different one, still same error.

Also - using a Mac. But the same issue arose on the Windows PC. Did not try to reset using the Windows computer, but reset issue has more to do with the other hardware?

Checked the serial port - and it's selected to right one.

# Answer
> 0 votes
Step Zero - check that the port selected works.

Step Next - if you still get the error, try the DFU reset options and follow the steps outlined in the link below.

https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/using-the-bootloader

---
Tags: serial, bootloader, hardware, nrf52
---


# Question
Title: Is it safe to power Arduino project using a power bank and wall charger?
I got an Arduino project that need a constant source of power. Rather than dealing with batteries, I want to use a power bank like this:

Better yet, I want to keep the power bank plugged in to the wall outlet using a wall charger like this:

The USB wire coming out of the power bank, I can modify it and connect it to the 5V on the Arduino (Pro Mini 5V version). Is it safe to do so? The application uses a stepper motor that draws around 200mA and only runs intermittently.

Thanks

# Answer
> 2 votes
Yes you can. A promini will run very well on 5V from a wallwart. Connect 5V to VCC (not RAW or VIN). You can also find wallwarts with 2.1mm/5.5mm plugs, and a mating barrel jack adapter that ends in screw terminals so you don't have to try hacking up a USB cable.

Power bank, you will have to play games to convince it that something is connected and drawing sufficient current to keep it turned on.

Wallwart example https://www.mpja.com/5-Volt-DC-Plug-Power-Supply-4A-Regulated/productinfo/18520+PS/

Barrel jack to screw terminal adapter example https://www.mpja.com/55\_21mm-Power-Jack-Screw-Terminals/productinfo/19454+PL/

# Answer
> 1 votes
Yes, that is my standard setup for Arduino and Raspberry Pi.

---
Tags: arduino-uno, safety
---


title: Arduino is freezing after 10-15 minutes

text:
# Question
Title: Arduino is freezing after 10-15 minutes
I am having a problem with my Arduino freezing after a small amount of time. I'm using an RTC DS1307 breakout to keep track of the time and display the time on an LCD. It displays hours, minutes and seconds (updated every second).

Then I have 25V which is supplied by a transformer and connected to a set of LEDs through a CAT4101 constant-current sink LED driver. The Arduino board is powered by a 2amp USB transformer.

At a set time, the timer should set off the process to dim the lights.

Everything is working well if I set the lights to dim within a few minutes. However, if I leave the board on for more than 10-15 minutes then everything seems to freeze (i.e. the time on the LCD stops being updated and stays stuck at the moment it froze).

I originally thought it could have been something to do with my code. But I then skimmed everything down to the bare essential and just uploaded the code necessary to update the time on the LCD. And even in this case it freezes.

The only way I managed to avoid things freezing was to disconnect the CAT4101 pin 1 from Arduino's PWM and disconnect pin 2 from Arduino's 5V.

What could be causing this issue?

CAT4101

```
pin 1 = connected to Arduino PWM
pin 2 = connected to +5v
pin 3 = connected to ground
pin 4 = connected to ground with 2kOhm resistor
pin 5 = connected to LED cathode

```

**UPDATE**

Code below (I have stripped down the code by removing any additional functions and leaving only the bare code which is leading the application to crash).

```
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>

RTC_DS1307 rtc;
DateTime now;
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);

void setup() {
  Wire.begin();
  rtc.begin();
  lcd.begin(16,2);

 if (!rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(__DATE__, __TIME__)); // time = hh:mm:ss format, e.g. 06:01:01
  }

  lcd.clear();
}

void loop() {
  now = rtc.now();
  updateDisplay();
}

void updateDisplay(){
 int h = now.hour(); // Get the hours right now and store them in an integer called h
 int m = now.minute(); // Get the minutes right now and store them in an integer called m
 int s = now.second(); // Get the seconds right now and store them in an integer called s

 lcd.setCursor(0, 0); // Set the cursor at the column zero, upper row...
 lcd.print(" The time is: "); // ...with spaces to clear characters from setting alarm.
 lcd.setCursor(4, 1); // Move the cursor to column four, lower row
 if (h<10){   // Add a zero, if necessary, as above
  lcd.print(0);
 }
 lcd.print(h);   // Display the current hour
 lcd.setCursor(6, 1); // Move to the next column
 lcd.print(":");  // And print the colon
 lcd.setCursor(7, 1); // Move to the next column
 if (m<10){   // Add a zero, if necessary, as above
  lcd.print(0);
 }
 lcd.print(m);   // Display the current minute
 lcd.setCursor(9, 1); // Move to the next column
 lcd.print(":");  // And print the colon
 lcd.setCursor(10, 1); // Move to the next column
 if (s<10){   // Add a zero, if necessary, as above
  lcd.print(0);
 }
 lcd.print(s);   // Display the current second
}

```

# Answer
> 1 votes
I would add a `delay(100);` to the bottom of your loop()

I'm betting even odds that solves it.

---
Tags: lcd, rtc, arduino-duemilanove
---


# Question
Title: ESP8266: Client Server Based Home Automation System
I am working on a home automation project in which I am trying to use Star Topology, where one esp8266 acts as a server and can be accessed from web browser to receive commands from the user, while two or more esp8266 acts as clients which are connected to relays. Upon the request of user, server esp8266 sends command to the respective client to trigger the relay and the client esp8266 replies with the current status of the relay.

Connections isn't a problem so I am keeping those things aside. So far

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

const char *ssid = "AndroidAP";
const char *password = "qvdo2440";

ESP8266WebServer server(80);
String webPage = "";

void handleRoot() {
  server.send(200, "text/html", webPage);
}

void setup() {
  webPage += "<h1>ESP8266 Web Server</h1>";
  webPage += "<p>Socket #2 <a href=\"socket2On\"><button>ON</button>
</a> <a href=\"socket2Off\"><button>OFF</button></a></p>";

  delay(1000);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println();
  while (WiFi.status() != WL_CONNECTED) {
   delay(500);
    Serial.print(".");
  }
  Serial.print("Configuring access point...");
  WiFi.softAP(ssid, password);
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.on("/", handleRoot);
  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}

```

This is the code for server side. I cannot think of how to program for client side. Any help would be appreciable.

And yes. I have been through many articles, tried out many things which i found on the internet. But nothing could help me. So i am here for few more suggestions with better elaboration.

# Answer
> 1 votes
I agree with most of 'Look Alterno's comment. So here it is explained in more detail.

Each ESP runs a web server. Each ESP will handle

* GET /root/status
* POST /root/change?device=x,state=y

When a client requests /root/status information on each relay managed by the device will be displayed. For satellite ESPs this will mean displaying live data and for the central on it will mean displaying the last known state (it could also request an update at this time). If you use an array then presenting this information will be quite simple.

When a client posts a change to a device then the satellite ESPs will change the relay state and the central ESP will forward the message onto the satellite. It should probably also request a status update to check that the change has occurred.

If you steer clear of hardcoding things and use arrays rather than variable1, variable2, variable3 you should be able to make this expandable. The biggest problem you will have is registering the satellites with the central device, but you could get around that for now by adding a configure page which had a HTML form that allowed you to enter the IP address of the central device and enter the name of the satellite and the name of the things connected to the relay.

Personally I wouldn't use a PC web server, yes it gives you more processing power, but I don't think you really need it for this, I was surprised how good they were. If you have issues look at using an ESP32 instead of a ESP8266 for the central node.

I hope that helps

# Answer
> -1 votes
```
#include<ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
String i;
long newvar;
String httpurl;
String TheHiddenAnswerOfClient;
HTTPClient http;
String SendWithAnswer(String IPcache, String monmessagecache)
{
  httpurl = "http://";
  httpurl += IPcache;
  httpurl += monmessagecache;
  http.begin(httpurl);
  http.GET();
  TheHiddenAnswerOfClient = (http.getString());
  http.end();
  return TheHiddenAnswerOfClient;
}

void setup() {
  // put your setup code here, to run once:
  i = "";
  newvar = 0;
  Serial.begin(9600);
  WiFi.disconnect();
  delay(3000);
  Serial.println("START");
  WiFi.begin("electromodule", "electromodule@456");
  while ((!(WiFi.status() == WL_CONNECTED)))
  {
    delay(300);
    Serial.print("..");
  }
  Serial.println("Connected");
}

void loop() {
  // put your main code here, to run repeatedly:
  i = (SendWithAnswer("192.168.0.2", "YES"));
  Serial.println("Before Clear");
  Serial.println(i);
  i.remove(0, 25);
  i.remove(i.length() - 11, 11);
  Serial.println("After clear");
  Serial.println(i);
  newvar = i.toInt();
  Serial.println((2000 + newvar));
}

```

---
Tags: esp8266, wifi, home-automation
---


# Question
Title: Getting issues while using SoftwareSerial
I am trying to read string send from esp8266 esp01 to Arduino mega. When I use normal Rx and Tx ports, it works properly but when i am initializing new serial port using SoftwareSerial then nothing is being shown on the serial monitor.

Please help me as i have been stuck and trying to solve this for weeks now. Below are the code for esp8266 and Arduino mega

> > Code for ARDUINO MEGA

```
#include<SoftwareSerial.h>

SoftwareSerial myS(4,5);

String data="true";

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
myS.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(myS.available()){
  data=myS.readString();
  }
  Serial.println(data);
  //Serial.write(data);
  delay(2000);
}

```

> > Code for ESP8266

```
void setup() {
  Serial.begin(9600);     // Initialize the Serial interface with baud rate of 9600
}

// the loop function runs over and over again forever
void loop() {
  if(Serial.available()>0)    //Checks is there any data in buffer
  {
    Serial.print("We got:");
    Serial.print(char(Serial.read()));  //Read serial data byte and send back to serial monitor
  }
  else
  {
    Serial.println("Hello World..."); //Print Hello word every one second
    delay(1000);                      // Wait for a second
  }
}

```

---

Moreover, i have tried read() as well instead of readString(), but it does not work either. I have also tried switching Rx and TX pins meaning connecting Rx-\>Tx, Tx-\>Rx and vice versa i.e. Rx-\>Rx and Tx-\>Tx, but it does not work in any of the case. Any help or suggestion will be appreciated. Thanks

# Answer
SoftwareSerial only works on a few select GPIO pins on the Mega. Specifically those pins that have PCINT on them.

But that is irrelevant. There is no reason to use `SoftwareSerial` on a Mega except in exceptional circumstances. You have four hardware UARTs on the Mega, so there is no call to use `SoftwareSerial`. Use the real UART pins and objects:

```
Serial -> RX(0) / TX(1)
Serial1 -> RX1(19) / TX1(18)
Serial2 -> RX2(17) / TX2(16)
Serial3 -> RX3(15) / TX3(14)

```

Just replace all references in your code to the `SoftwareSerial` instance with `Serial1` (delete the `#include` and the object instance constructor) and use TX1 and RX1 to connect your module:

```
String data="true";

void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);
    Serial1.begin(9600);
}

void loop() {
    // put your main code here, to run repeatedly:
    if(Serial1.available()){
        data=Serial1.readString();
    }
    Serial.println(data);
    //Serial.write(data);
    delay(2000);
}

```
> 3 votes

---
Tags: serial, esp8266, softwareserial, communication, serial-data
---


# Question
Title: Arduino as Slave on I2C bus to read data from other I2C devices
Good afternoon; I am a bit new to the world of I2C bus. I'm trying to implement a project that have Arduino MEGA as a master and Arduino nano as slave. I have some I2C sensors that i want the slave (Arduino nano) to read. Please how can i implement this.

# Answer
> 0 votes
An Arduino can be both a master and a slave. Nick Gammon's page on I2C describes how to do it. http://www.gammon.com.au/i2c

> Communicating with other devices
>
> So all this I2C stuff is great, you can use just two wires (plus ground) to talk to up to 119 devices. But what if you have a device (like a keypad) that doesn't support I2C? Well, the simple answer is that you can use something that does as an interface. For example, a second Arduino. My examples above do just that, using one as the master and second one to display text on LEDs.
>
> In fact, the "master" can also act as a slave, since you can have multiple masters on one wire. The example below shows how you can send data from one Arduino to another, whilst waiting for information to be sent from the second back to the first.

See the link for code examples.

---
Tags: i2c
---


# Question
Title: How Should I Send Data to My Laptop from Multiple Arduinos?
I'm working a project which involves reading multiple RFID tags, from multiple directions, at the same time. Because of the multiple directions, I need to use multiple antennae. Because of the multiple tags, I need to use a simultaneous RFID reader.

Unfortunately, the wiring of the simultaneous RFID reader doesn't support multiple antennae, so each antenna will need its own simultaneous RFID reader. It seems likely - although I'm waiting for confirmation on this - that each RFID reader will have to have its own Arduino as well. What's the least horrible way of sending the data those antenna-reader-Arduino combinations are gathering to a laptop?

If this makes a difference, the laptop I'm going to be sending the data to will be running Ubuntu, and I'd like to collect the data using Python's pyserial package. Once I've got the data in a Python program, we're home and dry.

# Answer
There are multiple solutions but the simplest one is probably to use Software serial, I2C, or SPI. The idea is basically the same for any of the protocols. You select one Arduino which is gonna be the master and be connected to the laptop. Than using any of those interfaces you connect the Arduino boards in to a chain. Than you can ask the slave Arduino boards if they have new data one by one. If they do they send it and the master forwards it to the laptop. In this way all the slave boards will wait until they are asked for data and thus avoid collisions of data streams.
> 1 votes

# Answer
If you have not purchased the Arduinos yet, you could consider using the ESP8266 ("Arduino-like" with embedded wifi module, and not much more expensive, depending on the project size). Then you use your laptop as a server, and each ESP8266 sends the data via wifi to the laptop.

Arduino as a client (via wifi): https://www.arduino.cc/en/Reference/WiFiClient
> 1 votes

---
Tags: rfid, python
---