title: Using several Arduinos simultaneously

text:
# Question
Title: Using several Arduinos simultaneously
I'm working on a project where I need to control the light of 5 buttons as well as listen when each button is switched on/off by the user. I would furthermore like to provide feedback on an OLED display. It looks like I'm running out of pins. This https://arduino.stackexchange.com/a/22689/69029 provides several options for that. I would specifically like to explore the option to have several arduinos connected to each other in a master/slave configuration. Where can I learn more about my option to build stuff using several Arduinos connected to each other? I can also forsee scenarios where I could use 3.3V devices as well as 5V devices.

# Answer
Among all the options mentioned, using a master/slave should be the last resort, especially when you are new to embedded programming or Arduino, it is not only more complicate but also more expensive to implement.

One potential solution that could free up the precious digital i/o pins that were used by the 5 buttons is using analog input to detect the status of the buttons.

simulate this circuit – Schematic created using CircuitLab

When sw1 is pressed, the voltage at the A0 will be around 0.83v, and when sw5 is pressed, the voltage at the A0 will be 2.5v. You can write a simple `switch...case` to determine which switch has been pressed.

The only problem of this circuit is that it can't handle more than one button been pressed simultaneously, but that could be solved by double the value of each resistor like 10k, 20k, 30k...

This will free-up 5 digital pins that can be used for control (such as servo, relay, etc.).
> 3 votes

# Answer
Instead of trying to use multiple Arduino boards, which would be hard, I'd suggest using a bigger Arduino. The mega 2560, for example, has **tons** of GPIO lines.
> 2 votes

# Answer
I haven't seen this being done much. But that's probably because it isn't the best option in almost all cases.

Having multiple pieces of code, for different boards, that you have to work together. Constantly having to upload to different boards. This sound like a nightmare.

The only use-case I could see is to have each Arduino have a single function that shouldn't change (much) over time, and having it act like just any another sensor IC, or led driver IC.

The best example of this would be some of the SparkFun Qwiic Twist, Quad Relay, and Button board. For these they use an Arduino compatible ATTiny84 IC with custom firmware to expose it's functionality over I2C.

But most of their Qwiic boards use custom ICs, since they are either cheaper, or less work to get working.
> 0 votes

---
Tags: communication
---


title: Cannot upload sketch to Arduino Nano

text:
# Question
Title: Cannot upload sketch to Arduino Nano
I've been using Arduino UNO for quite sometime and brought a new Arduino Nano. When I connected it to my computer, the power usb lit up and the blink sketch started running ( as expected of course).

Now I opened up the IDE and switched boards. But when I try to upload code to my Nano I get an error-

> avrdude: ser\_open(): can't open device "\\.\COM3": The system cannot find the file specified.

Clearly the IDE can't see my board. Uploading to my UNO goes fine. The serial port option is greyed out so I can't change it.

I have searched extensively online for a solution and have found none. This must be either a very unique issue or a very simple one.

# Answer
> 1 votes
Firstly, you have a clone not a genuine Arduino Nano. They use a different USB chip and require different drivers. Install the CH340 drivers.

Secondly your cable is bad. It sounds like one with no data wires in it used for powering or charging small low-powered devices like bluetooth headsets etc. Replace the cable with a proper one.

# Answer
> 4 votes
When using a cheap knockoff Nano, it seems that in the newer versions of the Arduino IDE (at least in 1.8.8), you may need to select "ATmega328P (Old bootloader)" from the Processor options under the Tools menu in order to upload sketches.

# Answer
> 2 votes
I've seen this error a few times and renaming the serial port fixed the problem in my case. I documented the steps in detail in Tip #4 of this blog post: https://gyorgybalassy.wordpress.com/2020/10/16/cant-open-device-com-access-is-denied-arduino-upload/

# Answer
> -1 votes
I don't really see a question in the OP, but here is the immediate answer:

Go into Control Panel..Device manager. Open the Ports (COM & LPT) and see what you have. It should be listed.

If it is a CH340 port it will just give a COMx number.

If you have the genuine article then it will actually say so and give you the COMx number to use.

If no COM ports show then try switching out the cable. Power cycle the Arduino and try again.

There aren't that many moving parts in this, but sometimes, Windows gets confused and a Windows reboot might be necessary. That usually only happens if you unplug and replug the Arduino too many times for Windows to keep track of.

---
Tags: arduino-ide, arduino-nano, ide, windows
---


# Question
Title: avrdude: stk500_rcv :programmer is not responding
I'm a newbee to Arduino programming and hoping someone can help me with this. These are the error messages.

avrdude: stk500\_rcv() : programmer is not responding

avrdude: stk500\_getsync() attempt 10 of 10:not in sync:

Problem uploading to board.

I'm using a Arduino UNO clone on com port 3,the blink sketch is functioning. I get the mentioned error message on all sketches I have ran. Not sure what to do.

# Answer
try this site: https://github.com/Makeblock-official/Makeblock-USB-Driver/ , it works for me. This is a driver for arduino, and command for bash
> 2 votes

# Answer
I had a same problem with UNO R3 (CH340G) MEGA328P for Arduino UNO R3

On Ubuntu 14.04 I checked the whether the USB chip not recognized, but it looks ok:

```
~$ dmesg | tail -n 6

[ 3350.417900] usb 2-2: new full-speed USB device number 5 using xhci_hcd
[ 3350.546759] usb 2-2: New USB device found, idVendor=1a86, idProduct=7523
[ 3350.546763] usb 2-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 3350.546764] usb 2-2: Product: USB2.0-Serial
[ 3350.547255] ch341 2-2:1.0: ch341-uart converter detected
[ 3350.547996] usb 2-2: ch341-uart converter now attached to ttyUSB0

```

But the upload went wrong like this:

```
~$ avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -v -v -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -Uflash:w:/home/oliver/Arduino_Build/Blink/Blink.hex:i

avrdude: Version 6.0.1, compiled on Oct 21 2013 at 15:55:32
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/usr/share/arduino/hardware/tools/avrdude.conf"
         User configuration file is "/home/oliver/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyUSB0
         Using Programmer              : stk500v1
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
....

```

After reading bunch of articles , , , , ,  it turned out my bad Chinese Arduino clones does not have bootloader installed on the Atmel microcontroller ship. To solve this problem you need a working Arduino and the clone Arduino we want to fix.

Walk trough who to burn the bootloader: http://www.instructables.com/id/How-to-fix-bad-Chinese-Arduino-clones/

## Shortly: Burn the bootloader

1. You need a working Arduino
2. Connect the working Arduino with a usb to the computer
3. Upload `Examples->ArduinoISP` on working Arduino
4. Connect the wires from the working Arduino to the clone as follows:
    * Pin 10 goes to reset pin
    * Pin 11 -\> 11, 12 -\> 12, 13 -\> 13
    * 5v to 5v and ground to ground
5. Go to `Tools->Board` and select the chinese board that is not working. in my case it's an Arduino Uno.
6. Go to `Tools->Programmer` and select `Arduino as ISP`.
7. Go to Tools again and select "Burn Bootloader".
8. Your clone should work just fine now, but don't forget to restore Programmer (set back to ArduinoISP or AVRISP).

My clone board does not had integrated LED on 13 pin :) you need to connect it for Blinking test.
> 2 votes

# Answer
I assume that you're trying to upload the code with the Rx and Tx pins connected..
Try removing the Rx and Tx and then click the upload button in the IDE..

This happens because your computer communicates with the Arduino via Serial communication. The Rx and Tx pins also do communicate via Serial communication. An Arduino does not have the capability to handle two such communications simultaneously. So, it goes out of sync.. And that's how you get this error...
> 2 votes

# Answer
You mentioned arduino uno clone, do you know what USB chip it's using and what chip you are uploading the sketches to?

The clone I have is very fussy and hangs up continuously. I have had luck once or twice with uploading the sketches. Depending on the chips on the board downloading the proper driver will help and selecting the proper chip under the board setting i.e. Atmega328 or atmega8 depending on the chip. Hope this helps as it worked for me.
> 1 votes

# Answer
I'm not familiar with Arduino Uno, but in case of a Nano switching to another **Processor** in the **Tools** menu of the Arduino IDE solved the problem for me. For my Nano the `ATmega328P (Old Bootloader)` is the one that works, maybe there is a similar option for Uno.

Steps and screenshot: https://gyorgybalassy.wordpress.com/2020/10/16/arduino-programmer-is-not-responding-not-in-sync-error/
> 1 votes

---
Tags: avrdude
---


# Question
Title: I cannot upload any code to my arduino nano
Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "Arduino Nano, ATmega328P"

Sketch uses 934 bytes (3%) of program storage space. Maximum is 30720 bytes.

Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

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

avrdude: stk500\_getsync() attempt 1 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 2 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 3 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 4 of 10: not in sync: resp=0x49

An error occurred while uploading the sketch

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

avrdude: stk500\_getsync() attempt 5 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 6 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 7 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 8 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 9 of 10: not in sync: resp=0x49

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

avrdude: stk500\_getsync() attempt 10 of 10: not in sync: resp=0x49

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

# Answer
For me selecting the `ATmega328P (Old Bootloader)` from the **Tools** --\> **Processor** menu in the Arduino IDE solved the problem.

See: https://gyorgybalassy.wordpress.com/2020/10/16/arduino-programmer-is-not-responding-not-in-sync-error/
> 1 votes

# Answer
I had the same problem with an Arduino Micro. When the upload starts, press once the reset button.
> 0 votes

---
Tags: arduino-nano
---


# Question
Title: Relay starts trigger about 6 times when connecting arduino to laptop
I have a fairly simple code to turn a relay on-off every 2 seconds When i attach the USB of the arduino Uno to the laptop, it goes into a frenzy and the relay triggers on off for 6 times within 3-4 seconds and then it settles down. This however doesnt happen when connecting directly to the power output.

Is there something that needs to be wired to stop this happening ?

I am using an arduino Uno with a relay JQC-3FF-S-Z connected directly to the arduino pins.

```
const int ONOFF_TRIGGER_PIN = 2;

void setup() {
  // put your setup code here, to run once:
  pinMode(ONOFF_TRIGGER_PIN, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(ONOFF_TRIGGER_PIN, LOW);
  delay(2000);
  digitalWrite(ONOFF_TRIGGER_PIN, HIGH);
  delay(2000);
}

```

# Answer
> 2 votes
The markings on your relay suggest the coil is for 5VDC. But you have the coil supply wired to 3V3. Move the coil supply to 5V, and try again.

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


# Question
Title: How to program Esp8266 remotly via wifi?
I hope it's not a sci-fi for arduino. But I saw that dual system with two MCU can program each other via radio connection. It has been done in experimental space cube projects.

