# Question
Title: Can a cheap RF module be used for two way communication
Can a cheap RF(transmitter and receiver) module be used for two way communication, not at the same time of course but for example arduino A sends string to be printed on lcd the arduino B receives it and prints it on lcd, then after some time arduino B sends a temperature data back to arduino A, then arduino prints the temperature data on the serial monitor. All of this while arduino A is connected to a transmitter and arduino B is connected a receiver.

# Answer
Each device that will ever transmit anything will need a transmitter. Each device that will ever receive anything, needs a receiver. The devices you show in your question are separate receivers and transmitters, so on Arduino A **and** Arduino B, you will need both a receiver and a transmitter in order to have real, two-way communication between them.

Some RF devices are "Transceivers" which have both a receiver and a transmitter in the same module. Some of these can operate "full-duplex", meaning they can receive at the same time they are transmitting other data (Typically each direction is on a different frequency, but not necessarily.) Most cheap ones are half-duplex, meaning the module can only receive or transmit at any one time.

**ADDITIONAL INFORMATION ABOUT RADIOHEAD**

Your comment mentioned the RadioHead library. I was able to find the documentation on the library and see that it supports a wide range of radio chipsets and modules. The cheap ones you note are simple ones that use OOK (on-off-keying) or ASK (amplitude-shift-keying) and don't actually have a protocol. The receiver simply provide a `HIGH` or `LOW` output if it detects a signal on it's designated receive frequency. The transmitter simply oscillates at the transmit frequency when it's input pin sees a `HIGH` value, and stops when it sees a `LOW` value.

The RadioHead `RH_ASK` class deals with these simple transmitters. The documentation is at http://www.airspayce.com/mikem/arduino/RadioHead/classRH\__ASK.html#details

This page notes the way to connect both a transmitter and receiver thus:

```
Connecting to Arduino

Most transmitters can be connected to Arduino like this:

Arduino                         Transmitter
 GND------------------------------GND
 D12------------------------------Data
 5V-------------------------------VCC

Most receivers can be connected to Arduino like this:

Arduino                         Receiver
 GND------------------------------GND
 D11------------------------------Data
 5V-------------------------------VCC
                                  SHUT (not connected)
                                  WAKEB (not connected)
                                  GND |
                                  ANT |- connect to your antenna syetem

```
> 2 votes

# Answer
Sure it can. A transmitter is only a transmitter *while it's actively transmitting*. And you can have as many receivers as you like.
> 0 votes

---
Tags: serial, rf
---


# Question
Title: If I run a function in loop() or setup(), and the function doesn't work after some time, is there a way to escape the function and return to the code?
The hardware is an Arduino Uno, using the Arduino IDE.
As a simplest working example, say I have this code (partially from Edgar Bonet's answer):

```
// Simulate an initialization that can hang. Connect pin 8 to ground if
// you want the function to ever return.
void initialize()
{
    pinMode(8, INPUT_PULLUP);
    while (digitalRead(8) == HIGH)
    ;  // wait
}

setup()
{
    initialize();             //Function I want to run

    Serial.begin(9600);       //Baud rate
    Serial.println("TEST 1"); //Test message
}

loop()
{
    Serial.println("TEST 2"); //Test message
    delay(1000);
}

```

if the `initialize()` function does not complete after some time, such as 2 secs., is there a way to ignore that function and continue with the rest of the code?

# Answer
> 1 votes
In general, the *right thing* to do in such a situation is to fix the `initialize()` function so that it always returns. If there is a timeout to be handled, it should be handled within that function. This is likely to be the easiest and cleanest solution.

However, if for whatever reason that is not feasible (maybe it comes from a library that is too opaque to edit), then the idea suggested by Michel Keijzers is a viable alternative:

> \[...\] set up a timer interrupt and start it just before you initialize the device/component you want to initialize. When the timer interrupt triggers and the device is not initialized, behave the same like a timeout has occurred.

The issue with this is that you would want the ISR (interrupt service routine) to return to the point where `initialize()` was called. This is not trivial, but it can be done. Actually, and contrary to what my own comment says, it can be handled without resorting to assembly hacks, by using the setjmp “non-local goto” feature of the avr-libc. Here is a proof of concept:

```
#include <setjmp.h>

jmp_buf env;

// Simulate an initialization that can hang. Connect pin 8 to ground if
// you want the function to ever return.
void initialize()
{
    pinMode(8, INPUT_PULLUP);
    while (digitalRead(8) == HIGH)
        ;  // wait
}

// This fires when the initialization times out.
ISR(TIMER1_OVF_vect)
{
    TIMSK1 = 0;       // disable timer interrupt
    longjmp(env, 1);  // go to where setjmp() was called
}

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

    // Configure Timer 1 to fire an interrupt in about 4 seconds.
    TCCR1A = 0;           // reset timer
    TCCR1B = 0;
    TCNT1  = 0;
    TIFR1  = _BV(TOV1);   // clear interrupt flag
    TIMSK1 = _BV(TOIE1);  // enable timer overflow interrupt
    TCCR1B = _BV(CS10)    // clock at F_CPU / 1024
           | _BV(CS12);   // ditto

    // Attempt initialization.
    if (setjmp(env) == 0) {

        // This is the normal program flow.
        Serial.println("Attempting initialization.");
        initialize();
        TIMSK1 = 0;  // disable timer interrupt
        Serial.println("Initialization succeeded.");
    } else {

        // We get here through longjmp() in case of timeout.
        Serial.println("Initialization aborted on timeout.");
    }

    Serial.println("Moving on to the rest of the program.");
}

void loop(){}

```

If pin 8 is grounded, the initialization succeeds and the program prints

```
Attempting initialization.
Initialization succeeded.
Moving on to the rest of the program.

```

If pin 8 is left floating, the initialization hangs and the program prints

```
Attempting initialization.
Initialization aborted on timeout.
Moving on to the rest of the program.

```

with a 4 second pause between the first and second lines.

# Answer
> 1 votes
I'm not sure if you should want this in the first place. Initialization normally should contain the necessary parts to start with.

If there is a device/component you want to initialize that is not able to initialize (because it is not present, or broken), check first if there is an intiialization function with a timeout and when the timeout is reached, set a boolean to denote the device has not been initialized.

If there is not a timeout function, you could try to set up a timer interrupt and start it just before you initialize the device/component you want to initialize. When the timer interrupt triggers and the device is not initialized, behave the same like a timeout has occurred.

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


title: How do I isolate numbers in text?

text:
# Question
Title: How do I isolate numbers in text?
I need to separate numbers from the text where my string of numbers will always be of length 8:

```
string text = "77953505HELLO THIS IS A MESSAGE"; //my string of numbers will always be of length 8

```

### My result

```
string number = "77953505"; //my string of numbers will always be of length 8
string message = "HELLO THIS IS A MESSAGE";

```

What operation should I use?

this is the job I'm doing

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

void loop() {
  if (Serial.available() > 0) {

    String Texto = String(Serial.read());

    String number = Texto.substring(0, 7);
    String message = Texto.substring(8);

    Serial.write(number);
    Serial.write(message);
  }
}

```

help me!

# Answer
> 4 votes
Depends, and probably better to use C strings:

1. If you know the number is always the same amount of characters, use the C function `strncpy`.
2. You can also split on a delimiter (char), with `strtok`, but in your case this is not possible since you don't know the delimiter character.
3. If the number has a variable length, start copying character by character through the string, until you find a character that gives false for the `isdigit` condition and copy the remainder (with strncpy) to the other string.

**Update after the question's edit**

Since the number of text to be copied is know, strncpy can be used with the following prototype:

```
char *strncpy(char *dest, const char *src, size_t n)

```

In your case put the text in a normal text string:

```
char text[80]; /* Assuming max length of text */

```

Copy it where needed:

```
strcpy(text, "77953505HELLO THIS IS A MESSAGE");

```

Note: it can be done in once like this:

```
char text[] = "77953505HELLO THIS IS A MESSAGE";

```

Than you can copy the items by:

```
char number[9]; // Add 1 for \0
char message[81]; // Assuming max length of message;

strncpy(number, text, 8);
strncpy(message, &(text[8]), strlen(text) - 8);

```

(Note not checked with compiler).

Improvements: use instead of 8 a define e.g.

```
#define NUMBER_LENGTH 8

char number[NUMBER_LENGTH + 1];

strncpy(number, text, NUMBER_LENGTH);
strncpy(message, &(text[8]), strlen(text) - NUMBER_LENGTH);

```

You can do similar for MESSAGE LENGTH

```
#define MESSAGE_LENGTH 80

```

Also, another improvement is not to copy the message, but just set the pointer to the correct place:

```
char* message = &(text[8]);

```

message will point to "HELLO THIS IS A MESSAGE"

like below

```
"77953505HELLO THIS IS A MESSAGE"
|        |
+-- text |
         +-- message

```

In an Arduino 80 bytes can be a lot of memory, using two buffers cost 160 bytes, and this way you save at least one buffer.

# Answer
> 1 votes
For a fixed length substring the simple arduino-ish way would be to use String.substring(left\_pos, right\_pos)

```
String number = text.substring(0, 7);
String message = test.substring(8); // right_pos is optional

```

This is not necessarily the best option depending on how you intend to use the resulting substring. Memory is allocated and the content is copied. Requiring at least double the memory (plus some overhead). If memory is tight you may not want to create a String but use char\* instead.

---
Tags: arduino-uno, string
---


title: AnalogWrite not working in if statement

text:
# Question
Title: AnalogWrite not working in if statement
Arduino Uno with ATMega328P `Processor.analogWrite` is not working properly in if statement. It changes the brightness of the LED as if there wasn't any if statement at all.

There are 2 potentiometers to create an intervall in which to program increases of the LED brightness, starting at 40% of the maximum. When it's lower than the minimum value, the LED is turned off.

```
int ledPin = 6;
int sensorPot = 1; // it's a potentiometer for now
int maxPot = 7; // potentiometer
int minPot = 3; // potentiometer
int fortypercent = 255*0.4;
int brightness = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(sensorPot, INPUT);
  pinMode(maxPot, INPUT);
  pinMode(minPot, INPUT);
  Serial.begin(9600);
}

void loop() {
  int start = analogRead(minPot);
  int maxVal = analogRead(maxPot);
  int sensor = analogRead(sensorPot);
  Serial.println(sensor/4);
  Serial.println(start/4);
  Serial.println(maxVal);
  if(sensor/4 > start/4) {
    analogWrite(ledPin,sensor/4);
  } else if(sensor = baslangic) {
    analogWrite(ledPin,LOW);
  } else if ((start < sensor < maxVal)) {
    brightness = sensor/4 - fortypercent;
    analogWrite(ledPin,brightness);
  } else if (sensor = maxVal) {
    analogWrite(ledPin , 255);
  }
}

