title: Make OTA work with Arduino Uno Wifi

text:
# Question
Title: Make OTA work with Arduino Uno Wifi
I just bought a Arduino Uni Wifi Rev. 2, with the itention of doing over the air uploads to the devices.

By reading the official Gettings started with the Arduino Uno Wifi guide, I thought the process was just to power the devices, connect to the SSID, then browse to it's IP and set it up.

But it seems like this is not the case, and that others have made this same mistake. This Arduino device doesn't create network by default, we have to upload a sketch that connects to our wifi.

So I have two questions.

1. **What Arduino board are they referencing in the guide linked above, that we can just connect to out of the box?**
2. **How can I get OTA support for my particular board?**

# Answer
> What Arduino board are they referencing in the guide linked above, that we can just connect to out of the box?

The first Uno WiFi was made in 2016 by arduino.org. It is retired and not available in stores.

> How can I get OTA support for my particular board?

The OTA support for Uno WiFi Rev. 2 is ready or almost ready, but the required additions are not merged in GitHub firmware and library repository even if they wait some months now. It looks like Arduino focuses on something else.
> 3 votes

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


# Question
Title: How to check if two device has the same address on I2C?
I start a new project with Arduino UNO and MCP23017 expander. Using this, I can connect 8 chips on Arduino, by selecting different addresses ( from 0x20 to 0x27 ). My question is, if I connect two MCP23017 chips with the same address, there is any way to see somehow that I have two chips with the same address ? I am using a standard I2C scanner in Arduino code, but is nt return me if I have multiple chips with the same address, he see only one chip for example !

Can you please help me with some ideas to check how man chips are connected with the same address?

# Answer
It's my understanding that duplicate I2C addresses prevent the master from communicating from the slaved devices, so the answer is no.

Instead, connect the devices one at a time, run the I2C scanner, note the address for each, and take note of any duplicate addresses.
> 1 votes

# Answer
If both devices are the same, are configured the same, and respond the same, then it is impossible to tell if there is one, two, or four hundred.

However if there are differences between the two devices you will get corrupt data.

I2C is an open-drain protocol. For a device to send a 0 it pulls the data line low. For it to send a 1 it lets the pullup resistor pull the line high.

So if you have two devices and they both send a 1 you get a 1. If they both send a 0 you get a 0. But if one sends a 1 and the other sends a 0 then the 0 will "win" and you will see a 0.

Since most devices, when powered up, revert to some pre-defined default state, chances are you will always see multiple devices of the same type on a single address as just one device.

One possible way around it is to have some control signal that is unique to each device which will cause them to only respond one at a time. For example, you might choose to pull all the RESET pins of the slaves LOW and raise each one in turn to see what address the device is on. If you then see two that respond on the same address then you know you have a conflict and can report it as such.

Another possibility is to connect the address control pins to IO pins and communicate with all the slaves on the same address - but you only set one slave's address to the "live" address at a time. That also gives you the ability to have far more than just 8 slaves.
> 1 votes

---
Tags: i2c
---


# Question
Title: Atmega328p Uploads via ISP but not bootloader
I'm trying to upload a bootloader to my atmega328p on a custom pcb containing external oscillator at 16MHz. It is possible to upload program via ICSP pins using Arduino as ISP (Official Arduino Uno) but not possible to upload a bootloader. This pcb needs bootloader as it will be used via FT232RL interface.

I've tried to upload bootloader at 115200 baud rate but that did not read any device signature. Also exact definition of my IC is "ATMEGA328P-AU TQFP-32 8-bit 20MHz", if it helps.

P.S That exact definition says it is 20MHz but I suspect that's correct as I don't entirely trust that shop.

Thanks in advance

Upload log

```
Sketch uses 1626 bytes (5%) of program storage space. Maximum is 32256 bytes.
Global variables use 192 bytes (9%) of dynamic memory, leaving 1856 bytes for local variables. Maximum is 2048 bytes.
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -carduino -P/dev/cu.usbmodem14101 -b115200 -D -Uflash:w:/var/folders/9z/8cpdsm0518x0b85yx7n4y_0c0000gn/T/arduino_build_452635/sketch_dec06a.ino.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/Users/deniz/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbmodem14101
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
         Hardware Version: 3
         Firmware Version: 4.4
         Vtarget         : 0.3 V
         Varef           : 0.3 V
         Oscillator      : 28.800 kHz
         SCK period      : 3.3 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "/var/folders/9z/8cpdsm0518x0b85yx7n4y_0c0000gn/T/arduino_build_452635/sketch_dec06a.ino.hex"
avrdude: writing flash (1626 bytes):

Writing | ################################################## | 100% 0.27s

avrdude: 1626 bytes of flash written
avrdude: verifying flash memory against /var/folders/9z/8cpdsm0518x0b85yx7n4y_0c0000gn/T/arduino_build_452635/sketch_dec06a.ino.hex:
avrdude: load data flash data from input file /var/folders/9z/8cpdsm0518x0b85yx7n4y_0c0000gn/T/arduino_build_452635/sketch_dec06a.ino.hex:
avrdude: input file /var/folders/9z/8cpdsm0518x0b85yx7n4y_0c0000gn/T/arduino_build_452635/sketch_dec06a.ino.hex contains 1626 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.21s

avrdude: verifying ...
avrdude: 1626 bytes of flash verified

avrdude done.  Thank you.

```

Bootloader log (P.S. all sync attempts happen at the same time)

```
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/cu.usbmodem14101 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/Users/deniz/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbmodem14101
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x60
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x66
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x78
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x1e
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x06
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x7e
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xe6
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x80
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x98
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x80

avrdude done.  Thank you.

```

# Answer
The first issue might be in Upload log. There is mentioned `programmer = arduino` (in version before edit). That means you might be uploading code into the wrong Arduino. So there is no ArduinoISP sketch and it won't work (getsync() errors)

Check if the upload is working between two arduinos, that should opted out wrong wiring on the programmer side and so on.

And as it's self made board, there might be some issues with wiring, omitting bypass capacitors (as it turned out in chat discussion - it was the main issue)
> 0 votes

---
Tags: atmega328, bootloader, avr, avrdude, isp
---


# Question
Title: How to know my Arduino core version and its location on my Ubuntu laptop?
**Bakground:**

When compiling a demo project about e-paper, I got this problem

```
./GxEPD/src/GxIO/GxIO_SPI/GxIO_SPI.h:39:5: error: ‘SPISettings’ does not name a type
     SPISettings _spi_settings;
     ^

```

which on the Internet, people often say your Arduino core is not up-to-date and the one installed from

```
sudo apt install arduino-core

```

is ancient. And you have to install the latest version.

Regardless of whether this solves my original problem or not, I want to have the latest Arduino core on my laptop. From arduino.cc I grabbed a zipped file and ran `./install.sh` which did not provide enough results to know what it exactly did. Now, I am concerned that I have multiple installation in several places.

**Main question:**

When I run my make file and it is processed by `arduino-mk`, which version of `arduino-core` is it referred to and where is it located?

I am looking for a full proof method. I do not want to open somewhere from `/` directory accidentally. Because maybe this is not the `arduino-core` in use.

# Answer
The ancient version installed by apt lives in `/usr/share/arduino/hardware/arduino/cores/arduino`.

If you download and unpack a recent version, it will stay wherever you left it. For example, I have an Arduino core in `/home/edgar/Downloads/arduino-1.8.10/hardware/arduino/avr/cores/arduino`. The installation script doesn't really install those files. It does install some icons and desktop shortcuts, but neither the core nor the Arduino IDE. Instead, it assumes the downloaded package will stay wherever it was when you ran the script.

If you want a somewhat cleaner installation, I suggest you move the package to `/opt`, recursively chown it to root, and run the setup script there. The core will then be in `/opt/arduino-<version>/hardware/arduino/avr/cores/arduino`.
> 1 votes

---
Tags: arduino-uno, ubuntu, core-libraries, arduino-makefile
---


# Question
Title: PWM using timer3 for servo control won't generate any output
I'm making a program for a small robot arm controlled by four servos. Problem: I need for PWM outputs, timer1 has three so i need to use timer3 for the last one

The main program and the timer1 outputs work great, the robot arm is functional. My problem is in the initialization of the PWM's. The PWM for timer1 is set to phase-correct, 64 pre-scaling and using WGM1\[0-3\] to 1010 so that i can use ICR1 as the top value, leaving OCR1\[0-2\] for counting up so output is on OCR\[0-2\].

According to the ATMEGA 2560 data book I should be able to initialize an identical PWM with timer3 with just one output in just the same way, but it just won't give me any output at all on OC3A.

Any help is greatly appreciated! :)

PS this is for a class project, so no servo libraries, and no major changes to the program (the current code is already approved by my professor, also the due date is in 24 hours so i don't have the time. Yes I know that sounds like trouble, but the project is technically done, I'd just really really like to get a full range of motion on my little Plexiglas robot)

PWM.c:

```
// INITIALIZE PHASE CORRECT PWM ------------------------------------------------------------------------------
void initPWM()
{
    DDRB |= (1<<DDB7);      // Output pin 5 OC3A
    DDRB |= (1<<DDB5);      // Output pin 11 OC1A
    DDRB |= (1<<DDB6);      // Output pin 12 OC1B
    DDRB |= (1<<DDB7);      // Output pin 13 OC1C

    // Initialize TIMER1 for OC1A, OC1B, OC1C:
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1)|(1<<WGM11);     // Clear OCnA on compare match (non inverting mode), Phase correct ICRn top Mode
    TCCR1B |= (1<<WGM13)|(1<<CS11)|(1<<CS10);                     // Phase correct ICRn top Mode, Pre-scaling 64 for 50Hz signal
    // Initialize TIMER3 for OC3A
    TCCR3A |= (1<<COM3A1)|(1<<WGM31);                            // Clear OCnA on compare match (non inverting mode), Phase correct ICRn top Mode
    TCCR3B |= (1<<WGM33)|(1<<CS31)|(1<<CS30);                     // Phase correct ICRn top Mode, Pre-scaling 64 for 50Hz signal

    // TIMER1 Top and bottom value:
    ICR1 = 5000;
    TCNT1 = 0;
    // TIMER3 Top and bottom value:
    ICR3 = 5000;
    TCNT3 = 0;

    // Start PWM in OCR = 200 (mid value for servo)
    OCR3A = 200;
    OCR1A = 200;
    OCR1B = 200;
    OCR1C = 200;

}

```