It is theoretically possible? I'm thinking about two arduino MCU first of them will be main MCU and second will be like programming device via serial link.I want to program mcu via wifi without cable connection. Somehow send hex file via wifi to eeprom and upload to second device flash memory.

How do you see this issue? Is that a big nonsense?

# Answer
> 2 votes
The firmware update over WiFi is called OTA update. OTA stands for "over the air".

The esp8266 can OTA update itself. The Arduino library for this is called ArduinoOTA and it is bundled with the ESP8266 Arduino boards support package.

See the example for ArduinoOTA library in IDE Examples menu.

Other MCU have the self update option too. ESP32 has it of course, then for SAMD boards Arduino made WiFi101OTA library. For ATmega I made the ArduinoOTA library based on the WiFi101OTA library so it supports SAMD too. And it doesn't have to be WiFi. Cable works too.

The OTA update stores the uploaded firmware in free part of the flash and after successful upload it moves the firmware to target location and resets the MCU.

For any Arduino with SD bootloader OTA update is possible, because the library only has to store the uploaded firmware to the SD card and reset the MCU.

For small ATmega ftp bootloaders exists. Here the bootloader waits for network upload.

Update over a second MCU solutions are for MCU with less flash, mostly for the ATmega328p. The ESPLink firmware and the WiFiLink firmware for ESP8266 can flash attached ATmega328p over RX/TX. The ESP8266AVRISP can flash ATmega wired over SPI.

ArduinoIDE supports OTA upload. It creates a network port based on MDNS record propagated by the ArduinoOTA library or firmware with OTA support.

Other update way is to download the new firmware from a server or upload it over a web page. ESP8266 has for this ESP8266httpUpdate and ESP8266HTTPUpdateServer libraries. For SAMD, ATmega and other boards my ArduinoOTA library has examples on how to store and apply the update received as download or upload.

---
Tags: programming, arduino-nano, nodemcu, uploading, programming-sequence
---


# Question
Title: Can the atmega328 return remainder during integer division?
When I write code like this:

```
int a = 7
int b = 2
int c = a/b
int r = a%b

```

Does the chip use the remainder while calculating c or does it redo the entire calculation?

# Answer
If using optimization, the compiler is smart enough to recognize this.

Since your example is so short, it could be optimized away entirely. To ensure that doesn't happen, the results in `c` and `r` have to be used in some way. Also, if `a` and `b` could *never* change, the values of `c` and `r` would be calculated during compilation. Therefore, I put the calculation in its own function.

From godbolt.com, using AVR-GCC 9.2.0:

```
#include<stdint.h>
#include<stdio.h>

uint8_t a = 0;
uint8_t b = 2;
uint8_t c = 0;
uint8_t r = 0;

void calculate() {
    c = a / b;
    r = a % b;
}

int main() {
    a = 7;
    b = 2;

    calculate();

    printf("%d %d", c, r);
}

```

compiles the `calculate()` function into

```
calculate():
        lds r24,a
        lds r22,b
        rcall __udivmodqi4
        sts c,r24
        sts r,r25
        ret

```

The results, stored in `r24` and `r25` respectively, are re-used from the same division operation.
> 3 votes

# Answer
The compiler is only as smart as you provide it the necessary information.

1. It is good to examine code on godbolt.com. But use it wisely.
Noone should ever compile without optimizations. In the example above the code is not optimized and thus would never been used as such on a board.
2. The example is so artificial that the compiler optimizes it away into just 2 instructions. So the code should be representative for the intended usage.
A better godbolt would be:

```
#include<stdint.h>
#include<stdlib.h>

void myDiv(uint8_t * c, uint8_t * r, const uint8_t a, const uint8_t b) {
    *c = a/b;
    *r = a%b;
}

```

So the input is not predetermined and also the resulting numbers are returned and not thrown away. Which translates with `-Os` to:

```
myDiv(unsigned char*, unsigned char*, unsigned char, unsigned char):
        mov r27,r25
        mov r26,r24
        mov r31,r23
        mov r30,r22
        mov r24,r20
        mov r22,r18
        rcall __udivmodqi4
        st X,r24
        st Z,r25
        ret

```
3. There is the `div(numerator, denominator)` function in `stdlib.h`. This function performs a division and returns both the dividend and the remainder. It is optimized for each platform and uses the best available method to get both. In Godbolt it would look like this:

```
#include<stdint.h>
#include<stdlib.h>

void myDiv2(uint8_t * c, uint8_t * r, const uint8_t a, const uint8_t b) {
    div_t d = div(a, b);
    *c = d.quot;
    *r = d.rem;
}

```

But what surprise, with `-Os` the resulting assembly looks exactly the same! (I leave it to the reader to try it on godbolt).

That means, the compiler is smart enough to:

a. recognise the intention when calling division and modulo an the same operands successively.
b. will use the best available method to achieve the intended calculation for you.

---

**EDIT after Edgar Bonet's comment:**
While playing around in godbolt I made a copy-paste mistake. `div` only applies to `int` values. That makes the resulting assembly code larger as there has twice the data to be shoveld around. After changing both examples to `int` they look almost similar. The only difference is:

The result is stored in `d` first and then copied to `c` and `r`.
So the division/modulo code is more efficient in that regard as the resulting values are copied directly from the registers used in the calling convention.

https://godbolt.org/z/61exz7
> 1 votes

---
Tags: programming, atmega328
---


title: 4WD Robot keeps freezing

text:
# Question
Title: 4WD Robot keeps freezing
I have been working on a 4WD robot for a while now. The parts I'm using are Arduino v4 shield, l298N driver motor, Hc 05 ultrasonic sensor, DHT 11, mq2, Bluetooth module, servo motor, ir transmitter and receiver module and an uno all powered by 2 18650 Li ion batteries and a power bank. when i tried using the Ir sensors only, ultrasonic only or both for obstacle detection and avoidance the code freezes and nothing works anymore until i move the obstacle away then the robot makes the decision it wanted to make. it also used to reset occasionally while frozen but i fixed that issue by powering the Arduino separately. i noticed this problem mostly occurs when all the IRs give a low signal. i think the problem is with my code but i don't really see what i typed wrong.

```
#include <dht.h>
#include <Servo.h>

#define servoPin 11

// Create a servo object
Servo Servo1;

//Ultrasonic Sensor
#define trigPin 9
#define echoPin 10
// defines variables
long duration;
int distance;

//sensor pins
#define gasSens A4
dht DHT;

#define DHT11_PIN 2

//motor driver pins
#define in1 8
#define in2 7
#define in3 6
#define in4 5

//infared pins
#define lftIr 12
#define ctrIr 4
#define rghIr 3

#define buzzer 13

int dist=1000;
int lastVal=0;
int degVal;
int leftDist;
int rightDist;
int gasVal;
int logicVal=49;
int buzzerTrig=0;
unsigned long curTime;

void setup() {
  // put your setup code here, to run once:
  Servo1.attach(servoPin);
  Servo1.write(100);

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  pinMode(lftIr,INPUT);
  pinMode(ctrIr,INPUT);
  pinMode(rghIr,INPUT);

  pinMode(buzzer, OUTPUT);

  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);

  curTime=millis();

  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available() > 0){ // Checks whether data is comming from the serial port
      logicVal = Serial.read(); // Reads the data from the serial port
   }

 if(millis()-curTime>=10000){
    int chk = DHT.read11(DHT11_PIN);
    gasVal=analogRead(gasSens);
    Serial.print(DHT.temperature);
    Serial.print(" C");
    Serial.print("|");
    Serial.print(DHT.humidity);
    Serial.print("%");
    Serial.print("|");
    Serial.print(gasVal);
    Serial.print("|");
    if(gasVal>500){Serial.println("Dangerous gas levels");buzzerTrig=1;}
    else{Serial.println("normal");buzzerTrig=0;}
    curTime=millis();
  }

 if(buzzerTrig==1){
  buzzerCall();
  logicVal==48;
  }

 if(logicVal=='1'){
      dist=distanceCall();

      int leftIr=digitalRead(lftIr);
      int centerIr=digitalRead(ctrIr);
      int rightIr=digitalRead(rghIr);

      if (leftIr==LOW && rightIr==HIGH){
        stopAll();
        while(leftIr==LOW){
          rightMov();
          leftIr=digitalRead(lftIr);
        }
        stopAll();
       }
       else if (leftIr==HIGH && rightIr==LOW){
        stopAll();
          while(rightIr==LOW){
            leftMov();
            rightIr=digitalRead(rghIr);
          }
        stopAll();
      }
      else if (leftIr==LOW && centerIr==LOW && rightIr==LOW){
          stopAll();
              while(leftIr==LOW || centerIr==LOW || rightIr==LOW){
                backMov;
                leftIr=digitalRead(lftIr);
                centerIr=digitalRead(ctrIr);
                rightIr=digitalRead(rghIr);
                }
                stopAll();
          }

      else if (leftIr==HIGH && centerIr==LOW && rightIr==HIGH){
          stopAll();
          while(centerIr==LOW){
            backMov;
            centerIr=digitalRead(ctrIr);
          }
          stopAll();
          delay(10);
          leftMov();
          delay(500);
          stopAll();
        }
      else{
        fowardMov();
      }
    }
}

int distanceCall(){
  // Clears the trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration = pulseIn(echoPin, HIGH);
    // Calculating the distance
    distance= duration*0.034/2;
    return distance;
}

void fowardMov(){
  digitalWrite(in2,HIGH);
  digitalWrite(in4,HIGH);
  digitalWrite(in1, LOW);
  digitalWrite(in3, LOW);
}

void backMov(){
  digitalWrite(in1,HIGH);
  digitalWrite(in3,HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in4, LOW);
}

void rightMov(){
  digitalWrite(in1, HIGH);
  digitalWrite(in4, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
}

void leftMov(){
  digitalWrite(in2, HIGH);
  digitalWrite(in3, HIGH);
  digitalWrite(in1, LOW);
  digitalWrite(in4, LOW);
}

void stopAll(){
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}

void buzzerCall(){
    tone(buzzer, 5000);
    delay(500);
    noTone(buzzer);
    tone(buzzer, 1000);
    delay(500);
    noTone(buzzer);
 }

```

The goal is for the robot to avoid obstacles and move autonomously using only the IR sensors. I used to power everything with the batteries but sometimes it shakes and moves slowly so i decided to power them seperately. Do you think the problem is with my code or it's a hardware problem? Thank you

# Answer
> 1 votes
I'm not surprised that you are having trouble, as you have a very complicated system. When troubleshooting complicated systems it is important to break it down into very simple 'chunks' and make sure each simple piece works separately.

I would remove everything but the code for the three IR sensors from your system, and use a random number generator to generate a random number between 0 & 7. Then I would use the binary representation of that number to generate the return values for the digitalRead() calls to the sensors, with appropriate printouts to show you what values were generated and what effect those values produced. I think you'll find that one or more of the 8 possible values causes problems, as you only have IF clauses for 4 (or 6 if you count the two 2-valued systems twice).

