# Question
Title: How to detect if LED is switched on in external circuit using Arduino NANO?
I want to detect when an LED is powered on using an Arduino NANO. The LED is part of an external circuit. The LED uses about 1.8V. Would the circuit below allow me to detect when the LED is switched on? Is this the correct method of doing it? (The LED in the diagram represents the external circuit).

# Answer
> 4 votes
I'm afraid your circuit does not work. In fact, the base of the transistor is always connected to the power, regardless the LED being ON or OFF. Therefore the BJT would be always in the ON-state. Also a current limiting resistor in series to the LED is missing (but I think that it was just for sake of simplicity).

Assuming that:

* you can mount in series something to the LED
* an additional 1.3-1.5V voltage drop will not cause too much issues (to be short: if the external circuit power supply is "large enough", and if you will not be too much upset if the LED luminosity will be smaller).
* You want to sense a signal LED, i.e. let's say with a current smaller than 20 mA.

Then, the safest way would be to use an optocoupler, such as 4N25-4N35. Put the LED of the optocoupler (transmitter side) in series to the LED you want to "sense", and use the phototransistor side to sense the LED status: it's emitter goes to the GND to your Arduino Nano, the collector to any input, with pull-up (The pull-up is mandatory!).

In this way, when current flows across the LED, it will also flow in the optocoupler LED, therefore the optocoupler phototransistor will be ON.