```

# Answer
**ORIGINAL RESPONSE, BASED ON DIFFERENT CODE**

You are comparing `sensorValue` to see if it's ever less than `minValue`.

However, you have mapped `sensorValue` to range from `0` to `255`, and `minValue` is set at `0`. How can anything from 0-255 be less than zero?

**NEW RESPONSE, BASED ON UPDATED CODE**

One of your `if` statements: `else if(sensor = baslangic)` is not comparing, but assigning `baslangic` to `sensor`. To compare, use `==`.

Your other `if` statement: `else if ((start < sensor < maxval))` is wrong. C++ doesn't work this way. Maybe you want: `if ((start<sensor) && (sensor<maxval))`?

Instead, your statement evaluates like `if ( (start<sensor) < (maxval) )`, which means you are comparing the `TRUE` or `FALSE` of `(start<sensor)` to the `int` that is `maxval`.
> 4 votes

---
Tags: arduino-uno
---


# Question
Title: Add a watermark to text message in an Arduino
I'm trying to add a watermark to the text in the Arduino and there are several levels of watermarks (fragile, semi-fragile, robust). What is the difference between these levels in terms of algorithms used?

# Answer
"Robustness", in the context of digital watermarking, specifies the ability to detect the watermark after some signal processing modification (for images, this might be translation, rotation, scaling, compression, etc.) Some digital watermarking techniques are robust against some operations but not against others. The classifications are:

* **Robust**: The watermark should be able to survive against any and all modification. This is often used in copyright protection, for example.
* **Fragile**: This kind of watermark is designed to be destroyed by any modification to the original. This allows any manipulation, even slight changes, to be detected. Fragile watermarks are generally used to enable authentication and integrity verification.
* **Semi-fragile**: The watermark should be "robust" against certain, defined, modifications, but "fragile" against others. In other words, the watermark should survive intact under the operations you want to allow, but be destroyed by anything else. Again, these are used to enable authentication.

---

For more information, you might find the 2005 paper A Review Study on Digital Watermarking by L. Jian and H. Xiangjian (in the journal *Information and Communication Technologies*) useful.
> 4 votes

# Answer
Watermarking is used to detect changes against the original source. In images this is done by changing some pixels, almost invisible to see, but enough to check the source or see if changes have been made.

For text this is not possible normally, since changing the text will visible change the output (when you print it).

Instead a so called CRC (cyclic Redundancy Code) is used and stored separately. E.g. a certain text has a specific CRC code. When the code is changed, the CRC code should be changed too. But if someone only changes the text, you can check the text against the (unchanged/encrypted) CRC code to see it has been mangled with.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: How to implement the Arduino Extended Database library in a custom class?
I am struggling to implement a custom class that uses the Arduino Extended Database Library (EDB.h). The purpose of my custom class is to manage my application's internal database.

While searching for a solution I found this, which seems very relevant: the code and goal are the same as mine.

But my problem with that Q&A is that I am not able to implement the given solution as I don't fully understand the way it should be written.

For the sake of trying to give the best support for explanation, I upladed the code below. Feel free to explain me how to modify it.

Thank you.

EDIT: Following duplicate comments, I'll try to be more precise in my question.

# Answer
> 1 votes
It is difficult to answer this question because I'm not sure what you have managed to achieve. Sorry if some of it seems a bit basic.

Look at Majenko's answer to the question. If you want to use this EDB class then you need to define two functions:

```
  void configWriter( unsigned long address, byte data );
  byte configReader( unsigned long address );

```

You need to be able to access the **single instance** of these functions from anywhere in the code, so the need to have global scope. When they are global you can assign them to pointers by using the function name and no brackets/parenthesis. i.e.

```
aPtr = configWriter;

```

So the call to create the EDB instance would be:

```
 configDB = new EDB( configWriter, configReader );

```

Now you could create the EDB instance using a class member function. To do this you have to make the function a `static` member, which means it has no access to the class's data. (in its simplest terms static means there is only one of the things it is referring to) i.e.

```
class myEDB
{
  public:
    static void configWriter( unsigned long address, byte data );
    static byte configReader( unsigned long address );
...
};
configDB = new EDB( myEDB::configWriter, myEDB::configReader );

```

Essentially its the same thing, but the code is compartmentalised better and you end up with neater code.

However, if you are only ever going to have one instance of the myEDB class then you can have a static member variable that hold the value of `this`. You set this value in the class constructor.

```
class myEDB
{
  public:
    static void configWriter( unsigned long address, byte data );
    static byte configReader( unsigned long address );
    myEDB() {pInstance = this;}
  private:
    static myEDB* pInstance = nullptr;
...
};
configDB = new EDB( myEDB::configWriter, myEDB::configReader );

```

When configReader or configWriter is called it checks to see if the member `pInstance` has a non null value, if it doesn't then it creates a new instance. The then use this `pInstance` to access the functions and variables for the instance of the class. (This is the design pattern for a single instance class or singleton).

**SO** what should **YOU** do?

Start simply, define two global functions that do what you need as per the top of this answer. If you get stuck, if you need more info feel free to ask or comment.

---
Tags: c++
---


# Question
Title: ToF VL53L1X sensor integrate with arduino
I have this latest version VL53L1X time of flight laser distance sensor: http://www.st.com/en/imaging-and-photonics-solutions/vl53l1x.html

I study about this sensor, It says that sensor only Access with API(Application program Interface) how do I Integrate that API code in arduino or how do I use Wire library to Integrate this sensor.

# Answer
> 1 votes
~~There's actually a library created by Pololu that is quite straightforward to use so you don't need to worry about any of that. I think it covers all available functionality. https://github.com/pololu/vl53l0x-arduino~~

~~I was also a bit confused by the API comment and the datasheet.~~

I misread the device name so the above is not relevant.

In theory I think to use the API you can just #include the C code they provide into your sketch like a normal library. You can download the API code from the manufacturer ST here. You'll need to give your name and email but it's free. It's in C but you can probably understand it if you're familiar with Arduino/C++.

Before compiling you would also need to implement some I2C functions for which they provide prototypes (in the vl53l1\_platform.c file). However, I think there are some additional steps when using C files that you will need to take to get this to compile, unfortunately I am not familiar with this so can't help - if anyone does then they can probably write a more complete answer.

The alternative is to write your own functions that replicate the functionality that is described in the API. I would do this by looking at the basic process flow in the API User Manual, taking each function and working through the API files to see what it does. The main thing you're looking for is the registers that you need to write (via I2C) in order to trigger a range measurement starting, and then the registers that you need to read to find out the result. I would note that there are multiple levels of #defines for some of the register values and there is a lot of code that deals with managing the status of the device, so this might take a while.

---
Tags: sensors, arduino-nano, i2c, c, attiny
---


title: Ultrasonic Sensor receiving Side

text:
# Question
Title: Ultrasonic Sensor receiving Side
I'm doing my project regarding 40khz ultrasonic sensor which will be used to get accurate distance measurements. I have a separate transmitter and receiver. I want to get the time between the moment my transmitter transmitted the waves and the time my receiver received it. However, I couldn't actually make it work. Does any of you give me a code that would help me transmit and receive the 40khz waves and get the time in between so I could use it to compute for the distance?Thank you in advance. I would greatly appreciate it!

# Answer
> 1 votes
This is the most basic ultrasound pulse and receive code. I wrote it to work with the `HC-SR04` modules; so hopefully it will work fro you too as those also sound at `40khz`.

The main functionality comes from the `pulseIn()` funciton.

```
#define TRIGPIN 9
#define ECHOPIN 10

void setup() {
  Serial.begin(9600);
  pinMode(TRIGPIN, OUTPUT);
  pinMode(ECHOPIN, INPUT);
}

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

  uint16_t duration = pulseIn(ECHOPIN, HIGH, 4000);
  int distance = (duration*.0343)/2;
  Serial.println(distance);
}

```

---

Note that you will need to adjust the `4000` (`μs`) to whatever timeout in you want (or emit entirely if you don't want it).

# Answer
> 0 votes
I don't have 'a code', but what you can do is using a timer set to 40 kHz and send the pulses you need. .

If nothing else needs to be done (nor in the future) you can use a delay function.

Also check the pulseIn function from Arduino, you can use this convenience function for the checking the result.

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


# Question
Title: Connecting CAT5 robustly between portable Arduino and more portable sensors
Newbie wiring question. I’m building a lightwand of some sort, involving an RGB LED and a few pushbuttons that I want to wave around (the “remote”), while staying connected over ~0.5 - 3m to an Uno (the “head”).

In a portable incarnation, the remote might be on your finger and the battery-operated head in your backpack. I’m hoping to use stranded CAT5 for the connection between them (“the bridge”) — it’s the right number of conductors, good flexibility, I have lots of it.

My question is: how should I best mate the CAT5 to both ends — pins on the Arduino at the head, and pins or bare wire off my LED and switches at the remote?

At the head, I like the idea of an RJ45 jack (“NOT ETHERNET”), both for modularity and as I’m a bit worried about strain on the cable pulling wires out of Arduino pins. (The jack basically gives me a good interface at the enclosure level.) I could get an RJ45-to-wiring-terminal-block, and then run solid jumpers from the block to the pins, but they’re expensive. I could try a keystone jack and just try using solid jumpers rather than more CAT5 going between the jack’s wire-breakout and the Arduino board — but I worry the jumpers won’t be the right “size” for the jack, and I’m worried about flimsiness. (If the entire head enclosure is in your backpack, it’s going to get jostled. I want something durable.)

I see some examples of an RJ45 jack soldered directly to a board. What sort of RJ45 is that, and could I do that and solder straight to the board pins on a cheap shield, with relatively novice soldering skills? Or is this at risk when people yank the cable inadvertently?

As I said: I’m a newbie, don’t know what’s reasonable, and keep coming up with overcomplicated architectures where the CAT5e connects to a jack to a block to jumpers to pins, etc. etc.

At the remote, I think I’m better off. Things need to be as small/portable as possible, so I think I bring the bare stranded wire out of the CAT5e onto a tiny bit of board, and just solder the strands directly to the leads coming off my buttons and LED, and wrap some tape around it, then attach the whole thing to a glove or a bracelet to keep it relatively immobile at the end of the cable. Ok or terrible?

Thanks for suggestions, directions, and other help. I’ve looked around and don’t see questions at this level of ignorance. One of the answers to this mentions that “people wire a RJ45 sock directly to an Arduino” (my head problem) but doesn't say exactly how. How can I attach sensors without a shield for a wearable project? is doing what I want, but also underspecified...

# Answer
Certainly go for RJ45 sockets. Not only does it help protect the wire, but it gives you a really easy way of swapping the wire for different lengths should you want to.

You can't solder an RJ45 socket directly to a normal prototyping board. The pins aren't in the right pattern. So, you could go for something like this

That can then either be soldered to wires or, since the pins are now in a normal 0.1" pitch, solder the whole module to a prototype board or shield.

Be sure you get a vanilla RJ45 socket, not a "MagJack", which contains extra Ethernet-specific electronics inside it.

If you do want to solder the wires directly to a PCB simply drill a couple of holes just in from one edge of the PCB, run the cable between them, and strap a cable tie around it. Here's an example:

That PCB has specially shaped slots designed into it for the cable tie.

Also, for soldering, you want a good quality cable. A cheap one from eBay will most likely be made of aluminium with a thin plating (if you're lucky) of copper. A better quality one will be made entirely of copper. Aluminium cables don't solder well. Fine for crimping to an RJ45 plug, but rubbish for soldering.
> 4 votes

---
Tags: pins, shields, wires
---


title: Camera on mkr1000 or nodemcu 0.9

text:
# Question
Title: Camera on mkr1000 or nodemcu 0.9
My question is: it is possible to connect camera on an Arduino/Genuino mkr1000 or to a NodeMCU 0.9?

If yes which one?

As far as I now ArduCam OV2640 has ported a library for ESP8266 (that is the chip inside the nodemcu)? Where can I find it and how does I plug the camera to the board?

Reading the camera user guide I've found that:

> The ArduCAM mini can be used in any platforms like Arduino, \[...\] as long as they have SPI and I2C interface

Does one of these 2 board have both SPI and I2C interfaces

EDIT: Here I list my personal search with possible interesting results:

I hope that can be useful the wiring scheme to ESP8266-12E

```
     ArduCAM mini   ->    ESP8266-12E
         CS         ->        D0
        MOSI        ->        D7
        MISC        ->        D6
         SCK        ->        D5
         GND        ->       GND
         VCC        ->       3V3
         SDA        ->        D2
         SCL        ->        D1