---
Tags: programming, sensors, robotics
---


# Question
Title: AMIS30543 | DataSheet Understanding CIRCULAR TRANSLATOR TABLE
I was reading the data sheet of AMIS-30543 stepper motor and I didn't understand fully what does this Circular Translator Table means, I have a couple of doubts

1. What does Circular Translator table Stands for.? How to read it .? pg:13
2. What does the current pairs can be projected approximately on a circle in Ix, Iy plane means.? pg:25

3. In the data Sheet it is given that **Changes on the NXT input will move the motor current one step up/down in the translator table (even when the motor is disabled: = 0)**. So the changes happened in the table while the motor was disabled will reflect as soon as the motor become active.? Like if I give say 5 step input while the motor was disabled and when I make the motor enable , will the motor will move by itself to reach that position in the translator table.? pg:25

Link to datasheet

# Answer
1. It describes the current going through the two coils of the stepper motor at each `step`.
2. I'm not quite sure, as I would think the last two diagrams should actually be squares. But for example, in the first image, you can see that the current in the X coil will steadily increase, while the current in the Y coil will steadily decrease. This will make the stepper rotate more slowly.

In the second image, you can see that only the Y coil driver is at 100% in step 0. In step 1 both coils are at 100%. In step 2 coil Y is turned off. I think this is profile produces more torque, but is less smooth.
3. No. I you are, for example using full step mode, and the motor is in step 0. If you give it 3 steps forward (while the motor is disabled) it would drive the coils (once you re-enable to motors) as described in the lookup table for step 3. Which in practice would mean the motor would rotate backward one step (instead of 3 steps forward).

In other cases, it could result in undefined behavior. Going from step 0 to step 2 could mean it would rotate clockwise, anticlockwise, or even not rotate at all.

Though in practice I don't think this would even be an issue, and disabling the motor, but still sending it step pulses is kind of silly.
> 1 votes

---
Tags: arduino-uno, programming, motor, electronics, stepper
---


# Question
Title: Servos jitter when powered by power module
I need 48 sg90 servos to move to a specific position each minute. Now I am using two arduino mega boards to power everything through 6 bread boards but it seems I need more power because some servos are ticking and are delayed. I cant get the external power supply to work independently of the computer. Once I unplug from my computer the servos jitter. Any help would be greatly appreciated.

# Answer
> 1 votes
Most servos use an analog signal (width of a pulse) for positioning. Any perturbation in that signal will cause unexpected behavior. Activating 48 servos simultaneously will likely indirectly or directly affect the analog signal.

The unexpected behavior might be mitigated through changes in software or hardware. These mitigation efforts may include:

1. Staggering the servo changes so that only 1 servo moves at a time.
2. Perhaps less effective but worth trying, staggering the servo changes so only 1 servo starts moving at a time. In this scenario more than 1 servos may be moving at a time.
3. Using a power supply which maintains the expected voltage even during events such as all servos starting simultaneously.

These are only 3 options to consider. Many more exist but may not be pertinent to your situation. More information is needed.

---
Tags: power, servo
---


# Question
Title: Float mulitplication Returns ovf or -0.0 for small whole float numbers
I wrote a simple multiplication function for matrices. Originally my matrices are stored in a single array in format (row, column):

(row0, col0), (row0, col1), (row0, colN), (row1, col0), ... (rowN, col0).

so a 2x2 identity matrix would look like

```
float eye[4] = {1, 0, 0, 1};

```

In the actual function I put the 2 array matrices being multiplied into 2d arrays (easy human readable) and then do the multiplication to get the new matrix output. Then convert back to single array. I am only dealing with 3x3, 3x1, and 1x3 matrices. So my code is not be 100% compatible with every matrix possibility. I have global arrays temp3 for my 3x1 and 1x3 matrices, and temp3x3 to hold 3x3 matrices. I use a global bool squared to determine which one the new output will go to.

I get that my code is not perfect, but my question is, why do I get overflow for simple operations? My code is as follows:

```
#include <math.h>
#include <WString.h>

#define FLOAT sizeof(float)
void multiplyMatrixAxB(const uint8_t rows1, const uint8_t cols1, const uint8_t size1, float matrix1[], const uint8_t rows2, const uint8_t cols2, const uint8_t size2, float matrix2[]);

float K[3]; // 3x1
float dgdn[3]; // 1x3

bool squared = false;
// Temp Variable to hold matrixes
float temp3x3[9];
float temp3[3];

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Starting Matrix Test Program\n"));

  uint8_t i;
  K[0] = 1.0;
  K[1] = 2.0;
  K[2] = 3.0;

  dgdn[0] = 0.0;
  dgdn[1] = 0.0;
  dgdn[2] = 1.0;

  Serial.println(F("Matrix K setup as:"));
  for(i = 0; i < sizeof(K)/FLOAT; i++)
  {
    Serial.print(K[i]);
    Serial.print(F("\n"));
  }

  Serial.println(F("Matrix dgdn setup as:"));
  for(i = 0; i < sizeof(dgdn)/FLOAT; i++)
  {
    Serial.print(dgdn[i]);
    Serial.print(F("\t"));
  }
}

void loop()
{
  squared = true;
  Serial.println(F("\n\nA 3x1 times a 1x3 should give 3x3"));
  multiplyMatrixAxB(3,1, sizeof(K)/FLOAT, K, 1, 3, sizeof(dgdn)/FLOAT, dgdn);
  for(i = 0; i < 9; i++)
  {
    Serial.print(*(temp3x3 + i), 6);
    if(!((i+1)%3))
    {
      Serial.println();
    }
    else
    {
      Serial.print(F("\t"));
    }
  }

  Serial.print(F("\n\n"));
  Serial.println(F("End of Test"));
  while(1){delay(1000);}
}

void multiplyMatrixAxB(const uint8_t rows1, const uint8_t cols1, const uint8_t size1, float matrix1[], const uint8_t rows2, const uint8_t cols2, const uint8_t size2, float matrix2[])
{
  if(cols1 != rows2)
  {
    Serial.println(F("Multiplying Invalid Matrixes. Check ColsA and RowsB"));
    while(1){delay(1000);}
  }

  if(size1 != rows1*cols1)
  {
    Serial.println(F("rows and columns do not match size of matrix A"));
    while(1){delay(1000);}
  }

  if(size2 != rows2*cols2)
  {
    Serial.println(F("rows and columns do not match size of matrix B"));
    while(1){delay(1000);}
  }

  uint8_t row, column, k, i;
  double mat1[rows1][cols1];
  double mat2[rows2][cols2];
  double newMat[rows1][cols2];

  // place matrix1 into 2d array
  row = 0;
  for(row = 0; row < rows1; row++)
  {
    column = 0;
    for(column = 0; column < cols1; column++)
    {
      mat1[row][column] = matrix1[row*cols1 + column];
    }
  }

  // place matrix2 into 2d array
  row = 0;
  for(row = 0; row < rows2; row++)
  {
    column = 0;
    for(column = 0; column < cols2; column++)
    {
      mat2[row][column] = matrix2[row*cols2 + column];
    }
  }

  // get new array with multiplied values
  row = 0;
  for(row = 0; row < rows1; row++)
  {
    column = 0;
    for(column = 0; column < cols2; column++)
    {
      k = 0;
      for(k = 0; k < cols1; k++)
      {
        newMat[row][column] += mat1[row][k]*mat2[k][column];
      }
    }
  }

  row = 0;
  i = 0;
  // Place new matrix into single array format
  for(row = 0; row < rows1; row++)
  {
    column = 0;
    for(column = 0; column < cols2; column++)
    {
      if(squared)
      {
        temp3x3[i] = newMat[row][column];
      }
      else
      {
        temp3[i] = newMat[row][column];
      }
      i++;
    }
  }
}

```

Hopefully that covered everything. I have more code, but it is all mostly commented out. At worst I missed a variable declaration here, but I will mention that in the IDE it compiles fine and runs. My output looks like this:

```
Starting Matrix Test Program

Matrix K setup as:
1.00
2.00
3.00
Matrix dgdn setup as:
0.00    0.00    1.00

A 3x1 times a 1x3 should give 3x3
0.000000    0.000000    1.000000
ovf 0.000000    2.000000
0.000000    0.000000    3.000000

End of Test

```

Where does this ovf come from? I have tried printing out in the multiplication statement in the for loop the index of mat1 x the index of mat2 = "result". This will actually print out exactly what I expect to see and then my output in the main loop will be ok. What is going on? I tried some delays to see if that was the issue between calculations as well. No good.

what I mean is placing in the inner most for loop (k loop):

''' Serial.print(mat1\[row\]\[k\]); Serial.print(" x "); Serial.print(mat2\[k\]\[column\]); Serial.print(" + "); ''' And then just outside it,

''' Serial.print(" = "); Serial.println(newMat\[row\]\[column\]); '''

I will not get any overflow in this scenario.

# Answer
> 1 votes
`newMat` is first declared:

```
double newMat[rows1][cols2];

```

and then updated:

```
newMat[row][column] += mat1[row][k]*mat2[k][column];

```

However, it has never been initialized. Non-static local variables are not implicitly initialized: `newMat` starts its life containing whatever garbage was in RAM at this location. You should initialize every element to zero before you start accumulating the sum of products.

---

**Edit**: Regarding the initialization as

```
float newMat[rows1][cols2] = {{0},{0}};

```

I would expect that to initialize the whole matrix to all zeros, but my experiment shows that it only initializes the first element of the first two rows, and the entire third row. Initializing an array with a list shorter than that array is supposed to initialize the other elements to zero. However, this appears to not work recursively with the inner arrays. I do not know whether it is a compiler bug or normal behavior. The following, however, does work:

```
float newMat[rows1][cols2] = {};  // zero-initialize

```

Regarding the copies within `multiplyMatrixAxB()`, you can completely avoid them by using pointers. For example,

```
double (*mat1)[cols1];

```

declares `mat1` as a pointer to arrays of length `cols1` of `double`. This would be equivalent to `double mat1[][cols1]` within a parameter list, and is compatible with a 2D array of width `cols1` and unspecified height. If you make this point to `matrix1`:

```
double (*mat1)[cols1] = (double (*)[cols1]) matrix1;

```

you can then use `mat1` as a different *view* of `matrix1`: you view it as an array of arrays of numbers, rather than a 1D array of numbers. You can then use `mat1` as you do now, and it will work by accessing the original data, without needing an extra copy.

Using this trick, the body of `multiplyMatrixAxB()` can be reduced to the following (skipping error checking):

