# Question
Title: How much voltage and current can a Arduino uno digital input sink?
I am having a digital output of 24VDC and 0.5A from ABB IRC5 controller. I need to feed this digital output to the digital input of Arduino uno. How can I do that?

# Answer
> 3 votes
One common misconceptions is that the current limit of a GPIO pin applies to inputs. It does not.

The 40mA "maximum sink" is only applicable when the pin is set to OUTPUT and is driven LOW - at which point the pin is connected to ground through a MOSFET.

However, when the pin is in INPUT mode it is *high impedance*. This means that it neither sinks nor sources current (apart from a very tiny *leakage current*). The only thing that matters is the voltage. That must:

* Never go higher than 0.3V above VCC (5.3V if powered from 5V)
* Never go lower than -0.3V
* Have logic levels that are within the thresholds of the input:
    + Below 0.3 × VCC for LOW
    + Above 0.6 × VCC for HIGH

You can connect the input to a signal that is 5V and 1,000,000 giga-amps and all will be well.

However, if you inadvertently set the pin to OUTPUT and drive it LOW there will instantly be smoke. For this reason it is common to add a small inline resistor (maybe 100Ω-470Ω) in order to limit any current through the circuit should the pin ever be set to OUTPUT and LOW.

Another "However", though: If you are using a voltage divider to reduce your incoming voltage to conform to the values above (as shown by @user43648 and suitable values given by @EdgarBonet) the inline resistor is pointless. The voltage divider itself will have a very high *output impedance* which massively limits the current. This impedance is like having a resistance equivalent to both the provided resistors in parallel inline with your input.

# Answer
> 3 votes
You have 2 different questions here. First one can be answered by google search, it is literally the first result.

*The Arduino Uno uses the atMEGA328 microcontroller, which has an absolute maximum rating of 40 mA source or sink per GPIO. Also, the total current through the supply or ground rails (i.e. the total of all current OP wants the GPIO pins to sink, or source) is rated to a maximum of 150 200 mA.*

And you should not apply more than 5V.

Regarding second question, Google can help again.

Vin is your 24V from controller, Vout is your Arduino digital 5V input. With that established, use voltage divider formula to calculate R1 and R2 values. I hope you can do that? That being said, I am disappointed, because I feel like you have put 0 effort into researching this.

# Answer
> 0 votes
As a complement to user43648's answer, it is worth noting that:

1. According to the datasheet, the 40 mA limit “is a stress rating only and functional operation of the device \[...\] is not implied” beyond the maximum tested current which is 20 mA.
2. The input voltage should be at least 3 V for the pin to be guaranteed to read high.
3. When sensing voltage through a voltage divider, 10 kΩ is a somewhat typical order of magnitude for the resistors.

Given the above, I would suggest using 47 kΩ for the top resistor and 10 kΩ for the bottom one. This should give about 4.2 V on the input pin, which is near the middle of the appropriate range for the pin to read `HIGH`.

# Answer
> 0 votes
In addition to the potential divider I would be tempted to strap the input pin to ground with a zener diode between 4V7 and 5V1 in case the lower resistor or its solder joints fail. even with a relatively high value series resistor 24V has plenty of potential to destroy the input pin if not the entire chip. The safest method though is use an opto-isolator and keep the nasty high voltages isolated from the delicate digital level components.

---
Tags: arduino-uno, digital-in
---


# Question
Title: Serial communication mac to Digispark ATtiny85
I want to use the Arduino IDE serial monitor with my Digispark ATtiny85 over USB.

I can without problems upload this code(Digispark CDC example):

```
#include <DigiCDC.h>
void setup() {
  SerialUSB.begin();
}
void loop() {
  SerialUSB.println(F("TEST!"));
 //SerialUSB.delay(10);
}

```

In a terminal, I can confirm, that it indeed creates a new devise:

```
ll /dev/*usb*
crw-rw-rw-  1 root  wheel   21,  89 27 Sep 10:36 /dev/cu.usbmodem1411
crw-rw-rw-  1 root  wheel   21,  88 27 Sep 10:36 /dev/tty.usbmodem1411

```

When trying to start the Arduino serial monitor, I get the error:

```
 Error opening serial port '/dev/cu.usbmodem1411'. (Port busy)

```

I have confirmed that there are no open files or processes using the USB port. I have the same problem trying to use `cu` or `screen` in the terminal.

I have googled the problem, and found that several people has the same problem on new mac computers, but I have not been able to find a solution. -any ideas?

* Digispark Rev3 (Chinese clone - with bootloader firmware 1.6 (1.06))
* Arduino IDE 1.8.7
* Mac OSX High Sierra 10.13.6

# Answer
SoftSerial and a real serial port on the mac will work. Or if you are careful use the DigiKeyboard and print the debug to the HID keyboard REMEMBERING to switch to a notepad equivalent window on the mac to receive and display the debugging text and not have it overwriting the arduino sketch by mistake. DigiCDC is a kludge that does not work properly on modern operating systems sorry!
> 1 votes

---
Tags: serial, usb, mac-os, attiny85, digispark
---


title: TinyDuino radio connection

text:
# Question
Title: TinyDuino radio connection
I am currently running a project with 2 TinyDuinos and 2 TinyShields 433MHz Radio (SI4432) in order to pass 3 axes (x , y ,z) from one to the other from long distance.

I have tried

* to concat the axes as one string and send the string,
* to send an array like `string axes = { x , y , z }` to the receiver (of course the variables are already defined),
* send only one string. In this case I have only the first 2 letters of the string. For example if the string was `string first = "456"` , I would get `"45"` on the receiver

The Radio shield's examples uses uint8\_t type and arrays to send and receive the data, I have already tried to cast the string to char\* and then to uint8\_t and nothing different happens. Maybe I am missing something.

Below there are my code screen shots. I will put 2 links for the examples of the transmitter and the receiver I got some code from

Similar Project : https://tinycircuits.com/blogs/learn/121634375-football-play-calling-watch-tutorial

Radio Shield Page: https://tinycircuits.com/products/433mhz-long-range-radio-tinyshield

TinyDuino Main Shield : https://tinycircuits.com/collections/all/products/tinyduino-processor-board

## Code Screenshots

# Answer
For this kind of thing you need to craft a packet to contain your data. The best method is to use a *struct*.

```
struct coords {
    int x;
    int y;
    int z;
};

```

Then you can define a variable from it:

```
struct coords myCoords;

```

And set individual values:

```
myCoords.x = 23;
myCoords.y = 180;
myCoords.z = -3817;

```

Now you can cast it to whatever type you need for sending:

```
manager.sendtoWait((uint8_t *)&myCoords, sizeof(struct coords), SERVER_ADDRESS);

```

Receiving is done in much the same way:

```
struct coords recCoords;
uint8_t len = sizeof(struct coords);
uint8_t from;

if (manager.recvfromAck((uint8_t *)&recCoords, &len, &from)) {
    Serial.print("X = ");
    Serial.println(recCoords.x);
    Serial.print("Y = ");
    Serial.println(recCoords.y);
    Serial.print("Z = ");
    Serial.println(recCoords.z);
}

```

---

In future please *post your actual code*, not pictures of your code. It makes it a real pain having to keep scrolling up and manually typing in bits of your code rather than being able to copy-and-paste a couple of lines.
> 0 votes

---
Tags: arduino-nano, wireless
---


# Question
Title: Wake up ESP8266 from deepSleep with a button
I have a button with two isolated tracks. I want to be able to wake up esp from deepSleep with this button, and also detect that it was clicked. So i can't connect it to reset, because esp won't work if i don't release a button. And if it's not at deepSleep, it will reset, and i don't want it. How to do this?

# Answer
Use some other pin to hold RESET HIGH or to disconnect the button from RESET while the esp8266 is not running.

simulate this circuit – Schematic created using CircuitLab

I asked on EE SE for the missing part of the circuit.
> 1 votes

# Answer
You can't stop deepSleep, all you can do is reset the board so connect the button to the reset pin and make the appropiate set-up:

1. Connect a pullup resistor (10k) in RST
2. Connect the button from RST to GND

When you push, RST has GND so the ESP gets reseted.

Remember that deepsleep only works for about an hour so you have to contemplate this situation, too, maybe with a static variable...

**EDIT** Thanks Juraj for the comment: "from SDK API "system\_deep\_sleep(0): there is no wakeup timer; in order to wake up, connect a GPIO to pin RST; the chip will wake up by a falling-edge on pin RST."
> -1 votes

---
Tags: esp8266, power, sleep
---


# Question
Title: How to HTTP post a data to Node express API from a Arduino esp8226?
I am HTTP posting a data to this web API https://morning-cliffs-85779.herokuapp.com/api/users from an **Arduino connected to esp8226**. I am using the **wifiesp library** to HTTP\_POST data.

The REST APIs are hosted in **Heroku**.

When I post it the Arduino gives the response

> Connected to server
> \[WiFiEsp\] Data packet send error (2)
> \[WiFiEsp\] Failed to write to socket 3
> \[WiFiEsp\] Disconnecting 3

and the Heroku server gives the response

> at=error code=H13 desc="Connection closed without response"

Below is the Arduino code:

```
  if (client.connect(server, 80)) {
    Serial.println("Connected to server");
    // Make a HTTP request
    String content = "id=5bc58842bdfea0153bb27214&volt=7";
    client.println("POST /api/users HTTP/1.1");
    client.println("Host: morning-cliffs-85779.herokuapp.com:80");// ("Host": host:port)
    client.println("Accept: */*");
    client.println("Content-Length: " + content.length());
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println();
    client.println(content);
  }

```

This is the Node Express API:

```
app.post('/api/users', function (req, res) {

console.log('here');

if (req.body.id) {
    DevReading.findByIdAndUpdate(req.body.id, {
        volt: req.body.volt
    }, function (err, reading) {
        if (err) throw err;

        res.send('Update Success');
    });
}

else {

var newDevReading = DevReading ({
    deviceName: 'test',
    volt: req.body.volt
});

newDevReading.save(function (err) {
    if (err) throw err;
    res.send('Reading Post Success');
});
}

});

```

# Answer
Did it heres the code

```
`if (client.connectSSL(server, 443)) {
Serial.println("Connected to server");
// Make a HTTP request
String PostData = content + volt;
Serial.println(PostData);
client.println("POST /api/users HTTP/1.1");
client.println("Host: morning-cliffs-85779.herokuapp.com");
client.println("Cache-Control: no-cache");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(PostData.length());
client.println();
client.println(PostData);
}`

```

Hope it helps some one
> 2 votes

---
Tags: arduino-uno, esp8266, web-server, http, node.js
---


# Question
Title: Watchdog timer stuck in restart loop? (green led flashing)
I am trying to set up a way to reboot arduino on command. The code below should do that but it seems like my arduino just get's stuck in some sort of a loop where I cant upload or get any serial output. The green led (pin 13) flashes very fast. The only way to stop this is to cut power to the device, even reset button does not work. This happens only when "R" is received via serial or if wdt\_reset() function is commented out.