```

# Answer
> 2 votes
There are a couple of levels of names in your question, so here are how they fit together:

**ESP8266** \- This is the bare chip found in the wide range of "esp8266"-based boards/modules/etc. The chip itself has no flash storage, no clock/oscillator, and no voltage regulation.

The I/O pins on the ESP8266 bare chip have labels like `GPIO0`, `GPIO1`, etc.

Chip outlined in Red is the ESP8266 alone.

So, to be of much use, the chips are often found on other modules along with flash memory, an oscillator, perhaps voltage regulation, a PCB antenna for the wifi portion, etc.

A popular "brand" of such module is the **AI-Thinker** modules, with names like

1. ESP-01
2. ESP-07
3. ESP-12
4. ESP-12E
5. ESP-12F

The different modules have different PCB sizes, but most notably, different numbers of pins from the actual ESP8266 chip brought out to the module's pins.

These often also call the I/O pins names like `GPIO0`, `GPIO1`, etc.

These ESP-xx modules, in turn, are often incorporated into larger modules that then add a USB-serial chip, LEDs, etc. One popular line are the NodeMCU series.

These modules provide different names for the I/O pins. **NodeMCU** in particular uses `D0`, `D1`, etc. and these don't correspond to the same numeric suffix as the bare chip. This chart gives the mappings for NodeMCU modules.

**ANSWER**

Thus, in the web page you linked about the ArduCAM and ESP8266, you can see a chart on the Hardware Connection of the the ArduCAM pins, and equivalent pins for both the NodeMCU-style pin names, and also the AI-Thinker and bare chip pin names.

The ESP-12 and ESP-12E both have the exact same ESP8266 chip inside, and the same amount of flash memory. There is no difference between them as far as connecting to the ArduCAM is concerned. The ESP-12E has a few more pins brought out to the headers than the ESP-12.

So, as long as you have D0, D1, D2, D5, D6, and D7 on a NodeMCU, **OR** GPIO4, GPIO5, GPIO12, GPIO13, GPIO14, and GPIO16 on the AI-Thinker module, then you can hook up the ArduCAM, as these are all the pins described in the hookup table.

---
Tags: arduino-ide, nodemcu, mkr1000
---


# Question
Title: Interrupt fires a random number of multiple times for one pulse
This is my first time posting on this forum. I have tried to format this question properly, but let me know if I need to correct anything. I searched to see if someone else had a similar problem, but let me know if someone has already answered this question.

**Overview:** I am sending pulses to my Arduino, but sometimes one single pulse is interpreted as anywhere from 2 to 30 pulses. But after looking at the pulse on an oscilloscope (see Fig. 1) I am not sure why. When I use a really long wire the ratio of false pulses to legit pulses is about 1 to 1. I shortened the length of the wire and improved the situation, so that only 1 in about every 2,000 pulses is registered as a false pulse.

For one test, I added a capacitor to the short wire situation, but that increased the rise time and made the problem worse. I am currently using `attachinterrupt` and have tested the situation with using both a rising and falling edge. Right now, I mainly want to understand how interrupts work on the Arduino in light of my current problem, although I welcome general advice.

1. When I set the interrupt to the falling edge, why does the Arduino still sometimes count 1 pulse as several? The falling edge in the photo, which is for the really long wire case, lasts about 40 microseconds and appears to have a clean break. The pulse remains low for about 80 milliseconds. Could the falling interrupt trigger during the rise time based off the oscillatory behavior shown in Fig. 1? I smoothed out the signal by adding in a 1 nF capacitor, but the Arduino still counted false pulses. So could the rise time period have anything to do with it? I also have a 10k Ohm pullup resistor connected to the Arduino's 5 V for the pulse path.

I have the relevant code attached below. I have much more code as well, but it deals with saving pulseCounts to the SD Card and uploading electricity consumption files through the cell network.

Cheers.

```
//Global Variables
unsigned long pulse_time = 0;
unsigned long last_pulse_time = 0;
byte code = 1; //code let's me see if a false pulse was reported for each
//SD file

void setup() {
  attachInterrupt(digitalPinToInterrupt(3), onPulse, RISING);
}

void onPulse() {
  pulse_time = millis();
  if ((pulse_time - last_pulse_time) > 50 ) {
    Serial.println("Good Pulse");
    pulseCount++;
    last_pulse_time = pulse_time;
  } else {
    Serial.println("Bad Pulse");
    pulseCount++;
    code = 2;
  }
}

```

# Answer
> 1 votes
Firstly, unless the processor pin is a Schmitt trigger, increasing capacitance will only make the problem worse by allowing any noise to be interpreted as multiple high-low transitions. For a CMOS logic input the area around the transition point of 1/2 VDD typical is actually an area of linear operation, not digital.

A Schmitt trigger introduces hysteresis such that when the signal is interpreted as a high level, it must go low by more than the hysteresis to be interpreted as a low level again. This is accomplished with a bit of positive feedback added to a buffer where the output transition from low to high then pulls the input that much higher or a transition from high to low pulls the input that much lower:

The red line represents the typical CMOS threshold and the green lines represent the thresholds defined by the hysteresis of the Schmitt trigger. The hysteresis defines the noise immunity of the input. Most processors have pins that are equipped with a Schmitt trigger or and external device like a 74HC14 can be used.

Another way to deal with this type of noise is to lock out any transitions within the expected pulse-to-pulse transitions: Once triggered, no more transitions are allowed until the lock out time expires.

---
Tags: interrupt, hardware
---


title: I need help with code for two 74HC595

text:
# Question
Title: I need help with code for two 74HC595
I created and learned this code myself from many examples. I tried to add another chip to it, but I have no idea. Do I need to rewrite all of it? Just some simple code is needed.

```
int latchPin = 2;
int dataPin = 3;
int clockPin = 4;
const int analogPin = A0;
const int ledPin = 13;
const int EmptyEn = 0;
const int GreenOne = 100;
const int GreenTwo = 200;
const int GreenThree = 300;
const int GreenFour = 400;
const int YellowOne = 500;
const int YellowTwo = 600;
const int RedOne = 750;
const int RedTwo = 900;
const int MaxHold = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
  int analogValue = analogRead(analogPin);
  if (analogValue > GreenOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > GreenOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B10000000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > GreenTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11000000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > GreenThree) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11100000);
    digitalWrite(latchPin, LOW);
    delay(1);
  }
  if (analogValue > GreenFour) {
    digitalWrite(latchPin, HIGH);
    shiftOut(dataPin, clockPin, MSBFIRST, B11110000);
    digitalWrite(latchPin, LOW);
    delay(1);
  }
  if (analogValue > YellowOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111000);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > YellowTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111100);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > RedOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111110);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > RedTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }
  if (analogValue > MaxHold) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
    digitalWrite(latchPin, HIGH);
    delay(100);
  }
  Serial.println(analogValue);
  delay(1);
}

```

# Answer
> 2 votes
Look for a repetition in your code.

```
  //Repeating code..
  if (analogValue > GreenOne) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000 );
    digitalWrite(latchPin, HIGH);
    delay(1);
  }

  if (analogValue > GreenTwo) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B10000000 );
    digitalWrite(latchPin, HIGH);
    delay(1);
  }

```

You will notice that you have a lot of repetition of the general structure of a if-comparison (always with a different value) and then a `shiftOut` with a different value to be shifted out.

```
  //General code structure
  //Only things to change is someComparisonValue and someDataValue
  //the rest is the same.
  if (analogValue > someComparisonValue) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, someDataValue);
    digitalWrite(latchPin, HIGH);
    delay(1);
  }

```

You can generalize and simplify the code by storing those different comparison values and data values in a look-up table (LUT). Now you could use two arrays to hold these values but you could also further condense it in a C `struct`, a "data structure".

Let's define a data structure which holds a threshold value and then the data to be shifted out as `struct`.

```
/* Defines a LUT entry */
struct LutEntry {
    int treshhold;  /* threshhold value */
    byte data;      /* data to be shifted out */
};

```

We can then pack the actual data into a single variable. Because this is constant data, it will take up flash memory instead of RAM.

```
static const LutEntry lutTable[] = {
    { GreenOne, B00000000},
    { GreenOne, B10000000},
    { GreenTwo, B11000000},
    { GreenThree, B11100000},
    { GreenFour, B11110000},
    { YellowOne, B11111000},
    { YellowTwo, B11111100},
    { RedOne, B11111110},
    { RedTwo, B11111111},
    { MaxHold, B00000000}
};

```

From there we can also see that there is a computable relationship between the index of the treshhold value and the data to be shifted out - an entry at index `i` will be associated with the `data` bitstring in which all bits from the MSB up to `i` inclusive are `1`, the rest being `0`. Except for `MaxHold` as special value. We could exploit this property to get rid of that `data` member entirely, but that is an exercise left to you.

Now we can re-write the `loop` code by simply taking a `analogRead` sample and then iterating through the entires of the LUT to shift out the corresponding data.

```
void loop() {
    int analogValue = analogRead(analogPin);
    int numLutEntries = (int)(sizeof(lutTable) / sizeof(lutTable[0]));

    for(int i=0; i < numLutEntries; i++) {
        if (analogValue > lutTable[i].treshhold) {
            digitalWrite(latchPin, LOW);
            shiftOut(dataPin, clockPin, MSBFIRST, lutTable[i].data);
            digitalWrite(latchPin, HIGH);
            delay(1);
        }
    }
    Serial.println(analogValue);
    delay(1);
}

```

Which transforms 69 lines of repeating code into 12 lines of non-repeating code.

After this general code cleanup it becomes easier to add another shift register: You can define a new look up table, or modify the structure of the old one, to hold the information you need (treshholds, data to be shifted out, the clock, data and latch pin for the register, ...). What logic needs to be there is something only you know, because the description "add another chip \[to this code\]" is quite broad.

In short:

* **DRY**: Don't repeat yourself. If you use a piece of code over and over again with only slight variances in used values, make it a function
* recognize the differences of the used data values in used code pieces and try to group them neatly together. Use the language feature of `structs` or `class` to express the meaning of this data
* exploit certain properties / relationships of your data to save even more memory / computing time.

---
Tags: arduino-uno
---


# Question
Title: Receive data from Arduino board to Android application
I'm trying to receive data and print it on a label of my application, but I can not get it. Actually, I have 0 experience with Arduino. It's the first time I see this. I read this tutorial to receive data from an Arduino. In my Arduino I have this code:

```
#include <SoftwareSerial.h>
const int RX_PIN = 2;
const int TX_PIN = 3;
SoftwareSerial blueTooth(RX_PIN, TX_PIN);
char commandChar;