```
// View the vectors as matrices.
double (*mat1)[cols1] = (double (*)[cols1]) matrix1;
double (*mat2)[cols2] = (double (*)[cols2]) matrix2;;
double (*newMat)[cols2];
if (squared)
  newMat = (double (*)[cols2]) temp3x3;
else
  newMat = (double (*)[cols2]) temp3;

// Matrix multiplication.
for (int i = 0; i < rows1; i++)
  for (int j = 0; j < cols2; j++) {
    newMat[i][j] = 0;
    for (int k = 0; k < cols1; k++)
      newMat[i][j] += mat1[i][k] * mat2[k][j];
  }

```

---
Tags: arduino-uno, float
---


# Question
Title: Inaccurate and non-precise voltage reading from Arduino Analog pin
```
float get_volt() {
  rawVolt = analogRead(voltageSensor);
  vOUT = (rawVolt * 4.6) / 1024.0;
  vIN = vOUT / (R2/(R1+R2));
  //if(vIN>12.0){vIN=12;}
  //if(vIN<11.12){vIN=11.12;}
  //return (vIN - 10.18) * (100 - 0) / (12.0 - 10.18) + 0;
  return vIN;
}

```

I am using a voltage sensor module which has a voltage divider with R1=30K Ohms and R2=7.5K Ohms and can measure up to 0-25V by using 10-bit Analog pin of arduino. the battery voltage comes as 11.4 volts when measured with a multimeter but I am getting an inaccurate reading from arduino ranging from 10.8 to 11.4. the Arduino voltage reference is stable at 4.6 V. Please help me to fix this, you can see the voltage reading in the image PS: the battery and arduino are connected to the same ground.

edit1: adding 0.1uf capacitor helped to improve from this

to this!

the data is taken for over a period of 1 hr at every 5 seconds, its a 12V 4000 mAh battery

# Answer
This should be a lot of fun but you might consider doing some research on analog circuits and A/D circuits. You have way too many digits to the right of the decimal, the accuracy is not there. The best you can get is 0.0044 volts per count with a 4.6v reference. What are you using to make your measurements, you need at 5 1/2 digit meter to have the decade better accuracy then what you are calibrating to. Your reference you state is 4.6 volts, something is not correct is should be 5.000V. You know any load placed on the on board regulator will have an effect on your A/D readings. The tolerance of the resistors you are using will have an impact on your reading. They generate noise that could be affecting your readings. 100nF should be enough capacitance,this will lower the input impedance. Increasing capacitance beyond this will slow the settling time of the circuit. If you are powering this from a computer USB expect noise from that power source, That would also explain the lower reference voltage on the A/D. With what you indicate you have, you are actually doing very well.
> 4 votes

---
Tags: arduino-mega, adc, voltage, analogreference, voltage-divider
---


title: max wattage LED for esp32

text:
# Question
Title: max wattage LED for esp32
Simple spec question I couldn't figure out, what is, practically speaking and ballpark, the maximum wattage of LED you can drive with an ESP32 (I guess about the same as an arduino?).

Conditions:

* using a boost converter for higher voltage: Yes
* using ESP32 pin as output and power: Yes
* use mosfets/external power circuit: no
* no other load is connected to the ESP32 board

My silly calculation:

* GPIO allows for 12mA output (source)
* cheap and small voltage boost elements go to about 9-12V

i.e. (12 milliamperes) * 12 volts = max 0.144 watts.

Is that about right (orders of magnitude)?

# Answer
No. You're way off.

If the output can provide 12mA at 3.3V that equates to (P=VI) 39.6mW. Boosting the voltages does not increase the power. Assuming a 100% efficient boost circuit (which does not exist) you would just be boosting to 12V at 39.6mW - which means (I=P/V) 3.3mA.

You can't magic more power out of thin air - if you could we'd all have "free energy" devices powering everything. Instead we have power supplies or batteries.

And that is what you will need. A source for that extra power to come from.
> 4 votes

# Answer
Technically the maximum power is unlimited however it depends on the driving circuit. With a simple MOSFET a few hundred watts is very feasible however the leds need to be in a series parallel configuration to keep the current reasonable. If you use the higher wattage LEDs you also have to supply a heat sink for them. As you get further into electronics and the associated circuits this will become more apparent. Another way to look at it is a simple spark can burn down a forest if the conditions are correct.
> 0 votes

---
Tags: led, esp32
---


title: Signal names HiFi

text:
# Question
Title: Signal names HiFi
i'm not sure if this is the right address, but maybe you know about it. I currently integrate bluetooth to my car's radio using a esp32. First i wanted to insert the signal at the d2b cd player, but since i don't know the right communication between the occ and the processor i don't see a solution here (and i don't have a cd player to get the reference signals)

But there is a CC player that i can use. There is a detailed documentation about the radio, too: https://www.motor-talk.de/forum/aktion/Attachment.html?attachmentId=753560 Page 12 (or 16 of the pdf)

TRK1R, TRK1L, TRK2R TRK2L and PBREF are used for the signals. CCINS will be GND if there is no CC in the slot and otherwise 5V CCEJT will be 5V if you press the eject button, otherwise it's GND

But this is not enough, there is a tape monitoring circuit that needs to be tricked. Can you see from the documentation how to do so?

CCPSE is connected from the processor to the tapedeck, but i don't know what it is good for CCMOD is connected to the latch 2, UG5V and the tapedeck. It's on 5V while the radio is on. RELL\_R and RELL\_F are 5V while idle and otherwise they change their value continuously.

CCMET is connected to the CPU, CC Amplifier and the Tapedeck. It's on 5V if the tapedeck is removed and otherwise always 0V. So i short circuit it with GND to simulate there is a tape deck.

CCLDG is connected to the shiftregister and the tapedeck and i have no idea what it is good for. it's always 0V

CCMOT and LED look like they are both the same from the datasheet. They are 0 in general but when the CC is running they turn 5V.

Maybe some can point me out how to trick the tape monitor

Thanks

# Answer
They make adapters that fit into the Tape socket (if you have one) and will play when you select the audio tape. That is no longer an option on the newer car radios. Mine has an audio input I can use, and it is a 2009 Flex.
> 1 votes

---
Tags: esp32, audio
---


# Question
Title: Read encoder output by using an optocoupler
I have a 512 pulses encoder with four wires: +5V, ChannelA, ChannelB, GND and I'm using it as feedback for my motor position (max 80 RPM) on Arduino UNO. Everything works fine, but I need also to generate a +5V signal everytime ChannelA is HIGH since I need to use it to trigger further actions.

I was thinking to read ChannelA by using an optocoupler in order to split the signal and use it both for feedback and for the +5V signal. Is it possible?

Is there any other easier solution to do that?

**EDIT**: I try to explain better what the additional device must do.

The device is a video camera system that takes a +5V signal from the encoder to trigger some actions by software (create key frames or more) and we need it for our computer vision system. I just need to use the encoders both for the motor feedback and to trigger the video camera. The signal is always +5V so I do not have problems with voltage levels. What do you suggest? I do not have to drive loads from channelA output, I just need the +5V signal to trigger the video camera. Can I split the channelA output and use it both for the motor controller and the video camera inputs?

EDIT2: Following the useful suggestions of @st2000 I tried to think to a solution like this:

Do you think it can work?

EDIT3: I changed swapped the motor controller and the video system positions in the circuit and I changed the voltage source from +12VDC to +5VDC for the motor controller since it accepts only +5V signals as input.

EDIT4: Following the suggestions of @st2000, I changed the circuit design by placing in parallel both devices (motor controller and video system) by using the optocoupler (6N136) only for the video output to isolate it from the whole system.

# Answer
> 1 votes
People sometimes use optical couplers when anticipating large voltage differences or the potential for large voltage differences. This may always be the case as in a light dimmer. Or may preventative as in ground loop mitigation for MIDI connections. If you anticipate these types of situations then an optical coupler may be a good design choice.

Alternatively if the signal is changing between 0 volts and 5 volts and the fan out of the signal is larger then the existing load and the new load combined and the new load is 5 volt tolerant then the signal might be able to drive both loads.

You might seek out the specifications of the 3 connected devices in question. At the very least, discover the current the encoder output will support. Then measure the resistance to ground of the input to the motor controller and the resistance to ground of the input to the video equipment. Find the parallel resistance of these two resistance and calculate the current at 5 volts. If the current is substantially less then the specified capacity of the encoder, the encoder might be able to drive the 2 loads. This assumes many things such as no ground loops being present. There are so many variable it is difficult to be predict the outcome.

# Answer
> 1 votes
A simple cheat is to place the LEDs of the two opto couplers in series and then modify the current limit resistor to bring the current back to where it should be.

---
Tags: arduino-uno, transistor, rotary-encoder, opto-isolator
---


title: Can't understand this codes process

text:
# Question
Title: Can't understand this codes process
```
    void loop()
    {
    if ( Serial.available() > 0 )
      {
    static char input[inputLength];

    static uint16_t i;

    char c = Serial.read();

    if ( c != '\n')
      input[i++] = c;

    else
    {
      input[i] = '\0';
      i = 0;

      uint16_t array[80];
      uint16_t j = 0;

      if ( !strncmp(input, "SEND", 4) )
      {
        char* p = input + 4;

        while ( (p = strchr(p, ' ')) != NULL )
          array[j++] = strtol(p, &p, 16);

        ir_start(array);
        Serial.println("WURKS");
      }
    }
  }
}

```

Hello I can't seem to figure out what this code is doing. I know the main goal but I can't figure out the proccess. If someone could please make the code dumber for me I would appreciate it :). Full code is here since its hard to copy code: https://anonfiles.com/z6ldWff0pf/no\_lib\_ino

# Answer
> 2 votes
It's easier to follow if you indent it properly. I'll do that, and add comments as I go:

```
void loop() {
    if ( Serial.available() > 0 ) { // If there is something in the serial RX buffer

        static char input[inputLength]; // Create a working string to store data in
        static uint16_t i; // This is the current index in that working string

        char c = Serial.read(); // Read the next character from serial

        if ( c != '\n') // If it's not a "line feed" character...
            input[i++] = c; // then store it in the input string and increment i

        else { // Otherwise...

            input[i] = '\0'; // Terminate the string with a NULL to make it valid C
            i = 0; // Reset the index to 0 ready for next time

            uint16_t array[80]; // Create an 80-int array (temporary)
            uint16_t j = 0; // And an index variable

            if ( !strncmp(input, "SEND", 4) ) { // If the string starts with SEND
                char* p = input + 4; // create a "pointer" to the string that starts 4 characters in

                while ( (p = strchr(p, ' ')) != NULL ) // While there is a space somewhere in the string
                    array[j++] = strtol(p, &p, 16); // convert the first portion to a number, store it in the array, and advance the pointer to the next space.

                ir_start(array); // Send the array through IR
                Serial.println("WURKS"); // Tell us it worked
            }
        }
    }
}

```