# Answer
I can see nothing wrong in your program except this:

```
DDRB |= (1<<DDB7);      // Output pin 5 OC3A

```

This is setting pin PB7 as an output, whereas digital pin 5 (OC3A) is PE3.
> 1 votes

---
Tags: servo, pwm, c
---


# Question
Title: Use JYETech 2.4 Inch LCD Display Screen Module with Arduino?
I have this JYETech 2.4 Inch LCD Display Screen Module that I would like to use for a project I have in mind, however, I'm not sure how to wire it up with my Arudino Mega. Here is the datasheet for the display. I have also attached a picture of the display below. The display is meant to work with a DIY oscilloscope but according to the manufacturer and other forum posts, it can be used as a display with other projects as well.

Pictures of the display

# Answer
> 1 votes
That display is an ILI9341 based one. On the DSO138 it connects the data pins D0-D7 to PORTB of the STM32.

You need to connect those 8 pins to 8 pins on the Arduino, along with the RS (Register Select) and CS (Chip Select) pins. The RD pin can be connected to 3.3V and the WR pin to GND, since you only really want to write to the screen (if you do want to read from the screen then you will want to connect RD and WR to two IO pins as well). Reset can be connected to a GPIO or to 3.3V, depending on if you want to do a hard reset at any point or not.

LED-A can connect to 5V, and each of the LED-K\* pins should connect to ground through a resistor each. The size of the resistor will set the backlight brightness (try 100Ω to start with).

Then it's just a matter of finding a library that works with the ILI9341 in 8-bit parallel mode (u8glib maybe? I don't know, I never use Arduino to drive a TFT).

Note that since this is a 3.3V device you should really use a level shifter for all the digital signals.

---
Tags: arduino-mega, programming, lcd, pins, tft
---


# Question
Title: String generator not working as expected
I'm trying to build a random string, save it to EEPROM as int, then read it back and output it.
If I give it a predefined string then it works fine. But Something is wrong with the random string generator.

```
  String output;
  char letter;

  String mystr=""; //"ABCabc123..";
  String characters = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz";
  String numbers = "0123456789";
  String other = "<>!.,()?|=&%¤#";

  // add random characters to empty string
  for(int i=0 ; i < 12 ; i++){
    mystr += characters[random(0, characters.length())];
  }
  // add two numbers, one other and two more characters
  mystr += numbers[random(0, numbers.length())];
  mystr += numbers[random(0, numbers.length())];
  mystr += other[random(0, other.length())];
  mystr += characters[random(0, characters.length())];
  mystr += characters[random(0, characters.length())];

  // loop the string and place one character in each EEPROM address
  for(int i=0 ; i < mystr.length() ; i++)
  {
    EEPROM.writeInt( i,mystr[i] );
  }

  // read the string back from EEPROM
  for(int i=0 ; i < 17 ; i++){
    letter = EEPROM.readInt(i);
    output += letter;
  }

```

If I run the code output will be "H". Every time.
If I use the predefined string "ABCabc123.." then it works correct.

What am I doing wrong with building the mystr?

# Answer
> 1 votes
Your first mistake is to use `String`. Don't. Instead use a `char` array.

```
char mystr[18]; // Room for 17 characters plus the NULL terminating character

```

Your string constants should also be char arrays, not `String` variables. And better to put them in `PROGMEM`:

```
const char characters[] PROGMEM = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz";
const char numbers[] PROGMEM = "0123456789";
const char other[] PROGMEM = "<>!.,()?|=&%¤#";

```

Now filling your target array becomes:

```
for(int i=0 ; i < 12 ; i++){
  mystr[i] = pgm_read_byte_near(characters + random(0, 50));
}

mystr[12] = pgm_read_byte_near(numbers + random(0, 10));
mystr[13] = pgm_read_byte_near(numbers + random(0, 10));
mystr[14] = pgm_read_byte_near(other + random(0, 14));
mystr[15] = pgm_read_byte_near(characters + random(0, 50));
mystr[16] = pgm_read_byte_near(characters + random(0, 50));
mystr[17] = 0; // Don't forget the NULL...

```

Your second problem is the use of `EEPROM.writeInt` and `EEPROM.readInt`. Those are for writing integer values, not characters. Instead just use `EEPROM.read` and `EEPROM.write`:

```
for (int i = 0; i < 17; i++) {
    EEPROM.write(i, mystr[i]);
}

```

Then to read back:

```
for (int i = 0; i < 17; i++) {
    mystr[i] = EEPROM.read(i);
}
// And don't forget to terminate the string...
mystr[17] = 0;

```

---
Tags: string
---


title: Missing time when using timer

text:
# Question
Title: Missing time when using timer
I have set up Timer2 to count every tick at 16MHz, or 62.5ns per tick. Then I run the following code:

```
int t = 0;
    for (int i=0;i<64;i++){
  data[4*i] = TCNT2;
  data[4*i+1] = TCNT2;
  byte now = data[4*i+1];
  byte last = data[4*i];
  t += now > last? (long)(now-last) : 256 -(long)(last-now);
  data[4*i+2] = TCNT2;
  data[4*i+3] = TCNT2;
  }
}
for (int i=0;i<255;i++){
  Serial.println(data[i]-data[i+1]);
}

```

and I get the output: "4 4 4 11" (repeated) which makes sense, 4 clock cycles to read *TCNT2* and write it to the correct place in *data* and 11 cycles when also evaluating the loop condition. However, I can't understand when the variable *t* is updated. I have tried running with and without *t* and both give the same timings. From my (obviously lacking) understanding updating a variable is at minimum one instruction, so how can it do it under one clock cycle? Am I misunderstanding what one instruction is or does the *TCNT2* counter for the timer not update accurately here?

# Answer
Ops, I just realized it's the compiler working it's magic. I never used t, thus the compiler said "Wtf is this guy doing, this t is useless and I'll remove it!". When I used t I got sensible results.
> 1 votes

---
Tags: timers, time, speed
---


# Question
Title: Connect a hundred SIM800L's to Arduino (or any other board)
Is there a way to connect one hundred SIM800L's to Arduino? Essentially I want to be able to communicate with any of them that I want. If Arduino isn't capable of doing this, what do you suggest, so I could connect to and control 100 SIM cards?

Thanks for your help in advance!

R.

# Answer
> 1 votes
You left unclear, what your exact requirements are. So the answer will be as general as your question. The SIM800L uses the Serial interface (UART). So the point is to connect to 100 different serial interfaces.

If it is ok to talk to each SIM800L sequentially (only one at a time), you can use a series of multiplexers. A multiplexer chip connects one pin to one of multiple pins (called channels here). Depending on the used chip, the channel can be selected in different ways. The standard way is with simple digital input pins, that construct a binary number. So for 8 channels you need 3 input pins (`2^3`). Other ways are through communication interfaces like SPI or I2C.

Normally a multiplexer has only 8 channels, though you can also find once with more, but I don't think there are multiplexers with 100 channels. So you could next the multiplexers. If you put another multiplexer on every channel of the first multiplexer, you get `8*8 = 64` channels with 9 multiplexers in total. Add some more multiplexers on the next level and you will get to over 100 channels. Then you need 2 of these multiplexer trees to multiplex both serial lines (TX and RC). Since that are a lot of multiplexers and thus a lot of inputs to choose the correct channels, you could use multiplexers with SPI or I2C interface. The first would require 1 digital output pin of the Arduino per multiplexer as slave select pin, the latter would require either a multiplexer type, that can as many different I2C addresses as multiplexers in your system, or a bit more complex programming and also 1 pin per multiplexer to change the address of the chip to configure. How to use these multiplexers with Arduino depends on the used chip. You should refer to it's datasheet.

As you now see, connecting one single Arduino to 100 serial interfaces it a complex task. Depending on your actual requirements and goals in your "PoC project", it might be a better way to follow Majenkos advice and build it more modular with multiple Arduinos/microcontrollers.

---
Tags: arduino-uno
---


# Question
Title: Why does the reading on the ESP32 read max, when the reading on UNO read accurately?
I have a 'Capacitive Soil Moisture Sensor' hooked up to my Uno. Very simple code. AnalogRead(MoistureSensorPin); This will return a differing value that I can work with.

When applying the same code to an ESP32 with a similar set-up. It always returns '4095' which I understand is the maximum value an analog input can return. But I cannot understand why it does this.

Any help will be much appreciated.

# Answer
The ESP is a 3.3v device. If your Uno is a 5v device, its A/D converter can measure and report voltages from 0 to 4.9878v (5v minus 1 LSB). If the same signal is presented to the ESP, any value above 3.29919 volts (3.3v - 1 LSB) will read as 4095, i.e., out of range.