```
#include <avr/io.h>
#include <avr/wdt.h>

int ledPin = 3;

void setup()
{
  MCUSR=0;
  wdt_disable();
  Serial.begin(57600);
  Serial.println("BOOT!");
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  delay(500);
}

void loop(){
  if (Serial.available() > 0){
    char cmd = Serial.read();
    if (cmd == 'R'){
      Serial.println("R received!");
      wdt_enable(WDTO_1S);
      delay(2000);
      Serial.println("1 SEC.");
    }
  }
  wdt_reset();
  digitalWrite(ledPin, HIGH);
}

```

What am I doing wrong?

# Answer
One of the most obvious issues here is that you are enabling the watchdog timer with a delay of 1S and then you are asking the micro controller to sleep for 2S, printing something and then going back into the loop. This, in theory, should be fine(your wdt should trigger a reboot during the 2 second wait) but I've seen it cause issues.

Additionally some bootloaders(notably the Optiboot bootloader on Uno and newer boards) can have issues with watchdog timers causing the wdt to remain enabled after reset even though the setup loop disables it. To start with - try increasing the wdt time to something greater than 2S(you should be able to do WDTO\_8S) and see if the issue persists.

**EDIT** \- The OP is using an Arduino Pro Mini clone. The included bootloader on the Arduino Pro Mini does not support system restarts by the WDT. Essentially, on a device with a bootloader that does not support WDT restarts, the board will restart but the timer / reset will not causing the board to continuously reset on reboot. There are alternative bootloaders for Arduino boards that may resolve this issue. Another solution is to use a different method to reboot the board.
> 4 votes

# Answer
Enabling watchdog timer system restart and waiting in a loop until reset is a legitimate way of SW resetting the µC as is using watchdog for catching µC's misbehavior which can be caused by various reasons.

However, some precautions have to be made when using watchdog system reset because on all AVRs that also have watchdog interrupt the watchdog **with prescaler set to 0000 = 16 ms** remains active after watchdog system reset condition. It is therefore responsibility of a programmer to clear **MCUSR** and to disable watchdog timer **as soon as possible** after occurrence of such a condition. Since LPM routines for initializing .data and .bss sections can last longer than watchdog timeout interval, the code for disabling the watchdog must be placed in **.init3 section** and the contents of **MCUSR** can optionally be saved for later reset source examination. Here is the code that does the described:

```
uint8_t mcusr_copy __attribute__ ((section (".noinit")));
void disable_wdt(void) \
     __attribute__((naked)) \
     __attribute__((section(".init3")));
void disable_wdt(void) {
  mcusr_copy = MCUSR;
  MCUSR = 0x00;
  wdt_disable();
}

```

However, the problem may arise when using a bootloader which does not account for the possibility of watchdog system reset condition. If that is the case, watchdog timeout will happen inside bootloader (which is executed the first) before the above code will have the chance to disable the watchdog timer and µC will be stuck in an endless reset loop. Since reseting the µC will **not** clear **WDRF** flag in **MCUSR** register (it can be cleared only in software or by Power-on reset) the only way will then be to cycle the power and upload a new code when watchdog timer is still not activated by previous code. **WDRF** in **MCUSR** register must be cleared before `wdt_disable()` because **WDE** can not be cleared if **WDRF** is still set - therefore the order of the instrucions in the above code is very important. The function placed in **.init3** section must not be called from later code.
> 2 votes

# Answer
Remove watchdogs flag at init is one solution. I am using optiboot 8.0 and it works perfect.

```
// Function Pototype
void wdt_init(void) __attribute__ ((naked, used, section(".init3")));

// Function Implementation
void wdt_init(void)
{
    MCUSR = 0;
    wdt_disable();
    return;
}

```
> 0 votes

# Answer
You can restart the Arduino with this command:

```
asm volatile ("  jmp 0");

```
> -1 votes

---
Tags: serial, arduino-pro-mini, reset
---


# Question
Title: Get accelerometer values from BNO055 using adafruit's Unified Sensor Library
If I understand correctly using the `Adafruit_Sensor` one can extract information from the sensor specific information. These sensors are currently mentioned in the `README`. I am using the BNO055 for two things:

1. Orientation values (Heading, pitch, roll)
2. Linear Acceleration values

My code is similar to the Example mentioned Adafruit\_BNO055's bunny

### Code

I tried the following in my `loop()`

```
void loop() {
  // put your main code here, to run repeatedly:
  sensors_event_t event;
  bno.getEvent(&event);

  Serial.print(F("Orientation: "));
  Serial.print((float)event.orientation.x);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.y);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.z);
  Serial.println(F(""));

  Serial.print(F("Acceleration: "));
  Serial.print((float)event.acceleration.x);
  Serial.print(F(" "));
  Serial.print((float)event.acceleration.y);
  Serial.print(F(" "));
  Serial.print((float)event.acceleration.z);
  Serial.println(F(""));

  delay(BNO055_SAMPLERATE_DELAY_MS);
}

```

Created `sensors_event_t event` and used the `orientation` and `acceleration` parameters to obtain the orientation and acceleration values in x, y, z directions.

### output

The orientation and accleration values are the same:

```
Orientation: 105.50 -20.56 -101.00
Acceleration: 105.50 -20.56 -101.00
Orientation: 97.81 -14.69 -119.56
Acceleration: 97.81 -14.69 -119.56
Orientation: 93.81 -10.94 -125.56
Acceleration: 93.81 -10.94 -125.56
Orientation: 94.44 -12.25 -122.56

```

I tried adding another event `event1` in the `loop()` but I still get the same results

```
sensors_event_t event;
  bno.getEvent(&event);

  Serial.print(F("Orientation: "));
  Serial.print((float)event.orientation.x);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.y);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.z);
  Serial.println(F(""));

  sensors_event_t event1;
  bno.getEvent(&event1);
  Serial.print(F("Acceleration: "));
  Serial.print((float)event1.acceleration.x);
  Serial.print(F(" "));
  Serial.print((float)event1.acceleration.y);
  Serial.print(F(" "));
  Serial.print((float)event1.acceleration.z);
  Serial.println(F(""));

  delay(BNO055_SAMPLERATE_DELAY_MS);

```

Can't the BNO055 along with the Adafruit\_Sensor library not provide the acceleration and orientation values as events or is the library used only to obtain orientation values from the BNO055?

# Answer
> 1 votes
## Findings

If I use the same `sensors_event_t` in the code and use `event.acceleration` and `event.orientation` within the `loop()` and they provide me exactly the same values. I in fact get the same values for heading, pitch, roll and acceleration in x, y, z direction.

```
sensors_event_t event;
  bno.getEvent(&event);

  Serial.print(F("Orientation: "));
  Serial.print((float)event.orientation.heading);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.pitch);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.roll);
  Serial.println(F(""));
 Serial.print((float)event.acceleration.x); // same as roll
 Serial.println(F(""));
 Serial.print((float)event.acceleration.y); // same as pitch
 Serial.println(F(""));
 Serial.print((float)event.acceleration.z); // same as heading
 Serial.println(F(""));

```

## Sensor

I have a **Blue Dot** BNO055 sensor and it has marking on it for X, Y, Z directions as follows:

I crossed checked with the logic of Euler Angles from Wikipedia

If i rotate along the x Axis, I do in fact get roll (0 to 360) and so on.

## Inference

The `Adafruit_Sensor` library provides only orientation values when used with BNO055 and Linear acceleration values need to be called separately using the **Adafruit\_BNO055**.

### code for Linear Acceleration and orientation

```
  sensors_event_t event;
  bno.getEvent(&event);

  Serial.print(F("Orientation: "));
  Serial.print((float)event.orientation.heading);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.pitch);
  Serial.print(F(" "));
  Serial.print((float)event.orientation.roll);
  Serial.println(F(""));
//  Serial.print((float)event.acceleration.x); // same as roll
//  Serial.println(F(""));
//  Serial.print((float)event.acceleration.y); // same as pitch
//  Serial.println(F(""));
//  Serial.print((float)event.acceleration.z); // same as heading
//  Serial.println(F(""));

  imu::Vector<3> li_ac = bno.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);
  Serial.print(F("Li. Acc.: "));
  Serial.print((float)li_ac.x());
  Serial.print(F(" "));

  Serial.print((float)li_ac.y());
  Serial.print(F(" "));

  Serial.print((float)li_ac.z());
  Serial.print(F(" "));
  Serial.println();

  delay(BNO055_SAMPLERATE_DELAY_MS);

```

# Answer
> 0 votes
You must set the operation mode from adafruit\_bno055\_opmode\_t enum. Use `bno.setMode`.

For modes see section 3.3 in the datasheet.

The `sensors_event_t` is an union struct so the same memory is accessed with different member names.

---
Tags: sensors, adafruit, bno055
---


# Question
Title: What is the smallest duration that can be measured using micros()?
What is the least value of time that I could measure(count) using `micros()`?

# Answer
> What is the least value of time that I could measure(count) using micro() in Arduino board?

The answer is 64 clock cycles or 4 us @ 16 MHz. Please see the Arduino AVR core\[1\] for more details.

Cheers!

Ref. \[1\] https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c#L25
> 3 votes

---
Tags: timers, arduino-micro, time
---


title: I2C communication is not working

text:
# Question
Title: I2C communication is not working
I have been working on my project but I get an error and I need some advice or correction.

I use I2C method to communicate between master and slave. I've got two questions:

1. I send 7 inputs (from master) to the slave but only receives 6
2. Will my coding make an output like this video

**Master Code**

```
// Master Code
#include <Wire.h>
byte nChar =0;
char input[7];

void setup () {

  Serial.begin(9600);
  Wire.begin();
}

void loop()
{
  if (nChar < 7) {if (Serial.available()) { input[nChar++] = Serial.read();}}

    else {

      Wire.beginTransmission(1);

      //a
      Wire.write(input[0]);
      Serial.print("Drawer : ");
      Serial.println(input[0]);

      //x
      Wire.write(input[1]);
      Serial.print("Output : ");
      Serial.println(input[1]);

      //00
      Wire.write(input[2]);
      Wire.write(input[3]);
      Serial.print("Output : ");
      Serial.print(input[2]);
      Serial.println(input[3]);

      //y
      Wire.write(input[4]);
      Serial.print("Output : ");
      Serial.println(input[4]);

      //00
      Wire.write(input[5]);
      Wire.write(input[6]);
      Serial.print("Output : ");
      Serial.print(input[5]);
      Serial.println(input[6]);

      delay(15);

      while (Serial.available())
      {
        //Remove extra
        Serial.read();
      }
      Wire.endTransmission();
        nChar = 0;
    }
  }

```

**Slave Code**