void setup () {
  Serial.begin(57600);
  Serial.println("Let's start!");
  blueTooth.begin(9600);
  blueTooth.println("Hello, world?");
}

void loop () {
 if (blueTooth.available())
    Serial.write(blueTooth.read());
  if (blueTooth.available())
    blueTooth.write(Serial.read());
}

```

My Android code is this:

```
public class MainActivity extends AppCompatActivity {
FrameLayout frame;
GifImageView imagen;
TextView mensaje,debug;
Button boton;
private TextToSpeech talk;
public static StringBuilder sb;
private static final String TAG = "conexionBluetooth";
ConnectedThread mConnectedThread;
BluetoothAdapter blueAdapter;
BluetoothDevice mDevice;
BluetoothSocket mSocket;
Handler handler;

final int MENSAJE_RECIBIDO = 1;
final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static String MAC = "00:21:13:02:EA:07";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getSupportActionBar().hide();
    setContentView(R.layout.activity_main);
    talk = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int i) {
            if(i == TextToSpeech.SUCCESS){
                talk.setLanguage(Locale.US);
                mensajeInicio();
            }
        }
    });
    debug = (TextView) findViewById(R.id.debug);
    mensaje = (TextView) findViewById(R.id.mensajeApp);
    frame = (FrameLayout) findViewById(R.id.androidIc);
    imagen = (GifImageView) findViewById(R.id.imageBluethoot);
    imagen.setVisibility(View.INVISIBLE);
    frame.setVisibility(View.VISIBLE);
    boton = (Button) findViewById(R.id.botonInicio);
    Animation flotarArriba = new TranslateAnimation(
            TranslateAnimation.ABSOLUTE, 0f,
            TranslateAnimation.ABSOLUTE, 0f,
            TranslateAnimation.RELATIVE_TO_PARENT, 0f,
            TranslateAnimation.RELATIVE_TO_PARENT, 0.05f
    );
    flotarArriba.setDuration(1000);
    flotarArriba.setRepeatCount(-1);
    flotarArriba.setRepeatMode(Animation.REVERSE);
    flotarArriba.setInterpolator(new LinearInterpolator());
    mensaje.setAnimation(flotarArriba);
    boton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            boton.setEnabled(false);
            mConnectedThread.write("0");
            Toast.makeText(getApplicationContext(),"Data send to arduino",Toast.LENGTH_LONG).show();
        }
    });
    handler = new Handler(){
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MENSAJE_RECIBIDO:
                    byte[] readBuf = (byte[]) msg.obj;
                    String strIncom = new String(readBuf, 0, msg.arg1);
                    sb.append(strIncom);
                    int endOfLineIndex = sb.indexOf("\r\n");
                    if (endOfLineIndex > 0) {
                        String sbprint = sb.substring(0, endOfLineIndex);
                        sb.delete(0, sb.length());
                        debug.setText(sbprint);
                        boton.setEnabled(true);
                    }
                    //Log.d(TAG, "...String:"+ sb.toString() +  "Byte:" + msg.arg1 + "...");
                    break;
            }
    }};
    configBluetooth();
    comprobarEstadoBluetooth();
}

@Override
public void onResume() {
    super.onResume();
    Log.d(TAG, "...onResume - try connect...");

    BluetoothDevice device = blueAdapter.getRemoteDevice(MAC);

    try{
        mSocket = crearSocket(device);
    } catch (IOException e) {
        Toast.makeText(getApplicationContext(),"ERROR!! No se ha logrado crear el enchufe! " + e.getMessage(),Toast.LENGTH_LONG).show();
        finish();
    }

    blueAdapter.cancelDiscovery();

    Log.d(TAG, "...Connecting...");
    try{
        mSocket.connect();
        Log.d(TAG,"Connection OK!!");
    } catch (IOException e) {
        try{
            mSocket.close();
        } catch (IOException e1) {
            Toast.makeText(getApplicationContext(),"Error fatal en el metodo onResume. Incapaz de cerrar conexion: " + e1.getMessage(),Toast.LENGTH_LONG).show();
            finish();
        }
    }
    mConnectedThread = new ConnectedThread(mSocket);
    mConnectedThread.start();
}

@Override
public void onPause() {
    super.onPause();
    Log.d(TAG, "...In onPause()...");
    try {
        mSocket.close();
    } catch (IOException e) {
        Toast.makeText(getApplicationContext(),"Error fatal en el metodo onPause. Incapaz de cerrar conexion: " + e.getMessage(),Toast.LENGTH_LONG).show();
    }
}

private void enable() throws IOException {
        boton.setText(getString(R.string.finalizar));
        mensaje.setText(getString(R.string.mensajeActivo));
        frame.setVisibility(View.INVISIBLE);
        imagen.setVisibility(View.VISIBLE);
        mensaje2();
        boton.setText(getString(R.string.iniciar));
        mensaje.setText(getString(R.string.pontelos));
        frame.setVisibility(View.VISIBLE);
        imagen.setVisibility(View.INVISIBLE);
        mensaje1();

}

private void mensajeInicio(){talk.speak(getString(R.string.app_name) + getString(R.string.textApp) + getString(R.string.pontelos),TextToSpeech.QUEUE_FLUSH,null);}
private void mensaje1(){talk.speak(getString(R.string.pontelos),TextToSpeech.QUEUE_FLUSH,null);}
private void mensaje2(){talk.speak(getString(R.string.mensajeActivo),TextToSpeech.QUEUE_FLUSH,null);}

private void configBluetooth(){
    Toast.makeText(getApplicationContext(),"Metodo llamado",Toast.LENGTH_LONG).show();
    blueAdapter = BluetoothAdapter.getDefaultAdapter();
    if(blueAdapter != null){
        Set<BluetoothDevice> pairedDevices = blueAdapter.getBondedDevices();
        if(pairedDevices.size() > 0){
            for(BluetoothDevice device: pairedDevices){
                if(device.getName().equals("HC-06")) {
                    mDevice = device;
                    Toast.makeText(getApplicationContext(), "Nombre del dispositivo: " + mDevice.getName() +
                            "\nDireccion MAC: " + mDevice.getAddress() + ".", Toast.LENGTH_LONG).show();
                }
            }
        }
    }
}

private void comprobarEstadoBluetooth(){
    if(blueAdapter == null){
        Toast.makeText(getApplicationContext(),"ERROR!!! No hay soporte Bluetooth!",Toast.LENGTH_LONG).show();
        finish();
    }else{
        if(blueAdapter.isEnabled()){
            Toast.makeText(getApplicationContext(),"Bluetooth encendido. . .",Toast.LENGTH_LONG).show();
        }else{
            Intent activarBTH = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(activarBTH, 1);
        }
    }
}

