title: How to simulate Arduino?

text:
# Question
Title: How to simulate Arduino?
QUCS is the only open source software which offers simulation (and designing PCB layout \[in future\]) of electrical circuits. But the problem with QUCS is that it is under development and many important features are not yet available in it.

I want to simulate Arduino Uno board in it for my circuit. Does anyone know how to simulate Arduino or any other micro-controller in it?

**P.S.** Also any other open source software for simulation and PCB designing?

# Answer
> 3 votes
Simulating a microcontroller's program is common, but not as part of a circuit, unless you're into Systems on Chips.

## Model the micro interfaces and simulate the peripherals separately

Analog systems cannot be modelled accurately by hand calculations alone, therefore simulation is often a necessary step (on top of that, real circuits might behave differently from the model). Non-programmable digital systems are deterministic in their behaviour, but only if the interfaces are correct - tight specifications on impedances and such often mean simulation is required here as well. Generally speaking, for both simulation becomes a must when the system is not dead simple. Microcontrollers on the other hand are sufficiently deterministic not to require any simulation: they do what they're told, except in very very very rare cases (single event upsets from radiation for example). Now, what they're told might allow glitches to happen, but that's a different story\*. Therefore, usually the analog, or digital circuits around a microcontroller would be given equivalent interfaces based on the microcontroller's behaviour and physical specifications, and simulated separately.

\*: As the code becomes more and more complex, it gets more and more difficult to follow what the microcontroller might do. Unexpected glitches may arise from e.g. concurrent access (though I can't say this is common in the micro realm), or insufficient resources (that is why dynamic allocation \[malloc,new\] are highly discouraged, so that the resources allocation is known at compilation time) etc. That's usually why tests are required, and step-by-step debugging is used as a means to locate any error that arises. But inherently, microcontrollers are highly predictable and except in certain cases, it is not worth it to go through simulation (do not mix up simulations and tests, tests are always required!).

## Advantages of microcontroller simulators

However, microcontrollers simulators do exist. They are particularly helpful to watch what happens inside the microcontroller when the code executes step by step: call stack, watches on variables, interrupt vectors etc. This can also be done on the actual hardware using in circuit debuggers, but simulators are cheaper and are also good to save on EEPROM erase/write cycles and to avoid damaging your micro if you are afraid that the devices around it might be incorrectly configured (some controllers are very expensive, especially if they are qualified for medical, military or aerospace applications). I have seen such ICD's and simulators for Microchip PICs (MPLABX), but there must be equivalents for AVR (the micro which is on the Arduino's), or perhaps even integrated in an arduino-friendly environment (though I doubt it). You might want to take a look here.

## If you've got deep pockets: mixed signal simulators

Finally, there are mixed signal simulators which allow you to simulate analog, programmable and non-programmable digital circuits alike; one component will have an analog SPICE model, another a VHDL model, and ADC/DAC blocks will be added automatically by the simulator between those devices depending on the logic input/output technology you specify. Those are extremely expensive (the one I used is Cadence Virtuoso), you don't want to do that unless you're doing an integrated circuit or something critical.

P.S: DesignSpark PCB v3 has LTspice in it. Never tried that feature in there though, I used to use LTspice directly.

*Note that your opening "QUCS is the only open source software \[...\]" is wrong. There are plenty of simulators out there which are open source. I agree QUCS is a very user-friendly one though.*

# Answer
> 3 votes
You can use 123d.circuits.io for simulation and PCB design for Arduino circuits.

See this one for example.

More generally, a previous answer states that Microcontroller based circuits are not simulated. Maybe that's true when prototyping costs are low (though I doubt it), but in an SoC or complex embedded system, microcontrollers certainly are simulated as part of the overall system.

Sometimes as a highlevel model such as a symbolic simulator or sometimes as a part of the overall mixed-signal simulation environment in which the digital part is usually simulated at RT level.

# Answer
> 1 votes
See my blog which will explain all steps at http://tutorial4you.weebly.com/blog/arduino-simulation-on-proteus

# Answer
> 1 votes
To add to the list of simulator answers, try out Micro-Cap 12. It was a few thousand dollars originally, but the company has ceased operations now and has provided it for free. Pretty cool.

# Answer
> 1 votes
How to simulate Arduino? What is the best Arduino simulator?

Following are the main features of the wokwi arduino simulator

It is free :)

• Supports multiple file projects

• Supports most of the famous Arduino libraries

• Whatever compiles on the Arduino IDE will compile on the simulator

• Supported by all browsers

• Compiles with latest Arduino IDE

• Supports FastLED and many other peripherals

• No download or installation needed

• Easy to share the code and project with just a single click

• Smart - Code Autocompletion, Code auto-formatting are supported

• Provides standard library demo examples

• Project can be compiled on RUN on Mobile browsers as well

• Tries to be closer to real circuits – Example – Button bounce like in real hardware

• Supports Arduino Mega, Arduino Nano, Arduino UNO, ATtiny85

• Supports assembly instruction execution

• Provides LED power and FPS features for FastLED projects

• Supports a plethora of Arduino peripherals for the project – Ultrasonic sensors, Slide switches, NeoPixel matrix, Potentiometer, Servo motors, SSD1306 OLED displays, temperature and humidity sensors, rotary dialer, membrane keypad and more

• Serial monitor is supported as well

## Website: https://wokwi.com

Here are a few examples

# Answer
> -1 votes
Try this: simulIDE

Google: simulIDE for arduino picture

Supports also: PIC, ATtiny, ATR, Arduino...

---
Tags: simulator
---


# Question
Title: PID control doesn't work. After computing the values, the values just become equal to 0
So, I have a working code of the stabilizer project using 2 servo motors, mpu6050, Arduino Uno. However, I want to add PID part for tuning the servo motors movement. I followed the example PID library and just changed the input as data received from the mpu6050 sensor, and output as the data that we send to servo motor. The problem is after adding the PID part project stopped working properly. Servo motors did not react to the accelerometer movement anymore. I tried printing out the values computed by the PID and all of them turned out to be 0 and they don't change even if I rotate the sensor. Can anyone spot the mistake in the code with PID part? I am pretty sure that the rest works perfectly.

```
/*
                        DIY Gimbal - MPU6050 Arduino Tutorial
                        by Dejan, www.HowToMechatronics.com
                        Code based on the MPU6050_DMP6 example from the i2cdevlib library by Jeff Rowberg:
                        https://github.com/jrowberg/i2cdevlib
*/
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"

#include "MPU6050_6Axis_MotionApps20.h"
//#include "MPU6050.h" // not necessary if using MotionApps include file
#include "PID_v1.h"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
#include <Servo.h>
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 mpu;
//MPU6050 mpu(0x69); // <-- use for AD0 high

double Setpointx, Setpointy, Inputx, Inputy, Outputx, Outputy, pidX, pidY;
double Kp = 2, Ki = 5, Kd = 1;
PID myPID0 (&Inputx, &Outputx, &Setpointx, Kp, Ki, Kd, DIRECT) ;
PID myPID1 (&Inputy, &Outputy, &Setpointy, Kp, Ki, Kd, DIRECT) ;
// Define the 3 servo motors
Servo servo0;
Servo servo1;
Servo servo2;
float correct;
int j = 0;

#define OUTPUT_READABLE_YAWPITCHROLL

#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards

bool blinkState = false;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
  mpuInterrupt = true;
}

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
  // join I2C bus (I2Cdev library doesn't do this automatically)
  Setpointx = 10;
  Setpointy = 10;

  myPID0. SetMode (AUTOMATIC);
  myPID1. SetMode (AUTOMATIC);

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif

  // initialize serial communication
  // (115200 chosen because it is required for Teapot Demo output, but it's
  // really up to you depending on your project)
  Serial.begin(115200);
  while (!Serial); // wait for Leonardo enumeration, others continue immediately

  // initialize device
  //Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  pinMode(INTERRUPT_PIN, INPUT);
  devStatus = mpu.dmpInitialize();
  // supply your own gyro offsets here, scaled for min sensitivity
  mpu.setXGyroOffset(17);
  mpu.setYGyroOffset(-69);
  mpu.setZGyroOffset(27);
  mpu.setZAccelOffset(1551); // 1688 factory default for my test chip

  // make sure it worked (returns 0 if so)
  if (devStatus == 0) {
    // turn on the DMP, now that it's ready
    // Serial.println(F("Enabling DMP..."));
    mpu.setDMPEnabled(true);

    attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    //Serial.println(F("DMP ready! Waiting for first interrupt..."));
    dmpReady = true;

    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    // Serial.print(F("DMP Initialization failed (code "));
    //Serial.print(devStatus);
    //Serial.println(F(")"));
  }

  // Define the pins to which the 3 servo motors are connected
  servo0.attach(10); //Z Axis
  servo1.attach(9); //Y Axis
  servo2.attach(8); //X Axis
  servo1.write(90);
  servo2.write(90);
}
// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {
  // if programming failed, don't try to do anything
  if (!dmpReady) return;

  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt && fifoCount < packetSize) {
    if (mpuInterrupt && fifoCount < packetSize) {
      // try to get out of the infinite loop
      fifoCount = mpu.getFIFOCount();
    }
  }

  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();

  // get current FIFO count
  fifoCount = mpu.getFIFOCount();

  // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
    // reset so we can continue cleanly
    mpu.resetFIFO();
    fifoCount = mpu.getFIFOCount();
    Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
  } else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

    // read a packet from FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);

    // track FIFO count here in case there is > 1 packet available
    // (this lets us immediately read more without waiting for an interrupt)
    fifoCount -= packetSize;

    // Get Yaw, Pitch and Roll values
#ifdef OUTPUT_READABLE_YAWPITCHROLL
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

    // Yaw, Pitch, Roll values - Radians to degrees
    Inputx = ypr[2];
    myPID0.Compute();
    Outputx = pidX;
    Inputy = ypr[1];
    myPID1.Compute();
    Outputy = pidY;
    Serial.print("\nX: ");
    Serial.print(pidX);
    Serial.print("\nY: ");
    Serial.print(pidY);
    ypr[0] = ypr[0] * 180 / M_PI;
    pidX = pidX * 180 / M_PI;
    pidY = pidY * 180 / M_PI;
    // Skip 300 readings (self-calibration process)
    if (j <= 300) {
      correct = ypr[0]; // Yaw starts at random value, so we capture last value after 300 readings
      j++;
    }
    // After 300 readings
    else {
      ypr[0] = ypr[0] - correct; // Set the Yaw to 0 deg - subtract  the last random Yaw value from the currrent value to make the Yaw 0 degrees
      // Map the values of the MPU6050 sensor from -90 to 90 to values suatable for the servo control from 0 to 180
      int servo0Value = map(ypr[0], -90, 90, 0, 180);
      int servo1Value = map(pidY, -90, 90, 0, 180);
      int servo2Value = map(pidX, -90, 90, 180, 0);
      // Control the servos according to the MPU6050 orientation
      servo0.write(90);
      servo1.write(servo1Value);
      servo2.write(servo2Value);
    }
#endif
  }
}

```