Also, using the optocoupler the two systems are electrically insulated each other (and you won't need to share the grounds).

Below you can find an example.

EDIT: If you cannot wire the optocoupler LED in series (e.g. not enough voltage headroom because the power supply is too close to the LED Vf, or your LED is already on a PCB), you can connect the optocoupler in parallel. Assuming the LED current is much larger than 1mA, you can use the following circuit. Choose RO so that the current flowing on the optocoupler will be 1mA (390-470 Ohm in your case). Usage of high current-transfer-ratio (CTR) optocoupler is suggested, but this might work also with a 4N25 or 4N35 (you'll be pretty close to the limit...)

# Answer
> 1 votes
The answer depends on your definition of "on".

An led is on if

1. There is voltage across I th or
2. There insufficient voltage across it, or
3. There is current through it, or
4. It generates light output, or
5. It generates sufficient light output.

...

Based on each of the above, there is an answer to your question.

# Answer
> 0 votes
No, you will not detect the LED state at all, as your transistor base is connected to the target circuit's supply rail, not a switched node.

Additionally, your circuit risks burning out the LED as it lacks a current limiting resistor.

Speaking more generally, the only *safe* way to do this with a fully unknown circuit is to have an optical sensor looking at the LED.

If you can determine that it is safe to make an electrical connection to the circuit (ie, that the internal ground is not riding on mains voltage) and that the point of the circuit you want to measure is within an allowed voltage above that, then you can connect the grounds and measure the switched side of the LED / resistor. **But until you have far more electrical engineering experience, you are probably not in a position to make this safety determination.** Even battery powered devices can generate dangerous voltages internally.

It's important that you not connect *between* the LED and resistor, but rather to whichever side of that series unit is not connected to a supply rail, as the voltage drop on the LED itself may not be sufficient to register.

Certain fancier LED drivers may give you problems, for example if they regulator current internally. Also, LEDs with PWM brightness control may require filtered polling, or even interrupts / hardware pulse-in.

---
Tags: led, arduino-nano, input, transistor
---


# Question
Title: Issue sharing MISO with multiple RC522 RFID Readers
so for about the last 8.5 hours (almost non-stop) I have been trying to figure out one issue and I have exhausted every search I could possibly think of.

I'm building a puzzle that requires 5 RFID readers on the 1 Arduino, but for the sake of testing i've only been using 2.

Both readers work independantly, I can read out the UIDs of the little cards, which is all I need to do, but as soon as I make them share the MISO line, it simply stops printing anything out. I have no idea why.

Both readers have a common external 3.3v power supply and ground, they share all other lines but have an individual Slave Select. For testing I put both of their MISO cables into a breadboard which then leads into the Arduino on PIN 12, but it will only print out the UID when only ONE cable is plugged into the breadboard.

So is there something special I need to do to make this work? Is there a reason why the readers sharing a MISO line would break it? Even if i don't initialise one of them, just for the fact that it's plugged in still breaks it. I have tried setting one to HIGH and one to LOW, both to LOW, both to HIGH, nothing changes it.

Also, something else kind of confusing to me, it's meant to be active LOW to activate the SS, but when only 1 is plugged into the MISO line, it doesn't seem to matter which state it's in, it always prints...

I did a little bit of testing on my sketch just a moment ago and realised that when both are plugged into the MISO, the sketch will not progress past this line (which is also the first line in the loop)

```
if ( ! mfrc522_2.PICC_IsNewCardPresent())
        return;

```

I know everything else is working because it works when there is nothing else plugged into the MISO line, but I need it to work when all the others are plugged in too.

Please please please, if you have any idea, let me know.

I'm using the MFRC522 Library

EDIT:

This is basically the setup i'm using:

I'm not using any voltage translators or shifters, everything is 5v from the arduino except for the power to the readers which is coming from an external 3.3v supply like mentions previously.

I'm pretty certain that this is the datasheet for the RC522 i'm using, though i'm not sure if it's V1 or V2, but given the differences between them I don't think it matters:

http://www.nxp.com/documents/data\_sheet/MFRC522.pdf

I don't know if they are able to share MISO lines like someone below said, I just assumed I could?

# Answer
> 4 votes
I am joining this conversation VERY late, however maybe my answer can help someone who is just now looking into this.

I was able to get SEVEN RC522 readers working on one Arduino! My solution was very similar to your idea, except instead of the SS pin, I used the MISO pin.

If you look into how the pins work, all of them are outputs going from the master (Arduino) to the slaves (RC522), EXCEPT for the MISO pin which is an input going from the slaves to the master.

So I gave each RC522 scanner it's own MISO pin on the Arduino, and the rest of the pins were shared with all the scanners.

To get it working with the code, the simplest solution I found was to initialize a new RFID using the corresponding MISO pin each time I wanted to read from one of the RC522s.

This worked for the Arduino because you can set several of the digital pins as MISOs, however I haven't figured out how to get this working on a Raspberry Pi yet (without using a multiplexer) because the Pi has a few specific pins that are used for MISO.

I was using the old Sunfounder library. At the bottom of this page (http://wiki.sunfounder.cc/index.php?title=Mifare\_RC522\_Module\_RFID\_Reader), if you download the "RFID-RC522\_test\_experiment" zip file it will have the library included. Just copy and paste the RFID1 folder into your Arduino Library folder. Here is a simple tutorial for that library: https://www.sunfounder.com/learn/RFID\_kit\_V1\_for\_Arduino/lesson-29-rfid-entrance-guard-system-rfid-kit-v1-0-for-arduino.html

Here is some example code. It is pretty ugly but it worked.

```
void checkRFID(int i){
  if(i==0){
    rfid.begin(2,4,5,7,3,6);
  }
  if(i==1){
    rfid.begin(2,4,5,8,3,6);
  }
  if(i==2){
    rfid.begin(2,4,5,9,3,6);
  }
  if(i==3){
    rfid.begin(2,4,5,10,3,6);
  }
  if(i==4){
    rfid.begin(2,4,5,11,3,6);
  }
  if(i==5){
    rfid.begin(2,4,5,12,3,6);
  }
  if(i==6){
    rfid.begin(2,4,5,13,3,6);
  }
  delay(100);
  rfid.init();
  uchar status;
  uchar str[MAX_LEN];
  // Search card, return card types
  status = rfid.request(PICC_REQIDL, str);
  if (status != MI_OK)
  {
    return;
  }
  // Show card type
  rfid.showCardType(str);
  //Prevent conflict, return the 4 bytes Serial number of the card
  status = rfid.anticoll(str);
  if (status == MI_OK)
  {
    memcpy(serNum, str, 5);
    rfid.showCardID(serNum);//show the card ID
    Serial.println();
    Serial.println();
  }
  delay(100);
  rfid.halt(); //command the card into sleep mode
}

```

# Answer
> 3 votes
Looking at the datasheet for the MFR522, it is not clear that it even supports multidrop SPI. It does not mention anything about the state of the SPI output pins when the chip is not selected. It also mentions that the chip uses the slave select line to detect what communication mode to use upon startup, but does not mention anything about how the chip will react to changes on that pin after startup.

Considering this, along with the fact to your library also does not seem to support connections to multiple MFR522, my guess is that this chip only supports a 1-to-1 SPI link.

Further, the SPI Timing characteristics in the datasheet specify how lon gthe SS (called NSS) must be high before communication can begin, but does not specify how long after SS goes low that the MISO goes tri-state, which would be an important thing to know if the chip did support multidrop SPI.

This is all backed up by the behavior you are seeing. If both chips are driving the MISO line simultaneously, then communication will not be possible when both are connected.

To support multiple MFR522 connections, you could possibly...

1. Use a multiplexing buffer to only enable SPI lines to one chip at a time. Downside is you would need Extra hardware, but upside is that you could probably use existing library intact by selecting the desired MFR522 before making the linrary calls.
2. Connect each MFR522 to different GPIO pins on the Arduino and bit bang the SPI to each chip independently. Upside is that you don't need any extra hardware and you potentially have a lot of flexibility on how you access the MFR522's. Downside is you will have to retrofit this bit-banged SPI into the library or use (or write) a different library.

I've seen this question come up many times over the years, so if you do choose option #2, please publish your code so others can use it!

# An Experiment

I'd propose you do this to find out if your chips are compatible with multi-drop SPI...

1. Power up your system with a RC522 reader.
2. Check and make sure it works.
3. Disconnect the SS and MISO lines from the RC522 so they are no longer connected to the Arduino (or anything else). Leave the RC522 powered up - if it resets it might loose the auto-detected SPI configuration.
4. Use a jumper to connect the SS line to ground.
5. Connect the MISO line to ground with a 1K ohm resistor.
6. Use a multimeter to check the voltage on the MISO line.
7. Connect the MISO line to Vcc with the 1K ohm resistor.
8. Use a multimeter to check the voltage on the MISO line.
9. Connect the SS line to Vcc.
10. Repeat steps 3-6.

Report back the table of the 4 voltage readings you got and we should have our answer!

# Answer
> 2 votes
I do not know if every module has a pull-up resistance in sck and mosi if that is the case, it could be that for every module connected over teh lines the resistance gets lower. so maybe the module can not drop the voltage so there is no comunication. check with a multimeter the resistance between Vcc and MOSI it has to be around 4.7k generally. hope this could help.

---
Tags: arduino-uno, spi, rfid
---


# Question
Title: Problem with transmitting 2 byte data in correct way
I'm using Atmel Studio with Atmega328P.

I'm trying to send the decimal number 876 continuously from the micro-controller. This was just to learn.

To send 876 I need two bytes which is:

0x036C = 00000011 01101100

So I manipulated a code and here is what I use now:

```
#include <avr/io.h>
#define F_CPU 16000000
#define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

void USART0Init(void)
{
    // Set baud rate
    UBRR0H = (uint8_t)(UBRR_VALUE>>8);
    UBRR0L = (uint8_t)UBRR_VALUE;
    // Set frame format to 8 data bits, no parity, 1 stop bit
    UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);
    //enable transmission and reception
    UCSR0B |= (1<<TXEN0);
}

int main (void)
{
    //Initialize USART0
    USART0Init();

    while(1)
    {

        UDR0 = 0b00000011;
        UDR0 = 0b01101100;

    }

}

```

The problem is at the receiving side the data comes as:

01101100 00000011 00000011 . . .

Here is the screen shot of the binary data at the receiving end:

However it should be received correctly as two byte chunks 00000011 01101100.

And here you can see the problem of the data being received as uint16(not only 876 as desired):

How can I fix this and receive the data properly as two bytes with correct order as 876?

# Answer
The data sheet for the 328P - section 24.7.1 - contains an example of waiting for the transmission to complete before sending another byte.

When sending serial data, you determine the order of bytes and will need to reassembly in the correct order on receipt. You can use bit shift operators to move the bytes back into the correct location. If you send the most significant byte first (MSB) and then the least significant byte (LSB), putting them back into a 16 bit integer would look something like:

uint16\_t result = (MSB \<\< 8) | LSB;
> 1 votes

# Answer
Your code has a fundamental error: when you write "UDR0 = 0b00000011;", the CPU does not wait until the transmission is complete - that would be terribly wasteful, in terms of time. It just write to the transmit data buffer. Furthermore, if the transmission was not ongoing yet, that instruction also starts transmission (assuming the USART is properly initialized, as it is in your case). However, if a transmission is ongoing, and the data buffer is not empty, this write instruction might be either ignored or it might overwrite the data on the buffer.

Therefore, with your code, you're continuously writing two bytes (at a very high speed, because that loop would result in very few asm instructions), without checking if actually you can write to the transmit data buffer register. This will result in most of the bytes being "randomly" ignored, with some other being randomly picked and trasmitted.

Before sending any data, you must check if the data register is empty:

```
while ( !(UCSR0A & (1 << UDRE0)));
UDR0 = firstByte;
while ( !(UCSR0A & (1 << UDRE0)));
UDR0 = secondByte;

```

Where firstByte and secondByte are either the numeric values or two 8-bit variables.

Instead of the two "while" statements, you can use the built-in macro:

```
loop_until_bit_is_set(UCSR0A, UDRE0);

```
> 1 votes

# Answer
First, you want to determine what you are trying to send. Send data in binary form is rare.

Secondly, you want to wait for each transmission to send before starting the next one.
> 0 votes

---
Tags: serial, avr, byte-order
---


# Question
Title: Does data coming in on Arduino serial port store for some time?
I am using Arduino Uno and my question is when data is coming on Rx pin and at that time our program is not checking Serial.available()

Then after some time the program will check Serial.available(). Can we read data? Does it get stored in memory?

If stored how to remove that?

Is the answer the same for Software.Serial()?

# Answer
Yes. The serial port uses a *ring buffer* (also known as a *circular buffer*) for storing the incoming data until you want it. That buffer is 16 bytes in size on the smaller Arduinos and 64 bytes in size on the larger one. A similar ring buffer is used to store transmitted data until the port is ready to transmit it in the background.
> 7 votes

# Answer
Yes. The receive ring buffer is 64 bytes and will discard anything past that until the program reads them out of the buffer.

> But be careful: In serial monitor, any number of bytes more than 64 and ending with Enter will give you `Serial.available==63` at the Arduino - and no `\n` at the end. This is important especially if you are using readline() in Python.
>
> However, when NOT in the serial monitor, you can actually get the result `Serial.available==64` and use Serial.read() to get them in sequence. No `\n` is required.
>
> So be careful debugging in the serial monitor when it comes to buffer size and newlines. It is subtly different when programs are talking vs the serial monitor.
>
> **Most important difference is that a program can send a single byte and continue. Serial monitor will send a single character, but is blocked until you press newline to get it to transmit. Yet serial monitor does not send the newline character.**

---

Simple scenario: You want the Arduino to respond to a single-byte command code send via the serial cable from a Raspbian system running a Python data logging program based on something the Arduino reads or by time of day.

You need to trigger the Arduino to take some action as a result.

So on the Arduino you want to first clear the receive buffer by simply reading it out like so:

Arduino code to read a single-character command:

```
byte ch;
void setup() {
  Serial.begin(9600));
  while (Serial.available>1) ch = ser.read();
}
void loop {
  if (Serial.Available==1 && Serial.read()=='X') {
     .....respond to the X command....
  }
  else
     ....etc...
  delay(60000);
}

```

> Note that when a Rpi Python program is sitting there waiting for linein=ser.readline() the Arduino transmit buffer size is not relevant. Python collects each byte as it comes in until the `\n` then returns the string to linein. The line can be very long. I have tested it to 100 bytes.

---

Software.Serial acts exactly the same way.
> 2 votes

---
Tags: arduino-uno, serial, xbee, communication, softwareserial
---


# Question
Title: Flashing ESP8266 over WiFi whith samrtphone?
I'm working on a project in which an ESP8266 is the brain of the device. I want to add new features to the device controller later but this requires that the user open the controller and reprogram the ESP8266.

I want the user to be able to update the firmware with his smartphone (maybe through an application). How can I do that? Is this possible with this chip?

# Answer
> 3 votes
ESP8266 OTA can be performed through a web browser as detailed in the ESP8266 OTA information page.

Since a smartphone has a web browser I can see no reason why you can't use that.

---
Tags: programming, esp8266, flash
---


# Question
Title: Programming Leonardo with TTL to USB cable
I have wired my Arduino as seen in the picture, with the RX of the cable plugged into the TX (D1) of the Leonardo and the TX of the cable plugged into the RX(D0) of the Leonardo. I then have the ground plugged into GND and the power into 5V. The driver is installed correctly and the IDE recognizes the port, however, whenever I try and upload any sketch, I get the error:

Programmer Type : butterfly Description : Atmel AppNote AVR109 Boot Loader

Connecting to programmer: .avrdude: butterfly\_recv(): programmer is not responding

avrdude: butterfly\_recv(): programmer is not responding

I can upload sketches fine via usb, is it just unable to do so via a USB to TTL cable?

Thanks in advance

# Answer
The bootloader on the Leonardo operates through the native USB port of the ATMega32U2 chip, not the UART.

You cannot treat it like an Uno because it isn't an Uno.

You can only program it through the USB port or through the ICSP connector.

If you want to use UART to upload you will need to replace the bootloader with a suitable UART based alternative. (Before you ask, no I don't know if one even exists or where to get it if it does).
> 2 votes

---
Tags: serial, arduino-ide, usb, arduino-leonardo
---


# Question
Title: Using Raspberry Pi to Receive Float from Arduino using NRF24L01
Good day. I've been learning on how to transfer data from Arduino to Raspberry Pi wirelessly using NRF24L01 based on the following reference: Raspberry Pi 3 Tutorial 14 – Wireless Pi to Arduino Communication with NRF24L01+.

The reason why I want to do this is to log temperature and humidity data wirelessly using DHT22 sensors.

The Arduino code is shown below:

```
//SendReceive.ino

#include<SPI.h>
#include<RF24.h>

// CE, CSN pins
RF24 radio(9, 10);

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

    radio.begin();
    radio.setPALevel(RF24_PA_MAX);
    radio.setChannel(0x76);
    radio.openWritingPipe(0xF0F0F0F0E1LL);
    const uint64_t pipe = (0xE8E8F0F0E1LL);
    radio.openReadingPipe(1, pipe);

    radio.enableDynamicPayloads();
    radio.powerUp();

}

void loop(void){
    radio.startListening();
    Serial.println("Starting loop. Radio on.");
    char receivedMessage[32] = {0};
    if(radio.available()){
        radio.read(receivedMessage, sizeof(receivedMessage));
        Serial.println(receivedMessage);
        Serial.println("Turning off the radio.");
        radio.stopListening();

        String stringMessage(receivedMessage);

        if(stringMessage == "GETSTRING"){
            Serial.println("Looks like they want a string!");
            const char text[] = "Yo wassup, haha";
            radio.write(text, sizeof(text));
            Serial.println("We sent our message.");
        }
    }
    delay(100);

}

```

Meanwhile, the Raspberry Pi code is shown below:

```
import RPi.GPIO as GPIO
from lib_nrf24 import NRF24
import time
import spidev

GPIO.setmode(GPIO.BCM)

pipes = [[0xE8, 0xE8, 0xF0, 0xF0, 0xE1], [0xF0, 0xF0, 0xF0, 0xF0, 0xE1]]

radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 17)

radio.setPayloadSize(32)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MIN)

radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()

radio.openWritingPipe(pipes[0])
radio.openReadingPipe(1, pipes[1])
radio.printDetails()
# radio.startListening()

message = list("GETSTRING")
while len(message) < 32:
    message.append(0)

while(1):
    start = time.time()
    radio.write(message)
    print("Sent the message: {}".format(message))
    radio.startListening()

    while not radio.available(0):
        time.sleep(1 / 100)
        if time.time() - start > 2:
            print("Timed out.")
            break

    receivedMessage = []
    radio.read(receivedMessage, radio.getDynamicPayloadSize())
    print("Received: {}".format(receivedMessage))

    print("Translating the receivedMessage into unicode characters")
    string = ""
    for n in receivedMessage:
        # Decode into standard unicode set
        if (n >= 32 and n <= 126):
            string += chr(n)
    print("Out received message decodes to: {}".format(string))

    radio.stopListening()
    time.sleep(1)

```

Based on the Arduino code above, the code that shows the data that is transmitted is shown below:

```
const char text[] = "Yo wassup, haha";

```

Based on the Raspberry code above, the codes that decode the received data from Arduino are shown below:

```
for n in receivedMessage:
    # Decode into standard unicode set
    if (n >= 32 and n <= 126):
        string += chr(n)

```

However, these decoding code only works if I transmit string or integer from Arduino to Raspberry Pi. It doesn't work if I transmit float. Since DHT22 records temperature and humidity up until 1 decimal point, it is required for me to transmit float. Can anyone here please teach me how to decode the float values?

Thank you very much.

# Answer
> 1 votes
If you say you only need one digit, why not multiplying your value with 10 (with rounding), transmit it as a 4 byte (unsigned?) integer, and divide by 10 after receiving.

You only need to check if you have little or big endian conversion needed (swapping MSB/LSB 2 byte or single byte). But you see this very fast if you print the values in hex format.

---
Tags: arduino-uno, nrf24l01+, raspberrypi
---


# Question
Title: Is it possible to use Wi-Fi as a wireless connection to my Arduino/Windows PC LAN without using the internet
My Situation and Problem:

I am wanting to put together a system to help monitor the soil moisture content in my garden and a small heated greenhouse I use in the winter. Also, In the near future I would like to build a system to remotely monitor the nutrients in my soil and other grow media, and have it accessible through my computer using a system similar to the one I'll have monitoring the moisture levels. In both situations I am growing nearly all crops hydroponically.

I have found several instances of people doing this by having the information posted to a service provider's website. Then it is possible to access the information by way of email or connecting in some manner to the service provider's site.

I plan to store the data in the cloud, but where I live we get internet access through satellite dish or land based re-transmission sites. So, I am planning to keep all gathered data in "The Cloud" manually, once received when I turn on my computer. I even have to use a booster device in my house to get dependable cell phone service. My land line telephone service provider doesn't offer high speed internet service, so I don't presently use a smart phone. I recently read a news article talking about a similar, though more widespread situation in Australia. In Australia they call it the tyranny of distance.

In addition to my garden and greenhouse, I have several other ideas for using Arduino to gather data using wifi and do any number of other things, and most of these ideas include accessing the gathered data through my computer connected to an Arduino device as required. It would certainly be helpful if anyone would be willing to share any ideas or point me toward inexpensive solutions.

Thanks for your kind consideration.

# Answer
> 1 votes
I have a hydroponic setup working. Actually I'm working in a second version. My solution is this:

I'm using a nodeMCU, because it have WiFi and lots of memory. In the breadboard I also have a real time clock (RTC), a LDR to measure real light level, and a temp/humidity sensor (DH-11), plus a small OLED display. The green led represent the HID light for testing purposes. I still need to add more elements, but it's good enough to show you my setup.

The nodeMCU send information to a MQTT *broker* . I can watch that information using an MQTT *client* in my Android smartphone. With the same client I can send orders to the nodeMCU (like changing light schedule, etc.)

MQTT is a protocol designed for Internet of Thing. It small and simple. You need a *broker* (server) to receive and send messages. I'm using Mosquitto running on Linux, on a old laptop that is on all time.

This is the big picture (no Internet involved):

Mosquitto is free, and it's available for PC, Mac and Linux here.

You have free clients for Android, iPhone, Windows, Mac, and Chrome. I'm using MQTT Dash.

MQTT is lightweight, easy, multiplatform, multiclient, and the best part of it: minimal programming.

# Answer
> 0 votes
Ok, my idea is that you could connect the arduino AND your computer to the same router ( that doesn't need to internet access) to create a simple LAN. Then program the arduino to send every X amount of time data to the computer with a simple protocol like UDP knowing the LAN address of the computer ( example would be 192.168.1.2) and the one of the arduino, you could send UDP packets with IP address of the computer and since the router sees that the IP is in its internal LAN it just sends it straight away. Now there are a few problems to this approach:

1) The arduino needs to have signal to be connected with the router, so the distances need to be reasonable.

2) Both the arduino and the computer needs to be always on. The arduino isn't a big issue, just remember that if for some reason you'll use the millis() or micros() functions eventually they'll reset to 0 and start again. As for the computer instead, this could be a bit expansive, since having a normal pc on for all the time can impact the electricity bill quite a bit. The solution to this would be for example to make the arduino write data on a SD card and when it sees that the computer is on and that it's able to send it to it, it starts retriving data from the SD, sending it to the PC and then deleting it. The problem with this is that the SD has a limit as well, so just keep this in mind.

---
Tags: wifi
---


# Question
Title: How can I have the user instantiate an object?
So I'm building a MIDI controller. It has a 16-positions selector that lets the user select a "program": a playlist of commands to send to a MIDI instrument.

A push-switch allows the user to scroll through that playlist, running each command in sequence, one at a time.

The way I'm trying to implement this is as follows: Playlist is a pure abstract class and each Program is derived from it. Each Program would have their own methods for each step, an array of pointers to these functions and a public playNext() method that loop() could call whenever the push-button is pressed with program.playNext()

I'm stuck at the selection of a program stage. I guess I could have an array of pointers to each program and call \*arrayOfPrograms\[currentProgram\]-\>playNext() but that would mean I would have to instantiate all the programs in setup() and keep them alive at all times...

Is there a way I could only instantiate the selected program and still call its playNext() method easily?

Sorry for the noob question. I'm fairly new to this and it gets confusing very quickly ;-) Thanks for your help.

Max

# Answer
You seem like you are almost there. Allocate the objects using `new` and free with `delete`.

```
// Abstract parent
class Playlist {
    public:
    virtual void playNext() = 0;
    // etc.
};
// Derived classes
class Something : public Playlist
    public:
    void playNext() {
        // your code here
    }
};
class SomethingElse : public Playlist
    public:
    void playNext() {
        // your code here
    }
};
// More derived classes......

// A pointer of the current program
Playlist *play_list = nullptr;

// A factory function to create a Playlist while also freeing previous
Playlist * create_playlist(int which_program) {
    // Important - delete old
    delete play_list;
    play_list = nullptr;
    // There are only 16 types, use a switch or if
    switch (which_program) {
        case 1:
            // Create a new one and save in global ptr
            play_list = new Something;
            break;
        case 2:
            play_list = new SomethingElse;
            break;
        // More cases here.....
    }
    return play_list;
}

```

\[edit\]--------------------------

Ok. The issue is that C++ does not have a lot of reflection options. So you can't create a class only by its name (as a string). Here's another solution I came up with. It's not completely automatic as it involves registering each class in `setup`. But I think it's close to what you want:

```
class Playlist;  //Forward declaration

// Each class will have a function to create itself
typedef Playlist * (*CreateFunc)();

// The parent class. It also holds a list of all child classes
// Could probably refactor into 2 separate classes
class Playlist{
  public:
  // Need virtual dtor
  virtual ~Playlist() {
    delete last_created;
  }

  // Put all the overridable function declarations here
  virtual void playNext() = 0;

  // This has to be called for each child. (See macro below)
  static void register_class(int id, CreateFunc f) {
    all_maps[num_maps].id = id;
    all_maps[num_maps++].f = f;
  }

  // Factory method to instantiate an object
  static Playlist * create_playlist(int id) {
      // Delete old pointer
      if (nullptr != last_created) {
          delete last_created;
          last_created = nullptr;
      }
      for (int i = 0; i < num_maps; i++) {
          // Search the list for name match
          if (id == all_maps[i].id) {
              // Call the creation func
              return all_maps[i].f();
          }
      }
      return nullptr;
  }
  protected:
  // A struct to hold the class name and a pointer to the creation function
  struct Map {
    int id;
    CreateFunc f;
  };
  static Map all_maps[32];
  static int num_maps;
  static Playlist* last_created;
};
// Static declarations
Playlist::Map Playlist::all_maps[32] = {{0, nullptr}};
int Playlist::num_maps = 0;
Playlist* Playlist::last_created = nullptr;

// Example child class
class Child1 : public Playlist{
  public:
  void playNext() {Serial.println("Child1");}

  // Must have this function and it must be static
  static Playlist * create() {return new Child1;}
};
// Another example
class Child2 : public Playlist{
  public:
  void playNext() {Serial.println("Child2");}
  static Playlist * create() {return new Child2;}
};

// Helper macro to simplify registering
#define REGISTER_PLAYLIST(id, name) Playlist::register_class(id, &name::create)

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

  // This must be done for all classes
  REGISTER_PLAYLIST(0, Child1);
  REGISTER_PLAYLIST(1, Child2);

  // Example usage
  Playlist*p = Playlist::create_playlist(0);
  p->playNext();
  p = Playlist::create_playlist(1);
  p->playNext();
}

void loop() {

}

```

I just whipped this up. Probably room for improvement....
> 1 votes

# Answer
I'm not fully understanding the way your sketch should work.

However, I think what you need is some kind of Controller object. The controller object instantiates one program. The controller also keeps a Boolean to play the next one (playNext). Once the program finishes, the controller can delete the just played program, checks if the Boolean is set to play the next, instantiate the next program to play and play it.

This results that programs are not depending on each other.
> 0 votes

---
Tags: arduino-uno, c++
---


# Question
Title: strcat appending multiple times when called in loop
The strcat function is working fine when called for the first time but when the broker goes down and it's attempting to reconnect it is appending the value twice. I am not able to figure out the problem as i am writing C code for the first time.

```
void reconnect() {

  while (!client.connected()) {
    const char* cid = clientID.c_str();
    if (client.connect(cid)) {
       const char* sTopic = strcat("clm/",cid);
       client.publish(outTopic, sTopic);
       client.subscribe(sTopic);
    } else {
    // Wait 5 seconds before retrying
    for(int i = 0; i<5000; i++){
      delay(1);
    }
  }
}

```

}

It is called in the loop method

```
void loop() {
  if (!client.connected()) {
    reconnect();
  }
}

```

The value of sTopic for the first time is `clm/5C:CF:7F:3D:5B:F6` but when the broker restarts and the client connects again it is `clm/5C:CF:7F:3D:5B:F65C:CF:7F:3D:5B:F6`

What could be the reason for the same ?

# Answer
> 1 votes
strcat won't allocate any memory for the new string. So what really happens is that the location where the string constant `"clm/"` is stored gets the id appended.

In other words the second time around it's as if you passed `"clm/5C:CF:7F:3D:5B:F6"` as first parameter.

To fix that you need to supply a proper buffer for strcat to do its work:

```
if (client.connect(cid)) {
   char[64] sTopic ={0};
   strcat(sTopic , "clm/");
   strcat(sTopic , cid);

```

# Answer
> 2 votes
> Appends a copy of the *source* string to the *destination* string.

source

Congratulations, you've broken your string literal. Either stick to using `String` or make sure you allocate a string properly and then concatenate into that.

# Answer
> 0 votes
You have to cat only one string per time. Your assumption is that it performs

```
dest = strcat(string_1, string_2)

```

However, it is:

```
dest = strcat(dest, string_1)

```

So you should use

```
char sTopic[256]; // Max possible length

...

strcpy(dest, "clm/");
strcat(dest, cid);

```

This will first copy "clm/" to dest, than cid will be concatenated.

(code not tested)

See reference: reference

---
Tags: esp8266, c
---


# Question
Title: Urgent need of help splitting a JSON formatted string received by UDP
I guess that my problems are because I'm new to C, but after spending three evenings without success I thought I'd give it a try to ask here!

I receive a JSON-formatted string in a UDP message. It contains several values that I would like to catch and convert to variables. The string format is like this:

```
{
  "U1": 224,
  "U2": 227,
  "U3": 224,
  "I1": 0,
  "I2": 0,
  "I3": 0,
  "P": 0,
  "PF": 0,
  "E pres": 639,
  "E total": 69901578,
  "Serial": "16889379",
  "Sec": 393833
}

```

Actually I really only need to get values U1, U2, U3 and I1, I2, I3. I'm grateful for all the help I can get solving this!

Best regards Per

# Answer
Two possible approaches:

1. Tokenize the string using `strtok()`, probably a few levels deep. This may require you learning quite a bit more about C++, pointers, and character arrays as strings.
2. An excellent opportunity to use an existing library, such as ArduinoJSON, which abstracts out the difficulties you may encounter if the fields in your JSON string arrive in a different order, etc.

An example of using ArduinoJSON for your case is shown in the documentation (excerpted/adapted from Decoding JSON)

```
#include <ArduinoJson.h>

// [...] other code

char json[] = "{ \"U1\": 224, \"U2\": 227, \"U3\": 224, \"I1\": 0, \"I2\": 0, \"I3\": 0, \"P\": 0, \"PF\": 0, \"E pres\": 639, \"E total\": 69901578, \"Serial\": "16889379", \"Sec\": 393833 }";

//
// Step 1: Reserve memory space
//
StaticJsonBuffer<200> jsonBuffer;

//
// Step 2: Deserialize the JSON string
//
JsonObject& root = jsonBuffer.parseObject(json);

if (!root.success())
{
  Serial.println("parseObject() failed");
  return;
}

//
// Step 3: Retrieve the values
//
uint16_t    u1 = root["U1"];
uint16_t    u2 = root["U2"];
uint16_t    u3 = root["U3"];
uint16_t    i1 = root["I1"];
uint16_t    i2 = root["I2"];
uint16_t    i3 = root["I3"];

```
> 1 votes

---
Tags: string, json
---


# Question
Title: Using Serial as boolean function argument
The following program compiles in the Arduino IDE.

```
void doSomething(bool) {}

void setup() {
  doSomething(Serial);
}

void loop() {}

```

But, as expected, this one doesn't:

```
class MyClass {};

void doSomething(bool) {}

void setup() {
  MyClass myClass;
  doSomething(myClass);
}

void loop() {}

```

The compiler returns the error `cannot convert 'MyClass' to 'bool' for argument '1' to 'void doSomething(bool)'`

---

Why is it possible to compile the former? Isn't Serial a normal class instance (of `HardwareSerial`)? Does it makes any sense to interpret `Serial` as a bool?

# Answer
> 4 votes
`HardwareSerial` defines `operator bool()`, which allows it to be used in a boolean context.

---
Tags: serial
---


title: Arithmetic types in Arduino

text:
# Question
Title: Arithmetic types in Arduino
I'm looking for a complete list of the arithmetic types in the Arduino framework. On the Internet I found various incomplete lists: sometimes there is `short`, sometimes `word`, but other types are missing.

Could someone please provide an exhaustive list of the arithmetic data types in Arduino, including the C/C++ types and the Arduino-defined types (or aliases, e.g. the one created among others in Arduino.h with `typedef uint8_t byte;`) with a short description? If two types are identical please include both names in the list but making clear that they are the same.

# Answer
You have integers in 8, 16, 32 and 64 bits, both signed and unsigned. You have float and double, which can be the same thing on some systems.

There are many names given to those variable types, some standard or ubiquitous, some vague or unique, or change depending on which type of CPU you are working with.

The names aren't important, since they only exist in the source code. All that matters is the underlying size. Names of the same underlying size and signedness are interchangeable at will.

For example:

* uint8\_t = unsigned char
* int32\_t = long = int on 32 but systems
* uint16\_t = unsigned short = int on 8 bit systems

As you can see `int` changes depending on the system you are on. So it is best to stick to specifically named types. I always use the `[u]int[N]_t` types.

So you have:

* uint8\_t
* int8\_t
* uint16\_t
* int16\_t
* uint32\_t
* int32\_t
* uint64\_t
* int64\_t

And:

* float
* double (if the compiler supports double on the platform you are compiling for, otherwise it is just float).

Arduino itself provides some more unique variable names that are completely nonstandard, such as `byte` for `unsigned char`.

In `short` (pun intended), stick to variables that specifically define their type if you are worried about how big they all are, and avoid all the rest.

For overloading the compiler will automatically "upscale" the variables to the best fitting available function (known as *type promotion*) unless functions are flagged as `explicit`, so you can have a function with a `long` parameter and pass any integer variable up to and including a `long` in size. The same with `float` / `double` types - if your function takes a `double` you can pass it a `float`. Useful when you don't know if the target provides a real `double` or not - just use `double` and it will work regardless with either `double` or `float`.
> 2 votes

# Answer
The Arduino "language" is actually C/C++. GNU GCC and tool chain are used. The Arduino IDE uses a preprocessor to make it easier for beginners by removing some of the C/C++ requirements such as forward declaration of functions.

The GNU AVR GCC data types and representation, and the answer to your question can be found on the project Wiki page; https://gcc.gnu.org/wiki/avr-gcc

For C/C++ there are build-in data types but also a set of standards. One of the standard header files with data types is `stdint.h`. http://www.nongnu.org/avr-libc/user-manual/group\__avr\__stdint.html

`Arduino.h` and additional header files within the Arduino core libary contains the extensions or redefinitions made. The complete reference list; https://www.arduino.cc/en/Reference/HomePage

Cheers!
> 2 votes

---
Tags: data-type
---


# Question
Title: Can I read two PWM signals and output two square waves on an UNO?
My system requires that I read two independent PWM signals (60hz) and output two corresponding square waves. These output square waves vary in frequency according to their corresponding input duty cycle. The output frequencies will vary between 1-60Hz. (outside of tone() range)

I'm planning out the best way to approach this project. My initial thought is to use the two available external interrupts set to CHANGE to measure the inputs. I believe I'll also need to reference a timer in this routine, to determine the time since the last change.

Unless I'm mistaken, it looks like I will also need a timer interrupt for each output, to control the frequency properly.

The Arduino UNO has 3 timers. timer0: 8bit (used internally), timer1: 16bit, and timer2: 8bit. In short, can I run all of these interrupts in the same code? Will I run out of timers, or can I multitask the timers between my requirements?

Thanks!

# Answer
Your signals are slow enough that you may not need any timer. You can just use the Arduino `micros()` function to handle all your timings. Of course, `micros()` itself relies on Timer 0, but you don't need to access any timer directly.

I would use the external interrupts in `CHANGE` mode to measure the duty cycle. For example:

```
const uint8_t INPUT_0_PIN  = 2;  // digital 2 is also INT0
const uint8_t OUTPUT_0_PIN = 4;

// Measured duration of the HIGH level of input 0.
static volatile uint32_t input_0_high_time;

// Interrupt handler invoked when input 0 toggles.
static void on_input_0_change()
{
    static uint32_t time_rise;             // last time the signal rose
    uint32_t now = micros();
    if (digitalRead(INPUT_0_PIN) == HIGH)  // detected rising edge
        time_rise = now;
    else                                   // detected falling edge
        input_0_high_time = now - time_rise;
}

void setup()
{
    pinMode(INPUT_0_PIN, INPUT);
    pinMode(OUTPUT_0_PIN, OUTPUT);
    attachInterrupt(0, on_input_0_change, CHANGE);
}

```

For handling two inputs, you can duplicate everything that has a `0` in its name and name it with a `1`. If your signal is no slower than 60 Hz, you can also replace all `uint32_t` by `uint16_t` to make the code slightly faster.

For generating the outputs, do something similar to the Blink Without Delay example:

```
void loop()
{
    uint32_t now = micros();

    // Determine suitable period for output 0.
    uint32_t input_0_high_time_copy;
    noInterrupts();  // avoid race condition while reading
    input_0_high_time_copy = input_0_high_time;
    interrupts();
    uint32_t output_0_half_period =
            map(input_0_high_time_copy, 0, 16666, 8333, 500e3);

    // Toggle output 0 when needed.
    static uint32_t time_output_0_toggle;
    static uint8_t output_0_state;
    if (now - time_output_0_toggle >= output_0_half_period) {
        time_output_0_toggle += output_0_half_period;
        output_0_state = !output_0_state;  // toggle state
        digitalWrite(OUTPUT_0_PIN, output_0_state);
    }
}

```

Again, you can handle two outputs by duplicating the code and replacing `0` with `1`. Note that you *cannot* replace `uint32_t` by `uint16_t`, as it would not work for the slowest frequencies.

**Edit**: Now we may ask the question whether it is possible to use some timers to make all this more accurate. The answer is yes, you could achieve maximum accuracy by using four 16-bit timers:

* You could use the input capture function of a 16-bit timer, with the prescaler set to 8, to measure the transitions of one of your inputs with a resolution of 0.5 µs.
* You could use a 16-bit timer in CTC mode, with the prescaler set to 256, to toggle one of your outputs at the desired frequency, with a 16 µs resolution.

For reference, `micros()` has a resolution of 4 µs. The 16 µs resolution of the timer-generated output seems poor in comparison, but the timer has the advantage of having zero jitter.

Now, for doing that that, you would need an Arduino Mega 2560. The Uno has only one 16-bit timer, so it could help with only one of your two channels.

There is still something you can do with a single 16-bit timer. Set it to normal counting mode, with the prescaler at 8, and use it instead of `micros()` for timing your inputs: in `setup()`

```
// Configure Timer 1.
TCCR1A = 0;          // normal counting mode
TCCR1B = _BV(CS11);  // clock at F_CPU/8

```

and in the interrupt handler, you replace `uint32_t now = micros();` by

```
uint16_t now = TCNT1;

```

And now you have `input_0_high_time` (which should also be `uint16_t`) in units of 0.5 µs.
> 0 votes

# Answer
Your approach is generally sound.

Depending on the square waves you are generating, one timer can generate two pulse train with independent duty cycles but dependent phases.

That leaves two times for measuring the duty cycles of the input pulse train.

But replicating the input pulse trains makes zero practical sense.
> 0 votes

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


# Question
Title: Is there a way to power off external devices during deep sleep
I am looking to work with deep sleeping, particularly with the ESP8266 but this question applies to most all micros. I am interested in running the device off of battery power for as long as possible. My solution would be something like a weather station where you know you only want to take a measurement every x minutes. So, I would like to sleep as much as possible in between measurements to extend battery life as much as possible. However, sleeping the microcontroller is one thing. How about when you have some sensors that piggyback off of the battery too. No need for those to be powered while the micro is sleeping and not taking a measurement.

Similar to this, I was thinking about reading the battery level. There are plenty of examples on how to do this online using a voltage divider (if necessary) and running the battery into analog input. This also draws from the battery while sleeping.

So, is there a way I can run all of these external sensors/devices through a transistor or something with low power draw when off and turn it all one when the device wakes up from sleep?

Thanks!

# Answer
> 1 votes
I made a temperature and humidity sensor which runs off 3 x AA batteries. It lasts a couple of years without changing the batteries, and writes to an SD card.

The power-control part of the circuit is here:

The general idea is that Q1 is used to turn on/off a "switched 5V" rail (5V\_SW) to which are attached most of the peripherals. This is done in conjunction with power-down sleep mode on the processor. A watchdog timer wakes the processor every 8 seconds to check to see if it is time to take another reading.

---

The full schematic is:

---

I think I've changed the batteries once since making it in 2013.

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


title: Getting BPM from the given code

text:
# Question
Title: Getting BPM from the given code
I have found code that can blink an LED on Arduino according to Heart Beat. I am using AD8232 as a sensor for Heart Rate.

Code for it is:

```
//  Variables
int PulseSensorPurplePin = 0; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED13 = 13; // The on-board Arduino LED
int Signal; // holds the incoming raw data. Signal value can range from 0-1024
int Threshold = 550; // Determine which Signal to "count as a beat", and which to ingore.

void setup() {
  pinMode(LED13, OUTPUT); // pin that will blink to your heartbeat
  Serial.begin(9600); // Sets up Serial Communication at certain speed.
}

void loop() {
  Signal = analogRead(PulseSensorPurplePin); // Read the PulseSensor's value.
  // Assign this value to the "Signal" variable.
  Serial.println(Signal); // Send the Signal value to Serial Plotter.
  if(Signal > Threshold) {
    // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
    digitalWrite(LED13, HIGH);
  } else {
    digitalWrite(LED13, LOW); //  Else, the signal must be below "550", so "turn-off" this LED.
  }
  delay(10);
}

```

My question is: How can I get BPM?

Edited below:

Is this code for BPM correct?

```
int x = 0;
int LastTime = 0;
bool BPMTiming = false;
bool BeatComplete = false;
int BPM = 0;
#define UpperThreshold 518
#define LowerThreshold 490
int LED13 = 44; // The on-board Arduino LED
int Signal; // holds the incoming raw data. Signal value can range from 0-1024

void setup() {
  pinMode(LED13, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int value = analogRead(0);
  if (value > UpperThreshold) {
    if (BeatComplete) {
      BPM = millis() - LastTime;
      BPM = int(60 / (float(BPM) / 1000));
      BPMTiming = false;
      BeatComplete = false;
    }
    if (BPMTiming == false) {
      LastTime = millis();
      BPMTiming = true;
    }
  }
  if ((value < LowerThreshold) & (BPMTiming))
    BeatComplete = true;
    // display bpm
  Serial.print(BPM);
  Serial.println(" BPM");
  x++;
  Signal = analogRead(0); // Read the PulseSensor's value.
  // Assign this value to the "Signal" variable.
  if (Signal > UpperThreshold) {
    // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
    digitalWrite(LED13, HIGH);
  } else {
    digitalWrite(LED13, LOW); //  Else, the signal must be below "550", so "turn-off" this LED.
  }
}

```

# Answer
> 2 votes
If you know the interval between heart beats, you can calculate the frequency using the formula: frequency = 1 / time. Now if you take the frequency and multiply it by 60, you should get BPM.

I don't have one of the sensors you are using so I connected a potentiometer to pin A0 to test this code.

```
    int UpperThreshold = 518;
    int LowerThreshold = 490;
    int reading = 0;
    float BPM = 0.0;
    bool IgnoreReading = false;
    bool FirstPulseDetected = false;
    unsigned long FirstPulseTime = 0;
    unsigned long SecondPulseTime = 0;
    unsigned long PulseInterval = 0;

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

    void loop(){

      reading = analogRead(0);

      // Heart beat leading edge detected.
      if(reading > UpperThreshold && IgnoreReading == false){
        if(FirstPulseDetected == false){
          FirstPulseTime = millis();
          FirstPulseDetected = true;
        }
        else{
          SecondPulseTime = millis();
          PulseInterval = SecondPulseTime - FirstPulseTime;
          FirstPulseTime = SecondPulseTime;
        }
        IgnoreReading = true;
      }

      // Heart beat trailing edge detected.
      if(reading < LowerThreshold){
        IgnoreReading = false;
      }

      BPM = (1.0/PulseInterval) * 60.0 * 1000;

      Serial.print(reading);
      Serial.print("\t");
      Serial.print(PulseInterval);
      Serial.print("\t");
      Serial.print(BPM);
      Serial.println(" BPM");
      Serial.flush();

      // Please don't use delay() - this is just for testing purposes.
      delay(50);
    }

```

Updated answer in response to your comments below:

The sketch is reading the data and sending the data to the serial monitor every 50ms because of the delay(50). What if we changed that to 1000 ms? The serial monitor would update once per second which would be more "human readable". The problem with that idea is for heart rates faster than 60 BPM, the reading would be inaccurate. I don't have a sensor to test with but I'm guessing a 1 second delay would make the code inoperable.

Before we add more complexity to this sketch we really should get rid of that delay. It would be nice to have one "timer" that we could use to update the BPM calculation and a second "timer" to update the serial monitor every second, or half second, or what ever you want it to be.

We can do that without any libraries using millis(). Here is an updated sketch using millis() for timers. This sketch has the blinking of the on board LED added to it. I'm using an Uno so you'll have to change LED\_BUILTIN to what ever pin number you are using.

```
int UpperThreshold = 518;
int LowerThreshold = 490;
int reading = 0;
float BPM = 0.0;
bool IgnoreReading = false;
bool FirstPulseDetected = false;
unsigned long FirstPulseTime = 0;
unsigned long SecondPulseTime = 0;
unsigned long PulseInterval = 0;
const unsigned long delayTime = 10;
const unsigned long delayTime2 = 1000;
const unsigned long baudRate = 9600;
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;

void setup(){
  Serial.begin(baudRate);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop(){

  // Get current time
  unsigned long currentMillis = millis();

  // First event
  if(myTimer1(delayTime, currentMillis) == 1){

    reading = analogRead(0);

    // Heart beat leading edge detected.
    if(reading > UpperThreshold && IgnoreReading == false){
      if(FirstPulseDetected == false){
        FirstPulseTime = millis();
        FirstPulseDetected = true;
      }
      else{
        SecondPulseTime = millis();
        PulseInterval = SecondPulseTime - FirstPulseTime;
        FirstPulseTime = SecondPulseTime;
      }
      IgnoreReading = true;
      digitalWrite(LED_BUILTIN, HIGH);
    }

    // Heart beat trailing edge detected.
    if(reading < LowerThreshold && IgnoreReading == true){
      IgnoreReading = false;
      digitalWrite(LED_BUILTIN, LOW);
    }

    // Calculate Beats Per Minute.
    BPM = (1.0/PulseInterval) * 60.0 * 1000;
  }

  // Second event
  if(myTimer2(delayTime2, currentMillis) == 1){
    Serial.print(reading);
    Serial.print("\t");
    Serial.print(PulseInterval);
    Serial.print("\t");
    Serial.print(BPM);
    Serial.println(" BPM");
    Serial.flush();
  }
}

// First event timer
int myTimer1(long delayTime, long currentMillis){
  if(currentMillis - previousMillis >= delayTime){previousMillis = currentMillis;return 1;}
  else{return 0;}
}

// Second event timer
int myTimer2(long delayTime2, long currentMillis){
  if(currentMillis - previousMillis2 >= delayTime2){previousMillis2 = currentMillis;return 1;}
  else{return 0;}
}

```

The code compile size with delay is 4,732 vs the millis timers at 4,682 (with the LED code removed). Two timers for less than the price of one delay :)

The LED will remain on for the duration of the heart beat reading above the LowerThreshold. If you want to have it on longer or decide how long it should be on for, I won't write the code for you but I will give you a hint. You can copy myTimer1() again and make a third timer.

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


# Question
Title: Sharing a Digital Pin / What to do when two components need a specific Digital Pin?
I am new to the world of Arduino and picked up an Uno R3. I have run into a situation where I have two components that specifically need digital pin 11, 12, 13 as specified by the libraries used to interact with them.

Each component also uses other pins that were able to be specified as different with the libraries but for those 3 the libraries say I cannot change them. What do you do in a situation like this? Is it somehow possible for two components to use the same pins? Any help is appreciated.

The two libraries I am trying to use are https://github.com/nRF24/RF24 (Wifi Receiver & Transmitter using component nrf24l01+) and https://github.com/steigeia/RFID\_UNID\_LOGGER/blob/master/libraries/AddicoreRFID/AddicoreRFID.h (RFID Reader/Writer using component RC522).

# Answer
> 1 votes
It seems probable that both libraries use SPI which connects to the SPI hardware on the chip via those pins. See How do you use SPI on an Arduino?

You haven't said what libraries, nor what hardware, but you possibly may be able to share those pins between the two devices. They would both need *separate* slave select pins. Often D10 (digital pin 10) is used as a default for slave select.

Another possible solution is to use "bit-banged" SPI for one device. I have a page on my forum about SPI which includes a bit-banged software implementation.

The library is at https://github.com/nickgammon/bitBangedSPI and is quite short.

---
Tags: arduino-uno
---


title: Trying to get my MPU chip to work

text:
# Question
Title: Trying to get my MPU chip to work
I'm new to Arduino and I'm trying to get my MPU 6050 chip to work. The simple code runs fine but when I use the downloaded example I get the following:

Arduino: 1.6.5 (Windows 7), Board: "Arduino/Genuino Uno"

```
Build options changed, rebuilding all
....

g.cpp.o

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-gcc -w -Os -Wl,--gc-sections -mmcu=atmega328p -o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp/MPU6050_DMP6.cpp.elf C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050_DMP6.cpp.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\Wire\Wire.cpp.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\Wire\utility\twi.c.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp/core.a -LC:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp -lm

C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setRate(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:133: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setExternalFrameSync(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:175: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDLPFMode(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:218: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setFullScaleGyroRange(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:253: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setFullScaleAccelRange(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:387: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMotionDetectionThreshold(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:531: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMotionDetectionDuration(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:561: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZeroMotionDetectionThreshold(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:601: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZeroMotionDetectionDuration(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:632: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setSlaveAddress(unsigned char, unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:972: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o:C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1558: more undefined references to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)' follow
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getIntStatus()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1687: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1687: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1687: undefined reference to `I2Cdev::readByte(unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setFIFOEnabled(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2351: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setI2CMasterModeEnabled(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2375: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::resetFIFO()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2391: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::resetI2CMaster()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2400: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::reset()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2426: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o:C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2450: more undefined references to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)' follow
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setClockSource(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2543: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getFIFOCount()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2708: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2708: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2708: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getFIFOBytes(unsigned char*, unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2744: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2744: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2744: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getDeviceID()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2764: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2764: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2764: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getOTPBankValid()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2785: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2785: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2785: undefined reference to `I2Cdev::readBit(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setOTPBankValid(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2789: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getXGyroOffsetTC()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2792: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2792: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2792: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setXGyroOffsetTC(signed char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2796: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getYGyroOffsetTC()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2802: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2802: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2802: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setYGyroOffsetTC(signed char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2806: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getZGyroOffsetTC()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2812: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2812: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2812: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZGyroOffsetTC(signed char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2816: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZAccelOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2876: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setXGyroOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2886: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setYGyroOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2896: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZGyroOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2906: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDMPEnabled(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2971: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::resetDMP()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2974: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMemoryBank(unsigned char, bool, bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2983: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMemoryStartAddress(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2989: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::readMemoryByte()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2995: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2995: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2995: undefined reference to `I2Cdev::readByte(unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::readMemoryBlock(unsigned char*, unsigned int, unsigned char, unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3016: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3016: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3016: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::writeMemoryBlock(unsigned char const*, unsigned int, unsigned char, unsigned char, bool, bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3060: undefined reference to `I2Cdev::writeBytes(unsigned char, unsigned char, unsigned char, unsigned char*)'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3066: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3066: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3066: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::writeDMPConfigurationSet(unsigned char const*, unsigned int, bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3170: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDMPConfig1(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3198: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDMPConfig2(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3208: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
collect2.exe: error: ld returned 1 exit status
Error compiling.

```

Help would be most appreciated

Thanks!

# Answer
> 1 votes
You seem to be missing the I2C header. If you are using the Arduino IDE, beware that it has its own whacky idea of where headers should be. Try adding the #include to the .ino file.

# Answer
> 0 votes
Get i2cdevlib from this linkhttp://github.com/jrowberg/i2cdevlib or just git clone if your linux user. then go to i2cdevlib--\> arduino folder.There have a folder name with I2Cdev ,just copy that folder in to your library folder in your workspace and then restart the IDE .It will compile now

---
Tags: arduino-uno, c++, mpu6050
---


title: Problem uploading to Arduino Uno

text:
# Question
Title: Problem uploading to Arduino Uno
The problem occurred while testing a ping program with the ethercard examples from github.

Now no program will upload. It will say uploading.... and gets stuck there. The error message below appears:

```
Arduino: 1.6.7 (Windows 7), Board: "Arduino/Genuino Uno"

WARNING: Category '' in library UIPEthernet is not valid. Setting to 'Uncategorized'

Sketch uses 1,030 bytes (3%) of program storage space. Maximum is 32,256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xdf
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xdf
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

```

# Answer
I'm having the same issue on my Macbook Pro. It happens randomly. The only solution i found is disconnecting the USB cable from the PC wait for a few mins and reconnect it again (possibly using another USB port). It worked for me!
> 1 votes

# Answer
When you get this error, they have several things to check :

* Is my board reconised by Windows ?
* Is my board model is the right one ?
* Is the serial port is the right one ?
* Is my cable damaged ?

Generally the upload problem is easy to fix.

If your board is a custom one

* bootload problem
* crystal problem.
* reset not triggered properly ? (try to push it when arduino ide say "uploading sketch")
> 1 votes

# Answer
Disconnect everything to Arduino, Plug in your Arduino to your computer - check for the Serial port, Check for your Arduino Model, select programmer as USBasp, open up BLink sketch from Examples and HIT upload.

if you don't see your Arduino in Tools\>Port then it should be the problem of USB cable, Computer USB port or "DRIVERS"
> 1 votes

# Answer
1. Remove the ethercard, return to the basic board.
2. Disconnect the Arduino from the host.
3. Reboot the host computer.
4. Reconnect the Arduino.
5. Upload the Blink example.

This should sort things out, well it did when it happened to me.
> 0 votes

# Answer
If you have the Arduino Uno with removable chip then try to remove the IC. Then plug it again and check the power on the IC with a multimeter on pin 7 (+ positive) and pin 8 (- negative). If you are getting 5V there then you need to try to upload a simple blink sketch. If you are not getting the appropriate voltage then you can try to use a different wire to upload the sketch.
> -1 votes

---
Tags: uploading
---


title: How to compare two string?

text:
# Question
Title: How to compare two string?
I meet a terrible problem. I can't compare two string!

My job is simple, every 1ms use `SoftwareSerial read_card(2, 3);`to check if i read a id card.And don't read a card twice.Here are my code:

```
bool CardReader::check()
{
    String str= read_card.readString();
    if (str.length() == 0 ) return false;
    //Log("card:%s", str);
    Serial.println("card_id");
    Serial.println(str);
    Serial.println(card);
    Serial.print("cmp:"); Serial.println(str == card);
    if (str.length() == card.length())
    {
        uchar *p1 = (uchar*)str.c_str(), *p2 = (uchar*)str.c_str();
        for (int i = 0; i < card.length(); i++)
            if (p1[i] != p2[i])
                break;
        return false;
    }
    card = str;
    return true;
}

```

Let's see output:

```
card_id
 Rq
 僐R
cmp:1

```

The hex are:

```
00 01 52 71 02
00 83 52 52 00

```

Why the two string is equal?

Bugs are fixed.If string begin with '\0',`==` can't work and `=` can't work either.

```
bool CardReader::check()
{
    String str = read_card.readString();
    if (str.length() == 0) return false;
    if (str.length() == card.length())
    {
        uchar *p1 = (uchar*)str.c_str(), *p2 = (uchar*)card.c_str();
        for (int i=0; i < card.length(); i++)
        {
            Log("%d:%d", p1[i],p2[i]);
            if (p1[i] != p2[i])
                goto find_card;
        }
        return false;
    }
find_card:
    for(int i=0;i<5;i++)
        card[i]=str[i];
    return true;
}

```

# Answer
Because both strings are empty. In fact, calling the method c\_str() will give a an array, which has at its first position (\[0\]) the null terminator (0x00 or '\0'). What follows the 0x00, is just rubbish.

In fact, check the card length, it will be 0.

(btw, there are some bugs in the code too. It always return false if the string have the same length, and it will always return true otherwise. EDIT: following the Nick Gammon's answer I also noticed that you get the pointer of the same string :). I corrected also this).

I think the code should be rewritten to:

```
if (str.length() == card.length())
{
    uchar *p1 = (uchar*)str.c_str(), *p2 = (uchar*)card.c_str();
    for (int i = 0; i < card.length(); i++)
        if (p1[i] != p2[i])
            return false;
}
else
    return false;
return true;

```

EDIT:

I add there what I wrote in the comments, for future reference, and explained in details. The problem lies on the String class, which on one hand, it allows adding '\0' characters, through the method concat(char\*), but on the other, it uses the strcmp (and other C standard functions) to perform compare between strings. This leads to unpredictable results. Maybe this is a bug in the String class.

In particular, SoftwareSerial extends Stream. Stream::readString() (which is used in the program to get str), is implemented as follows:

```
String Stream::readString()
{
  String ret;
  int c = timedRead();
  while (c >= 0)
  {
    ret += (char)c;
    c = timedRead();
  }
  return ret;
}

```

The line `ret += (char)c;` uses operator +=, which is implemented in WString.h as:

```
String & operator += (char c)           {concat(c); return (*this);}

```

**Note that readString() also allows adding any non negative value of c, including 0, i.e. '\0' - see while (c \>= 0) in its code above**

In turn, concat(char c) is implemented in WString.cpp as:

```
unsigned char String::concat(char c)
{
    char buf[2];
    buf[0] = c;
    buf[1] = 0;
    return concat(buf, 1);
}

```

And concat(const char \*cstr, unsigned int length) is implemented as:

```
unsigned char String::concat(const char *cstr, unsigned int length)
{
    unsigned int newlen = len + length;
    if (!cstr) return 0;
    if (length == 0) return 1;
    if (!reserve(newlen)) return 0;
    strcpy(buffer + len, cstr);
    len = newlen;
    return 1;
}

```

In the above method, length (instead of strlen) is used to determine the length of the string to add, and the new length is calculated using it:

```
newlen = len + length;

```

**That's the bug**: you can add a '\0' char to the string, and this will also result in an increased length of the string. They should have checked if length \<= strlen(cstr), before performing this concat operation.

Now, if you call the method String::equals or use the operator == (it is the same, as it is defined in WString.h as `unsigned char operator == (const String &rhs) const {return equals(rhs);}`), you call this code:

```
unsigned char String::equals(const String &s2) const
{
    return (len == s2.len && compareTo(s2) == 0);
}

```

Which, in turn, calls:

```
int String::compareTo(const String &s) const
{
    if (!buffer || !s.buffer) {
        if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
        if (buffer && len > 0) return *(unsigned char *)buffer;
        return 0;
    }
    return strcmp(buffer, s.buffer);
}

```

And strcmp ends its compare operation if it first encounters a null operator (or when a compare mismatch occurs).

Therefore in your case, readString() added a null character to the "ret" String at first, and then some other characters. This created a String which begins with '\0'. Such string is equal to any other string beginning with a '\0', regardless what follows '\0'. But if you call length(), you'll get "len" (which String::concat() does not correctly calculate, and it will be non 0), as you can find in WString.h:

```
inline unsigned int length(void) const {return len;}

```

Disclaimer: future versions of WString.h and WString.cpp could have fixed this bug.
> 0 votes

# Answer
> Why the two string is equal?

```
        uchar *p1 = (uchar*)str.c_str(), *p2 = (uchar*)str.c_str();

```

Both p1 and p2 point to the same string so of course they will always compare equal.

---

Do you mean:

```
if (str == card)
   // do something

```
> 1 votes

# Answer
Try strcmp()

See if it works.
> 0 votes

---
Tags: programming, string
---


title: Problem with 16x2 LCD using Arduino

text:
# Question
Title: Problem with 16x2 LCD using Arduino
I've connected the circuit as shown in https://www.arduino.cc/en/Tutorial/HelloWorld?from=Tutorial.LiquidCrystal and I ran the program, but I can't fix this problem:

the LCD seems not to respond correctly: the first row is black and for what concerns the elements of the second, they all have three top lines of pixel high and the others low..

I checked over and over if I made some mistake connecting wires but I haven't found any error..

Is the LCD broken according to you? How can I fix?

Here the photos of the circuit: https://drive.google.com/open?id=0B2h2zzEgtaqydElrRDVUNGVuWDA

# Answer
> 1 votes
I looked the images you have on Google Drive. On the image called IMG\_20170822\_233722.jpg, I see you are using a 50k ohm potentiometer to control the display contrast. Normally you would use a 10k ohm potentiometer. Using the 50k will make the adjustment very sensitive and hard to adjust. If you are careful and adjust it slowly, it might work for you.

The other image, IMG\_20170822\_234242.jpg, clearly shows "poor solder joint" connections on the display. D4 - D6 (especially D5 to D6) look like they could be "shorted" together. I think you could fix them by using Desoldering braid or if you don't have any, you could heat up each connection with your soldering iron then quickly "flick" the display to remove the solder. After you have removed the excess solder from each connection, I strongly recommend applying soldering paste to the connections next. The soldering paste really helps the solder to flow into the connection. Now try re-soldering each connection. I'm not sure what kind of solder or iron you are using but I can tell you what works for me. 25 watt pencil tip soldering iron with 22 gauge / 0.71mm rosin core solder.

I can't tell for sure from the pictures if any of the display pins are shorted together and I don't know if shorting them together will damage the display, Arduino or both.

# Answer
> 0 votes
Black first row suggests that the LCD is incorrectly initiated. That's often caused by wrong code or wrong hardware / connection.

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


title: How to know physical address of XBee?

text:
# Question
Title: How to know physical address of XBee?
I have a system with a server (a personal computer with an XBee Dongle plugged in, running a Java program) and some Boe-Bots with XBees attached and Arduino programs. I know how to get the Boe-Bots to send a message to the server. I want the server to obtain the Boe-Bot's XBee's physical address so that it can send a message to that particular Boe-Bot with the Java method
com.digi.xbee.api.XBeeDevice.sendData(RemoteXBeeDevice remoteXBeeDevice, byte\[\] data) knowing what argument to put for remoteXBeeDevice.

I can think of two ways this might be possible.

1) There might be a method in the Arduino XBee library to obtain an XBee's physical address. Then the Boe-Bot can get its own address and send it in a message to the server. I have not found such a method.

2) On the server side, there might be a method in the Java XBee library that allows it to automatically determine the physical address of a client that is communicating with the server. I thought that XBeeMessage.getDevice() was such a method, but it returned a RemoteXBeeDevice with an XBee64BitAddress of FFFFFF... which is not the proper address of the Boe-Bot's XBees.

Does anyone know the correct Arduino method for option 1 or the correct Java method for option 2?

Edit: XBee S1

# Answer
> 1 votes
First you can check the signal received from the xbee connected with the server by using coolterm or arduino serial monitor. This is to ensure there are connections between the two xbees.

Then, you will receive some funny characters which is normal, you need to change these characters into hexadecimal form which is more preferable to use coolterm as it has the ability to do so.

Laslty, the characters received will be about 21 characters long. It starts with 7E as a starting character. That is what I received when using XBee S2. These characters then can be translated into other form.

I would suggest a book entitled Wireless Sensor Network by Robert Faludi to understand more.

---
Tags: communication, xbee
---


# Question
Title: How is interaction with CDC device with no interface endpoints working?
I'm working on uploading to Digispark board. It uses micronucleus bootloader and i can see uploader code. I've modified it a bit to see interfaces and endpoints count:

```
    nucleus->device = usb_open(dev);

    // added by me - start
    int interfaces, endpoints, j;
    struct usb_interface_descriptor *interface = NULL;

    interfaces = dev->config->bNumInterfaces;
    fprintf(stderr, "Found interfaces: %i\n", interfaces);

    interface = &(dev->config->interface[0].altsetting[0]);
    fprintf(stderr, "Endpoints: %i\n", interface->bNumEndpoints);
    // added by me - end

    // get nucleus info
    unsigned char buffer[4];
    int res = usb_control_msg(nucleus->device, USB_ENDPOINT_IN| USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, 0, (char *)buffer, 4, MICRONUCLEUS_USB_TIMEOUT);

```

I wonder how it's working because interface #0 has no endpoints:

```
$./micronucleus --type intel-hex /tmp/Start.ino.hex
> Please plug in the device ...
> Press CTRL+C to terminate the program.
Found interfaces: 1
Endpoints: 0
> Device is found!
connecting: 40% complete
> Device has firmware version 1.6
> Available space for user applications: 6012 bytes
> Suggested sleep time between sending pages: 8ms
> Whole page count: 94  page size: 64
> Erase function sleep duration: 752ms
parsing: 60% complete
> Erasing the memory ...
erasing: 80% complete
> Starting to upload ...
writing: 100% complete
>> Micronucleus done. Thank you!

```

Usually i expect interface to have 2 endpoints (in & out from usb.h):

```
#define USB_ENDPOINT_IN         0x80
#define USB_ENDPOINT_OUT        0x00

```

Can anyone explain me how `usb_control_msg(nucleus->device, USB_ENDPOINT_IN| USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, 0, (char *)buffer, 4, MICRONUCLEUS_USB_TIMEOUT);` is working without endpoint?

# Answer
Micronucleus uses control transfers to upload code (it's not a CDC device). You don't need an endpoint for control transfers - they use the implicit endpoint 0 that is always present whether you define one or not.

You only need to define endpoints for interfaces that want to communicate using bulk, interrupt or isochronous transfers.

```
Bus 003 Device 073: ID 16d0:0753 MCS Digistump DigiSpark
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x16d0 MCS
  idProduct          0x0753 Digistump DigiSpark
  bcdDevice            1.02
  iManufacturer           0
  iProduct                0
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           18
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         0 (Defined at Interface level)
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
Device Status:     0x18c0
  (Bus Powered)
  Debug Mode

```
> 2 votes

---
Tags: bootloader, uploading, digispark
---


title: Arduino and Optoisolators

text:
# Question
Title: Arduino and Optoisolators
I am looking for an efficient (and safe) way to use the Arduino to switch a higher voltage device off and on. The first option would be a relay, but they are fairly bulky. I was wondering if I should use an Optoisolator instead ?

Here is a link to the Data sheet for the Optoisolator I am using..

http://www.everlight.com/file/productfile/el817.pdf I think (if I am reading it correctly) it expects an input voltage of 1V at about 20mA ?

However, I think it may be more involved than I originally thought. Here is a sort of simulation of what I am trying to achieve. http://tinyurl.com/y9xd7lzb

As you can maybe tell, I am using a voltage divider to reduce the output from the arduino (from 5V to 1V). My concerns are ..

1. Is this the best approach ?
2. Is it efficient ?
3. are there any problems I should be aware of ? Precautions I need to take ?
4. Is the voltage divider a good approach to feed the input to the Optoisolator ?

Also, efficiency is an issue as the Arduino (probably a Nano) will be running off batteries.

The target device is a 20V DC motor. I am a novice when it comes to electronics, so I would be grateful of any help or advice you can give.

Many thanks..

Dave.

# Answer
> 2 votes
> Is this the best approach ?

Not really, no.

> Is it efficient ?

No, far from it.

> are there any problems I should be aware of ? Precautions I need to take ?

You don't want a voltage divider to power an opto-isolator. An opto-isolator won't be powerful enough to cope with the motor current. You need flyback protection.

> Is the voltage divider a good approach to feed the input to the Optoisolator ?

No, definitely not.

Unless you require galvanic isolation all you need is a simple NPN transistor or N-channel MOSFET circuit:

simulate this circuit – Schematic created using CircuitLab

# Answer
> 0 votes
your optocoupler's 2ndary side isn't powerful enough to switch a load.

use the 2ndary side to switch a switcher, instead.

---
Tags: relay, opto-isolator
---


title: Specifying port in Ciao.write

text:
# Question
Title: Specifying port in Ciao.write
As far as I know, Ciao uses port 80 as the default and I haven't found a way of changing the port it attempts to connect to.

I tried using `"192.168.0.23:8080"` but the `Ciao.write()` seems to timeout after a while. Is there a way to specify the port to use?

P.S I'm using an Arduino Uno WiFi DevEd

# Answer
You can't. The factory firmware of Uno Wifi is discontinued.

Uno WiFi and WiFi Link doc
> 1 votes

---
Tags: arduino-uno, wifi, http
---


# Question
Title: Yet another display 16x2 not working with arduino
I found hundreds of questions about display not working with arduino. However, no matter how trivial this looks like I am having the same problem I cannot understand by reading the other posts.

I have an Arduino micro connected to a display from the adafruit kit

RGB LCD SHIELD KIT W/ 16X2 CHARACTER DISPLAY

I haven't been able to understand whether positive or negative, but I think from the picture is RGB positive.

I have connected everything as shown in the diagram in this page:

LCD "Hello World!"

Obviously changing the pins as I have

```
RS at 8
E at 7
d4 = 12
d5 = 11
d6 = 10
d7 = 9;

```

The potentiometer changes the contrast, if I saturate it I can see the black boxes.

In the code put this as

```
const int rs = 8, en = 7, d4 = 12, d5 = 11, d6 = 10, d7 = 9;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

```

I checked with the multimeter whether the soldering is good and it carries the signal at the end of the wires.

and the rest as the example in the link,

This is my mess (please ignore the other arduino and the thermocople which is not connected, the other orange wire goes to GND of the Arduino).

Any ideas that might help?

# Answer
> 1 votes
1. disconnect the E line, power up the system and adjust the contrast so you see 1 black bar on the first line;
2. reconnect the E line and see if your code is working.
3. go from there.

---
Tags: lcd, arduino-micro, display
---