private BluetoothSocket crearSocket(BluetoothDevice device) throws IOException {
    if(Build.VERSION.SDK_INT >= 15){
        try{
            final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
            return (BluetoothSocket) m.invoke(device, uuid);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    return device.createRfcommSocketToServiceRecord(uuid);
}

private class ConnectedThread extends Thread {
    private final InputStream mInStream;
    private final OutputStream mOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mInStream = tmpIn;
        mOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[256];  // buffer store for the stream
        int bytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mInStream.read(buffer);        // Get number of bytes and message in "buffer"
                handler.obtainMessage(MENSAJE_RECIBIDO, bytes, -1, buffer).sendToTarget();     // Send to message queue Handler
                handler.handleMessage(new Message());
            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main activity to send data to the remote device */
    public void write(String message) {
        Log.d(TAG, "...Data to send: " + message + "...");
        byte[] msgBuffer = message.getBytes();
        try {
            mOutStream.write(msgBuffer);
        } catch (IOException e) {
            Log.d(TAG, "...Error data send: " + e.getMessage() + "...");
        }
    }
}
}

```

I notice the following behaviors:

* The application does not crash when it is executed.
* When I start the application, the bluetooth module of the Arduino flashes differently. (I guess it's because my app connectswith the board).
* Inside the Log Cat, it can be seen that the connection has been made correctly. . .

What could be missing here to print the data received from the Arduino? I do not know if it's me, or the handler method never runs. (public void handleMessage (Message msg))

Also note that in the serial monitor of the Arduino, the value that I command when pressing the button of the application is never printed...

**UPDATE**

Investigating on the internet about the module of my Bluetooth (HC-06) I found that;

* If the light of the module is constantly flashing, it is not paired with the phone.
* If the module light stays on, then it is already connected.

My concern is that when I open my application, to blink constantly, it blinks much slower. . . Could it be that I've never been able to connect?

# Answer
I don't think your code is correct:

```
void loop () {
 if (blueTooth.available())
    Serial.write(blueTooth.read());
  if (blueTooth.available())         <----
    blueTooth.write(Serial.read());
}

```

Shouldn't you be monitoring Serial.available on this line?
> 3 votes

# Answer
I could solve it already !!!! It turns out that the bluetooth module was badly connected to the arduino !!!! I can already receive data! thank you very much for your comments, especially chrisl, for your suggestion to use the bluetooth serial monitor app! :)

I had connected the VCC to 5V ... that was what was bothering me, I read on the web that if you have it in 5V, as a self defense, the RX pin is completely blocked. The VCC must be connected to 3.3V.

**EDIT:** I forgot something very important! had to change the baud of bluetooth to 9600 like Serial! this part was very important too.
> 0 votes

---
Tags: arduino-uno, softwareserial, android
---


title: Arduino + nRF24L01 + ESP8266 mod

text:
# Question
Title: Arduino + nRF24L01 + ESP8266 mod
I was wondering if it is possible to connecting two Arduino boards with each other (Uno + Nano) using an ESP8266 mod on one of them and an nRF24L01 on the other board?

I have seen lots of details of connecting two nRF but couldn't find any about ESP talking to nRF.

# Answer
No. That would be like trying to connect your TV to your microwave. Both RF devices, but both work different ways and do different things.

Just because they are both rectangular boxes with a window in the front doesn't mean they are the same.
> 1 votes

# Answer
No, that is not possible: the ESP8266 is a WiFi SoC, and the nRF24L01 uses a proprietary protocol.
The fact that they both operate in the same frequency range doesn't matter if the protocols are different.
> 0 votes

---
Tags: arduino-uno, esp8266, arduino-nano, nrf24l01+
---


# Question
Title: What are these components in Arduino Mega Schematic?
I was looking at Arduino Mega's reference schematic here and trying to understand how the circuit functions. However, I am unable to understand what these schematic symbols (marked in black rectangles) represent or what their function is. Can anyone please explain it to me?

# Answer
@Transistor accurately answered what they are. I'll approach their specific function.

The Arduino Mega documentation gives some information on "RESET-EN" and "UBOOT."

1. **"RESET-EN"** allows you to enable/disable the auto-reset feature. By default there is a trace between the pads. That's why it look like there is a short in parallel below it. Cut the trace to disable auto-reset. Solder bridge back together to re-enable.

With auto-reset enabled, the board will automatically reset every time the serial communication is initially established. This causes problems if you are using a non-usb power supply and want to plug in for some debugging or have a design that opens and closes serial comm.
2. **"UBOOT"** is related to the DFU (Device Firmware Update) bootloader. This may be on the back of the board and will be different between revs.

> The ATmega16U2/8U2 is loaded with a DFU bootloader, which can be activated by:
>
> * On Rev1 boards: connecting the **solder jumper** on the back of the board (near the map of Italy) and then resetting the 8U2.
> * On Rev2 or later boards: there is a resistor that pulling the 8U2/16U2 HWB line to ground, making it easier to put into DFU mode.

You can use this to update the USB firmware and even change the device name when you plug it in. More info here.

3. **"GROUND"** can optionally link USB ground (UGND) to the main circuit ground. I don't know enough about USB comm circuit design to understand what the advantages or disadvantages are here. Perhaps someone else can clarify this idea. ATMEGA8U2-MU datasheet for reference.
> 2 votes

# Answer
The symbol indicates a pair of solder pads that can be bridged by the user using a blob of solder.

Here's something similar.

*Figure 1. Source: CyberGibbons.*
> 6 votes

---
Tags: arduino-mega
---


# Question
Title: Digital input signal to be converted to analog signal
Hello and a very good day. I am currently doing my final year project which involving Arduino KY-031 Knock Sensor as my input signal and it is apparently a digital type of sensor. So, my question is can the digital signal be converted to analog signal ?

The reason I need it to be analog signal because I wanted it to be classified into 3 type of stages (low,medium,high).
p/s: I am using Arduino Uno as my controller.

# Answer
> 4 votes
You can create an analogue representation of any signal - but you can't add in information which wasn't previously there. The KY-031 doesn't give you any more information than "knock" or "no knock", so there's no way to get further detail out of it.

---
Tags: sensors
---


title: A4988 and capacitors

text:
# Question
Title: A4988 and capacitors
I’m working at a project which involves 3 stepper motors that are driven by A4988 drivers. I have read that I have to connect an 100uf capacitor in parallel with the motor power supply that goes to the driver, but do I have to use a capacitor for every driver, or only 1 capacitor because the drivers are connected in parallel to the same 12v power supply.

# Answer
There are two purposes of such capacitor:

* first it supply power for short peaks in demand, so effectively enabling the 12V power source supply much more current for short time, than it can support over long time and so the driver have more stable power and works generally better. Also it protects the driver from noise of other parts.
* the other is protect all other parts from voltage drops and noise caused by the driver. It is recomended to have capacitors as near as possible to any IC/driven circuit for this reason.

So basically - if you have good power source, you can often get away even without such capacitors. But if you power also logic from the same source, it is already better to have some capacitors on power lines where posssible. Escpecially if you expect some noise around (like having motors near or lines to motors in paralel with other lines ...). Depends how much you care and how critical you see the project. Hobby project just for fun can go even without capacitors and be all good. Good industry projects have capacitors always everywhere.

I had project, where it worked even without capacitors (laser printer), but now I would place some there in any case near each driver, just to be sure. 100uF is really good capacity, enables for lot power. But if you use any other value (which you have more ready), it should not hurt too. It is not about if it would work or not, it is more about if it ensures, that it would work flawlessly even in bad conditions even under unexpected conditions and would not have "sometimes strange problems, which disapear spontaneously during debugging".

Also note, that for improving power are good high capacity electrolytes. For preventing noise are much better ceramic (which are fast, even if they have a lot smaler capacity) and so many people put both there (like 100uF electrolyte and 100nF ceramic in paralel).

**Short answer:** Do as you want, it would probably work anyway. I personally would place big+small capacitors near each driver.
> 5 votes

---
Tags: arduino-nano, stepper
---


# Question
Title: Having an issue running an Arduino sketch
I just got my USB host shield attached to my Arduino Uno, opened the program sketch for `USBDESC.ino` and I'm getting an error. It says "usbhub.h not found". It won't compile. How did I go wrong?

I am using the Mac version of the Arduino IDE and downloaded the USB host shield Master v 2.0 file directly into /Arduino/java/examples. This was how I have added every previous library download. Please help. Thanks.

# Answer
I don't know how you came up with that location as the right place to put libraries. It is wrong. Oh so very wrong.

Libraries go in `~/Documents/Arduino/libraries` as stated in the first hit for "arduino macos libraries" on Google.
> 0 votes

---
Tags: arduino-uno
---


title: GPS showing incorrect speed

text:
# Question
Title: GPS showing incorrect speed
I am using Arduino ATmega 2560. When i am using "AT+CGNSINF" command to get GPS value, sometimes it showing incorrect speed. The correct speed should be (50-60)km/h but sometimes it showing (200-300)km/h. How can I fix the problem or avoid/ignore the unexpected speed. here is my code

```
void get_GPS()
{
    sendATCommand("AT+CGNSINF","OK", 1000);

    // condition for valid response
    while (strstr(AT_Buffer, "+CGNSINF: 1,1") != NULL)
    {
        delay(3000);
        strtok(AT_Buffer, ",");
        strtok(NULL, ",");
        strtok(NULL, ",");
        strtok(NULL, ",");
        strtok(NULL, ",");
        strtok(NULL, ",");
        Serial.println("\n");
        Serial.println(strtok(NULL, ","));

        //sendATCommand("AT+CGNSINF", "OK", 1000);
    }
}
uint8_t sendATCommand(char* ATcommand, const char *expectedResponse, unsigned long timeout)
{
    uint8_t x = 0, answer = 0;

    memset(AT_Buffer, '\0', AT_BufferLength);    // Initialice the string
    delay(100);
    while (Serial1.available() > 0) Serial1.read();    // Clean the input buffer
    if (ATcommand[0] != '\0')
    {
        Serial1.println(ATcommand);    // Send the AT command
    }

    unsigned long previous = millis();

    // this loop waits for the answer
    do {

        if (Serial1.available() != 0) {    // if there are data in the UART input buffer, reads it and checks for the asnwer
            AT_Buffer[x] = Serial1.read();
            //Serial.print(AT_Buffer[x]);
            x++;
            if (strstr(AT_Buffer, expectedResponse) != NULL)    // check if the desired answer (OK) is in the response of the module
            {
                answer = 1;
                break;
            }

        }
    } while ((millis() - previous < timeout));    // Waits for the asnwer with time out

    return answer;
}

```

# Answer
> 2 votes
Speed calculation in most GPS systems is very crude. It consists of simply "Where was I then? Where am I now?". Many will also add "How long has passed between then and now?", but many also don't - they assume a fixed time between points (1 second, for example). It doesn't know it's supposed to move, all it knows is the coordinates it has at the moment.

With the latter, if you don't get a reading for a couple of seconds (buildings in the way, for example) the position can suddenly jump a long way. You can see the effect in your phone's GPS in built-up areas - your position may jump long distances and then pause for a bit.

To visualise it in 1-dimension, you can think of a simple number sequence 0-9 and the difference between each value:

```
Value:        0 1 2 3 4 5 6 7 8 9
Difference:     1 1 1 1 1 1 1 1 1

```

The difference equates to the "speed" of the sequence.

Now if the numbers don't get updated smoothly, but all at once at the end, you get something like:

```
Value:        0 1 2 2 2 2 2 7 8 9
Difference:     1 1 0 0 0 0 5 1 1

```

The end results is the same, but you get a "dead" period with no "movement" and then a big jump with an unusually high speed.

It's up to you to filter out such anomalies. It's simple enough to say "5 is too much - ignore it". You could also average the past 10 seconds worth of data (for example) and use that as your average speed over that time period, which would smooth out such peaks and troughs.

---
Tags: arduino-mega, gps, speed
---


# Question
Title: Printing transmission data from nRF24L01+
I have a beginner's problem. I have 2 nRF24L01+ devices. They are communicating with each other great, and I can talk with the nRF via SPI.

The problem is I want to display, on the serial monitor, the number of retransmitted packets (ARC\_CNT) and the number of lost packets (PLOS\_CNT), which are both in the "observe\_tx" register on the nRF.

I am using the "Getting Started" example from RF24 1.3.1, with Arduino 1.84, with a few more bits added, and it all works great apart from getting it to show PLOS\_CNT & ARC\_CNT! I have tried:

```
printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"));

```

But this does not give the correct result.

As you have probably guessed, I know nothing about C or C++. There must be a simple way of showing the 2 numbers?

The code I am using is:

```
#include <SPI.h>
#include "RF24.h"
#include <printf.h> // Required for "radio.printDetails();"

/****************** User Config ***************************/
/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 0;

/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(7, 8);
/**********************************************************/

byte addresses[][6] = {"1Node", "2Node"};

// Used to control whether this node is sending or receiving
bool role = 0;

void setup() {
  //pinMode(53,OUTPUT); //may not be required after all
  Serial.begin(115200);
  printf_begin(); //required for "radio.printDetails();" to work
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
  radio.begin();
  // Set the PA Level low to prevent power supply related issues since this is a
  // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_LOW); // _MIN, _LOW, _HIGH, _MAX
  radio.setDataRate(RF24_250KBPS); //250KBPS, _1MBPS, _2MBPS  Lowest rate gives longest range.
  radio.setChannel(108); // 0 - 124 (2.4GHz - 2.524GHz) Usually above 100 best. USA 70 - 80 best.
  radio.setRetries(15, 15); // set retry delay and no of retries. delay between retries, 0=250uS, 15 = 4000uS
  radio.setCRCLength(RF24_CRC_16);  // 8 or 16 bit crc
  radio.printDetails();
  Serial.print(radio.getChannel());
  radio.setAutoAck(1);
  // Open a writing and reading pipe on each radio, with opposite addresses
  if (radioNumber) {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1, addresses[0]);
  } else {
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1, addresses[1]);
  }
  // Start the radio listening for data
  radio.startListening();
}