# Answer
You seem to have some misconceptions about PID. For explaining I will use a different use case of a PID control, which is easier to understand (and also mentioned in the documentation of the PID library):

A PID control can be used in any feedback loop system with consistent feedback. When you drive your car you want it to reach a specific speed. For that you press the gas pedal, changing its angle until you reach the target speed. In this scenario you are doing the PID control. The setpoint is the target speed, the input is the actual current speed and the output is the angle of the gas pedal.

You see: Output and input/setpoint don't have the same unit. They are completely different measurements of different things. They are only connected via the feedback loop in the system, meaning that increasing the gas pedal angle will increase the speed of the car. The PID control is then just a formula which involves the actual speed, the desired speed and some scaling variables (Kp, Ki, Kd)(to tune the behavior of the control). And the output of the formula is then the needed gas pedal angle at that time.

**So what does this mean for you?**

* You don't need to convert the output value into an angle. The unit of the output is not important, since the PID will control itself to get to the setpoint. It is more important to tune the PID through Kp, Ki and Kd to get the PID to behave correctly in your system.
* The workflow looks like this:

1. Set the setpoint variable `Setpointx` to the wanted input value.
    2. Read the input from the MPU and save it to `Inputx`
    3. Call `myPID0.Compute();` to compute the output from setpoint and input.
    4. Read the value from `Outputx` and write it to your servo. The servo movement will then cause a change in the read input in the next loop.
    5. repeat from step 2
* As I currently don't really understand your feedback loop system: Make sure, that the feedback loop is working correctly. An increase in the output should lead to an increase in the input. Make sure it is consistent. Your input value should not have too much noise (or the PID will react to that noise). For testing you might want to tune Kp, Ki and Kd down so that the PID works slower. Then you can see the behavior better. Make sure, that both PID controls aren't influencing each other. They need to be independent.
* Use `myPID0.Compute();` every time you write a new value to your servo and only then. Calling it in between will be just a waste. So it makes sense to use that line somewhere directly before writing to the servo.

---

If it still not works, then you should have a detailed look at the read values and how they relate to the servo angle. Are the requirements above met? Are they stable enough. Is the feedback loop as expected? What does changing Kp, Kd and Ki change in the outcome?
> 1 votes

# Answer
This chunk of code is feeding radians into the PID algorithm, and then discarding/overwriting the output with the initialized-to-zero pidX and pidY values.

```
...
Inputx = ypr[2];
myPID0.Compute();
Outputx = pidX;
Inputy = ypr[1];
myPID1.Compute();
Outputy = pidY;
...

```

I'd set the output limits to match the device under control:

```
void setup() {
   // join I2C bus (I2Cdev library doesn't do this automatically)
   Setpointx = 10;  // MPU degrees
   Setpointy = 10;  // MPU degrees

   myPID0. SetMode (AUTOMATIC);
   myPID1. SetMode (AUTOMATIC);
   myPID0.SetOutputLimits(0,180); // servo degrees
   myPID1.SetOutputLimits(0,180); // servo degrees
   ...

```

...and then convert the inputs to match the setpoints, and feed the constrained PID outputs directly to the controls:

```
Inputx = ypr[2]*180.0/M_PI;
myPID0.Compute();
pid_X = Outputx;
Inputy = ypr[1]*180/M_PI;
myPID1.Compute();
pidY = Outputy;
...
servo1.write(Outputx);
servo2.write(Outputy);
...

```

It is important to use the `PID.SetOutputLimits(min,max)` so that the PID routine can internally ensure that the outputs don't wander deep into infeasible control regimes. If you don't call SetOutputLimits(), the default output constraints are 0-255, which would not make sense for a 0-180 servo.

One way to think of your PID constants `Kp = 2, Ki = 5, Kd = 1;` is how big an output unit change (degrees of servo setting) you want to make for a unit of input (MPU radians or degrees?) error, integrated error (error\*seconds/5 per https://playground.arduino.cc/Code/PIDLibrarySetSampleTime/), or delta error. They might need adjusting if the system isn't responding as you like.
> 0 votes

---
Tags: servo, accelerometer, pid
---


# Question
Title: how to put whitespace in long Serial println() input
I have this long, Serial.println() that is in quotes, on multiple lines. Arduino IDE warns: "Missing terminating character". I am certain there is a way to break the lines up, while having the entire text enclosed in quotes, but I don't remember how.

```
Serial.println("
<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
<svg
   xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
    xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"
   id=\"svg8\" version=\"1.1\" viewBox=\"0 0 227.35277 156.29323\"
   height=\"6.1532764in\"
   width=\"8.9508963in\"
   sodipodi:docname=\"etchasketchborder.svg\">
    <defs
     id=\"defs2\" />
  <path
     style=\"fill:#ff0000;stroke:#ff0000;stroke-width:1.32300019;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\"
     d=\"m 12.000819,0.66145838 c -6.2819637,0 -11.33936062,5.05739692 -11.33936062,11.33936062 V 144.29249 c 0,6.28197 5.05739692,11.33936 11.33936062,11.33936 H 215.35224 c 6.28197,0 11.33885,-5.05739 11.33885,-11.33936 V 12.000819 c 0,-6.2819637 -5.05688,-11.33936062 -11.33885,-11.33936062 z M 18.932696,12.696383 H 205.5854 c 5.02557,0 9.07128,4.04571 9.07128,9.071282 v 77.03923 c 0,5.025575 -4.04571,9.071285 -9.07128,9.071285 H 18.932696 c -5.025572,0 -9.0712819,-4.04571 -9.0712819,-9.071285 v -77.03923 c 0,-5.025572 4.0457099,-9.071282 9.0712819,-9.071282 z\"
    />
  <ellipse
     style=\"fill:#ffffff;fill-opacity:1;stroke:#ff0000;stroke-width:1.32300007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\"
     cx=\"21.16666\"
     cy=\"130.59085\"
     rx=\"10.583334\"
     ry=\"9.0714283\" />
  <ellipse
     style=\"fill:#ffffff;fill-opacity:1;stroke:#ff0000;stroke-width:1.32300007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\"
     cx=\"200.62982\"
     cy=\"131.57361\"
     rx=\"10.583334\"
     ry=\"9.0714283\" />
      </svg>
");

```

# Answer
Ah, I figured it out. you cant do this:

```
Serial.println("foo
                                bar");

```

but you can do this:

```
Serial.println("Foo"
                "Bar");

```

So then in bash I write a little command, to take my svg files, and escape the quotes that exist in the file, then another line to add quotes at the start and end of every newline. then I can just copy paste my svg images into the println() function.

```
$ sed -i 's/"/\\"/g' input.svg

```

and

```
$ xargs -I{lin} echo \"{lin}\" <input.svg

```

respectively.
> 2 votes

---
Tags: programming, arduino-ide, c++
---


# Question
Title: ESP32 in Arduino-IDE with FS.h and SPIFFS
I'm working on a webserver on ESP32 in Arduino IDE and would like to load an html-file. Tried to use SPIFFS.open from the library FS.h from github. Errormessage says SPIFFS was not declared in this scope. (As far as I can see, there's no bracket in the wrong place.)

I did not find any example for ESP32 and FS.h and desperately hope for some help. Thanks in advance.

Here is my code:

    #include "FS.h"
    #include "WiFi.h"

/*Wifi Access data*/
const char* ssid_ap = "AccessPoint";
const char* password_ap = "12345678";

const char * ssid_sta     = "";
const char * password_sta = "";

/* set global variables */
byte WiFiMode = 0;  // WIFI_STA = 1 = Workstation  WIFI_AP = 2  = Accesspoint
int request_counter;
String sHTML;
String sHTMLRequest;

/* Create instance of server on Port 80 */
WiFiServer server(80);
WiFiClient client;

/*
 * ******SETUP*******************************************************
 */
void setup() {

/*initialize GPIO*/

/*start serial communication */
  Serial.begin(115200);
  SPIFFS.format();
  Serial.println("Spiffs formatted");

/* start WiFi as workstation (STA), if not possible
   start as Acess Point
   initialize server */
  WiFi_Start_STA();
  if (WiFiMode == 0) WiFi_Start_AP();
}

/*
 * **LOOP*************************************************************
 */