(If this isn't your issue, adding wiring diagrams of each system to your question will help us understand it better.)

Update:

> Perhaps a different ESP unit would be the ideal solution?

As far as I know, all of the ESP's are 3.3v devices. So the solutions I see are:

1. Power your sensor with 3.3v (is this an option?) so its output will be within the input range of the ESP's built-in A/D.
2. Scale the sensor output from it's 0-5v range to the 0-3.3v range the ESP can accept. Whether you can use a simple divider network or would need an op-amp may depend on the sensor, but if, as I suspect, it is a simple resistance device, a voltage divider should work.
3. Use an external 5v A/D converter. This will require a 5v power supply (which I presume you are using already, to power the sensor) and voltage level conversion between the A/D and input pin(s) of the ESP. The conversion could be a purchased level-converter board or a simple resistor-divider network.
> 1 votes

---
Tags: arduino-uno, sensors, analogread, esp32
---


title: Driving an enable pin low via arduino

text:
# Question
Title: Driving an enable pin low via arduino
I have the following V regulator, that has an enable pin that i'd like to control via an arduino: https://www.pololu.com/product/2582

I tried using a relay (ELEGOO Relay Module 4 Channel DC 5V with Optocoupler for Arduino) with the following pins:

## Relay pin1: 0v of 24v battery

## Relay pin2: enable pin of pololu v regulator

I then enabled the above relay via an arduino digital out pin.

However it seemed to have no effect, the regulator never shut off. If i manually join the two relay pins, pin1 and pin2 the regulator does shut off though .. A and B in picture.

Any ideas why the relay is not working via the arduino? or should it work? am i doing something wrong? I am not too familiar with pull up or pull downs..

I have since disconnected everything and put it away, i am just looking for theory help, confirmation it should wotk. I managed to get the relay working for leds at the time .. would the fact that current flows in the other direction for this pull down relay setup, be my issue and that i should swap around wires A and B?

(As a workaround i used a relay to switch on or enable the 24v Vin line out from the battery instead, that seemed to work okay..)

# Answer
> 1 votes
Unless you require galvanic isolation (and it's highly unlikely that you do) you don't need the relay.

The EN pin only needs to be above 1.3V to turn the unit on, or below 0.9V to turn it off. The voltage range is anything up to 30V.

Just connect the EN pin directly to an Arduino IO pin. Write a HIGH for on and a LOW for off. And of course connect the grounds together.

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


# Question
Title: Arduino Nano/Uno and js sketch compiling/uploading from browser
I need to compile generated source code in js runtime then upload it to my device.

### Compiling:

I have found arduino-cli

### Uploading:

There is only avrgirl but it doesn't work in browser. What should I do?

# Answer
> 1 votes
You can't, and that's a good thing. If the browser could let a Web site access your hardware, that would be a huge security breach. You may be able to bypass this security restriction if you can write an extension (plugin) for your browser.

---
Tags: arduino-uno, arduino-nano, compile, node.js
---


# Question
Title: Trying to control DC motor speed with PID
i'm trying to control a DC motor with PID. I have already made a code where i control the motor with an ultrasonic sensor (for distance) but now i need to run the motor at a given RPM (the Output). I did a lot of resarch and found that i will have to use the PID Library. But with my existing code i'm not sure if it's going to work. I know that i will have to modify PWM values by the Input on the analogWrite(). Can you enlight me on this PID? Here is my code:

```
int enableBridgePin = 10;
int forwardPin = 11;
int backWardPin = 9;
int tickPin = 2;
const int trig = 5;
const int echo = 6;

int dt;
int distance;

void setup() {
  pinMode(enableBridgePin, OUTPUT);
  pinMode(forwardPin, OUTPUT);
  pinMode(backWardPin, OUTPUT);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);

  digitalWrite(forwardPin, LOW);
  digitalWrite(backWardPin, LOW);

  digitalWrite(enableBridgePin, HIGH);
}

void loop() {
  analogWrite(enableBridgePin,255);

  digitalWrite(forwardPin, HIGH);
  digitalWrite(backWardPin, LOW);
  Serial.println(distancefonction(dt,distance));

  if (distancefonction(dt,distance)<15 && distancefonction(dt,distance)>7){
    slowdown();}
}

int distancefonction(int dt, int distance) //function to show distance

void slowdown(){
  for(int i=255;i>=0;--i){
      analogWrite(enableBridgePin,i);
      delay(10);}
   Serial.println("SLOWDOWN");
}

```

# Answer
PID- or any similar control needs

* set point
* actual value
* controlling variable (your PWM value)

The difference between set point and actual variable and its change over time are combined to calculate the controlling variable in order to minimize that difference.

Control theory in general is too complex to answer the "how to" here in general.

Besides measuring the actual value you also need knowledge about the behavior of your system: e.g. If you change the PWM value from 50 to 100, how much and how quick will the motor speed change? Even the response form over time will affect the optimal parameters for your control loop. It's called (feedback) loop because any change of the PWM value will change that difference and lead to a different new value of the controlling PWM value again (Allowing for instable behavior in case of bad controlling parameters).

Getting the actual value is your first task. How your `distancefonction` affects the desired value (set point) might also need more clarification...
> 1 votes

---
Tags: arduino-uno, motor, pwm, pid
---


# Question
Title: Common button on two Arduinos and two computers
We have two computers giving two presentations that need to be triggered in sync. I know how to send the space button via Arduino, but I want to check it will be safe for the computers. If each Arduino is connected to their computer via USB, both data pins togeather and both grounds togeather (not sure if I can find a dt momentarily push button in two days). Is there anything I should keep in mind incase both sides are not at the same voltage as eachother?

# Answer
> 1 votes
The ground of both computers are connected also via their power lines. You get a ground loop that *might* result in malfunctions and/or defects.

Think about using a galvanically separated connection, for example via an optocouple.

# Answer
> 1 votes
As long as you don't have to send anything from the pcs to the arduinos (or at least not with both) you can simply connect the arduinos TX with both pc's RX. This way you need only one arduino. Use series resistors (1k) to handle voltage differences between the pcs. If you need two arduinos you're fine without galvanic isolation, but I recommend series resistors on the reading gpios as well (just in case you configure the ports as outputs accidentially). In case you use laptops which usually don't have PE, you have to connect the arduinos grounds as well.

---
Tags: arduino-uno, power
---


# Question
Title: How to use? ATmega328P Development Board for Arduino UNO R3 Bootloader Project DIY
How to use? ATmega328P Development Board for Arduino UNO R3 Bootloader Project DIY.

# Answer
> 2 votes
The purpose of this board is to flash (Arduino) bootloader to Atmega 328 chips. It has not a build in programmer, only a ICSP header to connect the programmer.

So wire it with a programmer and then chip in, ZIF close, burn bootloader, ZIF release, chip out, next chip in, ZIF close, ....

video

# Answer
> 0 votes
Actually you can program with this device. Treat it as a Genuino Uno and select AVRISPmkII programmer. Used mine several times.

---
Tags: arduino-uno
---


# Question
Title: Comparing a text string to text output (DHT22)
Lately I've received a DHT22 sensor. I've started to create a small temperature and humidity monitor station. One of the things I noticed was if you pulled out the sensor while in use, it displayed "nan". What I wanted to do was if the variable "temp" (for the temperature) equaled "nan", my LCD would display a message. But I keep getting a scope, conversion, and declaring errors. I've tried every variable and a lot of online forums, documentations, and the official Arduino reference site. My code looks like this:

```
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <LiquidCrystal.h>

const int rs = 53, en = 51, d4 = 49, d5 = 52, d6 = 48, d7 = 47;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#define DHTPIN 27
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

int chk;
float hum;
float temp;

byte bigdot[8] = {
  B00000,
  B00000,
  B00000,
  B01110,
  B01110,
  B01110,
  B00000,
  B00000
};

byte circle[8] = {
  B00110,
  B01001,
  B01001,
  B00110,
  B00000,
  B00000,
  B00000,
  B00000
};

void setup() {
  lcd.createChar(0, bigdot);
  lcd.createChar(1, circle);
  lcd.begin(16, 2);
  dht.begin();
  do {
  lcd.setCursor(5,1);
  lcd.write(byte(2));
  lcd.setCursor(4,0);
  lcd.print("Loading");
  delay(500);
  lcd.clear();
  lcd.setCursor(7,1);
  lcd.write(byte(2));
  lcd.setCursor(4,0);
  lcd.print("Loading");
  delay(500);
  lcd.clear();
  lcd.setCursor(9,1);
  lcd.write(byte(2));
  lcd.setCursor(4,0);
  lcd.print("Loading");
  delay(500);
  lcd.clear();
  dht.readHumidity();
  dht.readTemperature();
  } while (hum > 90 || temp > 50.00);
  Serial.begin(9600);

}

void loop() {
    hum = dht.readHumidity();
    temp = dht.readTemperature();
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Temp: ");
    lcd.print(temp);
    lcd.write(byte(1));
    lcd.print("C");

    lcd.setCursor(0,1);
    lcd.print("RH:   ");
    lcd.print(hum);
    lcd.print("%");

    if (temp == a) {
      lcd.clear();
      lcd.home();
      lcd.print("Whoops! An");
      lcd.setCursor(0,1);
      lcd.print("error occured!");
    };
    Serial.print("Humidity: ");
    Serial.print(hum);
    Serial.print(" %, Temp: ");
    Serial.print(temp);
    Serial.println(" Celsius");
    delay(2000); //Delay 2 sec.
 }

```

Thanks in advance!

# Answer
> 1 votes
A "float" number has multiple possible states, besides just being a number (It never, though, can be compared to a string):

* A real floating point number
* Infinity
* Something that isn't a valid number

The latter is what you want - that is, the internal data of the float variable doesn't represent a valid number.

There are two functions in the standard math library that deal with this for you.

To use it:

```
if (isnan(temp)) {
    lcd.print("Invalid");
}

```

---
Tags: arduino-ide, string, dht22
---


# Question
Title: How to set an array size to a variable which might change later into the code?
I'm trying to initialize an array globally which could be of different sizes according to future code in Arduino. `int n=0;
int val[n];`This says that the array bound is not an integer constant before '\]' token. This also says that the val variable wasn't declared.

I have browsed other forms and have been told to use dynamic storage usage which I don't know how to use.

I'm trying to store different weight values respective to time in a variable. I first tried to store the weight in one variable but couldn't find the total weight etc.

# Answer
As others have suggested, dynamically allocated memory is often problematic on a memory-starved device like an Arduino. As you create and release memory, the "heap" (a pool of memory to be used for that purpose) gets broken up into "islands" of free memory with still-used blocks of memory peppered throughout.

In fairly short order you wind up with your available memory pretty much unusable, your app runs out of available memory, and your app crashes.

This is known as "heap fragmentation". When you only have a couple of K of RAM to work with, it quickly becomes fatal.

If you can be sure that you allocate a dynamic buffer in a function call sequence, don't do any other dynamic memory allocation, and then free it before returning, you can probably get away with it without fragmentation, but you really have to be careful.

If you instead dynamically allocate a block of memory very early in your app's life and then keep it for the entire run that can be okay too. That block takes a chunk of your heap and just stays there.

A third alternative is to allocate a statically sized array at compile time that's big enough for your largest use, and treat that as a buffer. You can save contents there as needed, then when you're done with those contents, use the buffer for something else.
> 1 votes

# Answer
The Arduino platform uses a C / C++ compiler. In C++ one can use features such as Vectors to create what appear as arrays of varying sizes. However, it is likely memory is wasted when trying to abstract the memory usage from the application in this way. In an embedded environment, memory is likely at a premium. Consequently, it is almost always better to handle array sizes in embedded situations by allocating the expected amount manually at the beginning of the program.

Tip: If the size of the array depends on the situation the application is used in and there are advantages of smaller verses larger arrays depending on the application, try using Conditional Compiling to create different versions of the application.
> 0 votes

# Answer
In general arrays declared like

```
int array[n];

```

needs a constant size `n`, so that the correct memory size can be allocated at the time of declaration. Otherwise the compiler doesn't know what to do with that variable. You cannot change the size of an array, especially not by simply assigning values to non-existent elements. To create a new array with a size unknown at compile time, you would need to use dynamic allocation:

```
int *array = new int[n];

```

The variable `array` is actually not the array itself, but a pointer to an integer array. The compiler will create the pointer variable, which will only hold an address, where the new dynamically created array is stored. With the `new` keyword we are allocating a new memory space. With `int[n]` we are telling the program to allocate space for `n` integers. You can create arrays with sizes unknown at compile time, but you cannot change the size of an array. You would need to create a new one to change size. Dynamically allocated storage, that is not needed anymore should be freed. (You can google more about this)

**BUT: On an Arduino you should not use dynamic allocation.** If you use the dynamic allocation too much (over and over again) in a program, you will get memory fragmentation. As you allocate and free memory of different sizes, you will get many small memory spaces, which are too small to hold your new arrays. So this memory is now useless and Arduinos only have very little RAM to use for dynamic memory. When your RAM is full, your program will crash. Real computers - in contrast - have loads of memory, so that is not a problem there.

It is better to allocate your memory statically, with enough space to handle your biggest expected amount of data. So you should really think about, if you really need dynamic allocation. I would say no.

---

There are also other problems with your code.

* You use the following for loop:

```
for(n = 0; isFinished = true; n++)

```

A single `=` marks an assignment. So at the start of every for loop iteration you are assigning `true` to `isFinished`. And every assignment will evaluate as true. So you have an infinite loop there. If you want to check for equality, you need to use `==` (double equal sign). Also in that for loop `isFinished` newer changes. You initialize it with `false`, so the loop will not run once. If you instead check for it to be `false` the loop will be infinite, since there is no possibility, that this variable changes inside the loop. Instead use `n` for the loop condition and run the loop as many times as you have elements in your array.
* Generally your logic seems not well thought through. You are already using a for loop to measure multiple values, so why don't you just directly measure as many values, as you want to measure, by using the for loop as described above. Then you don't need all the `isFinished` stuff, because you will always have all the needed values, when you exit the for loop. So you also don't need to check, if there are enough values measured. And it is not clear, what the threshold check should do.
> 0 votes

---
Tags: array
---


# Question
Title: Need advice on serial bytes reading optimization
I am doing some device serial data read and publishing values to MQTT. Using ESP8266 for this.

Currenty I request serial device by sending a command and parse all byte values individually, how to do this in better way ?

each byte parse is done in such way:

```
float Heat = (float)data[38];

  sprintf(mqtt_topic, "%s/%s", mqtt_topic_base, "Temp"); mqtt_client.publish(mqtt_topic, String(Temp).c_str());

float Power = (float)data[39];
......
..... and etc...

```

# Answer
In principle it is ok to use your way, but a simple improvement is to change the magic numbers (38, 39) to constants or define:

```
const int offset_heat = 38;

…

float Heat = (float)data[offset_heat];

```

or a define:

```
#define OFFSET_HEAT 38

…

float Heat = (float)data[OFFSET_HEAT];

```

If all values are consecutive you can keep a variable to read the values:

```
int offset = 38; // Normally starts at 0 assuming you read values from the start

float heat = (float) readByte(&offset);

…

int readByte(uint8_t* offset)
{
    int value = data[*offset];
    (*offset)++;
    return value;
}

```

This increases the offset after reading the value.

Some remarks:

* It's a convention not to use capitals for local variables (so change Heat to heat)
* You don't use the Heat variable in `sprintf`, maybe this is intentional.
> 1 votes

---
Tags: esp8266
---


title: data classification with arduino

text:
# Question
Title: data classification with arduino
I want to classify my data from 3 sensors with arduino so that every time i enter the specific date or hour, or also it can be a period of time like 10 days ago, it shows me the exact data. In other word i want to classify my data so that whenever i want every detail of data, i would be able to get it by entering the information of year,date,time. I also didn't want my data to be in separate files and time stamps. I want to be able to do that within one file and search inside that file...

```
#include "RTClib.h"
#include <SD.h>
#include <SPI.h>

RTC_DS1307 rtc;
const int chipSelect = 10;

File dataFile;

String print_time(DateTime timestamp) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.hour();
int Minute = timestamp.minute();
      int Second= timestamp.second();

      sprintf(message, "%d-%d-%d %02d:%02d:%02d", Month,Day,Year,Hour,Minute,Second);

      return message;
    }

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

      pinMode(chipSelect, OUTPUT);
      if (!SD.begin(chipSelect)){
        Serial.println("Error: SD card would not initiate.");
      }

      rtc.begin();
      if (!rtc.isrunning()){
        Serial.println("Clock is not running");
      }

      dataFile = SD.open("log0.csv", FILE_WRITE);
      if (!dataFile){
        Serial.println("Could not open file.");
      }

    }

    void loop(){
      Datetime now = rtc.now();
      dataFile.println(print_time(now));

      delay(3000);
    }