void loop() {
  /****************** Ping Out Role ***************************/
  if (role == 1)  {
    radio.stopListening(); // First, stop listening so we can talk.
    Serial.println(F("Now sending"));
    unsigned long start_time = micros();
    // Take the time, and send it.  This will block until complete
    if (!radio.write( &start_time, sizeof(unsigned long) )) {
      Serial.println(F("failed"));
    }
    radio.startListening(); // Now, continue listening
    unsigned long started_waiting_at = micros(); // Set up a timeout period, get the current microseconds
    boolean timeout = false; // Set up a variable to indicate if a response was received or not
    while (!radio.available()) {
      // While nothing is received
      if (micros() - started_waiting_at > 200000 ) {
        // If waited longer than 200ms, indicate timeout and exit while loop
        timeout = true;
        break;
      }
    }

    if (timeout) {
      // Describe the results
      Serial.println(F("Failed, response timed out."));
      printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"));
    } else {
      unsigned long got_time;
      // Grab the response, compare, and send to debugging spew
      radio.read( &got_time, sizeof(unsigned long) );
      unsigned long end_time = micros();
      // Spew it
      Serial.print(F("Sent "));
      Serial.print(start_time);
      Serial.print(F(", Got response "));
      Serial.print(got_time);
      Serial.print(F(", Round-trip delay "));
      Serial.print(end_time - start_time);
      Serial.println(F(" microseconds"));
    }
    // Try again 1s later
    delay(1000);
  }

  /****************** Pong Back Role ***************************/
  if (role == 0) {
    unsigned long got_time;
    if (radio.available()) {
      // Variable for the received timestamp
      while (radio.available()) {
        // While there is data ready
        radio.read(&got_time, sizeof(unsigned long));
        // Get the payload
      }
      radio.stopListening();
      // First, stop listening so we can talk
      radio.write(&got_time, sizeof(unsigned long));
      // Send the final one back.
      radio.startListening();
      // Now, resume listening so we catch the next packets.
      Serial.print(F("Sent response "));
      Serial.println(got_time);
    }
  }

  /****************** Change Roles via Serial Commands ***************************/

  if (Serial.available()) {
    char c = toupper(Serial.read());
    if (c == 'T' && role == 0) {
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1; // Become the primary transmitter (ping out)
    } else if (c == 'R' && role == 1) {
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
      role = 0; // Become the primary receiver (pong back)
      radio.startListening();
    }
  }
} // Loop

```

# Answer
```
printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"));

```

This should be

```
printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"),
 OBSERVE_TX, PLOS_CNT, ARC_CNT);

```

Where the two variables contain the values.

* first OBSERVE\_TX= means the text that is literally printed
* %02X is the format of the variable which is printed
* OBSERVE\_TX is the variable name

The variable names should be in the same order as the formatting (%'s).

However, in your case the above will not result in the values you want. The items above (OBSERVE\_PLOS\_CNT and ARC\_CNT) are offsets from an addres. What you want is to print the content of that address. Since I don't have an Arduino IDE nearby, you should find yourself the address, and use \*(address + OBSERVE\_PLOS\_CNT). This will use the address, adds OBSERVE\_PLOS\_CNT, and * means it will show the content of that new address.

Btw, I'm not sure about the exact use of printf\_P and PSTR.
> 2 votes

---
Tags: nrf24l01+, software
---


# Question
Title: Can I make multiple loop() functions with Arduino Uno?
I have a problem. I want to make a car with a motor, front lights and rear lights. I want to run them at the same time but in different loops.

This is my code.

```
const int red1 = 10;
const int red2 = 11;
const int blue1 = 12;
const int blue2 = 13;
const int front1 = 3;
const int front2 = 4;
const int back1 = 5;
const int back2 = 6;
const int enablePWMPin = 9;
const int controlPinA = 8;
const int controlPinB = 7;
int buzzer = A0;

void setup() {
  pinMode(red1, OUTPUT);
  pinMode(red2, OUTPUT);
  pinMode(blue1, OUTPUT);
  pinMode(blue2, OUTPUT);
  pinMode(front1, OUTPUT);
  pinMode(front2, OUTPUT);
  pinMode(back1, OUTPUT);
  pinMode(back2, OUTPUT);
  pinMode(enablePWMPin, OUTPUT);
  pinMode(controlPinA, OUTPUT);
  pinMode(controlPinB, OUTPUT);

  digitalWrite(enablePWMPin, LOW);
  digitalWrite(front1, LOW);
  digitalWrite(front2, LOW);
  digitalWrite(back1, LOW);
  digitalWrite(back2, LOW);
  digitalWrite(red1, LOW);
  digitalWrite(red2, LOW);
  digitalWrite(blue1, LOW);
  digitalWrite(blue2, LOW);
  noTone(buzzer);
}

void loop() {
  digitalWrite(enablePWMPin, HIGH);
  digitalWrite(controlPinA, HIGH);
  digitalWrite(controlPinB, LOW);
  delay(3000);
  digitalWrite(controlPinA, LOW);
  digitalWrite(controlPinB, HIGH);
  delay(3000);
}

void loop() {
  digitalWrite(red1, HIGH);
  digitalWrite(red2, HIGH);
  digitalWrite(blue1, LOW);
  digitalWrite(blue2, LOW);
  delay(250);
  digitalWrite(red1, LOW);
  digitalWrite(red2, LOW);
  digitalWrite(blue1, HIGH);
  digitalWrite(blue2, HIGH);
  delay(250);
}

void loop() {
  int directionA = digitalRead(controlPinA);
  int directionB = digitalRead(controlPinB);
  if (directionA == HIGH && directionB == LOW) {
    digitalWrite(front1, HIGH);
    digitalWrite(front2, HIGH);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  } else if (directionA == LOW && directionB == HIGH) {
    digitalWrite(back1, HIGH);
    digitalWrite(back2, HIGH);
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
  } else {
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  }
}

```

I'm using an Arduino Uno. Can I start all the loop() functions at the same time?

# Answer
As the others have stated, no you can't have multiple loop functions. What you need to do is modify your approach so that each thing you are trying to do can be done sequentially without blocking (ie: remove the delay function usage). Expanding on some suggestions by JRobert, Here is how I would make these functions "run at the same time":

```
void loop() {

    lights1();
    lights2();
    motor();

}

void lights1() {

  static unsigned long lastTime = 0;
  const long interval = 3000;
  static bool state = 0;

  unsigned long now = millis();

  if ( now - lastTime > interval && state == 0) {
    state = 1;
    lastTime = now;
    digitalWrite(enablePWMPin, HIGH);
    digitalWrite(controlPinA, HIGH);
    digitalWrite(controlPinB, LOW);
  }

  if ( now - lastTime > interval && state == 1) {
    state = 0;
    lastTime = now;
    digitalWrite(controlPinA, LOW);
    digitalWrite(controlPinB, HIGH);
  }
}

void lights2() {

  static unsigned long lastTime = 0;
  const long interval = 250;
  static bool state = 0;

  unsigned long now = millis();

  if ( now - lastTime > interval && state == 0) {
    state = 1;
    lastTime = now;
    digitalWrite(red1, HIGH);
    digitalWrite(red2, HIGH);
    digitalWrite(blue1, LOW);
    digitalWrite(blue2, LOW);
  }

  if ( now - lastTime > interval && state == 1) {
    state = 0;
    lastTime = now;
    digitalWrite(red1, LOW);
    digitalWrite(red2, LOW);
    digitalWrite(blue1, HIGH);
    digitalWrite(blue2, HIGH);
  }

}

void motor() {
  int directionA = digitalRead(controlPinA);
  int directionB = digitalRead(controlPinB);
  if (directionA == HIGH && directionB == LOW) {
    digitalWrite(front1, HIGH);
    digitalWrite(front2, HIGH);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  } else if (directionA == LOW && directionB == HIGH) {
    digitalWrite(back1, HIGH);
    digitalWrite(back2, HIGH);
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
  } else {
    digitalWrite(front1, LOW);
    digitalWrite(front2, LOW);
    digitalWrite(back1, LOW);
    digitalWrite(back2, LOW);
  }
}

```

This approach will simulate running all three functions at the same time. Each function runs one at a time. But, since the delay has been removed from the light1/2 functions, they will end quickly during the 'waiting' period instead of pausing execution. This will allow the motor(s) to run and lights to blink all at the same time.
> 9 votes

# Answer
No you cannot.

Not only is it no proper C/C++ to have multiple identical functions, i.e. it will not compile (as jfpoilpret's comment suggests). It is also not in accordance with the idea of programm flow in the Arduino world - the sketches \- where you have two methods on the highest (user accessible) level: `void setup()` and `void loop()`. `setup` is run exactly once at the beginning of your program. Following that `loop` is looped (hence the name) forever. You need to properly restructure your code to implement your intended program flow, i.e. call your own functions from `loop`. Read more on www.arduino.cc with tutorials worth studying.
> 3 votes

# Answer
What are you trying to accomplish? Are these loops meant to run simultaneously (not possible)? Or one after the other? You could get pretty close to "simultaneous" if "real fast" is good enough. You'd need to

* Give each loop function a new, unique name;
* Split each of the first two loops at the delay()s for a total of 5 functions;
* Use a timer library such as SimpleTimer to run each of the functions at the rate you need them to.
* and from the only loop() function, keep calling SimpleTimer's '.run()' function to keep the whole thing going.

You could improve the speed of the individual functions by replacing the digitalRead() and digitalWrite() calls with direct reads and writes to port and bit you want read or set.
> 2 votes

# Answer
> I want to run them at the same time but in a different loop.

First of all, you can only do one thing at a time. So that's out.

Secondly, to run multiple loops sequentially (one at a time), it is fairly easy:

```
void loop1(void) {...}
void loop2(void) {...}
...

void loop(void) {
  loop1(); //run loop1
  loop2(); //run loop2
  ...
  loopn(); //run loopn
}

```

Whether it works will depend on how you have coded those loops.
> 2 votes

# Answer
To use multiple loops at the same time you need a **Arduino Due** Board. It is the only board compatible with library `#include <Scheduler.h>`

See Examples \> Scheduler Library \> Multiple Blinks

```
// Include Scheduler since we want to manage multiple tasks.
#include <Scheduler.h>

int led1 = 13;
int led2 = 12;
int led3 = 11;

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

  // Setup the 3 pins as OUTPUT
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  // Add "loop2" and "loop3" to scheduling.
  // "loop" is always started by default.
  Scheduler.startLoop(loop2);
  Scheduler.startLoop(loop3);
}

// Task no.1: blink LED with 1 second delay.
void loop() {
  digitalWrite(led1, HIGH);

  // IMPORTANT:
  // When multiple tasks are running 'delay' passes control to
  // other tasks while waiting and guarantees they get executed.
  delay(1000);

  digitalWrite(led1, LOW);
  delay(1000);
}

// Task no.2: blink LED with 0.1 second delay.
void loop2() {
  digitalWrite(led2, HIGH);
  delay(100);
  digitalWrite(led2, LOW);
  delay(100);
}

// Task no.3: accept commands from Serial port
// '0' turns off LED
// '1' turns on LED
void loop3() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c=='0') {
      digitalWrite(led3, LOW);
      Serial.println("Led turned off!");
    }
    if (c=='1') {
      digitalWrite(led3, HIGH);
      Serial.println("Led turned on!");
    }
  }

  // IMPORTANT:
  // We must call 'yield' at a regular basis to pass
  // control to other tasks.
  yield();
}

```
> 2 votes

---
Tags: programming
---


# Question
Title: Distance from Arduino UNO to LCD: How far?
How far from the UNO can I place an LCD (the typical 16x2)? Assuming that everything that is plugged into the LCD comes directly from the Arduino (power and data).

I'd like to mount the LCD on the wall at eye level, my "box" will be on the floor, close to a power source.

# Answer
The actual distance depends highly on several other factors:

* Wire thickness / current carrying capacity / resistance
* RFI (Radio Frequency Interference) environment
* Data rate that you write to the LCD (Maybe you are using an I2C or SPI backpack)

In general, even 5 meters is **probably** going to work if you use sufficient wiring, but try it and see.