```
#include <Wire.h>
byte ledPins[] = {12, 11, 10, 9, 8, 7, 6};
byte ledPins2[] = {12, 11, 10, 9, 8, 7, 6};
byte count;
byte nChar;
char c;
char input[8];
char data[30] = "";
int n;
#define nBits sizeof(ledPins)/sizeof(ledPins[0])
#define nBits sizeof(ledPins2)/sizeof(ledPins[0])

void setup()
{
  Wire.begin(1);
  Serial.begin(9600);
  for (byte i = 0; i < nBits; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
for (byte i = 0; i < nBits; i++) {
    pinMode(ledPins2[i], OUTPUT);
    }
  Serial.begin(9600);
}

void loop()
{
  if (nChar < 8) {                    //accumulate three characters
    if (Serial.available()) {
      c = Serial.read();
      input[nChar++] = c;
    }
  }
  else {
    input[8] = 1;                   //atoi() expects string terminator
    n = atoi(input);                //convert the input characters to integer
    dispBinary(n);
    delay(100);                     //wait for any additional characters
    while (Serial.available()) {    //ignore them
      c = Serial.read();
    }
    nChar = 1;
  }
}

void receiveEvent(int howMany)
{
  while (1 < Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
}

void dispBinary(int n) //Vertical
{
  if (n >= 0 && n <= 5) {
    for (byte i = 0; i < nBits; i++) {
      digitalWrite (ledPins[i], n & 1);
      n /= 2;
    }
  }
}

void dispBinary2(int n) //Horizontal
{
  if (n >= 0 && n <= 5) {
    for (byte i = 0; i < nBits; i++) {
      digitalWrite (ledPins2[i], n & 1);
      n /= 2;
    }
  }

}

void b()
{
  if (data[0] != 'a')
  {
    dispBinary(atoi("00"));
    delay(100);
    dispBinary2(atoi("00"));
    delay(100);
    goto fin;
  }
  if (data[1] = 'x')
  {
    char xdata[2] = {data[2], data[3]};//(data[2], data[3]);
    dispBinary2(atoi(xdata));
    delay(100);
  }
  if (data[4] = 'y')
  {
    char ydata[2] = {data[5], data[6]};//(data[5], data[6]);
    dispBinary(atoi(ydata));
    delay(100);
  }

fin:;
}

```

# Answer
Most coders would your `while (1 < Wire.available()) {` write as `while ( Wire.available() > 1) {` and read it "repeat while there is more the 1 byte available". but wait, why leave that one byte there? you want "repeat while there is no more byte available".

you need `while (0 < Wire.available())`
> 1 votes

---
Tags: arduino-nano
---


title: More than 4 PWM output at 25khz?

text:
# Question
Title: More than 4 PWM output at 25khz?
Is it possible using an arduino to control more than 4 PWM fan at 25khz ?

I have found this but 4 PWM limited with an UNO

https://arduino.stackovernet.com/fr/q/8407

An other arduino, like a 2560 could be used ?

Thanks Best regards Sébastien

# Answer
> 0 votes
Indeed you could use a Mega. See this answer: it explains how you can use Timer 1 on an Uno to provide two PWM channels at 25 kHz. This is the only 16-bit timer on that board. The Mega, on the other hand, has four 16-bit timers: Timers 1, 3, 4 and 5. These timers are almost identical to the Uno's Timer 1, except that they provide 3 PWM channels each. So you have potentially up to 12 PWM channels that you can run at 25 kHz.

Now, look at this pinout diagram. Every pin labeled `OCnx`, where `n` is either 1, 3, 4 or 5, and `x` is a letter, is a 16-bit PWM output. Just take the code from the answer I linked to and adapt it to the Mega. You configure all those timers in the same way, and you set the duty cycle for pin `OC3B` by writing to the register `OCR3B` (and so on...).

---
Tags: pwm, frequency
---


title: ESP8266 too many argument to function

text:
# Question
Title: ESP8266 too many argument to function
My project uses ESP8226 to allow: 1) user to set an alarm. 2) after 20 sec of the alarm ringing, it will notify to phone via blynk app using motion sensor. 3) after 40 sec it will turn off sensor and will not send notification again. There are two problems that I have:

* Got error with coding (digitalRead(nilai\_sensor, LOW);) "too many arguments to function 'int digitalRead(uint8\_t)"
* I need help with coding for turn off the sensor and will not nofify again.

Below is my Arduino code:

```
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
BlynkTimer timer;
WidgetRTC rtc;
WidgetLED led1(V10);
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "a7d4522186464dd297870f2ab8e53250";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "NabiL";
char pass[] = "limaringgitlimapuluhsen";
int flag = 0;
int buzzer = 12;
int motor = 13;
int sensor = 4;

int saat;
int on_delay;
int off_delay;
int ok_delay;

int get1 = 0;
int get2 = 0;
int nilai_sensor = 0;

void blinkLedWidget()
{
  if (led1.getValue()) {
    led1.off();
    Serial.println("LED on V1: off");
  } else {
    led1.on();
    Serial.println("LED on V1: on");
  }
}

void clockDisplay()
{
  // You can call hour(), minute(), ... at any time
  // Please see Time library examples for details

  String currentTime = String(hour()) + ":" + minute() + ":" + second();
  String currentDate = String(day()) + "/" + month() + "/" + year();
  Serial.print("Current time: ");
  Serial.print(currentTime);
  Serial.print("Current Time: ");
  Serial.print(currentDate);
  Serial.println();

  // Send time to the App
  Blynk.virtualWrite(V1, currentTime);
  // Send date to the App
  Blynk.virtualWrite(V2, currentDate);
}

BLYNK_CONNECTED() {
  // Synchronize time on connection
  rtc.begin();
}
BLYNK_WRITE(V5) // Timer
{
  Serial.println(param.asStr());

  if (param.asInt())
  {
    on_delay = saat + 20;  //20Saat
    off_delay = saat + 10;  //10Saat
    ok_delay = saat + 40;  //40Saat

    digitalWrite(buzzer, HIGH);
    digitalWrite(motor, HIGH);
  }
}
BLYNK_WRITE(V6) // Timer
{
  Serial.println(param.asStr());

  if (param.asInt())
  {
    on_delay = saat + 20;  //20Saat
    off_delay = saat + 10;  //10Saat
    ok_delay = saat + 40;  //40Saat

    digitalWrite(buzzer, HIGH);
    digitalWrite(motor, HIGH);
  }
}
BLYNK_WRITE(V0){
  Serial.println(param.asStr());

  if (param.asInt())
  {

    digitalWrite(buzzer, HIGH);
    digitalWrite(motor, HIGH);

  }
  else

  {
    digitalWrite(buzzer, LOW);
    digitalWrite(motor, LOW);

  }
}
BLYNK_WRITE(V12){
  Serial.println(param.asStr());

  if (param.asInt())
  {

    digitalWrite(buzzer, HIGH);
  }
  else

  {
    digitalWrite(buzzer, LOW);
  }
}
BLYNK_WRITE(V13){
  Serial.println(param.asStr());

  if (param.asInt())
  {

    digitalWrite(motor, HIGH);
  }
  else

  {

    digitalWrite(motor, LOW);
  }
}
void setup()
{
  // Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  setSyncInterval(10 * 60); // Sync interval in seconds (10 minutes)

  // Display digital clock every 1 seconds
  timer.setInterval(1000L, clockDisplay);
timer.setInterval(1000L, blinkLedWidget);
  // Setup notification button on pin D1

  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(4, INPUT);

}
void loop()
{
  saat = millis() / 1000;

  if(saat == off_delay)
  {
    digitalWrite(buzzer, LOW);
    digitalWrite(motor, LOW);
  }

   if(saat == on_delay)
  {
    Serial.println("Time Up");
    get1 = 1;
  }

     if(get1 == 1)
    {
     Serial.println("Program Sensor");

   nilai_sensor = digitalRead(sensor);

    if(nilai_sensor == HIGH)
    {
      Serial.println("Still sleeping");
     Blynk.notify("Still sleeping");

    //delay(5000);
   }
  }

if(saat == ok_delay)
  {
    Serial.println("Shut Down Sensor");
    get2 = 1;
  }
 if(get2 == 1)
  {
    Serial.println("turn off Sensor");
    nilai_sensor = digitalRead(sensor);
   digitalRead(nilai_sensor, LOW);

  }

  Blynk.run();
  timer.run(); // Initiates BlynkTimer

}

```

# Answer
The function `digitalRead()` has only one argument: the digital pin that you want to know the state (*high* or *low*).

You must change the use of this function, to something like this:

```
int state = digitalRead(nilai_sensor)

if (state == low) {
    //do something here
}

```

Hope you can find helpfull :D
> 2 votes

---
Tags: nodemcu, blynk
---


# Question
Title: Should I buy Arduino as a Computer Engineering Student?
I'm going to be in the third year of university in a month. I'm satisfied with the software part of my bachelor but I feel like I lack in practice in practical implementation. Would getting an Arduino board and playing around with it worth it and useful for me?

# Answer
> 5 votes
It depends. If you don't have any knowledge about microcontrollers it might be useful.

However, Arduino hides a lot of concepts in their libraries. If you want to go more indepth check other systems like STM32 or PIC.

You also can do both, start with Arduino to get a rough feeling, continue with another.

More important is WHAT you try, don't stop with LEDs/switches, but check communication protocols like SPI, I2c, UART etc. And learn what timers, interrupts etc. are and how to use them.

# Answer
> 3 votes
As already stated in previous answers, there is no clear-cut answer to this kind of question. It all depends on what you want to learn.

If that can help, I will share my personal experience. I studied computer science for only one year at university. Then I stopped to continue on my physics major. But as I never lost interest in computers, I continued learning on my own. I started playing with Arduinos just because it looked like a fun way to learn some microcontroller stuff and low-level programming. The barrier to entry is extremely low: in no time you get your LED blinking, and from there you can start exploring plenty of possibilities. The Arduino IDE and core library make it extremely easy to make *simple* programs, but they are quite limited when you want to get more serious. For many people, this environment, plus extra downloadable libraries, is all they need to achieve their goals. For me, it was a stepping stone to learn lower level stuff, like direct hardware access, use of the avr-libc, and even assembly programming.

Today, what I love most about Arduinos (or, rather, the AVR microcontrollers at their core), is their *simplicity* and *understandability*. Today, when I disassemble a program I have written, I can understand basically everything: the C runtime initialization code, the memory allocation, the way the compiler translates my own code... I find it extremely rewarding to reach such an understanding of a (kind of) computer system.

The same level of understanding would be (for me) impossible to achieve on a typical PC. Even though I use Linux, which is Open Source, and I have access to the full source code, the whole software stack involved in running even the simplest program is overwhelming. The kernel itself is like millions of lines of code. Even the assembly language of an x86 (or x86\_64) is something I find way too complex for my taste.