```

# Answer
If you plan to continuously take data at a fixed rate, I suggest you don't timestamp the individual records. Instead, store the initial timestamp and the data sampling period in a binary header, followed by fixed-size binary records. Then, when you want to retrieve the record for time `t`, you can `fseek()` right to

```
uint32_t offset = header_size
                + record_size * (t - initial_time) / sampling_period;

```

If there is a slight chance that you may fail to record some data points, you may want to have a boolean in each record that tells whether the data is valid. You can then fill the missing data with invalid records.

If your Arduino is likely to be turned on and off unpredictably, then timestamping every record may be a better option, but finding a specific record will likely be very slow.
> 1 votes

# Answer
1. Create a single file (SD logger?)
2. When data is received from a sensor, store it in the file, and store this information:
    1. Date/Time stamp
    2. Which sensor
    3. Sensor data
3. When a request for data is received (probably containing start and end time stamps, parse through the file, and start returning information for those date/time stamps within the requested start/end time stamps.

If step 3 takes too long (and results in missing new sensor measurements), you have to do the read in smaller steps between the reading of sensors.
> 0 votes

---
Tags: arduino-uno, programming, c++, datalogging, data
---


title: Locating a fault in writing a variable

text:
# Question
Title: Locating a fault in writing a variable
I'm writing this piece of code for Arduino Uno, which takes in input on pin 2 the value of a PIR sensor. In order to debug, in this moment I'm taking the signal on pin 2 from the 5V power supply:

```
int inputPinSensor1 = 2; // input pin for sensor 1
int sensor_1_State = LOW; // we start assuming no motion detected for sensor 1
int val = 0; // variable for reading the pin status

void setup() {
  pinMode(inputPinSensor1, INPUT); // declare sensor 1 pin as input

  Serial.begin(9600);
}

void loop(){
  detectChange(&inputPinSensor1, &sensor_1_State);
}

void detectChange(int* inputPin, int* pirState) {
  // read input value
  val = digitalRead(*inputPin);
  // check if the input is HIGH
  if (val == HIGH) {
    if (*pirState == LOW) {
      // we have just turned on
      Serial.println("Current detected");
      *pirState = HIGH;
    }
  } else {
    if (*pirState == HIGH){
      // we have just turned off
      Serial.println("Current ended");
      *pirState = LOW;
    }
  }
}

```

This code should detect the passage from a LOW value to an HIGH value on pin 2, and vice versa. In this way I'm expecting to have an HIGH value on pin 2 when I connect the jumper and a LOW value when I disconnect the jumper. But what I get is two possible behaviors: sometimes I get "Current detected" at the begin of the execution, after which there are no further messages, and sometimes I get a rapid alternation of "Current detected" and "Current ended".

# Answer
> 1 votes
As Majenko says in their comments, a pin that's not connected to anything "floats" and gives unpredictable results.

You either need to connect such a pin to ground through a "pull-down" resistor or to +5V through a "pull-up" resistor. (10KΩ is a good value to start with.)

If you connect the pin to +5V through a pull-up resistor then you would ground it to change it's state. In that case the pin reads HIGH normally, and drops to LOW when triggered. Note that the Arduino has a special mode, INPUT\_PULLUP, that connects the pin to an internal pull-up resistor. In that case you don't need an external pull-up resistor.

In your case, connect the pin to ground with a 10KΩ restistor. Then when you want the pin to go high attach the pin to +5V. That will swamp the connection to ground and pull the pin up to just below 5V.

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


# Question
Title: Error: function was not declared in this scope when using a library without classes
I have created a library of functions that doesn't have and mustn't have a class. In order to have functions inside the library that can only be called from the library itself, you just write them into the .cpp file and leave them out of the header file completely. Here is the .cpp file of the library (the header file is empty):

```
#include "Lib.h"

// Definition of foo1
static void foo1(){
    foo2();
}

// Definition of foo2
static void foo2() {}

```

When including the library in an empty sketch and compiling it I get the following error message:

> error: 'foo2' was not declared in this scope

What is the problem here?

# Answer
When creating a library with functions that are not mentioned in the header file, the order of appearence in the .cpp file suddenly becomes relevant. In order for a function to be used by another function, it has to be declared first.

The first possibility in this example would be to define `foo2` before defining `foo1` like this:

```
#include "Lib.h"

// Definition of foo2
static void foo2() {}

// Definition of foo1
static void foo1(){
    foo2();
}

```

However, this is not only bad practice, it also doesn't always work. If there is any sort of recursive procedure that makes functions call each other, you can't define both of them before the respective other at the same time.

The more elegant and foolproof way to do this is by **declaring** each function first like you usually would in the header file and then defining what they actually do. The .cpp file of this library would then look like this:

```
#include "Lib.h"

static void foo1(); // Declaration of foo1
static void foo2(); // Declaration of foo2

// Definition of foo1
void foo1(){
    foo2();
}

// Definition of foo2
void foo2() {}

```
> 1 votes

---
Tags: library, compilation-errors
---


# Question
Title: Button circuit draws all power away from LEDs
I'm very new to Arduino, so please forgive me if I don't know the proper terms for things.

Whenever I press the button on the board, the LEDs all shut off.

I can't host the image files on imgur, and I don't know how well Flikr will work with it.

Now:

The resistors being used are 220 ohm resistors for the LEDs. The one for the button is a 10k ohm resistor.

This also happens without a resistor in place. I tried simply replacing the button with a wire from the positive to a row, with a wire leading from there to another row, back to ground.

What do I do to fix this?

Edit: Sorry about the images being extremely low quality, they've been updated.

Here's the code, but it's mostly irrelevant:

```
//DEFINE STUFF BABYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
int ButtonState2 = 0;
int ButtonState1 = 0;
int ButtonState0 = 0;
const int ButtonPin2 = 2;
const int ButtonPin1 = 1;
const int ButtonPin0 = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  digitalWrite(13, LOW);
  digitalWrite(12, LOW);
  digitalWrite(11, LOW);
  digitalWrite(10, LOW);
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);
  digitalWrite(7, LOW);
  digitalWrite(6, LOW);
  digitalWrite(5, LOW);
  digitalWrite(4, LOW);
  digitalWrite(3, LOW);
  pinMode(ButtonPin2, INPUT);
  pinMode(ButtonPin1, INPUT);
  pinMode(ButtonPin0, INPUT);
  Serial.print(78);
}