So you see it receives data through serial and stores it, byte by byte, in `input` until it receives `\n` at which point it looks to see if it starts with `SEND`, then effectively "cuts off" the SEND by only considering everything after the SEND. Then it slices the remainder of the string up by looking for the next space each time and convert each portion to an integer which it stores in an array.

It then sends that array.

# Answer
> 0 votes
I was dumb, turns out it was converting the hex into a int. I sent the array through serial and looked at it.

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


title: Error message - Need help

text:
# Question
Title: Error message - Need help
I found this Haptic Headband project on YouTube (link below) and I am trying to verify the code that was given in the instructions with the Arduino IDE. However, I keep getting the message below and am not too sure what I need to do to fix it. I'd appreciate any help I could get to solve this issue.

I have also attached a pdf of the instructions with the code to use for the headband.

PDF: https://cdn-learn.adafruit.com/downloads/pdf/haptic-headband.pdf?timestamp=1602887165

https://www.youtube.com/watch?v=xD7bfBx5D9M&ab\_channel=AdafruitIndustries

```

libraries\Adafruit_DRV2605_Library\Adafruit_DRV2605.cpp.o (symbol from plugin): In function `Adafruit_DRV2605::Adafruit_DRV2605()':
(.text+0x0): multiple definition of `Adafruit_DRV2605::setRealtimeValue(unsigned char)'
sketch\Adafruit_DRV2605.cpp.o (symbol from plugin):(.text+0x0): first defined here
libraries\Adafruit_DRV2605_Library\Adafruit_DRV2605.cpp.o (symbol from plugin): In function `Adafruit_DRV2605::Adafruit_DRV2605()':
(.text+0x0): multiple definition of `Adafruit_DRV2605::useERM()'
sketch\Adafruit_DRV2605.cpp.o (symbol from plugin):(.text+0x0): first defined here
libraries\Adafruit_DRV2605_Library\Adafruit_DRV2605.cpp.o (symbol from plugin): In function `Adafruit_DRV2605::Adafruit_DRV2605()':
(.text+0x0): multiple definition of `Adafruit_DRV2605::useLRA()'
sketch\Adafruit_DRV2605.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Uno.

```

# Answer
> 1 votes
“Multiple definition” means that you have something defined more than once. According to the error message, some methods are defined both in libraries\Adafruit\_DRV2605\_Library and in your sketch folder.

It looks to me like you are trying to use two copies of the Adafruit\_DRV2605 library. One of them is properly installed as a library, and the other is within your sketch folder. You don't need two copies. If the library is properly installed, there is no point in copying its source files to your sketch folder. Get rid of that extra copy and try recompiling.

---
Tags: arduino-ide, compilation-errors, error
---


# Question
Title: It is possible to revive my Arduino Leonardo (mini beetle) board?
I have this board:

It has the `atmega32u4` chip.

I have updated its code several times, and used it without issues for several months. Today, while updating (using Arduino IDE) it started to throw some errors. At the end it said that the checksum didn't match, so I repeated again few more times with the same behavior until it reported "Uploaded" without errors. I used for few minutes and it was working as expected. Then, I had to do another update and the same happened (checksum didn't match). However this time I got to the point in which it was no longer detected by the OS (Ubuntu), and no LED is turning on.

Whenever I connect it to the USB port, I can only see in the logs:

`usb 1-9.4: new full-speed USB device number 9 using xhci_hcd`

However `/dev/ttyACM0` is not longer created.

I'm trying to use `avrdude` to reset it, but it is reporting:

`avrdude: ser_open(): can't open device "/dev/ttyACM0": No such file or directory`

which make sense as `/dev/ttyACM0` doesn't exists. So, what are my options? Is there anything I can do to make it work again?

**UPDATE**

I didn't realize that this board has a reset marked as "RES". Following `Juraj` recommendation I bridged `RES` and `GND`. The LED marked as "SDA" turns ON after I release the contact and I can read in the logs:

```
[1212051.679205] usb 1-9.4: USB disconnect, device number 22
[1212058.532030] usb 1-9.4: new full-speed USB device number 23 using xhci_hcd
[1212058.621972] usb 1-9.4: New USB device found, idVendor=2341, idProduct=0036
[1212058.621982] usb 1-9.4: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[1212058.621988] usb 1-9.4: Product: Arduino Leonardo
[1212058.621994] usb 1-9.4: Manufacturer: Arduino LLC
[1212058.622933] cdc_acm 1-9.4:1.0: ttyACM0: USB ACM device

```

Which I think its good news. However, it seems ttyACM0 becomes available for few seconds. I was able to upload the Blink example into the chip and I can confirm its working because its blinking. Still the ttyACM0 disappears after few seconds.

Output of `avrdude -c avr109 -p atmega32u4 -P /dev/ttyACM0` :

```
Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: safemode: Fuses OK (E:FB, H:D8, L:FF)
avrdude done.  Thank you.

```

# Answer
Probably you have overwritten your Bootloader.

Connect MOSI, MISO, SCK and RESET to an ISP-Programmer and flash the file Caterina-LilyPadUSB.hex to it.

There are lots of tutorials on the net how to use a spare arduino as an ISP-Programmer.
> 2 votes

---
Tags: arduino-leonardo, avrdude, atmega32u4
---


title: Read Internal Registers of RS485

text:
# Question
Title: Read Internal Registers of RS485
I am trying to interface sele EM2M, I am using Arduino Mega with RS 485 module. I want to read the internal registers I am using ModbusMaster library. The data which I want to receive is in the internal registers but I am not getting how can I read Internal registers. When I use other software to read data I am getting the out

I also wanted to know the difference between Internal Registers and Holding Registers

Another questions how are the frames formed for communication in rs485 from the above image I can understand 01 04 but from where do they get 00 1A please explain the same.

# Answer
The issue is been resolved. I was reading the holding registers and also I tried to read the Input registers but I didn't received any output it was because the register address entered by me was wrong when I referred to a Simply Modbus Master software from where I was able to receive the data when I send a command, from the same software I came to know about the frame structure and how they were formed. So when I tried to enter those register address they were working fine.

Thank you everyone for your help
> 0 votes

# Answer
The RS485 has no internal registers, all of that is in your target unit. Hopefully the instructions for that will tell you how to do it. Start by getting simple communications working then slowly progress from there.
> 1 votes

---
Tags: arduino-mega, communication, rs485
---


# Question
Title: Arduino master/slave communication using RS485
I am using Arduino Uno as a Master Device and 3 Arduino Unos as slave devices.

I am sending data from each slave to master after every 3 seconds continuously, and is going to execute further logic accordingly.

I have been using a lot of libraries to test this scenario. There are libraries which are using SoftwareSerial and HardwareSerial too, but these libraries are not working for me when i have multiple slaves and one master (It is only working with one master and one slave).

Please suggest me a better library which would be useful in my scenario.

**Wiring Diagram:**

# Answer
> 2 votes
First of all, your connection is just wrong, you should make the RS-485 bus as a straight line, with a 120 ohm resistor at the beginning and another one at the end. Each slave should tap into that line as close as possible to that line, look for datasheets and you will understand what I am talking about.

Second, you can use Modbus as a pretty good and easy to use communication protocol.

# Answer
> 0 votes
RS485 module has resistor 120 Ohm inside

---
Tags: arduino-uno, arduino-ide, communication, rs485
---


# Question
Title: ESP-12e - RX/TX pins flickering on boot when used as GPIO pins
I am using ESP-12e as a controller for my garden lights. I am using pins 1 (TX), 3 (RX) and 5 as an analog output (PWM signal with mosfets) for three separate light sets. ESP is powered on when wall switch is turned on (wall switch turns on power adapter). When I turn the switch on, for short period of time lights connected to pin 1 and 3 work at full power and after that they are set according to PWM signal. Lights on pin 5 works just as expected. I am not using Serial communication, just elegantOTA library for OTA updates and async web server. Is it possible to somehow disable RX/TX functionality at all/before they are set to high, or I am forced to solder lights on pins 1 and 3 to another ones? I tried some software tricks I found online, but without success.

# Answer
> I am not using Serial communication,

You might not be, but the bootloader sure is.

> Is it possible to somehow disable RX/TX functionality at all/before they are set to high

No. It's hard coded in ROM. There's nothing you can do.

> or I am forced to solder lights on pins 1 and 3 to another ones?

You could use one IO pin to control a buffer the other IO pins. Something like an AND gate (74HC08) would do the job:

simulate this circuit – Schematic created using CircuitLab

Only when `CTL` is `HIGH` will the `L0`-`L2` signals be mirrored on the outputs to the LEDs. That way you ignore whatever is going on with those pins until you actively drive the `CTL` signal high. Choose one pin that has no boot noise for `CTL` and the other pins then don't matter.

For more detail on what pins do what at boot time read this.
> 1 votes

# Answer
According to this reference, GPIOs 1 and 3 have dedicated behaviour during boot (debug output or pulled high) which can not be disabled in your sketch. You have to either choose different pins or implement an additional circuitry.
> 1 votes

---
Tags: esp8266
---


# Question
Title: Arduino RS485 shield to RS485 temperature & humidity sensor
I’m try to get data from rs485 is not work please advise to me.

```
1.  Try to connect PC usb485 to DY-MD02 is work.
    Send command “AUTO” or “READ”

2.  Try to Arduino rs485 shield to DY-MD02 is not work.
    Send command “AUTO”

```

my code

''''

```
char command[4] = {'A', 'U', 'T', 'O'};

int n = sizeof(command)/sizeof(command[0]);   // Number of elements in an array

String incoming = "";   // for incoming serial string data

void setup()

{

      // initialize serial ports
      Serial.begin(9600);
      pinMode(EN,OUTPUT);
      digitalWrite(EN,HIGH); //Enable high, RS485 shield waiting to transmit data
      Serial.write(command,n); //Test send command Auto,Read to RS485
      delay(500);
}

void loop()

{

      String temp;
      digitalWrite(EN,LOW); //Enable low, RS485 shield waiting to receive data

      while(Serial.available() > 0 )
      {
          temp=Serial.read();
          Serial.println(temp);
          delay(1000); //Delay for some time, waiting for data transmitted
      }

}

```

''''

---

if change code to = ***Serial.readString()*** not show anything.

please help me Thank

---

to Juraj

Maker tell me can connect with Arduino uno and send manual to me.

see in attach file.

# Answer
i'm tray change this code to readStringUntil, is OK

```
if(Serial.available() > 0)
  {
    temp = Serial.readStringUntil('\n');
    Serial.println(temp);
    delay(1000); //Delay for some time, waiting for data transmitted
  }

```

Thank all for help me ^^
> 1 votes

# Answer
I will suggest try to use Modbus Master library it will help you get the data from sensor. The issue with the code is you are only sending the command but while interfacing with modbus there is a packet/ frame which you need to form and then send it the packet/frame format is in the below diagram