void loop() {

/* Check if a client has connected */
  client = server.available();
  if (!client)
  {
    return;
  }

/*Wait for the client to send data */
  Serial.println("neuer Client verbunden");
  /*Count Aufruf der Seite: */
  request_counter ++;
  unsigned long clTimeout = millis()+250;
  while(!client.available() && (millis()clTimeout)
  {
    Serial.println("time-out bei Client-Verbindung!");
    return;
  }

/****** open html files  *******/
 SPIFFS.begin();
 File f = SPIFFS.open("/home.txt", "r");
    if (!f) {
    Serial.println("file open failed");
    }
    f.close();

}

/**********************************************************************
 *
 **************** FUNCTIONS ********************************************
 *

---

*/

/*
 * Fct tries to start WiFi in workstation mode,
 * if not possible sets WiFiMode=AP
 * starts server
 */
void WiFi_Start_STA() {
  unsigned long timeout;

WiFi.mode(WIFI_STA);   //  Try to start WiFi as Workstation

WiFi.begin(ssid_sta, password_sta);
  timeout = millis() + 12000L;
  while (WiFi.status() != WL_CONNECTED && millis() < timeout) {
  delay(10);
  }

if (WiFi.status() == WL_CONNECTED) {
    server.begin();
    WiFiMode = WIFI_STA;

Serial.print("Verbunden mit IP - Addresse: ");
    for (int i = 0; i < 3; i++) {
      Serial.print( WiFi.localIP()[i]);
      Serial.print(".");
    }
    Serial.println(WiFi.localIP()[3]);

}
  else {
    WiFi.mode(WIFI_OFF);

```
Serial.println("WLAN-Verbindungsaufbau fehlgeschlagen");
}

```

}

/*
 *starts WiFi in AP-mode
 *starts server
 */
void WiFi_Start_AP() {
  WiFi.mode(WIFI_AP);   // Access Point mode
  WiFi.softAP(ssid_ap, password_ap);
  server.begin();       // start server
  IPAddress ApIP = WiFi.softAPIP();   //read IP of Access Point
  WiFiMode = WIFI_AP;

Serial.print("ESP-Netzwerk: ");
  Serial.print(ssid_ap);
  Serial.print(" aufgebaut. ");
  Serial.print( " IP-Addresse: ");
  Serial.println(ApIP);
}

# Answer
The answer is belated but since the question is still open...

The code does not include spiffs library. The line below should fix the problem.Note it should be below the the include statement for FS

```
include <SPIFFS.h>

```

So the code should look like

```
#include "FS.h"
#include "WiFi.h"
#include "SPIFFS.h"

```
> 1 votes

---
Tags: arduino-ide, web-server, esp32
---


# Question
Title: Can pin mode damage Arduino with connected electronics?
I am not that experienced with electronics, so this might be a silly question. But I dont know. Assume that I have connected some electronic circuit (transistors, leds, anything else) to the Arduino pins, is there any chance that I damage the hardware if I change the pinmode to input? What role do the integrated pullup/pulldown resistors play? Basically, is it possible to create some "unintended" flow of current, that damages the board or external hardware, if I change the pinmode or disable/enable the pullup/pulldown resistors (or something else that I dont know about)? Can I break the hardware by programming mistakes?

# Answer
You are coming with some good questions about a complicated subject. You will be going through a learning process. If you do not violate the design parameters of the micro (voltage and current to name a few) you normally will not damage it. Knowing all of those parameters and what the circuirity surrounding the micro has a huge impact on your what can damage your micro and design. Without a schematic, this will change with each circuit and integration, it is impossible to give a definitive answer but I will take a SWAG.

Question: "is there any chance that I damage the hardware if I change the pinmode to input?" and it depends on what mode the pin is in before you change it and what is connected to the pin. Generally you will not damage it assuming your voltages are equal to or less then the voltage supplying the microprocessor and the pin is not connected to an inductive component. You can get changes in your external hardware.

You ask "Can I break the hardware by programming mistakes?". Again I cannot give a definitive answer unless the circuit and what is connected is known. LEDs etc are generally no problem. If in doubt place a resistor in series with the load, something in the range of 330 to 500 ohms and see what happens. If you turn on some external device that damages stuff that is one possibility.

You ask: "if I change the pinmode or disable/enable the pullup/pulldown resistors..."Probably not but it depends on what is connected to the pins. Generally if the pull up resistors are needed such as for a button turning them off will cause some intermittent problems where it is on then off but that will not damage the micro, the effect on external devices is unknown as are the devices.

This stuff is not going to be assimilated in a few days but over a much longer period. There is always more then one way to do a project, the best is probably what you decide. You will make mistooks, and possibly destroy some of your Arduinos, this is to be expected, that is why I have spares. The most important part of the process is to enjoy and have fun.
> 1 votes

---
Tags: pins, hardware, electronics, pinmode
---


title: Can a power cut damage the software?

text:
# Question
Title: Can a power cut damage the software?
When unplugging the power source of a device that is writing some data "A" to an SD card, also other data "B" might get corrupted. (This is detailed here.)

Regarding Arduino projects *without* an SD card, is it OK to remove the power source of Arduino microcontrollers anytime because the memory inside them uses a different technology than SD cards do (what are the names or differences of the respective technologies)?

Or are there several entirely independent memories - one for data and one for software/sketches?

Or do Arduino projects have to be programmed such that there are periods without data-writing and an LED indicates when it is safe to cut off the power?

# Answer
> 2 votes
First we need to look at the different memory technologies in a microcontroller:

* First you have the flash memory. This is where the program is saved, but it can also be used to hold user data. On AVR based Arduinos it can only be written while programming or by the bootloader. But boards like the various ESPs can also have a little file system in it. Here you can get problems with a power loss while write operations happen.
* The RAM holds the current value of all variables. But it also always looses all data when unpowered. This is normal behavior because it is volatile memory. A power loss won't change anything here.
* That leaves us with EEPROM, a non-volatile memory type. You can corrupt your data with a power loss during write operations.

Then we need to look at the data structures. Most memory in Arduinos and similar boards a organized as a simple array of bytes. EEPROM is usually handled this way. If you write a data structure and have a power loss during that time, you must view this data structure as corrupt (for example writing a string with 20 characters, but while writing the 6th byte the power goes out). Other data is not harmed. On the other hand when you use a filesystem in flash like SPIFFS a write action in a file also involves handling a filesystem table. Outage during handling of the table might corrupt your filesystem integrity, thus can also harm other files.

SD cards are a special case, since their internal controllers move the data around to some unknown algorithm to implement wear leveling. This is not done with standard microcontrollers (you would need to implement it yourself if needed). The actual memory technology is also just flash, but you don't want to disturb the SD card while its handling its wear level algorithmus. That might corrupt the SD card completely. Also the linked answer talks about the SD card of a Raspberry Pi, which has a complete OS running on it. Running an OS involves way more changing non-volatile data than a microcontroller typically needs. So its way less likely to have the same situations with a microcontroller.

> Or do Arduino projects have to be programmed such that there are periods without data-writing and an LED indicates when it is safe to cut off the power?

Normally that is not needed, though it depends on your application and how the sketch handles the data. Are you saving data to non-volatile memory? How often do you do it? How often do you cut the power? If you are writing to byteswise memory like EEPROM, can you tolerate specific data corruptions? How much data are you writing each time?

Without assessing all these questions you cannot really say. Typically beginners just start without precaution in that direction. When you see problems after replugging, then you still can add an activity LED to the project.

---
Tags: power, memory
---


title: Connecting a servo motor to an Arduino

text:
# Question
Title: Connecting a servo motor to an Arduino
I currently have a push solenoid connected to my standard Arduino board. The Arduino is powered via its USB cable, while the solenoid is powered using a 12V Huawei adapter (in conjunction with a MOSFET driver module).

How can I switch out the push solenoid for a servo motor? The operational voltage of the servo is 4.8 to 7.2V (with a stall torque of 13 kg-cm) to give you an idea of its size. I have been told to buy a DC-DC step-down module (to adjust the Huawei supply from 12V down to 5V) but I think it could be easier to power the servo using some sort of USB?

Or other suggestions are welcome. I want the easiest solution (since I am NOT tech savvy) and I can't buy parts until I am for certain the solution will work (that's research for you). Thanks!

# Answer
You will have to check in the servos datasheet for the maximal current, that it draws (motors draw more current, when inhibited by mechanical force, so be sure to get the maximal current from the datasheet). From the data, that you gave us, I think it will draw rather much current. So you should not power it over the USB port of your PC (which gives 500mA at maximum). Also you should not use the 5V pin of your Arduino, or you may fry components like the diode, that lies in the current path from USB to 5V pin.

For your step down module, you will also have to check, if it can provide the current, that the servo needs, or you may kill it. If you want to use USB, you can use a standard USB charger or powerbank. Often these can provide more than 1A (depending on the actual product). Most USB wallwart chargers have a current specification on them. But (as said earlier) don't provide the power through the Arduino. Provide it directly from the source, so that the possibly high current for the servo does not have to pass trough the Arduino. You can also power the Arduino with the same source in parallel to the servo, so that you don't need two sources or a converter.

For more info, you will have to provide more information about the servo
> 1 votes

# Answer
I don't know if i understand your question properly, but if you want to connect the servo to the Arduino try connecting it to the 5v Output of your board.
> 0 votes

# Answer
Getting a DC-DC step down converter would definitely work and would be a good way to do it. However,realistically you will be fine if you connect the servo to +5V from USB, since you said it only draws absolute max of 1.2A. Almost all USB ports can handle that.
> -1 votes

---
Tags: motor, servo
---


# Question
Title: How to turn I2C Sensors on and off with an Arduino Mega 2560?
I want to **turn on and off** I2C Sensors with the Arduino Mega 2560.

---

I use one max. 0.4A NPN Transistor, which controls the Vcc line to the sensor.

When I plug my Arduino into my laptop and the sketch begins working everything is fine. The sensor is turned on and is working.

**But when I set the Transistor Base to Low and cut the Vcc the sensor acts weird. The LED on the sensor breakout board shines very weak. So the sensor/breakout board is getting electricity from somewhere else; probably from the I2C connections.**

---

Same results with this small experiment:

1. Breakout board directly connected to the Arduino (without Transistor)
2. Vcc-3.3V pin wire disconnected from the Arduino female pin

---

How can i properly turn on and off an I2C sensor with an Arduino?

Do I have to use additional transistors for every I2C line? Are better circuit solutions available or maybe a software solution?

How should I design my circuit and my software if I have multiple I2C sensors connected to my Arduino and I want to use them independently from each other?

---

Used hardware: Arduino Mega, Sensor Breakout Board

---

Software excerpt for power control:

```
void setup() {

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

    ...

    delay(10000);
    digitalWrite(7, LOW);

    ...
}

```

# Answer
The SDA and SCL pins have pull up resistors on them. So their voltage is 5V. By disconnecting Vcc on the sensor you are running the sensor out of spec. since the voltage on the SDA and SCL pins exceed Vcc.

Most chips have clamping diodes. So the chip is clamping the 5V on the I2C pins to Vcc. So you are powering the chip through the pull-up resistors on the I2C pins.

This would explain why the power led is lit, but not as bright.
> 2 votes

# Answer
if your sensor does not consume more that 20ma, you can power it's GROUND pin with an arduino pin by using pinMode(sensor, OUTPUT), analogWrite(sensor, 255) : at that stage no power flows to the sensor since all its pins are high. When you want to power back the sensor, you need to lower the value of "255" to 0 , if your sensor uses 5v or to around 40 , if your sensor uses 3.3v. I have been using this system for a while without any problem. You might need a small delay(50), to give time for the sensor to power up.
> -1 votes

---
Tags: sensors, power, i2c, transistor
---


# Question
Title: Where does the 5v Output power on the Arduino uno come from?
I am wondering where the extra 5v output power on the Arduino uno come from. Is it directly from the atmega328 microcontroller or from the external power source (usb or 9v battery). Thanks.

# Answer
If you are connected to USB then it comes direct from the USB port's 5V.

If you have an external power supply connected (either to the barrel jack or to the VIN pin) then it comes from the onboard 5V regulator.

The only thing that ever comes from the ATMega chip is digital signals.
> 2 votes

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


# Question
Title: Is there any way to download a sketch from an Arduino?
I made a sketch, but then I lost it. However, I uploaded it to the Arduino before losing it. Is there any way I can get it back?

# Answer
It should be possible as long as the security bit isn't set. This question was asked on EE a while back.

Is it possible to extract code from an arduino board?

But you won't get the Arduino code you wrote back. The code is compiled into assembly and you'll have to convert that back to C yourself.
> 43 votes

# Answer
This answer doesn't directly answer the question, but still will result in the same end result.

The Arduino IDE uses temporary directories to store build files, including the original sketch as well as the HEX and intermediate files.

On a Mac, these are in /var/folders by default, and on a Windows machine they are in …\Local Settings\Temp\ (which depending on the version of Windows could be in several places).

I've found that especially in Windows, these build files don't get deleted when you close the sketch or IDE, so they may exist on your machine for far longer than you would think.

Also, by default, Crashplan, Backblaze and Time Machine back-up these locations, so even if they have been deleted, they may still be in a backup.

The advantage here is that you will recover C code rather than ASM.
> 26 votes

# Answer
You can download the hex dump of the file, but there is no easy way to get all the C++ code and comments. If you can understand assembly, you could recreate the program, but that would take a while. There are dissasemblers available for some devices, i don't know about arduino.
> 6 votes

# Answer
I think there is another way to do this, without extracting the code from the Arduino board. Remenber the date you create the sketch, and look for it in C:\Users\User\AppData\Local\Temp\ (For example : C:\Users\User\AppData\Local\Temp\untitled4390292704786567977.tmp\sketch\_jan19a ). You could find your unsaved code unless it was deleted by some "freeing space program". Good luck!
> 6 votes

# Answer
Unless your objective is to simply copy the identical code to another device, the simple answer is: **no**

As has been pointed out in other answers, you can turn the hex code on the device back into assembler code.

For example (once you have copied the code from the device back onto your disk):

```
avr-objdump -j .sec1 -d -m avr5 yourFileHere.hex

```

Run on one of the bootloader files I get these results (in part):

```
00007e00 <.sec1>:
    7e00:       11 24           eor     r1, r1
    7e02:       84 b7           in      r24, 0x34       ; 52
    7e04:       14 be           out     0x34, r1        ; 52
    7e06:       81 ff           sbrs    r24, 1
    7e08:       f0 d0           rcall   .+480           ;  0x7fea
    7e0a:       85 e0           ldi     r24, 0x05       ; 5
    7e0c:       80 93 81 00     sts     0x0081, r24
    7e10:       82 e0           ldi     r24, 0x02       ; 2
    7e12:       80 93 c0 00     sts     0x00C0, r24
    7e16:       88 e1           ldi     r24, 0x18       ; 24
    7e18:       80 93 c1 00     sts     0x00C1, r24
    7e1c:       86 e0           ldi     r24, 0x06       ; 6
    7e1e:       80 93 c2 00     sts     0x00C2, r24
    7e22:       80 e1           ldi     r24, 0x10       ; 16
    7e24:       80 93 c4 00     sts     0x00C4, r24
    7e28:       8e e0           ldi     r24, 0x0E       ; 14
    7e2a:       c9 d0           rcall   .+402           ;  0x7fbe
    7e2c:       25 9a           sbi     0x04, 5 ; 4

```

As you can see, not particularly helpful for reproducing what your sketch did. There are likely to be one of two scenarios:

* Your sketch was short, in which case you might, after weeks of work, turn the assembler code back into C
* Your sketch was long, in which case it would be virtually impossible to turn it back into C

In the "short sketch" case, you are better off just rewriting from scratch. That would be faster, almost certainly. In the "long sketch" case - it just isn't worth it. None of the variable names are preserved, and the way the compiler optimizes code, even the structure of the code would be hard to determine.
> 6 votes

# Answer
**Download**:

```
avrdude \
    -c <programmer type> \
    -P <connection port> \
    -b <override RS-232 baudrate> \
    -p <partno, AVR device> \
    -U <memtype>:r:file_name[:format]

```

**Upload**:

Use `w` (write) instead of `r` (read) for the `-U` option.

More details at manual - avrdude Option-Descriptions.

---

**Example**:

Download UNO v3 (ATmega328) flash ROM (bootloader) given port `/dev/ttyACM0` as Intel HEX:

```
avrdude -c arduino -P /dev/ttyACM0 -b 115200 -p m328p -U flash:r:SaveFlash.hex:i

```

---

If used directly from from the arduino IDE archive also add:

```
-C path-to/arduino-V/hardware/tools/avr/etc/avrdude.conf

```
> 3 votes

# Answer
Another approach might be to treat the program onboard the Arduino as a black-box exercise. That is, run the program and take careful notes of what happens (via Serial Monitor or whatever). If, in fact there is any output that you can observe, make it a task to create your own new code to emulate what the program DOES. This won't be productive unless the original programmer liberally included Serial.print() statements throughout the code, something I STRONGLY RECOMMEND as a programming habit to develop. Doing so, facilitates just the exercise I am suggesting. (Ask me why I developed that habit for everything I have coded for the past 30 years.)

Unfortunately, most people sprinkle a few comments here and there, which is helpful 5 years later if you have the source code. Personally, I comment EVERY LINE of source code. But comments in the source don't help later in this sort of situation, as the compiler doesn't put them in the machine code it generates. (Perhaps that might be a valuable option for the compiler. Yes, it takes bytes, but how valuable might it be years later for an important project?)

My two cents worth, which probably is worth the price the reader of this post paid to see it!
> 0 votes

---
Tags: sketch
---


title: How to use ESP-01 GPIOs for input?

text:
# Question
Title: How to use ESP-01 GPIOs for input?
I'm trying to use one of ESP-01 GPIOs as an input, however, I'm always reading 1 and nothing attached to these pins.

Basically, I'm trying to detect high voltage from another sensor like a touch sensor or infrared to do some stuff (initial state will be low, so boot won't be affected).