void loop() {
  // put your main code here, to run repeatedly:
  ButtonState2 = digitalRead(ButtonPin2);
  ButtonState1 = digitalRead(ButtonPin1);
  ButtonState0 = digitalRead(ButtonPin0);
  if (ButtonState2 == HIGH){
    digitalWrite(13, HIGH);
    }
    else{
      digitalWrite(13, LOW);
      }
}

```

# Answer
As per your statement, `wire from the positive to a row, with a wire leading from there to another row, back to ground`.

That describes a short circuit between V+ and ground.

Remove either the ground wire or the positive wire.
> 1 votes

# Answer
You have your switch shorting both pin 1 and V+ to ground when you press the switch. Do *not* do that.

**The resistor you have isn't doing anything at all**. It isn't really a meaningful part of your circuit. It is in the middle of one of the rows of your breadboard. All the pins in the same side of one row of the breadboard are connected to each other.

In your breadboard, every row, from 1 to 30, is divided into columns a-e and columns f-j. All the pins a-e in a row are connected to each other, and all the columns f-j are connected to each other. You have one end of your resistor in row 7, column g, and the other end in row 7, column h. So the resistor is short-circuited by the breadboard, and doesn't serve any purpose.

It's as if both ends of your resistor are connected to different points on a wire. If you were to measure the resistance between the leads of that resistor as it's connected, you'd get zero ohms.

You need to rearrange your wiring so you have a wire coming from +5V to one row of your breadboard. Let's call that the +5V row. Have a 10K resistor with one lead into another pin in that row, and then put the other end of the resistor into another row. Let's call that the pull-up row. (It's weakly connected, through a 10K resistor, to +5V. Now plug your switch into that row, also. Finally, run a wire from the opposite side of the switch and into ground.

Make sure to configure the pin as an INPUT.

If you set it up as an OUTPUT, set it to HIGH, and close the switch, you'll short the pin output to ground, probably destroying that pin's output driver. **DON'T DO THAT.**

Now, when the switch is open, the pull-up resistor weakly connects the pin to +5V, so you get a HIGH signal. When you close the switch, it shorts the pin to ground, pulling the input LOW.

Note that you could skip the connections to +5V and set the pin to INPUT\_PULLUP mode instead. INPUT\_PULLUP mode connects the pin to +5V internally, through a high ohm resistor.
> 1 votes

---
Tags: led, button, breadboard
---


# Question
Title: Avrdude verification error after months of successful use
I have a 2560 that I've been working with for a while (over a year for sure), programming it with an avrisp mk2. No issue this whole time, then suddenly, a couple of days ago it starts failing with

```
avrdude: verification error, first mismatch at byte 0x0002
         0x01 != 0x95
avrdude: verification error; content mismatch

```

And very obviously not flashing (there's logic that blinks the LED on boot, and the LED isn't blinking anymore).

The first time this happened, the board appeared completely dead - the programmer wouldn't recognize it, and refused to flash it. After a few days and *magic* it started recognizing it again, and going through the motions of flashing my firmware, but the verification error persists. The location of the error hasn't changed, nor has the two values (0x01 vs 0x95).

Any ideas what this could be?

# Answer
> 2 votes
Still don't know why, but now have a fix. Re-running the 'Burn bootloader' command from Arduino allowed me to then burn my firmware. Not sure if the issue is with fuses somehow being changed, or what, but this seems to have fixed the issue.

One more fun fact - I tried the same thing on a brand new Mega - same effect. First trying to burn my firmware resulted in a verification error (at a slightly different address), then burned bootloader and re-burned my firmware successfully. Wondering if an update to boards.txt or avrdude came through and changed something.

# Answer
> 1 votes
**TLDR:** Make sure that `-D` flag is not used when calling `avrdude` to upload your app using the ISP programmer.

After burning the bootloader on a bare ATmega328p chip using the Arduino IDE and an Arduino Uno as ISP, I am running into the same problem that the OP mentioned with this message:

```
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0094
         0x68 != 0x6a
avrdude: verification error; content mismatch

```

Right after burning the bootloader, I can upload an application using this `avrdude` command (yours would vary slightly due to port name, etc.):

```
avrdude -C/etc/avrdude.conf -v -patmega328p -cstk500v1 -b19200 -P/dev/ttyACM0 -D -Uflash:w:main.hex:i

```

However, if I change the application code, recompile, and rerun the same `avrdude` code again, then I get the verification error mentioned by the OP.

In my case, I have confirmed that the `-D` flag is the problem. In fact, if I remove the `-D` flag in the `avrdude` command above, then I can change, compile, and upload my code as many times as I want.

Note that this is different when using the Arduino IDE to program an Arduino Uno directly (using serial communication through the bootloader), where the `-D` flag is used

```
avrdude -C/etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyACM0 -b115200 -D -Uflash:w:main.hex:i

```

since you wouldn't want to erase the bootloader on the Arduino Uno. Somehow using the `-D` flag is OK in that case.

---
Tags: avrdude
---


# Question
Title: Unable to declare variable in a library that doesn't have a class: multiple definition of the variable
I have created a library `Lib` that doesn't have a class. I want this library to have a variable that can be accessed from outside. The way I would go about this is to just declare them in the header file.

However, if I do this like so:

```
int myVariable = 1;

```

with the `.cpp`-file containing only

```
#include "Lib.h"

```

I get this error message when compiling an empty sketch that includes this library:

> multiple definition of \`myVariable'

and for some weird reason

> Multiple libraries were found for "Lib.h"

on top of that (although, this is something I have encountered before - when there is some error during the compilation, this error may come alongside it, even though there are no multiple libraries; it goes away when the other compilation errors are resolved aswell).

What is causing that error and how to resolve it?

# Answer
In Lib.h you should declare an

```
extern int myVariable;

```

In Lib.cpp you can define it once

```
#include "Lib.h"
int myVariable=123;
...

```
> 3 votes

# Answer
If you want a "variable" that is used at compile time, for instance to set the size of an array, then a variable is *not* what you want.

Variables change. That's what "variable" means. If you are using it for something at compile time then it can't be variable, since it must never change.

Ergo, you want either a *constant* or a `#define` macro which is replaced with a *literal*. Both of these can be done in the header, since they both by default have local TU scope:

```
const int myVariable = 123;

```

Or to use a macro:

```
#define SAMPLE_ARRAY_SIZE 123

```
> 1 votes

---
Tags: library, compilation-errors
---


# Question
Title: Can I send data from one MKR1000 to another MKR1000
I want to simply send data from one MKR1000 to the other over wifi, both are connected to the same network, but sending the data is where I get stuck, I've looked through tuts everywhere but can't seem to find an answer.. can someone point me to a solution?

I've set up my devices using the tut https://www.arduino.cc/en/Tutorial/Wifi101WiFiChatServer but the devices don't communicate to each other they only take telnet from the host server(my laptops wifi hotspot)

# Answer
WiFiClient object wraps a TCP socket. A normal TCP socket is connected to IP address and port. WiFiServer starts a listening socket on a port. If server on listening socket is contacted by a remote client socket, it creates a local socket connected with the remote client socket on a free port and returns a WiFiClient object wrapping the socket. Everything you write or print to a WiFiClient is send to that one remote socket.

If one of your client boards creates a WiFiClient and connects it to IP address and port of the WiFiServer on your 'server' board, then you get there a WiFiClient from server.available() and this two WiFiClient objects are connected. What you write/print on one side you read only from the WiFiClient object on the other side.

client socket

```
if (client.connect(serverIP, PORT)) {
  client.print("request\n");
  String response = client.readStringUntil('\n');
  Serial.println(response);
  client.stop();
}

```

server side

```
WiFiClient client = server.available();
if (client && client.connected()) {
  String request = client.readStringUntil('\n');
  Serial.println(request);
  client.print("response\n");
  client.stop();
}

```
> 1 votes

# Answer
I found a tutorial that explains exactly what Majenko and Juraj explained, https://www.instructables.com/id/MKR1000-IoT-Clientserver-Communications/

the library code that the tutorial references is useful, the tutorial is useful to us learning communication
> 1 votes

---
Tags: communication, mkr1000
---


title: DC Motor Control L298N

text:
# Question
Title: DC Motor Control L298N
I am trying to control the speed of two motors using L298N. I use "Arduino Nano ATmega 168". I change the analogWrite between 0-255 but I cannot see any difference. When I assign it to something like 120 the motor stops.

The pwm pins of the motor drive is connected to the 7th and 8th pins of the Arduino. My code is like that:

```
const int in1=9; //motor 1
const int in2=10;//motor 1
const int in3=11;//motor 2
const int in4=12;//motor 2
const int p1=7;//pwm pin for motor 1
const int p2=8; //pwm pin for motor 2

void setup() {
  // put your setup code here, to run once:
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
pinMode(p1,OUTPUT);
pinMode(p2,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  analogWrite(p1,255);
  analogWrite(p2,130);
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);

}

```

PS:

* My Arduino and Motor Shield have same the ground
* I use a power supply and not a battery.

I would be happy if anyone could help me)

# Answer
> 1 votes
const int p1=7;//pwm pin for motor 1

const int p2=8; //pwm pin for motor 2

PWM pins on a '168 are 3,5,6,9,10,11

---
Tags: arduino-nano, l298n, speed
---


title: Arduino ultrasonic sensor weird output

text:
# Question
Title: Arduino ultrasonic sensor weird output
So I just got into arduino and bought Elegoo's car robot v3 kit and built it, but when I put the robot on "object avoidance" it constantly spins as though there is an object in front of it. I tried changing the code and had no luck so I thought maybe it was the sensor itself, when I hooked it up and ran:

```
void loop() {
   a=sr04.Distance();
   Serial.print(a);
   Serial.println("cm");
   delay(1000);
}

```