I will prefer use an Arduino Mega or other arduino which have more than 1 Serial port for communication. I also faced a similar issue but it was resolved after digging a little bit you can have a look at the issue here
> 0 votes

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


title: Connecting arduino with MATLAB

text:
# Question
Title: Connecting arduino with MATLAB
I installed Octave support package for Arduino and it is listed in the packages installed when pkg list command is run.But when the command "a= arduino('COM8')"; is run,"error: serial: Error opening the interface: No such file or directory" is shown.Please respond.

# Answer
> 2 votes
Using `clear` command on Octave before executing `a=arduino('COM8')` will remove this problem.

Use it like this:

```
clear
a=arduino('COM8')

```

---
Tags: arduino-nano, matlab
---


# Question
Title: Value keeps incrementing even though loop has terminated, why?
I use a double called delta and use that to turn off an LCD if delta is larger than the timeout threshold. Once that happens, delta is supposed to set to 0 and then other parts of the program run. However, delta continues to increment and I'm not sure why.

This is causing a problem because delta is used to determine if the device should "sleep". So when I try to wake up the device via button click, delta is always way past the timeout threshold and the device immediately goes back to sleep.

Any thoughts as to why? Thanks in advance.

```
#include <M5StickC.h>

double BUTTON_PRESS_NEXT_PRESS_TIME= .5; //Time in seconds
double MINIMUM_BUTTON_PRESS_TIME = .05; //Time in seconds
int BUTTON_PRESS_SLEEP = 3; //Time in seconds
int SCREEN_TIMEOUT = 5;
int count;

static int pressCount = 1;
static int nextPress= 1;

static bool buttonIsPressed;

void setup(void) {
  buttonIsPressed = false;
  M5.begin();
  M5.Lcd.setRotation(0);
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

  // Datum is middle centre
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Axp.ScreenBreath(100);

  updateScreen();
}

void updateScreen() {
   char tmp[12];

  // Datum is middle centre
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Lcd.drawString(dtostrf(pressCount,4,0,tmp), 80,60,6);
  M5.Lcd.drawString(dtostrf(nextPress,3,0,tmp), 80,100,6);
}

static void evaluatePress(double d) {
   // Evaluate press
  if (d >= BUTTON_PRESS_NEXT_PRESS_TIME) {
    nextPress++;
    pressCount = 1;

    if (nextPress == 19) {
      nextPress= 1;
    }
  }
  else if (d >= MINIMUM_BUTTON_PRESS_TIME && d < BUTTON_PRESS_NEXT_PRESS_TIME) {
    pressCount++;
  }

  updateScreen();
}

void sleepLoop() {
  bool bIsPressed = false;
  Serial.println("Sleep 1");
  while(1) {
    Serial.println("Sleep 2");
    if (digitalRead(M5_BUTTON_HOME) == LOW && !bIsPressed) {
      bIsPressed = true;
    }

    if (digitalRead(M5_BUTTON_HOME) == HIGH && bIsPressed){
      Serial.println("BREAKY BREAKY");
      M5.Axp.ScreenBreath(100);

      break;
    }
  }
}

void awakeLoop() {
  double delta;
  double old_time;
  double current_time;

  Serial.println("Awake 1");

  while(1) {
    Serial.println("Awake 2");
     //Calculate delta time
    old_time = current_time;
    current_time =  millis();
    delta = delta + (current_time - old_time)/1000;

    if (digitalRead(M5_BUTTON_HOME) == LOW && !buttonIsPressed) {
      buttonIsPressed = true;
      delta = 0;
    }

    if(digitalRead(M5_BUTTON_HOME) == HIGH && buttonIsPressed) {
      buttonIsPressed = false;
      evaluatePress(delta);
      delta=0;
    }

    if(delta > SCREEN_TIMEOUT && !buttonIsPressed) {
      Serial.println(delta);
      Serial.print("BREAK AWAKE");
      Serial.println(M5.Axp.ScreenBreath(0));
      count = 0;
      break;
    }
    else {
      count++;
    }
  }

  delta = 0;
}

void loop() {
  awakeLoop();
  sleepLoop();
}

```

# Answer
Here:

```
void awakeLoop(){
  double delta;
  // The rest of the function body...
  delta = 0;
}

```

delta is being defined as a variable local to the function `awakeLoop()` and with automatic storage. This means the variable is created whenever the program enters the function, is *not* implicitly initialized, and is destroyed when the function returns.

The last statement `delta = 0;` has no effect, as it is setting a variable that is going to be destroyed right away. The compiler most likely got rid of it.

You most likely want the variable to retain its value across invocations of the function. For this to be the case, it has to be either global (defined outside the function) or local with the `static` qualifier. In both cases, it will have static storage, i.e. its lifetime will be the whole program run. Also, if you fail to explicitly initialize it, the compiler will implicitly initialize it to zero.
> 1 votes

---
Tags: c++
---


title: continuous print of button Pushed

text:
# Question
Title: continuous print of button Pushed
When pushing a button I want to read the value...once. If I push(hold) the button I get a continuous print of button1Pushed

```
    if(button1State == LOW) {
     Serial.println("button1Pushed");
  }

```

But if I try to solve it like this, nothing happens, not a single print. What am I missing?

```
 int button1State = digitalRead(button1);
  int lastButton1State;

  if(button1State != lastButton1State){
      if(button1State == LOW){
        Serial.println("button1Pushed");
               }
        }

  lastButton1State = button1State;

```

# Answer
`lastButton1State` is not initialized and therefore has no strictly defined value. In your case, it appears to have a value of `0` (which is random, it's not due to implicit initialization, which is only done for global variables). The condition `if(button1State != lastButton1State)` becomes true only if the button is released.

You can check that by changing

```
if(button1State == LOW){
  Serial.println("button1Pushed");
}

```

to

```
if(button1State == HIGH){
  Serial.println("button1 released");
}

```

The following should work:

```
int last_button_state=HIGH; // initialize to HIGH, so the button does not teigger on very first iteration
void setup () {
  // whatever you want to do here
}
void loop() {
  int button_state=digitalRead(button1);
  if (button_state!=last_button_state && button_state==LOW) {
    Serial.println("button pressed");
  }
  else if (button_state!=last_button_state && button_state==HIGH) {
    Serial.println("button released");
  }
  last_button_state=button_state;
}

```
> 2 votes

---
Tags: arduino-uno
---


# Question
Title: 915Mhz vs Wifi (speed impact of duty cycle limitations)
I am currently using an esp32 with Wifi. I need at least 15kByte/s constant throughout. This works fine but I am not happy with the range.

I came across the RFM69HCW 915MHz module. It is stated with 300 kbps.

Now what is confusing me are duty cycle regulations. Various countries have a 1% limit. Is this limit considered in the 300 kbps? Or do I effectively only get 3 kbps because I cannot constantly send?

# Answer
300kbps is the data transmission rate. Not the throughput rate.

That means that yes, if you only transmit for 1% of the time then for 1% of the time you are getting 300kbps - i.e., 3kbps as you correctly surmised.
> 1 votes

---
Tags: esp32
---


# Question
Title: Difference between WiFiClient and HttpClient
Apologies if this question appears to be too vague but I would like to know the key differences between these two clients.

While WiFiClient comes pre-loaded with Arduino IDE, HttpClient doesn't. Also, to send HTTP commands to a server (XML/JSON), which one to go for?

# Answer
> 5 votes
WiFiClient provides a raw connection to the internet through a WiFi access point (such as your home router).

HttpClient provides a connection to a web server via an existing Client connection, such as a WiFiClient connection.

So the simplest answer to your question

> to send HTTP commands to a server (XML/JSON), which one to go for?

is "Use both".

You use WiFiClient to connect to the internet, then you use HttpClient on your WiFiClient connection to communicate with a website. As it states in the readme on HttpClient's github repository:

> Because it expects an object of type Client, you can use it with any of the networking classes that derive from that. Which means it will work with EthernetClient, WiFiClient and GSMClient.

To understand the concept more fully you will first need to understand the OSI 7-Layer Model which is essential reading for anyone doing anything with networking software.

# Answer
> 1 votes
As Majenko Said,

WiFiClient is raw in the sense you have to deal with the HTTP protocol stuff yourself, a shot snippet of raw GET request is provided below

```
  WiFiClient wc;
  wc.print("GET ");
  wc.print(/xml/device_description.xml);
  wc.println(" HTTP/1.1");
  wc.print("Host: ");
  wc.println(selectedDevice->getIp());
  wc.println("Connection: close");  //automatically close Connection
  wc.println("");

```

each line is terminated with "\r\n", the request is terminated with an empty line

Where as the HttpClient is a library which handle all the low level HTTP protocol stuff and provide simple interface to sent HTTP GET/POST request to any device that support HTTP

```
HTTPClient http;
http.begin(serverName);
http.addHeader("Content-Type", "text/plain");
int httpResponseCode = http.POST("Hi Sending POST request");
Serial.println(httpResponseCode);
http.end();

```

To send JSON change the header with the below line

```
http.addHeader("Content-Type", "application/json");

```

So the answer is if you want to deal with the low level HTTP protocol use WiFiClient else use HTTPClient

---
Tags: wifi
---


# Question
Title: Spikes in CO2 and TVOC measurements with CJMCU-811 sensor
Firstly, I'm not sure if this is the right SE to ask this question. Please feel free to direct me somewhere else if needed.

I am observing large spikes in CO2 and TVOC measurements using the CJMCU-811 sensor. When plotted it looks like this:

Nothing particular is happening around the sensor at those moments of spikes, I'm not breathing on the sensor etc.

I use Arduino Uno with the following code:

```
/******************************************************************************
  Read CO2 and TVOCs from CJMCU-811 sensor

  Arduino connection:
  3.3V to 3.3V
  ACC to 3.3V
  GND to GND
  WAK to GND
  SDA to A4
  SCL to A5

******************************************************************************/
#include <Wire.h>

#include "SparkFunCCS811.h"
#define CCS811_ADDR 0x5B

CCS811 mySensor(CCS811_ADDR);

void setup()
{
  Serial.begin(9600);
  Serial.println("CCS811 Basic Example");

  Wire.begin();

  CCS811Core::status returnCode = mySensor.begin();
  if (returnCode != CCS811Core::SENSOR_SUCCESS)
  {
    Serial.println(".begin() returned with an error.");
    while (1);
  }
}

void loop()
{

  if (mySensor.dataAvailable())
  {

    mySensor.readAlgorithmResults();

    delay(1);

    Serial.print("CO2 ");
    Serial.print(mySensor.getCO2());

    Serial.print(", tVOC ");
    Serial.print(mySensor.getTVOC());

    Serial.println();
  }

  delay(2000);
}

```

Of course I can filter and not worry about them, but I'm nevertheless curious what is causing it. Any suggestions what could be the reason for that?

# Answer
I have two of those sensors in a long term setup and I know those spikes very well. I once put lots of effort in debugging and I personally gave up on the ccs811 and use a different sensor now.

Back then I have already tried what Jaromanda suggests in his comment. Both of my sensos showed the same behaviour while the spikes on both sensors did **not correlate** in any form. Also, if I remember it right, those erronous readings appeared to be at dedicated values. I tried several pullups, which also didn't make any difference and on the oscilloscope everything looked fine. Printing the output of the I2C related functions revealed that communication was always stable. If it was I2C related I would expect those erronous readings to be completely random anyway (which they aren't from my experience).