**So what I'm supposed to do to read the actual value 0?**

Here is the code I'm running:

```
#define PIN0 0
#define PIN2 2
#define PIN3 3 // Using RX as GPIO

void setup() {
  Serial.begin(115200,SERIAL_8N1,SERIAL_TX_ONLY);
  pinMode(PIN0, INPUT);
  pinMode(PIN2, OUTPUT);
  pinMode(PIN3, INPUT);
  digitalWrite(PIN2, HIGH);
  digitalWrite(PIN0, LOW);
  digitalWrite(PIN3, LOW);
}

void loop() {
  Serial.print("PIN0: ");  Serial.print(digitalRead(PIN0));  Serial.print("\t");
  Serial.print("PIN2: ");  Serial.print(digitalRead(PIN2));  Serial.print("\t");
  Serial.print("PINRX: ");  Serial.print(digitalRead(PIN3));  Serial.println("");

  delay(500);
}

```

Here is the Serial Reading:

```
PIN0: 1 PIN2: 1 PINRX: 1
PIN0: 1 PIN2: 1 PINRX: 1
PIN0: 1 PIN2: 1 PINRX: 1
PIN0: 1 PIN2: 1 PINRX: 1

```

# Answer
You are writing `0` to an input pin. From the Arduino reference:

"If the pin is configured as an INPUT, digitalWrite() will enable (HIGH) or disable (LOW) the internal pullup on the input pin. It is recommended to set the `pinMode()` to INPUT\_PULLUP to enable the internal pull-up resistor."

Also, when you leave an input pin floating, ie. don't connect anything to it, and also don't enable (or explicitly disable) the internal pull-up or connect an external pull-up, the input pin can show `1`, or it could show `0`.

TL;DR: You shouldn't leave the input pins floating; floating pins are susceptible to electrical noise and can show anything or even fluctuate. If you want them to show `0` when nothing is connected, add an external pull-down resistor.
> 2 votes

---
Tags: esp8266, pins
---


title: Arduino uno spi sck not working

text:
# Question
Title: Arduino uno spi sck not working
I am trying to verify sck output on my arduino uno. I don't have oscilloscope so I loopbacked miso to sck and tried Executing int rx0=SPI.transfer(5) while printing this using Serial.printrx0) it is giving 255.Whether this is expected output?

# Answer
> 3 votes
As suggested by KIIV and myself, you can test the SPI port by:

* connecting MOSI to MISO and checking if you receive what you send
* connecting SCK to the timer input T1 and counting the clock pulses.

Below is a sketch that performs both tests:

```
/*
 * Test the SPI port.
 *
 * Connect:
 *   MOSI (11) to MISO (12)
 *   SCK (13) to T1 (5)
 */

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

    // Configure SPI port.
    DDRB |= _BV(PB2)   // SS (digital 10) as output
          | _BV(PB3)   // MOSI (digital 11) as output
          | _BV(PB5);  // SCK (digital 13) as output
    SPCR = _BV(SPE)    // enable port
         | _BV(MSTR);  // master mode

    // Configure Timer 1.
    TCCR1A = 0;          // normal mode
    TCCR1B = _BV(CS10)   // count rising edges of T1 = digital 3
           | _BV(CS11)   // ditto
           | _BV(CS12);  // ditto
}

void loop() {
    TCNT1 = 0;  // clear timer
    uint8_t data = random(256);
    Serial.print(data);
    Serial.print(" -> ");
    SPDR = data;  // send
    delay(1);
    if (bit_is_set(SPSR, SPIF)) {  // transfer complete?
        Serial.println(SPDR);
    } else {
        Serial.println("nothing received");
    }
    Serial.print("    clock pulses: ");
    Serial.println(TCNT1);
    delay(1000);
}

```