it displayed the correct distances so I figured it could not be the sensor. The curious thing happened when I added a few lines to the car's code to also make it print the distance it was seeing, and when the sensor is hooked up to the car for whatever reason all it sees is 18cm no matter the actual distance, which explains why it is constantly spinning. I have found the problem, but now my issue is that for the life of me I cannot figure out why it detects only 18cm constantly when hooked to the car.

```
#include <SR04.h>

/*
 * @Description: Rocker_Control
 * @Author: HOU Changhua
 * @Date: 2019-08-12 18:00:25
 * @LastEditTime: 2019-08-27 10:45:29
 * @LastEditors: Please set LastEditors
 */
#include <Servo.h>
#include <stdio.h>
#include "HardwareSerial.h"
#include "ArduinoJson-v6.11.1.h" //ArduinoJson

/*Driving Interface for Ultrasound Ranging*/
#define ECHO_PIN A4
#define TRIG_PIN A5

/*Motor Drive Interface*/
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

/*Driving Interface for Infrared Pipeline Patrol*/
#define LineTeacking_Pin_Right 10
#define LineTeacking_Pin_Middle 4
#define LineTeacking_Pin_Left 2
#define LineTeacking_Read_Right !digitalRead(10)
#define LineTeacking_Read_Middle !digitalRead(4)
#define LineTeacking_Read_Left !digitalRead(2)

#define carSpeed 180 //PWM(That is: motor speed/vehicle speed)

Servo servo;
unsigned long IR_PreMillis;
unsigned long LT_PreMillis;

enum FUNCTIONMODE
{
  IDLE,
  LineTeacking,
  ObstaclesAvoidance,
  Bluetooth,

} func_mode = IDLE; /*Functional model*/

enum MOTIONMODE
{
  STOP,
  FORWARD,
  BACK,
  LEFT,
  RIGHT
} mov_mode = STOP; /*Motion model*/

void delays(unsigned long t)
{

  for (unsigned long i = 0; i < t; i++)
  {
    getBTData_Plus();
    delay(1);
  }
}

/*Acquisition Distance: Ultrasound*/
unsigned int getDistance(void)
{
  static unsigned int tempda = 0;
  unsigned int tempda_x = 0;
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  tempda_x = ((unsigned int)pulseIn(ECHO_PIN, HIGH) / 58);
  if (tempda_x < 150)
  {
    tempda = tempda_x;
  }
  else
  {
    tempda = 30;
  }
  return tempda;
}
/*Control motor: */
void forward(bool debug, int16_t in_carSpeed)
{

  analogWrite(ENA, in_carSpeed);
  analogWrite(ENB, in_carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  if (debug)
    Serial.println("Go forward!");
}

/*Control motor: */
void back(bool debug, int16_t in_carSpeed)
{

  analogWrite(ENA, in_carSpeed);
  analogWrite(ENB, in_carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  if (debug)
    Serial.println("Go back!");
}
/*Control motor:*/
void left(bool debug, int16_t in_carSpeed)
{
  analogWrite(ENA, 250);
  analogWrite(ENB, 250);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);

  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  if (debug)
    Serial.println("Go left!");
}
/*Control motor:*/
void right(bool debug, int16_t in_carSpeed)
{
  analogWrite(ENA, 250);
  analogWrite(ENB, 250);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  if (debug)
    Serial.println("Go right!");
}
/*Control motor:*/
void stop(bool debug = false)
{
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
  if (debug)
    Serial.println("Stop!");
}
/*
  Bluetooth serial port data acquisition and control command parsing
*/
void getBTData_Plus(void)
{
  String comdata = "";

  while ((Serial.available() > 0) && (false == comdata.endsWith("}")))
  {
    comdata += char(Serial.read());
    delay(3);
  }
  if ((comdata.length() > 0) && (comdata != "") && (true == comdata.endsWith("}")))
  {
    StaticJsonDocument<200> doc;                                //Create a JsonDocument object
    DeserializationError error = deserializeJson(doc, comdata); //Deserialize JSON data
    if (!error)                                                 //Check if deserialization is successful
    {
      int control_mode_N = doc["N"];
      char buf[3];
      uint8_t temp = doc["H"];
      sprintf(buf, "%d", temp);
      String CommandSerialNumber = buf; //Get the serial number of the new command

      switch (control_mode_N)
      {
      case 5: /*Clear mode  processing <command：N 5>*/
        func_mode = Bluetooth;
        mov_mode = STOP;
        Serial.print('{' + CommandSerialNumber + "_ok}");
        break;
      case 3:               /*Remote switching mode  processing <command：N 3>*/
        if (1 == doc["D1"]) // Line Teacking Mode
        {
          func_mode = LineTeacking;
          Serial.print('{' + CommandSerialNumber + "_ok}");
        }
        else if (2 == doc["D1"]) //Obstacles Avoidance Mode
        {
          func_mode = ObstaclesAvoidance;
          Serial.print('{' + CommandSerialNumber + "_ok}");
        }
        break;
      case 2: /*Remote switching mode  processing <command：N 2>*/

        if (1 == doc["D1"])
        {
          func_mode = Bluetooth;
          mov_mode = LEFT;
          Serial.print('{' + CommandSerialNumber + "_ok}");
        }
        else if (2 == doc["D1"])
        {
          func_mode = Bluetooth;
          mov_mode = RIGHT;
          Serial.print('{' + CommandSerialNumber + "_ok}");
        }
        else if (3 == doc["D1"])
        {
          func_mode = Bluetooth;
          mov_mode = FORWARD;
          Serial.print('{' + CommandSerialNumber + "_ok}");
        }
        else if (4 == doc["D1"])
        {
          func_mode = Bluetooth;
          mov_mode = BACK;
          Serial.print('{' + CommandSerialNumber + "_ok}");
        }
        else if (5 == doc["D1"])
        {
          func_mode = Bluetooth;
          mov_mode = STOP;
          Serial.print('{' + CommandSerialNumber + "_ok}");
        }
        break;
      default:
        break;
      }
    }
  }
}

/*Bluetooth remote control mode*/
void bluetooth_mode()
{
  if (func_mode == Bluetooth)
  {
    switch (mov_mode)
    {
    case FORWARD:
      forward(false, carSpeed);
      break;
    case BACK:
      back(false, carSpeed);
      break;
    case LEFT:
      left(false, carSpeed);
      break;
    case RIGHT:
      right(false, carSpeed);
      break;
    case STOP:
      stop();
      break;
    default:
      break;
    }
  }
}
/*
  Line Teacking Mode
*/
void line_teacking_mode(void)
{
  if (func_mode == LineTeacking)
  {
    if (LineTeacking_Read_Middle)
    {                           //Detecting in the middle infrared tube
      forward(false, carSpeed); //Control motor：the car moving forward
      LT_PreMillis = millis();
    }
    else if (LineTeacking_Read_Right)
    {                         //Detecting in the right infrared tube
      right(false, carSpeed); //Control motor：the car moving right
      while (LineTeacking_Read_Right)
      {
        getBTData_Plus(); //Bluetooth data acquisition
      }
      LT_PreMillis = millis();
    }
    else if (LineTeacking_Read_Left)
    {                        //Detecting in the left infrared tube
      left(false, carSpeed); //Control motor：the car moving left
      while (LineTeacking_Read_Left)
      {
        getBTData_Plus(); //Bluetooth data acquisition
      }
      LT_PreMillis = millis();
    }
    else
    {
      if (millis() - LT_PreMillis > 150)
      {
        stop(); //Stop motor control：Turn off motor drive mode
      }
    }
  }
}
/*f(x) int */
static boolean function_xxx(long xd, long sd, long ed) //f(x)
{
  if (sd <= xd && xd <= ed)
    return true;
  else
    return false;
}
/*Obstacle avoidance*/
void obstacles_avoidance_mode(void)
{
  static uint16_t ULTRASONIC_Get = 0;
  static unsigned long ULTRASONIC_time = 0;
  static boolean stateCar = false;
  static boolean CarED = false;
  static uint8_t switc_ctrl = 0x00;
  static boolean timestamp = true;
   Serial.print(A4);
   Serial.println("cm");
   delay(1000);

  if (func_mode == ObstaclesAvoidance)
  {
    servo.attach(3);
    if (millis() - ULTRASONIC_time > 100)
    {
      ULTRASONIC_Get = getDistance(); //Measuring obstacle distance
      ULTRASONIC_time = millis();
      if (function_xxx(ULTRASONIC_Get, 0, 30)) //If the distance is less than Xcm obstacles
      {
        stateCar = true;
        stop(); //stop
      }
      else
      {
        stateCar = false;
      }
    }
    if (false == CarED)
    {
      if (stateCar == true)
      {
        timestamp = true;
        CarED = true;
        switc_ctrl = 0x00;
        stop();          //stop
        servo.write(30); //sets the servo position according to the  value
        delays(500);
        if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
        {
          switc_ctrl |= 0x01;
          //goto
        }
        else
        {
          switc_ctrl &= (~0x01);
        }
        servo.write(150); //sets the servo position according to the  value
        delays(500);
        if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
        {
          switc_ctrl |= 0x02;
          //goto
        }
        else
        {
          switc_ctrl &= (~0x02);
        }
        servo.write(90); //tell servo to go to position in variable 30
        delays(500);
        if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
        {
          switc_ctrl |= 0x04;
          //goto
        }
        else
        {
          switc_ctrl &= (~0x04);
        }
      }
      else
      {
        forward(false, 180); //Control motor：the car moving forwar
        CarED = false;
      }
    }

    if (true == CarED)
    {
      // Get cpu time
      static unsigned long MotorRL_time;
      if (timestamp == true || millis() - MotorRL_time > 420)
      {
        timestamp = false;
        MotorRL_time = millis();
      }
      if (function_xxx((millis() - MotorRL_time), 0, 400))
      {
        switch (switc_ctrl)
        {
        case 0 ... 1:
          left(false, 150); //Control motor：The car moves forward and left
          break;
        case 2:
          right(false, 150); //Control motor：The car moves forward and right
          break;
        case 3:
          forward(false, 150); //Control motor：the car moving forwar
          break;
        case 4 ... 5:
          left(false, 150); //Control motor：The car moves forward and left
          break;
        case 6:
          right(false, 100); //Control motor：The car moves forward and right
          break;
        case 7:
          back(false, 150); //Control motor：Car backwards
          break;
        }
      }
      else
      {
        CarED = false;
      }
    }
  }
  else
  {
    servo.detach();
    ULTRASONIC_Get = 0;
    ULTRASONIC_time = 0;
  }
}
void setup(void)
{
  Serial.begin(9600);         //initialization
  servo.attach(3, 500, 2400); //500: 0 degree  2400: 180 degree
  servo.write(90);            //sets the servo position according to the 90（middle）

  pinMode(ECHO_PIN, INPUT); //Ultrasonic module initialization
  pinMode(TRIG_PIN, OUTPUT);

  pinMode(IN1, OUTPUT); //Motor-driven port configuration
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);

  pinMode(LineTeacking_Pin_Right, INPUT); //Infrared tracking module port configuration
  pinMode(LineTeacking_Pin_Middle, INPUT);
  pinMode(LineTeacking_Pin_Left, INPUT);
}

void loop(void)
{
  getBTData_Plus();           //Bluetooth data acquisition
  bluetooth_mode();           //Bluetooth remote mode
  line_teacking_mode();       //Line Teacking Mode
  obstacles_avoidance_mode(); //Obstacles Avoidance Mode
}

```