My final (vague) theory was that maybe there exist race conditions between the computation and the I2C interface or maybe the adc and the approximation algorithm (that's all "inside" of the sensor). I once produced such a bug myself which resulted in a similar behaviour.

At least I'm pretty sure that there is nothing you can do in your sketch to fix this problem, because for the mentioned reasons it is very unlikely related to communication problems. You might want to work-around it or look for an updated firmware. Or (my prefered solution) choose a sensor which does a **true CO2 measurement** (the ccs811 only returns a pseudo, calculated CO2-equivalent approximation). Those higher-class sensors use NDIR technique and are only a bit more expensive (still under 50$) but you'll probably have much more reliable readings, less problems and a wider measurement range (up to 0-40000ppm vs 400-8192ppm).

Ps: did you follow the guidelines concerning the "burn-in time"? Because honestly, that was a mistake I did: I simply plugged it in of curiosity to test communication and read about this step afterwards. But I don't believe it has something to do with this problem, because there are physical reasons why one should do so, but those artifacts seem to be of digital nature.
> 2 votes

# Answer
There is a CCS811 library which supports querying the internal firmware version of the sensor, and flashing a new firmware (latest is 2.0.1). Older firmware versions used to have burn-in compensation which apparently caused more harm than good (instead, new firmware requires sensors to be burned-in during 48 hours), and also relied on an external sensor for temperature compensation, which is simply missing on most cheap breakout boards. Ironically many cheap boards come with CCS811 flashed with an older firmware, which periodically samples the voltage on a floating pin and uses that value to correct CO2/TVOC calculations.

Unless your board features a thermistor, consider upgrading the sensor firmware to 2.0.1. Even or boards with a thermistor (e.g. original Adafruit), new firmware might give better results.
> 2 votes

# Answer
I saw similar behavior from 3 CJMCU-811 sensors that I bought (in one order, so probably the same manufacturing lot) in mid 2019. Two gave readings with steady, spikey, but uncorrelated upward growth. The third periodically spiked into the 2000-3000 ppm zone and then popped back to ~450 ppm (in an empty room with decent airflow). A logic analyzer on the I2C lines didn't show issues (or I missed them).

I went as far as adding a line to reset the sensors every few minutes. Replacing the sensors with what I assume was a different manufacturing lot resolved the issue.

I'm using the AdaFruit ccs811 library on ESP8266s (Wemos D1 minis).

**Months later:** The replacements have gone haywire, occasionally giving readings in the 3000ppm range until reset, at which point they're back to the 400-600ppm range for a while until drifting higher. I recommend avoiding the ccs811.
> 1 votes

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


title: Can you use Serial Port as a variable?

text:
# Question
Title: Can you use Serial Port as a variable?
I am doing a project where, for troubleshooting reasons, I find myself often swapping components to different serial ports. Maybe one time it's in Serial, then in Serial1, maybe I need to try if software serial works.

But changing every line where Serial.print or Serial.write is written for the new port is a hassle and easy to screw up.

Would it be possible to either create a definition at the beginning of the code that lets me rename Serial to SensorSerial so just by changing that definition I am sure it will use the correct port?

# Answer
> 14 votes
Yes. The simplest way is with a preprocessor macro. Macros get replaced verbatim before compilation happens, so you can do something like:

```
#define MY_SERIAL Serial

void setup() {
    MY_SERIAL.begin(115200);
}

void loop() {
    MY_SERIAL.println(millis());
    delay(1000);
}

```

# Answer
> 20 votes
Majenko's answer is the right answer for your question. But to answer the title of the question, if you ever need to use different Arduino outputs and inputs as variable, most of them have common type Stream or Print. So it would be:

```
Stream& SensorSerial = Serial;

```

or

```
Stream* SensorSerial;
SensorSerial = &Serial;

```

The Arduino Stream classes hierachy:

---
Tags: serial, variables
---


# Question
Title: Button to stop a stopwatch not working correctly!
I'm trying to implement a stopwatch with an LCD display, and I'm supposed to be using the `attachInterrupt` command to catch the button press. The clock runs perfectly, but the button input isn't caught or acted upon at all.

In `void setup()`, I have set it up this way: `attachInterrupt(digitalPinToInterrupt(buttonPin), buttonInterrupt, RISING);`.

And the buttonInterrupt function only does `start = !start`, so in a sense just flipping the start variable.

This is the updated version of the code:

```
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int buttonPin = 7;
volatile int buttonState;
int lastButtonState;
long sec;
long startTime;

void setup() {
  lcd.begin(16, 2);
  pinMode(buttonPin, INPUT_PULLUP);
  lcd.setCursor(0,0);
  lcd.print("Push the button!");
  attachInterrupt(digitalPinToInterrupt(buttonPin),buttonInterrupt,HIGH);
}

void loop() {

  buttonState = digitalRead(buttonPin);
  if(buttonState == LOW){
    startTime = millis();
  }

  while(buttonState == HIGH){
    long time = millis();
    long z = (time - startTime);
    sec = (z/1000);
    long ms = z%1000;
    lcd.setCursor(0,1);
    lcd.print(sec);
    lcd.print(".");
    lcd.print(ms);
    lcd.setCursor(8,1);
    lcd.print("Secs");

    if(buttonState == LOW){
      break;
    }
  }
}

void buttonInterrupt() {
  if(buttonState == LOW){
    buttonState = HIGH;
  }else{
    buttonState = LOW;
  }
}

```

The loop function works as far as time counting is concerned, but doesn't work to stop the time with the button. Any help is appreciated, I'm extremely new to Arduino (literally started yesterday). My circuit looks like this: https://i.stack.imgur.com/XHHy5.png

If there is any other way to print the numbers other than printString, more than happy to hear them!

Thanks!

# Answer
There are several issues here. First and foremost, your button is wired incorrectly. If you connect one end of the button to +5V, then the other end should have a pushdown to GND, like here:

(Image from the Arduino Button example).

The second issue is the lack of debouncing. You should ignore the rising edges you sense for a few milliseconds after you record one.

The third issue is the timekeeping. As explained by Sim Son, your seconds will not be very accurate. It's better to just count the milliseconds elapsed since the button press, and then break the count into full seconds and remaining milliseconds.
> 3 votes

---
Tags: arduino-uno, button
---


title: Error message - help needed

text:
# Question
Title: Error message - help needed
As many of you know (if you read my bio or simply read my previous questions), I'm trying to build a rocket. The code was going well, but once I split my objects into 2 files, a `.h` and `.cpp` file, this error message appeared.

The full code is on GitHub because it is simply too long!

Here is the error message :

```
Arduino: 1.8.1 (Windows 7), Board: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpInitialize()'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpPacketAvailable()'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(long*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(int*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(long*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(int*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(long*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(int*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(VectorInt16*, unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetEuler(float*, Quaternion*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpProcessFIFOPacket(unsigned char const*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

(.text+0x0): multiple definition of `MPU6050::dmpGetFIFOPacketSize()'

sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

exit status 1
Error compiling for board Arduino Pro or Pro Mini.

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

```

# Answer
The problem is the way the author of the MPU6050 library wrote MPU6050\_6Axis\_MotionApps20.h is not compatible with the way you're using the library. Multiple proposals for fixing the issue have been submitted but they are all outdated to some extent:

https://github.com/jrowberg/i2cdevlib/pull/174

download at https://github.com/martinjos/i2cdevlib/archive/master.zip

https://github.com/jrowberg/i2cdevlib/pull/162

download at https://github.com/cgel/i2cdevlib/archive/master.zip

https://github.com/jrowberg/i2cdevlib/pull/268

download at https://github.com/onliner10/i2cdevlib/archive/master.zip
> 2 votes

# Answer
This is 3 years way too late, but here's what I did

1. In my own `mpu_sensor.h` file, I only included

```
#ifndef MPU_SENSOR_H
#define MPU_SENSOR_H

#include "MPU6050.h"
#include "helper_3dmath.h"
....
#endif

```

Note that I don't include `MPU6050_6Axis_MotionApps20`, since most datatypes are declared in `MPU6050` and `helper_3dmath`

2. In my `mpu_sensor.cpp` file, here's my includes:

```
#include "MPU6050_6Axis_MotionApps20.h"
#include "mpu_sensor.h"

```

Please note that `MPU6050_6Axis_MotionApps20.h` must be before the line that includes `mpu_sensor.h`.

It works now. I agree that the library itself should be updated, but it seems like the author is not updating for the past few years.
> 3 votes

---
Tags: c++
---


title: Can I use this camera switcher?

text:
# Question
Title: Can I use this camera switcher?
I am wondering can I use this bicks camera switcher with the arduino since it uses a PWM signal.

If i can do I just put it on one of the PWM outputs or do I need to wire I add something to make it work. \**You can find the user manual here under attachments.\**https://store.bicks.us/multiview/20-bicks-s-multiview-duo-fpv-camera-switcher.html

# Answer
The pwm output of an RC receiver is the same signal used to control a servo. So if you used the servo library with Arduino to control the pwm of this device it should work fine.
> 0 votes

---
Tags: pwm, camera
---


title: Air data rate nRF24L01

text:
# Question
Title: Air data rate nRF24L01
I'm using two nRF24L01 to communicate with each other. I did the right setup and they worked fine, however I wanted to change the air data rate to a lower value, for more stability, as the datasheet says.

How can I setup the configuration for this?

After a small research I knew that you can change this using `RF_DR` to change the value of the transmission, but I didn't really know how I could exactly write the correct code for this.

Another question: does this effect the range of the module? Or does it only affect the stability? And if not, then which code can I use to extend the range of these two modules ?

# Answer
> 1 votes
Increasing stability will increase the (usable) range. At least a bit. You could try decreasing the packet size, to make it even more reliable. There is no way to increase the output-power (only decrease).

You could try different channels, and see which one gives you the best range in your application.

After that you have to get NRF24 modules, with external antennas and amplifiers.

# Answer
> 1 votes
According the nRF datasheet if you decrease the data rate it will definitely affect your range.

A lower data rate will increase your stability due to which the nRF can detect weaker signals (-102 dB at 250Kbps) due to this you can significantly increase the range (up to 1km theoretically).

Also if you need to increase your range further you can attach an antenna with a higher gain than what you already have.

No other software changes will affect the range other than reducing the transmission speed.

# Answer
> -1 votes
The documentation for the function you want is here.

Reducing the speed doesn't directly increase the range, but increased stability will have the knock-on effect that the fringes of transmission distance will be more reliable, making it appear that you have slightly greater distance.

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


# Question
Title: Is it possible to upload and run code from EEPROM during boot time?
I am having problems while writing custom bootloader, so that it uploads code from EEPROM (for now internal, as I have no external memory in my hands) and writes into flash. After ~2 weeks of struggling I encountered these question and answers. After that, I realized that I made a mistake not checking the possibility of it. However, I am still confused about several things:

1. If Harvard Architecture limits what I want, how come optiboot can flash the memory from incoming UART data, which is not even a memory?
2. If UART reads and flashes memory accordingly, cant I do the same with EEPROM? Read bytes, erase flash, write bytes.
3. If it is not possible, given two answers in above link, then how does this work? I guess, it is the same logic as I want, using external memory and rewriting flash. Does it mean Harvard Architecture limits only internal memory exchange?

**UPDATE:** Here is what I have done for now:

In separate sketch, EEPROM is filled with binary code. Bootloader (edited optiboot v8):

```
  // Set up watchdog to trigger after desired timeout
  watchdogConfig(WDTPERIOD);
#if BIGBOOT

  if ((eeprom_read(0x000) == 0x0C) && (eeprom_read(0x001) == 0x94))
  {
    //while (EECR & (1 << EEPE)); //wait if previous data is still being written
    uint8_t i, j;

    for (i = 0; i < 8; ++i) // 8 pages total
    {
      uint8_t *code;
      code = buff.bptr;
      address.word = (i * 128);

      for (j = 0; j < 128; ++j)  // 128 words at a time
      {
        if (j % 64 == 0)
          LED_PORT ^= _BV(LED);

        *code++ = eeprom_read(address.word + j);
      }

#ifdef VIRTUAL_BOOT_PARTITION
      virtualBootPartition(buff, address);
#endif

      writebuffer(0x46, buff, address, 128);
    }

    while(1); // wait for WDT
  }
#endif

#if (LED_START_FLASHES > 0) || LED_DATA_FLASH || LED_START_ON
  /* Set LED pin as output */
  LED_DDR |= _BV(LED);
#endif

```

while my function looks like this:

```
#if BIGBOOT
static uint8_t eeprom_read(uint16_t addr)
{
  EEAR = addr; //read from that address
  EECR |= (1 << EERE); //enable reading

  return EEDR;
}
#endif

```

I use `make atmega328 BIGBOOT=1` to generate hex file. It does not work + UART uploading also fails. If I set `BIGBOOT` to 0 and generate, UART uploading works fine.

P.S. `virtualBootPartition` is function which is called in `STK_PROG_PAGE` case. In order to not repeat the same piece of code, I collected that part into the function.

```
#ifdef VIRTUAL_BOOT_PARTITION
/*
 *              How the Virtual Boot Partition works:
 * At the beginning of a normal AVR program are a set of vectors that
 * implement the interrupt mechanism.  Each vector is usually a single
 * instruction that dispatches to the appropriate ISR.
 * The instruction is normally an rjmp (on AVRs with 8k or less of flash)
 * or jmp instruction, and the 0th vector is executed on reset and jumps
 * to the start of the user program:
 * vectors: jmp startup
 *          jmp ISR1
 *          jmp ISR2
 *             :      ;; etc
 *          jmp lastvector
 * To implement the "Virtual Boot Partition", Optiboot detects when the
 * flash page containing the vectors is being programmed, and replaces the
 * startup vector with a jump to te beginning of Optiboot.  Then it saves
 * the applications's startup vector in another (must be unused by the
 * application), and finally programs the page with the changed vectors.
 * Thereafter, on reset, the vector will dispatch to the beginning of
 * Optiboot.  When Optiboot decides that it will run the user application,
 * it fetches the saved start address from the unused vector, and jumps
 * there.
 * The logic is dependent on size of flash, and whether the reset vector is
 * on the same flash page as the saved start address.
 */

#if FLASHEND > 8192
/*
 * AVR with 4-byte ISR Vectors and "jmp"
 * WARNING: this works only up to 128KB flash!
 */
#if FLASHEND > (128*1024)
#error "Can't use VIRTUAL_BOOT_PARTITION with more than 128k of Flash"
#endif
  if (address.word == RSTVEC_ADDRESS) {
    // This is the reset vector page. We need to live-patch the
    // code so the bootloader runs first.
    //
    // Save jmp targets (for "Verify")
    rstVect0_sav = buff.bptr[rstVect0];
    rstVect1_sav = buff.bptr[rstVect1];

        // Add "jump to Optiboot" at RESET vector
        // WARNING: this works as long as 'main' is in first section
    buff.bptr[rstVect0] = ((uint16_t)pre_main) & 0xFF;
    buff.bptr[rstVect1] = ((uint16_t)pre_main) >> 8;

#if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
// the save_vector is not necessarilly on the same flash page as the reset
//  vector.  If it isn't, we've waiting to actually write it.
  }
  else if (address.word == SAVVEC_ADDRESS) {
      // Save old values for Verify
      saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
      saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];

      // Move RESET jmp target to 'save' vector
      buff.bptr[saveVect0 - SAVVEC_ADDRESS] = rstVect0_sav;
      buff.bptr[saveVect1 - SAVVEC_ADDRESS] = rstVect1_sav;
  }
