title: Weird char on a 20X4 LCD

text:
# Question
Title: Weird char on a 20X4 LCD
I'm trying to make an RC controller.

I have a problem with my LCD.

I have already double-checked the wiring and the connections are great.

I made a PCB with Kicad and order it to JLCPCB. I have some mistake, you can see the soldered wire.

Before the PCB, I did my project with a breadboard and it worked fine.

```
const String menuElem[4] = {"Models", "Trims", "Reverse command", "Channel"};

const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void menu() {
  lcd.clear();
  //lcd.setCursor(0,0);
  //byte pos = 0;
  //int sizeOfanArray = *(&array + 1) - array;
  byte menuElemLength = *(&menuElem + 1) - menuElem;
  for (byte i = 0; i < menuElemLength; i++) {
    lcd.setCursor(2, i);
    lcd.println(menuElem[i]);
  }
  showMenuNav(currentMenuPos);
}

```

# Answer
> 2 votes
Your code to calculate the length of your `String`s does not make sense. The `String` type is an object type. The addresses of your String objects will not match the length of the charcters in those strings. You should use an array of C strings as suggested by Juraj, and then you should use `strlen()` to get the length of those strings (C strings have a null terminating byte, and `strlen()` uses that null to calculate the length. Note that C strings can't handle Unicode.)

The String type is best avoided on Arduino anyway, as String objects tend to fragment the extremely limited heap memory on Arduino devices and cause out-of-memory crashes.

---
Tags: lcd
---


# Question
Title: Accessing funcition in object via `->` is crashing (resetting) Arduino
I have several classes that call each other running on an Arduino Mega. I am using the `ArduinoSTL` library to get the std library, most notably the std::vector.

The core problem is as follows: my `Manager` object that is created in the Arduino global space, is called in the `loop()`. The `Manager` object in one of it's functions spawns a derived object `Derived derived` (the constructor also takes a pin int and a delay value, but just simplifying for now) and calls a function in it `derived.startExecution()`. All is happy. Then I store a pointer to the object into a `std::vector<base*> myVector` via `myVector.push_back(&derived)`. All is happy. As long as I don't leave the function, I can then take the pointer out of the vector container and call another function in the object. For example: `myVector.back()->continueExecution()` and all is great. Now the problem. If I copy paste the line `myVector.back()->continueExecution()` into a different function, the Arduino restarts. I'm losing my sanity here. I know that the issue is not the pointer, but the call to the function using the pointer. Using println & delay(500), in a new function inside the Manager I can do the following without issue (no restart):

* retrieve pointer from vector. All good.
* assign pointer from vector to a temporary pointer type to be able to refer to that pointer. All good
* calling the function in the object causes instant Arduino Hardware reset (not a single line will execute in the function that is called).

All this leads me to the conclusion that calling the function in the object is causing a problem. I rewrote a simplified version of the code below, and it executes well on this website (please see: https://godbolt.org/z/G3x556), but on the Arduino it crashes.

What can I do to understand why the object crashes the program? how can I validate that the object is OK prior to calling the function? Why does the call to the function in an object that should be alive crashes the system? why does the call work in the function which stored it in the vector, but not in a different function? How can I answer these questions. I have hit a limit on ideas. Thank you for your time!

My code simplified:

```
#include <iostream>
//#include <ArduinoSTL.h> //commented out to work on website
#include <vector>

//base class is used to be able to push everything into a std::vector
//in ArduinoSTL lib.
class Base
{
    public:
        virtual void continueExecution()
        { std::cout << "Base" << std::endl; }

        // a polymorphic class MUST have a virtual destructor
        virtual ~Base(){};
};

//lots of these classes will exist one day if I keep at this grind
class Derived : public Base
{
    public:
        Derived()
        {
            std::cout<< "Derived constructor" << std::endl;
        }

        void startExecution()
        {
            std::cout << "Derived object, start function"<< std::endl;
            //start work
        }

        void continueExecution()
        {
            //continue when time has eleapsed
            std::cout << "Derived continueExectution " << std::endl;
        }
};

class Manager
{
    public:
        void beginExecutingDerivedObject()
        {

            //derived object
            Derived derivedObj;

            derivedObj.startExecution();

            myVector.push_back(&derivedObj);

            //if I run the line that crashes the code below this
            //comment, all is OK. But that is not where it is needed.
            myVector.back()->continueExecution();
        }

        void finishExecutionOfDerivedObject()
        {
            //CODE CRASH HERE. The moment the function is called, a reset
            //occurs.
            myVector.back()->continueExecution();

            //any code here may appear on the console, but it's just a
            //memory dump. By this point, the Arduino has thrown up it's arms.
        }

    private:
        //create vector
        std::vector<Base*> myVector;
};

//main is actually the arduino loop()
int main()
{
    //this manager class is in the sketch global space
    Manager manager;

    //this is called by a function call in the loop()
    manager.beginExecutingDerivedObject();

    //this is also called by a function call in the loop()
    manager.finishExecutionOfDerivedObject();
}

```

# Answer
> 4 votes
`Derived derivedObj;` is a local variable. It's deleted when the function exits. You have saved a pointer to it, but with that object now gone your pointer points to nothing of any interest - so doing *anything* with it is doomed to failure.

Instead you need to create a `new` object on the heap, which will already be a pointer:

```
Derived *derivedObj = new Derived();
derivedObj->startExecution();
myVector.push_back(derivedObj);

```

And then be sure to `delete` any objects you remove from the vector or you'll have lost that memory forever.

---
Tags: c++, reset, pointer, object-oriented, vector
---


# Question
Title: Problem with a function having a parameter with a default value
I've got a problem using a default value for a function parameter.

This code gives *"'blink' was not declared in this scope"*:

```
void loop(void) {
  blink(12, 2, 1000);
}

void blink(const uint8_t led, int num, const uint16_t l = 12) {
  Serial.println(led);
  Serial.println(num);
  Serial.println(l);
}

```

but it works if I don't assign a default value to the "l" arg:

```
void blink(const uint8_t led, int num, const uint16_t l) {

```

or if I put the blink function before the loop:

```
void blink(const uint8_t led, int num, const uint16_t l = 12) {
  Serial.println(led);
  Serial.println(num);
  Serial.println(l);
}

void loop(void) {
  blink(12, 2, 1000);
}

```

# Answer
> 10 votes
It's just a failing of the Arduino build process to generate prototypes (function *declarations*) for functions that have default argument values. There's otherwise nothing wrong with what you're doing. Not in my opinion anyway. The build process sometimes chokes on function or class templates as well. The answer to these sorts of problems is probably that these features are not considered part of the Arduino "language".

Just a reminder: In C++ a function *declaration* needs to have been seen in order to generate a call to it. A *definition* will serve *as* a declaration. In either case, one must have been seen before the call site. Generating declarations where needed is, perhaps, the greater part of what the Arduino build process does that can be said to make the Arduino "language" different from plain C++.

The following were generated by working out of /tmp/default-param with the "input" being default-param.ino, running:

```
arduino-cli -b arduino:avr:uno build --build-path /tmp/build

```

and inspecting /tmp/build/sketch/default-param.ino.cpp which I'm calling "output". You can use the same process if you want to see exactly what the build process is doing to your code.

## Non-default argument

This input:

```
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

```

generates:

```
#include <Arduino.h>
#line 1 "/tmp/default-param/default-param.ino"
#line 1 "/tmp/default-param/default-param.ino"
void setup();
#line 4 "/tmp/default-param/default-param.ino"
void loop();
#line 5 "/tmp/default-param/default-param.ino"
void func(int xyzzy);
#line 1 "/tmp/default-param/default-param.ino"
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

```

The build process has inserted a valid C++ function declaration prior to the call site, so the compiler is happy.

## With default argument

But this input:

```
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy = 7) {}

```

generates:

```
#include <Arduino.h>
#line 1 "/tmp/default-param/default-param.ino"
#line 1 "/tmp/default-param/default-param.ino"
void setup();
#line 4 "/tmp/default-param/default-param.ino"
void loop();
#line 1 "/tmp/default-param/default-param.ino"
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy = 7) {}

```

No declaration prior to the call site this time, so the compiler is not happy with this generated code.

## Build process

The build process is a rather ugly... process... that scrapes the output of the compiler and generated ctags to build include paths and to try to generate forward references for things. Sometimes, it just gets it wrong. I'm not sure what the *exact* error is in the build process, but it is probably just a failure to match the error caused by calling an undeclared function with its matching entry in the ctags. You can try reading through the build process documentation to make sense of this. Ultimately though, you may have to read the source to arduino-cli/arduino-builder to get to exact cause.

Non-.ino (and non-.pde) files more or less go through the build process unscathed. So, if you really want default arguments, you can make use of and .h file for your function prototype/declaration and a .cpp file for its body and follow the normal rules of C++.

## Using your own declaration

You can just make your own declaration for it. Doing so makes it not detect an error on that line.

```
void func(int xyzzy = 7);

void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

```

Output:

```
#include <Arduino.h>
#line 1 "/tmp/default-param/default-param.ino"
void func(int xyzzy = 7);

#line 3 "/tmp/default-param/default-param.ino"
void setup();
#line 6 "/tmp/default-param/default-param.ino"
void loop();
#line 7 "/tmp/default-param/default-param.ino"
void func(int xyzzy);
#line 3 "/tmp/default-param/default-param.ino"
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

```

As you can see it generates a proto type for whatever reason. But not one that conflicts with your own.

---

It is probably better if you want to make use of default arguments to just use headers and .cpp file for those functions that have them so that you're not subject to changes in the ability of arudino-cli/arduino-builder to handle them.

# Answer
> 0 votes
If you use a function after you call it in the same file, you have to (or at least it is better) to add a so called 'forward declaration' before calling it. The best place is before the first function, and in your case it should look like:

```
void blink(const uint8_t led, int num, const uint16_t l);

```

You can omit the `= 12` or not.

---
Tags: arduino-ide, functions
---


# Question
Title: Using HC-08 bluetooth module with arduino
I have an arduino mega 2560 and a recently purchased HC-08 module and the connection is as the following:

**Arduino** | **HC-08**

VCC - VCC

GND - GND

14TX3 - TXD

15TX3 - RXD

When I power up the arduino it shows that flashing light and I am able to see it on my android phone but would only reject the connection every time I tried to pair. Also I am not able to send or receive any data from it at all, here is my code:

```
#include <SoftwareSerial.h>

SoftwareSerial hc08(15,14) // RX pin, TX pin;

void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  hc08.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (hc08.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(hc08.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    hc08.write(Serial.read());
  }
}

```

I'd really appreciate help on how to get it working.

# Answer
> 1 votes
```
void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  Serial3.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (Serial3.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(Serial3.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    Serial3.write(Serial.read());
  }
}

```

# Answer
> 1 votes
I think this is the problem on the hardware setting. It should be: Arduino | HC-08

VCC - VCC

GND - GND

14RX3 - TXD

15TX3 - RXD

Variable declare: SoftwareSerial hc08(14,15) // RX pin, TX pin;

---
Tags: bluetooth, communication, atmega2560
---


# Question
Title: Atmega328 and ADXL335 - is the right choice for vibration analysis?
I'm planning to use the ATMEGA328 and the ADXL335 accelerometer to monitor the bearing and gears vibration of a industrial extractor that works at maximum speed of 3000rpm at 380VAC - 50Hz .

The main scope of this monitoring is to get continuously the vibration readings and apply the FFT transform in order to identify if there is something that is not running well.

My primary concerns are regarding the sampling speed of the ATMEGA328P: i've tried to identify the needed sampling speed but i'm a little bit confused about the relation of motor/gear speed and the ADC sampling speed of the ATMEGA...also, the ADXL is the right choice?

# Answer
> My primary concerns are regarding the sampling speed of the ATMEGA328P

The ATmega328 can sample up to **~10ksps (kilo-samples-per-second) in normal configuration and at 10-bit ADC resolution**, or reliably and with good (near 10-bit) resolution **up to ~50ksps if you speed up the ADC clock**. You can get even faster if you want to sacrifice a lot on sample resolution, but at faster speeds this processor is too slow to even reliably grab the data and transmit it or store it, so you should go to a much much beefier and better microcontroller, such as a 32-bit Arduino Zero, Portenta, or non-Arduino STM32 or something.

## Example of speeding up the ATmega328 to sample up to ~50kHz:

See my library here, and my initial article on it here.

```
#include <eRCaGuy_NewAnalogRead.h>

void setup()
{
    adc.setADCSpeed(ADC_FAST); // now analogRead() will operate up to ~50 kHz
}

void loop()
{
    // these readings can now be done up to ~50 kHz
    uint16_t reading = analogRead(A3);
}

```

I don't remember the exact details of configuring the ADC clock, but it's all in the ATmega328 datasheet, and in my code--which you can study at the library link above, and you can look at Nick Gammon's website on it here: https://www.gammon.com.au/adc.

## How fast do you need to sample? Only you can answer that question.

Perhaps you read some academic paper that says that vibrations of 102kHz on a 5cm diameter motor made of material X can cause microfractures in the material if exposed for 100 hours. Well, in this case, you need to sample at *at least* 204kHz (2x the frequency of interest) to see if 102kHz vibrations exist.

Or, perhaps you just want to use FFT to determine the RPMs of the motor since it will almost certainly have a dominating frequency at its rotational frequency due to imperfect balance of the motor. In that case, sampling at 2x the max RPM (but in samples *per second*, not minute) is sufficient. You stated a max rotational speed of 3000 RPM, so that's `3000 rot/min x 1 min/60 sec = 50 Hz`. *To detect your RPM, therefore, by sampling vibration, you need to sample at least 2x as fast as this, or 100 Hz or higher.*

Remember, this is all Nyquist frequency stuff. All that the Nyquist frequency says is \[in my own words\]:

> you can only detect a frequency up to 1/2 as high as your sampling rate

...or otherwise stated \[in my own words\]:

> you must sample at 2x whatever frequency it is you are trying to measure

Any sample rate lower than this, and you get aliasing and it is mathematically and physically impossible to determine if a higher frequency exists. Any frequencies higher than 1/2x your sample rate which *appear* to exist in your FFT analysis *must* be thrown out, as they are invalid.

So, *what max vibrational frequency do you need to measure?* That's for you to find out. If you're looking to find gear tooth wear (ex: a broken, cracked, or missing gear tooth), you can come up with some estimations based on number of teeth per rotation, and knowing your motor's max rotational speed in rotations per second.

Example: assuming 32 teeth per revolution, you will be rotating at 3000 rot/min / 60 sec/min = 50 rot/sec x 32 teeth/rot = 1600 teeth/sec. But, to identify a broken tooth maybe you need to do a waveform analysis of the *shape* of the wave over that broken tooth, so you should sample at 5x to 10x that rate, or perhaps 1600 teeth/sec x 10 samples/tooth = 16000 samples/sec = 16 kSps. But...5 samples per tooth might be enough, or only 8 kSps...

See how some of this analysis might work? *You have to figure out what it is you're trying to figure out, and sample accordingly.* *If you don't know what you're trying to figure out, just sample as fast as you can and then with that data try to see what you can figure out from what you just sampled!* Such are the ways of engineering and curious minds! :)

---

With that being said, assuming you use my library's `adc.setADCSpeed(ADC_FAST);` trick, you can sample 1 channel up to 50kHz or 3 channels up to 50/3 = ~16kHz, meaning **the max vibrational frequency you can detect with FFT for 3 channels is ~8kHz with an ATmega328.** Is that enough?

BUT, you will have jitter problems unless you put the ADC into continuous sample mode at a fixed interval, and you cannot sample all 3 channels at once, so there will naturally be an offset between them all, as they happen in sequence one after the other.

---

## How fast can the ADXL335 sample? (ie: what's its "bandwidth", or frequency response?)

As for the ADXL335, its datasheet reveals it to be an analog 3-axis accelerometer, not a digital one, so you are limited by:

1. how fast the ADC you have on your microcontroller can sample the sensor (we already came up with ~16khz (kSps)/channel, for 3 channels, above) and
2. what the ADXL335's *bandwidth*, or max frequency response, is.

The datasheet (see image below) says you get a bandwidth of **0.5 Hz to 1600 Hz** for the X and Y axes, and **0.5 Hz to 550 Hz** for the Z axis, *all depending on the chosen bypass capacitors, cx, cy, and cz you choose for it.* See the image and highlighting below.

Bandwidth means simply \[in my own words\]:

> *Bandwidth* is the maximum frequency at which a device can respond to changes in the thing is it measuring (ex: an accelerometer to changes in acceleration).

By definition, a bandwidth for a low-pass filter, or a sensor responding to a high-frequency input, is equal to the frequency at which point the measurement of the thing being measured is attenuated by **3 db**, or in other words, is 1/sqrt(2) = 0.707 times as big as the actual thing being measured. So, if the bandwidth of an accelerometer is 50 Hz, then that means if it tries to measure a 50 Hz vibration, then the measurement it outputs at that frequency is attenuated to 0.707x as large as the actual amplitude of that vibration. Therefore, it is said that this sensor cannot be reliably used to measure higher frequencies than this. Note that since `Power = V^2/R`, and the 0.707 rule applies to voltage, the attenuation is 0.707^2 = 0.5 for power.

If you bought your ADXL335 sensor from Adafruit here for $15 (https://www.adafruit.com/product/163), they state:

> The XYZ filter capacitors are 0.1uF for a 50 Hz bandwidth

...which means they chose capacitors to give it a **50 Hz bandwidth, or frequency response**. This means the sensor is limited to reliably measuring vibrations only up to 50Hz. You should sample at least 2x this bandwidth then in order to adequately capture frequencies up to that value, again, based on Nyquist. This means **for this Adafruit version of the device and with these chosen bypass capacitors you can sample at 100 Hz or higher to detect vibrations up to 50 Hz (that's Hertz, *not* kiloHertz!)**. Even if you sample much much faster, the maximum reliable frequency this device can measure is only up to 50 Hz before attenuation of its measurements becomes a significant concern. Whether sampling at 100 Hz or 1000 Hz, the frequency this sensor can measure, in this configuration, is only up to **50 Hz**, which is only 50/sec x 60sec/min = 3000 RPM if your goal is to just detect the rotational frequency, but not any higher-frequency vibrating modes, for your device.

A 50 Hz bandwidth (max frequency response), FYI, is optimized to reduce sample noise *for handheld tilt-based game controllers*, as it intentionally attenuates any frequencies above 50 Hz, and 50 Hz input from a human is a good expectation for human control signals. You might sample this sensor for such a game controller anywhere from 50 Hz to 1 KHz, but again, it can't detect vibrations any faster than about 50 Hz. So, **the Adafruit version of the ADXL335 is optimized to be used to make home-made tilt-based hand controllers for games, toys, smart devices, radio control devices, etc.**

## Extra note on sampling frequency

Even though the Nyquist frequency says you only need to sample **2x** the frequency of interest *to detect the frequency of interest through FFT or similar*, you need to realize that if you ever want to *plot* a given signal or inspect its shape or waveform, you should sample at least **5x** to **10x** as fast as the frequency of the signal you are trying to record and inspect.

This is how oscilloscopes are rated. A "100 Mhz" bandwidth oscilloscope will have a sample rate of at least 5x to 10x that, or 500 MSps (Mega-samples-per-second) to 1 GSps (Giga-samples-per-second). This makes sense because the purpose of an oscilloscope is to plot waveform *shapes*, and that requires at least 5 to 10 points per period, or 5x to 10x the sample rate of the rated bandwidth in order to display a reasonably-nice picture of the waveform.

For pure FFT or frequency analysis, where you just want to know the *frequency* of the thing being measured, but don't need to know how the waveform *looks*, a sample rate exactly 2x or higher than the frequency of the thing being measured is physically and mathematically sufficient.
> 3 votes

# Answer
First of all, 3000 RPM is only 50 Hz, so sampling is not a problem for the fundamental frequency. But you usually want to see harmonics, to pick up gear tooth issues, etc. I suggest using my Daqarta software with a sound card to do your initial testing. It already does everything you need, including waveform, spectrum, and spectrogram displays plus a lot more. You can use it free for 30 sessions or 30 days, then the sound card inputs are no longer supported. By that time you should have a good idea about what you need. As it turns out, Daqarta also supports Arduino, and that does *not* end with the trial period. So you may be able to do everything with an Arduino, for free. The Daqarta site also has a contact page, and I am glad to answer questions and provide specific help for any issues that arise. That include free users.
> 2 votes

---
Tags: atmega328
---


# Question
Title: Arduino due erase button and power switching
Last days I have been investigatin schematics of arduino due board. The purpose of proper understanding of schematics in crucial for me, beacuse I indend to build myself my own board with some minor modifications.

I would really want to learn something from it and not just blindly copy stuff that are already done. In schematics there are two things that I do not understand. First is the working principle of erase button (see: erase button). I have my own idea how does it work, but would like to clarify the working principle from someone that know exactly what is the purpose of all the elements that are connected to erase button. Also, why is ERASE\_CMD line connected to Atmega processor? Second thing is switching of power supply between external power and both usbs (see: usb switch). Again, would someone please just brifly describe working principle? Here I really do not undertand why is there op amp added?

Thank you in advance.

Erase button:

USB switch:

PLEASE NOTE: Both pictures are taken from original arduino webpage: https://store.arduino.cc/due (see: documentation -\> schematics)

# Answer
The asker posted the same question and received an answer here There is discussion regarding the purpose of the Erase switch here
> -1 votes

---
Tags: power, usb, arduino-due
---


# Question
Title: How do I program an LCD screen and do I need an Arduino
I am trying to create a small device with a screen that tells the date and time. I am thinking of using a UCTRONICS 0.96 Inch OLED Module (type that on Amazon). I am very new at coding, and I know more about electrical engineering, so I have a few questions.

1. Do I need an Arduino that big to power this screen or any screen? I am trying to put this in a compact housing
2. How do you set up the screen and code it to tell the time and date
3. Is there a better screen for me to pick that is easier to work with, or is there a screen that comes programmed telling the time and date

Can someone help, please?

# Answer
OLED screen is really good looking for both indoor and outdoor and I think you have made a good choice.

You need the following things to complete your project easily.

1. Display (which you have already found one
2. Arduino (why? easy to program, lots of libraries available, and also tutorials)
3. RTC - Real-time clock - This is another IC (DS1307, for example)

Arduino need not be UNO. You can use ATTiny85 MCU. the programming will be the same as how you program a UNO. ATtiny85 has no builtin I2C, but the libraries are there to emulate I2C to be connected to OLED displays.

If you want to avoid the third option, go with internal timekeeping alone. But, over a week, you will see the time difference (the internal clocks of the MCU are not accurate, so the time will lead or lag over a period of time)

have you thought about a keypad or a single button to give the option to the user to set the time?
> 2 votes

# Answer
The screen you reference is an input only device, that is, it accepts output from other sources and presents the information. It is not, per se, a stand-alone computer for processing information in the manner you describe.

Image above courtesy linked Amazon site.

One option you can consider is a device known as Sparkfun Microview.

Image above courtesy to linked Amazon site.

This device is an integrated Arduino with OLED display. That's only half the objective. You'll also have to have a programming interface (referenced on the site) as well as an external input for RTC (real time clock). Rather than provide a link, an Amazon search for "Arduino RTC" returns many options. Kit form (assembly required (minor soldering), fully assembled, with and without battery.

All of the above requires, at a minimum, a power source for the Microview and a breadboard on which to make the connections. One can, of course, design a PCB to consolidate the components.

The programming portion is easily accomplished (relative reference) by researching that aspect via the internet. There are tutorials for the Microview, which by necessity include Arduino programming, as well as supplemental tutorials for the RTC. Sparkfun is known (by me) for providing good online support via these tutorials.

If you decide to travel this route to your goal, you may have Arduino specific questions which would be acceptable to this SE.
> 1 votes

---
Tags: programming, lcd
---


# Question
Title: How to access GPS location without internet
I need to provide a basic geolocation service for my clients. I built a location service based on the phone geolocation. It works great, not a problem. My problem is that some of my clients don't have an internet connection.

I know there is a company like Geotab that can provide these types of services.

If I want to build my own (very basic one), how can I make my DIY (Arduino based) GPS communicate with my web servers?

# Answer
If you want to send data to a server on the internet, you will need an internet connection, or at least a connection to a internet gateway.

Which type of connection you use, and how you set up that connection, depends on distance, speed, and coverage you need.

Probably the most universal for your application, in the sense that it will work wherever a phone would work, is to use a GSM/GPS module with an Arduino. You can google around for such modules; there are many. Note that you will need a SIM card for every module you use.

The GSM-bit of the module can then be used as a modem to communicate with your server over TCP/IP. There are many examples showing how to do that on the interwebs, so I won't go there.

If this doesn't help you enough, please add more detail to your question and I will edit the answer.
> 2 votes

---
Tags: gps, web-server, tcpip
---


# Question
Title: SoftWire Library Programming Questions for I2C with Digital Pins
I am trying to use 3 TOF10120 Laser Sensors with one Arduino that all have the same, fixed I2C Address. I don't believe it is possible to change the I2C address of the TOF10120, but if I am wrong, please let me know (also, I need 3 different addresses). This being said, I am trying to use the SoftWire Library (https://github.com/stevemarple/SoftWire \- very interesting library, but not great documentation) to help me to use my three sensors with Digital Pins. Does anyone have any experience with the SoftWire Library and how to get readings from a laser sensor?

I can provide the code I have, but it probably wouldn't be very helpful anyway. I am particularly curious as to how to use the DigitalWrite() and DigitalRead() functions for I2C with SoftWire.

Thanks for all the help in advance!

# Answer
You can change the tof10120 to any i2c address between 1 and 254. you need to write the serial string 's7-xxx#' where xxx is the decimal address required (in string form). I wrote a simple python program for the raspberry pi to change my sensor addresses via the Rx Tx.
> 2 votes

---
Tags: i2c, digital
---


title: Grove Base Kit Multiple I2C Connection

text:
# Question
Title: Grove Base Kit Multiple I2C Connection
I tried to connect two modules that require I2C connection and they won't work at the same time.

I used the Arduino Sensor Kit - Base. This kit does not need any connection, you just have to code to get your desired output. I wanted to display the Air Pressure (BMP280) module values to the 0.96" OLED Display, however, it is refusing to run both the air pressire and the OLED display at the same time. Only running one module (either Air pressure or OLED) at a time makes it work. Does it have something to do with how the I2C connection is wired on the board?

```
#include "Arduino_SensorKit.h"

void setup() {
  // put your setup code here, to run once:
  Oled.begin();
  Oled.setFlipMode(true);
  Oled.setFont(u8x8_font_7x14B_1x2_r);

  Pressure.begin();
}

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

  Oled.setCursor(0, 10);
  Oled.print("Temp: ");
  Oled.print(Pressure.readTemperature());
  Oled.print(" C");
  Oled.setCursor(0, 20);
  Oled.print("Pres: ");
  Oled.print(Pressure.readPressure());
  Oled.print(" Pa");
  Oled.setCursor(0, 30);
  Oled.print("Alti: ");
  Oled.print(Pressure.readAltitude());
  Oled.print(" m");

  delay(1000);
}

```

What I did:

1. Test to see if Air Pressure will still work while both Air Pressure and OLED is connected by using `Serial.begin()`. Now I know that only the OLED does not work when both modules are connected.
2. Changed order of initialization. Same result: Air Pressure works but not OLED

# Answer
About two weeks ago there was a change in the Arduino\_SensorKit Library that introduced an error with the instanciation of the Oled object.

I found the error in the release (v1.0.6) of the library. The previous release (v1.0.5) could cause another issue, as it uses a software I2C. I doubt the hardwired sensores are connected with the correct pins. But I have no hardware, so I can not check this.

I propose a workaround to see, if the identified issue caused your observations.

```
#include "Arduino_SensorKit.h"

U8X8_SSD1306_128X64_NONAME_HW_I2C Oled2;
// if the line above does not work
// comment it and uncomment the following line.
// U8X8_SSD1306_128X64_NONAME_HW_I2C Oled2(U8X8_PIN_NONE);

void setup()
{
  Oled2.begin();
  Oled2.setFlipMode(true);
  Oled2.setFont(u8x8_font_7x14B_1x2_r);

  Pressure.begin();
}

void loop()
{
  Oled2.clear();

  Oled2.setCursor(0, 10);
  Oled2.print("Temp: ");
  Oled2.print(Pressure.readTemperature());
  Oled2.print(" C");

  delay(1000);
}

```

Could you please try out and report your experience. If it would work, I can support the fixing of the issue.
> 3 votes

---
Tags: arduino-uno, i2c
---


# Question
Title: Not able to build program with arduino program under clion
I'm pretty new to arduino and I just downloaded clion and installed the arduino plugin so I have an IDE that I'm used to. Here is my code:

```
#include <Arduino.h>

// Time between a switch indicating not full and the time a valve is opened
#define SWITCH_DELAY 5000

#define PIN_SWITCH 2
#define PIN_GREEN 3
#define PIN_YELLOW 4

#define INT16 int
#define UINT16 unsigned int
#define UINT32 unsigned long

DelayChecker    degassingChecker(PIN_SWITCH, PIN_GREEN);

void setup() {
    pinMode(PIN_SWITCH, INPUT);
    pinMode(PIN_GREEN, OUTPUT);
    pinMode(PIN_YELLOW, OUTPUT);

    Serial.begin(9600);
    Serial.print("UINT16: " + sizeof(UINT16));
    Serial.print("UINT32: " + sizeof(UINT32));
}

void loop() {
    UINT32 now = millis();

    degassingChecker.check(now);
}

public class DelayChecker {
    private:
        UINT32 delayExpires = 0;
        UINT16 switchId = 0;
        UINT16 solenoidId = 0;
        bool solenoidOn = false;

    public:
        DelayChecker(const unsigned int sw, const unsigned int sol) {
            switchId = sw;
            solenoidId = sol;
        }

        void check(const UINT32 now) {
            if (delayExpires == 0) {
                INT16 switchState = digitalRead(switchId);
                if (switchState == LOW) {
                    delayExpires = millis() + SWITCH_DELAY;
                    digitalWrite(PIN_YELLOW, HIGH);
                }
            }
            else {
                if (now >= delayExpires) {
                    INT16 switchState = digitalRead(switchId);
                    if (switchState == LOW) {
                        if (!solenoidOn) {
                            digitalWrite(solenoidId, HIGH);
                            solenoidOn = true;
                        }
                    }
                    else {
                        if (solenoidOn) {
                            digitalWrite(solenoidId, LOW);
                            solenoidOn = false;
                        }
                    }
                }
            }
        }
};

```

I hit the run button and get the following.

```
====================[ Build | untitled1 | Debug ]===============================
/opt/clion/bin/cmake/linux/bin/cmake --build /home/thomas/CLionProjects/untitled1/cmake-build-debug --target untitled1 -- -j 12
[  7%] Building C object CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/wiring_pulse.c.obj
[  7%] Building CXX object CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/new.cpp.obj
[ 10%] Building C object CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/wiring_shift.c.obj
/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/new.cpp:29:46: error: expected initializer before 'noexcept'
 void * operator new(size_t size, void * ptr) noexcept {
                                              ^~~~~~~~
gmake[3]: *** [CMakeFiles/uno_CORE.dir/build.make:317: CMakeFiles/uno_CORE.dir/opt/arduino-1.8.13/hardware/arduino/avr/cores/arduino/new.cpp.obj] Error 1
gmake[3]: *** Waiting for unfinished jobs....
gmake[2]: *** [CMakeFiles/Makefile2:99: CMakeFiles/uno_CORE.dir/all] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:133: CMakeFiles/untitled1.dir/rule] Error 2
gmake: *** [Makefile:151: untitled1] Error 2

```

It looks like an error in the libraries. Has anyone seen anything like this?

# Answer
> 2 votes
I found a github issue fixing this error : https://github.com/vsch/CLionArduinoPlugin/issues/36

It worked for me

---
Tags: c++, library
---


# Question
Title: Cannot program two arduinos at the same time because they both use the same COM port
I am not able to program my second arduino because they both use the same com port. In other words this picture says it all:

In order to upload my sketch I have to disconnect one arduino. How can I tell windows to use a different COM port?

It will be nice if I do not have to disconnect one arduino evey time I want to upload a sketch. I already restarted my computer and I get the same problem.

# Answer
> 20 votes
I did not knew I could change the port on windows. This is how I did it thanks to @Majenko's comment.

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


# Question
Title: 16x2LCD Display serial read extra character
I get extra character (frowning face) when sending a text over the serial monitor(see attached image)

When empty string is sent over the serial monitor, the LCD display still shows the extra character of frowning face.

How do I get rid of the extra character?

I use the tutorial code below and change nothing in the code. https://www.arduino.cc/en/Tutorial/LibraryExamples/LiquidCrystalSerialDisplay/

```
#include <LiquidCrystal.h>

    // initialize the library by associating any needed LCD interface pin
    // with the arduino pin number it is connected to
    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void setup() {
      // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);
      // initialize the serial communications:
      Serial.begin(9600);
    }

    void loop() {
      // when characters arrive over the serial port...
      if (Serial.available()) {
        // wait a bit for the entire message to arrive
        delay(100);
        // clear the screen
        lcd.clear();
        // read all the available characters
        while (Serial.available() > 0) {
          // display each character to the LCD
          lcd.write(Serial.read());
        }
      }
    }

```

# Answer
> 1 votes
The LCD display acts a bit different to a normal console. For instance, it does not recognize the newline character and uses the corresponding ASCII code (10) like a normal letter. Depending on the letter map of your display (for which there are several variants on the market) this will print a more or less random character. To avoid this, you have to strip the last letter from the input string before sending it to the display.

For the same reason, sending an empty string does nothing, since an empty string sends no letters. To clear individual characters in the display, you have to overwrite them with a space.

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


# Question
Title: Is it possible to generate an exact 15 kHz clock pulse using an Arduino?
I want to generate a 15 kHz pulse with an Arduino using Timer1, but the problem is that if we want a 15000 Hz clock we need to initialize the timer with *1/15000* seconds or *66.66* microseconds, but we can only pass integers without any decimal precision in the `Timer1.initialize(66);` function which generates a frequency of 15155 Hz.

So is it possible by any other means to generate an exact *15000 Hz* or frequencies between *15000 Hz - 15155 Hz*?

```
#include <TimerOne.h>

void setup() {
  pinMode(9,OUTPUT);
  Timer1.initialize(66);  // Frequency, 100 µs = 10 kHz
  Timer1.pwm(9,255);
}

void loop() {}

```

# Answer
> 20 votes
You can get pretty close if you program Timer 1 directly (not through the library), and have it run with the prescaler set to 1. Ideally, you want the period of the timer in clock cycles to be:

F\_CPU / 15 kHz = 16,000 kHz / 15 kHz ≈ 1066.67 CPU cycles

If you round this to the nearest integer, you get

F\_CPU / 1,067 = 16,000 kHz / 1,067 ≈ 14.9953 kHz

This is about 0.03% too slow, well within the tolerance of the ceramic resonator clocking the Uno.

Here is my attempt at this. I have tested it.

```
constexpr float PWM_FREQUENCY = 15e3;  // 15 kHz
constexpr uint16_t PERIOD = round(F_CPU / PWM_FREQUENCY);

void setup() {
    // Configure Timer 1 for 15 kHz PWM on pin 9 = PB1 = OC1A.
    DDRB  |= _BV(PB1);    // set pin as output
    TCCR1B = 0;           // stop timer
    TCCR1A = _BV(COM1A1)  // non-inverting PWN on OC1A
           | _BV(WGM11);  // mode 14: fast PWM, TOP = ICR1
    TCCR1B = _BV(WGM12)   // ditto
           | _BV(WGM13)   // ditto
           | _BV(CS10);   // clock @ F_CPU
    ICR1   = PERIOD - 1;  // period
    OCR1A  = PERIOD / 4;  // duty cycle
}

void loop(){}

```

# Answer
> 10 votes
Since the timer1 library only accepts whole numbers for the µs parameter you get a error. You could skip using the library and configure the timer directly. Or you could have a look at the source code of the library, and see that you can kind of bypass the limitation it has by only calculating a more accurate value for the `ICR1` register.

Look at `cycles = ((F_CPU/100000 * microseconds) / 20);`. If you were to insert your 66.66666µs into this, instead of 66µs, you'd get `533` instead of `528`.

This value is then used to set the PWM frequency in line 213. So you'd need to overwrite the `ICR1` register with the more accurate value.

Your final code should look like:

```
pinMode(9,OUTPUT);
Timer1.initialize(66);
ICR1 = 533;
Timer1.pwm(9,255);

```

PS you might need to tweak this 533 value to get an even more accurate resulting frequency.

# Answer
> 6 votes
A better way to do the above *average* 15 kHz (or any other frequency) is with a phase accumulator scheme. There are no IF tests; on each tick of an interrupt, you add a step to an accumulator and output the state of its MSB. This can give incredible resolution, and is probably the best you can do. But though the *average* frequency will be dead-on, the jitter can be terrible. I use this method in my open-source DaqPort sketch https://www.daqarta.com/dw\_rraa.htm#00ff, which is used by DaquinOscope https://www.daqarta.com/dw\_rroo.htm and Arduino\_Oscillators https://www.daqarta.com/dw\_rrss.htm mini-apps running in Daqarta. There's also a Jitter\_Tbl macro to compute the jitter for arbitrary sample rates and output frequencies. Although not relevant here, this phase accumulator method can also go to exceptionally *low* frequencies, into the micro-hertz range, and the jitter is extremely small there.

# Answer
> 3 votes
I can get within 5 Hz of 15,000 using a 16 MHz clock on a Nano, Uno or 2560. Here is the code...

```
// RTM_TimerCalc 1.20
// Timer-1 Mode_14_16Bit_Fast_TOP_is_ICR

TCCR1B = 0x18; // 0001 1000, Disable Timer Clock
TCCR1A = 0xA2; // 1010 0010

ICR1 = 1067-1;
OCR1A = (int) (ICR1 * 0.25);
OCR1B = (int) (ICR1 * 0.50);
TCNT1=0x0;

// UnComment following lines for UNO-NANO Timer-1 Pins
// pinMode(9, OUTPUT);  // OC1a
// pinMode(10, OUTPUT); // OC1b

// UnComment following lines for 2560 Timer-1 Pins
// pinMode(11, OUTPUT);  // OC1a
// pinMode(12, OUTPUT);  // OC1b

TCCR1B |= 1; // Prescale=1, Enable Timer Clock

```

Here is the Error Results... ASK: 15,000 Hz CALC: 14,995.3139643861 Hz OFFSET: -4.6860356139 Hz

hth

# Answer
> 2 votes
*In answer to a comment from the OP asking for another microcontroller that can do this, and in addition to Majenko's reply comment:*

A SAMD21G running at 48 MHz (as seen on some Arduinos) can make 15 kHz, in several ways.

Note that this assumes that the clock is exactly 48 MHz, and stable, and both assumptions could well be wrong, unfortunately. It helps if the clock is derived from a crystal; not all SAMD21G-based Arduinos do that, if any. This possible lack of clock precision and stability applies to all MCUs.

The SAMD21G does have a fractional PLL, and you can of course adjust the PER register, so some fine-tuning is possible if you have the equipment to measure the actual output frequency.

If you decide to go with one of the SAMD21G-based Arduinos: there is a PWM library for those (I know it well, as I wrote it) that will let you set a clock divider, a prescaler, and a resolution, which should make it easy enough to arrive at a (nominal) 15 kHz. There's a frequency table under "extras".

# Answer
> -1 votes
Yes, you can. Sort of...

A 66.6 µs delay means one delay of 66 µs and then two delays of 67 µs. You could keep a close loop that calculates the micros() divided by 66 and modulo by 2 for every iteration. This will give you an alternating 1 and 0. Save the previous value to check this value for a change and digitalWrite HIGH or LOW.

I have no means at the moment to test the code, but in (semi-pseudo) code this would look something like:

```
void loop()
{
  int freq=15000;
  float interval = ((float)1000000/(float)freq)/2;//33.333333
  byte state=0;
  byte previousState=0;
  while (1)
  {
    unsigned long currentMicros=micros();
    previousState=state;
    state = (unsigned long)((float)currentMicros / interval) % 2;
    if (state==1 && previousState==0) digitalWrite(9,HIGH);
    if (state==0 && previousState==1) digitalWrite(9,LOW);
  }
}

```

This method will guarantee that after one second exactly 15000 periods have passed. The timing of the individual periods, however, might vary a little.

---
Tags: arduino-uno, pwm, timers, frequency
---


title: SIM7000E Waveshare can't do anything

text:
# Question
Title: SIM7000E Waveshare can't do anything
Can someone help me? I'm using a sim7000e from Waveshare. One week ago it was working normally, but now it doesn't work at all; it even can't read the RX-TX communication.

```
#include <SoftwareSerial.h> //koneksi ke modem

#define TINY_GSM_MODEM_SIM7000
#define TINY_GSM_DEBUG SerialMon
#define BAUD 9600
#define SerialMon Serial

const byte rxpin = 2;
const byte txpin = 3;

SoftwareSerial SerialAT(rxpin, txpin); // RX, TX

```

That's my code for connecting to the Arduino. I believe it from my Arduino, but I don't know if something wrong from Arduino.

My 5V (sim7000E) to 5V (arduino mega2560), GND to GND.

Because I'm using Putty on USB for reading my AT-cmd it doesn't and has some trouble.

# Answer
I'm having similar issues, although it could well be my fault!

I can't see any coding sending AT commands, or waiting for responses in your example.

Try running your TX pin to your RX pin on your Arduino (take the SIM7000e out of the equation completely). If your code works, then the issue is elsewhere.

I've tried connecting via USB and that seems through a terminal. I was able to connect to a mobile network using the AT command

AT+CSTT="cmnet"
> 2 votes

---
Tags: serial, arduino-mega, communication
---


title: Is there a 3.3V and 12V 18650 circuit?

text:
# Question
Title: Is there a 3.3V and 12V 18650 circuit?
Is there an all in one circuit which regulates charging, protects and steps up/down an 18650 battery to 12V and 3.3V at the same time, so I can power a sensor and my ESP32?

# Answer
> 3 votes
I would suggest using a 12V controller, and then adding a 3.3V switching regulator using the 12V supply. That would be 2 off-the shelf components and you're done.

---
Tags: esp32, battery, voltage
---


title: What's wrong with the ACS712 sensor?

text:
# Question
Title: What's wrong with the ACS712 sensor?
I have two ACS712 sensors, one rated for 5A, another—for 20A.

I wanted to test how precise they are, and played with different devices (in my case, old PC fans). I copy-pasted the source code from here, and changed only the `Vref` value as expected, so that I get a measurement of zero when there is no current. I double-checked, the value remains zero for both ACS712 sensors. The sensor (or the multimeter) is connected in series. Only one sensor (or multimeter) is connected at the same time.

Here's the data I get. Values in parenthesis correspond to the percentage of the value compared to the one got with a multimeter.

| Setup | Measured by
a multimeter | Measured by
ACS712 5A | Measured by
ACS712 20A |
| --- | --- | --- | --- |
| Old CPU fan | 87 mA | 73 mA (84%) | 49 mA (56%) |
| UPS fan rated 1.9 W | 174 mA | 170 mA (97%) | 97 mA (55%) |
| Two fans together | 0.25 A | 244 mA (98%) | 146 mA (55%) |
| Server fan rated at 0.6 A | 0.49 A | 463 mA (95%) | 268 mA (55%) |
| Three server fans | 1.35 A | 1,293 mA (96%) | 683 mA **(51%)** |

While the 5A variant seems to be slightly off (another possibility would be that the multimeter is off and the ACS712 measurements are exact), things are very different for the 20A-rated counterpart: its values are wrong initially, **and for higher current, they are getting wronger**.

Why is it so? Is it broken, or have I missed something?

# Answer
> 4 votes
Your problem is that you are trying to measure motes of dust with a yard stick. The yard stick is great at measuring things in inches and feet, but when you want to find the size of something that's around 1mm in size all you can say is "it's less than an inch" or "smaller than an eighth of an inch".

You have to remember that a 20A sensor has to fit that whole range of 0-20A - that's 0-20,000mA into half the range of the ADC. That's at most 512 graduations on an Arduino, and since you can usually count on "±1 LSB quantisation noise" you really only get half that as a usable value. So you're looking at a resolution of about 40mA at best with an accuracy of ±40mA. When you want to measure small currents they're just going to get lost in the lack of resolution. At 100mA you're still only in the range of just "There might be a current there, somewhere".

For measuring current you need to size your sensor / shunt appropriately to the range of the currents you're sensing. If you're working with small variations in a large DC current then pre-conditioning the sensing to change the offset and amplify the interesting part of the signal is required, so that the signal isn't swamped by the underlying offset. If you're working with small currents then you require a sensor / shunt that gives you an appropriate signal for that current range.

Additionally, different variants of the sensor have different sensitivity: 185 mV/A for the 5A model, and 100 mV/A for the 20A model. The code you are using doesn't take this in account. Using the correct sensitivity, the last value in your table, 683 mA, becomes 1,264 mA (683×185/100=1264). This is close enough, if you consider the ±40mA accuracy.

---
Tags: current
---


# Question
Title: I'm working on a NodeMCU project and have a small doubt about LEDs and resistors
In my NodeMCU I want a statement to turn on an LED, which is easy, just use `pinnumber, HIGH`. But, what I'm trying to do here is connect multiple LEDs to one pin like this:

I just wanted to know if this will work and whether all the LEDs will turn on by one command write `(pinnumber, high)` or do I have to do something else to this circuit? Please help I'm a noob to electronics.

And also, is the resistor correct(1k ohm) or is it 220ohm, because different places suggest different things.

# Answer
No! Most likely it will not work.

An LED lights up if the Voltage between the Anode (one side of the LED) and cathode (the other leg) exceeds a so called forward voltage (Vf).

This Vf depends on the creation process and differs between different colors. Vf can be between abt. 1.8 Volt (red LEDs) and abt. 4.2 Volt (blue LEDs). Even if the LEDs would have the same color, they might have different forward voltages. If you arrage 4 LEDs in parallel, like you did above, the Voltage over the 4 LEDS is as low as the Vf of the LED with the lowest Vf among the four. If the four LED would not have equal (Vf)s, only one LED will light up and all others stay dark or just glow a little bit.

The sum of the current that flows through the 4 LEDs must also flow through the resistor. So the resistor must let pass 4 times the current that is required for one LED. An normal 3mm or 5mm LED works best at about 10mA to 20mA. Let's say the LEDs have all the same Vf = abt. 2 Volts, and you choose to drive them with 15 mA. You need 60 mA in sum for the 4 LEDs, that must pass the resistor. You can compute the required resistance with Ohms law. `R = U / I`.

* R is the resistance in Ohms.
* U is the voltage over the resistor in Volts.
* I is the current through the resistor in Ampere.

U = Voltage of the ESP (3.3 Volt) minus the lowest forward voltage of the LEDs (2 Volt) I = the wanted current 60mA = 0.06 Ampere

R = (3.3-2) / 0.06 = 140 / 6 = abt. 23 Ohm (27 Ohm resistors should be available.)

The resistor depends on the Voltage of the ESP, the kind of the LED and the amount of current you need to reliably light up the LEDs. You can not just take values from schematics or discussions the internet. Also 60 mA is very much current for the ESP pin. That might be a problem.

The best way the Light up 4 LEDs from one pin would be to use one resistor for each LED and a MOS FET Transistor that is connected to 5 Volts with its Drain pin, the parallel LED resistor pairs with its Source and to the ESP pin with its Gate. You should also be sure that the MOS FET you use is able to switch with a 3.3 V voltage from the ESP on its Gate.

If you did not understand what I have written, I advice you to learn the basics before experimenting further. The values above are all useless if the conditions change.
> 3 votes

# Answer
Yes, technically your circuit works. But don't do like this.

TLDR;

This applies only to what you are doing

1. LED is current device. We control brightness by control current flow through it.
2. Each IO pin (of ESP8266) has current drive capable (source/sink) 12mA only, so calculate it wisely or you risk killing it.
3. Simplest way to control current of LED is using current limiter or just a resistor in series
4. Voltage drop across red LED (Vf) is 1.8v
5. 4 LEDs in parallel work just like 1 LED, assuming the same kind, but of course 4 times dimmer
6. Current goes through each LED = 1/4 of current goes through resistor (kirchhoff law of current)
7. Equation: 3v3 = 1.8v + V\_R hence , V\_R = 1.5v
8. Current goes through resistor I\_R = V\_R / R
9. 5mm LED has nominal current of 20mA to be considered brightest that last VERY long time.
10. BUT ESP8266 can only do 12mA. You go 20mA, ESP8266 goes bye bye.
11. So choose 10mA to be on safe side. Plug 10mA into #8, hence R = 1.5v / 10mA = 150 ohm
12. You can choose resistor value from 220R up to 1K, no problem. Higher resistance, less current.
13. You can do rough calculation, ignore voltage drop across LED, just use 3v3 / 10mA = 330R. Hence you will see people usually use resistor 330 ohm regardless 3v3 or 5v, red LED or green LED. Because at 5v it is 15mA, red or green makes only 0.3mA different. Nothing to worry.
14. But your circuit has 4 LEDs in parallel, hence current through each LED = 10mA/4 = 2.5mA
15. Fact: Even as low as 0.15mA (R=10k with 3v3 power supply), RED and GREEN LEDs are still bright enough for indication.

Note:

* My guess is, you are using LEDs like a torch. More LEDs = more brightness, right? Unfortunately, it won't work like that. You want to use transistor (BJT) or mosfet as a switch to turn on power supply for LED instead of driving LED from IO pin. Google high side switch or low side switch for that matter. Better solution is to use LED driver IC.
* Normally for simple indicator, I just whack a 470R resistor in series of a LED regardless voltage to drive it (5v or 3v3). It still gives quite intense brightness when you stare directly on it. Sometime you want to use 1k ohm just to reduce the brightness further or even sanding the LED from crystal clear into translucent white.
> 1 votes

---
Tags: led, nodemcu, voltage-level, electronics, electricity
---


# Question
Title: Which Arduino for many analogue sensors (and WiFi)?
For context, I come from a very software-heavy background so I know very little about hardware.

I'm looking to build a system that requires at least 6 sensors (pH, electrical conductivity, humidity, temperature, light intensity, flow rate), and I want to send all of this input over WiFi at ~10 minute intervals. Most of these sensors will be analogue.

I noticed that for example the Arduino Uno only has 6 analogue inputs. Plus from research, I would need to connect a WiFi module to the Uno which seems too much of a hassle and added cost.

I'm looking at the ARDUINO NANO 33 IOT right now. It seems perfect for what I want to do since it's cheap, has 8 analogue pins, and has WiFi out-of-the-box. Is my reasoning correct in choosing this Arduino? I'm wondering why something with WiFi capability and more pins is cheaper than the Uno.

Thanks in advance!

# Answer
> 3 votes
For short answer: Just use NodeMCU ESP32 or any ESP32 dev board.

TLDR;

ESP32 is actually a wifi module but has very powerful processor (240MHz max), way more faster than Arduino Uno (atmega328 @16MHz). Because of this, wifi comes as natural for ESP32.

You can even buy ESP32 dev board around US$10 (include shipping) while the esp32 module itself costs only $5

Arduino UNO 33 IOT is simply SAMD21 (@48MHz) with external wifi module. This wifi module alone costs about US$10. This configuration is similar to Arduino UNO + wifi shield but of course cheaper because you don't need an extra costly shield for wifi.

The expensive wifi shield is actually HDG204 wifi SIP (system in package) + 32-bit AVR AT32UC3C1512C (66MHz max). Pretty much the wifi shield piggy back on Arduino UNO is 4 times faster than 8-bit micro atmega328 of Arduino UNO. So... it's pricey.

*Edit:*

ESP32 has 2x 12-bit ADC with 16 channels exposed out to IO pin on most of ESP32 dev board.

If you just read some temperature sensors, range finder sensors, humidity sensors... You are good with most of ADC inside microcontrollers these days. Unless you are building instrumentational device, well, this is a whole different story.

# Answer
> 0 votes
Doesn't matter the number of analog pins if you're doing 10 minute polls.

Run the power to each sensor from its own digital pin. Connect the sensor outputs to a single analog pin. Note that any analog pin can be used as a digital pin, but not vice-versa.

Start with all sensors turned off (ie. the individual digital power pins turned `LOW`). When you poll, turn `HIGH` a single sensor's digital pin, read the output on the analog pin, and then power back down the sensor. Move on to sensor two, sensor three etc.

This is pretty much multiplexing the analog pin. I do this all the time in my indoor grow room environment automation systems.

Typically I use Wemos D1 minis for the task, or NodeMCU-12e devices. The last batch of D1 minis I paid less than $10 for five of them, shipping and taxes included. Both devices I mentioned have wifi and bluetooth inherent. I even reprogram them over the air (OTA).

---
Tags: arduino-uno, arduino-nano-33-iot
---


title: ESP send string to Arduino

text:
# Question
Title: ESP send string to Arduino
I'm trying to send a string from an ESP32 to an Arduino. I'm using a level shifter, where the Uno is now the Mega (since I couldn't get the Uno to work).

RX0 is now RX1, connected to UART2 of ESP32.

```
// Master sender ESP32

#include <HardwareSerial.h>

void setup() {
  // Serial.begin(115200);
  Serial2.begin(9600, SERIAL_8N1, 16, 17);
  delay(100);
}

void loop() {
  String shape = "1,2,3";
  Serial2.println(shape);
  delay(500);
}

```

---

```
//Receiver Mega

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial1.begin(9600);
  Serial.begin(19200);
  delay(100);
}

void loop() {
  if (Serial1.available()) {
    String received = "";
    received = Serial1.readString();
    Serial.println(received);
  }
}

```

Is there something in either sketch that should be changed?

# Answer
> 2 votes
readString**Until**('\n')

```
//Receiver Mega

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial1.begin(9600);
  Serial.begin(19200);
  delay(100);
}

void loop() {
  if (Serial1.available()) {
    String received = "";
    received = Serial1.readStringUntil('\n');
    Serial.println(received);
  }
}

```

It's about how `Serial.readString()` works: it reads from the serial port forever in this case. It stops reading if the serial interface is given a time-out. There are two possibilities:

* use `readStringUntil()` on the receiver
* call `mySerial.setTimeout(300);` (from `setup()`) to set a 300ms (for instance, as long as it's significantly less than 1000) time out on the receiver — it defaults to one second!

---
Tags: serial, esp32, uart, esp
---


# Question
Title: Is there something like a Virtual Environment for Arduino?
I'm using Arduino IDE for a variety of projects.

The libraries and boards used in different projects are different and I would like to have a customized environment for each project.

Eg: In a project involving an Arduino, I don't want all the ESP boards or Adafruit libraries that I might use on another project.

Python has something called Virtual Environments, where you can switch between environments and have a different setup of libraries and configurations for each project.

Is there something like this I can configure for Arduino?

# Answer
> -1 votes
Sorry, but in Arduino IDE no such functionality as virtual enviroment. To add your own version of libraries to each projects you may only add it (libraries) directly to a project dir.

---
Tags: arduino-ide
---


# Question
Title: Can Arduino uno adjust input square wave duty, phase and frequency with just timer-counter?
Requirement:

* I have input 4KHz pulse input
* Divide it's frequency in half
* Arbitrarily adjust phase
* Arbitrarily adjust duty
* Out put the modified pulse

My solution (CPU):

```
uint8_t cnt = 0;
uint16_t t1 = 235;
uint16_t t2 = 5;
String cmd;

void setup() {
  pinMode(3, OUTPUT);
  pinMode(2, INPUT);

  Serial.begin(9600);
  delay(500);
  attachInterrupt(digitalPinToInterrupt(2), rising_edge, RISING);
  Serial.println("PWM init");
}

void loop() {
  if (Serial.available() > 0) {
    cmd = Serial.readString();

    if (cmd.substring(0,8) == "setdelay"){
      t1 = cmd.substring(9).toInt();
      Serial.print("setting delay to ");
      Serial.print(t1);
      Serial.println(" us");
    }
    else if (cmd.substring(0,7) == "sethigh"){
      t2 = cmd.substring(8).toInt();
      Serial.print("setting high time to ");
      Serial.print(t2);
      Serial.println(" us");
    }
  Serial.flush();
  }
}
void rising_edge() {
  cnt = cnt + 1;
  if (cnt >= 2) {                           //divide by 2
    delayMicroseconds(t1);
    digitalWrite(3,HIGH);
    delayMicroseconds(t2);
    digitalWrite(3,LOW);
    cnt = 0;
  }
}

```

However this makes heavy use of CPU, and I need to use CPU for something else.Is it possible to implement all this with TC ?

Thanks in Advance !

# Answer
> 1 votes
> this makes heavy use of CPU, and I need to use CPU for something else

The issue with this code is that is heavily uses the CPU for *busy waiting* rather than for doing useful work. You should try to get rid of those waiting loops:

For the pulse generation, you can keep roughly the same logic as your existing code: output a single pulse every other time a rising edge is sensed on the input. This pulse can be conveniently generated by Timer 1 on pin 9 by using a PWM mode and stopping the timer after a single cycle. I would use inverting PWM mode, with the timer starting at zero on the input pulse:

* at `t1` microseconds, a compare match sets the output HIGH
* at `t1+t2` microseconds, the timer overflow sets the output LOW, and the overflow interrupt stops and resets the timer

Here is a tentative, untested implementation:

```
// Set the pulse timings. To be called from loop() on user's request.
void set_timings(uint16_t t1, uint16_t t2)
{
    uint16_t ocr1a = t1 * 16 - 1;        // initial time in LOW state
    uint16_t icr1 = (t1 + t2) * 16 - 1;  // timer period
    noInterrupts();  // protect critical section
    OCR1A = ocr1a;
    ICR1 = icr1;
    interrupts();
}

// Configure Timer 1. To be called from setup().
void setup_timer() {
    DDRB  |= _BV(PB1);    // set pin digital 9 = PB1 = OC1A as output
    TCCR1A = _BV(COM1A0)  // PWM on OC1A, inverting mode
           | _BV(COM1A1)  // ditto
           | _BV(WGM11);  // mode 14: fast PWM, top = ICR1
    TCCR1B = _BV(WGM12)   // ditto
           | _BV(WGM13)   // ditto
           | 0;           // stopped
    TCNT1  = 0;           // reset
    TIFR1  = _BV(TOV1);   // clear overflow flag
    TIMSK1 = _BV(TOIE1);  // enable overflow interrupt
    set_timings(235, 5);  // initial timings
}

// Interrupt triggered by a rising edge of the input.
void on_rising_edge() {
    static uint8_t count;
    if (++count % 2) return;   // divide by 2
    TCCR1B |= _BV(CS10);       // start timer, clock @ F_CPU
}

// Stop and reset the timer when it overflows.
ISR(TIMER1_OVF_vect) {
    TCCR1B = 0;  // stop
    TCNT1  = 0;  // reset
}

```

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


title: Ok to Connect 2.9V Stepper to 3.3V pin?

text:
# Question
Title: Ok to Connect 2.9V Stepper to 3.3V pin?
So I have a stepper motor that's rated for 2.9V and 0.8A and I connected it to a L9110 Driver and I wanted to drive it with my arduino. But I don't know how to drive it safely without damaging the motor. I am using the stepper.h library and thought of connecting it to 3.3V pin on the Arduino but I am a bit concerned.. is it Ok to power it with 3.3V if no then What can I do?

Edit: the L9110 module I am using is a dual H Bridge.

Edit2: I was Indead Powering the Stepper and the Module directly from the arduino.. luckily the arduino survived.

Edit3: So I didn't have a 3V power supply so I used a Voltage Divider with a 9V battery and connected the L9110s module with the battery (after its voltage divided) and the module powers on.. but when the arduino starts driving the stepper the module's led starts Flickering instead of staying on and the stepper doesn't turn... I don't know what is the problem.

# Answer
> 3 votes
Motors draw a LOT of current compared to CMOS circuits.

The 3.3V output on most Arduinos can only provide a very small amount of current. The Arduino Uno, for example, says it only provides a max of 50mA from its 3.3V regulator. Your motor driver probably needs \>10X more than that.

The overload protection on the Arduino's voltage regulator will probably kick in and cause it to shut off. It might take a while to cool down before 3.3V output comes back. I've heard that the protection on Arduino knockoffs doesn't always work, so you could also fry the voltage regulator if you try to draw too much from it.

Bottom line: **Don't do that.**

Get a high current supply for your motor driver.

---
Tags: power, stepper-motor
---


# Question
Title: Programming AT24C16 EEPROM with Arduino Nano
I have been trying to program an AT24C16 EEPROM and have set up a circuit as per the attached image.

I have been using the following Arduino code:

```
#include <Wire.h>

#define disk1 0x50    //Address of 24LC256 eeprom chip

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

  unsigned int address = 10;

  writeEEPROM(disk1, address, 72);
  Serial.println(readEEPROM(disk1, address), DEC);
}

void loop(){}

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(data);
  Serial.println(Wire.endTransmission());

  delay(5);
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
  byte rdata = 0xFF;

  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Serial.println(Wire.endTransmission());

  Wire.requestFrom(deviceaddress,1);

  if (Wire.available()) rdata = Wire.read();

  return rdata;
}

```

Unfortunately I only ever receive '255' in the serial monitor suggesting that no data has been written.

The code was from this tutorial which explains how the wiring on pins 1-3 governs the address of the chip.

# Answer
Well, I think I see part of what is happening. I'm not sure to what degree this is an Arduino problem, but it may be of some use to someone wanting to interface this chip with an Arduino. So, here's what I see:

You're writing to the chip just fine so far as I2C is concerned. But the content of what you're writing is not exactly correct to the chip itself.

You have:

```
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8));   // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB

```

Which is intuitive, but unfortunately not how the AT24C16 apparently works. To be clear, the tutorial you've referenced uses the 24LC256, which *does* use the addressing scheme above. But you're not using that chip.

The chips in the series covered by the AT24LC16 datasheet need progressively larger EEPROM addresses for the larger memory sizes. As the size of the chip increases they are effectively stealing configurable bits from the A0, A1, A2 pins and repurposing them as part of the EEPROM address **encoded into** the I2C address. You'll see that the for up to the 2Kbit/256byte/8-bit addressable EEPROM, all of A0, A1, A2 can be used to set the I2C address (to have multiple of these chips). By the time you work your way up to the 16kbit/2kbyte/11-bit addressable chip, all of the A0, A1, A2 are specified as **no connect**; the datasheet says that *can* be connected to ground. The reason for doing this probably just for controlling noise.

The chip expects only the lower 8 bits of the EEPROM word address to be sent in the data portion of the I2C write (or "dummy" write). But the bits in excess of 8-bits, the upper 3-bits for your 11-bit addressable, are expected to be encoded into the I2C address itself, like so:

```
const uint8_t i2c_base_address = 0x50;
const uint8_t upper_three_eeprom_adress_bits = (eeaddress >> 8) & 0x7;
const uint8_t i2c_address = i2c_base_address | upper_three_eeprom_adress_bits;
Wire.beginTransmission(i2c_address);
Wire.write(eeaddress & 0xFF); // address LSB

```

---

The datasheet speaks of "BYTE WRITE" where single bytes per I2C write transactions are written to EEPROM. And it speaks of "PAGE WRITE" where an entire page payload is sent, 16-bytes for your model. Because you are sending two bytes as part of data portion of the I2C write, **you are doing neither of these things**. The chip's notion of "current address" is updated differently for "byte" vs "page" writes.

If I had guess, they didn't want there to be a qualitative difference in handling 1 vs 2 byte I2C write transactions or alternately between 15 (page size minus one) vs 16 (page size) byte I2C write transactions. So, they just decided anything in the middle ground between a single byte write and an entire page write should be ignored, so no EEPROM write operation carried out.
> 1 votes

# Answer
In response to the answer from @timemage I updated my code which now allows me to read and write to the EEPROM chip as intended. Here is the code just in case anyone else wants it quickly:

```
#include <Wire.h>

#define disk1 0x50    //Address of eeprom chip

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

  unsigned int address0 = 0;

  writeEEPROM(disk1, address0, 1);

  Serial.println(readEEPROM(disk1, address0), DEC);
}

void loop() {}

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{

  const uint8_t i2c_base_address = 0x50;
  const uint8_t upper_three_eeprom_adress_bits = (eeaddress >> 8) & 0x7;
  const uint8_t i2c_address = i2c_base_address | upper_three_eeprom_adress_bits;
  Wire.beginTransmission(i2c_address);
  Wire.write(eeaddress & 0xFF); // address LSB

  Wire.write(data);
  Wire.endTransmission();

  delay(5);
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
  byte rdata = 0xFF;

  const uint8_t i2c_base_address = 0x50;
  const uint8_t upper_three_eeprom_adress_bits = (eeaddress >> 8) & 0x7;
  const uint8_t i2c_address = i2c_base_address | upper_three_eeprom_adress_bits;
  Wire.beginTransmission(i2c_address);
  Wire.write(eeaddress & 0xFF); // address LSB

  Wire.endTransmission();

  Wire.requestFrom(deviceaddress, 1);

  if (Wire.available()) rdata = Wire.read();

  return rdata;
}

```
> 2 votes

---
Tags: arduino-nano, eeprom
---


title: arduino mega buzzer output

text:
# Question
Title: arduino mega buzzer output
I have project by Arduino mega which have 22 inputs and 22 outputs and buzzer reset and output reset pushbuttons , it have two status

1. if the input is high(not continuous ) the output will on and the buzzer will be on, if output reset pushbutton is pressed the output will off , if buzzer reset pushbutton is pressed the buzzer will off.
2. if the input is always high (continuous high signal on input ) the output will on and the buzzer will be on, in this case we will not reset the output even if the output reset pushbutton is pressed , and we will be able to reset the(turn off) buzzer by the buzzer reset pushbutton, and wait until input state to change to high again to repeat procedure

help me with editing my code

```

    //int input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,23,24}; //input pins (23 for reset ,24 for buzzer reset)
//int output[] = {26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 24, 34, 44, 45, 46, 47, 48,49}; //output pins (49 for buzzer)

int in1 =     2;

int in25 =   26;// for output reset
int in26 =   27;// for buzzer reset

///////////////

int out1 = 28   ;

int out24= 51   ;
int out25= 52   ; // output for buzzer

////////////////////////////////////

int buttonState1 =  0;

int buttonState24 =  0;
int buttonState25 =  0; //for  reset
int buttonState26 =  0; //for buzzer reset

//unsigned long previousMillis = 0;        // will store last time buzzer was updated
//const long interval = 10000;           // interval at which to buzzer (milliseconds)
//int buzzerState = LOW;             // buzzerState used to set the buzzer

void setup() {

  pinMode(in1 , INPUT);

  pinMode(in24 , INPUT);
  pinMode(in25 , INPUT);
  pinMode(in26 , INPUT);

///////////////////////////

pinMode(out1, OUTPUT);
pinMode(out2, OUTPUT);

pinMode(out24, OUTPUT);
pinMode(out25, OUTPUT);

digitalWrite(out25, LOW); // buzzer LOW

}

void loop() {
  buttonState1 = digitalRead(in1);
  if (buttonState1 == HIGH) {
    digitalWrite(out1, LOW);
    //digitalWrite(out25, LOW);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState25 = digitalRead(in25); //read reset button state from input (25) pin 26
  if (buttonState25 == HIGH )

  {
    digitalWrite(out1, HIGH); //reset out1
    //digitalWrite(buzzer, LOW);
  }

  //else {
   // buttonState26 = digitalRead(in26); //read the buzzer reset button state from input (26)pin 27
   // if (buttonState26 == HIGH) {
    //  digitalWrite(out25, HIGH);

   // }
  //}

    //   while (digitalRead(input1) == HIGH);
    //digitalWrite(buzzerrelay, LOW);

    ////////////////////////////////////////////////////////////

 buttonState2 = digitalRead(in2);
  if (buttonState2 == HIGH) {
    digitalWrite(out2, LOW);
   // digitalWrite(out25, LOW);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState25 = digitalRead(in25); //read reset button state
  if (buttonState25 == HIGH )

  {
    digitalWrite(out2, HIGH); //reset the output
    //digitalWrite(buzzer, LOW);
  }

 // else {
  //  buttonState26 = digitalRead(in26); //read the buzzer reset button state
    //if (buttonState26 == HIGH) {
    //  digitalWrite(out25, HIGH);

    //}
 // }

   //////////////////////////////////////////////////////////////

  //  }
 // }

  }

```

# Answer
> 2 votes
Any time you have the same sequence of code repeated over and over with slight variations, that is a "code smell" (an indication that you may be using the wrong approach.)

You should use arrays of pin numbers as you have in the first couple of commented-out lines, and write code that loops through those arrays, as well as functions that take parameters and can do the same thing using different values that are passed in.

Don't try to tackle a problem like this without learning the skills and concepts you need. You said "...I am new to Arduino and arrays , and now I'm focusing on solving buzzer problem." That is a mistake. Code like you have posted is hard to write, hard to read, and **much harder** to maintain.

# Answer
> 0 votes
Here is your code simplified. (untested)

Since the pins are sequential, you could calculate pin numbers, instead of using an array for pin number lookup.

For example, you could use a loop `for (int i = 1; i < 25; i++)` and first input pin would be referenced as `i + 1` and first output pin would be referenced as `i + 27`.

```
// https://arduino.stackexchange.com/questions/80972/arduino-mega-buzzer-output

//  int in25 = 26;                           // for output reset
//  int in26 = 27;                           // for buzzer reset

//  int out25 = 52   ;                       // output for buzzer

//  int buttonState25 =  0;                  // for  reset
//  int buttonState26 =  0;                  // for buzzer reset

//  arrays are zero indexed (first element is at index zero)
//  array index      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26

    int in [27] = {255,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};   // input  pin numbers (26 for reset, 27 for buzzer reset)
    int out[26] = {255, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 24, 34, 44, 45, 46, 47, 48, 49, 50, 51, 52    };   // output pin numbers (52 for buzzer)

    int buttonState[27];

//  unsigned long previousMillis = 0;        // will store last time buzzer was updated
//  const long interval          = 10000;    // interval at which to buzzer (milliseconds)
//  int buzzerState              = LOW;      // buzzerState used to set the buzzer

    void setup() {

      for (int i = 1; i < 27; i++) { buttonState[i] = 0;      }       // clear states of buttons 1 to 26
      for (int i = 1; i < 26; i++) { pinMode(out[i], OUTPUT); }       // configure outputs 1 to 25

      digitalWrite(out[25], LOW);                                     // buzzer LOW

    }

    void loop() {

      for (int i = 1; i < 25; i++) {                                  // loop buttons 1 to 24

        buttonState[i] = digitalRead(in[i]);

        if (buttonState[i] == HIGH) {
          digitalWrite(out[i], LOW);
//        digitalWrite(out[25], LOW);
//        delay(10000);
//        digitalWrite(buzzer, LOW);
        }

        buttonState[25] = digitalRead(in[25]);       // read reset button state

        if (buttonState[25] == HIGH ) {
          digitalWrite(out[i], HIGH);                // reset the output
//        digitalWrite(buzzer, LOW);
        }

//      else {
//        buttonState[26] = digitalRead(in[26]);     // read the buzzer reset button state
//        if (buttonState[26] == HIGH) {
//          digitalWrite(out[25], HIGH);
//        }
//      }
      }
    }

```

---
Tags: arduino-mega, input, digital-in
---


title: sro4m-2 waterproof ultrasonic sensor

text:
# Question
Title: sro4m-2 waterproof ultrasonic sensor
I bought this waterproof ultrasonic sensor about 5 of them with the part number SR04M-2 Written on the PCB silkscreen Which is different from the usual SR04t-0.2, they are just not working, I don't know if its using a different communication protocol or its faulty because no output is coming out of the sensor at all. if anyone out there has ever came across this type and was able to walk his/her way around it should help

# Answer
> 3 votes
I found this code for the SRF05 and it works for the SRO4M-2 as well. Good Luck!

```
const unsigned int TRIG_PIN=13; //RX
const unsigned int ECHO_PIN=12;  TX
const unsigned int BAUD_RATE=9600;

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  Serial.begin(BAUD_RATE);
}

void loop() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  const unsigned long duration= pulseIn(ECHO_PIN, HIGH);
  int distance= duration/29/2;
  if(duration==0){
    Serial.println("Warning: no pulse from sensor");
  } else {
    Serial.print("distance to nearest object:");
    Serial.println(distance);
    Serial.println(" cm");
  }
  delay(100);
}

```

# Answer
> 2 votes
RX = trig and TX = Echo this is counter intuitive but it works. The manufacturer did not bother to indicate trig and echo on the PCB. I discovered this on link : https://bitbucket.org/teckel12/arduino-new-ping/issues/40/aj-sr04m-board. When I switch RX & TX as indicated in the pics it worked

---
Tags: arduino-uno, sensors, ultrasonics
---


title: Printing vairable with U8GLib

text:
# Question
Title: Printing vairable with U8GLib
I have this code that takes temperature and humidity values from a DHT11 sensor and number of faces from an external python code and prints them on an OLED screen but instead of values of variables it keeps printing 0, how can I solve it? (Sorry some parts are not in English but just consider them as random variable names.)

```
//dht11 kodu için ayarlamalar
#include <dht.h>
dht DHT;
#define DHT11_PIN 7

//ekran için ayarlamalar
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
char bufferX [20];
char bufferY [20];
char bufferZ [20];

//fan kodu için ayarlamalar
int mot1 = 8;
int mot2 = 9;
int en1 = 10;
int dir = 6;
bool state = true;
int nob = A0;
int val = 0;
int fan_hizi = 0;
String faces_str;
int faces;
float sicaklik;
float nem;

void draw(void)
{
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 15, bufferX);
  u8g.drawStr( 0, 30, bufferX);
  u8g.drawStr( 0, 45, bufferY);
  u8g.drawStr( 0, 60, bufferZ);
}

void setup() {
  Serial.begin(9600); //iletişim ve dht11 verisi

  // pin ayarları
  pinMode(mot1,OUTPUT);
  pinMode(mot2,OUTPUT);
  pinMode(en1,OUTPUT);
  pinMode(dir,INPUT_PULLUP);
}

void loop() {
  //dht11 kodu
  sicaklik = DHT.temperature;
  nem = DHT.humidity;
  delay(1000);

  //iletişim kodu
  if(Serial.available() > 0) {
    faces_str = Serial.readString();
    faces = faces_str.toInt();
  }

  Serial.print(faces);

  //sınırlar
  if(faces == 0 && sicaklik < 25 && nem < 65) {
    fan_hizi = 50;
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
  }
  if(faces >= 1 || sicaklik >= 25 || nem >= 65) {
    fan_hizi = 250;
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
  }

  //ekran
  sprintf(bufferX, "Yuzler: %d", faces);
  sprintf(bufferY, "Sicaklik: %d", sicaklik);
  sprintf(bufferZ, "Nem: %d", nem);
   u8g.firstPage();
  do {
  draw();
    }
  while ( u8g.nextPage() );
  delay(10);

  //fan kodu
  analogWrite(en1, fan_hizi);
  digitalWrite(mot1, HIGH);
  digitalWrite(mot2, LOW);
  delay(1000);
  digitalWrite(mot1, LOW);
  }

```

# Answer
> 1 votes
I do not understand, how you initialize the DHT sensor object. (I wonder why this compiles at all.)

Your way:

```
//dht11 kodu için ayarlamalar
#include <dht.h>
dht DHT;
#define DHT11_PIN 7

```

I would use:

```
//dht11 kodu için ayarlamalar
#include <DHT.h>
#define DHT11_PIN 7

DHT dht( DHT11_PIN, DHT11 );

```

Don't forget to start the DHT object with:

```
void setup() {
  // ... code removed for brevity
  dht.begin();
}

```

Now use the `dht` object instad of the DHT class.

```
sicaklik = dht.readTemperature();
nem = dht.readHumidity();

```

You did not specify what libraries you have used. But I tried all DHT libs I could find and none of them compiled with your code without errors.

The following code compiles on my IDE for an arduino UNO having olivers ug8lib and adafruits DHT sensor library installed. BTW: You even did not mention the Arduino/ESP you used. So I guess it is an UNO.

```
//dht11 kodu için ayarlamalar
#include "DHT.h"
#define DHT11_PIN 7
DHT dht( DHT11_PIN, DHT11 );

//ekran için ayarlamalar
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
char bufferX [20];
char bufferY [20];
char bufferZ [20];

//fan kodu için ayarlamalar
int mot1 = 8;
int m ot2 = 9;
int en1 = 10;
int dir = 6;
bool state = true;
int nob = A0;
int val = 0;
int fan_hizi = 0;
String faces_str;
int faces;
float sicaklik;
float nem;

void draw(void)
{
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 15, bufferX);
  u8g.drawStr( 0, 30, bufferX);
  u8g.drawStr( 0, 45, bufferY);
  u8g.drawStr( 0, 60, bufferZ);
}

void setup()
{
  Serial.begin(9600); //iletişim ve dht11 verisi

  // pin ayarları
  pinMode(mot1,OUTPUT);
  pinMode(mot2,OUTPUT);
  pinMode(en1,OUTPUT);
  pinMode(dir,INPUT_PULLUP);
}

void loop()
{
  //dht11 kodu
  sicaklik = dht.readTemperature();
  nem = dht.readHumidity();
  delay(1000);

  //iletişim kodu
  if(Serial.available() > 0)
  {
    faces_str = Serial.readString();
    faces = faces_str.toInt();
  }

  Serial.print(faces);

  //sınırlar
  if(faces == 0 && sicaklik < 25 && nem < 65)
  {
    fan_hizi = 50;
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
  }

  if(faces >= 1 || sicaklik >= 25 || nem >= 65)
  {
    fan_hizi = 250;
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
  }

  //ekran
  sprintf(bufferX, "Yuzler: %d", faces);
  sprintf(bufferY, "Sicaklik: %d", sicaklik);
  sprintf(bufferZ, "Nem: %d", nem);
  u8g.firstPage();

  do
  {
    draw();
  }  while ( u8g.nextPage() );

  delay(10);

  //fan kodu
  analogWrite(en1, fan_hizi);
  digitalWrite(mot1, HIGH);
  digitalWrite(mot2, LOW);
  delay(1000);
  digitalWrite(mot1, LOW);
}

```

I do not have the time to assemble the hardware to try it. So I can say it compiles, but I can not say it works.

**EDIT:**

Now I found adidax "DHT11 lib". your code compiles with this library. But you forgott to read the values from the sensor, before you read them from the variables.

The following line is missing:

```
void loop() {
  //dht11 kodu
  DHT.read( DHT11_PIN ); // <-- this line is missing
  sicaklik = DHT.temperature;
  nem = DHT.humidity;
...

```

---
Tags: variables, oled, print, u8glib
---


# Question
Title: Library for working with a 4-digit 7-segment indicator SH5461AS
Good day. Tell me an excellent library for working with a 4-digit 7-segment indicator. I am currently using `#include <fDigitsSegtPin.h>`

But it does not allow you to display letters, does not allow you to put dots in the right place. I think it is not flexible. I want it to be easy enough to control the indicator and have sufficient freedom to choose segments (numbers, letters, dots, dashes). I tend to use the library: "`SevenSeg` library".

Tell me a really good option for my goal, and so that, as always, this library does not slow down all the code

I am using an indicator of the form:

# Answer
This one tm1637 sounds good. I was thinking to use it next time.
**Edit 1:**
Lately posted image suggests that it is without a separate display controller chip, then this library should work.
**Edit 2:**
This library specific to the SH5461AS display: Library
Include these three libraries:

```
#include "Segment.h"
#include "Digit.h"
#include "Display.h"

```

Print needs to be in the loop:

```
void loop() {
  d.print("1.234"); // Must be looped!
}

```

For disabling decimal points:

```
#define DISABLE_DP

```

The library's Github has very good documentation too
> 4 votes

---
Tags: library, 7-segment
---


# Question
Title: Send data from one NodeMCU to another NodeMCU using Serial Communication
i am using NodeMCU (ESP8266) to communicate with another NodeMCU (ESP8266) using Serial Communication. Because i am using ESP-NOW to communicate and ESP-NOW and WiFi can not work together very well so trying with this serial communication option.

Here is how i connected the pins:

```
   Slave ->   Master
    D1    ->   D2
    D2    ->   D1
    GND   ->   GND

```

Here is how my sketch looks like:

**Sender.ino**

```
#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin(D1, D2); /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop() {
  // put your main code here, to run repeatedly:
   Wire.beginTransmission(5); /* begin with device address 8 */
   Wire.write("Hello ESP 2");  /* sends hello string */
   Wire.endTransmission();    /* stop transmitting */

   Wire.requestFrom(5, 4); /* request & read data of size 13 from slave */
   while(Wire.available()){
      char c = Wire.read();
    Serial.print(c);
   }
   Serial.println();
   delay(1000);
}

```

**Receiver.ino**

```
#include <Wire.h>

void setup() {
 Wire.begin(5);
 Wire.onReceive(receiveEvent); /* register receive event */
 Serial.begin(115200);           /* start serial for debug */
}

void loop() {
 delay(100);
}

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
 while (0 <Wire.available()) {
    char c = Wire.read();      /* receive byte as a character */
    Serial.print(c);           /* print the character */
  }
 Serial.println();             /* to newline */
}

```

But the communication is not working at all, not sure where i am wrong. It can code wise or may be via connection wise or it might be possible that NodeMCU to NodeMCU connection is not possible at all!

Thank you!

# Answer
As already stated, your code uses the I2C interface (via the `Wire` library) and not the Serial interface (which is an Arduino term for UART). They work fundamentally different.

As you only communicate between 2 devices, which you both can program yourself. I would ditch the I2C interface. It doesn't give you any advantage here, but some disadvantages (for example, that you can't have real bidirectional communication, as the slave cannot do anything by its own, only, if the master asks for it).

Instead you should use a Serial (UART) interface. As the NodeMCU only has 1 full hardware Serial interface, which you already use for debugging, you could use the `ESPSoftwareSerial` library to create an extra Serial interface via software. It has limitations (in how many interfaces can listen at a time and how fast the communication can go), but most likely this will solve your problem. Also Serial is easier for beginners, than I2C.
> 0 votes

---
Tags: serial, esp8266, nodemcu, serial-data, espressif
---


title: Using lambdas as callback functions

text:
# Question
Title: Using lambdas as callback functions
Using the Ticker library for the ESP32, how can I use a lambda as an argument to the *attach* method?

```
tickerSystemManager.attach(1000, [&](){
  systemManager->sync();
});

```

Attempting to use the above, I get the following error:

```
Matrx.cpp:11:4: error: no matching function for call to 'Ticker::attach(int, Matrx::setup()::<lambda()>)'
...
Ticker.h:40:8: note: candidate: void Ticker::attach(float, Ticker::callback_t)

```

How can I capp a lambda into this method?

# Answer
> 3 votes
As @timemage explains in a comment, you cannot pass a capturing lambda to a function that expects a plain pointer to function. There is, however, a way out of this: the `Ticker` class provides an overload of the `attach()` method that allows you to provide a parameter of any type to tour callback:

```
template<typename TArg>
void attach(float seconds, void (*callback)(TArg), TArg arg)

```

You can use this version of `attach()` and provide it both

* a non-capturing lambda that gets a pointer to `systemManager`
* that pointer as a third argument.

**Edit**: I did a few tests, and it seems my compiler cannot properly perform template argument deduction in this case, but the approach works if you explicitly specialize the template. Namely:

```
tickerSystemManager.attach<typeof systemManager>(
    1000,
    [](typeof systemManager p){ p->sync(); },
    systemManager);

```

---
Tags: arduino-ide, c++, esp32, lambda
---


# Question
Title: How can I stop someone from hacking in to my Arduino via Bluetooth?
I am using an HC-05 bluetooth Module. How can I stop someone from pairing with my device by brute forcing the key? Failing that, and if someone does pair with my device, is there a way to authenticate the user? I was thinking of salted hash with a shared secret key. Is there anything better?

# Answer
Configure your Bluetooth module to AT Command Mode

Then use `AT+PIN` Command to change the default PAIRING PIN of the Bluetooth Module.

Visit this link for more information about how to configure bluetooth to AT Mode
> 2 votes

# Answer
In case someone else asks the same question in the future, here's the answer...

Technically speaking, the Arduino cannot be hacked for the simple reason that it doesn't have an Operating System like other devices such as the Raspberry Pi, BeagleBone, Rock64 etc. So in as much as someone might be able to bruteforce the HC-05 pin and get access, there's pretty much nothing else they can do past that point, so my advice to you is that don't stress over it. However I would suggest adding a few security measures to your HC-05 Bluetooth module:

1. Change the default pin (0000 or 1234) to something else.
2. Lock the module to connect only to a specific device via the MAC Address and the AT+BIND command.

Cheers!
> 1 votes

---
Tags: bluetooth
---


# Question
Title: Why NVIC_EnableIRQ handler function only run once?
I have a code that spit out random number when the ISR register is ready:

```
#define TRNG_KEY  0x524E47
uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
uint32_t msk = 0x1FE;

void setup()
{
  Serial.begin(9600);
  PIOC->PIO_PER = msk;
  PIOC->PIO_OER = msk;
  PIOC->PIO_OWDR = ~msk;

  PMC->PMC_PCER1 = PMC_PCER1_PID41;
  TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY);
  TRNG->TRNG_IER = 1 << 0;
}

void loop()
{
  if (TRNG->TRNG_ISR == 1) {
  PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10];
  }
  delay(500);
}

```

The code above works. However, when I tried to switch to internal interrupt:

```
#define TRNG_KEY  0x524E47
uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
uint32_t msk = 0x1FE;

void setup()
{
  Serial.begin(9600);
  PIOC->PIO_PER = msk;
  PIOC->PIO_OER = msk;
  PIOC->PIO_OWDR = ~msk;

  PMC->PMC_PCER1 = PMC_PCER1_PID41;
  TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY);
  TRNG->TRNG_IER = 1 << 0;

  NVIC_EnableIRQ(TRNG_IRQn);
}

void loop()
{

}

void TRNG_Handler(void) {
  PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10];
}

```

The code only spit out one random number and then freezes, indicating TRNG\_Handler(void) was only executed once. I cannot figure out why.

Thanks in Advance !

# Answer
> 2 votes
Two things:

1. Never use `delay()` inside an ISR. On *some* systems it may work, but on most it will just block. It's bad practice to have your ISRs run for more time that absolutely needed anyway.
2. You need to read the status register for the TRNG to clear the interrupt flag. You're doing that in your first code sample with `if (TRNG->TRNG_ISR == 1) {`.

---
Tags: interrupt, arduino-due, sam3x
---