You may also need to add shielding to mitigate RFI.
> 3 votes

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


title: Single & multi sensor code

text:
# Question
Title: Single & multi sensor code
I have been having problems trying to run multi sensor code for my project, this requires four KY-024 Linear magnetic Hall sensors as position sensors that trigger NC independent relays to make a circuit. I can get the code to run on one independent circuit, one hall switch one relay with no problems. But when I try the code for 4 hall sensors + relays I get no response from the circuit at this point I am at a loss where to go from here the code compiled with no problems.

```
int hallswitch = 1;
int val = 0;
int RELAY1 = 6;

void setup() {
  pinMode(hallswitch, INPUT);
  pinMode(RELAY1, OUTPUT);
}

void loop() {
  val = digitalRead(hallswitch);

  if (val == HIGH) {
    digitalWrite(RELAY1, HIGH);
  }
  else {
    digitalWrite(RELAY1, LOW);
  }
}

```

and

```
int hallswitch1 = 1;  //Pin for Hall switch
int hallswitch2 = 2;  //Pin for Hall switch
int hallswitch3 = 4;  //Pin for Hall switch
int hallswitch4 = 5;  //Pin for Hall switch

int val = 0;       //Integer for reading Hall statu

int RELAY1 = 6;    // The socket number on the Arduino that the relay1 will go to.
int RELAY2 = 7;    // The socket number on the Arduino that the relay1 will go to.
int RELAY3 = 8;    // The socket number on the Arduino that the relay1 will go to.
int RELAY4 = 9;    // The socket number on the Arduino that the relay1 will go to.

void setup()
{
  pinMode(hallswitch1, INPUT);
  pinMode (RELAY1, OUTPUT);

  pinMode(hallswitch2, INPUT);
  pinMode (RELAY2, OUTPUT);

  pinMode(hallswitch3, INPUT);
  pinMode (RELAY3, OUTPUT);

  pinMode(hallswitch4, INPUT);
  pinMode (RELAY4, OUTPUT);
}

void loop() {
  val = digitalRead(hallswitch1);               //Read Hall pin status
  val = digitalRead(hallswitch2);               //Read Hall pin status
  val = digitalRead(hallswitch3);               //Read Hall pin status
  val = digitalRead(hallswitch4);               //Read Hall pin status

  if (val == HIGH) {                        //If there is a magnet infront of Hall switch...
    digitalWrite(RELAY1, HIGH);             // Turn RELAY1 on:
    digitalWrite(RELAY2, HIGH);
    digitalWrite(RELAY3, HIGH);
    digitalWrite(RELAY4, HIGH);
  }
  else {
    digitalWrite(RELAY1, LOW);               // Turn RELAY1 off:
    digitalWrite(RELAY2, LOW);
    digitalWrite(RELAY3, LOW);
    digitalWrite(RELAY4, LOW);
  }
}

```

# Answer
> 1 votes
This is the quick and dirty way, I would suggest re writing it to use arrays rather then having to declare all these variables and copy paste pinMode, read,writes if statments a bunch of times.

```
 int hallswitch1 = 1;  //Pin for Hall switch
 int hallswitch2 = 2;  //Pin for Hall switch
 int hallswitch3 = 4;  //Pin for Hall switch
 int hallswitch4 = 5;  //Pin for Hall switch

 int val1 = 0;       //Integer for reading Hall statu
 int val2 = 0;
 int val3 = 0;
 int val4 = 0;

 int RELAY1 = 6;    // The socket number on the Arduino that the relay1 will go to.
 int RELAY2 = 7;    // The socket number on the Arduino that the relay1 will go to.
 int RELAY3 = 8;    // The socket number on the Arduino that the relay1 will go to.
 int RELAY4 = 9;    // The socket number on the Arduino that the relay1 will go to.

void setup()
{

  pinMode(hallswitch1, INPUT);
  pinMode (RELAY1, OUTPUT);

  pinMode(hallswitch2, INPUT);
  pinMode (RELAY2, OUTPUT);

  pinMode(hallswitch3, INPUT);
  pinMode (RELAY3, OUTPUT);

  pinMode(hallswitch4, INPUT);
  pinMode (RELAY4, OUTPUT);

}

void loop() {

  val1 = digitalRead(hallswitch1);               //Read Hall pin status
  val2 = digitalRead(hallswitch2);               //Read Hall pin status
  val3 = digitalRead(hallswitch3);               //Read Hall pin status
  val4 = digitalRead(hallswitch4);               //Read Hall pin status

  if (val1 == HIGH) {digitalWrite(RELAY1, HIGH);}
  else {digitalWrite(RELAY1, LOW);}

  if (val2 == HIGH) {digitalWrite(RELAY2, HIGH);}
  else {digitalWrite(RELAY2, LOW);}

  if (val3 == HIGH) {digitalWrite(RELAY3, HIGH);}
  else {digitalWrite(RELAY3, LOW);}

  if (val4 == HIGH) {digitalWrite(RELAY4, HIGH);}
  else {digitalWrite(RELAY4, LOW);}

}

```

---
Tags: arduino-uno
---


# Question
Title: Looking for Power Bank with "Always-On-Feature"
I want to build a mobile weather station with an Arduino and some sensors. I want to use a power bank as power source. The Powerbank should support "Always-On", because weather data should not be measured continuously. This means that almost no current flows between the time intervals. Common power banks switch off automatically when the current flow is low.

I don't want to connect an additional device or electronic component to increase the power consumption. So I need a power bank that doesn't switch off even when the current flow is low.

During my search I found the Powerbank "V44 USB Battery Pack" from Voltaic. Unfortunately I cannot buy them in Germany. https://www.voltaicsystems.com/v44

Can anyone recommend an alternative?

# Answer
> 2 votes
Lithium cell based powerbanks use a boost converter to boost the voltage from the Cell to the 5V for the USB. They turn off because keeping the voltage boosted when not used wastes quite a bit of power.

If all your devices can run straight on 3.3V you can use a Lithium cell directly with a voltage regulator (and with the normal protection circuitry).

Otherwise you can simulate a button press on the on button with a gpio pin to activate the boost circuitry when you are ready to take your measurements; let he voltage stabilize; use transistors to connect the components to power; take your measurements; disconnect the components and then let the timeout expire after which the voltage will drop again.

---
Tags: arduino-mega, sensors, power
---


title: PROGMEM Corrupted Array

text:
# Question
Title: PROGMEM Corrupted Array
I am trying to store a large number of values into a couple of arrays using PROGMEM, but I am finding that a few of the values are read back corrupted. I am storing just 1s and 0s, but when I read these values back, I will sometimes get values greater than 1. I am using a MEGA 2560 to do this.

```
// Each array contains 32000 values
const byte VALUES_1[] PROGMEM = { 1, 0, 1, .... 0 };
const byte VALUES_2[] PROGMEM = { 1, 1, 0, .... 0 };
const byte VALUES_3[] PROGMEM = { 1, 0, 1, .... 1 };
const byte VALUES_4[] PROGMEM = { 1, 0, 1, .... 1 };
const byte VALUES_5[] PROGMEM = { 1, 0, 1, .... 1 };

const long ARR_LEN = 32000;
long index = 0;

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

byte readNextValue() {
  if (index >= 160000L) {
    return -1;
  }

  Serial.print(index);
  Serial.print(" ");

  long arr = index / ARR_LEN;
  long i = index % ARR_LEN;
  index++;

  byte j = -1;
  switch(arr) {
    case 0:
      j = pgm_read_byte_far(VALUES_1 + i);
      Serial.println(j);
      return j;
    case 1:
      j = pgm_read_byte_far(VALUES_2 + i);
      Serial.println(j);
      return j;
    case 2:
      j = pgm_read_byte_far(VALUES_3 + i);
      Serial.println(j);
      return j;
    case 3:
      j = pgm_read_byte_far(VALUES_4 + i);
      Serial.println(j);
      return j;
    case 4:
      j = pgm_read_byte_far(VALUES_5 + i);
      Serial.println(j);
      return j;
  }

  Serial.println("Unable to return next value");
  return -1;
}

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

```

What I have noticed is that when I use `pgm_read_byte_far` for `case 0` I will get garbage values for right away, but using `pgm_read_byte_near` will cause these garbage values to occur sometime later. Any insight to this problem is appreciated.

# Answer
Just a follow up in case someone else has the same problem. One solution is Nick's answer in his comment, which grabs the far addresses first in the setup, storing them in an array, and using them. I

```
// Each array contains 32000 values
const byte VALUES_1[] PROGMEM = { 1, 0, 1, .... 0 };
const byte VALUES_2[] PROGMEM = { 1, 1, 0, .... 0 };
const byte VALUES_3[] PROGMEM = { 1, 0, 1, .... 1 };
const byte VALUES_4[] PROGMEM = { 1, 0, 1, .... 1 };
const byte VALUES_5[] PROGMEM = { 1, 0, 1, .... 1 };

long VALUES[] = { 0, 0, 0, 0, 0 };

const long ARR_LEN = 32000;
long index = 0;

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

  VALUES[0] = (long) pgm_get_far_address(VALUES_1);
  VALUES[1] = (long) pgm_get_far_address(VALUES_2);
  VALUES[2] = (long) pgm_get_far_address(VALUES_3);
  VALUES[3] = (long) pgm_get_far_address(VALUES_4);
  VALUES[4] = (long) pgm_get_far_address(VALUES_5);
}

byte readNextValue() {
  if (index >= 160000L) {
    return -1;
  }

  Serial.print(index);
  Serial.print(" ");

  long arr = index / ARR_LEN;
  long i = index % ARR_LEN;
  index++;

  byte j = pgm_read_byte_far(VALUES[arr] + i);
  Serial.println(j);

  return j;
}

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

```

This runs perfectly with all bytes correct. The better answer would be to convert the bytes into bits like everyone else was saying in order to save memory space.
> 2 votes

---
Tags: arduino-mega, progmem, atmega2560
---


# Question
Title: Can I generate 5 sec delay within an interrupt program?
```
void buttonPressed()
{
  if(ledOn)
  {
    ledOn = false;
    digitalWrite(13,LOW);
  }else
  {
    ledOn = true;
    digitalWrite(13,HIGH);
  }

  vout=analogRead(sensor);
  vout=(vout*500)/1023;
  tempc=vout; // Storing value in Degree Celsius
  tempf=(vout*1.8)+32; // Converting to Fahrenheit
  lcd.setCursor(0,0);
  lcd.print("ROOM TEMPERATURE");

  lcd.setCursor(0,1);
  lcd.print("C = ");
  lcd.print(tempc);

  lcd.print("  F = ");
  lcd.print(tempf);
  Serial.print("f ");
  Serial.print(tempf);
}

```

here is the code of interrupt and i want to monitor the sensor value for about 5second.

# Answer
You don't need interrupts for any of that. Your main loop just needs to test the switch, eg.

```
void loop ()
  {
  if (digitalRead (button) == HIGH)  // assuming LOW means pressed
     return;

  // read thermocouple here

  // display results

  delay (5000);

  }

```

---

> I want to print the value of the thermistor on lcd using interrupts and i want the value to stay about 5 secs