#else
        // Save old values for Verify
        saveVect0_sav = buff.bptr[saveVect0];
    saveVect1_sav = buff.bptr[saveVect1];

        // Move RESET jmp target to 'save' vector
        buff.bptr[saveVect0] = rstVect0_sav;
        buff.bptr[saveVect1] = rstVect1_sav;
}
#endif

#else
/*
 * AVR with 2-byte ISR Vectors and rjmp
 */
  if (address.word == rstVect0) {
    // This is the reset vector page. We need to live-patch
    // the code so the bootloader runs first.
    //
    // Move RESET vector to 'save' vector
      // Save jmp targets (for "Verify")
    rstVect0_sav = buff.bptr[rstVect0];
    rstVect1_sav = buff.bptr[rstVect1];
    addr16_t vect;
    vect.word = ((uint16_t)pre_main-1);
    // Instruction is a relative jump (rjmp), so recalculate.
    // an RJMP instruction is 0b1100xxxx xxxxxxxx, so we should be able to
    // do math on the offsets without masking it off first.
    // Note that rjmp is relative to the already incremented PC, so the
    //  offset is one less than you might expect.
    buff.bptr[0] = vect.bytes[0]; // rjmp to start of bootloader
    buff.bptr[1] = vect.bytes[1] | 0xC0;  // make an "rjmp"
#if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
  }
  else if (address.word == SAVVEC_ADDRESS) {
    addr16_t vect;
    vect.bytes[0] = rstVect0_sav;
    vect.bytes[1] = rstVect1_sav;
    // Save old values for Verify
    saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
    saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];

    vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  // Move RESET jmp target to 'save' vector
  buff.bptr[saveVect0 - SAVVEC_ADDRESS] = vect.bytes[0];
  buff.bptr[saveVect1 - SAVVEC_ADDRESS] = (vect.bytes[1] & 0x0F)| 0xC0;  // make an "rjmp"
  }
#else

  // Save old values for Verify
  saveVect0_sav = buff.bptr[saveVect0];
  saveVect1_sav = buff.bptr[saveVect1];

  vect.bytes[0] = rstVect0_sav;
  vect.bytes[1] = rstVect1_sav;
  vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  // Move RESET jmp target to 'save' vector
  buff.bptr[saveVect0] = vect.bytes[0];
  buff.bptr[saveVect1] = (vect.bytes[1] & 0x0F)| 0xC0;  // make an "rjmp"
  // Add rjmp to bootloader at RESET vector
  vect.word = ((uint16_t)pre_main-1); // (main) is always <= 0x0FFF; no masking needed.
  buff.bptr[0] = vect.bytes[0]; // rjmp 0x1c00 instruction
}

#endif
#endif // FLASHEND
#endif // VBP

```

# Answer
If you have a sketch which can write its updated version into EEPROM of ATmega328p and then boootload from the EEPROM, then you can use the flash for the same purpose. The ATmega328p has 32kB of flash and only 1kB EEPROM.

For my ArduinoOTA library I developed a way to store the uploaded binary in upper half of the flash and then let the bootloader copy the binary to address 0 and reset the MCU.

The Optiboot 8 has do\_spm() function. This function can be called from the sketch to write to flash memory.

To copy the binary stored in upper half of the flash to address 0, I wrote a new function for the Optiboot. It is called copy\_flash\_pages and has an extra boolean parameter to request a reset of MCU after copying the pages.

For network upload the sketch size is larger then half of the flash of 328p because of the networking library. So ArduinoOTA is only for ATmega with more then 64kB flash.

If you have a way how to get the binary of size less then half of the 328p flash, then you can write it to the upper half of the flash and then use my copy\_flash\_pages function to bootload it.

Resources:

* header file to access the Optiboot functions from sketch
* boards definition and bootloader for 328p with Optiboot with copy\_flash\_pages function in my\_boards (note the changed fuses in boards.txt for Uno/Nano/Mini)
* the InternalStorageAVR class in ArduinoOTA library as example how to store and apply the binary

Example of InternalStorage use:

```
  if (!InternalStorage.open(length)) {
    Serial.println("There is not enough space to store the update. Can't continue with update.");
    return;
  }
  byte b;
  while (length > 0) {
    if (!source.readBytes(&b, 1)) // reading a byte with timeout
      break;
    InternalStorage.write(b);
    length--;
  }
  InternalStorage.close();
  if (length > 0) {
    Serial.print("Timeout downloading update file at ");
    Serial.print(length);
    Serial.println(" bytes. Can't continue with update.");
    return;
  }
  Serial.println("Sketch update apply and reset.");
  InternalStorage.apply(); // this doesn't return

```
> 1 votes

---
Tags: atmega328, bootloader, eeprom, flash
---


title: Hc-05 bluetooth module pairing issue

text:
# Question
Title: Hc-05 bluetooth module pairing issue
Module light is blinking/working but it's not showing for pairing in my smart phone.I have supplied it 3.3 volts and have tried different phones.

# Answer
It won't pair directly you will need other apps for pairing the modules. Try using this app. It will solve your issue for sure
> 0 votes

# Answer
I put together a complete tutorial on using the HC-05 in the Arduino environment for remote programming. You can see it here
> 0 votes

---
Tags: arduino-uno, bluetooth, hc-05
---