It should print:

```
167 -> 167
    clock pulses: 8
241 -> 241
    clock pulses: 8
217 -> 217
    clock pulses: 8
[...]

```

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


# Question
Title: Failed to boot VL53L0X: VL53L0X Error: -6
I am using a VL53L0X sensor in my project. It was working fine when suddenly it started to show failed to boot error. I tried debugging but of no use. I ran I2C scanner sketch and it detected the sensor at 0x29.

I get the following error -

```
23:38:27.797 -> Adafruit VL53L0X test
23:38:27.830 -> VL53L0X Info:
23:38:27.830 -> Device Name: VL53L0X ES1 or later, Type: VL53L0X, ID: VL53L0CBV0DH/1$1
23:38:27.830 -> Rev Major: 1, Minor: 1
23:38:27.864 -> VL53L0X: StaticInit
23:38:27.932 -> VL53L0X: PerformRefSpadManagement
23:38:27.932 -> refSpadCount = 2226323456, isApertureSpads = 92
23:38:27.932 -> VL53L0X Error: -6
23:38:27.932 -> Failed to boot VL53L0X

```

This is the code I used (its the example code with just 0x29 and true passed in begin function for verbose output):

```
#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

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

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(1);
  }

  Serial.println("Adafruit VL53L0X test");
  if (!lox.begin(0x29,true)) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }
  // power
  Serial.println(F("VL53L0X API Simple Ranging example\n\n"));
}

void loop() {
  VL53L0X_RangingMeasurementData_t measure;

  Serial.print("Reading a measurement... ");
  lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!

  if (measure.RangeStatus != 4) {  // phase failures have incorrect data
    Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println(" out of range ");
  }

  delay(100);
}

```

I am using an Arduino nano - following are the connections

ARDUINO-\>VL53L0X
3v3-\>Vin
GND-\>GND
A4-\>SDA
A5-\>SCL

I have rechecked the connection and voltages the sensor does receive 3v3 and gnd.

I need help with this asap.

Thanks in advance :)

# Answer
I was facing same issue, now my problem is solved here.

This problem mostly occurs when we apply a power supply to the MCU that has capacitors at its output. This type of power supply's rising voltage is like you can see the image:

If you look at the data sheets of MCUs, you see that most MCUs can work at 1.8V to 5.5V. Here the rising voltage is slow; the MCU starts working at 1.8V and send signals to VL53L0x, but the sensor doesn't work at 1.8V.

So, what you need to do is add some delay (first power supply gets stable then start communication with sensor) in your code to avoid this issue. Do not add delay in the loop; it will affect the working of the MCU, where exactly you need to add delay. Code modifications are in the video below:

https://youtu.be/QEiNbTB8nNE

or you just can search on Youtube: How to fix VL53L0X error
> 1 votes

# Answer
From the VL53L0X API documentation The error shows up as

```
#define VL53L0X_ERROR_RANGE_ERROR   ((VL53L0X_Error) -6)

```

Not very helpful, but maybe you still have the factory protective cover installed?