New Debug:

```
/*Acquisition Distance: Ultrasound*/
unsigned int getDistance(void)
{
  static unsigned int tempda = 0;
  unsigned int tempda_x = 0;
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  tempda_x = ((unsigned int)pulseIn(ECHO_PIN, HIGH) / 58);
  if (tempda_x < 150)
  {
    tempda = tempda_x;
  }
  else
  {
    tempda = 30;
  }
  Serial.print(tempda);
  Serial.println("cm");
  delay(1000);
  return tempda;
}

```

# Answer
> 1 votes
Welcome to the wonderful world of Arduino programming and robotics!

As you have discovered, sometimes the magic doesn't work with the first incantation, so some work is required to get the spell just right ;-).

When troubleshooting a problem with a sophisticated system like the Elegoo kit you have, it helps to drastically simplify things to start with to establish a working baseline, then add complexity incrementally until the problem behavior occurs. Then you can concentrate on the (hopefully) smaller piece of code that caused the problem, without having to wade through lines and lines of irrelevant programming.

It appears that you have started in the right direction with your simple program to display the distance once per second, so you have the right idea. If you haven't done so already, I suggest you create a completely new Arduino sketch, with just your once/second measurement as the entire program (plus the #include necessary to access the sensor). Once you have it running in isolation, then add just the 'obstacles\_avoidance\_mode(void)' function along with some print statements to instrument the different decision trees of the function. For instance, I might simplify the function down to something like this:

```
void obstacles_avoidance_mode(void)
{
  static uint16_t ULTRASONIC_Get = 0;
  static unsigned long ULTRASONIC_time = 0;
  ULTRASONIC_Get = getDistance(); //Measuring obstacle distance
  ULTRASONIC_time = millis();
  Serial.print("time = ");Serial.print(ULTRASONIC_time);
  Serial.print(", dist = ");Serial.println(ULTRASONIC_Get);
 }

```

Then add the required 'getDistance() function to the bottom of your new test program and call 'obstacles\_avoidance\_mode(void)' once per second. Once you have that working to your satisfaction, then start adding small pieces of 'obstacles\_avoidance\_mode(void)' one at a time, along with whatever preconditions are required to force each small section to execute as you cause the sensor's reported distance to change by moving your hand toward and away from the sensor. Don't worry about the motors and/or servos all; you can hook them up later as needed.

By doing this you should very rapidly come to understand how the program is making decisions, without getting bogged down in all the other stuff going on in the full robot code.

Hope this helps,

Frank

# Answer
> 0 votes
`Serial.print(A4)` makes no sense, that just directly reads the GPIO pin (0 or 1). Maybe that statement is actually messing up the configuration of the GPIO and messing up the distance measurement. You need to use the `getDistance()` function. For debugging, try printing the tempda return value just before the return statement. You still might need to convert that echo timing to cm distance though.

# Answer
> 0 votes
I'm using ultrasonic sensor to get the water level in a watertank for my irrigation system. The following piece of code for measuring the distance works fine for me. I'd suggest to replace:

```
tempda_x = ((unsigned int)pulseIn(ECHO_PIN, HIGH) / 58);

```

(BTW what is 58?) with the following:

```
long duration;
duration = pulseIn(ECHO_PIN, HIGH);
tempda_x = duration*0.034029/2;

```

0.034029 is the speed of sound per second(m/s). And this times the duration it takes sound to get back, divided by 2 gives us the distance from the object.

Hope it helps.

---
Tags: arduino-uno, sensors, hc-sr04
---


title: Using Arduino Micro with MPU6050

text:
# Question
Title: Using Arduino Micro with MPU6050
I have an Arduino Micro and an MPU6050 gyro/accelerometer board; I want to read DMP data from the MPU6050, but the sketch requires the use of the interrupt pin, of which I have none of the interrupt pins available and they cannot be switched around.

I'm wondering how to go about reading the DMP data when needed. I've tried but always just receive the value 180 for any reading.

Thank you!

# Answer
I searched quite some time for everything regarding the MPU6050, but there is just rumors and jokes about the dmp funcionality. One project encorporates the hard reverse-engeneering some wise people did, which is: http://www.i2cdevlib.com/docs/html/class\_m\_p\_u6050.html

This also uses the interrupt, which I suppose you can't really avoid. Why exaclty this would be necessary though, is not a thing I could tell you.. I assume, that the dmp works somehow with the fifo buffer and can only interact through it. The cited library has examples with and without dmp, which I can really recommend.

Using this thing for a quadcopter however I can just say, that the dmp is too slow to control such a fast system, so maybe first consider what you really need. From my experience it does some magic things, but acts strange is due to it's not documentary it is a pain to work with.

Hope this helps.
> 2 votes

# Answer
You can, in fact, avoid the use of an interrupt with the MPU6050/DMP combination. See the ongoing thread at https://github.com/jrowberg/i2cdevlib/issues/479 and this post for example. I've been running an MPU-6050 based system using polled (vs interrupt) driven configuration for months without any issues (other than a pesky motor noise issue I'm currently trying to resolve).

Regards,

Frank
> 0 votes

---
Tags: accelerometer, mpu6050
---


title: Useless box wiring and code

text:
# Question
Title: Useless box wiring and code
just want to give a back story first. So i saw this video on youtube about the useless box, and i thought that it would make a great gift for my 7 year old. So i went out and bought everything that the guy posted in his description box. Just want to say that i am very new to Arduino and how these things work. I actually just want to build this as a gift to my son. I know on Stack platforms that before you ask questions you need to try yourself, i have been trying to get this thing working for the past 36 hours, and im not getting anywhere.

So here is a list of the things i have tried so far.

1. Firstly i bought everything exactly the same as what the guy had, imported it so i know its the same stuff.
2. I downloaded the code and schematic.
3. I wired the little board 4 times, to make sure i did it correctly.
4. I have redrawn the schematic in tinkercad to make sure all the wires are going to the correct places.

Here is the link to my tinkercad drawing the code is in there as well. Please note that on tinkercad i cant get the arduino board not to be plugged in by usb, it is supposed to get power from the external power supply (4AA battries).

https://www.tinkercad.com/things/43WIrlmR1K3-project1

Here is a link to the youtube video: https://www.youtube.com/watch?v=cpdjQ0gheDQ&t=311s

Here is the schematic he provided:

Here is the Code he provided:

```
 #include <Servo.h>

Servo handServo;
Servo boxServo;

int switchStatus=0, action=1, vot, randNumber=0;
const int ledPin = 13;
const int frontSwitchPin = 2;
const int handServoPin = 5;
const int boxServoPin = 6;

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

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin,HIGH);

  handServo.attach(handServoPin);
  boxServo.attach(boxServoPin);
  handServo.write(180);
  boxServo.write(70);

  //randomSeed(analogRead(0));
}

void loop()
{
  switchStatus = digitalRead(frontSwitchPin);
  //action = random(1,16);

  if (switchStatus == LOW){

    if (action == 1)
    {
      Serial.println("Action 1");
      for (int i = 70; i <= 110; i++)
      {
        boxServo.write(i);
        delay(20);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(20);
      }
      delay(1000);
      handServo.write(26);
      delay(200);
      for (int i = 26; i <=180; i++)
      {
        handServo.write(i);
        delay(20);
      }
      for (int i = 110; i >= 70; i--)
      {
        boxServo.write(i);
        delay(20);
      }
      action++;
    }

    else if (action == 2)
    {
      Serial.println("Action 2");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(550);
      handServo.write(26);
      delay(550);
      handServo.write(180);
      delay(550);
      boxServo.write(70);
      delay(1500);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(3000);
      boxServo.write(70);
      action++;
    }

    else if (action == 3)
    {
      Serial.println("Action 3");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(1000);
      boxServo.write(70);
      delay(2000);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(550);
      handServo.write(180);
      delay(500);
      boxServo.write(70);
      action++;
    }

    else if (action == 4)
    {
      Serial.println("Action 4");
      for (int i = 70; i <= 110; i++)
      {
        boxServo.write(i);
        delay(20);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(20);
      }
      delay(2000);
      handServo.write(26);
      delay(200);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 5)
    {
      Serial.println("Action 5");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(2000);
      handServo.write(65);
      delay(550);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(2000);
      handServo.write(26);
      delay(400);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 6)
    {
      Serial.println("Action 6");
      for (int i = 70; i <110; i++)
      {
        boxServo.write(i);
        delay(20);
      }
      delay(1000);
      for (int i = 0; i < 12; i++)
      {
        for (int j = 70; j <= 110; j++){
          boxServo.write(j);
          delay(6);
        }
        delay(200);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(30);
      }
      handServo.write(26);
      delay(400);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      delay(1500);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(3000);
      boxServo.write(80);
      action++;
    }

    else if (action == 7)
    {
      Serial.println("Action 7");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(400);
      handServo.write(26);
      delay(1000);
      for (int i = 0; i < 6; i++)
      {
        for (int j = 70; j <= 110; j++){
          boxServo.write(j);
          delay(6);
        }
        delay(200);
      }
      delay(500);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 8)
    {
      Serial.println("Action 8");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(2000);
      for (int i = 0; i < 7; i++)
      {
        handServo.write(75);
        delay(100);
        handServo.write(40);
        delay(100);
      }
      delay(500);
      handServo.write(180);
      delay(1000);
      boxServo.write(70);
      action++;
    }

    else if (action == 9)
    {
      Serial.println("Action 9");
      for (int i = 70; i <= 105; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(2000);
      boxServo.write(110);
      for (int i = 180; i >=35; i--)
      {
        handServo.write(i);
        delay(40);
      }
      delay(500);
      handServo.write(26);
      delay(200);
      for (int i = 26; i <=180; i++)
      {
        handServo.write(i);
        delay(40);
      }
      boxServo.write(70);
      delay(2000);
      boxServo.write(100);
      delay(3000);
      boxServo.write(70);
      action++;
    }

    else if (action == 10)
    {
      Serial.println("Action 10");
      for (int i = 70; i <= 105; i++)
      {
        boxServo.write(i);
        delay(100);
      }
      delay(1000);
      for (int i = 0; i < 10; i++)
      {
        for (int j = 70; j <= 100; j++){
          boxServo.write(j);
          delay(6);
      }
        delay(100);
      }
      boxServo.write(110);
      delay(100);
      handServo.write(26);
      delay(650);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 11)
    {
      Serial.println("Action 11");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(2000);
      for (int i = 0; i < 3; i++)
      {
        handServo.write(65);
        delay(200);
        handServo.write(40);
        delay(200);
      }
      delay(1500);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      delay(1500);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(3000);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 12)
    {
      Serial.println("Action 12");
      for (int i = 70; i <= 110; i++)
      {
        boxServo.write(i);
        delay(50);
      }
      delay(1000);
      for (int i = 180; i >= 26; i--)
      {
        handServo.write(i);
        delay(50);
      }
      delay(2000);
      handServo.write(26);
      delay(200);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 13)
    {
      Serial.println("Action 13");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(2000);
      for (int i = 180; i >= 60; i--)
      {
        handServo.write(i);
        delay(40);
      }
      for (int i = 0; i < 3; i++)
      {
        handServo.write(60);
        delay(200);
        handServo.write(40);
        delay(800);
      }
      handServo.write(26);
      delay(2000);
      handServo.write(180);
      delay(500);
      boxServo.write(70);
      action++;
    }

    else if (action == 14)
    {
      Serial.println("Action 14");
      for (int i = 70; i <= 105; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(4000);
      boxServo.write(110);
      handServo.write(26);
      delay(650);
      handServo.write(180);
      delay(500);
      boxServo.write(100);
      delay(4000);
      boxServo.write(70);
      action++;
    }

    else if (action == 15)
    {
      Serial.println("Action 15");
      for (int i = 70; i <= 105; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(1000);
      for (int i = 0; i < 3; i++)
      {
        for (int j = 70; j <= 105; j++){
          boxServo.write(j);
          delay(50);
        }
        for (int j = 105; j >= 70; j--)
        {
          boxServo.write(j);
          delay(50);
        }
      }
      for (int j = 70; j <= 110; j++){
        boxServo.write(j);
        delay(50);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(40);
      }
      delay(1000);
      handServo.write(26);
      delay(400);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action = 1;
    }

  }

}

```