In conclusion, the Arduino has been for me a very rewarding learning experience. If you want to get your hands dirty with bare metal programming, I definitely recommend you get an Uno, or something similar, and start playing with it. Once you get your first program running (and that takes no time!) start looking under the hood: read the source of the Arduino core (it's short and very readable), read the datasheet of the microcontroller, start poking the hardware, take a look at how the compiler allocates memory, how it translates your source code...

# Answer
> 0 votes
I don't think there is a should or should not about it, do you want a low cost experimental setup using the C language to toy with ideas and concepts without a massive outlay or proprietary software or NDA's to get chip data that ties you to a single company then why not? You can get Arduino clones very cheaply from the likes of aliexpress etc as well as prototyping kits. While the Arduino IDE is a relatively primitive editor you can use any programmers editor you like to compose your C files and use the Arduino IDE just to do the final compile and linking and upload/burn them to the target device. It can be done so cheaply that even if you decide it does not inspire your imagination you won't have wasted hundreds of $! Just spent a couple of tens of $ to accumulate a significant micro-controller playground! Assuming you already have some kind of personal computer or easy access to one.

---
Tags: arduino-uno
---


# Question
Title: Sketch with multiple classes (.h and .cpp) - how to interconnect classes
I wanted to move most functionality of my sketch into different classes, to keep things better organized. One class worked just fine, but when I had to use multiple classes and pass information between then things stopped working.

I have two classes, my main Remote class, and my RemoteDisplay class. The main class takes care of fx, measuring battery voltage and I want to display this through the RemoteDisplay class. To do so I initiate the Display class with a pointer to the Remote class, so I can access the voltage function. This, however, doesn't work, even though I forward declare the Remote class in the Display class.

**Remote.ino**

```
#include "Remote.h"

Remote Remote;

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

void loop() {
  Remote.display.showBattery();
}

```

**Remote.h**

```
#include "RemoteDisplay.h"
class Remote
{

public:

  RemoteDisplay display;

  Remote( void );

  float voltage;

};

```

**Remote.cpp**

```
#include "Remote.h"

Remote::Remote(void)
{
  display.initiate(this);
}

```

**RemoteDisplay.h**

```
class Remote;

class RemoteDisplay
{

public:

  RemoteDisplay(void);

  void initiate( Remote * _pointer );

  void showBattery( void );

private:

  /* Reference to the remote class */
  Remote * pointer;
};

```

**RemoteDisplay.cpp**

```
#include "RemoteDisplay.h"

void RemoteDisplay::initiate( Remote * _pointer )
{
  pointer = _pointer;
}

void RemoteDisplay::showBattery( void )
{
  Serial.println( pointer->voltage );
}

```

I get the errors:

```
error: invalid use of incomplete type 'class Remote'
showBattery( pointer->voltage() );

note: forward declaration of 'class Remote'
class Remote;

```

Why is it so? Any help is much appreciated.

# Answer
> 0 votes
In RemoteDisplay.cc you are using Remote in the Initiate method.

Also, since you use the voltage property, you need to include "Remote.h" within (as first line normally) in RemoteDisplay.cpp.

Also it is advised to use within every header file the following pattern (example for RemoteDisplay.h):

```
#ifndef REMOTE_DISPLAY_H
#define REMOTE_DISPLAY_H
...
...
#endif // REMOTE_DISPLAY_H

```

This prevents problems that two include header files forever include each other.

---
Tags: class, pointer
---


title: Low-Power library question

text:
# Question
Title: Low-Power library question
i'm study the Low-Power library to better undertand how it works.
In this part of code i have some question.

Sometime he uses commands like:

```
power_timer1_disable();
power_timer0_disable();

```

but in other part of code, example "TIMER2\_OFF":

```
if (TCCR2B & CS22) clockSource |= (1 << CS22);
if (TCCR2B & CS21) clockSource |= (1 << CS21);
if (TCCR2B & CS20) clockSource |= (1 << CS20);

// Remove the clock source to shutdown Timer2
TCCR2B &= ~(1 << CS22);
TCCR2B &= ~(1 << CS21);
TCCR2B &= ~(1 << CS20);

power_timer2_disable();

```

he uses the register code and, in the end, the function.

Someone can explain to me why?

# Answer
> 0 votes
It's doing basically this:

```
clockSource = TCCR2B & (_BV(CS22) | _BV(CS21) | _BV(CS20)); // store prescaler
TCCR2B &= ~(_BV(CS22) | _BV(CS21) | _BV(CS20));             // select "no source" - disable clock source
power_timer2_disable(); // disable whole timer2 in Power Reduction Register

```

Definition of power\_timer2\_disable macro is:

```
#define power_timer2_disable()  (PRR |= (uint8_t)(1 << PRTIM2))

```

In short, you have to turn off the clock source before the power gets cut off by PRR register (to avoid unexpected behaviour).

> **Power Reduction Register**
>
> The Power Reduction Register (PRR), provides a method to stop the clock to individual peripherals to reduce power consumption. The current state of the peripheral is frozen and the I/O registers can not be read or written. ***Resources used by the peripheral when stopping the clock will remain occupied, hence the peripheral should in most cases be disabled before stopping the clock.*** Waking up a module, which is done by clearing the bit in PRR, puts the module in the same state as before shutdown. Module shutdown can be used in Idle mode and Active mode to significantly reduce the overall power consumption. In all other sleep modes, the clock is already stopped.

---
Tags: sleep
---


# Question
Title: Serial monitor returns "48" when I enter "0"
I am going through an Arduino Learning Book(978-1-59327-448-1) and I've run into the same issue twice now.

When I enter data into the serial monitor, the number that it reads and displays(when asked to print) is way different than what I'm entering.

In diagnosing the problem, I went to https://www.arduino.cc/en/Serial/Read
Copied the code into a new sketch, and tried to run it. When I Enter 0, I get 48, and a second line saying 10. Enter 1, I get 49 and 10, etc. Here are the results when I enter 0, then 1, then 2, then 3

I received: 48 I received: 10

I received: 49 I received: 10

I received: 50 I received: 10

I received: 51 I received: 10

here is the code I'm using

```
int incomingByte = 0;   // for incoming serial data

void setup() {
    Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

    // send data only when you receive data:
    if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();

            // say what you got:
            Serial.print("I received: ");
            Serial.println(incomingByte, DEC);
    }
}

```

I have the serial monitor set to 9600. All sketches have worked fine so far, including those that use Serial.print functions, but when I use Serial.read, things seem to get screwed up.

I'm sure I'm missing something stupid, but I've googled around and all the answers are much higher level than just trying to run the code in the Arduino.cc example

Thanks in advance for helping a first timer!

PS: I Tried to get all of the code into the grey box with various line spacing and indenting strategies, but it's not perfect. Does anyone have any tips on that?

# Answer
> ```
>            Serial.println(incomingByte, DEC);
>
> ```

You told it to print the incoming byte in decimal, so that is what it did. 48 is the decimal equivalent of ASCII '0'.

Change that line to:

```
Serial.println((char) incomingByte);

```

That casts the thing you are printing to a character, and then the appropriate version of Serial.println prints it as a character, not a decimal number.

---

10 is the decimal equivalent of a new line (newline) so that is why you are also seeing 10 printed.

---

> I need to convert the incoming stuff into integers so that it can see if im guessing right or not

Assuming you mean an integer other than 0 to 9 (like, 42 for example) then you need a bit more work. I have a page about that sort of thing:

http://www.gammon.com.au/serial

Example code:

```
/*
Example of processing incoming serial data without blocking.

Author:   Nick Gammon
Date:     13 November 2011.
Modified: 31 August 2013.

Released for public use.
*/
// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 50;

void setup ()
  {
  Serial.begin (115200);
  } // end of setup

// here to process incoming serial data after a terminator received
void process_data (const char * data)
  {
  // for now just display it
  // (but you could compare it to some value, convert to an integer, etc.)
  Serial.println (data);
  }  // end of process_data

void processIncomingByte (const byte inByte)
  {
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte

      // terminator reached! process input_line here ...
      process_data (input_line);

      // reset buffer for next time
      input_pos = 0;
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch

  } // end of processIncomingByte

void loop()
  {
  // if serial data available, process it
  while (Serial.available () > 0)
    processIncomingByte (Serial.read ());

  // do other stuff here like testing digital input (button presses) ...

  }  // end of loop

```

In this example, the function `process_data` is called when there is a complete number to be handled.
> 2 votes

# Answer
You can use `Serial.parseInt()` to read a number sent from Serial Monitor. parseInt waits for all numeric characters of the sent text, so it blocks the execution of your sketch for a very short time until all characters are received. At higher baud rate it will be faster. If your sketch doesn't need to loop as fast as possible, then you can use it. `parseInt` stops at first character that is not a digit (for example a newline character) and returns the received number as long.

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

void loop() {
  if (Serial.available() > 0) {
    long number = Serial.parseInt();
    Serial.println(number);
  }
}

```
> 0 votes

---
Tags: serial
---


# Question
Title: Sorting voltage data from pin A0 to 3 variables (ranked)
I don't have any code for this yet but I would like some ideas on coding it. I have a directional antenna that is rotating at a slow speed and a ham radio connected to the antenna. I have an output port on the radio that will put a voltage out from 0 to 5 volts for signal strength. I also have the rotational degree data that is captured. The question I have is do I try to do a long if then else statement to capture the 3 highest voltages and directions as variables for later processing or is there a better way. An example would go a long way as well.

# Answer
> 0 votes
It needs a bit more work but I would suggest using arrays to store the signal and positions something like this.. From (G7WJD) EXPIRED!

```
#define signalPin A0
#define degreePin A1
int signalStrength;
// STORE DATA IN ARRAY
// 0 [strength, direction]
// 1 [strength, direction]
// 2 [strength, direction]
int signals[3][3];
int degree;
bool positionSavedFlag = false;
void setup() {

}

void loop() {
 signalStrength = analogRead(signalPin);
 degree = analogRead(degreePin);
 // comapare with previous data
 for (int x = 0; x < 3; x++) {
  // have we saved data for this position before?
  if (degree == signals[x][1]) {
    // yes
    positionSavedFlag = true;
    // is it stronger than previous signal at this position
    if (signalStrength > signals[x][0]) {
      // yes so save / update it
      signals[x][0] = signalStrength;
    }
  }
 }
 // now since position not already stored , store it

 }

```

---
Tags: variables
---


# Question
Title: using string to display text on serial monitor
After using int to display text in serial monitor, now i am trying to use string but there is something wrong. The expected reslut is "Led1 is on" in serial monitor but what i get is "285". This is the code involving strings.

```
String(ledPin1="Led1 is on");
Serial.println(ledPin1);

```

while this is the full code

```
int numledPin1Blinks=5;
int ledPin1Blinks=2;
int i;
int j;
int waiTtimeoff2=1000;
int waitTimeOn2=1000;
int ledPin2=10;
int ledPin1=13;
int waiTtimeOn1=1000;
int waiTtimeOff1=1000;
void setup()
{pinMode(10,OUTPUT);
pinMode(13,OUTPUT);
Serial.begin(9600);
String(ledPin1="Led1 is on");

}

void loop()
{Serial.println(ledPin1);
for (i=1;i<=3;i=i+1){
Serial.print("   You are on blink
no#:  ");
Serial.println(i);
digitalWrite(ledPin1,HIGH);
delay(waiTtimeOn1);
digitalWrite(ledPin1,LOW);
delay(waiTtimeOff1);}
Serial.println(" ");

Serial.println("Led 2 is on!");
for (j=1;j<=4;j=j+1){
Serial.print(" You are on blink no
#:");
Serial.println(j);
digitalWrite (ledPin2,HIGH);
delay(waitTimeOn2);
digitalWrite (ledPin2,LOW);
delay(waiTtimeoff2);}
Serial.println(" ");

}

```

# Answer
Your syntax is incorrect. You are assigning the address of a static string literal to an integer, then using the results of that assignment (the address of the string literal, as it "falls through" to the left) to create a new String object. That `String` object is then being thrown away.

You need to create a *new* `String` variable (not re-use one that you actively use for another part of your program) and assign a string literal to it:

```
String led1Message = "LED 1 is on";

```

Then you can print *that* variable instead:

```
Serial.println(led1Message);

```

**HOWEVER** `String` objects are very very fragile on the Arduino and should be avoided. Forget trying to learn to use them, since you will only have to un-learn them at a later date. Skip them and start straight away with C-strings (NULL-terminated `char` arrays). Also learn about `PROGMEM`.

For instance, the above could be written as:

```
const char led1Message[] PROGMEM = "LED 1 is on";

```

And then use a casting to get `println` to grab it from flash:

```
Serial.println((__FlashStringHelper*)led1Message);

```

This uses pretty much zero RAM, which on an Arduino is very important. Even more important it doesn't cause heap fragmentation which can cause your program to crash randomly.
> 2 votes

---
Tags: arduino-uno
---


title: Difference between 3.3v & 5v

text:
# Question
Title: Difference between 3.3v & 5v
Im quite new to arduino in general and i'm sorry for the beginner question.
could someone explain what the 3.3v and 5v on boards do? I know their voltages. but can you run one on the other? whenever i try to search about it i see people saying that most newer modules are running on 3.3v so they convert their 5v arduino to 3.3v. something about if you run one on the other it could break it.

the arduino I bought looks like it has both! is that even possible?
I also purchased this LED matrix as I wanted to make a wifi enabled scrolling text display. the matrix says it requires 5v. since this arduino says vin is 5-12v the two should connect and work properly, right?

# Answer
> 0 votes
The difference for different voltage boards lies in the parts, that are soldered on it. Often microcontrollers support more than one supply voltage, but impose different performance limits on the system. Take for example the Arduino Uno: It uses the Atmega328p, which can run both on 3.3V and 5V. But on the UNO there is a 16MHz quartz, which generates the controllers clock signal. The Atmega328p cannot run 16MHz with only 3.3 volts. To run a board on a voltage, for which it wasn't directly build, mostly requires you to resolder it with the correct parts.

---

> whenever i try to search about it i see people saying that most newer modules are running on 3.3v so they convert their 5v arduino to 3.3v

There are special chips, called voltage regulators/converters. They come with various working principles, but basically they are converting one voltage to another. The Arduino Uno has one connected to Vin, so that you can apply between 7V and 12V to Vin and the Arduino itself will only see the 5V it get's from the regulator. Some modules also have a voltage regulator, but not all. Be careful not to provide more than the specified voltage to any board or you may destroy it.

---

> the arduino I bought looks like it has both! is that even possible?

First, as Juraj wrote, this is not an Arduino. It is an ESP8266, a totally different chip and board. But you can also program it through the Arduino IDE, without it being an Arduino. Second: When they write, that you can provide it with either 3.3V or 5V, they mean, that you can provide 5V through the USB jack and a voltage regulator will convert it to 3.3V for the ESP, which runs completely on 3.3V. You should not connect 5V to any other pin.

---

> since this arduino says vin is 5-12v the two should connect and work properly, right?

As stated above the 12V is only, what you can at maximum provide at Vin. The ESP8266 runs on 3.3V, so you will have to provide 3.3V (or more over the Vin pin). The LED matrix runs at 5V, as you stated. So you need a 5V source and a level shifter for the 2 lines between the ESP8266 and the matrix. If you connect them directly, you would damage the ESP8266. So: No, you cannot use it directly. It is up to you, if you want to use a level shifter or buy another matrix display, which can be controlled by a 3.3V signal.

# Answer
> 0 votes
As seen in the OEM data sheet for the MAX7219 https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf the MAX7219 needs a supply voltage of 4 to 5.5V. with a minimum signal voltage for High of 3.5V when Vcc = 5V.

Folks often get counterfeit parts from e-bay or elsewhere, with unknown characteristics.

For best results, I would power the '7219 from 5V, and use a buffer chip powered from 5V, such as 74AC125, http://www.onsemi.com/pub/Collateral/MC74AC125-D.PDF which will take ~ 2.5V with Vcc = 5V to boost the ~3V output from the ESP2855 to 5V levels.

---
Tags: esp8266, voltage, max7219
---


# Question
Title: Quaternion values from BNO055 not available
I am trying to obtain Quaternion values from a BNO055 connected to ESP32-PoE board by Olimex.

## Code

```
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

Adafruit_BNO055 bno = Adafruit_BNO055(55);

void setup() {
  // put your setup code here, to run once:
  Wire.begin(13, 16, 400000);
  Serial.begin(115200);

  if (!bno.begin()) {
    Serial.println("No BNO055 Detected!");
    while(1);
  }
  delay(100);
  bno.setMode(Adafruit_BNO055::OPERATION_MODE_NDOF_FMC_OFF);
  bno.setExtCrystalUse(true);
}

void loop() {
  // put your main code here, to run repeatedly:
  imu::Quaternion quat = bno.getQuat();
  imu::Vector<3> euler = quat.toEuler();

  Serial.print("W: ");
  Serial.print(quat.w());
  Serial.print(F(" "));

  Serial.print("x: ");
  Serial.print(quat.x());
  Serial.print(F(" "));

  Serial.print("y: ");
  Serial.print(quat.y());
  Serial.print(F(" "));

  Serial.print("z: ");
  Serial.print(quat.z());
  Serial.print(F(" "));

  Serial.print("X: ");
  Serial.print((float)euler.x());
  Serial.print(F(" "));
  Serial.print("Y: ");
  Serial.print((float)euler.y());
  Serial.print(F(" "));
  Serial.print("Z: ");
  Serial.print(float(euler.z()));
  Serial.print(F(" "));
  Serial.println("");
  delay(200);
}

```

### output

```
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00
W: 0.00 x: 0.00 y: 0.00 z: 0.00 X: 0.00 Y: nan Z: 0.00

```

The sensor seems to be working since I tried a simple script and the values are avaiable.

Is there some specific setting missing during `setup()` in order to obtain Quaternions.

### Purpose

For Absolute orientation, the Quaternion values need to be converted to Euler .

# Answer
Apparently in the `setup()` it is preferable to have a `delay(1000)` as opposed to `delay(100)`.

### Code

```
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <math.h>

#define DEG (180/M_PI)

Adafruit_BNO055 bno = Adafruit_BNO055(55);

void setup() {
  // put your setup code here, to run once:
  Wire.begin(13, 16, 400000);
  Serial.begin(115200);

  if (!bno.begin()) {
    Serial.println("No BNO055 Detected!");
    while(1);
  }
  delay(1000);
  bno.setMode(Adafruit_BNO055::OPERATION_MODE_NDOF_FMC_OFF);
  bno.setExtCrystalUse(true);
}

void loop() {
  // put your main code here, to run repeatedly:
  imu::Quaternion quat = bno.getQuat();
  imu::Vector<3> euler = quat.toEuler();

//  Serial.print("W: ");
//  Serial.print(quat.w());
//  Serial.print(F(" "));
//
//  Serial.print("x: ");
//  Serial.print(quat.x());
//  Serial.print(F(" "));
//
//  Serial.print("y: ");
//  Serial.print(quat.y());
//  Serial.print(F(" "));
//
//  Serial.print("z: ");
//  Serial.print(quat.z());
//  Serial.print(F(" "));

  Serial.print("Yaw: ");
  Serial.print(euler[0] * DEG);
  Serial.print(F(" "));
  Serial.print("Pitch: ");
  Serial.print(euler[1] * DEG);
  Serial.print(F(" "));
  Serial.print("Roll: ");
  Serial.print(euler[2] * DEG);
  Serial.print(F(" "));
  Serial.println("");
  delay(200);
}

```
> 0 votes

---
Tags: sensors, adafruit, esp32, bno055
---


title: Transmitting serial data over Wi-Fi

text:
# Question
Title: Transmitting serial data over Wi-Fi
I have a device that outputs a TX RX RS232 serial string. Is there a way I can take this locally to an Arduino and send over Wi-Fi to another Arduino?

I'm relatively new to all of this so any advice will be greatly appreciated!

# Answer
> 0 votes
Yes, and there are many tutorials how to do it.
Most popular one uses ESP8266 module. What is even more interesting you can use ESP module as an Arduino (and yes, you can program it using Arduino IDE).

---
Tags: rs232
---


title: Iteed SD card breakout info for Arduino

text:
# Question
Title: Iteed SD card breakout info for Arduino
I got an SD card breakout from an online shop, its the iteed kind without the level shifter, it has the 3.3 / 5 V switch. I cannot find any libraries or write example for it.

Has anyone dealt with it before with Arduino? I have tried finding info but I only get the level shifter kind that has the MOSI pins!

enter image description here

# Answer
Use standard Arduino SD library or the SdFat library. All SD card 'modules' are only a holder and eventually level converters. The SPI device is the SD card itself.

Set the SD adapter to the voltage of your board, connect it to power and SPI bus, choose some pin as SS pin, insert SD card and it must work.

Pins: MISO is master in slave out, MOSI is master out slave in. DO is data out, DI is data in. SD card is slave, so MISO to DO and MOSI to DI
> 0 votes

# Answer
So, a quick google for "Itead SD card breakout" comes up with their website/wiki where there is a schematic. Can't believe you did not try this. It is just that - a breakout board. It will allow you to connect Arduino to an SD card. You can look up any generic example for SD + Arduino on the web.

They explicitly say

> It can work with 5V or 3.3V power supply, and both 5V/3.3V IO operation level. It can be controlled directly by a wide range of microcontrollers such as Arduino, AVR, PIC, ARM and MSP430.
> 1 votes

# Answer
Alrighty, For anyone else struggling with this in the future. Using arduino mega and iteed sd breakout withoit level shifter G-Ground DO-50 CLK-52 DI-51 CS-53 +-5V then in the code before setup specify chip select to 53 Thanks for all the help.
> 0 votes

---
Tags: arduino-uno, arduino-mega, library, sd-card
---


# Question
Title: How can I discover attached motor shields in code?
I'm using the Motor Shield v2 and I'm looking for a way to automatically discover the addresses of attached motor shields.

# Answer
If you configure each I2C device to have a unique address, then it's easy to determine which ones are connected.

This sketch is derived from the I2C Scanner sketch found here: I2cScanner

```
// This sketch tests the standard 7-bit addresses.
// Devices with higher bit address might not be seen properly.
#include <Wire.h>
byte shieldOneAddress = 0x27;
byte shieldTwoAddress = 0x32;
byte error, address;

void setup(){

  Wire.begin();
  Serial.begin(9600);
  Serial.println("Scanning for shields...");

  for(address = 1; address < 127; address++){

    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if(error == 0){
      if(address == shieldOneAddress){
        Serial.println("Shield One is connected.");
      }
      if(address == shieldTwoAddress){
        Serial.println("Shield Two is connected.");
      }
    }

  }
  Serial.println("Scan complete.\n");
}

void loop(){}

```
> 1 votes

---
Tags: arduino-motor-shield
---


title: ESP8266 + HC-05 on same arduino

text:
# Question
Title: ESP8266 + HC-05 on same arduino
I'm absolutely new to arduino, so please excuse me if this is a noob question. I want to use a ESP8266 esp-03 Wifi module with a HC-05 bluetooth module together with my arduino uno. Unfortunately both use the TX and RX pins on the board. Is there a way to use both, the wifi and the bluetooth modules? Or do I have to purchase a wifi board?

# Answer
You can (just about) use any combination of two of:

* Serial to PC,
* HC-05
* ESP-03

You have, basically, a *hardware* UART (pins 0/1), and a *software* UART (any pins of your choice).

Only the hardware UART can be used for communication with the PC, and you can only reliably use one instance of SoftwareSerial.

So, you could:

* Use Serial to the PC (0/1) and HC-05 (SoftwareSerial, your choice of pins), or
* Use Serial to the PC (0/1) and ESP-03 (SoftwareSerial, your choice of pins), or
* Hardware Serial for ESP-03 (0/1) and SoftwareSerial for HC-05 (your choice of pins), or
* Hardware Serial for HC-05 (0/1) and SoftwareSerial for ESP-03 (your choice of pins)

If you want anything more complex than that then you need to use a board with more than one hardware Serial port (such as a Mega2560).
> 3 votes

---
Tags: arduino-uno, esp8266, hc-05, rx-pin
---


# Question
Title: Arduino ModBus RTU master communication with Power Meter problem
i have an arduino UNO with RS485 module.

I have made this connection:

And i have an problem with communication of this module with power meter "InePro PRO-1Mod" (datasheet) over ModBus protocol. I want for example read an **L1 Voltage value**, which i know from the manual (page 24 & 25) that this value is stored in "read holding register" with adrress **5002**. I should communicate with these paramaters:

* Baud rate 9600
* 8 data bits
* even parity
* 1 stop bit

There is also mention about 120 ohms resistor placed by the power meter (but it is 15cm long cable, and even with the resistor there is no change)

I have tried using many of ModBus libraries and for now none of them doesn't work. I have tried "Modbus-Master-Slave-for-Arduino" , "ModbusMaster and now at last i am using this "simple-modbus".

I think that with that simple modbus library i went far as i can, but it is still doesn't working, but i see on the display of power meter that there is some try to communication (i see a black dot which shows modbus communication) but i don't receive any useful data.

I am using this code:

```
    #include <SimpleModbusMaster.h>
#include <AltSoftSerial.h>

#define TxEnablePin 2                    // RS485 modbus direction control pin:
#define baud 9600                           // modbus port speed:
#define timeout 1000                        // modbus timeout in mSec:
#define polling 500                         // modbus scan rate in mSec:
#define retry_count 15

#define TOTAL_NO_OF_REGISTERS 1// number of registers to poll for:

AltSoftSerial altSerial;

enum
{
 PACKET1,
 TOTAL_NO_OF_PACKETS                       // leave this last entry
};

Packet packets[TOTAL_NO_OF_PACKETS];        // array of Packets to be configured

//struct packetPointer packet1 = &packets[PACKET1];
unsigned int regs[TOTAL_NO_OF_REGISTERS];   // master register array
long previousMillis = 0;
long interval = 1200;
unsigned long currentMillis;

void setup() {
 Serial.begin(9600);
 altSerial.begin(9600);
 altSerial.println("Hello World");
 modbus_construct(&packets[PACKET1], 5, READ_HOLDING_REGISTERS, 5000, 2, 0);  //initialize packet
 modbus_configure(&Serial, baud, SERIAL_8E1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
}

void loop() {
 modbus_update();

 float Power;
 unsigned long temp = (unsigned long)regs[1] << 16 | regs[0];
 Power = *(float*)&temp;

  currentMillis = millis();
 if (currentMillis - previousMillis >= interval)
 {
   altSerial.print("Exception errors: ");
   altSerial.println(packets[PACKET1].exception_errors);

   altSerial.print("Failed requests: ");
   altSerial.println(packets[PACKET1].failed_requests);

   altSerial.print("Successful requests: ");
   altSerial.println(packets[PACKET1].successful_requests);
   altSerial.print("Low byte: ");
   altSerial.println(regs[0]);
   altSerial.print("High byte: ");
   altSerial.println(regs[1]);
   altSerial.print("Power ");
   altSerial.println(Power);
   altSerial.println("----------");

   previousMillis = currentMillis;
 }

}

```

And i have got only this output in the pc (its repeating of course):

```
----------
Exception errors: 0
Failed requests: 5
Successful requests: 0
Low byte: 0
High byte: 260
Power 0.00
----------

```

Altserial library i am using together with USB2TTL convertor on pins 8 & 9, to see output.

I should mention that there is only A and B screw terminals on power meter, so i have no option to make common ground connection. I also using an 15cm twisted pair cable UTP.

Can someone help me to make it work ? I have tried to change adrress of holding register to 0x5000 or 5002, tried changing number of registers.

I have tried to connect rs485 module with USB2TTL to pc and run software called "qModMaster" and it works, but with arduino it doesn't work.

Slave ID (power meter) is 5.

Thank you, for your help.

# Answer
> 3 votes
**I have made it. Now it is working. I only checks A & B cables (tried a new one) and change address of register from 5000 to 0x5000 and now it works. I thought that this library already give 0x before address, because i didn't see it anywhere with 0x before.**

An advice for people with the same problems: Most of the devices which is using RS485 and ModBus protocol (and have an some kind of display) shows an communication (over 485 & modbus) on display by some kind of mark, for example in my case it was an "dot" which blinks when there's an communication. When this mark is shown, it is sign of that the communication settings is right, so data, parity bit, stop bit & baudrate is OK (data has successfully reached the dest. device).

After that, these devices send you an error message back on its line. So if you have problems with getting data, you should send your message (ask) from the arduino to that device, over an Transmit pin from arduino (of course trough an converter, for example max485) and the Receiving pin (side) connect to your PC through again some kind of converter from UART to USB. (Warning: you should have the same ground potential, so wire all grounds together)

Install some software to communication for modBus on PC (i am using this soft: https://www.simplymodbus.ca/ | you can use demo ) After that let arduino sent an message and receive it by PC. (in simplymodbus look at the "response") read that code and look to the manual for the device you using, where there should be an description of error codes, if not look at this doc.: http://www.simplymodbus.ca/exceptions.htm or THIS).After that you will have an better look on what is going on and where there is a problem.

# Answer
> 1 votes
I'm using a mp5w pulse meter, the settings:

* Baud rate : 9600
* Address : 02
* Parity : none
* Stop bit : 1

Modbus memory map table for measurement value /(PV) :

* Modebus : 31002
* Address : 03E9
* Size : 5

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


# Question
Title: What exactly does the Arduino preprocessor do?
Arduino claims to be a "language," not just an "application framework," and Arduino files have their own extension, `.ino`. The language is obviously C++, but not quite. My understanding is that Arduino has some sort of special preprocessor which converts `.ino` files into C++ files before compiling them.

My question is: What *exactly* does this preprocessor do? What exactly are the differences between "Arduino language" and real C++? The Arduino documentation seems to gloss over this.

In particular, I've had weird things happen when I try to define my own classes in my sketch. It's hard to figure out what I'm doing wrong when the language doesn't seem to be specified anywhere.

# Answer
It does four things, basically:

1. It adds `#include <Arduino.h>` to the top of your file, which gives you access to all the classes, functions and defined variables/macros of the API.
2. It joins together all the INO files together into a single monolithic file (in the same order as the tabs in the window),
3. It matches `#include` entries with libraries and adds the files in those libraries to the list of files to compile, and
4. It scans through the ino file(s) looking for functions and adds prototypes to them to the top of your file.

It's the latter that can cause problems. Historically it never got the prototypes in the right place, and if you ever passed a structure of your own devising to a function it would break horribly. It does a better job these days, but it's still not 100% perfect.

It basically means that you don't have to adhere to the "You must define it before you use it" rule of C/C++. Which of course makes for lazy programmers.
> 8 votes

# Answer
See my answer: How the IDE organizes things

I'm not sure if link-only answers which refer to a Stack Exchange link are OK. In case they are not, here is the first part of that answer:

## This is how the IDE organizes your "sketch":

* The main `.ino` file is the one of the same name as the folder it is in. So, for `foobar.ino` in `foobar` folder - the main file is foobar.ino.
* Any other `.ino` files in that folder are concatenated together, in alphabetic order, at the end of the main file (regardless of where the main file is, alphabetically).
* This concatenated file becomes a `.cpp` file (eg. `foobar.cpp`) - it is placed in a temporary compilation folder.
* The preprocessor "helpfully" generates function prototypes for functions it finds in that file.
* The main file is scanned for `#include <libraryname>` directives. This triggers the IDE to also copy all relevant files from each (mentioned) library into the temporary folder, and generate instructions to compile them.
* Any `.c`, `.cpp` or `.asm` files in the sketch folder are added to the build process as separate compilation units (that is, they are compiled in the usual way as separate files)
* Any `.h` files are also copied into the temporary compilation folder, so they can be referred to by your .c or .cpp files.
* The compiler adds into the build process standard files (like `main.cpp`)
* The build process then compiles all the above files into object files.
* If the compilation phase succeeds they are linked together along with the AVR standard libraries (eg. giving you `strcpy` etc.)

A side-effect of all this is that you can consider the main sketch (the .ino files) to be C++ to all intents and purposes. The function prototype generation however can lead to obscure error messages if you are not careful.
> 5 votes

---
Tags: programming, c++, sketch
---


# Question
Title: Switching external power supply to 5V cooling fan with an Arduino and 2N2222 transistor
I'm using a 2N2222 transistor as a low-side switch to turn a 5V computer fan on and off with an Arduino digital pin, which responds programmatically to a button press - i.e. the relevant digital pin is switched from LOW to HIGH for a determined time in response to a button press recorded on A0.

My circuit looks like this:

And here's my code:

```
#define btnPin A0
#define signalPin 6

void setup() {
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(signalPin, OUTPUT);
  digitalWrite(signalPin, LOW);
}

void loop() {
  if(digitalRead(btnPin) == LOW){
  digitalWrite(signalPin, HIGH);
  delay(5000);
  digitalWrite(signalPin, LOW);
  }
}

```

For simplicity, I'm showing a separate button component in the diagram, but I'm actually using a button that's wired into an LCD shield.

My expectation is that, when I press the button, the digital pin wired to the transistor's base will cause the transistor to close the circuit and turn the fan (and LED) on for five seconds.

The problem that I have is that the Arduino's digital pin doesn't seem to be able to saturate the base, so not enough current passes through the transistor to power the fan. It does turn the LED on and off as expected, but the fan needs much more current than the LED. If I take a wire directly from VIN or the 5V pin and touch it to base (through a resistor, of course), it does succeed in saturating the base, and the fan turns on. Measuring the current from VIN (or the 5V pin) to base, I get 4mA, so my assumption is that 4mA is sufficient to saturate the base. My understanding is that an Arduino digital pin should easily supply this. But in my case, the current from the relevant digital pin to the transistor's base never goes higher than 1.4mA. I've tried different pins on the board, but always get the same result.

So the question is, why does the circuit work as expected for the LED, but not for the fan? Any help/suggestions will be greatly appreciated!

# Answer
> 2 votes
To fully turn the transistor on you should give the base somewhere around 1/10 to 1/20 of the collector current. If you read the datasheet for the PN2222 (a highly recommended activity) you will see that Vce(sat) is specified with Ic/Ib = 10.

Now, the Microchip ATMega328 MCU chip in many (but not all) Arduinos is capable of sourcing 10mA or 15mA with minimal drop (assuming a 5V supply), again this information is available in the MCU datasheet (Figure 31-71 on page 355).

So it appears you are using an "Arduino" with some other MCU. In which case you can either use another transistor to boost the current or substitute a logic-level MOSFET.

# Answer
> 1 votes
Based on the description of your circuit, it sounds like you might not have connected the Arduino's ground to the "negative rail", the same part of the circuit where the transistor's emitter is connected. You must make that connection in order to properly bias the base-emitter junction of the transistor.

I recommend you draw a schematic for this sort of question, that would be helpful.

# Answer
> 1 votes
I seem to have solved the problem. As mentioned in the question, I was using a button wired into an LCD shield. As the LCD shield occupies all the header pins on the Arduino, the LCD shield helpfully provides circuit connections for the unused Arduino pins. It seems that the LCD shield I was using has some fault which only allowed limited current to flow from the corresponding Arduino pins. This would explain the anomaly that only the LED lit up as expected, but the fan failed to work: presumably the weak current into the transistor's Base created sufficient gain to power the LED, but not the fan. Eventually, after many attempts at getting the circuit to work, even the LED stopped working and that's when I realised that there must be a continuity problem with the header connections. So, removing the LCD shield and wiring everything directly into the Arduino with a separate push button, everything started working as expected. Many thanks for all the helpful replies. I've got a much better handle on how BJTs work now!

# Answer
> 0 votes
You should also have a diode across the motor, cathode to 5V and anode to the transistor. When the transistor turns off, the motor will try and keep the 200mA current flowing. The diode lets that current dissipate. Without it, you can get a high voltage spike at the transistor which can damage it.

---
Tags: arduino-uno
---


# Question
Title: Accessing raspberrypi.local from Nodemcu
Currently I am trying to access a rest API from NodeMCU. The API is hosted on my local LAN on a Raspberry pi 3 b. The Raspberry pi is accessible on LAN using the raspberrypi.local domain address. But the problem is I am unable to access the raspberrypi.local address form NodeMCU. It is unable to just resolve the address. Can anyone please help me resolve this issue?

# Answer
> 3 votes
In order to access the API, your NodeMCU needs to know the IP address your Pi has at this time. There are several ways to resolve `raspberrypi.local` to the actual IP. Assuming the NodeMCU got its IP assigned by your WiFi hotspot, it also received a DNS server IP. This is where the NodeMCU would ask first. However, if this DNS server is hosted by your internet provider, it obviously would not know what to respond when asked for your `raspberrypi.local`.

Another way, especially for `.local` domains, is mDNS. NodeMCU has a module to do that.

If you work with this a lot, consider running a local development network with your own DHCP/DNS combo. dnsmasq is a good place to start. Lots of tutorials online. The Pi can host that for you.

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


# Question
Title: Connection from Arduino Uno to Microsoft SQL Server Database
I would like to make a connection from **Arduino Uno to Microsoft SQL Server** for storing student attendance records into a table from my database.

So, what is the best way to do that? I need a suggestion or useful references and links.

I have written a web application on Visual Studio using C# language. What Arduino does is getting fingerprint through sensor, then I would like to store the attendance records of a student into database. So the attendance records can be retrieved from database to the web application and display to teachers.

This is just for project purpose only and the connectivity between Visual & SQL Server using these two lines below:

```
SqlConnection con = new SqlConnection();
con.ConnectionString = "Data Source=DESKTOP-H7KQUT1;Initial Catalog=SAOS1;Integrated Security=True";

```

# Answer
Using a layer between Arduino and MSSQL might give you the least headache. Would you like to do this on-premise or in the cloud?

For an easy cloud approach, look at AWS Lambda. Write a Lambda function that inserts into your MSSQL database, possibly running on AWS too. Your choice of Java, Node.js, C#, or Python. Hook it up with incoming MQTT messages from your Arduino. https://stackoverflow.com/questions/33165045/aws-lambda-and-sql-server-integration could help.

For a cloud-free approach, you could run your own local MQTT server (broker, to be exact, Mosquitto being the most popular), and have your C# subscribe as an MQTT client. When the Arduino publishes a fingerprint signature, your C# script can do the database work.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: How to get a feedback that something connected to an Arduino is working?
Assume you have an Arduino Uno board, the board is connected to some sensors, maybe a stepper motor or something, it does not matter.

How to get feedback or diagnostics or something that all the things are working, or if not then get feedback that are not working?

# Answer
> 1 votes
There is no general mean of error detection in microcontrollers, so also not for an Arduino. Problems can occur at many points, extremely depending on how your project works. Think about a sensor, that is connected over some network bus; the sensor itself may fail, but also the network bus, so that you are not able to connect to the sensor anymore. Also the Arduino has no possibility to report errors to you, that you didn't anticipated in your sketch (like the log files on a PC would do). So there is not one answer for it. Here are some possibilities (some of them already described in previous answers):

* Check the output of library functions for error messages. Many (but not all) libraries return status codes from their important functions. For example: The `Wire.endTransmission()` function will return a status code, with which you can determine, if the transmission succeded and what might have gone wrong.
* Check sensors for expected values. If the values go out of range (for example a temperature of -20°C where you would expect room temperature) you can be pretty sure, that something is wrong with the sensor (assuming it worked properly before).
* Add sensors to your project, to sense, if it is working as expected, and program the Arduino to do the corresponding actions on failure (for example an alarm)

The first two options are simple, the third can get very complex and expensive and is normally only used, if the project really demands sensing malfunction electronically (like for a robot, that could hurt humans, when moving in the wrong direction).

# Answer
> 1 votes
To expand on Juraj's answers, tackle this question from the user's point of view. What does *all things are working* mean for them? Does the temperature you read from a sensor have to be within .2C of a reference value? The stepper has to move a thing from defined positions A to B?

Based on the answers to questions like this, which is sort of a black-box testing approach, think about how to obtain reference values, then write tests in your Arduino to check if they are met. You might have to move your system into a defined testing stage first, like move the steppers to a defined starting point, then go test.

---
Tags: arduino-uno
---


title: Beginner problem with DC motor

text:
# Question
Title: Beginner problem with DC motor
I am new to electronics and I'm having a problem when creating my project. I have created a Bluetooth controlled rover using HC-06, Dual H-bridge motor driver and 4 DC motors. However, only two of the DC Motors are moving and the other two remain still.

Could you please suggest what happened?

Attached is the wiring of the motors and code.

```
char t;

void setup() {
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if(Serial.available()) {
    t = Serial.read();
    Serial.println(t);
  }

  if(t == '1') {
    digitalWrite(9,HIGH);
    digitalWrite(10,LOW);
    digitalWrite(11,HIGH);
    digitalWrite(12,LOW);
  }

  else if(t == '2') {
    digitalWrite(9,LOW);
    digitalWrite(10,HIGH);
    digitalWrite(11,LOW);
    digitalWrite(12,HIGH);
  }

  else if(t == '3') {
    digitalWrite(9,LOW);
    digitalWrite(10,LOW);
    digitalWrite(11,HIGH);
    digitalWrite(12,LOW);
  }

  else if(t == '4'){
    digitalWrite(9,HIGH);
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
    digitalWrite(12,LOW);
  }

  else if(t == '5') {
    digitalWrite(9,LOW);
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
    digitalWrite(12,LOW);
  }

  delay(100);
}

```

# Answer
To analyze your problem:

1. Switch two wires between two motors (and repeat this to get all combinations), to find out if the code/wiring until the motors is wrong, or there is a problem with the motors.
2. Print out the values of pins 9, 10, 11 and 12 and the value of t/input to see if the pins are controlled as you expect.
3. Remove all but one motors, for all motors one at a time, to see if there is no influence between them.

Below is not an answer to your question, but I can only align the code as answer.

It is better coding style to use the following form:

```
void loop() {
  if(Serial.available()){
    t = Serial.read();
    Serial.println(t);
  }

  if ((t >= '1') && (t <= '5'))
  {
    int input = (int) t - (int)'0';

    digitalWrite( 9, (input == 1) || (input == 4) ? HIGH : LOW);
    digitalWrite(10, (input == 2)                 ? HIGH : LOW);
    digitalWrite(11, (input == 1) || (input == 3) ? HIGH : LOW);
    digitalWrite(12, (input == 2)                 ? HIGH : LOW);
  }

  delay(100);
}

```

Note: ? : is a ternary operator which means : a ? b : c =\> if a then b else c.

Instead of using 9, 10, 11, 12 define pin numbers (e.g. PIN\_MOTOR\_X), and for 1, 2, 3, 4, 5 input numbers define LEFT, RIGHT, UP/FORWARD, DOWN/BACKWARD, STOP.
> 3 votes

---
Tags: arduino-uno, motor, l298n
---


# Question
Title: After restoring the BNO055 offsets to the sensor the calibration values are all 0
Board: **ESP32**

Script: restore\_offsets.ino from Adafruit's BNO055 library

The only difference is I am storing the information in ESP's **NVS** using the `Preferences` Library

### Code

```
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <Preferences.h>

/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (1000)

Adafruit_BNO055 bno = Adafruit_BNO055(1390);

Preferences Calibration;

/**************************************************************************/
/*
    Display some basic info about the sensor status
    */
/**************************************************************************/
void displaySensorStatus(void)
{
    /* Get the system status values (mostly for debugging purposes) */
    uint8_t system_status, self_test_results, system_error;
    system_status = self_test_results = system_error = 0;
    bno.getSystemStatus(&system_status, &self_test_results, &system_error);

    /* Display the results in the Serial Monitor */
    Serial.println("");
    Serial.print("System Status: 0x");
    Serial.println(system_status, HEX);
    Serial.print("Self Test:     0x");
    Serial.println(self_test_results, HEX);
    Serial.print("System Error:  0x");
    Serial.println(system_error, HEX);
    Serial.println("");
    delay(500);
}

/**************************************************************************/
/*
    Display sensor calibration status
    */
/**************************************************************************/
void displayCalStatus(void)
{
    /* Get the four calibration values (0..3) */
    /* Any sensor data reporting 0 should be ignored, */
    /* 3 means 'fully calibrated" */
    uint8_t system, gyro, accel, mag;
    system = gyro = accel = mag = 0;
    bno.getCalibration(&system, &gyro, &accel, &mag);

    /* The data should be ignored until the system calibration is > 0 */
    Serial.print("\t");
    if (!system)
    {
        Serial.print("! ");
    }

    /* Display the individual values */
    Serial.print("Sys:");
    Serial.print(system, DEC);
    Serial.print(" G:");
    Serial.print(gyro, DEC);
    Serial.print(" A:");
    Serial.print(accel, DEC);
    Serial.print(" M:");
    Serial.print(mag, DEC);
}

/**************************************************************************/
/*
    Display the raw calibration offset and radius data
    */
/**************************************************************************/
void displaySensorOffsets(const adafruit_bno055_offsets_t &calibData)
{
    Serial.print("Accelerometer: ");
    Serial.print(calibData.accel_offset_x); Serial.print(" ");
    Serial.print(calibData.accel_offset_y); Serial.print(" ");
    Serial.print(calibData.accel_offset_z); Serial.print(" ");

    Serial.print("\nGyro: ");
    Serial.print(calibData.gyro_offset_x); Serial.print(" ");
    Serial.print(calibData.gyro_offset_y); Serial.print(" ");
    Serial.print(calibData.gyro_offset_z); Serial.print(" ");

    Serial.print("\nMag: ");
    Serial.print(calibData.mag_offset_x); Serial.print(" ");
    Serial.print(calibData.mag_offset_y); Serial.print(" ");
    Serial.print(calibData.mag_offset_z); Serial.print(" ");

    Serial.print("\nAccel Radius: ");
    Serial.print(calibData.accel_radius);

    Serial.print("\nMag Radius: ");
    Serial.print(calibData.mag_radius);
}

/**************************************************************************/
/*
    Arduino setup function (automatically called at startup)
    */
/**************************************************************************/
void setup(void)
{
    Wire.begin(13, 16, 400000);
    Serial.begin(115200);
    delay(1000);
    Serial.println("Orientation Sensor Test"); Serial.println("");

    /* Initialise the sensor */
    if (!bno.begin())
    {
        /* There was a problem detecting the BNO055 ... check your connections */
        Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
        while (1);
    }

    Calibration.begin("offsets", false);
    adafruit_bno055_offsets_t calibrationData;
    sensor_t sensor;

    int32_t bnoID = Calibration.getInt("bnoID");
     bool foundCalib = false;
    /*
    *  Look for the sensor's unique ID at the beginning oF EEPROM.
    *  This isn't foolproof, but it's better than nothing.
    */
    bno.getSensor(&sensor);
    if (bnoID != sensor.sensor_id)
    {
        Serial.println("\nNo Calibration Data for this sensor exists in NVS");
        delay(500);
    }
    else
    {
        Serial.println("\nFound Calibration for this sensor in NVS.");

        // Accelerometer offsets
        calibrationData.accel_offset_x = Calibration.getInt("acc_off_x");
        calibrationData.accel_offset_y = Calibration.getInt("acc_off_y");
        calibrationData.accel_offset_z = Calibration.getInt("acc_off_z");

        // Gyroscrope offsets
        calibrationData.gyro_offset_x = Calibration.getInt("gyr_off_x");
        calibrationData.gyro_offset_y = Calibration.getInt("gyr_off_y");
        calibrationData.gyro_offset_z = Calibration.getInt("gyr_off_z");

        // Magnetometer offsets
        calibrationData.mag_offset_x = Calibration.getInt("mag_off_x");
        calibrationData.mag_offset_y = Calibration.getInt("mag_off_y");
        calibrationData.mag_offset_z = Calibration.getInt("mag_off_z");

        displaySensorOffsets(calibrationData);

        Serial.println("\n\nRestoring Calibration data to the BNO055...");
        bno.setSensorOffsets(calibrationData);

        Serial.println("\n\nCalibration data loaded into BNO055");
        foundCalib = true;
    }

    delay(1000);

    /* Display some basic information on this sensor */
//    displaySensorDetails();

    /* Optional: Display current status */
    displaySensorStatus();

   //Crystal must be configured AFTER loading calibration data into BNO055.
    bno.setExtCrystalUse(true);

    sensors_event_t event;
    bno.getEvent(&event);
    if (foundCalib){
        Serial.println("Move sensor slightly to calibrate magnetometers");
        while (!bno.isFullyCalibrated())
        {
            bno.getEvent(&event);
            displayCalStatus();
            Serial.println("");
            delay(BNO055_SAMPLERATE_DELAY_MS);
        }
    }
    else
    {
        Serial.println("Please Calibrate Sensor: ");
        while (!bno.isFullyCalibrated())
        {
            bno.getEvent(&event);

            Serial.print("X: ");
            Serial.print(event.orientation.x, 4);
            Serial.print("\tY: ");
            Serial.print(event.orientation.y, 4);
            Serial.print("\tZ: ");
            Serial.print(event.orientation.z, 4);

            /* Optional: Display calibration status */
            displayCalStatus();

            /* New line for the next sample */
            Serial.println("");

            /* Wait the specified delay before requesting new data */
            delay(BNO055_SAMPLERATE_DELAY_MS);
        }
    }

    Serial.println("\nFully calibrated!");
    Serial.println("--------------------------------");
    Serial.println("Calibration Results: ");
    adafruit_bno055_offsets_t newCalib;
    bno.getSensorOffsets(newCalib);
    displaySensorOffsets(newCalib);

    Serial.println("\n\nStoring calibration data to NVS...");

    bno.getSensor(&sensor);
    bnoID = sensor.sensor_id;
    // enter the Sensor ID
    Calibration.putInt("bnoID", bnoID);

    // store new Accelerometer offsets
    Calibration.putInt("acc_off_x", newCalib.accel_offset_x);
    Calibration.putInt("acc_off_y", newCalib.accel_offset_y);
    Calibration.putInt("acc_off_z", newCalib.accel_offset_z);

    // store new Gyroscope offsets
    Calibration.putInt("gyr_off_x", newCalib.gyro_offset_x);
    Calibration.putInt("gyr_off_y", newCalib.gyro_offset_y);
    Calibration.putInt("gyr_off_z", newCalib.gyro_offset_z);

    // store new Magnetometer offsets
    Calibration.putInt("mag_off_x", newCalib.mag_offset_x);
    Calibration.putInt("mag_off_y", newCalib.mag_offset_y);
    Calibration.putInt("mag_off_z", newCalib.mag_offset_z);
    Serial.println("Data stored to NVS..");

    Serial.println("\n--------------------------------\n");
    delay(500);
}

void loop() {
    /* Get a new sensor event */
    sensors_event_t event;
    bno.getEvent(&event);

    /* Display the floating point data */
    Serial.print("X: ");
    Serial.print(event.orientation.x, 4);
    Serial.print("\tY: ");
    Serial.print(event.orientation.y, 4);
    Serial.print("\tZ: ");
    Serial.print(event.orientation.z, 4);

    /* Optional: Display calibration status */
    displayCalStatus();

    /* Optional: Display sensor status (debug only) */
    displaySensorStatus();

    /* New line for the next sample */
    Serial.println("");

    /* Wait the specified delay before requesting new data */
    delay(BNO055_SAMPLERATE_DELAY_MS);
}

```

The only difference in the code is instead of passing the offset struct I save information individually using `putInt` method

### steps

1. I calibrate the sensor connected via I2C
2. Once the calibration is done store it into NVS
3. Observe values for a bit
4. Restart the node and retreive the offsets from NVS

## Problem

The calibration offsets are stored into the BNO and it takes *hella time* in the following block:

```
   if (foundCalib){
        Serial.println("Move sensor slightly to calibrate magnetometers");
        while (!bno.isFullyCalibrated())
        {
            bno.getEvent(&event);
            displayCalStatus();
            Serial.println("");
            delay(BNO055_SAMPLERATE_DELAY_MS);
        }
    }

```

I added the `displayCalStatus` to see the values of the accelerometer, gyroscope and magnetometer and all values within the block are Zero.

Doesn't this defy the whole idea of storing offsets in the first place if the values are all zero?

### Output from board

```
Found Calibration for this sensor in NVS.
Accelerometer: 19 -10 4
Gyro: -3 -4 9
Mag: 589 986 1473
Accel Radius: 0
Mag Radius: 0

Restoring Calibration data to the BNO055...

Calibration data loaded into BNO055

System Status: 0x0
Self Test:     0xF
System Error:  0x0

Move sensor slightly to calibrate magnetometers
    ! Sys:0 G:0 A:0 M:0
    ! Sys:0 G:0 A:0 M:0
    ! Sys:0 G:0 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0
    ! Sys:0 G:3 A:0 M:0

```

As you can observe the calibration are all set to 0 and I have to do the whole thing again. why ?

# Answer
The displayCalStatus() function shows the status of the calibration, not the offsets or current sensor values. With calibration in progress the status is zero. Once the calibration of a sensor is complete, the status is 3. The sensor starts the calibration itself with first movements after power up.

The set offsets are used after power-up only until the initial automatic calibration finished.

from datasheet:

> Once the device is calibrated, the calibration profile can be reused to get the correct orientation data **immediately after ‘Power of Reset’**. However, once the sensor enters the internal calibration routine, the calibration profile **is overwritten** with the newly obtained sensor offsets and sensor radius.
> 1 votes

---
Tags: adafruit, esp32, bno055
---


# Question
Title: Why isn't the stack pointer changing in this simple sketch?
I'm playing around with context switching, and my first idea is to play with SP and see how it changes. However, Sp doesn't do what I expect. The sketch is below. I'm using an Uno R3. What I expect to see is that SP should first print out some value, then it should be 4 integers further along (4x2 bytes?) when printed the second time. But that doesn't happen, and both times I see the exact same value for SP. What could the problem be?

```
    void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);

  Serial.print("X = ");
  Serial.println(SP,HEX);
}
void loop() {
  // put your main code here, to run repeatedly:
Serial.print("BEFORE: ");
Serial.println(SP,HEX);
int y = 15;
int z = y;
int g = z + y;
int dsf = z-y;
  Serial.println(dsf+g); //this should make these variables DO something...
  Serial.print(" After = ");
  Serial.println(SP,HEX);
  delay(1000);
}

```

# Answer
It's impossible to second-guess the compiler like that. There's a couple of things you need to realise:

* The compiler will optimize out any variables that just get assigned to other variables as part of calculations and have no further use
* The AVR CPU has 32 registers. More than enough to not *need* to use RAM to store values for a simple sketch like that.

Making the variables `volatile` will certainly help, since that forces the compiler to place them in memory. However you really should examine the assembly code the compiler produces to know exactly what it's doing.
> 2 votes

# Answer
Another way the compiler can optimize is to compile small or single-use functions inline. What you expected would get wrapped inside a call and return sequence, may not.

Inserting `__attribute__ ((noinline))` ahead of the function definition can suppress that optimization:

```
__attribute__ ((noinline)) void foo(int bar)
{
   // do something
}

```

suppresses the inlining for function foo(). Inlining has frustrated my investigations more than once, so I created this easier to remember macro. (The keyword is just `__NOINLINE`; the #else-clause is there so that, umm, "someone", doesn't unwittingly try to use the "\__attribute..." declarator with another compiler that doesn't recognize it).

```
// Don't compile this function inline
//   '__NOINLINE void foo(void){ ... }'
#ifdef __GNUC__
#define __NOINLINE  __attribute__ ((noinline))
#else
#define NOINLINE error 'NOINLINE' not defined for this compiler
#endif

```
> 3 votes

---
Tags: arduino-uno, avr
---