You are misusing interrupts in what you are attempting. See my page about interrupts. You simply should **not** be attempting to print or delay inside an interrupt routine. The most you should do is detect that the switch is pressed:

```
volatile bool switchIsPressed = false;

// Interrupt Service Routine (ISR)
void buttonPressed()
  {
  switchIsPressed = true;
  }  // end of buttonPressed ISR

```

Now in your main loop you detect that the switch is pressed and take your reading. If you want to do something else "remember" the time you showed the value, like this:

```
unsigned long whenTemperatureDisplayed = 0;

void loop ()
  {
  if (switchIsPressed && whenTemperatureDisplayed == 0)
    {
    // take reading ...
    // display reading ...
    whenTemperatureDisplayed = millis ();  // when we displayed the reading
    switchIsPressed = false;               // ready for next time
    }  // end of if switch was pressed

  if (whenTemperatureDisplayed != 0 &&
      millis () - whenTemperatureDisplayed >= 5000) // 5 seconds are up
    {
    // stop displaying the reading ...
    whenTemperatureDisplayed = 0;
    }  // end of if time is up

  // do other stuff here

  }  // end of loop

```
> 4 votes

# Answer
It's bad practice to use a delay within a timer, and 5 seconds is a huge amount of time. Also print statements and possibly lcd print statements I would not advice.

What is better, is to calculate the value, store it in a global variable (vout?). Than set a boolean that a new value has been calculated.

Your main program checks the boolean and does all the print/lcd code.

If you think you might miss values, than create a global array where you add values in your interrupt, and let the main program process the array.
> 3 votes

# Answer
Strictly speaking, yes you CAN generate 5 second delay in interrupt. But you really, really should NOT do it.

And if you are going to do it anyway, it could not be easily done with delay(), as Arduino supports only one level of interrupts and delay depends on interrupts enabled. (which can also be cheated away, but it should not be).

The right thing is use interrupt for fast detection of key pressed and manage other parts in loop(), see https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay how to wait in main, while doing other work.

Also using lcd and Serial inside interrupt can bring a lot of problems, especially if you are using it also in loop() (as the key can be pressed anytime and interrupt can well -interrupt- such commands in the loop and then make your output all wrong and possibly crash your program on the way too.)

---

Read http://gammon.com.au/interrupts if you want to know more about interrupts and why your idea is not the best possible way.

Question: Can I hit really hard my thumb with heavy hammer? Answer: Yes, you can, but you really should not do it. There are much better ways for using thumbs and hammers.
> 2 votes

---
Tags: arduino-uno, lcd, interrupt, temperature-sensor
---


title: How to fade out RGB strip?

text:
# Question
Title: How to fade out RGB strip?
I have a NodeMCU controlling an RGB strip. I have followed a guide and used this code:

```
#include <ESP8266WiFi.h>

#define redPin 13 //D7 - Red channel
#define grnPin 12 //D6 - Green channel
#define bluPin 14 //D5 - Blue channel
#define max(a,b) ((a)>(b)?(a):(b))

WiFiServer server(80); //Set server port

String readString; //String to hold incoming request
String hexString = "FFFFFF"; //Define initial color here (hex value), 080100 would be a calm warm tone i.e.

int state;
int r;
int g;
int b;

float R;
float G;
float B;

int x;
int V;

///// WiFi SETTINGS - Replace with your values /////////////////
const char* ssid = "xxxxxxx";
const char* password = "xxxxx";
IPAddress ip(x,x,x,x);      // set a fixed IP for the NodeMCU
IPAddress gateway(x,x,x,x);  // Your router IP
IPAddress subnet(255,255,255,0); // Subnet mask

void WiFiStart() {
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  //Set a fixed IP. You can comment this out and set it in your router instead.
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print("_");
  }
  Serial.println();
  Serial.println("Done");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("");
  server.begin();
}

void allOff() {
  state = 0;
  analogWrite(redPin, 0);
  analogWrite(grnPin, 0);
  analogWrite(bluPin, 0);
}

//Write requested hex color to the pins (10-bit PWM)
void setHex() {
  state = 1;
  long number = (long) strtol( &hexString[0], NULL, 16);
  r = number >> 16;
  g = number >> 8 & 0xFF;
  b = number & 0xFF;
  r = map(r, 0, 255, 0, 1023);  //added for 10-bit PWM
  g = map(g, 0, 255, 0, 1023);  //added for 10-bit PWM
  b = map(b, 0, 255, 0, 1023);  //added for 10-bit PWM
  analogWrite(redPin, (r));
  analogWrite(grnPin, (g));
  analogWrite(bluPin, (b));
}

//Compute current brightness value
void getV() {
  R = roundf(r/10.23);  //for 10bit pwm, was (r/2.55);
  G = roundf(g/10.23);  //for 10bit pwm, was (g/2.55);
  B = roundf(b/10.23);  //for 10bit pwm, was (b/2.55);
  x = max(R,G);
  V = max(x, B);
}

//For serial debugging only
void showValues() {
  Serial.print("Status on/off: ");
  Serial.println(state);
  Serial.print("RGB color: ");
  Serial.print(r);
  Serial.print(".");
  Serial.print(g);
  Serial.print(".");
  Serial.println(b);
  Serial.print("Hex color: ");
  Serial.println(hexString);
  getV();
  Serial.print("Brightness: ");
  Serial.println(V);
  Serial.println("");
}

void setup(){
  Serial.begin(9600);
  delay(1);
  pinMode(redPin, OUTPUT);
  pinMode(grnPin, OUTPUT);
  pinMode(bluPin, OUTPUT);
  setHex(); //Set initial color after booting. Value defined above
  WiFi.mode(WIFI_STA);
  WiFiStart();
}

void loop() {
  //Reconnect on lost WiFi connection (superfluous - will reconnect anyway)
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  while(client.connected() && !client.available()) {
    delay(1);
  }
  //Respond on certain Homebridge HTTP requests
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (readString.length() < 100) {
          readString += c;
        }
        if (c == '\n') {
          Serial.print("Request: ");
          Serial.println(readString);
          //Send reponse
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          //On
          if(readString.indexOf("on") >0) {
            setHex();
            showValues();
          }

          //Off
          if(readString.indexOf("off") >0) {
            allOff();
            showValues();
          }

          //Set color
          if(readString.indexOf("set") >0) {
            hexString = "";
            hexString = (readString.substring(9,15));
            setHex();
            showValues();
          }

          //Status on/off
          if(readString.indexOf("status") >0) {
            client.println(state);
          }

          //Status color (hex)
          if(readString.indexOf("color") >0) {
            client.println(hexString);
          }

          //Status brightness (%)
          if(readString.indexOf("bright") >0) {
            getV();
            client.println(V);
          }
          delay(1);
          client.stop();
          readString="";
        }
      }
    }
  }
}

```

I have tried to fade out by putting my code below in the `allOff()` function, but it only fades out then comes back white. I would also be interested in fading between different colours in the `setHex()` function.

```
void allOff() {
  state = 0;
  for (int i=r; i <= 1023; i--){
  analogWrite(redPin, i);
  analogWrite(grnPin, i);
  analogWrite(bluPin, i);
  }
}

```

I would appreciate it if anyone could give me the right way to do this. Thank you.

# Answer
> 1 votes
> ```
> for (int i=r; i <= 1023; i--){
>     analogWrite(redPin, i);
>     analogWrite(grnPin, i);
>     analogWrite(bluPin, i);
>     }
>
> ```

analogWrite expects a range of 0 to 255, not 0 to 1023.

In any case, why are you starting with the `r` value and decreasing that? What about `b` and `g`?

And why not stop at zero? Your code will reach zero, and then keep going down to -1, -2 etc. I think you mean `i >= 0` not `i <= 1023`.

Let's assume that the previously set values of r, g and b are what you want to fade. Make a loop that decreases them at the same rate:

```
for (float fade = 1.0; fade >= 0.0; fade -= 0.01)  // 100 steps
    {
    analogWrite(redPin, (float) r * fade);
    analogWrite(grnPin, (float) g * fade);
    analogWrite(bluPin, (float) b * fade);
    delay (10);  // short delay so you notice it
    }

```

---

> So how could I apply this code to fade between colours in my setHex function?

Well, fading to black is a special case of fading from one colour to another. To do it in (say) 100 steps you need to work out a "delta" - that is the difference, for each of r/g/b from the initial colour to the new one. So for example if the old red value was 10 and the new red value is 50, then the delta is 40 (50 - 10). So over your 100 steps you need to change the red value by 40 / 100. Using floating point arithmetic lets you handle numbers which aren't integers (in this case 40 / 100 would be 0.4). Example code:

```
  const float STEPS = 100;

  // save old values of r/g/b
  byte oldR = r;
  byte oldG = g;
  byte oldB = b;

  // calculate new values
  long number = (long) strtol( &hexString[0], NULL, 16);
  r = number >> 16;
  g = number >> 8 & 0xFF;
  b = number & 0xFF;

  // work out deltas
  float deltaR = (r - oldR) / STEPS;
  float deltaG = (g - oldG) / STEPS;
  float deltaB = (b - oldB) / STEPS;

  // fade from old to new
  for (float f = 0; f < STEPS; f++)
    {
    analogWrite(redPin, oldR + (deltaR * f));
    analogWrite(grnPin, oldG + (deltaG * f));
    analogWrite(bluPin, oldB + (deltaB * f));
    delay (10);
    } // end of for

```

---
Tags: programming, arduino-ide, c++, pwm, rgb-led
---


# Question
Title: Bluetooth module HC-05 not finding mobile phones, only PC
I put the HC-05 in the AT mode with arduino and the comands:

```
AT+CMODE=1
AT+ROLE=1
AT+INQM=0,10,48
AT+CLASS=0
AT+INIT
AT+INC

```

It responds "OK" after all till AT+INC, and after this, shows only my notebook's adress, but it has many other mobile phones near with bluetooth on (I can find with my cell phone) and they are not found. Why? Someone help me please

# Answer
Bluetooth maybe on, but some phones are "invisible" until you put them in "other Bluetooth devices can find me" -mode.

Current iPhones are visible when Bluetooth is on but, Androids for example, (at least 7.0 upwards) are visible only when you have the Bluetooth settings screen open.
> 0 votes

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


# Question
Title: 'AttachPinChangeInterrupt' was not declared in this scope
I am a beginner trying to upload the SimpleExample328.ino sketch on my Arduino Uno. When I verify my sketch however, I run into the error:

> 'AttachPinChangeInterrupt' was not declared in this scope.

I would assume the header file `PinChangeInt.h` is not in the correct location; currently the `PinChangeInt` folder (that contains `PinChangeInt.h`) is placed in the `Arduino IDE libraries` folder, which I believe is the correct location.

Did I place the header file in the wrong location or does this error result from another cause? Thanks :)

# Answer
> 1 votes
You don't have the library installed. To install:

The .ZIP file will download to your computer. Take note of the location.

* Open up the Arduino IDE
* Go to `Sketch` \> `Include Library` \> `Add .ZIP library...`
* Browse to the download location
* Select the PinChangeInt ZIP file

Its done! Compile your program and all should work!

---
Tags: arduino-uno, compilation-errors
---