So in my tinkercad when i run the simulation everything works (exept for the motors breaking but i know it because of the extra power its getting from the usb which i can turn off). When you look in the Serial Monitor it runs through all the "Actions" and when you simulate the button that gets pressed by the servo everthing stops and wait until you toggle the switch again and it goes to the next action.

I have done exactly the same and like i said i wired the board 4 times to make sure its exactly the same. When i switch on the project on my board the servos keep spinning and does not stop and wait for the switch, but when i toggle the switch it actually plays the next "Action", but in the times where it is suppose to wait or stop when the switch is in the off position the servos keep rotating looks like in an anti-clockwise rotation.

Please any help would be greatly appreciated. If you need more info or if anything is unclear please ask me to provide more and i will. I tried to make it as clear as possible. Thanks

# Answer
> 3 votes
> Yes they turn 360

Normal servos turn between 0 and 180° (or a bit more or less). On these servos you can set the angle through `Servo.write()`. But if the servo spins 360° and more, it is a continuous rotation servo. Here the `Servo.write()` value sets the rotation speed, not the angle. A value of `90` let's it stand still. Values below 90 means rotation backwards, above 90 forward. The higher the distance from 90, the higher the rotation speed will be.

In the video the servos are mounted in a way, that they cannot spin 360°, so they must be normal servos (that also fits with the code). If your servos spin more, you unfortunately bought the wrong servo type.

The code sets the idle position of the boxservo to 70 and of the handservo to 180. That means, that with a continuous rotation servo both servos would spin in idle state, the handservo being way faster than the boxservo.

So you would need to buy normal servos for this project.

---
Tags: arduino-uno, programming, servo, project
---


# Question
Title: Cannot write to HID USB device (Arduino, V-USB, HidSharp)
I am currently prototyping an HID USB device using Arduino Nano and V-USB library. The problem is that although I can read from the device I cannot write to it.
Here is the schema:  As for the firmware I'm using the hid-serial library.
Here is the Arduino code:

```
#include <HIDSerial.h>

HIDSerial serial;

unsigned char buffer[32];

void setup() {
  serial.begin();
}

void loop() {
  if(serial.available()) {
    int size = serial.read(buffer);
    if (size!=0) {
      serial.write((const uint8_t*)buffer, size);
      serial.write('\n');
    }
  }
  serial.poll();
}

```

Here is the HID report descriptor:

```
    0x06, 0x00, 0xff,              // USAGE_PAGE (Generic Desktop)
    0x09, 0x01,                    // USAGE (Vendor Usage 1)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x09, 0x00,                    //   USAGE (Undefined)
    0x82, 0x02, 0x01,              //   INPUT (Data,Var,Abs,Buf)
    0x95, HIDSERIAL_INBUFFER_SIZE, //   REPORT_COUNT (32)
    0x09, 0x00,                    //   USAGE (Undefined)
    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)
    0xc0                           // END_COLLECTION

```

And lastly, here is the code running on host (.NET/C# using HidSharp library):

```
var devices = DeviceList.Local;
var hidDeviceCollection = devices.GetHidDevices(this.vendorId, this.productId).ToList();
var device = hidDeviceCollection.First();
var stream = device.Open();
var buffer = new byte[9];
buffer[0] = 0;
buffer[1] = 42;
stream.Write(buffer);
buffer = stream.Read();

```

When I run the code above despite stream.CanRead being true I receive an exception "Can't write to this device.". However if I change the code to the "Hello World" example provided by the library I can read from the device without issue.

# Answer
Found the error.
While the HidSharp was sending output reports, the device driver expected feature reports.
Changing the line

```
0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)

```

to

```
0x92, 0x02, 0x01,              //   OUTPUT (Data,Var,Abs,Buf)

```

resolved the issue.
> 1 votes

---
Tags: usb, avr
---


title: Multiple MPU9250 Synced

text:
# Question
Title: Multiple MPU9250 Synced
I am interested in collecting data from 3 MPU9250 via I2C communication protocol. As I've read, I can collect measurements on the same I2C Bus from up to two MPUs. However, how can I collect **Synced** data from more than 2 MPUs. And if not Arduino what do you recommend?

# Answer
The MPU uses a FIFO buffer for the data. So the time of measurement is not necessarily the same as the time of communication. Additionally there is the FSYNC pin. In the MPU9250 datasheet there is nearly nothing described about that pin, only the pin description:

> 11 FSY Frame synchronization digital input. Connect to GND if unused.

I would interpret this as: If you pulse this pin to high (active high), a measurement is started. I cannot garantee, that it works this way; I also only can look into the datasheet. For my answer I will assume, that the pin really works this way. You will have to test this yourself.

Based on that info I would propose the following solution (without being able to try it myself due to the lack of MPU):

Connect 1 Arduino digital output pin to the FSYNC pins of all MPUs. If you pulse this pin from LOW to HIGH (and then to LOW again after a short time to return to the passive state), the MPUs will start their measurements. Since they all get the same start pulse, they will do the measurement at the same time. (It may be, that you need to configure the MPU for this) When the measurement is done, the data will be placed in the FIFO buffer. Then you need to grab this data from all the MPUs over I2C.

Here come a trick, so that you can effective connect to a great number of MPUs: The address pin of the MPU is also checked during operation. This means, that you can change the address of an MPU during operation by connecting it's address pin to a digital output pin of your Arduino. Do this with every used MPU, one output pin for one MPU address pin. On the Arduino you set all the pins to the same output state (let's say LOW) to keep all the MPUs on the same address. You must not ever call this address through I2C. If you want to communicate with one of the MPUs, you output a HIGH at it's address pin. This specific MPU will change it's address, where you can now communicate like normal. When you are done communicating with it, just output LOW again. Now you can activate the next MPU for communication by outputting HIGH on it's corresponding address pin.

This way you have 1 inactive address and 1 active address, where the MPU's being there change based on your digital outputs.
> 0 votes

---
Tags: arduino-uno, mpu6050, datalogging, oscillator-clock, multiplexer
---


# Question
Title: How to get the overall average of the data received
I have an arduino uno with two sensors. Voltage and current sensors. I need to get the average value of voltage and current each time the data is received. But i don't know how to add up the current and previous values and divide it to how many values that it has received.

Can someone help me, please? I need it for my project

This is the code i have made

```
void setup(){
Serial.begin(9600);
}
void loop(){
    int n=5;
    float sum=0;
    float ave=0;
    for(int x=0;x<n;x++){
        float volt=analogRead(A0);
        float voltage = map(volt,0,1023,0,2500);
        voltage/=100;
        Serial.print("Voltage: ");
        Serial.print(voltage,2);
       sum=sum+voltage;
       }
ave=sum/n;
Serial.print("Average: ");
Serial.print(average,2);
delay(3000);
}

```

But this only takes the average of 5 datas. I want to get the average of all data received.

# Answer
> 3 votes
```
void setup(){
Serial.begin(9600);
}
void loop(){
    static unsigned long count=0;
    static float sum=0;
    float ave=0;
    int volt=analogRead(A0);
    float voltage = map(volt,0,1023,0,2500) / 100.0;
    Serial.print("Voltage: ");
    Serial.print(voltage,2);
    sum=sum+voltage;
    count++;
    ave=sum/count;
    Serial.print("  Average: ");
    Serial.println(ave,2);
    delay(3000);
}

```

This runs quite a while. The average is restarted only with a Reset of your arduino.

Alternatively, you might want to learn about a moving average (aka low pass filter)

---
Tags: arduino-uno, current, voltage
---