Also, IMHO the Adafruit library is a bit buggy. I now use the Pololu library (among other things, the Pololu library allows usage of the WIRE1, WIRE2, & WIRE3 hardware I2C busses.

27 September 2020 Update: On the Adafruit technical support forum, I did a search for 'VL53L0X ERROR'. There were several thread mentioning ERROR -6 issues, but most of them were due to poor or missing solder on the VL53L0X header pins. Could that be your problem?
> 0 votes

# Answer
Since it sort of worked before I am assuming it is connected correctly. However you failed to mention pull up resistors on the I2C bus. If they are not there or to weak that could cause what you are seeing.
> 0 votes

# Answer
I found a new possible solution to this problem, as I spent 2 days to solve it, I feel that I need to share it with you guys. I also could find the sensor through i2C scanner, but could not initialize it.

Here is the summary of solutions:

1. *Powering problem 1*: **add a 50ms delay in the setup function** (before the sensor init, obviously). This way, the Vin will have time enough to reach the level needed by the sensor, as explained in a previous message (ocrdu)
2. *Powering problem 2*: This sensor demands more than others, normally the **5V pin of your board will do it better than the 3v3**. If there are many sensors connected at the same time, **disconnect all of them to check whether they are using the power our vl53l0x needs**.
3. *Powering problem 3*: If you feed it with an external source, **unify grounds with the board**, don't forget it
4. *SCL - SDA weak signals*: **add a pullup (2k2 - 4k7 from each channel to vin)**, this way the signals will perform better, that could be the problem
5. *Soldering problem*: **Make sure that each header pin is well soldered**. I've found many cases of poor soldering. The tiny pads don't help. It is advisable to check continuity with a multimeter between the headers and the pads where they should be connected
6. *XSHUT not pulled up*: My problem, this was that AZDelivery board says that it has a pull up in XSHUT (which works like an enable). But it could either be false, or badly implemented. **Xshut needs to be high, 3v3/5v**, otherwise, the sensor won't work. Bridge the XSHUT to Vin or implement a pull up and the problem will be solved.

* **I am using adafruit's library 1.1.2, and it works, with pullups, without pullups, connected to 5V and also connected to 3V3, with the 50ms delay, and connecting XSHUT to high (3V3 / Vin)**
* **My board is vl53l0x from AZDelivery (5€ amazon)**
* **I have tested the sensor with arduino nano and with ESP32, both work fine**

Hope you guys find this useful \<3

\[esp32\] \[sensor\] \[i2c\] \[boot\] \[error\]
> 0 votes

---
Tags: arduino-nano
---


title: Observing USB Gamepad with Arduino?

text:
# Question
Title: Observing USB Gamepad with Arduino?
I have a gamepad which I want to treat as a sensor for my Arduino board. I want Arduino to trigger a certain action based on button pushes from the gamepad. Different buttons, different actions.

The gamepad comes with a USB connector. I cut the the USB cable open, solder it with pluggable pins which are then connected to a breadboard. I supply the gamepad with 5V power from Arduino and connect the USB's Data+ to Arduino's analog input pin (A0). Please check the images below.

I thought by observing the voltage coming from the gamepad's Data+ pin, I can probably determine if a button is being pushed. However, the observable input voltage in Arduino's A0 do not produce any meaningful difference between button push and release.

My question: Is it possible to detect Gamepad's button pushes with this arrangement? If it's possible, where do you think I'm doing wrong?

simulate this circuit – Schematic created using CircuitLab

# Answer
As mentioned, the problem is the gamepad you have uses communicates over USB, which requires a USB Host chip to communicate with. However, USB Host shields can be found on eBay (under "arduino USB Host shield") from US$10, and they come with a USB socket, so you could use it easily with another gamepad that hadn't had the connector snipped. This also would allow use with HID devices such as mice and keyboards if you wished, so a worthwhile shield to own.
> 2 votes

# Answer
USB devices make a serial communication, a series of packets of bits are sent and received, which is not beyond your power to learn and talk with. Using a USB Host shield or a chip would be easier (and more costly), but doing it yourself will be much more fun and educational.

Surprisingly, for some USB devices (like a keyboard) you need to poll the data. Nothing will be sent to the host automatically. To find out the protocol they speak, you need to connect the game-pad to a PC and monitor the signals.

Also you need to monitor both D+ and D- signals, they are both used.

Here is a wonderful video by Ben Eater about the USB Keyboards where he goes deep into monitoring the signals and the protocol, can be a good start for your project: https://www.youtube.com/watch?v=wdgULBpRoXk
> 0 votes

---
Tags: usb
---


# Question
Title: Switching fan on with transistor, fan running very slowly
I want to control a fan with an arduino from 0 rpm to full rpm. Using a (modified) pwm signal from the arduino I can control the speed w/ the pwm signal, but it cannot go all the way to 0 rpm.

So I decided to add a transistor as a switch using following schematic.

The fan is a Snowman F120, I used BC337 as a transistor (800mA) and a resistor of 2.2 kOhm, for controller I use pin 6 on an arduino nano and set it high/low. Arduino and the fan are both run from the 12v power supply. I removed the pwm signal to just have it full on or off for testing purposes.

I was hoping to use the transistor as an on/off switch and when on just send the pwm signal as that was working already.

The fan can now be turned off/on with the arduino but it spins super slow, say 10% of full pwr. Can someone explain why this is? Is there a better way to control this?

Edit: I did try to remove the resistor completely and the fan still moves only slowly

Edit: it is a 4 wire fan, but it cannot go all the way to 0 with pwm. That's why I want the 'switch'

I lowered the resistor to 120 ohm, and switched gpio pin, no effect, if I wait long enough the transistor gets hot

Edit: I connected the transitor to the 5V of the Arduino instead of the Digital out (high) and low and behold fan works well (resistor still in between, both 120 and 2.2kOhm tested, both situations work). I guess the digital output cannot provide enough current?

\** Solution:

* Used IRLZ34N mosfet with a 120Ohm as gate resistor
* and a 100 kOhm as pull down resistor to GND as otherwise the mosfet would always be open \**

# Answer
> 5 votes
With a 2.2K resistor you're massively limiting the current that can flow through the transistor.

I haven't looked up the specs on that transistor, but taking typical values for Vbe (0.6V) and Hfe (100) we can calculate:

```
Ibe = (5V - 0.6V) / 2200 ohm = 0.002A

Ice = Ibe x Hfe = 0.002 x 100 = 0.2A

```

So even though your transistor is capable of 800mA you're actually only allowing 200mA maximum.

Add to that the voltage drop of the transistor and you have a recipe for a slow fan.

Really you would be better off using an N-channel MOSFET for this job since it is controlled by the voltage at the gate, not the current flowing through it. Also in saturation mode they are more like a very low value resistor rather than a couple of diodes.

Also if your fan is a 4-wire fan (as the ones I have found on Google looking for that model are) then you don't even want a transistor: one of the pins of the fan is a PWM input which you can connect (along with fan ground) direct to the Arduino (it basically includes the transistor internal to the fan) for speed control.

# Answer
> 1 votes
I have used the BC337 to switch small loads like fans, so I know this works in general. As Majenko explained, 2.2kOhm base resistance is a bit high, though.

"I did try to remove the resistor completely and the fan still moves only slowly" - if you controlled the transistor without base resistor, chances are that the GPIO got damaged, try another GPIO *with* 500-1000 Ohm. As a rule of thumb: If the transistor gets warm when switching a small load, something is wrong. If there's a reasonable voltage drop between emitter and collector, reduce the base resistance if possible.

Another thing is that you should not low-side-switch a 4-pin fan if you want to control it with its PWM input at the same time. In case the ground path is disconnected, the entire fan's circuit is at supply voltage level: Arduino will see 12V at its pins. Use a high-side switch instead

Edit: did you actually make sure that the fan had 100% duty cycle at the PWM input when the transistor was on?

---
Tags: switch, transistor
---


# Question
Title: Why i am not getting the decimal number as output? The code is explained with the help of comments
```
// Defined three array arr0,arr1,arr2
int arr0[] = {0, 0, 0, 0, 0, 0, 0, 0};
int arr1[] = {0, 0, 0, 0, 0, 0, 0, 0};
int arr2[] = {0, 0, 0, 0, 0, 0, 0, 0};

//cord function takes binary number array as input and returns decimal
//number to a single variable as output
int cord(int a[]) {
  int v = 0;
  for (int i = 0; i < 8; i++)
  {
    int p = 1;
    for (int j = 0; j < i; j++)
    {
      p = p * 2;
    }
    v = v + a[i] * p;
  }
  return v;
}

//function bcord takes input row & col and updates the value in arr0,arr1,arr2 to 1 wherever
// there is some value in the row and column coordinate Eg.2,0 will make 2nd index of arr0
// to 1 or 2,1 will make 2nd index of arr1 to 1
int bcord(int row[], int col[])
{

  int n = sizeof(col) / sizeof(col[0]);

  for (int i = 0; i < n; i++)
  {
    int j;
    if (col[i] == 2)
    {
      j = row[i];
      arr2[j] = 1;
    }
    if (col[i] == 1)
    {
      j = row[i];
      arr1[j] = 1;
    }
    if (col[i] == 0)
    {
      j = row[i];
      arr0[j] = 1;
    }
  }
  int led0 = cord(arr0);
  Serial.print(led0);
  int led1 = cord(arr1);
  Serial.println(led1);
  int led2 = cord(arr2);
  Serial.println(led2);
  return 0;
}

void setup()
{
  Serial.begin(9600);
  int row[] = {0, 0, 2, 2, 1};
  int col[] = {0, 1, 0, 1, 1};
  bcord(row, col);
}

void loop() {}
// Output expected is decimal numbers which are stored in led0, led1 and led2 on the serial
// monitor

```

# Answer
In C++, you cannot pass an array as a parameter to a function. When you write the function prototype

```
int bcord(int row[], int col[], int n)

```

the compiler considers it a synonym of:

```
int bcord(int *row, int *col, int n)

```

In other words, both `row` and `col` are pointers, not arrays.

When you call the function like this:

```
bcord(row, col);

```

the compiler implicitly converts the call into this:

```
bcord(&row[0], &col[0]);

```

In other words, you are really passing pointers to the first element of each array. This is a standard language behavior called “decay to pointer”.

When I compile your code with warnings enabled, I get the following:

```
In function 'int bcord(int*, int*)':
warning: 'sizeof' on array function parameter 'col'
will return size of 'int*' [-Wsizeof-array-argument]
   int n = sizeof(col) / sizeof(col[0]);
                     ^
arr-ind.ino:31:30: note: declared here
 int bcord(int row[], int col[])
                              ^

```

Thus the compiler is telling you what is wrong. The variable `n` is not what you expect.

The standard solution is to pass the size of the array from the caller: move the definition of `n` to `setup()`, define `bcord()` as:

```
int bcord(int row[], int col[], int n)

```

and call it as

```
bcord(row, col, n);

```
> 3 votes

---
Tags: arduino-ide
---


# Question
Title: Arduino ESP8266WebServer hangs after a while but responds pings
I have an ESP8266 module that I use to be able to power on three computers if they are off. The ESP8266WebServer has what I needed to have a POST method rather than a simpler GET one since I am sending a password and I want that little extra security.

The code works and the circuits work as expected but only for a while. I have not been able to track down what is happening but whatever I do, it always hangs after some time but only the web server, it stills continues to respond pings so I know it is still connected and the serial monitor writes back my debug texts.

What I have tried after researching for some time:

* The HTML output string probably gets too big for the memory and should use PROGMEM but in the end, I sill need to manipulate it and something breaks. Gave up on it.
* The HTML output had an embedded image for the logo that also probably gets too big for the memory. Erased the image but stills hangs about the same time with or without it.
* Looked for a way to hardreset the ESP8266 module, could not find how and it is surely bad practice and may come with other kind of problems.
* Add a timeout for the connection, did not make any difference either.

I am missing something with the handle of the web server that gets the memory or something full and it stops answering request after a while because of it.

Here is the code:

```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid     = "";
const char* password = "";
const char* hostname = "";
const String imgLogo = "";

ESP8266WebServer server(9080);

String header = "";

String output1State = "off";
String output2State = "off";
String output3State = "off";

const int output1 = D1;
const int output2 = D2;
const int output3 = D8;

const int input1 = D5;
const int input2 = D6;
const int input3 = D7;

const int ledPin =  LED_BUILTIN;

unsigned long currentTime = millis();
unsigned long previousTime = 0;
const long timeoutTime = 2000;

unsigned long previousMillisOff = 0;
unsigned long previousMillisOn = 0;
unsigned long previousMillisMsg = 0;

void setup() {
  Serial.begin(9600);
  pinMode(output1, OUTPUT);
  pinMode(output2, OUTPUT);
  pinMode(output3, OUTPUT);
  pinMode(input1, INPUT);
  pinMode(input2, INPUT);
  pinMode(input3, INPUT);

  digitalWrite(output1, LOW);
  digitalWrite(output2, LOW);
  digitalWrite(output3, LOW);

  WiFi.disconnect();
  delay(500);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);

  WiFi.mode(WIFI_STA);
  WiFi.hostname(hostname);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println(WiFi.getAutoConnect());
  digitalWrite(ledPin, HIGH);

  server.on("/", HTTP_GET, handleRoot);
  server.on("/serverAction", HTTP_POST, serverAction);
  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void)
{
  server.handleClient();

  unsigned long currentMillis = millis();
  if(currentMillis - previousMillisOff > 5000)
  {
    previousMillisOff = currentMillis;
    digitalWrite(ledPin, LOW);
    previousMillisOn = currentMillis;
  }

  currentMillis = millis();
  if(!digitalRead(ledPin) && currentMillis - previousMillisOn > 250)
  {
    previousMillisOn = currentMillis;
    digitalWrite(ledPin, HIGH);
    previousMillisOff = currentMillis;
  }

  currentMillis = millis();
  if(currentMillis - previousMillisMsg > 30000)
  {
    Serial.println(WiFi.localIP());
    previousMillisMsg = currentMillis;
  }
}

void handleRoot()
{
  boolean PC01 = digitalRead(input1);
  boolean PC02 = digitalRead(input2);
  boolean PC03 = digitalRead(input3);

  String HTML = String("<!DOCTYPE html>\r\n<html>\r\n") +
    " <head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta http-equiv=\"cache-control\" content=\"no-cache, must-revalidate, post-check=0, pre-check=0\" />\r\n    <meta http-equiv=\"cache-control\" content=\"max-age=0\" />\r\n   <meta http-equiv=\"expires\" content=\"0\" />\r\n   <meta http-equiv=\"expires\" content=\"Tue, 01 Jan 1980 1:00:00 GMT\" />\r\n    <meta http-equiv=\"pragma\" content=\"no-cache\" />\n\r   <link href=\"data:image/x-icon;base64," + imgLogo + "\" rel=\"icon\" type=\"image/x-icon\" />\r\n   <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;} .button { background-color: #195B6A; border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;} .button2 {background-color: #800000;}</style>\r\n </head>\r\n <body>\r\n    <img src=\"data:image/png;base64," + imgLogo + "\"/>\r\n\r\n    <h1>Server switch</h1>\r\n  " +
    "   <p>Estado PC01 - " + (PC01 ? "Encendido" : "Apagado") + "\r\n" +
    "   <p>\r\n" +
    "   <form action=\"/serverAction\" method=\"post\">\r\n" +
    "     Contraseña: <input type=\"password\" name=\"pwd\">\r\n" +
    "     <p>\r\n" +
    "     <input type=\"text\" name=\"server\" value=\"PC01\" hidden>\r\n" +
    "     <button class=\"button " + (PC01 ? "" : "button2") + "\" type=\"submit\"" + (PC01 ? " disabled> PC01 encendido" : ">Encender PC01") + "</button>\r\n" +
    "   </form>\r\n\r\n" +
    "   <p>Estado PC02 - " + (PC02 ? "Encendido" : "Apagado") + "\r\n" +
    "   <p>\r\n" +
    "   <form action=\"/serverAction\" method=\"post\">\r\n" +
    "     Contraseña: <input type=\"password\" name=\"pwd\">\r\n" +
    "     <p>\r\n" +
    "     <input type=\"text\" name=\"server\" value=\"PC02\" hidden>\r\n" +
    "     <button class=\"button " + (PC02 ? "" : "button2") + "\" type=\"submit\"" + (PC02 ? " disabled> PC02 encendido" : ">Encender PC02") + "</button>\r\n" +
    "   </form>\r\n\r\n" +
    "   <p>Estado PC03 - " + (PC03 ? "Encendido" : "Apagado") + "\r\n" +
    "   <p>\r\n" +
    "   <form action=\"/serverAction\" method=\"post\">\r\n" +
    "     Contraseña: <input type=\"password\" name=\"pwd\">\r\n" +
    "     <p>\r\n" +
    "     <input type=\"text\" name=\"server\" value=\"PC03\" hidden>\r\n" +
    "     <button class=\"button " + (PC03 ? "" : "button2") + "\" type=\"submit\"" + (PC03 ? " disabled> PC03 encendido" : ">Encender PC03") + "</button>\r\n" +
    "   </form>\r\n </body>\r\n</html>";

  server.send(200, "text/html", HTML);

}

void serverAction()
{

  if( ! server.hasArg("pwd") || ! server.hasArg("server") || server.arg("pwd") == NULL || server.arg("server") == NULL)
  {
    server.send(400, "text/plain", "400: Invalid Request");
    return;
  }

  if(server.arg("pwd") == "0123456789")
  {
    String redirect = String("<script>var timer = setTimeout(function() { window.location=\'/\' }, 5000);</script></body></html>");
    if(server.arg("server") == "PC01")
    {
      if(!digitalRead(input1))
      {
        server.send(200, "text/html", "<html><body><h1 style=\"text-align: center\">Encendiendo " + server.arg("server") + "</h1>" + redirect);
        digitalWrite(output1, HIGH);
        delay(1000);
        digitalWrite(output1, LOW);
      }
      else
        server.send(200, "text/html", "<html><body><h1 style=\"text-align: center\">" + server.arg("server") + " ya encendido</h1>" + redirect);

    }
    else if(server.arg("server") == "PC02")
    {
      if(!digitalRead(input2))
      {
        server.send(200, "text/html", "<html><body><h1 style=\"text-align: center\">Encendiendo " + server.arg("server") + "</h1>" + redirect);
        digitalWrite(output2, HIGH);
        delay(1000);
        digitalWrite(output2, LOW);
      }
      else
        server.send(200, "text/html", "<html><body><h1 style=\"text-align: center\">" + server.arg("server") + " ya encendido</h1>" + redirect);
    }
    else if(server.arg("server") == "PC03")
    {
      if(!digitalRead(input3))
      {
        server.send(200, "text/html", "<html><body><h1 style=\"text-align: center\">Encendiendo " + server.arg("server") + "</h1>" + redirect);
        digitalWrite(output3, HIGH);
        delay(1000);
        digitalWrite(output3, LOW);
      }
      else
        server.send(200, "text/html", "<html><body><h1 style=\"text-align: center\">" + server.arg("server") + " ya encendido</h1>" + redirect);
    }
    else
    {
      server.send(401, "text/plain", "401: Unauthorized");
    }
  }
  else
  {
    server.send(401, "text/plain", "401: Unauthorized");
  }
}

void handleNotFound(){
  server.send(404, "text/plain", "404: Not found");
}

```

Any suggestions would be appreciated.

# Answer
When you use `String` the way you do, you're doing a lot of memory allocations. The ESP8266 doesn't have a lot of memory and is easily subject to a problem called "heap fragmentation" \- memory is allocated from a fixed pool called a "heap". Over time the free parts of the heap may become so fragmented that you can no longer allocate chunks of memory over a certain size. The way that you're building the string in the variable `HTML` will probably cause this to happen quickly.

To check for heap fragmentation, add this code to the end of `handleRoot()`:

```
  Serial.print("getFreeHeap: ");
  Serial.println(ESP.getFreeHeap());
  Serial.print("getHeapFragmentation: ");
  Serial.println(ESP.getHeapFragmentation());
  Serial.print("getMaxFreeBlockSize: ");
  Serial.println(ESP.getMaxFreeBlockSize());

```

And use your web server, especially reloading the root page, until you see the problem happen.

If you have a memory leak (memory is being allocated but never freed), you'll see `getFreeHeap` drop and not go back up.

If you have heap fragmentation, you'll see `getMaxFreeBlockSize` get smaller until it's smaller than the biggest strings you're trying to allocate (probably the total length of the root web page). You'll also see `getHeapFragmentation` get bigger over time - it's a metric from 0 to 100% of how fragmented the heap is. If it gets to 40 or 50% you're in trouble.

If you are seeing heap fragmentation you're going to need to rethink the way you build the web page you're serving. You need to minimize the number of times that you allocate memory. You may not know it but every time you add something on to a `String`, it frees the memory for the old string and allocates memory for the new one.

For instance, you build the web page like this:

```
 String HTML = String("<!DOCTYPE html>\r\n<html>\r\n") +
    " <head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta http-equiv=\"cache-control\" content=\"no-cache, must-revalidate, post-check=0, pre-check=0\" />\r\n    <meta http-equiv=\"cache-control\" content=\"max-age=0\" />\r\n   <meta http-equiv=\"expires\" content=\"0\" />\r\n   <meta http-equiv=\"expires\" content=\"Tue, 01 Jan 1980 1:00:00 GMT\" />\r\n    <meta http-equiv=\"pragma\" content=\"no-cache\" />\n\r   <link href=\"data:image/x-icon;base64," + imgLogo + "\" rel=\"icon\" type=\"image/x-icon\" />\r\n   <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;} .button { background-color: #195B6A; border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;} .button2 {background-color: #800000;}</style>\r\n </head>\r\n <body>\r\n    <img src=\"data:image/png;base64," + imgLogo + "\"/>\r\n\r\n    <h1>Server switch</h1>\r\n  " +
    "   <p>Estado PC01 - " + (PC01 ? "Encendido" : "Apagado") + "\r\n" +
    "   <p>\r\n" +
    "   <form action=\"/serverAction\" method=\"post\">\r\n" +

```

Every time you use `+` to add to the `String` here, you're causing the compiler to unnecessarily allocate memory. It's completely unnecessary to add most of these strings together. The C++ compiler will automatically concatenate strings written on separate lines, like so:

```
 String HTML = String("<!DOCTYPE html>\r\n<html>\r\n") +
    " <head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta http-equiv=\"cache-control\" content=\"no-cache, must-revalidate, post-check=0, pre-check=0\" />\r\n    <meta http-equiv=\"cache-control\" content=\"max-age=0\" />\r\n   <meta http-equiv=\"expires\" content=\"0\" />\r\n   <meta http-equiv=\"expires\" content=\"Tue, 01 Jan 1980 1:00:00 GMT\" />\r\n    <meta http-equiv=\"pragma\" content=\"no-cache\" />\n\r   <link href=\"data:image/x-icon;base64," + imgLogo + "\" rel=\"icon\" type=\"image/x-icon\" />\r\n   <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;} .button { background-color: #195B6A; border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;} .button2 {background-color: #800000;}</style>\r\n </head>\r\n <body>\r\n    <img src=\"data:image/png;base64," + imgLogo + "\"/>\r\n\r\n    <h1>Server switch</h1>\r\n  "
    "   <p>Estado PC01 - " + (PC01 ? "Encendido" : "Apagado") + "\r\n"
    "   <p>\r\n"
    "   <form action=\"/serverAction\" method=\"post\">\r\n"

```

Just making that change will reduce the heap fragmentation. This won't solve the problem but it should allow your program to run longer without crashing.

This is a big subject. The best way to do it is to use C strings (character arrays) and avoid allocating memory altogether, but this is difficult and tedious even for experienced programmers. The ESP8266 Arduino Core documentation offers some advice (see the section "Memory, memory, memory"), including using `PROGMEM` for constant literal strings and creating `String` objects with all the space they'll need when they're allocated, to avoid freeing and re-allocating the internal buffer they use to store the string.

If you're having heap fragmentation issues, do everything you can to reduce `String` use in your program. If that doesn't get your web server working reliably, search the web and Stack Overflow for more advice on how to avoid heap fragmentation, and post new questions here about specific issues.
> 4 votes

---
Tags: esp8266, wifi, esp8266webserver
---


# Question
Title: Can't burn fuse bits on ATMega168 with Arduino Uno as ISP
I have an ATMega168 that I am programming via my Arduino Uno as ISP. I can burn the bootloader and transfer a hex file just fine, but I can't seem to be able to change the fuse bits. I found a lot of people having similar problems, but most still weren't resolved after many years or can't connect to their chip at all.

A weird thing I notice is that my ATMega is recognized as an 328p all the time. I know they're practically identical, but nothing works when I change settings to an 168, I always have to set it to 328p. Avrdude tells me the signature is wrong, whenever I try it with 168. Might that already be an indicator for something being wrong!? I ordered a 168 and it's printed on the chip, so it should be an actual 168.

Furthermore I noticed that I can only use the Baud rate of 115200, but I read that only 19200 should be correct and when I use that I get no response as well.

This is the command I'm trying to use:

```
avrdude -Cavrdude.conf -patmega328p -PCOM3 -carduino -b115200 -U efuse:w:0x00:m -U hfuse:w:0xDD:m -U lfuse:w:0xFF:m

```

And the response I get is:

```
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x00 != 0xdd
avrdude: verification error; content mismatch

```

I tried different software and different USB cables, to no avail.

If anyone could provide any direction I can try and look for a solution or mistakes I might have made, I'd be really grateful!

# Answer
> 2 votes
I got an answer on another forum. I was missing a **10μF capacitor** between the Ground and Reset of the Arduino. Not a single documentation, image or video I saw mentioned that. Everything works fine now.

---
Tags: arduino-uno, avrdude, atmega
---


# Question
Title: Assign a delay value generated by a random function called randomBlink()
I'm trying to make a sketch where my led blinks with random delay. I have 2 functions: ledBlink() and randomBlink(). The randomBlink use as delay parameter a random number "r" generated from 1 to 499 and pass this value to the ledBlink function to make the led blink with a delay according the random number generated. But seems like that led doesn't consider the random value of blinkDelay. Any help is appreciated, thank you so much!

```
#include <JC_Button.h>

int ledPin = 11;

int ledState = LOW;
unsigned long blinkDelay;
unsigned long lastBlinkMillis = 0;

void setup() {

  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void ledBlink()
{
  unsigned long currentMillis = millis();

  if (currentMillis - lastBlinkMillis >= blinkDelay)
  {
    // save the last time you blinked the LED
    lastBlinkMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

void randomBlink()
{
  unsigned long r = random(500);
  blinkDelay = r;
  ledBlink();

}

void loop() {
  randomBlink();
}

```

# Answer
> 4 votes
Your problem descriptions is a bit unclear, though I think I see your problem.

On every `loop()` iteration you call `randomBlink()`, which generates a new random delay value and then calls `ledBlink()`, which in turn checks `millis()` for the time to toggle the LED and exits fast. So you are blinking only when the current `blinkDelay` has passed, but you generate new random values for `blinkDelay` on every `loop()` iteration - so really really fast. In the time needed for even the small delays you may have generated thousands of new random values, so it is very likely that some of them are rather small values. You check against these so you only get short delays.

Think of how you would do such thing in real life. Lets say you use a dice to determine the numbers of minutes to wait. You are throwing the dice every few seconds while watching the clock. Chances are that you will at some point get a 1 or 2 after waiting 1 or 2 minutes. It is unlikely that you don't get a 6 for 6 minutes straight. Instead you would want to through the dice only once per waiting period.

For the code this means, that you need to restructure it. Calculate the new delay value only when you toggle the LED. So something like this:

```
void ledBlink()
{
  unsigned long currentMillis = millis();

  if (currentMillis - lastBlinkMillis >= blinkDelay)
  {
    // save the last time you blinked the LED
    lastBlinkMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);

    // generate new random delay
    randomBlink();
  }
}

void randomBlink()
{
  unsigned long r = random(500);
  blinkDelay = r;
}

void loop() {
  ledBlink();
}

```

Calling `ledBlink()` in every `loop()` iteration makes sure, that the toggling of the LED actually happens. A new random value for the delay is only called after the LED just got toggled. Now the range of the delay will be the full 499ms.

---
Tags: millis
---


# Question
Title: Where are these junk characters (from serial) coming from?
I currently have 2 Arduinos both hooked up to HC-12s and have successfully got them communicating. But I am now trying to be able to process the data sent across and store it as a variable so as to make comparisons. But I'm getting junk data that comes over with the code, which prevents me from being able to do these comparisons.

For example, from one arduino when I sent "stop" I received

```
stop<⸮=l⸮⸮⸮

```

I cant figure out what this junk is from, also, I've limited the receivedChars to a size of 4, why am I getting more than 4 characters?

The code from the sender

```
#include <SoftwareSerial.h>

SoftwareSerial HC12(3, 2); // HC-12 TX Pin, HC-12 RX Pin

void setup() {
  Serial.begin(9600);             // Serial port to computer
  HC12.begin(9600);               // Serial port to HC12
  Serial.print("Checking HC-12 module: ");
  HC12.write("AT");               //Check for response(this is sending data to the HC, the SET pin must be low for this to work)
  delay(1000);
  HC12.write("AT+RX");            //Gets configs of HC-12
}

void loop() {
  while (HC12.available()) {        // If HC-12 has data
    Serial.write(HC12.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) {      // If Serial monitor has data
    HC12.write(Serial.read());      // Send that data to HC-12
  }
}

```

The simplified receiving code

```
    #define BYTELENGTH 4 //Limited to 4 chars
       #define ENDMARKER '\n'  //To know when stop stop reading serial

       SoftwareSerial HC12(3, 2); // HC-12 TX Pin, HC-12 RX Pin

  Serial.begin(9600); //Fastest it can be on the nano
  HC12.begin(9600); // Serial port to HC12s

      char receivedChars[BYTELENGTH - 1];
      int byteIndex;
      char curChar;

      while (HC12.available()) {        // If HC-12 has data
        curChar = HC12.read();
        if(curChar != ENDMARKER){
          receivedChars[byteIndex] = curChar;
          byteIndex++;
        }
      }
      if(strcmp(receivedChars,"") != 0){
        Serial.println(receivedChars);
        receivedChars[0] = 0;
      }

```

# Answer
I would say you are printing data outside of your `char` array, because you didn't terminate the C-string in it and the size of your array is too small.

You have

```
#define BYTELENGTH 4 //Limited to 4 chars
char receivedChars[BYTELENGTH - 1];

```

so your `char` array is only 3 elements big. When you want to save a string in that array, you always need to terminate it with a null character `\0` (which is also zero in decimal representation). So in that `char` array you only have space for 2 characters. But your message "stop" is 4 characters long, so you need a `char` array with at least 5 elements. If you are not in an extreme tight memory situation I would suggest using a buffer with a bit headroom above your biggest message (to be sure, that nothing breaks, if you later use messages that are a bit longer). So more like this:

```
#define BYTELENGTH 10 //Limited to 4 chars
char receivedChars[BYTELENGTH + 1]; // message length + null character termination

```

And then you need to change your receiving code to add a null character at the end of the message. Also you might want to actually use the newline character `\n` as message delimiting (which you are currently not doing):

```
bool full_message_received = false;

void loop(){
    while (HC12.available()) {        // If HC-12 has data
        curChar = HC12.read();
        if(curChar != ENDMARKER){
          receivedChars[byteIndex] = curChar;
          byteIndex++;
        } else {
          receivedChars[byteIndex] = '\0'; // terminating the c-string
          full_message_received = true; // marking the message as fully received
        }
    }
    if(full_message_received){
        Serial.println(receivedChars);
        receivedChars[0] = 0;
        full_message_received = false;
    }
}

```

**What happens, if I don't terminate the string with a null character?** All the functions, that handle C-strings (like `strcmp()` or also `Serial.print()`) use the null character to determine, at which point the string is at its end. They don't know the size of your array, so they just read byte after byte, until they reach the null character. They even read more data than is in your array. The junk characters are most likely exactly, what currently is placed in the memory directly after your array. `Serial.print()` doesn't know, that they don't belong to the C-string, since you didn't use the null character to tell it that. It just keeps printing characters, until it reaches a byte, that is zero.

You even wrote data to memory outside of the array. Depending on what comes directly after your array in the memory this can be without any problems, but you might also overwrite some other data, without knowing, what that data is. That can lead to very weird and hard to debug problems. Be sure to never write outside of your array. You might break things in weird ways.
> 1 votes

# Answer
It appears you have a baud rate problem. I am surprised you are getting anything. You need software to start the serial port such as SoftwareSerial mySerial(rxPin, txPin) then in setup mySerial.begin(9600); You need that in each application and the baud rates need to be the same.

I have used SC16IS750 I2C/SPI-to-UART devices as an external UART, they work great and have many nice features such as a 64 bytes of transmit and receive FIFOs. Some versions of this have been obsoleted but they are still available and work fine. You get 8 additional I/Os as well.
> 0 votes

# Answer
According to this vidéo in French it appeared that the problems comes from the SoftwareSerial library which if not reliable enough to provide accurate timings for your transmission. There are alternate software serial libraries (like AltSoftSerial), which use hardware timers, but I can't tel you more because I didn't try to use it.

All I can say, is that I my case removing SoftwareSerial to use the defaut hardware serial port solved the problems I had.

Alternatively, you can use I²C ⇒ UART IC like MAX3100, in order to provide aother hardware UART (With MAX3100 you'll need to add a 3.6468 or 1.8234 MHz crystal and 2×22pf capacitors) - I also didn't try it yet (Chip and crystal are ordered though. Or also you should be able to make the i2c ⇒ UART conversion with one more Arduino.
> -1 votes

---
Tags: serial, arduino-nano, softwareserial, hc-12
---


# Question
Title: Can we have 2 HC12 on a single Arduino (1 to receive and other to transmit)?
I'm working on a project and I need to send 2 datas and receive them at the same time.

My question is: Is it possible to have 2 Arduinos both have 2 HC12 (total 4), because I want each Arduino to send and receive data at the same time.

It's hard for me to have 4 Arduinos.

# Answer
> 2 votes
Yes you can - one on `Serial` pins 0/1 and the other using `SoftwareSerial` on any other pins. Note that the one on `SoftwareSerial` will interfere with the one on `Serial` as it disables interrupts while sending or receiving.

It may be better to use an Arduino which has multiple hardware serial ports. Maybe one of the Teensy boards would be better for your needs.

Alternatively if (and I am not familiar with the modules enough to know if this is right or not) they operate as a transparent serial bridge then you could connect one module to the TX pin for transmission and the other to the RX pin for reception - reading from serial receives from one, and writing to serial transmits through the other.

Also note that you will have to ensure that both pairs of modules are running on different channels to prevent interference between them.

# Answer
> 0 votes
Yes, you just need to connect your TX pin on the RX pin of one HC-12, and your RX pin on the TX pin of the other HC-12, and use separate channels for both HC-12. And then you do the same thing on the otherside, but you need of course, to reverse the channels - Et voila.

However, you might need to take precautions (distancing / shielding) to avoid your emitting HC-12 to parasite the channel of the nearby receiver.

By the way, it seems that one should refrain as much as possible to use SoftwareSerial, which is not robust enough for high speed and seems to cause data distortion.

---
Tags: arduino-uno
---


title: No ttyACM0 nor ttyUSB0

text:
# Question
Title: No ttyACM0 nor ttyUSB0
I checked several related posts but couldn't solve my problem.

I have Antergos Linux :

```
# uname -a
Linux biutitude 4.14.11-1-ARCH #1 SMP PREEMPT Wed Jan 3 07:02:42 UTC 2018 x86_64 GNU/Linux

```

The board is a Seeeduino Lorawan.

The problem is that the menu to select the port is greyed, and when I check in /dev I don't see any new tty when I plug the card. However the card blinks.

I tried : \- adding myself to lock + tty + uucp (and restarted my session) \- created a dialout group because I didn't have one, added myself to it \- loading cdc\_acm module but got the following error :

```
# modprobe cdc_acm
modprobe: FATAL: Module cdc_acm not found in directory /lib/modules/4.14.11-1-ARCH

```

Thus I tried :

```
[root@biutitude biu]# depmod -ae
depmod: WARNING: -e needs -E or -F
depmod: ERROR: could not open directory /lib/modules/4.14.11-1-ARCH: No such file or directory
depmod: FATAL: could not search modules: No such file or directory
[root@biutitude biu]# depmod
depmod: ERROR: could not open directory /lib/modules/4.14.11-1-ARCH: No such file or directory
depmod: FATAL: could not search modules: No such file or directory

```

I'm clearly out of ideas. The weirdest is that a few months ago, I was able to use a RFduino card without any trouble.

# Answer
My solution - install linux-modules-extra kernel module on ubuntu 20.04. Solved my problem which was identical.

Get OS details:

```
uname -a
Linux seeeduino-node 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

```

Install the sudo apt install linux-modules-extra:

```
sudo apt install linux-modules-extra-<kernel-version>

```

Example:

```
sudo apt install linux-modules-extra-5.4.0-91-generic

```

You need to reboot the machine afterwards it should work.
> 2 votes

---
Tags: serial, usb, linux
---